styled-ppx
                                
                                 styled-ppx copied to clipboard
                                
                                    styled-ppx copied to clipboard
                            
                            
                            
                        CSS Extraction at build-time
We can remove the runtime completely and go for static styles. Generate CSS files in the _build folder (for Melange/native) and in-source in ReScript.
- We will remove the runtime completely allowing much faster implementation
- Output real CSS (can be extracted to a new file, cached)
- Need to know how to generate files on the same folder (both in rescript and melange)
 
- Dynamic components can be translated to CSS variables
- Is that possible?
- https://pawelgrzybek.com/interpolate-css-custom-properties-values/
- There are a few limitations: media-queries/selectors
 
- Which dynamic values aren't representable as CSS variables?
- If there's a list of them, can we generate inline styles for those?
 
 
- Is that possible?
- We can have development type-safety if we keep the parsing/type-checking + inline styles at run-time.
- Not sure how thought, maybe with unboxed?
 
- We already have a css-in-js logic implemented in native
Design
styled.div
module C = [%styled.div "height: 100%"]
(* pushes into the Stylesheet ".div12312 {height: 100%}" *)
(* module C = <div className="div12312" /> *)
module C = [%styled.div (~what) => "width: $(what); height: 100%"]
(* pushes static properties ".div12312 {height: 100%}" *)
(* generates dynamic properties with CSS vars ".div12345 {width: (--var-what)}" *)
(* module C = <div className="div12312 div12345" style={ReactDOM.Style.make("--var-what": what)} /> *)
cx
let cx = [%cx "height: 100%"]
(* pushes properties ".hash {height: 100%}" *)
(* let cx = ".hash" *)
Ideal plan
- [x] Understand what it means 0 runtime cost with dynamic styling compiledcssinjs.com https://github.com/callstack/linaria
- [ ] Read a few resources about it
- https://shud.in/posts/ssr-streaming-and-css-in-js
- https://github.com/andreipfeiffer/css-in-js
- https://medium.com/@tkh44/writing-a-css-in-js-library-from-scratch-96cd23a017b4
- https://scrimba.com/g/gcssvariables
- https://github.com/threepointone/glam/tree/e9bca3950f12503246ed7fccad5cf13e5e9c86e3
- https://www.youtube.com/watch?v=Gw28VgyKGkw&ab_channel=LeeRobinson
- https://github.com/tw-in-js/twind
- https://joshwcomeau.com/css/css-variables-for-react-devs/
- https://www.lekoarts.de/javascript/writing-performant-css-with-vanilla-extract
- Rethinking CSS - Introducing Stylex https://youtu.be/ur-sGzUWId4
- The problem with importing css https://www.coolcomputerclub.com/posts/importing-css
- Take a look at ppx_css from janestreet https://github.com/janestreet/ppx_css/blob/master/inline_css/src/inline_css.ml
- React 18's discussion https://github.com/reactwg/react-18/discussions/110
 
- [x] Create the logic at runtime first (styled-ppx.emotion-native)
- [ ] Implement a CSS printer for static styles
- Can we reuse server-emotion css module to print it
- Re-implement all css_to_emotion/css_types.Debug and Declarations_to_emotion
 
- Create a CSS pretty printer
- https://github.com/janestreet/ppx_css/blob/master/css_jane/src/css_jane.ml
- https://github.com/astrada/ocaml-css-parser/blob/master/test/css_fmt_printer.ml
- https://git.chimrod.com/css_lib.git/tree/lib/print.ml
 
- Apply SCSS to CSS transformations
- Ref: https://github.com/postcss/postcss-nested
- ensure selectors are “resolved”
- ensure & in selectors are replaced with the parent hash
- ensure media queries are at the top level
- ensure media queries render with “and”
 
 
- Can we reuse server-emotion css module to print it
- [ ] Generate static files from the output of the server-emotion
- Generate css files similarly to https://github.com/hyper-systems/rescript-sx
- Create a cache for it (don’t re-generate files that don’t change)
- Avoid the hashing in testing (or add labels)
 
- [ ] Dynamic styling
- Parser should support CSS variables
- Render to styles should render to inline styles as well (native-react + to_string)
 
- [ ] Support dynamic values. (Transform to CSS variables and inject static CSS)
- What should we do on interpolation in selectors and mediaqueries?
 
- [ ] Remove the "bridge" from css to bs-emotion and move it to inline-styles
- [x] Implement a vendor-prefixer for unsupported properties https://github.com/kripod/style-vendorizer (styled-ppx.emotion-native)
- [ ] Remove array API? and css extension?
Similar implementations
- https://github.com/stereobooster/css-in-js-101
- https://4catalyzer.github.io/astroturf/introduction
- https://twind.dev/handbook/introduction.html#features
- https://github.com/microsoft/griffel
- https://github.com/CraigCav/css-zero
- https://github.com/callstack/linaria
- https://github.com/modulz/stitches
- https://github.com/atlassian-labs/compiled
- https://github.com/jsxstyle/jsxstyle
- cssx https://github.com/krasimir/cssx/tree/master/packages/cssx https://www.smashingmagazine.com/2016/04/finally-css-javascript-meet-cssx/
- emotion https://github.com/emotion-js/emotion/blob/v9.2.12/packages/create-emotion/src/index.js https://github.com/thysultan/stylis.js/tree/master/src
- Zero-runtime CSS-in-TypeScript with 🧁 vanilla-extract https://www.youtube.com/watch?v=-Idub5K7K6Q&t=2556s
- https://github.com/antfu/unocss
- https://github.com/justjavac/postcss-rs
- https://github.com/4Catalyzer/astroturf
- https://twitter.com/devongovett/status/1454126641555386372?s=28
- https://blogg.bekk.no/increasing-the-performance-of-elm-css-34075512d6a6
- withCSSVaris a simple helper to access/modify css variables in your code
- https://github.com/kentaromiura/withCSSVar/tree/main
- https://github.com/yukukotani/just-styled
- https://github.com/Anber/wyw-in-js
- https://nerdy.dev/custom-prop-categories
- https://yak.js.org/docs/features
The problem remaining to solve is the static interpolation:
let small = `px 10 in
let classname = [%cx {| margin: $(small); |}];
How can we access small, and turn it into a CSS variable?
Possible solutions
let%cx classname = {
  let lola = small in
  {| font-size: $(lola) |}
};
let%css_var = `px 10 in
(* let small = CssJs.publishGlobalVar (__MODULE__ ++ "-small",`px 10); `px 10 in *)
let classname = [%cx {| margin: var(--small); |}]
(Problems of hashing name, and others)
let classname = [%cx {| margin: $(small); |}] @@ { small: small }