484 Commits

Author SHA1 Message Date
github-actions[bot] 44388b459f chore: release v1.12.0 v1.12.0 2026-09-04 10:11:18 +00:00
Julius Marminge 0c01f443b2 fix: read variant tokens from flattened class selectors (#662)
* fix: read variant tokens from flattened class selectors

Tailwind 4.3.3 stopped nesting variants under the utility class and emits
compound selectors instead:

  <= 4.3.2                           4.3.3
  .active\:x { &:active { ... } }    .active\:x:active { ... }

The native processor only read `:active`, `:focus`, `:disabled`, theme
`:where(...)`, `:dir()` and `[data-*]` tokens from nested rules. On the
flattened form the leading class token was accepted and the rest of the
selector ignored, so every variant compiled as an unconditional style:
`active:bg-red-500` was red at rest, `disabled:opacity-50` always dim,
`dark:` always on.

Read variant tokens from the components that follow the class token too,
sharing one reader with the nested path. A flattened compound the runtime
cannot observe (`disabled:` also emits `[aria-disabled="true"]`) is
dropped, matching what its empty nested rule compiled to before.

Regression test feeds both selector shapes straight to ProcessorBuilder,
so it does not depend on which Tailwind the repo pins. With
`@tailwindcss/node` at 4.3.3 the existing suite goes from 11 failures
(pressable, touchables, data-attributes, dir) to green.

* chore: bump tailwind dependencies to 4.3.3

Root catalog, @tailwindcss/node and @tailwindcss/oxide in the package, and
@tailwindcss/vite in the vite example. The repo now runs its own suite
against the flattened variant selectors that 4.3.3 emits.

* fix: handle flattened theme roots on web and skip unobservable compounds

Two follow-ups from review and CI on Tailwind 4.3.3.

Web: Tailwind now flattens `:root { &:where(.dark, .dark *) {} }` into a
sibling `:root:where(.dark, .dark *) {}` rule. The rule visitor only
rewrote nested theme variants into `.dark`, so the flattened form kept its
`:root` prefix and a scoped `.dark` class could not select it; the
`bg-background in dark theme` e2e test failed. Route a theme-layer `:root`
rule whose second token is `:where(.theme)` through the same rewrite.

Native: a selector mixing a supported variant with a token the runtime
cannot observe (`disabled:active:` emits `[aria-disabled="true"]:active`)
used to keep the branch gated on `:active` alone. Track unsupported tokens
in `readSelectorVariants` and skip the whole selector instead of applying
it under a weaker condition.
2026-09-04 07:58:05 +02:00
Hubert Bieszczad 9a5d57774d chore: remove PR blocking instruction 2026-09-03 08:47:40 +02:00
Hubert Bieszczad 62b3be7774 fix: drop frozen listeners (#660)
* fix: drop frozen listeners

* chore: return current snapshot in useCSSVariable

* chore: remove useSyncExternalStore
2026-09-02 11:41:49 +02:00
Hubert Bieszczad 9186a34091 ci: close pro issues on release with different message than oss (#659) 2026-09-02 10:35:45 +02:00
Hubert Bieszczad af5f834f0c fix: use useSyncExternalStore in withUniwind for better compatibility with react lifecycle (#657)
* fix: use useSyncExternalStore in withUniwind for better compatibility with react lifecycle

* test: extend freeze tests
2026-09-01 09:18:59 +02:00
Julius Marminge 0a053751f1 fix: skip unchanged native stylesheet reinitialization (#652) 2026-09-01 07:22:32 +02:00
Hubert Bieszczad deaef5676c fix: useSyncExternalStore in state hooks for better compatibility with react lifecycle (#650) 2026-08-28 09:50:05 +02:00
Hubert Bieszczad 7e4fb7d065 test: migrate web tests to vitest (#647) 2026-08-26 08:12:49 +02:00
Feri Irawan cb24851129 feat: support drop-shadow filter function (#645)
Add processDropShadow handler to compile Tailwind CSS v4 drop-shadow
filter utilities (drop-shadow-sm, drop-shadow-md, etc.) into React
Native compatible filter strings.

Supports preset sizes, arbitrary values, color modifiers, and
combined filters.
2026-08-26 07:57:25 +02:00
Hubert Bieszczad 280976a219 fix: web lazy components not hot reloading css (#646) 2026-08-24 10:07:30 +02:00
Hubert Bieszczad 0f8bdcd713 chore: fix tests typecheck (#637) 2026-08-20 09:17:52 +02:00
Joe Deleeuw 20b1d37a5b fix: handle symlinked uniwind origins in metro resolver (#609) 2026-08-19 14:54:14 +02:00
github-actions[bot] 4531f5169e chore: release v1.11.0 v1.11.0 2026-08-17 10:12:20 +00:00
Hubert Bieszczad 642c7d7b72 docs: update skill with ScopedVariables (#633)
* docs: update skill with ScopedVariables

* chore: update skill compatibility version
2026-08-17 11:45:04 +02:00
Hubert Bieszczad 8333993561 chore: remove filterFn and create string directly (#632) 2026-08-14 15:11:22 +02:00
Jacek Pudysz 4896be8d80 feat: add filter support on iOS and React Native 0.87 canary (#631)
* feat: add filter support on iOS and React Native canary

* chore: use set instead of array

---------

Co-authored-by: Hubert Bieszczad <brentlokk@gmail.com>
2026-08-14 12:05:25 +02:00
Hubert Bieszczad d0ad34689e chore: dont pass dataSet if none data-* were provided to withUniwind component (#630) 2026-08-13 11:32:37 +02:00
Jacek Pudysz 7611bf049e chore: update color scheme handling for React Native 0.87 compatibility (#628) 2026-08-12 17:26:37 +02:00
Hubert Bieszczad a37d8800bc chore: resolve dataSet to undefined when to data-set prop was provided (#629) 2026-08-12 14:02:00 +02:00
Jacek Pudysz 005b94ffe1 fix: align uniwind types with latest react native 0.87 (#627) 2026-08-12 12:20:47 +02:00
Hubert Bieszczad 54260e3f8d chore: typecheck tests (#626)
* chore: typecheck tests

* chore: add to ci
2026-08-12 07:49:43 +02:00
Dima Lebedynskyi b8f5d8c66c feat: scoped variables (#611)
* feat: add ScopedVariables component for per-subtree CSS variable overrides

* feat: add opt-in cacheKey to ScopedVariables for native style caching

* docs(expo-example): add ScopedVariables demo

Demonstrate per-subtree CSS variable overrides in the expo example app:
theme default, scoped override, nested inheritance (nearest wins), and the
opt-in cacheKey. Adds --color-primary/--color-surface/--gap theme defaults so
the unscoped baseline renders intentionally.

* fix(ScopedVariables): apply scoped variables to the web DOM cascade

On web, Uniwind passes classes through RNW unchanged, so real elements
resolve `var(--name)` from the live CSS cascade. The wrapper only applied
its variables to the hidden dummyParent used for JS reads, so scoped
overrides never reached descendants — styling stayed at the theme default
while useCSSVariable readouts (which use the dummyParent path) looked
correct. Set the variables as inline custom properties on the
display:contents wrapper so they cascade to children (numbers -> px).

Add web regression tests asserting the wrapper carries the overrides
inline, nested wrappers only declare their own overrides, and invalid
keys are dropped. Rework the expo-example demo with origin pills
(default/set here/inherited), swatches, and a gap strip so the
override/inherit story is legible.

* fix(ScopedVariables): address review feedback on PR #611

- useCSSVariable: recompute on context change, not only on global
  Theme/Variables events — an updated <ScopedVariables> variables prop
  (or a nearer provider) now surfaces the new value. Adds web + native
  regression tests for a prop update.
- utils: always drop non-`--` keys (not just in dev), gating only the
  Logger.error behind __DEV__, so invalid keys can't reach the web read
  helper and corrupt a resolved inheritable property in production.
- getWebStyles/getWebVariable: wrap the scoped-variable read in
  try/finally so the temporary custom properties are always cleared,
  even if a DOM read throws.
- Document the variables prop stability contract (define outside render
  or useMemo) in JSDoc.
- Remove two unused @ts-expect-error directives in tests.
- Reword the demo's cacheKey section so it no longer claims parity with
  section 2.

* refactor(ScopedVariables): address maintainer review on PR #611

- Derive the native style cache key from the merged variables map instead
  of a user-supplied cacheKey prop; removes the cache-bypass path and the
  stale-key footgun
- Drop the display: contents View wrapper on native, render the bare
  provider like ScopedTheme.native
- Remove the expo-example demo (playground only, covered by tests)
- useCSSVariable: skip the mount-time recompute, useState already
  resolved the initial value
- Extract toWebValue (number -> px) web util, reuse in config,
  getWebStyles and the web wrapper
- Remove the ScopedVariables prop type test
- Trim long comments to match repo style

* fix(ScopedVariables): use JSON.stringify for the derived cache key

The key:value; concatenation had no escaping, so values containing
separators could collide ({'--a': '1;--b:2'} vs {'--a': '1', '--b': '2'})
and serve wrong cached styles.

* chore: general corrections

* chore: stream ui precommit

* chore: more improvements

* feat: add ScopedVariables component for per-subtree CSS variable overrides

* feat: add opt-in cacheKey to ScopedVariables for native style caching

* docs(expo-example): add ScopedVariables demo

Demonstrate per-subtree CSS variable overrides in the expo example app:
theme default, scoped override, nested inheritance (nearest wins), and the
opt-in cacheKey. Adds --color-primary/--color-surface/--gap theme defaults so
the unscoped baseline renders intentionally.

* fix(ScopedVariables): apply scoped variables to the web DOM cascade

On web, Uniwind passes classes through RNW unchanged, so real elements
resolve `var(--name)` from the live CSS cascade. The wrapper only applied
its variables to the hidden dummyParent used for JS reads, so scoped
overrides never reached descendants — styling stayed at the theme default
while useCSSVariable readouts (which use the dummyParent path) looked
correct. Set the variables as inline custom properties on the
display:contents wrapper so they cascade to children (numbers -> px).

Add web regression tests asserting the wrapper carries the overrides
inline, nested wrappers only declare their own overrides, and invalid
keys are dropped. Rework the expo-example demo with origin pills
(default/set here/inherited), swatches, and a gap strip so the
override/inherit story is legible.

* fix(ScopedVariables): address review feedback on PR #611

- useCSSVariable: recompute on context change, not only on global
  Theme/Variables events — an updated <ScopedVariables> variables prop
  (or a nearer provider) now surfaces the new value. Adds web + native
  regression tests for a prop update.
- utils: always drop non-`--` keys (not just in dev), gating only the
  Logger.error behind __DEV__, so invalid keys can't reach the web read
  helper and corrupt a resolved inheritable property in production.
- getWebStyles/getWebVariable: wrap the scoped-variable read in
  try/finally so the temporary custom properties are always cleared,
  even if a DOM read throws.
- Document the variables prop stability contract (define outside render
  or useMemo) in JSDoc.
- Remove two unused @ts-expect-error directives in tests.
- Reword the demo's cacheKey section so it no longer claims parity with
  section 2.

* refactor(ScopedVariables): address maintainer review on PR #611

- Derive the native style cache key from the merged variables map instead
  of a user-supplied cacheKey prop; removes the cache-bypass path and the
  stale-key footgun
- Drop the display: contents View wrapper on native, render the bare
  provider like ScopedTheme.native
- Remove the expo-example demo (playground only, covered by tests)
- useCSSVariable: skip the mount-time recompute, useState already
  resolved the initial value
- Extract toWebValue (number -> px) web util, reuse in config,
  getWebStyles and the web wrapper
- Remove the ScopedVariables prop type test
- Trim long comments to match repo style

* fix(ScopedVariables): use JSON.stringify for the derived cache key

The key:value; concatenation had no escaping, so values containing
separators could collide ({'--a': '1;--b:2'} vs {'--a': '1', '--b': '2'})
and serve wrong cached styles.

* chore: general corrections

* chore: stream ui precommit

* chore: more improvements

* chore: remove unused from test

---------

Co-authored-by: Dima Lebedynskyi <dimalebe@amazon.com>
Co-authored-by: Hubert Bieszczad <brentlokk@gmail.com>
2026-08-11 13:17:20 +02:00
Hubert Bieszczad 4e63803cef fix: web rn bundling by adding browser exports field (#624)
* fix: web rn bundling by adding browser exports field

* chore: reorder exports
2026-08-10 08:20:55 +02:00
github-actions[bot] 4614d75a11 chore: release v1.10.1 v1.10.1 2026-08-03 10:48:40 +00:00
Hubert Bieszczad 2ea1b53a8b fix: withUniwind remove className props on web after converting them (#615)
* fix: withUniwind remove className props on web after converting them

* chore: rename to testClassNamne

* chore: fixes
2026-07-27 14:08:31 +02:00
Hubert Bieszczad 6cce440432 fix: handle multiline classes (#610) 2026-07-21 12:28:21 +02:00
Hubert Bieszczad 3f971f1134 ci: fix validate issue 2026-07-17 16:11:17 +02:00
Hubert Bieszczad 5e8e2d5d98 ci: fix validate issue (#603) 2026-07-17 16:08:38 +02:00
Hubert Bieszczad 48cb66dcdf ci: verify if issue template has been used (#600) 2026-07-17 15:47:50 +02:00
Florian Lefebvre d84b3b149d fix: initialize theme from html root when available (#599) 2026-07-17 15:08:59 +02:00
Hubert Bieszczad 245f9af2c9 fix: vite8 not prebundling react native web (#596) 2026-07-14 07:48:58 +02:00
Anthony Mittaz 2afcc062d1 fix(metro): defer transform worker resolution for non-expo projects (#593)
* fix(metro): defer transform worker resolution for non-expo projects

* fix(metro): harden transform worker selection

* refactor(metro): simplify Expo worker configuration
2026-07-13 14:19:55 +02:00
Alex Hunt f568fdde25 fix: Remove reference to Touchable in package types (#592) 2026-07-07 20:39:01 +02:00
Hubert Bieszczad 6b498f2ada chore: update to expo 57 (#591)
* chore: update to expo 57

* chore: bump tailwind
2026-07-02 09:08:41 +02:00
Hubert Bieszczad a9cfacd30c ci: close issues on release (#590)
* ci: close issues on release

* chore: add error logging in release for closing issues
2026-07-02 07:38:48 +02:00
github-actions[bot] 22a6f67386 chore: release v1.10.0 v1.10.0 2026-07-01 13:19:09 +00:00
Hubert Bieszczad 1ac7b74c0d docs: update agents.md 2026-06-26 14:58:00 +02:00
Hubert Bieszczad 959fc89a5c feat: support rtl safe area classes (#589) 2026-06-26 12:17:27 +02:00
Hubert Bieszczad a39405147e feat: support min() css function (#588) 2026-06-26 10:39:58 +02:00
Hubert Bieszczad d7f3bd23e4 fix: important with state specificity (#585) 2026-06-23 12:51:52 +02:00
Hubert Bieszczad af3e7bf311 docs: split uniwind skill (#583)
* docs: split uniwind skill

* docs: update references in troubleshooting
2026-06-17 13:53:14 +02:00
github-actions[bot] f23e849c4a chore: release v1.9.0 v1.9.0 2026-06-11 09:50:33 +00:00
Hubert Bieszczad 6556203d50 fix: update web variant condition (#580) 2026-06-11 11:10:13 +02:00
Hubert Bieszczad ceb276d105 feat: layout direction component (#577)
* feat: layout direction component

* chore: use parent context if rtl is not provided

* docs: update skill with LayoutDirection
2026-06-10 16:03:18 +02:00
Hubert Bieszczad 0a503732b2 docs: add agents.md (#575) 2026-06-10 12:08:32 +02:00
Hubert Bieszczad 3091d35054 feat: inline rtl support (#574)
* feat: inline rtl support

* chore: exclude inherit dir
2026-06-10 11:34:41 +02:00
Hubert Bieszczad 86e0048d53 fix: bundler infinite loop when multiple uniwind instances are installed (#570)
fixes #353
2026-06-09 14:43:16 +02:00
Hubert Bieszczad 433cb71047 fix: combined variants overriding each other (#567)
* fix: combined variants overriding each other

* test: add more tests for combined variants
2026-06-08 08:21:19 +02:00
github-actions[bot] ec328ef6c4 chore: release v1.8.0 v1.8.0 2026-06-03 10:24:55 +00:00