Started playing around with Spindel last night. It's very cool! I find the API much more intuitive than #CL85MBPEF.
One bit of feedback: the DOM stuff is not well documented at all. It's only mentioned in passing in the readme, and it wasn't until I was poking around the examples that I realized there even was a DOM library piece. Almost feels like it should be its own library, i.e. Missionary is to Electric as Spindel is to Spindel DOM. Just my 2c.
I tried to add a simple toolbar to the tiptap example:
(defn make-app-spin [content-signal toolbar-signal]
(spin
;; Track the content signal for reactive updates
(let [content (iv/get-new (track content-signal))
;; Truncate for display if too long
display-html (if (> (count content) 500)
(str (subs content 0 500) "...")
content)
toolbar-state (iv/get-new (track toolbar-signal))]
(el/div {:class "tiptap-demo"}
,,, ;; Header
;; Editor container using foreign-node
(el/div {:class "editor-section"}
(el/h2 "Editor")
(foreign-node
{:class "tiptap-editor"
:on-mount (fn [el]
(create-editor! el content-signal))
:on-unmount (fn [_]
(destroy-editor!))
;; updates toolbar-state so the toolbar follows the cursor...
:on-mouseup on-mouseup
}))
;; Live preview of content - now reactively updated via signal
(el/div {:class "preview-section"}
(el/h2 "Content (HTML)")
(el/pre {:class "content-preview"}
(el/code display-html))
(el/h2 "Toolbar state")
(el/pre {:class "content-preview"}
(el/code (pr-str (into {} toolbar-state))))) ;; <---------------------- ???
(el/div {:class "toolbar"
:style (:style toolbar-state)}
(el/button {:on-click #(js/console.log "i")} "I")
(el/button {:on-click #(js/console.log "b")} "B")
(el/button {:on-click #(js/console.log "u")} "U"))
,))))
Reactivity on toolbar-state is working nicely. However, for the content preview, doing (pr-str toolbar-state) just renders the #object[...] repr, not very useful. So the into is just a way to show a readable form. Works, but not sure if this is idiomatic or if there's a "sanctioned" way to do this? 🙂 Thanks!I will take a look. We could maybe introduce a custom render protocol.