Created
December 12, 2018 16:22
-
-
Save isaksky/a96476fa51a10ba903b7c6bdcb13c85b to your computer and use it in GitHub Desktop.
Reframe codemirror
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns mything.components.codemirror | |
(:require [reagent.core :as reagent] | |
[re-frame.core :as rf] | |
[reagent.interop :refer [$]] | |
cljsjs.codemirror | |
cljsjs.codemirror.mode.clojure | |
cljsjs.codemirror.mode.sql)) | |
(def codemirror-defaults {:lineNumbers true | |
:lineWrapping true | |
:styleActiveLine true | |
:mode "text/x-mssql" | |
:tabMode "spaces"}) | |
(defn create-editor [this editor options value dispatch-path dims] | |
(let [cm (.fromTextArea js/CodeMirror | |
(reagent/dom-node this) | |
(clj->js (merge codemirror-defaults options)))] | |
(when value | |
($ cm setValue value)) | |
($ cm setSize (:width dims) (:height dims)) | |
($ cm on "change" | |
(fn [ed] | |
(rf/dispatch-sync (conj dispatch-path ($ ed getValue))))) | |
(reset! editor cm))) | |
(defn destroy-editor [editor] | |
(if @editor | |
(do (.toTextArea @editor) | |
(reset! editor nil)) | |
(js/console.warn "Could not kill CodeMirror instance"))) | |
(defn codemirror-editor | |
([{:keys [value dispatch-path options textarea-obj dims] | |
:or [value "", dispatch-path [], options {}, textarea-obj {}, dims {:height nil, :width nil}]}] | |
(let [editor (atom nil)] | |
(reagent/create-class | |
{:component-did-mount (fn [this] (create-editor this editor options value dispatch-path dims)) | |
:component-will-unmount (fn [this] (destroy-editor editor)) | |
:component-did-update (fn [this [_ {prev-dispatch-path :dispatch-path, | |
prev-options :options, | |
prev-textarea-obj :textarea-obj, | |
prev-dims :dims}]] | |
(let [{:keys [value dispatch-path options textarea-obj dims]} (reagent/props this) | |
editor-val ($ @editor getValue)] | |
(if-not (and (= prev-dispatch-path dispatch-path) | |
(= prev-options options) | |
(= prev-textarea-obj textarea-obj)) | |
;; big prop change where the others will be set | |
(do (destroy-editor editor) | |
(create-editor this editor options value dispatch-path dims)) | |
;; set value and dimensions individually if updated | |
;; editor setValue chokes for nil values | |
(do (when-not (= editor-val value) | |
($ @editor setValue (or value ""))) | |
(when-not (and (= prev-dims dims)) | |
($ @editor setSize (:width dims) (:height dims))))))) | |
:reagent-render (fn [] [:textarea textarea-obj])})))) | |
(comment | |
;; Usage | |
[codemirror-editor {:value query | |
:options {:mode "clojure" :lineNumbers true} | |
:dispatch-path [::change-dev-update]}]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FIY, a few things changed in the meantime:
cljsjs
deprecated in favor of NPM packages refered directly in shadowcljsreagent/dom-node
is nowreagent/as-element
(and others, but this is just a quick hint for anyone else landing here)