This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-31
Channels
- # aws (18)
- # babashka (35)
- # beginners (7)
- # cider (3)
- # clara (2)
- # clj-kondo (15)
- # cljs-dev (1)
- # cljsrn (3)
- # clojure (20)
- # clojure-canada (1)
- # clojure-dev (3)
- # clojure-spec (17)
- # clojure-uk (13)
- # clojutre (1)
- # cursive (7)
- # datomic (1)
- # duct (7)
- # fulcro (33)
- # helix (77)
- # jobs (3)
- # malli (15)
- # meander (3)
- # off-topic (30)
- # pathom (3)
- # quil (1)
- # reagent (1)
- # reitit (10)
- # shadow-cljs (2)
- # tools-deps (5)
- # xtdb (6)
- # yada (1)
@lilactown Do you advise some integration with css-in-js like $ ? Material-ui for example, it bundles a js-in-css solution https://gist.github.com/geraldodev/a9b60dd611d1628f9413dd6de6c3c974#file-material_ui_helix-cljs-L14 . It avoids global css which is a good thing.
I'm playing with Helix and React Native, I'm trying to understand the error here:
(apply $ rn/View {:style #js {:flex 1 :alignItems "center" :justifyContent "center"}}
[(rnc/text {:style #js {:fontSize 36}} "Hello Helix!")
(rnc/button {:title "Click me"})])
the code is for experimenting purposes (trying to wrap react native stuff with factory
)
but that code doesn't work, it errors with [object Object] is not ISeqable
the stack from RN is quite incomplete, so not sure, I was using the apply $
to isolate the constructor
when I use createElement
directly from React it works fine
digging a bit, the problem is happening during -native-props
call
doing this (apply helix.core/$ rn/Text {:style #js {:flex 1}} ["Hello" "World"])
works for me so I imagine the error has to do with the component children
@alidcastano I ran a couple of experiments to test that, but in the end, when I kept the props clean, it failed, when used the :style, it broke
was specifically problem with rn/View
from React Native from MacOS, and I can see a difference, the View is a string component (native component), the others are not
so I'm guessing the issue is with the fn
version of $
when used with native elements
you can break any with: (apply $ "div" {:style #js {:flex 1}} ["child"])
actually, I'm writing an issue, but as I test more (not on RN now, just on regular react on browser) I see it breaks with this: ($ "div" {:style #js {:flex 1}})
@alidcastano I figured a different problem, not really an issue per se, but a confusing situation
@wilkerlucio is there a particular reason youāre passing in styles as a JS object instead of a map?
the trick part is because its not clear with RN components are native and which are not
and that may vary depending on which RN impl its being targetted (mac os RN may have different settings than Windows, than ios, etc... and those can change over time)
the idea is that if youāre using $ then you should be able to just passing in maps
for example, Button
in RN for MacOS is not a native component
the same thing you mean in helix when you check for native when running $
if its a string or keyword
or if its a component
yeah, so using the js-obj could be the safe version for incosistent situations like this
yeah thereās a couple ways to handle this, at the application level and at the library (helix level)
but then I have to know which component is which (native or not)
if I could just throw #js in all of then, I can avoid caring about it
also, I fear changes between versions, a non-native component today may be turned native on the next version
the only thing that really matters is whether a component expects :style
as a JS object or not
yeah, but in impl that varies, which is the issue (which is not true for react dom)
yeah, I only have problems when using props with :style
ah, sorry, gotcha
yeah, I got the problem because I'm wrapping the components with factory
that's what I mean by native š
rn/View
=> "RCTView"
rn/Text
=>
#js{"$$typeof" "Symbol(react.forward_ref)",
:render #object[Text],
:displayName "Text",
:propTypes #js{:ellipsizeMode #object[bound checkType],
:numberOfLines #object[bound checkType],
:textBreakStrategy #object[bound checkType],
:onLayout #object[bound checkType],
:onPress #object[bound checkType],
:onLongPress #object[bound checkType],
:pressRetentionOffset #object[bound checkType],
:selectable #object[bound checkType],
:selectionColor #object[bound colorPropType],
:suppressHighlighting #object[bound checkType],
:style #object[Function],
:testID #object[bound checkType],
:nativeID #object[bound checkType],
:allowFontScaling #object[bound checkType],
:maxFontSizeMultiplier #object[bound checkType],
:accessible #object[bound checkType],
:adjustsFontSizeToFit #object[bound checkType],
:minimumFontScale #object[bound checkType],
:disabled #object[bound checkType],
:dataDetectorType #object[bound checkType]}}
rn/Button
=> #object[Button]
no worries, I'm just a new user hitting unexplored code paths š
@lilactown and you plan to also support #js style on native?
I think the macro ns may be a problem, because you can't know what to expect from the components
even though Button
is not native on MacOS RN, it may be native in other impls
so we can't know for sure what each is, makes sense?
@wilkerlucio using a macro routes around this problem completely
($ ^:native rn/View {:style {flex 1}})
will always convert the :style
prop to a JS object
if itās a symbol, it treats it as ānon-nativeā unless itās annotated with ^:native
metadata
so rn/View
can go from at runtime being a string, function, class, memoized, whatever, it doesnāt matter
a macro would do something like:
(defmacro view
[& args]
`($ ^:native rn/View ~@args))
which would always be unambiguous. no matter what rn/View
is at runtime, it would always have the same behavior
letās define native to be:
āa component which requires transformation of props before construction, e.g. :style
prop to be a JS object, :class
to be renamed to :className
, etc.ā
then whether or not rn/View
is a string or not is irrelevant, it will always be ānativeā. the detection of string/keyword is just a dumb heuristic to try and get that information at compile time
the inconsistency weāre running into now is that if you apply this same heuristic at runtime, itās even dumber, because apparently React Native has some of itās ānativeā components as strings and other ānativeā components as functions / memoized components /etc.
but Iāll have to think more about this issue before coming up with an encompassing solution