rnwind 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/core/parser/color.cjs +33 -1
- package/lib/cjs/core/parser/color.cjs.map +1 -1
- package/lib/cjs/core/parser/color.d.ts +10 -0
- package/lib/cjs/core/parser/declaration.cjs +121 -9
- package/lib/cjs/core/parser/declaration.cjs.map +1 -1
- package/lib/cjs/core/parser/gradient.cjs +46 -12
- package/lib/cjs/core/parser/gradient.cjs.map +1 -1
- package/lib/cjs/core/parser/gradient.d.ts +2 -1
- package/lib/cjs/core/parser/keyframes.cjs +27 -12
- package/lib/cjs/core/parser/keyframes.cjs.map +1 -1
- package/lib/cjs/core/parser/keyframes.d.ts +11 -0
- package/lib/cjs/core/parser/layout-dispatcher.cjs +33 -10
- package/lib/cjs/core/parser/layout-dispatcher.cjs.map +1 -1
- package/lib/cjs/core/parser/length.cjs +17 -1
- package/lib/cjs/core/parser/length.cjs.map +1 -1
- package/lib/cjs/core/parser/safe-area.cjs +24 -3
- package/lib/cjs/core/parser/safe-area.cjs.map +1 -1
- package/lib/cjs/core/parser/theme-vars.cjs +58 -8
- package/lib/cjs/core/parser/theme-vars.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.cjs +77 -9
- package/lib/cjs/core/parser/tokens.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.d.ts +9 -0
- package/lib/cjs/core/parser/transform.cjs +18 -9
- package/lib/cjs/core/parser/transform.cjs.map +1 -1
- package/lib/cjs/core/parser/tw-parser.cjs +136 -34
- package/lib/cjs/core/parser/tw-parser.cjs.map +1 -1
- package/lib/cjs/core/parser/tw-parser.d.ts +20 -0
- package/lib/cjs/core/parser/typography-dispatcher.cjs +19 -1
- package/lib/cjs/core/parser/typography-dispatcher.cjs.map +1 -1
- package/lib/cjs/core/parser/typography.cjs +15 -18
- package/lib/cjs/core/parser/typography.cjs.map +1 -1
- package/lib/cjs/core/parser/typography.d.ts +5 -5
- package/lib/cjs/core/style-builder/build-style.cjs +12 -3
- package/lib/cjs/core/style-builder/build-style.cjs.map +1 -1
- package/lib/cjs/core/style-builder/build-style.d.ts +3 -1
- package/lib/cjs/core/style-builder/union-builder.cjs +9 -11
- package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -1
- package/lib/cjs/core/style-builder/union-builder.d.ts +7 -8
- package/lib/cjs/metro/dts.cjs +6 -1
- package/lib/cjs/metro/dts.cjs.map +1 -1
- package/lib/cjs/metro/transformer.cjs +42 -77
- package/lib/cjs/metro/transformer.cjs.map +1 -1
- package/lib/cjs/metro/with-config.cjs +9 -29
- package/lib/cjs/metro/with-config.cjs.map +1 -1
- package/lib/cjs/runtime/hooks/use-scheme.cjs +17 -11
- package/lib/cjs/runtime/hooks/use-scheme.cjs.map +1 -1
- package/lib/cjs/runtime/hooks/use-scheme.d.ts +7 -4
- package/lib/cjs/runtime/index.cjs +2 -1
- package/lib/cjs/runtime/index.cjs.map +1 -1
- package/lib/cjs/runtime/index.d.ts +2 -2
- package/lib/cjs/runtime/lookup-css.cjs +41 -0
- package/lib/cjs/runtime/lookup-css.cjs.map +1 -1
- package/lib/cjs/runtime/lookup-css.d.ts +29 -0
- package/lib/cjs/runtime/resolve.cjs +8 -6
- package/lib/cjs/runtime/resolve.cjs.map +1 -1
- package/lib/cjs/runtime/wrap.cjs +50 -57
- package/lib/cjs/runtime/wrap.cjs.map +1 -1
- package/lib/cjs/runtime/wrap.d.ts +10 -4
- package/lib/cjs/testing/index.cjs +1 -1
- package/lib/cjs/testing/index.cjs.map +1 -1
- package/lib/esm/core/parser/color.d.ts +10 -0
- package/lib/esm/core/parser/color.mjs +34 -3
- package/lib/esm/core/parser/color.mjs.map +1 -1
- package/lib/esm/core/parser/declaration.mjs +122 -10
- package/lib/esm/core/parser/declaration.mjs.map +1 -1
- package/lib/esm/core/parser/gradient.d.ts +2 -1
- package/lib/esm/core/parser/gradient.mjs +45 -11
- package/lib/esm/core/parser/gradient.mjs.map +1 -1
- package/lib/esm/core/parser/keyframes.d.ts +11 -0
- package/lib/esm/core/parser/keyframes.mjs +27 -12
- package/lib/esm/core/parser/keyframes.mjs.map +1 -1
- package/lib/esm/core/parser/layout-dispatcher.mjs +33 -10
- package/lib/esm/core/parser/layout-dispatcher.mjs.map +1 -1
- package/lib/esm/core/parser/length.mjs +17 -1
- package/lib/esm/core/parser/length.mjs.map +1 -1
- package/lib/esm/core/parser/safe-area.mjs +24 -3
- package/lib/esm/core/parser/safe-area.mjs.map +1 -1
- package/lib/esm/core/parser/theme-vars.mjs +58 -8
- package/lib/esm/core/parser/theme-vars.mjs.map +1 -1
- package/lib/esm/core/parser/tokens.d.ts +9 -0
- package/lib/esm/core/parser/tokens.mjs +77 -10
- package/lib/esm/core/parser/tokens.mjs.map +1 -1
- package/lib/esm/core/parser/transform.mjs +18 -9
- package/lib/esm/core/parser/transform.mjs.map +1 -1
- package/lib/esm/core/parser/tw-parser.d.ts +20 -0
- package/lib/esm/core/parser/tw-parser.mjs +138 -36
- package/lib/esm/core/parser/tw-parser.mjs.map +1 -1
- package/lib/esm/core/parser/typography-dispatcher.mjs +19 -1
- package/lib/esm/core/parser/typography-dispatcher.mjs.map +1 -1
- package/lib/esm/core/parser/typography.d.ts +5 -5
- package/lib/esm/core/parser/typography.mjs +15 -18
- package/lib/esm/core/parser/typography.mjs.map +1 -1
- package/lib/esm/core/style-builder/build-style.d.ts +3 -1
- package/lib/esm/core/style-builder/build-style.mjs +12 -3
- package/lib/esm/core/style-builder/build-style.mjs.map +1 -1
- package/lib/esm/core/style-builder/union-builder.d.ts +7 -8
- package/lib/esm/core/style-builder/union-builder.mjs +9 -11
- package/lib/esm/core/style-builder/union-builder.mjs.map +1 -1
- package/lib/esm/metro/dts.mjs +6 -1
- package/lib/esm/metro/dts.mjs.map +1 -1
- package/lib/esm/metro/transformer.mjs +42 -77
- package/lib/esm/metro/transformer.mjs.map +1 -1
- package/lib/esm/metro/with-config.mjs +10 -30
- package/lib/esm/metro/with-config.mjs.map +1 -1
- package/lib/esm/runtime/hooks/use-scheme.d.ts +7 -4
- package/lib/esm/runtime/hooks/use-scheme.mjs +17 -11
- package/lib/esm/runtime/hooks/use-scheme.mjs.map +1 -1
- package/lib/esm/runtime/index.d.ts +2 -2
- package/lib/esm/runtime/index.mjs +2 -2
- package/lib/esm/runtime/index.mjs.map +1 -1
- package/lib/esm/runtime/lookup-css.d.ts +29 -0
- package/lib/esm/runtime/lookup-css.mjs +39 -1
- package/lib/esm/runtime/lookup-css.mjs.map +1 -1
- package/lib/esm/runtime/resolve.mjs +9 -7
- package/lib/esm/runtime/resolve.mjs.map +1 -1
- package/lib/esm/runtime/wrap.d.ts +10 -4
- package/lib/esm/runtime/wrap.mjs +50 -57
- package/lib/esm/runtime/wrap.mjs.map +1 -1
- package/lib/esm/testing/index.mjs +2 -2
- package/lib/esm/testing/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/parser/color.ts +32 -1
- package/src/core/parser/declaration.ts +119 -10
- package/src/core/parser/gradient.ts +48 -11
- package/src/core/parser/keyframes.ts +31 -3
- package/src/core/parser/layout-dispatcher.ts +32 -9
- package/src/core/parser/length.ts +18 -1
- package/src/core/parser/safe-area.ts +23 -2
- package/src/core/parser/theme-vars.ts +75 -8
- package/src/core/parser/tokens.ts +76 -9
- package/src/core/parser/transform.ts +19 -8
- package/src/core/parser/tw-parser.ts +148 -31
- package/src/core/parser/typography-dispatcher.ts +20 -1
- package/src/core/parser/typography.ts +15 -15
- package/src/core/style-builder/build-style.ts +12 -1
- package/src/core/style-builder/union-builder.ts +10 -12
- package/src/metro/dts.ts +6 -1
- package/src/metro/transformer.ts +42 -78
- package/src/metro/with-config.ts +10 -29
- package/src/runtime/hooks/use-scheme.ts +17 -10
- package/src/runtime/index.ts +2 -1
- package/src/runtime/lookup-css.ts +42 -0
- package/src/runtime/resolve.ts +9 -7
- package/src/runtime/wrap.tsx +57 -61
- package/src/testing/index.ts +3 -0
|
@@ -12,6 +12,7 @@ var property = require('./property.cjs');
|
|
|
12
12
|
var selector = require('./selector.cjs');
|
|
13
13
|
var themeVars = require('./theme-vars.cjs');
|
|
14
14
|
var tokens = require('./tokens.cjs');
|
|
15
|
+
var color = require('./color.cjs');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Default LightningCSS transform options for TailwindParser's visitor.
|
|
@@ -147,6 +148,33 @@ class TailwindParser {
|
|
|
147
148
|
merged.set(k, v);
|
|
148
149
|
return merged;
|
|
149
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Build the per-scheme theme token tables for `registerThemeTokens` —
|
|
153
|
+
* the data source for `useColor` / `useToken` / `useSize`. Emits one table
|
|
154
|
+
* per scheme the user wrote tokens under (`base` + each variant block /
|
|
155
|
+
* `.dark` override). `--color-*` values are lowered to sRGB (matching the
|
|
156
|
+
* className path) using `resolver` so a wide-gamut or `var()`-referencing
|
|
157
|
+
* token resolves to an RN-renderable string; other tokens pass through.
|
|
158
|
+
* @param resolver Full compiled `:root` table, for resolving `var()` refs.
|
|
159
|
+
* @returns Scheme → (token name → value) map.
|
|
160
|
+
*/
|
|
161
|
+
buildThemeTokens(resolver) {
|
|
162
|
+
const out = {};
|
|
163
|
+
for (const scheme of this.themeSchemes.keys()) {
|
|
164
|
+
const userTable = this.themeSchemes.get(scheme);
|
|
165
|
+
if (!userTable || userTable.size === 0)
|
|
166
|
+
continue;
|
|
167
|
+
const schemeResolver = new Map(resolver);
|
|
168
|
+
for (const [k, v] of this.effectiveVars(scheme))
|
|
169
|
+
schemeResolver.set(k, v);
|
|
170
|
+
const table = {};
|
|
171
|
+
for (const [name, raw] of userTable) {
|
|
172
|
+
table[name] = name.startsWith('--color-') ? lowerColorToken(raw, schemeResolver) : raw;
|
|
173
|
+
}
|
|
174
|
+
out[scheme] = table;
|
|
175
|
+
}
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
150
178
|
/**
|
|
151
179
|
* Build the Tailwind compiler on first use and cache it. The theme CSS
|
|
152
180
|
* gets a `theme(inline)` modifier on its `@import 'tailwindcss'` so
|
|
@@ -283,7 +311,8 @@ class TailwindParser {
|
|
|
283
311
|
// surface their role + resolved colour so the transformer
|
|
284
312
|
// can rewrite `<LinearGradient className="...">` into
|
|
285
313
|
// `colors={...}` / `start={...}` / `end={...}` props.
|
|
286
|
-
const
|
|
314
|
+
const gradientTable = schemeTables.get(themeVars.BASE_SCHEME) ?? schemeTables.get(schemes[0] ?? themeVars.BASE_SCHEME);
|
|
315
|
+
const gradient$1 = gradient.detectGradientAtom(rule.value.declarations.declarations, gradientTable);
|
|
287
316
|
if (gradient$1)
|
|
288
317
|
gradientAtoms.set(className, gradient$1);
|
|
289
318
|
// Haptics may live on the rule directly OR inside a
|
|
@@ -304,8 +333,8 @@ class TailwindParser {
|
|
|
304
333
|
const steps = [];
|
|
305
334
|
const baseTable = schemeTables.get(themeVars.BASE_SCHEME) ?? schemeTables.get(schemes[0] ?? themeVars.BASE_SCHEME);
|
|
306
335
|
for (const frame of rule.value.keyframes) {
|
|
307
|
-
const
|
|
308
|
-
if (
|
|
336
|
+
const offsets = keyframes.keyframeSelectorOffsets(frame.selectors);
|
|
337
|
+
if (offsets.length === 0)
|
|
309
338
|
continue;
|
|
310
339
|
const style = {};
|
|
311
340
|
const frameDecls = frame.declarations.declarations ?? [];
|
|
@@ -313,7 +342,10 @@ class TailwindParser {
|
|
|
313
342
|
for (const [key, value] of declaration.declarationToRnEntries(decl, baseTable))
|
|
314
343
|
style[key] = value;
|
|
315
344
|
}
|
|
316
|
-
|
|
345
|
+
// One frame can carry several offsets (`0%, 100% { … }`); emit a
|
|
346
|
+
// step for each so the terminal frame isn't lost.
|
|
347
|
+
for (const offset of offsets)
|
|
348
|
+
steps.push({ offset, style });
|
|
317
349
|
}
|
|
318
350
|
keyframes$1.set(name, { name, steps });
|
|
319
351
|
},
|
|
@@ -334,9 +366,23 @@ class TailwindParser {
|
|
|
334
366
|
if (!referencedKeyframes.has(name))
|
|
335
367
|
keyframes$1.delete(name);
|
|
336
368
|
}
|
|
337
|
-
|
|
369
|
+
const themeTokens = this.buildThemeTokens(compiledTheme);
|
|
370
|
+
return { atoms, keyframes: keyframes$1, propertyDefaults, gradientAtoms, hapticAtoms, candidates: [...candidates], schemes, breakpoints, themeTokens };
|
|
338
371
|
}
|
|
339
372
|
}
|
|
373
|
+
/**
|
|
374
|
+
* Lower a `--color-*` token value to an RN-renderable sRGB string, matching
|
|
375
|
+
* the className path: resolve any `var()` ref via `resolver`, then lower a
|
|
376
|
+
* wide-gamut form (`oklch(…)`, `lab(…)`, `color(p3 …)`) to sRGB. Hex / rgb /
|
|
377
|
+
* named colors pass through unchanged.
|
|
378
|
+
* @param raw Raw token value.
|
|
379
|
+
* @param resolver Var name → value table for resolving `var()` references.
|
|
380
|
+
* @returns RN-safe color string.
|
|
381
|
+
*/
|
|
382
|
+
function lowerColorToken(raw, resolver) {
|
|
383
|
+
const substituted = tokens.substituteThemeVars(raw, resolver);
|
|
384
|
+
return color.normalizeColorString(substituted) ?? substituted;
|
|
385
|
+
}
|
|
340
386
|
/**
|
|
341
387
|
* Wrap an error from `@tailwindcss/node`'s compiler or `lightningcss`'s
|
|
342
388
|
* transform with a `rnwind:` prefix so the user sees a clear "this came
|
|
@@ -383,6 +429,7 @@ function emptyOutput() {
|
|
|
383
429
|
candidates: [],
|
|
384
430
|
schemes: [themeVars.BASE_SCHEME],
|
|
385
431
|
breakpoints: new Map(),
|
|
432
|
+
themeTokens: {},
|
|
386
433
|
};
|
|
387
434
|
}
|
|
388
435
|
/**
|
|
@@ -454,8 +501,8 @@ function processStyleRule(declarations, className, ctx, nestedRules = []) {
|
|
|
454
501
|
ctx.referencedKeyframes.add(animationRef);
|
|
455
502
|
}
|
|
456
503
|
applyComposedTransform(bucket, ctx.schemes, ruleLocalVars);
|
|
457
|
-
applyComposedShadow(bucket, ctx.schemes, ruleLocalVars);
|
|
458
|
-
applyComposedRing(bucket, ctx.schemes, ruleLocalVars);
|
|
504
|
+
applyComposedShadow(bucket, ctx.schemes, ruleLocalVars, ruleSchemeTables);
|
|
505
|
+
applyComposedRing(bucket, ctx.schemes, ruleLocalVars, ruleSchemeTables);
|
|
459
506
|
// Phase 2: nested rules — three orthogonal flavours, dispatched on
|
|
460
507
|
// the lightningcss node `type`:
|
|
461
508
|
// - `media`: Tailwind v4 responsive variants (`sm:`, `md:`, …) wrap
|
|
@@ -600,7 +647,7 @@ function applyMediaRule(nested, className, bucket, ctx, ruleSchemeTables, ruleLo
|
|
|
600
647
|
for (const [k, v] of collectRuleLocalVars(decls))
|
|
601
648
|
nestedLocalVars.set(k, v);
|
|
602
649
|
applyComposedTransformToScheme(schemeBucket, nestedLocalVars);
|
|
603
|
-
applyComposedShadowToScheme(schemeBucket, nestedLocalVars);
|
|
650
|
+
applyComposedShadowToScheme(schemeBucket, nestedLocalVars, table);
|
|
604
651
|
bucket[scheme] = schemeBucket;
|
|
605
652
|
}
|
|
606
653
|
}
|
|
@@ -637,7 +684,7 @@ function applyInteractiveNestedRule(nested, bucket, ctx, ruleSchemeTables, ruleL
|
|
|
637
684
|
for (const [k, v] of collectRuleLocalVars(decls))
|
|
638
685
|
nestedLocalVars.set(k, v);
|
|
639
686
|
applyComposedTransformToScheme(schemeBucket, nestedLocalVars);
|
|
640
|
-
applyComposedShadowToScheme(schemeBucket, nestedLocalVars);
|
|
687
|
+
applyComposedShadowToScheme(schemeBucket, nestedLocalVars, table);
|
|
641
688
|
bucket[scheme] = schemeBucket;
|
|
642
689
|
}
|
|
643
690
|
}
|
|
@@ -703,7 +750,7 @@ function applyNestedSchemeRule(nested, bucket, ctx, ruleSchemeTables, ruleLocalV
|
|
|
703
750
|
for (const [k, v] of collectRuleLocalVars(innerDecls))
|
|
704
751
|
nestedLocalVars.set(k, v);
|
|
705
752
|
applyComposedTransformToScheme(schemeBucket, nestedLocalVars);
|
|
706
|
-
applyComposedShadowToScheme(schemeBucket, nestedLocalVars);
|
|
753
|
+
applyComposedShadowToScheme(schemeBucket, nestedLocalVars, table);
|
|
707
754
|
bucket[targetScheme] = schemeBucket;
|
|
708
755
|
}
|
|
709
756
|
/**
|
|
@@ -804,12 +851,13 @@ function applyComposedTransformToScheme(style, ruleLocalVars) {
|
|
|
804
851
|
* prop.
|
|
805
852
|
* @param style Scheme-specific style map.
|
|
806
853
|
* @param ruleLocalVars Combined outer+nested `--tw-*` vars.
|
|
854
|
+
* @param table Per-scheme var table for resolving `var(--color-x)` in colors.
|
|
807
855
|
*/
|
|
808
|
-
function applyComposedShadowToScheme(style, ruleLocalVars) {
|
|
856
|
+
function applyComposedShadowToScheme(style, ruleLocalVars, table) {
|
|
809
857
|
const rawShadow = ruleLocalVars.get('--tw-shadow');
|
|
810
858
|
const rawShadowColor = ruleLocalVars.get('--tw-shadow-color');
|
|
811
859
|
if (!rawShadow && rawShadowColor) {
|
|
812
|
-
const color = resolveCustomColorString(rawShadowColor);
|
|
860
|
+
const color = resolveCustomColorString(rawShadowColor, table);
|
|
813
861
|
if (!color)
|
|
814
862
|
return;
|
|
815
863
|
delete style.boxShadow;
|
|
@@ -838,8 +886,9 @@ function applyComposedShadowToScheme(style, ruleLocalVars) {
|
|
|
838
886
|
* @param bucket Per-scheme style map for the atom.
|
|
839
887
|
* @param schemes Scheme names active for this parse.
|
|
840
888
|
* @param ruleLocalVars Rule-local `--tw-*` vars.
|
|
889
|
+
* @param schemeTables Per-scheme var tables for resolving `var(--color-x)`.
|
|
841
890
|
*/
|
|
842
|
-
function applyComposedShadow(bucket, schemes, ruleLocalVars) {
|
|
891
|
+
function applyComposedShadow(bucket, schemes, ruleLocalVars, schemeTables) {
|
|
843
892
|
const rawShadow = ruleLocalVars.get('--tw-shadow');
|
|
844
893
|
const rawShadowColor = ruleLocalVars.get('--tw-shadow-color');
|
|
845
894
|
// Color-only utility (`shadow-red-50`, `shadow-gray-200`, …): emit
|
|
@@ -848,10 +897,11 @@ function applyComposedShadow(bucket, schemes, ruleLocalVars) {
|
|
|
848
897
|
// where setting `--tw-shadow-color` swaps in a solid color). Offset /
|
|
849
898
|
// blur / elevation come from the partner size utility's atom.
|
|
850
899
|
if (!rawShadow && rawShadowColor) {
|
|
851
|
-
const color = resolveCustomColorString(rawShadowColor);
|
|
852
|
-
if (!color)
|
|
853
|
-
return;
|
|
854
900
|
for (const scheme of schemes) {
|
|
901
|
+
// Resolve per scheme — a custom token may differ between light/dark.
|
|
902
|
+
const color = resolveCustomColorString(rawShadowColor, schemeTables.get(scheme));
|
|
903
|
+
if (!color)
|
|
904
|
+
continue;
|
|
855
905
|
const style = bucket[scheme] ?? {};
|
|
856
906
|
delete style.boxShadow;
|
|
857
907
|
style.shadowColor = color;
|
|
@@ -884,35 +934,62 @@ function applyComposedShadow(bucket, schemes, ruleLocalVars) {
|
|
|
884
934
|
* @param bucket Per-scheme style map for the atom.
|
|
885
935
|
* @param schemes Scheme names active for this parse.
|
|
886
936
|
* @param ruleLocalVars Rule-local `--tw-*` vars.
|
|
937
|
+
* @param schemeTables Per-scheme var tables for resolving `var(--color-x)`.
|
|
887
938
|
*/
|
|
888
|
-
function applyComposedRing(bucket, schemes, ruleLocalVars) {
|
|
939
|
+
function applyComposedRing(bucket, schemes, ruleLocalVars, schemeTables) {
|
|
889
940
|
const ringColor = ruleLocalVars.get('--tw-ring-color');
|
|
890
941
|
if (!ringColor)
|
|
891
942
|
return;
|
|
892
|
-
const color = resolveCustomColorString(ringColor);
|
|
893
|
-
if (!color)
|
|
894
|
-
return;
|
|
895
943
|
for (const scheme of schemes) {
|
|
944
|
+
// Resolve per scheme — a custom token may differ between light/dark.
|
|
945
|
+
const color = resolveCustomColorString(ringColor, schemeTables.get(scheme));
|
|
946
|
+
if (!color)
|
|
947
|
+
continue;
|
|
896
948
|
const style = bucket[scheme] ?? {};
|
|
897
949
|
if (!('borderColor' in style))
|
|
898
950
|
style.borderColor = color;
|
|
899
951
|
bucket[scheme] = style;
|
|
900
952
|
}
|
|
901
953
|
}
|
|
954
|
+
/**
|
|
955
|
+
* Tailwind composable shadow/inset-shadow alpha defaults. Their `100%` lives
|
|
956
|
+
* in an `@property` initial-value (not the rule's local vars), so after the
|
|
957
|
+
* `@supports` color-mix is unwrapped, `var(--tw-shadow-alpha)` is left dangling
|
|
958
|
+
* and the shadow color fails to resolve. Seed the default; a `/<opacity>`
|
|
959
|
+
* modifier still wins because the in-rule table value overrides it.
|
|
960
|
+
*/
|
|
961
|
+
const COMPOSABLE_ALPHA_DEFAULTS = new Map([
|
|
962
|
+
['--tw-shadow-alpha', '100%'],
|
|
963
|
+
['--tw-inset-shadow-alpha', '100%'],
|
|
964
|
+
]);
|
|
902
965
|
/**
|
|
903
966
|
* Resolve a CSS color string (`oklch(0.971 0.013 17.38)`, `#ff0000`,
|
|
904
967
|
* `rgb(0 0 0 / 0.1)`) to the hex string RN's `shadowColor` accepts.
|
|
905
968
|
* Wraps culori's parser via {@link parseCssColorToHex}.
|
|
906
|
-
*
|
|
969
|
+
*
|
|
970
|
+
* Custom `@theme` color tokens arrive as `var(--color-x)` (only the default
|
|
971
|
+
* palette is `theme(inline)`-d), so `table` is substituted FIRST — without it
|
|
972
|
+
* `shadow-<token>` / `ring-<token>` silently drop the color (culori can't
|
|
973
|
+
* parse a bare `var()`). The table is per-scheme so a token that differs
|
|
974
|
+
* between light/dark resolves to the right value for each.
|
|
975
|
+
* @param raw Raw color text from a `--tw-shadow-color` / `--tw-ring-color` prop.
|
|
976
|
+
* @param table Per-scheme var table for resolving `var(--color-x)` references.
|
|
907
977
|
* @returns `#rrggbb` string, or null when culori can't parse it.
|
|
908
978
|
*/
|
|
909
|
-
function resolveCustomColorString(raw) {
|
|
910
|
-
const
|
|
911
|
-
|
|
979
|
+
function resolveCustomColorString(raw, table) {
|
|
980
|
+
const seeded = new Map([...COMPOSABLE_ALPHA_DEFAULTS, ...(table ?? [])]);
|
|
981
|
+
const substituted = tokens.substituteThemeVars(raw, seeded);
|
|
982
|
+
// `coerceUnparsedValue` collapses Tailwind's opacity shape
|
|
983
|
+
// `color-mix(in oklab, <color> <pct>%, transparent)` (emitted by
|
|
984
|
+
// `shadow-<token>` / `ring-<token>`) to a flat rgba/hex and unwraps
|
|
985
|
+
// `var(…, fallback)`. Modern spaces (`oklch(…)`) then lower via
|
|
986
|
+
// `normalizeColorString`; anything still un-RN-safe falls to culori.
|
|
987
|
+
const coerced = tokens.coerceUnparsedValue(unwrapVariableFallback(substituted).trim());
|
|
988
|
+
if (typeof coerced !== 'string' || coerced.length === 0 || coerced.startsWith('var('))
|
|
912
989
|
return null;
|
|
913
|
-
if (
|
|
914
|
-
return
|
|
915
|
-
return parseCssColorToHex(
|
|
990
|
+
if (coerced.startsWith('#') || coerced.startsWith('rgb') || coerced.startsWith('hsl'))
|
|
991
|
+
return coerced;
|
|
992
|
+
return color.normalizeColorString(coerced) ?? parseCssColorToHex(coerced);
|
|
916
993
|
}
|
|
917
994
|
/**
|
|
918
995
|
* Parse any CSS color expression into an `#rrggbb` string via culori.
|
|
@@ -1018,6 +1095,12 @@ function parseShadowColor(expr) {
|
|
|
1018
1095
|
return rgba;
|
|
1019
1096
|
if (working.startsWith('#'))
|
|
1020
1097
|
return { color: working, opacity: 1 };
|
|
1098
|
+
// Named (`red`) / modern (`hsl(…)`, `oklch(…)`) colors — culori → sRGB hex.
|
|
1099
|
+
// Without this they fell to the default black at 0.1 alpha, silently losing
|
|
1100
|
+
// the user's `shadow-[0_2px_4px_red]` color.
|
|
1101
|
+
const hex = formatHexSafe(working);
|
|
1102
|
+
if (hex)
|
|
1103
|
+
return { color: hex, opacity: 1 };
|
|
1021
1104
|
return { color: '#000', opacity: 0.1 };
|
|
1022
1105
|
}
|
|
1023
1106
|
/**
|
|
@@ -1222,8 +1305,8 @@ function resolveLengthExpression(text) {
|
|
|
1222
1305
|
if (evaluated.unit === '%')
|
|
1223
1306
|
return `${stripTrailingZeros(evaluated.value)}%`;
|
|
1224
1307
|
if (evaluated.unit === 'rem')
|
|
1225
|
-
return evaluated.value * 16;
|
|
1226
|
-
return evaluated.value;
|
|
1308
|
+
return roundTransformValue(evaluated.value * 16);
|
|
1309
|
+
return roundTransformValue(evaluated.value);
|
|
1227
1310
|
}
|
|
1228
1311
|
/**
|
|
1229
1312
|
* Evaluate a CSS length expression to a `{value, unit}` pair.
|
|
@@ -1450,19 +1533,38 @@ function parseArithmeticFactor(tokens, cursor) {
|
|
|
1450
1533
|
return number_;
|
|
1451
1534
|
}
|
|
1452
1535
|
/**
|
|
1453
|
-
* Resolve a scale factor expressed as a percentage (`150%`)
|
|
1536
|
+
* Resolve a scale factor expressed as a percentage (`150%`), number (`1.5`),
|
|
1537
|
+
* or a `calc()` expression. Tailwind emits NEGATIVE scale utilities as a calc
|
|
1538
|
+
* (`-scale-x-100` → `calc(100% * -1)`), so a plain percent/number regex
|
|
1539
|
+
* silently dropped them — `-scale-*` (the horizontal-flip idiom) rendered
|
|
1540
|
+
* nothing. Fall back to the shared arithmetic evaluator, reading `%` as a
|
|
1541
|
+
* fraction (`100%` → 1) and rounding off f32 noise.
|
|
1454
1542
|
* @param text Raw value.
|
|
1455
|
-
* @returns Scale number (e.g. 1.5 for 150%), or null.
|
|
1543
|
+
* @returns Scale number (e.g. 1.5 for 150%, -1 for `calc(100% * -1)`), or null.
|
|
1456
1544
|
*/
|
|
1457
1545
|
function resolveNumberOrPercent(text) {
|
|
1458
1546
|
const trimmed = text.trim();
|
|
1459
1547
|
const percent = /^(-?\d+(?:\.\d+)?)%$/.exec(trimmed);
|
|
1460
1548
|
if (percent)
|
|
1461
|
-
return Number(percent[1]) / 100;
|
|
1549
|
+
return roundTransformValue(Number(percent[1]) / 100);
|
|
1462
1550
|
const bare = /^-?\d+(?:\.\d+)?$/.exec(trimmed);
|
|
1463
1551
|
if (bare)
|
|
1464
|
-
return Number(trimmed);
|
|
1465
|
-
|
|
1552
|
+
return roundTransformValue(Number(trimmed));
|
|
1553
|
+
const evaluated = evaluateLengthExpr(trimmed);
|
|
1554
|
+
if (!evaluated || evaluated.unit === 'rem')
|
|
1555
|
+
return null;
|
|
1556
|
+
return roundTransformValue(evaluated.unit === '%' ? evaluated.value / 100 : evaluated.value);
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Round a composed-transform numeric value to 4 decimals. lightningcss
|
|
1560
|
+
* serializes arbitrary literals (`scale-x-[0.333]`) back as noisy f32 text
|
|
1561
|
+
* (`0.3330000042915344`), and the resolvers `Number()` that verbatim — round
|
|
1562
|
+
* so the RN `transform` array stays clean.
|
|
1563
|
+
* @param value Raw number.
|
|
1564
|
+
* @returns Rounded number.
|
|
1565
|
+
*/
|
|
1566
|
+
function roundTransformValue(value) {
|
|
1567
|
+
return Math.round(value * 10_000) / 10_000;
|
|
1466
1568
|
}
|
|
1467
1569
|
/**
|
|
1468
1570
|
* Extract the angle from Tailwind's `skewX(12deg)` / `skewY(-5deg)` /
|