yeah, initially I was using helix.core/$ in the emitter
but ran into issues doing that with Hiccup, since both macros were trying to compile the component’s children. so started directly using Helixs prop impl inside a parser instead (that’s why the demo does it like that too)
created an issue for this (https://github.com/alidlo/rewrap/issues/1) still have to figure out how to best mix the two since there’s some overlap
I wonder how simple it would be to do it just for helix
it’s not hard to do, just two macros, hard part is making it extensible
@lilactown here’s link to exact code: https://github.com/alidlo/rewrap/blob/master/rewrap/src/rewrap/interop.cljc#L42-L55
i kinda wish Helix separated it’s hooks/dev optimizations from its interop/compilation since the former can be used with any React wrapper, whereas latter is more opinionated
right now, for example, I’m writing a UI library. its written in Typescript, considering writing it in Clojurescript but then I’d have to choose a React wrapper making it less useful
I would take a PR for a helper macro like that specific to helix. Riffing on what you have there:
(defmacro generate-native-macros
[sym->impl]
`(do
~@(for [[sym impl] sym->impl]
`(defmacro ~sym [& args#]
(helix/$ (with-meta ~impl {:native true}) ~@args#)))
is there anything specific about helix that is stopping you from using it to build a UI library?
to what extend would it make sense using all of Helix with Fulcro or Reagent?
opting for js just bc it by default has less code/opinions, not sure if there’s way around that
well, in my head, helix is so minimal and opinion-less that it’s just the same as writing in JS and using it with Fulcro or Reagent 😛
but I am probably biased, so I’m curious if there’s some specific choices that helix makes for you that make it feel like it impedes use w/ Fulcro/Reagent/Rum/etc.
I would also accept code size as a reasonable argument, I think that helix should be less code, for all that it does… not sure exactly how to accomplish that yet
but curious if there are other problem points
code size and extensibility are my two arguments. e.g. above you baked in helix.core/$
as emitter macro when my whole goal was to make it custom 😜
it can be error prone to mix different react wrappers, e.g. mixing helix and hicada I ran into uses since they both compile props and children a certain way. so that’s why with rewrap wanted to make those things extensible
hmm. I guess my expectation is that you would expose them as react components, same as what you would get with writing them in TS
so e.g. if you had a component:
(defnc my-component
[{:keys [foo bar]}]
,,,)
then some reagent app would use it like:
(defn app []
[:> ui-lib/my-component
{:foo "foo" :bar "bar"}
,,,])
rum, fulcro I assume have similar syntax for handling external React components
yea, i guess in that case it’d just a small code overhead, which I guess shouldn’t matter relative to entire cljs bundle we’re bringing in but psychologically it does 😅
FWIW at my previous job that’s exactly what we did: wrote our UI library components in JS/TS and then used them in our reagent app
it worked okay
yea, tbh, I just wonder what cool things I could do writing it primarily for cljs
plus have to consider optimizations in two languages versus one
yeah
and TS.. i used to love it before cljs lol
I still kinda like TS
I wrote my latest big idea in TS
trying to use it in a new CLJS lib is troublesome tho
i like it in general too, but in complex project TS error message become indecipherable
I hope CLJS implements support for goog.module
sooner rather than later
then you could use TS code in CLJS super super easily via tsickle
yea, mixing between them more easily would be great; thanks for link
is that possible using helix with electron?
making what less useful?
I need zero TS
I know this is easier said than done, I'd really appreciate some docstrings on helix.hooks functions/macros. I could contribute some of them, but use-callback is eluding me.
@dominicm personally, I never saw the point of that hook
you need it for performance reasons?
Gotta keep my re-renders down, yep
could you be a bit more specific please about what is elusive about use-callback
I just didn't understand the arguments, I assumed it would be like use-effect
, it seems like it's more like react/useCallback
Use effect takes a body, but use-callback takes a fn-body, but in the arglist it's called a body too 🤕
I see, probably simple mistake of docs
arglists* sry
docs could explain body must resolve to fn in this case.
useCallback(fn) in react is useMemo(() =>fn), so I always used useMemo because I find useCallback confusing
I am fairly sure helix relies a bit on the react docs
I have problems to understand react hooks too, and I only used use-state
and use-effect
until now 🙂
all hooks are basically use-state
> I am fairly sure helix relies a bit on the react docs This is unrelated. I understand useCallback. I didn't understand what to pass to use-callback without reading the source. Same for use-effect, which implicitly adds a fn (unlike useEffect).
https://github.com/Lokeh/helix/blob/0.0.12/src/helix/hooks.cljc#L158 See implicit fn here, but not https://github.com/Lokeh/helix/blob/0.0.12/src/helix/hooks.cljc#L231
I haven't tried, can you tell me if the answer to "what to pass to use-callback" is the same as with plain react?
Not quite. There's other parameters which are valid with use-callback
just make sure you use those hooks correctly, over-using them will cause performance issues.
use-callback is pretty safe afair.
It's not going to consume more memory than a single callback, and re-rendering twice is relatively expensive in comparison.
I never worried about re-render times, paint costs way more and that is optimized by default if I use identical props to components
that's what use-callback reduces too. I'm not certain, but the DOM will need updating if the callback function changes regularly.
I've had it cause reagent applications to grind to a halt.
Particularly with small animations.
PRs welcome!
honestly I regret the fancy thing I did with use-effect where it automatically wraps the body in a function
it’s too clever
Makes sense.
helix.hooks2
@lilactown Cool, if I get time this afternoon will spend some time on it
thanks! I bet it will help many others as well
like legit tho I want to create a helix.hooks2
probably once I’m done with the defhook
machinery
my goal for defhook
is that you can add custom hooks that support for automatically filling in a deps vector and linting for unspecified deps
once that’s done I can create a new hooks namespace without all the macro code in helix.hooks
auto-filling the deps vector is <3, as long as you can turn it off (sometimes I want to ignore a value)
yep, it would work just like it does for use-effect
/ use-memo
/ etc. today, just for custom hooks
(use-custom-hook
:auto-deps ;; auto fill
#(foo bar))
(use-custom-hook
[foo] ;; ignore bar
#(foo bar))
I see, very nice
if that cb function itself never accepts arguments seems like a good choice to just accept its body is it just bc it differs from React?
yeah, it differs from react and prevents certain patterns like using higher-order functions
Hi everybody. Just wanted to let you guys know that I created wrapper for emotion.js (styled component) https://github.com/khmelevskii/emotion-cljs It should be very useful to resolve problem working with css in cljs. This wrapper works good with helix.
I´m using cljss.core
But I´ll try to use this one
nice @y.khmelevskii! this looks really similar to what we built at work but fuller featured 😄
yeah, and please let me know your feedback 🙂
yeah, we use it in our project and I decided that it’s not a lot of work to open source it. Happy to share it!
The other day I was so confident that it's easy to use render props, today I wasted more than 4 hours already on trying to use material autocomplete, and all I get is m.call is not a function. Not fun.
@y.khmelevskii how do you use with cljs?
if I have a lib like antd
, and it has its Button
how do you use with this?
(defstyled Button :button
{:display :flex
:color :red})
($ antd/Button {:className (Button)})
?
hey @fabrao. If antd/button
is react component you can do the following:
(defstyled Button antd/Button
{:display :flex
:color :red})
($ Button)
Oh, if I can only use Button instead of antd/Button I can call Button as MyButton
, right? Thank you
one thing I like about what we use at work is we add the namespace to the generated class name
makes debugging styles way easier
so it ends up being css-123asdf-app_some-feature_foo
where evertying after css-123asdf
is the namespace + var
hello all, what is the minimum package.json
configuration for helix?
is this
{
"version": "1.0.0",
"private": true,
"scripts": {
"start": "npx shadow-cljs watch app"
},
"devDependencies": {
"shadow-cljs": "2.10.5"
},
"dependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-refresh": "^0.8.1",
}
}
enougth?yep should be good