davesnx / styled-ppx

Type-safe styled components for ReScript, Melange and native with type-safe CSS
https://styled-ppx.vercel.app
BSD 2-Clause "Simplified" License
399 stars 32 forks source link

Interpolation support for any expression (not only identifiers) #430

Open davesnx opened 5 months ago

davesnx commented 5 months ago

Explore how difficult is to support any expression inside the interpolation syntax.


[%css "font-size: $(string_of_int(23))"];

let base = 33;
[%css "font-size: $(string_of_int(base))"];

let darken = (color, num) => { ... };
[%css "color: $(darken(CssJs.blue, 0.3))"];

Any expression it might be virtually impossible to parse by styled-ppx, but we can “stop parsing” until a matching ) appears.

Another approach is trying to run the "current parser" as a single expression inside the interpolated value, I'm unsure how to do this since embeding ReScript/OCaml/Reason parsers is not an option (would bloat the binary)

Other ppxes that support some sort of expression interp is because the entire payload is valid: https://github.com/thierry-martinez/metapp.

metaquote uses a trick where [%expr] is the ppx, and [%e ] can be placed inside expr for any expression. Errors are tricky, and DX seems bad. Similar case is https://github.com/stedolan/ppx_stage

The last idea is to have a mini parser for only function calls in OCaml/Reason and ReScript that we support, similar on how ppx_str works https://github.com/AriaFallah/ppx_str/blob/master/src/ppx/ppx_str.ml and warn the user about it, so they can always extract into a function.