Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (s/def ::element
- (s/cat :type (s/or :htmltag keyword?
- :component symbol?)
- :props (s/? (s/map-of keyword? any?))
- :children (s/* (s/or :text-node string?
- :element ::element))))
- (s/def ::component
- (s/cat :name symbol?
- :props-signature (s/spec (s/cat :props any?))
- :body any?))
- (defn create-element [{:keys [type children props]}]
- `(react/createElement
- ~(case (key type)
- :htmltag (-> type val name)
- :component (-> type val))
- ~(when props
- (let [process-keys '(fn [[k v]]
- (case k
- :style [:style (clj->js v)]
- [k v]))]
- `(cljs-bean.core/object
- (into (cljs-bean.core/bean)
- (map ~process-keys ~props)))))
- ~@(when children
- (map
- (fn [node]
- (case (key node)
- :text-node (val node)
- :element (-> node val create-element)))
- children))))
- (defmacro jsx [react-tree]
- (let [ast (s/conform ::element react-tree)]
- (create-element ast)))
- (defmacro defcomponent [& args]
- (let [{:keys [name props body]} (s/conform ::component args)]
- (list 'defn
- name
- ['props]
- (list 'let ['props '(cljs-bean.core/bean props)]
- body))))
- (defcomponent Form [props]
- (let [[state setState] (react/useState (-> props :input :default))]
- (jsx
- [:input
- {:placeholder "hello world"
- :value state
- :onChange #(setState (-> % .-target .-value))}])))
- (defn app []
- (println "whesh")
- (jsx
- [:div {:style {:background-color "red"}} "hello"
- [:p "world"]
- [Form {:input {:default "mdr"}}]]))
- (react-dom/render
- (jsx
- [app])
- app-root)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement