reagent-project / reagent

A minimalistic ClojureScript interface to React.js
http://reagent-project.github.io/
MIT License
4.75k stars 415 forks source link

Any interest in being able to replace `react/createElement` with a custom function? #592

Open cj-price opened 1 year ago

cj-price commented 1 year ago

Any interest in being able to replace react/createElement with a custom create element function?

My use case is that I'd like to use css-in-js with emotion.

I have it working here: https://github.com/reagent-project/reagent/commit/42978d4839c3b6e2ab28bbc1d2362b5f28847736

06-13-23T10:15:58

Deraen commented 1 year ago

This is probably already possible with the Compiler protocol. make-element method is quite close to the createElement: https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/template.cljs#LL320C11-L320C11 https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/template.cljs#L128-L141 https://github.com/reagent-project/reagent/blob/master/doc/ReagentCompiler.md

You might have to refer to some impl functions to reuse the code for other methods, so the API isn't perfect, but if you get it working I can consider exposing the necessary functions.

Deraen commented 1 year ago

Checking your fork, there are few other createElement calls besides make-element but I'm quite sure that those don't matter, because the elements created in those cases refer to functions, not HTML elements, and they wouldn't use css.

cj-price commented 1 year ago

Awesome, thanks for the feedback. I'll take a look at implementing it with the compiler

cj-price commented 1 year ago

Have it working with the compiler here: https://github.com/cj-price/reagent-emotion/commit/e09a8e6db9762400d98a8b5fa824253fa20938ac

I haven't tested the other places where react/createElement is used but for general use the compiler protocol seems more than enough to implement something like this.

Would you like me to clean up the example and submit a PR?

Deraen commented 1 year ago

I guess Emotion is interesting enough to add a example to the repository.

The root package.json probably doesn't need to be changed?

The example should use shadow-cljs so it can use npm packages. There is an example in the material-ui folder.

The simple-example component seems unnecessary, as you can set the compiler directly on the render call. But perhaps it is for use from the intro ns now?

Deraen commented 1 year ago

And a link could be added the compiler protocol docs to the example folder.

cj-price commented 1 year ago

I submitted https://github.com/reagent-project/reagent/pull/593

I am using shadow-cljs as requested and removed the code from the intro. Also added a link on the docs. Willing to make any requested changes :)

The simple-example component seems unnecessary, as you can set the compiler directly on the render call. But perhaps it is for use from the intro ns now?

Yeah I did my testing on the intro which is why I rendered inside the simple example component.