helix

kennytilton 2021-08-25T13:28:33.115800Z

So things are going great marrying Matrix to Helix and I want to do the DRY thing and write a macro to write some macros. The problem is providing a react native type such as rn/View to the macro. Story here: https://clojurians.slack.com/archives/C03S1KBA2/p1629896337345000 But now I notice that helix $ has a bit of flexibility when it comes to the type parameter: "The $ macro takes a component type (string, keyword, or symbol referring to a Component)" The examples I see are "div" and :div. I bravely attempted "View" and :View to no avail. Is there some way to use CLJS reflection to get to the react native rn/View in generate CLJS? 🤞

kennytilton 2021-08-25T13:45:43.117Z

btw, the brave attempts ended with "Invariant Violation: View config not found for name View."

lilactown 2021-08-25T14:56:37.117400Z

the react native renderer doesn't accept strings

lilactown 2021-08-25T14:57:30.118300Z

you have to provide it a reified component (i.e. a function, class, or one of the values exported from react or react-native like react-native/View)

lilactown 2021-08-25T14:58:19.119100Z

react-dom and other renders are different, they accept "div" as a type

kennytilton 2021-08-25T15:17:01.122600Z

I just tested this: (defmacro View [mx-props jsx-props & children] `(tiltontec.model.core/make :myapp.mxreact/mxrn.elt :sid (swap! myapp.mxreact/sid-latest inc) :kids (tiltontec.model.core/cFkids ~@children) :rendering (tiltontec.cell.core/cF (helix.core/$ (mxfnc (apply helix.core/$ (when true rn/View) ~jsx-props {} (doall (map #(tiltontec.model.core/mget % :rendering) (tiltontec.model.core/mget ~'me :kids))))))) ~@(apply concat (into [] mx-props)))) ...and I think it worked. :) I can replace the (when true... with a case statement (case ~rn-ty :View rn/View :SafeAreaView etc) and get pretty much the DRY I was after. 🤞

kennytilton 2021-08-25T15:18:34.123200Z

No, not CASE, a big COND or sth.

kennytilton 2021-08-25T20:42:31.130300Z

I am starting to think I should unpack the helix.core/$ macro and write a macro that expands into .createElement yada yada. This will not be as powerful, but I am really just trying to get to the react native elements, and plan to use Matrix magic to make the react native elements easily programmable. One thing that puzzles me is that the CLJS helix.core defines get-react but does not use it in forms like: (apply create-element type' nil args) ...where create-element is just (def create-element react/createElement) But I know next to nothing about interop so I will not worry about it. 🙂 Current plan is to try creating some RN elements with some form of createElement and then worry about macros. Thanks for a huge leg up on RN from CLJS!

lilactown 2021-08-25T20:47:53.130900Z

IIRC (get-react) was a micro-optimization that emitted slightly nicer code

lilactown 2021-08-25T20:48:08.131300Z

haven't tested it in the case of (apply ,,,)

kennytilton 2021-08-25T23:00:00.134600Z

Ah, I found a reasonable compromise to get DRY and stay with the helix.core/$ macro:

(defmacro define-view-macro [gen-type]
  `(defmacro ~gen-type [mx-props# jsx-props# & kids#]
     `(tiltontec.model.core/make :myapp.mxreact/mxrn.elt
        :sid (swap! myapp.mxreact/sid-latest inc)
        :kids (tiltontec.model.core/cFkids ~@kids#)
        :rendering (tiltontec.cell.core/cF
                     (helix.core/$ (myapp.mxrgen/mxfnc
                                     (apply helix.core/$
                                       (get {:View         rn/View
                                             :SafeAreaView rn/SafeAreaView} ~~(keyword gen-type))
                                       ~jsx-props#
                                       {}
                                       (doall
                                         (map (fn [~'mapkid#]
                                                (tiltontec.model.core/mget ~'mapkid# :rendering))
                                           (tiltontec.model.core/mget ~'~'me :kids)))))))
        ~@(apply concat
            (into [] mx-props#)))))
I will have another one for atomic widgets (no children). I just have to type in an entry translating each keyword :View to the rn/View etc. Now I can (define-view-macro View). Next up will be yet another trivial macro so I can (define-view-macros View SafeAreaView ScrollView). Thx again for Helix. 🙏