Hi there, can anybody help me with a macro outputting a rum component? I want to add some sugar for standard components in my app, that always require the same set of mixins
(rum.core/defcs yo < editor.components.mixins/dispatching ,,,
[a b]
[:div "hello"])
Should become:
(defco yo [a b]
[:div "hello"])
with this macro:
(defmacro defco [sym args & body]
`(def
~sym
(rum.core/build-defcs
(fn ~(cons args body))
[editor.components.mixins/dispatching ,,,]
~(str sym))))
the two forms above macroexpand-1 to exactly the same form, but my macro throws a react error, because :div
is interpreted as a child (but react cannot render objects (keyword object in this instance)). any ideas?I've also struggled with this and gave up (but mostly because my macro knowledge was terrible, I didn't run into the same issue)
I took you having this problem as well as a challenge and tried again, try this please:
(defmacro defco [sym args & body]
`(rum.core/defc
~sym
~'< ALL_YOUR_MIXINS
~args
~@body))
I've also arrived myself at this version, which you can probably adjust to your liking:
(defn insert
"Inserts an element into a collection at the given index"
[coll idx elem]
(concat
(take idx coll)
[elem]
(drop idx coll)))
(defmacro def-styled
"rum/defc but automatically adds the reactive mixin"
[sym & args]
(let [docstring (when (= (second args) '<)
(first args))
filtered-args (if (= (first args) '<)
(rest args)
(if docstring
(nthrest args 2)
args))
definition `(rum/defc
~sym
~'< reactive
~@filtered-args)]
(if docstring
(insert definition 2 docstring)
definition)))
awesome, thank you, @azzurite
when I change :div
to "div" it works (showing div as a string in the dom, but no error)