@kbach/react 0.6.37 → 0.6.40

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.
@@ -75,64 +75,64 @@ var LRUCache = class {
75
75
  // src/core/registry.ts
76
76
  var BUILTIN_MODIFIERS = {
77
77
  // ── Mode ─────────────────────────────────────────────────────────────────
78
- dark: { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
79
- "not-light": { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
80
- light: { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
81
- "not-dark": { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
78
+ dark: { order: 60, darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
79
+ "not-light": { order: 60, darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
80
+ light: { order: 60, darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
81
+ "not-dark": { order: 60, darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
82
82
  // ── Interactive — JS state + CSS pseudo ───────────────────────────────────
83
- hover: { pseudo: ":hover", jsBehavior: "interactive", jsMatch: (_, s) => !!s.hover },
84
- "not-hover": { pseudo: ":not(:hover)", jsBehavior: "interactive", jsMatch: (_, s) => !s.hover },
85
- focus: { pseudo: ":focus", jsBehavior: "interactive", jsMatch: (_, s) => !!s.focus },
86
- "not-focus": { pseudo: ":not(:focus)", jsBehavior: "interactive", jsMatch: (_, s) => !s.focus },
87
- active: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.active || !!s.pressed },
88
- "not-active": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.active && !s.pressed },
89
- pressed: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.pressed || !!s.active },
90
- "not-pressed": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.pressed && !s.active },
91
- disabled: { pseudo: ":disabled", jsBehavior: "interactive", jsMatch: (_, s) => !!s.disabled },
92
- "not-disabled": { pseudo: ":not(:disabled)", jsBehavior: "interactive", jsMatch: (_, s) => !s.disabled },
93
- checked: { pseudo: ":checked", jsBehavior: "interactive", jsMatch: (_, s) => !!s.checked },
94
- "not-checked": { pseudo: ":not(:checked)", jsBehavior: "interactive", jsMatch: (_, s) => !s.checked },
95
- visited: { pseudo: ":visited", jsBehavior: "interactive", jsMatch: (_, s) => !!s.visited },
96
- "not-visited": { pseudo: ":not(:visited)", jsBehavior: "interactive", jsMatch: (_, s) => !s.visited },
97
- placeholder: { pseudo: "::placeholder", jsBehavior: "interactive", jsMatch: (_, s) => !!s.placeholder },
83
+ hover: { order: 10, pseudo: ":hover", jsBehavior: "interactive", jsMatch: (_, s) => !!s.hover },
84
+ "not-hover": { order: 10, pseudo: ":not(:hover)", jsBehavior: "interactive", jsMatch: (_, s) => !s.hover },
85
+ focus: { order: 20, pseudo: ":focus", jsBehavior: "interactive", jsMatch: (_, s) => !!s.focus },
86
+ "not-focus": { order: 20, pseudo: ":not(:focus)", jsBehavior: "interactive", jsMatch: (_, s) => !s.focus },
87
+ active: { order: 30, pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.active || !!s.pressed },
88
+ "not-active": { order: 30, pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.active && !s.pressed },
89
+ pressed: { order: 30, pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.pressed || !!s.active },
90
+ "not-pressed": { order: 30, pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.pressed && !s.active },
91
+ disabled: { order: 40, pseudo: ":disabled", jsBehavior: "interactive", jsMatch: (_, s) => !!s.disabled },
92
+ "not-disabled": { order: 40, pseudo: ":not(:disabled)", jsBehavior: "interactive", jsMatch: (_, s) => !s.disabled },
93
+ checked: { order: 35, pseudo: ":checked", jsBehavior: "interactive", jsMatch: (_, s) => !!s.checked },
94
+ "not-checked": { order: 35, pseudo: ":not(:checked)", jsBehavior: "interactive", jsMatch: (_, s) => !s.checked },
95
+ visited: { order: 5, pseudo: ":visited", jsBehavior: "interactive", jsMatch: (_, s) => !!s.visited },
96
+ "not-visited": { order: 5, pseudo: ":not(:visited)", jsBehavior: "interactive", jsMatch: (_, s) => !s.visited },
97
+ placeholder: { order: 0, pseudo: "::placeholder", jsBehavior: "interactive", jsMatch: (_, s) => !!s.placeholder },
98
98
  // ── CSS-only pseudo-classes (structural) ──────────────────────────────────
99
- first: { pseudo: ":first-child", jsBehavior: "css-only", forcesImportant: true },
100
- last: { pseudo: ":last-child", jsBehavior: "css-only", forcesImportant: true },
101
- odd: { pseudo: ":nth-child(odd)", jsBehavior: "css-only", forcesImportant: true },
102
- even: { pseudo: ":nth-child(even)", jsBehavior: "css-only", forcesImportant: true },
103
- only: { pseudo: ":only-child", jsBehavior: "css-only", forcesImportant: true },
104
- "focus-within": { pseudo: ":focus-within", jsBehavior: "css-only", forcesImportant: true },
105
- "focus-visible": { pseudo: ":focus-visible", jsBehavior: "css-only", forcesImportant: true },
99
+ first: { order: 0, pseudo: ":first-child", jsBehavior: "css-only", forcesImportant: true },
100
+ last: { order: 0, pseudo: ":last-child", jsBehavior: "css-only", forcesImportant: true },
101
+ odd: { order: 0, pseudo: ":nth-child(odd)", jsBehavior: "css-only", forcesImportant: true },
102
+ even: { order: 0, pseudo: ":nth-child(even)", jsBehavior: "css-only", forcesImportant: true },
103
+ only: { order: 0, pseudo: ":only-child", jsBehavior: "css-only", forcesImportant: true },
104
+ "focus-within": { order: 15, pseudo: ":focus-within", jsBehavior: "css-only", forcesImportant: true },
105
+ "focus-visible": { order: 25, pseudo: ":focus-visible", jsBehavior: "css-only", forcesImportant: true },
106
106
  // ── CSS-only pseudo-elements ───────────────────────────────────────────────
107
- before: { pseudo: "::before", jsBehavior: "css-only" },
108
- after: { pseudo: "::after", jsBehavior: "css-only" },
109
- selection: { pseudo: "::selection", jsBehavior: "css-only" },
110
- "first-letter": { pseudo: "::first-letter", jsBehavior: "css-only" },
111
- "first-line": { pseudo: "::first-line", jsBehavior: "css-only" },
112
- marker: { pseudo: "::marker", jsBehavior: "css-only" },
107
+ before: { order: 0, pseudo: "::before", jsBehavior: "css-only" },
108
+ after: { order: 0, pseudo: "::after", jsBehavior: "css-only" },
109
+ selection: { order: 0, pseudo: "::selection", jsBehavior: "css-only" },
110
+ "first-letter": { order: 0, pseudo: "::first-letter", jsBehavior: "css-only" },
111
+ "first-line": { order: 0, pseudo: "::first-line", jsBehavior: "css-only" },
112
+ marker: { order: 0, pseudo: "::marker", jsBehavior: "css-only" },
113
113
  // ── Group / peer ancestor selectors (CSS-only) ─────────────────────────────
114
- "group-hover": { ancestorSelector: ".group:hover ", jsBehavior: "css-only", forcesImportant: true },
115
- "group-focus": { ancestorSelector: ".group:focus ", jsBehavior: "css-only", forcesImportant: true },
116
- "peer-hover": { ancestorSelector: ".peer:hover ~ ", jsBehavior: "css-only", forcesImportant: true },
117
- "peer-focus": { ancestorSelector: ".peer:focus ~ ", jsBehavior: "css-only", forcesImportant: true },
114
+ "group-hover": { order: 10, ancestorSelector: ".group:hover ", jsBehavior: "css-only", forcesImportant: true },
115
+ "group-focus": { order: 20, ancestorSelector: ".group:focus ", jsBehavior: "css-only", forcesImportant: true },
116
+ "peer-hover": { order: 10, ancestorSelector: ".peer:hover ~ ", jsBehavior: "css-only", forcesImportant: true },
117
+ "peer-focus": { order: 20, ancestorSelector: ".peer:focus ~ ", jsBehavior: "css-only", forcesImportant: true },
118
118
  // ── Responsive — both CSS (@media min-width) and JS (breakpoints set) ──────
119
- sm: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("sm") },
120
- md: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("md") },
121
- lg: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("lg") },
122
- xl: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("xl") },
123
- "2xl": { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("2xl") },
119
+ sm: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("sm") },
120
+ md: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("md") },
121
+ lg: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("lg") },
122
+ xl: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("xl") },
123
+ "2xl": { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("2xl") },
124
124
  // ── Print media (CSS-only) ─────────────────────────────────────────────────
125
- print: { mediaQuery: "print", jsBehavior: "css-only", forcesImportant: true },
125
+ print: { order: 70, mediaQuery: "print", jsBehavior: "css-only", forcesImportant: true },
126
126
  // ── Orientation / accessibility media (CSS-only) ───────────────────────────
127
- landscape: { mediaQuery: "(orientation: landscape)", jsBehavior: "css-only", forcesImportant: true },
128
- portrait: { mediaQuery: "(orientation: portrait)", jsBehavior: "css-only", forcesImportant: true },
129
- "motion-reduce": { mediaQuery: "(prefers-reduced-motion: reduce)", jsBehavior: "css-only", forcesImportant: true },
130
- "motion-safe": { mediaQuery: "(prefers-reduced-motion: no-preference)", jsBehavior: "css-only", forcesImportant: true },
131
- "contrast-more": { mediaQuery: "(prefers-contrast: more)", jsBehavior: "css-only", forcesImportant: true },
132
- "contrast-less": { mediaQuery: "(prefers-contrast: less)", jsBehavior: "css-only", forcesImportant: true },
127
+ landscape: { order: 70, mediaQuery: "(orientation: landscape)", jsBehavior: "css-only", forcesImportant: true },
128
+ portrait: { order: 70, mediaQuery: "(orientation: portrait)", jsBehavior: "css-only", forcesImportant: true },
129
+ "motion-reduce": { order: 70, mediaQuery: "(prefers-reduced-motion: reduce)", jsBehavior: "css-only", forcesImportant: true },
130
+ "motion-safe": { order: 70, mediaQuery: "(prefers-reduced-motion: no-preference)", jsBehavior: "css-only", forcesImportant: true },
131
+ "contrast-more": { order: 70, mediaQuery: "(prefers-contrast: more)", jsBehavior: "css-only", forcesImportant: true },
132
+ "contrast-less": { order: 70, mediaQuery: "(prefers-contrast: less)", jsBehavior: "css-only", forcesImportant: true },
133
133
  // ── Directionality (CSS-only) ──────────────────────────────────────────────
134
- rtl: { dirSelector: '[dir="rtl"] ', jsBehavior: "css-only", forcesImportant: true },
135
- ltr: { dirSelector: '[dir="ltr"] ', jsBehavior: "css-only", forcesImportant: true }
134
+ rtl: { order: 80, dirSelector: '[dir="rtl"] ', jsBehavior: "css-only", forcesImportant: true },
135
+ ltr: { order: 80, dirSelector: '[dir="ltr"] ', jsBehavior: "css-only", forcesImportant: true }
136
136
  };
137
137
  var _pluginModifiers = {};
138
138
  var _allNames = null;
@@ -169,6 +169,8 @@ function getNamedGroupPeerModifier(name) {
169
169
  const pseudo = trigger === "hover" ? ":hover" : ":focus";
170
170
  const combinator = kind === "group" ? " " : " ~ ";
171
171
  const def = {
172
+ // Matches the plain group-hover/group-focus/peer-hover/peer-focus order below.
173
+ order: trigger === "hover" ? 10 : 20,
172
174
  ancestorSelector: `.${kind}\\/${escapedName}${pseudo}${combinator}`,
173
175
  jsBehavior: "css-only",
174
176
  forcesImportant: true
@@ -203,6 +205,15 @@ function getResponsiveModifiers() {
203
205
  }
204
206
  return _responsiveNames;
205
207
  }
208
+ function getModifierOrder(bucketKey) {
209
+ if (bucketKey === "base") return -1;
210
+ let max = 0;
211
+ for (const mod of bucketKey.split(":")) {
212
+ const order = getModifier(mod)?.order ?? 0;
213
+ if (order > max) max = order;
214
+ }
215
+ return max;
216
+ }
206
217
  function matchModifier(name, isDark, state, breakpoints) {
207
218
  return getModifier(name)?.jsMatch?.(isDark, state, breakpoints) ?? false;
208
219
  }
@@ -211,6 +222,11 @@ function matchModifier(name, isDark, state, breakpoints) {
211
222
  function isModeAwareColor(v) {
212
223
  return typeof v === "object" && v !== null && "light" in v && "dark" in v;
213
224
  }
225
+ function splitColorShadeRef(ref) {
226
+ const lastDash = ref.lastIndexOf("-");
227
+ if (lastDash <= 0) return null;
228
+ return { name: ref.slice(0, lastDash), shade: ref.slice(lastDash + 1) };
229
+ }
214
230
 
215
231
  // src/core/resolvers/color.ts
216
232
  function pickModeAwareFallback(v) {
@@ -230,13 +246,11 @@ function resolveColor(value, colors, isArbitrary) {
230
246
  else if (isModeAwareColor(entry)) hex = pickModeAwareFallback(entry);
231
247
  else if (typeof entry === "object" && "6" in entry) hex = pickModeAwareFallback(entry["6"]);
232
248
  } else {
233
- const lastDash = colorPart.lastIndexOf("-");
234
- if (lastDash > 0) {
235
- const colorName = colorPart.slice(0, lastDash);
236
- const shade = colorPart.slice(lastDash + 1);
237
- const scale = colors[colorName];
238
- if (scale && typeof scale === "object" && !isModeAwareColor(scale) && shade in scale) {
239
- const shadeVal = scale[shade];
249
+ const split = splitColorShadeRef(colorPart);
250
+ if (split) {
251
+ const scale = colors[split.name];
252
+ if (scale && typeof scale === "object" && !isModeAwareColor(scale) && split.shade in scale) {
253
+ const shadeVal = scale[split.shade];
240
254
  hex = shadeVal !== void 0 ? pickModeAwareFallback(shadeVal) : null;
241
255
  }
242
256
  }
@@ -377,6 +391,7 @@ function resolveSpacing(value, negative, spacing, isArbitrary) {
377
391
  if (negative) {
378
392
  if (typeof resolved === "number") return -resolved;
379
393
  if (typeof resolved === "string") {
394
+ if (resolved.startsWith("-")) return resolved.slice(1);
380
395
  if (/^\d/.test(resolved)) return `-${resolved}`;
381
396
  if (/^(calc|var|min|max|clamp|env)\s*\(/.test(resolved)) return `calc(-1 * (${resolved}))`;
382
397
  }
@@ -555,7 +570,7 @@ function makeBorderSideResolver(widthProp, colorProp) {
555
570
  if (!value) return { [widthProp]: 1 };
556
571
  if (isArbitrary) {
557
572
  const w2 = toNativeValue(value);
558
- if (typeof w2 === "number") return { [widthProp]: w2 };
573
+ if (typeof w2 === "number") return { [widthProp]: getEffectiveIsWeb() ? value : w2 };
559
574
  return { [colorProp]: value };
560
575
  }
561
576
  const color = resolveColor(value, colors, false);
@@ -576,7 +591,7 @@ var borderResolvers = {
576
591
  if (!value) return { borderWidth: borderWidth["DEFAULT"] ?? 1 };
577
592
  if (isArbitrary) {
578
593
  const w2 = toNativeValue(value);
579
- if (typeof w2 === "number") return { borderWidth: w2 };
594
+ if (typeof w2 === "number") return { borderWidth: getEffectiveIsWeb() ? value : w2 };
580
595
  return { borderColor: value };
581
596
  }
582
597
  const color = resolveColor(value, colors, false);
@@ -775,9 +790,9 @@ var filterResolvers = {
775
790
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
776
791
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
777
792
  },
778
- grayscale: ({ value }) => {
793
+ grayscale: ({ value, isArbitrary }) => {
779
794
  if (!getEffectiveIsWeb()) return null;
780
- const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
795
+ const v = isArbitrary ? `grayscale(${value})` : value === "0" ? "grayscale(0)" : "grayscale(100%)";
781
796
  return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
782
797
  },
783
798
  "hue-rotate": ({ value, negative, isArbitrary }) => {
@@ -786,9 +801,9 @@ var filterResolvers = {
786
801
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
787
802
  return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
788
803
  },
789
- invert: ({ value }) => {
804
+ invert: ({ value, isArbitrary }) => {
790
805
  if (!getEffectiveIsWeb()) return null;
791
- const v = value === "0" ? "invert(0)" : "invert(100%)";
806
+ const v = isArbitrary ? `invert(${value})` : value === "0" ? "invert(0)" : "invert(100%)";
792
807
  return { "--kb-invert": v, filter: FILTER_COMPOSE };
793
808
  },
794
809
  saturate: ({ value, isArbitrary }) => {
@@ -796,9 +811,9 @@ var filterResolvers = {
796
811
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
797
812
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
798
813
  },
799
- sepia: ({ value }) => {
814
+ sepia: ({ value, isArbitrary }) => {
800
815
  if (!getEffectiveIsWeb()) return null;
801
- const v = value === "0" ? "sepia(0)" : "sepia(100%)";
816
+ const v = isArbitrary ? `sepia(${value})` : value === "0" ? "sepia(0)" : "sepia(100%)";
802
817
  return { "--kb-sepia": v, filter: FILTER_COMPOSE };
803
818
  },
804
819
  "drop-shadow": ({ value, isArbitrary }) => {
@@ -849,9 +864,10 @@ var filterResolvers = {
849
864
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
850
865
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
851
866
  },
852
- "backdrop-grayscale": ({ value }) => {
867
+ "backdrop-grayscale": ({ value, isArbitrary }) => {
853
868
  if (!getEffectiveIsWeb()) return null;
854
- return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
869
+ const v = isArbitrary ? `grayscale(${value})` : value === "0" ? "grayscale(0)" : "grayscale(100%)";
870
+ return { "--kb-backdrop-grayscale": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
855
871
  },
856
872
  "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
857
873
  if (!getEffectiveIsWeb()) return null;
@@ -859,9 +875,10 @@ var filterResolvers = {
859
875
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
860
876
  return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
861
877
  },
862
- "backdrop-invert": ({ value }) => {
878
+ "backdrop-invert": ({ value, isArbitrary }) => {
863
879
  if (!getEffectiveIsWeb()) return null;
864
- return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
880
+ const v = isArbitrary ? `invert(${value})` : value === "0" ? "invert(0)" : "invert(100%)";
881
+ return { "--kb-backdrop-invert": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
865
882
  },
866
883
  "backdrop-opacity": ({ value, isArbitrary }) => {
867
884
  if (!getEffectiveIsWeb()) return null;
@@ -873,9 +890,10 @@ var filterResolvers = {
873
890
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
874
891
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
875
892
  },
876
- "backdrop-sepia": ({ value }) => {
893
+ "backdrop-sepia": ({ value, isArbitrary }) => {
877
894
  if (!getEffectiveIsWeb()) return null;
878
- return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
895
+ const v = isArbitrary ? `sepia(${value})` : value === "0" ? "sepia(0)" : "sepia(100%)";
896
+ return { "--kb-backdrop-sepia": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
879
897
  },
880
898
  "backdrop-filter": ({ value, isArbitrary }) => {
881
899
  if (!getEffectiveIsWeb()) return null;
@@ -945,8 +963,8 @@ var filterResolvers = {
945
963
 
946
964
  // src/core/resolvers/layout.ts
947
965
  var _standalone = null;
948
- function buildStandalone() {
949
- const web = getEffectiveIsWeb();
966
+ var _standaloneWeb = null;
967
+ function buildStandalone(web) {
950
968
  return {
951
969
  // Display
952
970
  // React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
@@ -961,7 +979,6 @@ function buildStandalone() {
961
979
  "inline-block": { display: web ? "inline-block" : "flex" },
962
980
  inline: { display: web ? "inline" : "flex" },
963
981
  grid: web ? { display: "grid" } : null,
964
- grd: web ? { display: "grid" } : null,
965
982
  "inline-flex": { display: web ? "inline-flex" : "flex" },
966
983
  "inline-grid": { display: web ? "inline-grid" : "flex" },
967
984
  hidden: { display: "none" },
@@ -1313,7 +1330,11 @@ function buildStandalone() {
1313
1330
  };
1314
1331
  }
1315
1332
  function getStandalone() {
1316
- if (!_standalone) _standalone = buildStandalone();
1333
+ const web = getEffectiveIsWeb();
1334
+ if (!_standalone || _standaloneWeb !== web) {
1335
+ _standalone = buildStandalone(web);
1336
+ _standaloneWeb = web;
1337
+ }
1317
1338
  return _standalone;
1318
1339
  }
1319
1340
  var layoutResolvers = {
@@ -1877,6 +1898,18 @@ var effectResolvers = {
1877
1898
  if (!isArbitrary && isNaN(parseFloat(value))) return null;
1878
1899
  const ms = isArbitrary ? value : `${value}ms`;
1879
1900
  return { transitionDelay: ms };
1901
+ },
1902
+ ease: ({ value, isArbitrary }) => {
1903
+ if (!getEffectiveIsWeb()) return null;
1904
+ if (isArbitrary) return { transitionTimingFunction: value };
1905
+ const presets = {
1906
+ linear: "linear",
1907
+ in: "cubic-bezier(0.4, 0, 1, 1)",
1908
+ out: "cubic-bezier(0, 0, 0.2, 1)",
1909
+ "in-out": "cubic-bezier(0.4, 0, 0.2, 1)"
1910
+ };
1911
+ const v = presets[value];
1912
+ return v !== void 0 ? { transitionTimingFunction: v } : null;
1880
1913
  }
1881
1914
  };
1882
1915
 
@@ -2926,9 +2959,21 @@ function getDefaultFontFamily() {
2926
2959
  }
2927
2960
  var _styleEl = null;
2928
2961
  var _ruleIndexByKey = /* @__PURE__ */ new Map();
2962
+ var _sheetKeys = [];
2963
+ var _ruleOrderByKey = /* @__PURE__ */ new Map();
2964
+ function findInsertionIndex(order) {
2965
+ let lo = 0, hi = _sheetKeys.length;
2966
+ while (lo < hi) {
2967
+ const mid = lo + hi >>> 1;
2968
+ if (_ruleOrderByKey.get(_sheetKeys[mid]) > order) hi = mid;
2969
+ else lo = mid + 1;
2970
+ }
2971
+ return lo;
2972
+ }
2929
2973
  function evictInjectedRule(rule) {
2930
2974
  const idx = _ruleIndexByKey.get(rule);
2931
2975
  _ruleIndexByKey.delete(rule);
2976
+ _ruleOrderByKey.delete(rule);
2932
2977
  if (idx === void 0) return;
2933
2978
  const sheet = _styleEl?.sheet;
2934
2979
  if (!sheet) return;
@@ -2937,6 +2982,7 @@ function evictInjectedRule(rule) {
2937
2982
  } catch {
2938
2983
  return;
2939
2984
  }
2985
+ _sheetKeys.splice(idx, 1);
2940
2986
  for (const [key, i] of _ruleIndexByKey) {
2941
2987
  if (i > idx) _ruleIndexByKey.set(key, i - 1);
2942
2988
  }
@@ -2956,15 +3002,20 @@ function getStyleEl() {
2956
3002
  document.head.appendChild(_styleEl);
2957
3003
  return _styleEl;
2958
3004
  }
2959
- function injectRule(rule) {
3005
+ function injectRule(rule, order) {
2960
3006
  if (isRuntimeCSSDisabled()) return;
2961
3007
  if (_injectedRules.get(rule)) return;
2962
3008
  try {
2963
3009
  const sheet = getStyleEl().sheet;
2964
3010
  if (sheet) {
2965
- const idx = sheet.cssRules.length;
3011
+ const idx = findInsertionIndex(order);
2966
3012
  sheet.insertRule(rule, idx);
3013
+ _sheetKeys.splice(idx, 0, rule);
3014
+ for (const [key, i] of _ruleIndexByKey) {
3015
+ if (i >= idx) _ruleIndexByKey.set(key, i + 1);
3016
+ }
2967
3017
  _ruleIndexByKey.set(rule, idx);
3018
+ _ruleOrderByKey.set(rule, order);
2968
3019
  _injectedRules.set(rule, true);
2969
3020
  }
2970
3021
  } catch {
@@ -3156,16 +3207,23 @@ function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens
3156
3207
  rules.push(rule);
3157
3208
  return rules;
3158
3209
  }
3159
- function injectClassRule(cls, bucketKey, styles, darkMode, important) {
3210
+ function injectClassRule(cls, bucketKey, styles, darkMode, important, order) {
3160
3211
  const cssRules = buildClassCSSRules(cls, bucketKey, styles, darkMode, important, getGlobalScreens());
3161
- for (const r of cssRules) injectRule(r);
3212
+ for (const r of cssRules) injectRule(r, order);
3213
+ return cssRules;
3162
3214
  }
3163
3215
  function resolve(classString, theme, darkMode = "attribute") {
3164
3216
  const cache = getThemeCache(theme);
3165
- const cacheKey = `${classString}::${darkMode}`;
3217
+ const cacheKey = `${classString}::${darkMode}::${getEffectiveIsWeb() ? "web" : "native"}`;
3166
3218
  const cached = cache.get(cacheKey);
3167
- if (cached) return cached;
3219
+ if (cached) {
3220
+ if (isWeb) {
3221
+ for (const { rule, order } of cached.rules) injectRule(rule, order);
3222
+ }
3223
+ return cached.result;
3224
+ }
3168
3225
  const result = {};
3226
+ const rules = [];
3169
3227
  const onWeb = isWeb;
3170
3228
  for (const parsed of parseClasses(expandModeAwareColorClasses(classString, theme.colors))) {
3171
3229
  const styles = resolveUtility(parsed, theme);
@@ -3179,10 +3237,13 @@ function resolve(classString, theme, darkMode = "attribute") {
3179
3237
  if (!result[bucketKey]) result[bucketKey] = {};
3180
3238
  Object.assign(result[bucketKey], styles);
3181
3239
  if (onWeb) {
3182
- injectClassRule(parsed.original, bucketKey, styles, darkMode, parsed.important);
3240
+ const order = getModifierOrder(bucketKey);
3241
+ for (const r of injectClassRule(parsed.original, bucketKey, styles, darkMode, parsed.important, order)) {
3242
+ rules.push({ rule: r, order });
3243
+ }
3183
3244
  }
3184
3245
  }
3185
- cache.set(cacheKey, result);
3246
+ cache.set(cacheKey, { result, rules });
3186
3247
  return result;
3187
3248
  }
3188
3249
  function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
@@ -3236,6 +3297,8 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
3236
3297
  function clearCache() {
3237
3298
  _injectedRules.clear();
3238
3299
  _ruleIndexByKey.clear();
3300
+ _ruleOrderByKey.clear();
3301
+ _sheetKeys.length = 0;
3239
3302
  if (_styleEl) {
3240
3303
  _styleEl.remove();
3241
3304
  _styleEl = null;
@@ -3263,12 +3326,15 @@ function deepMerge(base, override) {
3263
3326
  }
3264
3327
  return result;
3265
3328
  }
3266
- var configStore = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
3329
+ var configStore = { resolved: null, listeners: /* @__PURE__ */ new Set() };
3267
3330
  function getConfig() {
3268
3331
  if (configStore.resolved) return configStore.resolved;
3269
3332
  configStore.resolved = buildConfig({});
3270
3333
  return configStore.resolved;
3271
3334
  }
3335
+ function resetConfig() {
3336
+ configStore.resolved = null;
3337
+ }
3272
3338
  function resolveColorRefs(colors) {
3273
3339
  const MAX_DEPTH = 5;
3274
3340
  function resolveChain(raw, side) {
@@ -3302,10 +3368,9 @@ function resolveColorRefs(colors) {
3302
3368
  const a = opacity > 1 ? opacity / 100 : opacity;
3303
3369
  return hexToRgba(baseHex, a);
3304
3370
  }
3305
- const lastDash = ref.lastIndexOf("-");
3306
- if (lastDash <= 0) return null;
3307
- const name = ref.slice(0, lastDash);
3308
- const shade = ref.slice(lastDash + 1);
3371
+ const split = splitColorShadeRef(ref);
3372
+ if (!split) return null;
3373
+ const { name, shade } = split;
3309
3374
  if (!/^\d+$/.test(shade)) return null;
3310
3375
  const entry = colors[name];
3311
3376
  if (!entry || typeof entry !== "object" || isModeAwareColor(entry)) return null;
@@ -3367,7 +3432,6 @@ function buildConfig(userConfig) {
3367
3432
  clearPluginUtilities();
3368
3433
  clearPluginModifiers();
3369
3434
  }
3370
- for (const k of Object.keys(configStore.customVariants)) delete configStore.customVariants[k];
3371
3435
  const pluginAPI = makePluginAPI(resolved.theme);
3372
3436
  for (const plugin of resolved.plugins) {
3373
3437
  plugin(pluginAPI);
@@ -3396,8 +3460,6 @@ function makePluginAPI(theme) {
3396
3460
  },
3397
3461
  addVariant(name, selectorOrDef) {
3398
3462
  const def = typeof selectorOrDef === "string" ? _selectorToModifierDef(selectorOrDef) : selectorOrDef;
3399
- const selector = typeof selectorOrDef === "string" ? selectorOrDef : selectorOrDef.pseudo ?? selectorOrDef.mediaQuery ?? selectorOrDef.ancestorSelector ?? null;
3400
- if (selector !== null && selector !== name) customVariants[name] = selector;
3401
3463
  registerModifier(name, def);
3402
3464
  },
3403
3465
  theme(path, defaultValue) {
@@ -3430,7 +3492,6 @@ function initConfig(userConfig) {
3430
3492
  if (configStore._src === userConfig) return;
3431
3493
  updateConfig(userConfig);
3432
3494
  }
3433
- var customVariants = configStore.customVariants;
3434
3495
 
3435
3496
  // src/core/darkModeStore.ts
3436
3497
  var store2 = { isDark: false, notifiedIsDark: false, subscribers: /* @__PURE__ */ new Set() };
@@ -3541,6 +3602,10 @@ function stripWebOnlyProps(s) {
3541
3602
  delete s.position;
3542
3603
  }
3543
3604
  }
3605
+ function composeNativeStyle(computed, userStyle) {
3606
+ if (!userStyle) return computed;
3607
+ return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
3608
+ }
3544
3609
 
3545
3610
  // src/web-substitute.ts
3546
3611
  var _rnToHtml = {
@@ -3568,11 +3633,21 @@ function registerWebElement(rnComponent, htmlTag) {
3568
3633
  _userMap.set(rnComponent, htmlTag);
3569
3634
  _cache.delete(rnComponent);
3570
3635
  }
3636
+ var _forwardRefOrMemoType = /* @__PURE__ */ new Set([
3637
+ /* @__PURE__ */ Symbol.for("react.forward_ref"),
3638
+ /* @__PURE__ */ Symbol.for("react.memo")
3639
+ ]);
3640
+ function looksLikeRealRNPrimitive(type) {
3641
+ const t = type.$$typeof;
3642
+ if (t !== void 0) return _forwardRefOrMemoType.has(t);
3643
+ return !!type.prototype?.isReactComponent;
3644
+ }
3571
3645
  function getWebTag(type, props) {
3572
3646
  if (typeof type === "string") return null;
3573
3647
  if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3574
3648
  const obj = type;
3575
3649
  if (_userMap.has(obj)) return _userMap.get(obj);
3650
+ if (!looksLikeRealRNPrimitive(obj)) return null;
3576
3651
  const name = obj.displayName ?? obj.name;
3577
3652
  if (!name) {
3578
3653
  _cache.set(obj, null);
@@ -3642,8 +3717,9 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
3642
3717
  "lineBreakStrategyIOS",
3643
3718
  // TextInput
3644
3719
  "multiline",
3645
- "resizeMode",
3646
- // handled separately
3720
+ // NOTE: 'resizeMode' (Image's prop, not TextInput's) deliberately does NOT
3721
+ // go here — it's handled below in the isImage branch (mapped to CSS
3722
+ // object-fit). Blacklisting it here would make that branch unreachable.
3647
3723
  "blurOnSubmit",
3648
3724
  "clearButtonMode",
3649
3725
  "clearTextOnFocus",
@@ -3769,7 +3845,7 @@ function transformToWebProps(originalName, tag, props) {
3769
3845
  continue;
3770
3846
  }
3771
3847
  if (k === "keyboardType") {
3772
- if (!("type" in props) && !("secureTextEntry" in props)) {
3848
+ if (!("type" in props) && !props.secureTextEntry) {
3773
3849
  const mapped = _keyboardTypeMap[v];
3774
3850
  if (mapped) out.type = mapped;
3775
3851
  }
@@ -3785,7 +3861,7 @@ function transformToWebProps(originalName, tag, props) {
3785
3861
  }
3786
3862
  }
3787
3863
  if (isScrollable && k === "horizontal") {
3788
- if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
3864
+ if (v) pendingStyle = { ...pendingStyle ?? {}, display: "flex", flexDirection: "row", overflowX: "auto" };
3789
3865
  continue;
3790
3866
  }
3791
3867
  if (k === "pointerEvents") {
@@ -3905,6 +3981,7 @@ var InteractiveWrapper = forwardRef(
3905
3981
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
3906
3982
  const width = useConditionalWidth(needsWidth && !isWebPlatform);
3907
3983
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3984
+ const screens = getGlobalScreens();
3908
3985
  const [pressed, setPressed] = useState(false);
3909
3986
  const [hovered, setHovered] = useState(false);
3910
3987
  const [focused, setFocused] = useState(false);
@@ -3948,10 +4025,10 @@ var InteractiveWrapper = forwardRef(
3948
4025
  if (isNonStringComponent) stripWebOnlyProps(s);
3949
4026
  return s;
3950
4027
  },
3951
- [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked, isNonStringComponent]
4028
+ [resolvedStyle, isDark, pressed, hovered, focused, width, screens, disabled, checked, isNonStringComponent]
3952
4029
  );
3953
4030
  const skipComputedInline = isWebPlatform;
3954
- const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? [computedStyle, ...styleProp] : [computedStyle, styleProp] : computedStyle;
4031
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
3955
4032
  const componentProps = {
3956
4033
  ref,
3957
4034
  ...restForComponent,
@@ -4021,6 +4098,7 @@ export {
4021
4098
  flatten,
4022
4099
  clearCache,
4023
4100
  getConfig,
4101
+ resetConfig,
4024
4102
  buildConfig,
4025
4103
  onConfigChange,
4026
4104
  updateConfig,
@@ -4038,6 +4116,7 @@ export {
4038
4116
  chain,
4039
4117
  stripInternalMarkers,
4040
4118
  stripWebOnlyProps,
4119
+ composeNativeStyle,
4041
4120
  registerWebElement,
4042
4121
  getWebTag,
4043
4122
  getImpliedRNStyle,
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  EMPTY_BREAKPOINTS,
4
4
  InteractiveWrapper,
5
+ composeNativeStyle,
5
6
  expandModeAwareColorClasses,
6
7
  flatten,
7
8
  getActiveBreakpoints,
@@ -26,7 +27,7 @@ import {
26
27
  transformToWebProps,
27
28
  useConditionalGlobalDarkMode,
28
29
  useConditionalWidth
29
- } from "./chunk-ZTDE7V7I.mjs";
30
+ } from "./chunk-LQH3CJ3G.mjs";
30
31
 
31
32
  // src/jsx-runtime.tsx
32
33
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -51,7 +52,7 @@ var DarkWrapper = React.forwardRef(
51
52
  return s;
52
53
  }, [resolvedStyle, isDark, width, screens, isNonStringComponent]);
53
54
  const skipComputedInline = isWebPlatform;
54
- const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? [computedStyle, ...styleProp] : [computedStyle, styleProp] : computedStyle;
55
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
55
56
  const props = { ref, ...rest, style: finalStyle };
56
57
  return Array.isArray(children) ? React.createElement(Component, props, ...children) : React.createElement(Component, props, children);
57
58
  }
@@ -107,10 +108,6 @@ function omitConsumed(props) {
107
108
  }
108
109
  return out;
109
110
  }
110
- function mergeStyle(computed, userStyle) {
111
- if (!userStyle) return computed;
112
- return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
113
- }
114
111
  function withImpliedRNStyleIfNeeded(webTag, resolvedBase, userStyle) {
115
112
  const compensation = getImpliedRNStyle(webTag, resolvedBase);
116
113
  if (!compensation) return userStyle;
@@ -186,7 +183,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
186
183
  const computedStyle = flatten(resolved, false);
187
184
  stripInternalMarkers(computedStyle);
188
185
  if (typeof effectiveType !== "string") stripWebOnlyProps(computedStyle);
189
- finalStyle = mergeStyle(computedStyle, userStyle);
186
+ finalStyle = composeNativeStyle(computedStyle, userStyle);
190
187
  } else {
191
188
  finalStyle = userStyle ?? void 0;
192
189
  }