Commit cd205cf
authored
feat: Unify CSS-to-RN compiler and runtime pipeline (#5)
## Summary
This PR unifies the CSS-to-React-Native style pipeline into a new
`@cssxjs/css-to-rn` workspace package and wires CSSX, loaders, Babel
output, and runtime entrypoints through it. The goal is to replace the
separate forked CSS-to-RN transform libraries and the old CSSX runtime
with one maintainable compiler/runtime package.
Key changes:
- Adds `packages/css-to-rn`, a TypeScript ESM package owning CSS
parsing, selector IR, value resolution, property transforms, style
resolution, caching, and React runtime tracking.
- Keeps Stylus-to-CSS compilation separate, while moving pure CSS-to-RN
style compilation and runtime resolution into the unified package.
- Supports local JS template interpolation in function-scoped
`css`/`styl` templates, with interpolation values reusing one cache slot
per compiled call shape.
- Adds runtime CSS string compilation for generated CSS via
`useRuntimeCss()`, `useCssxLayer()`, and `cssx()`.
- Implements nested `var()` resolution, partial shorthand substitution,
dynamic dependency tracking, bounded cache behavior, deep inline-style
hashing, media/dimension tracking, web `matchMedia` invalidation, and
React Native `Dimensions` integration.
- Adds React 19 tracking without Teamplay or `@nx-js/observer-util`,
including Suspense/aborted-render cleanup tests.
- Adds `CssxProvider style` and `theme` for subtree-scoped provider CSS,
global utility classes, scoped `:root` / `:root.<theme>` variables, OS
dark-mode auto selection, and component tag overrides.
- Adds CSSX theme assets and exports: `cssxjs/themes/tailwind` and
`cssxjs/themes/shadcn`.
- Adds `@custom-media`, CSS media range evaluation for width/height
comparisons, built-in `@media (--theme-*)` aliases, and provider-aware
`useMedia()`.
- Adds component tag selectors through `themed(tagName, Component)`,
including `Tag`, `Tag.class`, `Tag:part(name)`, `Tag::part(name)`,
`Tag:hover`, and `Tag:active` matching.
- Adds `useCssVariable()`, `useCssVariableRaw()`, `getCssVariable()`,
and `getCssVariableRaw()` for subscribed and global JS access to
resolved CSS variables.
- Adds `useCssColor()` and `getCssColor()` for provider-aware JS color
bridges, including token lookup and `color-mix()` style mixing.
- Adds a deprecated JS `u()` helper and build diagnostics for deprecated
CSS `u` units.
- Adds validating `variables` and `defaultVariables` proxy methods:
`.assign()`, `.set()`, and `.clear()`.
- Resolves `var()` inside inline style props and tracks the variables
used by those inline props.
- Normalizes `oklch()`, `oklab()`, and `color-mix()` through pinned
`@colordx/core@5.4.3` so modern color CSS works on RN.
- Supports percentage/unitless `calc()` in CSS value resolution for
color-channel math while still rejecting mixed layout calc such as
`calc(100% - 16px)`.
- Mixes `color-mix(in srgb, color, transparent)` with premultiplied
alpha so transparent theme colors preserve the source RGB.
- Preserves source-condition TypeScript consumers without committing
build output: source entrypoints carry vendor shims, `themed()`
preserves wrapped component props, and `cssx()` accepts loader-produced
opaque sheet records at the type boundary.
- Implements `:hover`/`:active` aliases, `filter`,
`background-image`/gradient support, limited `background` shorthand,
animations/transitions/keyframes, and Reanimated v4-compatible animation
style output.
- Adds build-strict diagnostics for unsupported static declarations
while keeping runtime compilation graceful for generated CSS.
- Migrates loaders and Babel runtime paths to the unified package, with
source-condition test/dev imports and facade smoke coverage.
- Stops tracking generated `dist` output; package builds still emit
`dist` for published/default exports.
- Keeps legacy `runtime/*-teamplay` import paths as compatibility
wrappers only.
- Removes the old `packages/runtime` package from the active graph.
- Updates `architecture.md`, `AGENTS.md`, `plan.md`, public docs, README
credits, and CI smoke checks for the new architecture.
## Architect Review Follow-up
After a multi-agent architecture/performance/test-coverage review, this
PR now also:
- avoids promoting changed tracked sheets, interpolation values, or hook
dependencies from Suspense-aborted renders
- keeps `useCssxLayer(false)` hook order stable when toggled to a real
sheet
- allows and resolves template interpolation inside provider `:root`
custom property values
- resolves provider root variables from compiled sheets and `{ sheet,
values }` layers
- adds regression coverage for complex partial `var()` values in
box-shadow/filter/text-shadow/transform/background
- updates runtime docs for precompiled provider `:root` interpolation
- maps `:part(root)` to the root `style` prop consistently in the
unified resolver
- expands `@custom-media` subscriptions to concrete media dependencies
and marks width/height range queries as dimension-dependent
- surfaces runtime sheet compile diagnostics through `resolveCssx()` for
generated CSS callers
- keeps `cssxjs/runtime/web` and `cssxjs/runtime/react-native` exporting
the public CSSX/color helpers with smoke coverage
## Related PRs
- startupjs/startupjs#1327 wires `StartupjsProvider style` and `theme`
into CSSX so framework users can pass provider CSS and theme selection
through the StartupJS root provider.
- startupjs/startupjs-ui#41 moves StartupJS UI theming onto CSSX theme
assets, `startupjsUiTheme.cssx.css`, CSS variable primitives, and direct
component tag/part overrides.
## Validation
- `cd packages/css-to-rn && npm test`
- `cd packages/babel-plugin-rn-stylename-inline && yarn test`
- `cd packages/babel-plugin-rn-stylename-to-style && yarn test`
- `git diff --check`
- `cd packages/cssxjs && yarn test`
- CSSX theme entrypoints compile through JS import/default-export
wrappers instead of leaking `.cssx.css` assets into consuming web
builds.
- Cross-repo StartupJS UI validation with local source links:
- `node scripts/update-style-reference-docs.mjs` idempotency check
- `yarn generate-package-dts`
- `node scripts/check-startupjs-ui-exports.mjs`
- `yarn build` for startupjs-ui docs
- Playwright smoke for the generic Styling guide plus Button, Item, Div,
and DateTimePicker docs pages
- Playwright smoke for Storybook iframe stories: Overview, Button, Item,
Badge, Modal, Popover, System/StartupJS UI, and DateTimePicker
- visual screenshots checked for Styling, Button, Item, DateTimePicker,
provider, and popover stories
- Known during DateTimePicker smoke: Moment Timezone logs its existing
missing timezone-data warning; no CSS token, page, or provider errors
were observed.
- startupjs PR validation: `NODE_OPTIONS="-C cssx-ts" npm test` in
`core/startupjs`, plus the normal pre-commit hook with eslint and `npx
startupjs check`.
## Review Focus
This is a large architectural PR. Please scrutinize:
- Runtime cache invalidation, interpolation cache behavior, and
reference stability.
- Provider `:root` / `:root.<theme>` variable scoping and precedence
relative to runtime/default variables.
- Theme selection, OS color-scheme subscriptions, and `@media
(--theme-*)` behavior.
- `@custom-media`, range media evaluation, and `useMedia()`
subscriptions.
- Component tag selector matching and the `themed()` render-local
tracking model.
- `useCssVariable()` / `useCssColor()` exact subscriptions and
Suspense/aborted-render safety.
- Media/dimension invalidation, web `matchMedia` subscriptions, React
Native dimensions, and listener cleanup.
- Complex value parsing: nested `var()`, shorthand fragments, modern
colors, gradients/backgrounds, transforms, animations, transitions, and
invalid generated CSS.
- Babel output compatibility with existing CSSX `styleName`, `css`,
`styl`, and part workflows.
- Package exports/source-condition behavior and whether the new package
boundary is maintainable long term.1 parent 5d8d1b7 commit cd205cf
109 files changed
Lines changed: 18734 additions & 4226 deletions
File tree
- .github/workflows
- docs
- api
- guide
- migration-guides
- example
- packages
- babel-plugin-rn-stylename-inline
- __tests__
- __snapshots__
- test
- babel-plugin-rn-stylename-to-style
- __tests__
- __snapshots__
- babel-preset-cssxjs
- css-to-rn
- src
- react
- transform
- test
- engine
- react
- types
- cssxjs
- runtime
- test
- themes
- loaders
- compilers
- test
- runtime
- entrypoints
- platformHelpers
- test
- vendor
- react-native-css-media-query-processor
- react-native-dynamic-style-processor
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
33 | 33 | | |
34 | | - | |
35 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
36 | 40 | | |
37 | 41 | | |
38 | 42 | | |
| |||
51 | 55 | | |
52 | 56 | | |
53 | 57 | | |
54 | | - | |
| 58 | + | |
55 | 59 | | |
56 | 60 | | |
57 | 61 | | |
| |||
70 | 74 | | |
71 | 75 | | |
72 | 76 | | |
73 | | - | |
74 | | - | |
75 | | - | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
76 | 81 | | |
77 | 82 | | |
78 | 83 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
26 | 38 | | |
27 | 39 | | |
28 | 40 | | |
0 commit comments