lilactown / helix

A simple, easy to use library for React development in ClojureScript.
Eclipse Public License 2.0
627 stars 52 forks source link

Pass class and id via shorthand in $ #81

Open SevereOverfl0w opened 3 years ago

SevereOverfl0w commented 3 years ago

I propose that $ support the following: ($ "div.foo.bar#unique#id" {} …) where {:class ["foo" "bar"] :id "unique id"} would be set as a result of this.

Many hiccup-inspired tools utilize this kind of syntax, for example Reagent. The shorthand makes it a lot easier to sell a team on Helix that is currently using something with "less typing".

We've been using a $-wrapping macro at work since using Helix (~6 months at least) and have not found any downsides yet. Our code is definitely shorter! :)

lilactown commented 3 years ago

This seems specific to the web DOM, so I think this would be a good addition to the helix.dom/$d macro, rather than the helix.core/$.

SevereOverfl0w commented 3 years ago

There's an implementation of this in https://git.sr.ht/~severeoverfl0w/helix-sev

lilactown commented 3 years ago

Very nice! Question:

($d :div.foo.bar {& {:class "baz"}} ,,,)

based on my read of your code as-is, the dynamic prop :class will overwrite the class assoced onto the props map. This is because (helix detail) dynamic props are merged in after macro expansion, in something like:

(react/createElement "div" (merge-props #js {:class "foo bar"} {:class "baz"}) ,,,)

It's not clear to me what the correct behavior is here. what do you think?

SevereOverfl0w commented 3 years ago

@lilactown You're right, that's a limitation right now. It has that limitation because I didn't think it was possible to implement things such that this limitation wouldn't exist. I think there're two behaviours here that make sense:

If :&, &, etc. are present, we could wrap the expression such that the classes are appended. If they aren't present, then we do the current implementation?