Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Based on theller's gist to define a custom component, this code provides a function that lets you render reagent hiccup to a webcomponent on its shadow DOM -- ref: https://gist.github.com/thheller/36332574918b974a3e4996efcb7457d2
(ns simple-reagent-webcomponent (:require [reagent.core :as re]))
(defn webcomponent! [name view-component]
(let [;; defines the constructor function, which is the "class" object used by the customElements api
component (fn component [] (let [e
;; this is the equivalent of the call to "super"
(js/Reflect.construct js/HTMLElement #js [] component)]
(js/console.log (str name ": Constructed!"))
(set! (.-shadow e) (.attachShadow e #js {:mode "open"}))
e))]
(set! (.-prototype component)
;; establishes prototype hierarchy
(js/Object.create (.-prototype js/HTMLElement)
#js {:connectedCallback
#js {:configurable true
:value (fn []
(this-as this
;; attaches the reagent process to the shadow dom
(re/render [view-component] (.-shadow this))
(js/console.log (str name ": Connected! ") this)))}}))
;;finally, defines the component with these values
(js/window.customElements.define name component)
component))
(def globstate (re/atom 0))
(defn main-panel []
[:div
[:p "yo, dis a shadow dom p"]
[:form
[:p "Changes: " @globstate] [:br]
"First Name: " [:input {:type :text
:name :fname
:on-change (fn [e] (.preventDefault e)
(js/console.log "change!")
(swap! globstate inc))}] [:br]]])
(defn init [] (webcomponent! "test-comp" main-panel))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.