@kbach/react 0.5.62 → 0.6.1

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/dist/index.js CHANGED
@@ -33,8 +33,8 @@ __export(index_exports, {
33
33
  InteractiveWrapper: () => InteractiveWrapper,
34
34
  ThemeContext: () => ThemeContext,
35
35
  ThemeProvider: () => ThemeProvider,
36
- ThemeToggle: () => ThemeToggle,
37
36
  buildConfig: () => buildConfig,
37
+ clearCache: () => clearCache,
38
38
  cx: () => cx,
39
39
  defaultColors: () => defaultColors,
40
40
  defaultTheme: () => defaultTheme,
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  parseClasses: () => parseClasses,
49
49
  registerWebElement: () => registerWebElement,
50
50
  resolve: () => resolve,
51
+ setResolveTarget: () => setResolveTarget,
51
52
  splitClassTokens: () => splitClassTokens,
52
53
  styled: () => styled,
53
54
  updateConfig: () => updateConfig,
@@ -81,76 +82,6 @@ function useIsDark() {
81
82
 
82
83
  // src/useColors.ts
83
84
  var import_react2 = require("react");
84
- function applyOpacity(color, opacity) {
85
- const a = Math.max(0, Math.min(1, opacity / 100));
86
- if (color.startsWith("#")) {
87
- const h = color.slice(1);
88
- let rs, gs, bs;
89
- if (h.length === 3 || h.length === 4) {
90
- rs = h[0] + h[0];
91
- gs = h[1] + h[1];
92
- bs = h[2] + h[2];
93
- } else if (h.length === 8) {
94
- rs = h.slice(0, 2);
95
- gs = h.slice(2, 4);
96
- bs = h.slice(4, 6);
97
- } else {
98
- rs = h.slice(0, 2);
99
- gs = h.slice(2, 4);
100
- bs = h.slice(4, 6);
101
- }
102
- return `rgba(${parseInt(rs, 16)},${parseInt(gs, 16)},${parseInt(bs, 16)},${a})`;
103
- }
104
- if (color.startsWith("rgb(")) return color.replace("rgb(", "rgba(").replace(")", `,${a})`);
105
- if (color.startsWith("rgba(")) return color.replace(/,\s*[\d.]+\)$/, `,${a})`);
106
- return color;
107
- }
108
- function makeShadeProxy(shades) {
109
- return new Proxy(shades, {
110
- get(target, prop) {
111
- const key = String(prop);
112
- if (key === "then") return void 0;
113
- if (key.includes("/")) {
114
- const slash = key.indexOf("/");
115
- const shade = key.slice(0, slash);
116
- const op = Number(key.slice(slash + 1));
117
- const color = target[shade];
118
- return typeof color === "string" ? applyOpacity(color, op) : void 0;
119
- }
120
- return target[key];
121
- }
122
- });
123
- }
124
- function wrapColors(rawColors) {
125
- const cache = /* @__PURE__ */ new Map();
126
- const alpha = (color, opacity) => opacity === void 0 ? color : applyOpacity(color, opacity);
127
- return new Proxy({ alpha }, {
128
- get(_, prop) {
129
- const key = String(prop);
130
- if (key === "then") return void 0;
131
- if (key === "alpha") return alpha;
132
- if (key.includes("/")) {
133
- const slash = key.indexOf("/");
134
- const name = key.slice(0, slash);
135
- const op = Number(key.slice(slash + 1));
136
- const entry2 = rawColors[name];
137
- return typeof entry2 === "string" ? applyOpacity(entry2, op) : void 0;
138
- }
139
- const entry = rawColors[key];
140
- if (entry === void 0) return void 0;
141
- if (typeof entry === "string") return entry;
142
- if (!cache.has(key)) cache.set(key, makeShadeProxy(entry));
143
- return cache.get(key);
144
- }
145
- });
146
- }
147
- function useColors() {
148
- const { config } = useTheme();
149
- return (0, import_react2.useMemo)(() => wrapColors(config.theme.colors), [config.theme.colors]);
150
- }
151
-
152
- // src/ThemeProvider.tsx
153
- var import_react3 = require("react");
154
85
 
155
86
  // src/core/theme.ts
156
87
  var defaultColors = {
@@ -694,10 +625,11 @@ var defaultTheme = {
694
625
 
695
626
  // src/core/cache.ts
696
627
  var LRUCache = class {
697
- constructor(capacity = 1e4) {
628
+ constructor(capacity = 1e4, onEvict) {
698
629
  this.capacity = capacity;
699
630
  if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
700
631
  this.cache = /* @__PURE__ */ new Map();
632
+ this.onEvict = onEvict;
701
633
  }
702
634
  get(key) {
703
635
  if (!this.cache.has(key)) return void 0;
@@ -710,7 +642,10 @@ var LRUCache = class {
710
642
  if (this.cache.has(key)) {
711
643
  this.cache.delete(key);
712
644
  } else if (this.cache.size >= this.capacity) {
713
- this.cache.delete(this.cache.keys().next().value);
645
+ const oldestKey = this.cache.keys().next().value;
646
+ const oldestValue = this.cache.get(oldestKey);
647
+ this.cache.delete(oldestKey);
648
+ this.onEvict?.(oldestKey, oldestValue);
714
649
  }
715
650
  this.cache.set(key, value);
716
651
  return this;
@@ -732,9 +667,13 @@ var LRUCache = class {
732
667
  // src/core/platform.ts
733
668
  var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
734
669
  var isNative = !isWeb && (typeof globalThis.HermesInternal !== "undefined" || typeof globalThis.__fbBatchedBridge !== "undefined" || typeof navigator !== "undefined" && navigator.product === "ReactNative" || typeof globalThis.__REACT_NATIVE__ !== "undefined");
735
- var _cssGenMode = false;
670
+ var _resolveTargetOverride = null;
671
+ function setResolveTarget(target) {
672
+ _resolveTargetOverride = target;
673
+ }
736
674
  function getEffectiveIsWeb() {
737
- return isWeb || _cssGenMode || !isNative;
675
+ if (_resolveTargetOverride) return _resolveTargetOverride === "web";
676
+ return isWeb || !isNative;
738
677
  }
739
678
  function toNativeValue(raw) {
740
679
  if (/^-?\d+(\.\d+)?px$/.test(raw)) return parseFloat(raw);
@@ -915,18 +854,28 @@ function resolveColor(value, colors, isArbitrary) {
915
854
  if (isNaN(alpha)) return hex;
916
855
  return hexToRgba(hex, alpha);
917
856
  }
918
- function hexToRgba(hex, alpha) {
857
+ function parseHexRgb(hex) {
919
858
  const h = hex.replace("#", "");
920
- let r, g, b;
921
- if (h.length === 3) {
922
- r = parseInt(h[0] + h[0], 16);
923
- g = parseInt(h[1] + h[1], 16);
924
- b = parseInt(h[2] + h[2], 16);
925
- } else {
926
- r = parseInt(h.slice(0, 2), 16);
927
- g = parseInt(h.slice(2, 4), 16);
928
- b = parseInt(h.slice(4, 6), 16);
859
+ if (h.length === 3 || h.length === 4) {
860
+ return [
861
+ parseInt(h[0] + h[0], 16),
862
+ parseInt(h[1] + h[1], 16),
863
+ parseInt(h[2] + h[2], 16)
864
+ ];
865
+ }
866
+ if (h.length === 6 || h.length === 8) {
867
+ return [
868
+ parseInt(h.slice(0, 2), 16),
869
+ parseInt(h.slice(2, 4), 16),
870
+ parseInt(h.slice(4, 6), 16)
871
+ ];
929
872
  }
873
+ return null;
874
+ }
875
+ function hexToRgba(hex, alpha) {
876
+ const rgb = parseHexRgb(hex);
877
+ if (!rgb) return hex;
878
+ const [r, g, b] = rgb;
930
879
  return `rgba(${r},${g},${b},${alpha})`;
931
880
  }
932
881
  function resolveSpacing(value, negative, spacing, isArbitrary) {
@@ -970,8 +919,8 @@ function resolveFontSize(value, fontSizes, isArbitrary) {
970
919
  if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
971
920
  return fontSizes[value] ?? null;
972
921
  }
973
- var FILTER_COMPOSE = "var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)";
974
- var BACKDROP_FILTER_COMPOSE = "var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)";
922
+ var FILTER_COMPOSE = "var(--kb-blur,) var(--kb-brightness,) var(--kb-contrast,) var(--kb-grayscale,) var(--kb-hue-rotate,) var(--kb-invert,) var(--kb-saturate,) var(--kb-sepia,) var(--kb-drop-shadow,)";
923
+ var BACKDROP_FILTER_COMPOSE = "var(--kb-backdrop-blur,) var(--kb-backdrop-brightness,) var(--kb-backdrop-contrast,) var(--kb-backdrop-grayscale,) var(--kb-backdrop-hue-rotate,) var(--kb-backdrop-invert,) var(--kb-backdrop-opacity,) var(--kb-backdrop-saturate,) var(--kb-backdrop-sepia,)";
975
924
  var _standalone = null;
976
925
  function buildStandalone() {
977
926
  const web = getEffectiveIsWeb();
@@ -1233,9 +1182,9 @@ function buildStandalone() {
1233
1182
  "backface-visible": { backfaceVisibility: "visible" },
1234
1183
  "backface-hidden": { backfaceVisibility: "hidden" },
1235
1184
  // CSS filters — standalone = default/full effect (web-only)
1236
- grayscale: web ? { "--tw-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1237
- invert: web ? { "--tw-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1238
- sepia: web ? { "--tw-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1185
+ grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1186
+ invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1187
+ sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1239
1188
  // Divide none
1240
1189
  "divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
1241
1190
  // Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
@@ -1320,6 +1269,48 @@ function getStandalone() {
1320
1269
  if (!_standalone) _standalone = buildStandalone();
1321
1270
  return _standalone;
1322
1271
  }
1272
+ function makeSpacingResolver(prop) {
1273
+ return ({ value, negative, isArbitrary }, { spacing }) => {
1274
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1275
+ return v !== null ? { [prop]: v } : null;
1276
+ };
1277
+ }
1278
+ var PADDING_MARGIN_PROPS = {
1279
+ p: "padding",
1280
+ px: "paddingHorizontal",
1281
+ py: "paddingVertical",
1282
+ pt: "paddingTop",
1283
+ pr: "paddingRight",
1284
+ pb: "paddingBottom",
1285
+ pl: "paddingLeft",
1286
+ m: "margin",
1287
+ mx: "marginHorizontal",
1288
+ my: "marginVertical",
1289
+ mt: "marginTop",
1290
+ mr: "marginRight",
1291
+ mb: "marginBottom",
1292
+ ml: "marginLeft"
1293
+ };
1294
+ function makeBorderSideResolver(widthProp, colorProp) {
1295
+ return ({ value, isArbitrary }, { colors, borderWidth }) => {
1296
+ if (!value) return { [widthProp]: 1 };
1297
+ if (isArbitrary) {
1298
+ const w2 = toNativeValue(value);
1299
+ if (typeof w2 === "number") return { [widthProp]: w2 };
1300
+ return { [colorProp]: value };
1301
+ }
1302
+ const color = resolveColor(value, colors, false);
1303
+ if (color) return { [colorProp]: color };
1304
+ const w = borderWidth[value];
1305
+ return w !== void 0 ? { [widthProp]: w } : null;
1306
+ };
1307
+ }
1308
+ var BORDER_SIDE_PROPS = {
1309
+ "border-t": ["borderTopWidth", "borderTopColor"],
1310
+ "border-r": ["borderRightWidth", "borderRightColor"],
1311
+ "border-b": ["borderBottomWidth", "borderBottomColor"],
1312
+ "border-l": ["borderLeftWidth", "borderLeftColor"]
1313
+ };
1323
1314
  var RESOLVERS = {
1324
1315
  // ── Background ─────────────────────────────────────────────────────────────
1325
1316
  bg: ({ value, isArbitrary }, { colors }) => {
@@ -1353,64 +1344,8 @@ var RESOLVERS = {
1353
1344
  const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
1354
1345
  return { "--text-opacity": v };
1355
1346
  },
1356
- // ── Padding ────────────────────────────────────────────────────────────────
1357
- p: ({ value, negative, isArbitrary }, { spacing }) => {
1358
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1359
- return v !== null ? { padding: v } : null;
1360
- },
1361
- px: ({ value, negative, isArbitrary }, { spacing }) => {
1362
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1363
- return v !== null ? { paddingHorizontal: v } : null;
1364
- },
1365
- py: ({ value, negative, isArbitrary }, { spacing }) => {
1366
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1367
- return v !== null ? { paddingVertical: v } : null;
1368
- },
1369
- pt: ({ value, negative, isArbitrary }, { spacing }) => {
1370
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1371
- return v !== null ? { paddingTop: v } : null;
1372
- },
1373
- pr: ({ value, negative, isArbitrary }, { spacing }) => {
1374
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1375
- return v !== null ? { paddingRight: v } : null;
1376
- },
1377
- pb: ({ value, negative, isArbitrary }, { spacing }) => {
1378
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1379
- return v !== null ? { paddingBottom: v } : null;
1380
- },
1381
- pl: ({ value, negative, isArbitrary }, { spacing }) => {
1382
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1383
- return v !== null ? { paddingLeft: v } : null;
1384
- },
1385
- // ── Margin ─────────────────────────────────────────────────────────────────
1386
- m: ({ value, negative, isArbitrary }, { spacing }) => {
1387
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1388
- return v !== null ? { margin: v } : null;
1389
- },
1390
- mx: ({ value, negative, isArbitrary }, { spacing }) => {
1391
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1392
- return v !== null ? { marginHorizontal: v } : null;
1393
- },
1394
- my: ({ value, negative, isArbitrary }, { spacing }) => {
1395
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1396
- return v !== null ? { marginVertical: v } : null;
1397
- },
1398
- mt: ({ value, negative, isArbitrary }, { spacing }) => {
1399
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1400
- return v !== null ? { marginTop: v } : null;
1401
- },
1402
- mr: ({ value, negative, isArbitrary }, { spacing }) => {
1403
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1404
- return v !== null ? { marginRight: v } : null;
1405
- },
1406
- mb: ({ value, negative, isArbitrary }, { spacing }) => {
1407
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1408
- return v !== null ? { marginBottom: v } : null;
1409
- },
1410
- ml: ({ value, negative, isArbitrary }, { spacing }) => {
1411
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1412
- return v !== null ? { marginLeft: v } : null;
1413
- },
1347
+ // ── Padding & margin ───────────────────────────────────────────────────────
1348
+ // Generated below via makeSpacingResolver() — see PADDING_MARGIN_PROPS.
1414
1349
  // ── Sizing ─────────────────────────────────────────────────────────────────
1415
1350
  w: ({ value, isArbitrary }, { spacing }) => {
1416
1351
  const v = resolveSizing(value, spacing, isArbitrary);
@@ -1454,54 +1389,7 @@ var RESOLVERS = {
1454
1389
  }
1455
1390
  return null;
1456
1391
  },
1457
- "border-t": ({ value, isArbitrary }, { colors, borderWidth }) => {
1458
- if (!value) return { borderTopWidth: 1 };
1459
- if (isArbitrary) {
1460
- const w2 = toNativeValue(value);
1461
- if (typeof w2 === "number") return { borderTopWidth: w2 };
1462
- return { borderTopColor: value };
1463
- }
1464
- const color = resolveColor(value, colors, false);
1465
- if (color) return { borderTopColor: color };
1466
- const w = borderWidth[value];
1467
- return w !== void 0 ? { borderTopWidth: w } : null;
1468
- },
1469
- "border-r": ({ value, isArbitrary }, { colors, borderWidth }) => {
1470
- if (!value) return { borderRightWidth: 1 };
1471
- if (isArbitrary) {
1472
- const w2 = toNativeValue(value);
1473
- if (typeof w2 === "number") return { borderRightWidth: w2 };
1474
- return { borderRightColor: value };
1475
- }
1476
- const color = resolveColor(value, colors, false);
1477
- if (color) return { borderRightColor: color };
1478
- const w = borderWidth[value];
1479
- return w !== void 0 ? { borderRightWidth: w } : null;
1480
- },
1481
- "border-b": ({ value, isArbitrary }, { colors, borderWidth }) => {
1482
- if (!value) return { borderBottomWidth: 1 };
1483
- if (isArbitrary) {
1484
- const w2 = toNativeValue(value);
1485
- if (typeof w2 === "number") return { borderBottomWidth: w2 };
1486
- return { borderBottomColor: value };
1487
- }
1488
- const color = resolveColor(value, colors, false);
1489
- if (color) return { borderBottomColor: color };
1490
- const w = borderWidth[value];
1491
- return w !== void 0 ? { borderBottomWidth: w } : null;
1492
- },
1493
- "border-l": ({ value, isArbitrary }, { colors, borderWidth }) => {
1494
- if (!value) return { borderLeftWidth: 1 };
1495
- if (isArbitrary) {
1496
- const w2 = toNativeValue(value);
1497
- if (typeof w2 === "number") return { borderLeftWidth: w2 };
1498
- return { borderLeftColor: value };
1499
- }
1500
- const color = resolveColor(value, colors, false);
1501
- if (color) return { borderLeftColor: color };
1502
- const w = borderWidth[value];
1503
- return w !== void 0 ? { borderLeftWidth: w } : null;
1504
- },
1392
+ // border-t/-r/-b/-l generated below via makeBorderSideResolver() — see BORDER_SIDE_PROPS.
1505
1393
  // ── Border radius ──────────────────────────────────────────────────────────
1506
1394
  rounded: ({ value, isArbitrary }, { borderRadius }) => {
1507
1395
  const r = resolveRadius(value, borderRadius, isArbitrary);
@@ -1733,49 +1621,49 @@ var RESOLVERS = {
1733
1621
  "2xl": "blur(40px)",
1734
1622
  "3xl": "blur(64px)"
1735
1623
  };
1736
- if (value === "none") return { "--tw-blur": "", filter: FILTER_COMPOSE };
1624
+ if (value === "none") return { "--kb-blur": "", filter: FILTER_COMPOSE };
1737
1625
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1738
- return v !== void 0 ? { "--tw-blur": v, filter: FILTER_COMPOSE } : null;
1626
+ return v !== void 0 ? { "--kb-blur": v, filter: FILTER_COMPOSE } : null;
1739
1627
  },
1740
1628
  brightness: ({ value, isArbitrary }) => {
1741
1629
  if (!getEffectiveIsWeb()) return null;
1742
1630
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1743
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-brightness": v, filter: FILTER_COMPOSE };
1631
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-brightness": v, filter: FILTER_COMPOSE };
1744
1632
  },
1745
1633
  contrast: ({ value, isArbitrary }) => {
1746
1634
  if (!getEffectiveIsWeb()) return null;
1747
1635
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1748
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-contrast": v, filter: FILTER_COMPOSE };
1636
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
1749
1637
  },
1750
1638
  grayscale: ({ value }) => {
1751
1639
  if (!getEffectiveIsWeb()) return null;
1752
1640
  const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
1753
- return { "--tw-grayscale": v, filter: FILTER_COMPOSE };
1641
+ return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
1754
1642
  },
1755
1643
  "hue-rotate": ({ value, negative, isArbitrary }) => {
1756
1644
  if (!getEffectiveIsWeb()) return null;
1757
1645
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1758
1646
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1759
- return { "--tw-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1647
+ return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1760
1648
  },
1761
1649
  invert: ({ value }) => {
1762
1650
  if (!getEffectiveIsWeb()) return null;
1763
1651
  const v = value === "0" ? "invert(0)" : "invert(100%)";
1764
- return { "--tw-invert": v, filter: FILTER_COMPOSE };
1652
+ return { "--kb-invert": v, filter: FILTER_COMPOSE };
1765
1653
  },
1766
1654
  saturate: ({ value, isArbitrary }) => {
1767
1655
  if (!getEffectiveIsWeb()) return null;
1768
1656
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1769
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-saturate": v, filter: FILTER_COMPOSE };
1657
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
1770
1658
  },
1771
1659
  sepia: ({ value }) => {
1772
1660
  if (!getEffectiveIsWeb()) return null;
1773
1661
  const v = value === "0" ? "sepia(0)" : "sepia(100%)";
1774
- return { "--tw-sepia": v, filter: FILTER_COMPOSE };
1662
+ return { "--kb-sepia": v, filter: FILTER_COMPOSE };
1775
1663
  },
1776
1664
  "drop-shadow": ({ value, isArbitrary }) => {
1777
1665
  if (!getEffectiveIsWeb()) return null;
1778
- if (isArbitrary) return { "--tw-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1666
+ if (isArbitrary) return { "--kb-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1779
1667
  const presets = {
1780
1668
  "": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
1781
1669
  sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
@@ -1786,7 +1674,7 @@ var RESOLVERS = {
1786
1674
  none: "drop-shadow(0 0 #0000)"
1787
1675
  };
1788
1676
  const v = presets[value];
1789
- return v !== void 0 ? { "--tw-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1677
+ return v !== void 0 ? { "--kb-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1790
1678
  },
1791
1679
  // Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
1792
1680
  filter: ({ value, isArbitrary }) => {
@@ -1807,47 +1695,47 @@ var RESOLVERS = {
1807
1695
  "2xl": "blur(40px)",
1808
1696
  "3xl": "blur(64px)"
1809
1697
  };
1810
- if (value === "none") return { "--tw-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1698
+ if (value === "none") return { "--kb-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1811
1699
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1812
- return v !== void 0 ? { "--tw-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1700
+ return v !== void 0 ? { "--kb-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1813
1701
  },
1814
1702
  "backdrop-brightness": ({ value, isArbitrary }) => {
1815
1703
  if (!getEffectiveIsWeb()) return null;
1816
1704
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1817
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1705
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1818
1706
  },
1819
1707
  "backdrop-contrast": ({ value, isArbitrary }) => {
1820
1708
  if (!getEffectiveIsWeb()) return null;
1821
1709
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1822
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1710
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1823
1711
  },
1824
1712
  "backdrop-grayscale": ({ value }) => {
1825
1713
  if (!getEffectiveIsWeb()) return null;
1826
- return { "--tw-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1714
+ return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1827
1715
  },
1828
1716
  "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
1829
1717
  if (!getEffectiveIsWeb()) return null;
1830
1718
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1831
1719
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1832
- return { "--tw-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1720
+ return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1833
1721
  },
1834
1722
  "backdrop-invert": ({ value }) => {
1835
1723
  if (!getEffectiveIsWeb()) return null;
1836
- return { "--tw-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1724
+ return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1837
1725
  },
1838
1726
  "backdrop-opacity": ({ value, isArbitrary }) => {
1839
1727
  if (!getEffectiveIsWeb()) return null;
1840
1728
  const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
1841
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1729
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1842
1730
  },
1843
1731
  "backdrop-saturate": ({ value, isArbitrary }) => {
1844
1732
  if (!getEffectiveIsWeb()) return null;
1845
1733
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1846
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1734
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1847
1735
  },
1848
1736
  "backdrop-sepia": ({ value }) => {
1849
1737
  if (!getEffectiveIsWeb()) return null;
1850
- return { "--tw-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1738
+ return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1851
1739
  },
1852
1740
  "backdrop-filter": ({ value, isArbitrary }) => {
1853
1741
  if (!getEffectiveIsWeb()) return null;
@@ -1871,7 +1759,7 @@ var RESOLVERS = {
1871
1759
  const dir = directions[value];
1872
1760
  if (!dir) return null;
1873
1761
  return {
1874
- backgroundImage: `linear-gradient(${dir}, var(--tw-gradient-from, transparent), var(--tw-gradient-stops, transparent))`
1762
+ backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
1875
1763
  };
1876
1764
  },
1877
1765
  from: ({ value, isArbitrary }, { colors }) => {
@@ -1879,8 +1767,8 @@ var RESOLVERS = {
1879
1767
  const color = resolveColor(value, colors, isArbitrary);
1880
1768
  if (!color) return null;
1881
1769
  return {
1882
- "--tw-gradient-from": color,
1883
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, transparent)`
1770
+ "--kb-gradient-from": color,
1771
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
1884
1772
  };
1885
1773
  },
1886
1774
  via: ({ value, isArbitrary }, { colors }) => {
@@ -1888,15 +1776,15 @@ var RESOLVERS = {
1888
1776
  const color = resolveColor(value, colors, isArbitrary);
1889
1777
  if (!color) return null;
1890
1778
  return {
1891
- "--tw-gradient-via": color,
1892
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to, transparent)`
1779
+ "--kb-gradient-via": color,
1780
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
1893
1781
  };
1894
1782
  },
1895
1783
  to: ({ value, isArbitrary }, { colors }) => {
1896
1784
  if (!getEffectiveIsWeb()) return null;
1897
1785
  const color = resolveColor(value, colors, isArbitrary);
1898
1786
  if (!color) return null;
1899
- return { "--tw-gradient-to": color };
1787
+ return { "--kb-gradient-to": color };
1900
1788
  },
1901
1789
  // ── Transform extras (web-only) ───────────────────────────────────────────
1902
1790
  "skew-x": ({ value, negative, isArbitrary }) => {
@@ -2500,6 +2388,12 @@ var RESOLVERS = {
2500
2388
  return { rowGap: v };
2501
2389
  }
2502
2390
  };
2391
+ for (const [utility, prop] of Object.entries(PADDING_MARGIN_PROPS)) {
2392
+ RESOLVERS[utility] = makeSpacingResolver(prop);
2393
+ }
2394
+ for (const [utility, [widthProp, colorProp]] of Object.entries(BORDER_SIDE_PROPS)) {
2395
+ RESOLVERS[utility] = makeBorderSideResolver(widthProp, colorProp);
2396
+ }
2503
2397
  function resolveUtility(parsed, theme) {
2504
2398
  if (!parsed.value) {
2505
2399
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
@@ -2770,7 +2664,20 @@ function getDefaultFontFamily() {
2770
2664
  return globalThis[FONT_KEY];
2771
2665
  }
2772
2666
  var _styleEl = null;
2773
- var _injectedRules = new LRUCache(5e4);
2667
+ function evictInjectedRule(rule) {
2668
+ const sheet = _styleEl?.sheet;
2669
+ if (!sheet) return;
2670
+ for (let i = 0; i < sheet.cssRules.length; i++) {
2671
+ if (sheet.cssRules[i].cssText === rule) {
2672
+ try {
2673
+ sheet.deleteRule(i);
2674
+ } catch {
2675
+ }
2676
+ return;
2677
+ }
2678
+ }
2679
+ }
2680
+ var _injectedRules = new LRUCache(5e4, evictInjectedRule);
2774
2681
  var _CSS_DISABLED_KEY = "__kbach_runtime_css_disabled__";
2775
2682
  function disableRuntimeCSS() {
2776
2683
  globalThis[_CSS_DISABLED_KEY] = true;
@@ -2807,8 +2714,7 @@ function injectGlobalStyles(theme) {
2807
2714
  if (typeof document === "undefined" || isRuntimeCSSDisabled()) return;
2808
2715
  const rules = [BASE_RESET];
2809
2716
  const ff = theme.fontFamily;
2810
- if (!ff) return;
2811
- if (ff.sans && ff.sans !== "System") {
2717
+ if (ff?.sans && ff.sans !== "System") {
2812
2718
  const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
2813
2719
  rules.push(`body { font-family: ${family}; }`);
2814
2720
  }
@@ -2971,7 +2877,7 @@ function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens
2971
2877
  else rule = `[data-theme="dark"] ${selector} { ${decls} }`;
2972
2878
  } else if (darkScheme === "light") {
2973
2879
  if (darkMode === "media") rule = `@media (prefers-color-scheme: light) { ${selector} { ${decls} } }`;
2974
- else if (darkMode === "class") rule = `:not(.dark) ${selector} { ${decls} }`;
2880
+ else if (darkMode === "class") rule = `.light ${selector} { ${decls} }`;
2975
2881
  else rule = `[data-theme="light"] ${selector} { ${decls} }`;
2976
2882
  } else {
2977
2883
  rule = `${selector} { ${decls} }`;
@@ -3102,11 +3008,14 @@ function getConfig() {
3102
3008
  return store.resolved;
3103
3009
  }
3104
3010
  function resolveOneRef(ref, colors) {
3105
- const m = /^([a-z][a-z0-9]*)-(\d+)$/.exec(ref);
3106
- if (!m) return null;
3107
- const entry = colors[m[1]];
3011
+ const lastDash = ref.lastIndexOf("-");
3012
+ if (lastDash <= 0) return null;
3013
+ const name = ref.slice(0, lastDash);
3014
+ const shade = ref.slice(lastDash + 1);
3015
+ if (!/^\d+$/.test(shade)) return null;
3016
+ const entry = colors[name];
3108
3017
  if (!entry || typeof entry !== "object") return null;
3109
- return entry[m[2]] ?? null;
3018
+ return entry[shade] ?? null;
3110
3019
  }
3111
3020
  function resolveColorRefs(colors) {
3112
3021
  const MAX_DEPTH = 5;
@@ -3136,7 +3045,7 @@ function resolveColorRefs(colors) {
3136
3045
  function buildConfig(userConfig) {
3137
3046
  let theme = { ...defaultTheme };
3138
3047
  if (userConfig.theme) {
3139
- theme = deepMerge(theme, userConfig.theme);
3048
+ theme = { ...theme, ...userConfig.theme };
3140
3049
  }
3141
3050
  if (userConfig.extend) {
3142
3051
  const extendConfig = userConfig.extend;
@@ -3285,6 +3194,74 @@ function subscribeGlobalDarkMode(callback) {
3285
3194
  return () => store.subscribers.delete(callback);
3286
3195
  }
3287
3196
 
3197
+ // src/useColors.ts
3198
+ function applyOpacity(color, opacity) {
3199
+ const a = Math.max(0, Math.min(1, opacity / 100));
3200
+ if (color.startsWith("#")) {
3201
+ const rgb = parseHexRgb(color);
3202
+ if (!rgb) return color;
3203
+ const [r, g, b] = rgb;
3204
+ return `rgba(${r},${g},${b},${a})`;
3205
+ }
3206
+ if (color.startsWith("rgb(")) return color.replace("rgb(", "rgba(").replace(")", `,${a})`);
3207
+ if (color.startsWith("rgba(")) return color.replace(/,\s*[\d.]+\)$/, `,${a})`);
3208
+ return color;
3209
+ }
3210
+ function makeShadeProxy(shades) {
3211
+ return new Proxy(shades, {
3212
+ get(target, prop) {
3213
+ const key = String(prop);
3214
+ if (key === "then") return void 0;
3215
+ if (key.includes("/")) {
3216
+ const slash = key.indexOf("/");
3217
+ const shade = key.slice(0, slash);
3218
+ const op = Number(key.slice(slash + 1));
3219
+ const color = target[shade];
3220
+ return typeof color === "string" ? applyOpacity(color, op) : void 0;
3221
+ }
3222
+ return target[key];
3223
+ }
3224
+ });
3225
+ }
3226
+ function wrapColors(rawColors) {
3227
+ const cache = /* @__PURE__ */ new Map();
3228
+ const alpha = (color, opacity) => opacity === void 0 ? color : applyOpacity(color, opacity);
3229
+ return new Proxy({ alpha }, {
3230
+ get(_, prop) {
3231
+ const key = String(prop);
3232
+ if (key === "then") return void 0;
3233
+ if (key === "alpha") return alpha;
3234
+ if (key.includes("/")) {
3235
+ const slash = key.indexOf("/");
3236
+ const name = key.slice(0, slash);
3237
+ const op = Number(key.slice(slash + 1));
3238
+ const entry2 = rawColors[name];
3239
+ return typeof entry2 === "string" ? applyOpacity(entry2, op) : void 0;
3240
+ }
3241
+ const entry = rawColors[key];
3242
+ if (entry === void 0) return void 0;
3243
+ if (typeof entry === "string") return entry;
3244
+ if (!cache.has(key)) cache.set(key, makeShadeProxy(entry));
3245
+ return cache.get(key);
3246
+ }
3247
+ });
3248
+ }
3249
+ function useColors() {
3250
+ const { config } = useTheme();
3251
+ return (0, import_react2.useMemo)(() => wrapColors(config.theme.colors), [config.theme.colors]);
3252
+ }
3253
+
3254
+ // src/ThemeProvider.tsx
3255
+ var import_react4 = require("react");
3256
+
3257
+ // src/useSyncExternalStoreShim.ts
3258
+ var import_react3 = __toESM(require("react"));
3259
+ var useSyncExternalStore = import_react3.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
3260
+ const [, forceUpdate] = import_react3.default.useReducer((n) => n + 1, 0);
3261
+ import_react3.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
3262
+ return getSnapshot();
3263
+ };
3264
+
3288
3265
  // src/ThemeProvider.tsx
3289
3266
  var import_jsx_runtime = require("react/jsx-runtime");
3290
3267
  var STORAGE_KEY = "kbach-theme";
@@ -3302,6 +3279,22 @@ function persistMode(mode) {
3302
3279
  } catch {
3303
3280
  }
3304
3281
  }
3282
+ function subscribeSystemScheme(callback) {
3283
+ if (!isWeb || typeof window === "undefined") return () => {
3284
+ };
3285
+ const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
3286
+ if (!mq) return () => {
3287
+ };
3288
+ mq.addEventListener("change", callback);
3289
+ return () => mq.removeEventListener("change", callback);
3290
+ }
3291
+ function getSystemScheme() {
3292
+ if (!isWeb || typeof window === "undefined") return "light";
3293
+ return window.matchMedia?.("(prefers-color-scheme: dark)")?.matches ? "dark" : "light";
3294
+ }
3295
+ function getSystemSchemeServerSnapshot() {
3296
+ return "light";
3297
+ }
3305
3298
  function applyWebTheme(resolvedMode, strategy) {
3306
3299
  if (!isWeb) return;
3307
3300
  const root = document.documentElement;
@@ -3320,35 +3313,34 @@ function ThemeProvider({
3320
3313
  config: configOverride,
3321
3314
  disablePersistence = false
3322
3315
  }) {
3323
- const [resolvedConfig, setResolvedConfig] = (0, import_react3.useState)(
3316
+ const [resolvedConfig, setResolvedConfig] = (0, import_react4.useState)(
3324
3317
  () => configOverride ? buildConfig(configOverride) : getConfig()
3325
3318
  );
3326
- const [webWidth, setWebWidth] = (0, import_react3.useState)(
3327
- () => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
3328
- );
3319
+ const [webWidth, setWebWidth] = (0, import_react4.useState)(0);
3329
3320
  const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
3330
- const numericScreens = (0, import_react3.useMemo)(() => {
3321
+ const numericScreens = (0, import_react4.useMemo)(() => {
3331
3322
  const out = {};
3332
3323
  for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
3333
3324
  out[k] = typeof v === "number" ? v : parseInt(String(v), 10);
3334
3325
  }
3335
3326
  return out;
3336
3327
  }, [resolvedConfig.theme.screens]);
3337
- const _prevWidthRef = (0, import_react3.useRef)(-1);
3328
+ const _prevWidthRef = (0, import_react4.useRef)(-1);
3338
3329
  if (_prevWidthRef.current !== effectiveWidth) {
3339
3330
  _prevWidthRef.current = effectiveWidth;
3340
3331
  syncGlobalWidth(effectiveWidth);
3341
3332
  }
3342
- const _prevScreensRef = (0, import_react3.useRef)(null);
3333
+ const _prevScreensRef = (0, import_react4.useRef)(null);
3343
3334
  if (_prevScreensRef.current !== numericScreens) {
3344
3335
  _prevScreensRef.current = numericScreens;
3345
3336
  syncGlobalScreens(numericScreens);
3346
3337
  }
3347
- (0, import_react3.useEffect)(() => {
3338
+ (0, import_react4.useEffect)(() => {
3348
3339
  setGlobalWidth(effectiveWidth);
3349
3340
  }, [effectiveWidth]);
3350
- (0, import_react3.useEffect)(() => {
3341
+ (0, import_react4.useEffect)(() => {
3351
3342
  if (!isWeb || typeof window === "undefined") return;
3343
+ setWebWidth(window.innerWidth);
3352
3344
  let raf = 0;
3353
3345
  const update = () => {
3354
3346
  cancelAnimationFrame(raf);
@@ -3364,52 +3356,38 @@ function ThemeProvider({
3364
3356
  cancelAnimationFrame(raf);
3365
3357
  };
3366
3358
  }, []);
3367
- const [webScheme, setWebScheme] = (0, import_react3.useState)(() => {
3368
- if (isWeb && typeof window !== "undefined") {
3369
- return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
3370
- }
3371
- return "light";
3372
- });
3359
+ const webScheme = useSyncExternalStore(
3360
+ subscribeSystemScheme,
3361
+ getSystemScheme,
3362
+ getSystemSchemeServerSnapshot
3363
+ );
3373
3364
  const systemScheme = isWeb ? webScheme : colorScheme === "dark" ? "dark" : "light";
3374
- const [mode, _setMode] = (0, import_react3.useState)(() => {
3375
- if (!disablePersistence) {
3376
- const persisted = loadPersistedMode();
3377
- if (persisted) return persisted;
3378
- }
3379
- return defaultMode;
3380
- });
3381
- const setMode = (0, import_react3.useCallback)((next) => {
3365
+ const [mode, _setMode] = (0, import_react4.useState)(defaultMode);
3366
+ (0, import_react4.useEffect)(() => {
3367
+ if (disablePersistence) return;
3368
+ const persisted = loadPersistedMode();
3369
+ if (persisted) _setMode(persisted);
3370
+ }, []);
3371
+ const setMode = (0, import_react4.useCallback)((next) => {
3382
3372
  _setMode(next);
3383
3373
  if (!disablePersistence) persistMode(next);
3384
3374
  }, [disablePersistence]);
3385
- const toggle = (0, import_react3.useCallback)(() => {
3375
+ const toggle = (0, import_react4.useCallback)(() => {
3386
3376
  setMode(mode === "dark" || mode === "system" && systemScheme === "dark" ? "light" : "dark");
3387
3377
  }, [mode, systemScheme, setMode]);
3388
3378
  const resolvedMode = mode === "system" ? systemScheme : mode;
3389
3379
  const isDark = resolvedMode === "dark";
3390
3380
  syncGlobalDarkMode(isDark);
3391
- (0, import_react3.useEffect)(() => {
3381
+ (0, import_react4.useEffect)(() => {
3392
3382
  applyWebTheme(resolvedMode, resolvedConfig.darkMode);
3393
3383
  setGlobalDarkMode(isDark);
3394
3384
  }, [isDark, resolvedMode, resolvedConfig.darkMode]);
3395
- const setWebSchemeRef = (0, import_react3.useRef)(setWebScheme);
3396
- setWebSchemeRef.current = setWebScheme;
3397
- (0, import_react3.useEffect)(() => {
3398
- if (!isWeb || typeof window === "undefined") return;
3399
- const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
3400
- if (!mq) return;
3401
- const handler = (e) => {
3402
- setWebSchemeRef.current(e.matches ? "dark" : "light");
3403
- };
3404
- mq.addEventListener("change", handler);
3405
- return () => mq.removeEventListener("change", handler);
3406
- }, []);
3407
- (0, import_react3.useEffect)(() => {
3385
+ (0, import_react4.useEffect)(() => {
3408
3386
  if (!configOverride) return;
3409
3387
  updateConfig(configOverride);
3410
3388
  setResolvedConfig(getConfig());
3411
3389
  }, [configOverride]);
3412
- (0, import_react3.useEffect)(() => {
3390
+ (0, import_react4.useEffect)(() => {
3413
3391
  if (configOverride) return;
3414
3392
  let mounted = true;
3415
3393
  const unsub = onConfigChange((config) => {
@@ -3420,162 +3398,17 @@ function ThemeProvider({
3420
3398
  unsub();
3421
3399
  };
3422
3400
  }, [configOverride]);
3423
- const contextValue = (0, import_react3.useMemo)(
3401
+ const contextValue = (0, import_react4.useMemo)(
3424
3402
  () => ({ mode, resolvedMode, isDark, setMode, toggle, config: resolvedConfig }),
3425
3403
  [mode, resolvedMode, isDark, setMode, toggle, resolvedConfig]
3426
3404
  );
3427
3405
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: contextValue, children });
3428
3406
  }
3429
3407
 
3430
- // src/ThemeToggle.tsx
3431
- var import_react4 = __toESM(require("react"));
3432
- function getPrimitives() {
3433
- try {
3434
- const RN = require("react-native");
3435
- return {
3436
- View: RN.View,
3437
- Text: RN.Text,
3438
- Touchable: RN.TouchableOpacity,
3439
- Switch: RN.Switch
3440
- };
3441
- } catch {
3442
- const View = ({ style, ...rest }) => import_react4.default.createElement("div", { style, ...rest });
3443
- const Text = ({ style, ...rest }) => import_react4.default.createElement("span", { style, ...rest });
3444
- const Touchable = ({ onPress, style, ...rest }) => import_react4.default.createElement("button", { onClick: onPress, style, ...rest });
3445
- const Switch = ({
3446
- value,
3447
- onValueChange,
3448
- accessibilityLabel
3449
- }) => import_react4.default.createElement("input", {
3450
- type: "checkbox",
3451
- checked: value,
3452
- onChange: (e) => onValueChange?.(e.target.checked),
3453
- "aria-label": accessibilityLabel
3454
- });
3455
- return { View, Text, Touchable, Switch };
3456
- }
3457
- }
3458
- var { View: _View, Text: _Text, Touchable: _Touchable, Switch: _Switch } = getPrimitives();
3459
- function ThemeToggle({
3460
- variant = "button",
3461
- label,
3462
- lightLabel = "Light",
3463
- darkLabel = "Dark",
3464
- includeSystem = false,
3465
- style,
3466
- labelStyle
3467
- }) {
3468
- const { mode, isDark, setMode, toggle } = useTheme();
3469
- const View = _View, Text = _Text, Touchable = _Touchable, Switch = _Switch;
3470
- if (variant === "switch") {
3471
- return import_react4.default.createElement(
3472
- View,
3473
- { style: { flexDirection: "row", alignItems: "center", gap: 8, ...style } },
3474
- import_react4.default.createElement(Text, { style: { fontSize: 14, ...labelStyle } }, lightLabel),
3475
- import_react4.default.createElement(Switch, {
3476
- value: isDark,
3477
- onValueChange: (v) => setMode(v ? "dark" : "light"),
3478
- trackColor: { false: "#d1d5db", true: "#6366f1" },
3479
- thumbColor: isDark ? "#ffffff" : "#f3f4f6",
3480
- ios_backgroundColor: "#d1d5db",
3481
- accessibilityLabel: "Toggle dark mode"
3482
- }),
3483
- import_react4.default.createElement(Text, { style: { fontSize: 14, ...labelStyle } }, darkLabel)
3484
- );
3485
- }
3486
- if (variant === "icon-button") {
3487
- const icon = isDark ? darkLabel : lightLabel;
3488
- return import_react4.default.createElement(
3489
- Touchable,
3490
- {
3491
- onPress: toggle,
3492
- style: {
3493
- padding: 8,
3494
- borderRadius: 8,
3495
- backgroundColor: isDark ? "#374151" : "#f3f4f6",
3496
- ...style
3497
- },
3498
- accessibilityRole: "button",
3499
- accessibilityLabel: `Switch to ${isDark ? "light" : "dark"} mode`,
3500
- accessibilityState: {}
3501
- },
3502
- import_react4.default.createElement(Text, { style: { fontSize: 18, ...labelStyle } }, icon)
3503
- );
3504
- }
3505
- if (includeSystem) {
3506
- const modes = [
3507
- { key: "light", label: lightLabel },
3508
- { key: "dark", label: darkLabel },
3509
- { key: "system", label: "System" }
3510
- ];
3511
- return import_react4.default.createElement(
3512
- View,
3513
- { style: { flexDirection: "row", gap: 4, ...style } },
3514
- ...modes.map(
3515
- ({ key, label: mLabel }) => import_react4.default.createElement(
3516
- Touchable,
3517
- {
3518
- key,
3519
- onPress: () => setMode(key),
3520
- style: {
3521
- paddingHorizontal: 12,
3522
- paddingVertical: 6,
3523
- borderRadius: 6,
3524
- backgroundColor: mode === key ? isDark ? "#6366f1" : "#3b82f6" : isDark ? "#374151" : "#e5e7eb"
3525
- },
3526
- accessibilityRole: "button",
3527
- accessibilityLabel: `Set ${key} theme`,
3528
- accessibilityState: { selected: mode === key }
3529
- },
3530
- import_react4.default.createElement(Text, {
3531
- style: {
3532
- fontSize: 13,
3533
- fontWeight: "500",
3534
- color: mode === key ? "#ffffff" : isDark ? "#d1d5db" : "#374151",
3535
- ...labelStyle
3536
- }
3537
- }, mLabel)
3538
- )
3539
- )
3540
- );
3541
- }
3542
- const currentLabel = label ?? (isDark ? darkLabel : lightLabel);
3543
- return import_react4.default.createElement(
3544
- Touchable,
3545
- {
3546
- onPress: toggle,
3547
- style: {
3548
- paddingHorizontal: 16,
3549
- paddingVertical: 8,
3550
- borderRadius: 8,
3551
- backgroundColor: isDark ? "#374151" : "#e5e7eb",
3552
- ...style
3553
- },
3554
- accessibilityRole: "button",
3555
- accessibilityLabel: `Switch to ${isDark ? "light" : "dark"} mode`,
3556
- accessibilityState: {}
3557
- },
3558
- import_react4.default.createElement(Text, {
3559
- style: {
3560
- fontSize: 14,
3561
- fontWeight: "500",
3562
- color: isDark ? "#f9fafb" : "#111827",
3563
- ...labelStyle
3564
- }
3565
- }, currentLabel)
3566
- );
3567
- }
3568
-
3569
3408
  // src/styled.tsx
3570
- var import_react7 = __toESM(require("react"));
3409
+ var import_react5 = __toESM(require("react"));
3571
3410
 
3572
3411
  // src/useGlobalDarkMode.ts
3573
- var import_react5 = __toESM(require("react"));
3574
- var useSyncExternalStore = import_react5.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
3575
- const [, forceUpdate] = import_react5.default.useReducer((n) => n + 1, 0);
3576
- import_react5.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
3577
- return getSnapshot();
3578
- };
3579
3412
  function useGlobalDarkMode() {
3580
3413
  return useSyncExternalStore(
3581
3414
  subscribeGlobalDarkMode,
@@ -3586,12 +3419,6 @@ function useGlobalDarkMode() {
3586
3419
  }
3587
3420
 
3588
3421
  // src/useGlobalWidth.ts
3589
- var import_react6 = __toESM(require("react"));
3590
- var useSyncExternalStore2 = import_react6.default.useSyncExternalStore ?? function useSyncExternalStoreFallback2(subscribe, getSnapshot, _getServerSnapshot) {
3591
- const [, forceUpdate] = import_react6.default.useReducer((n) => n + 1, 0);
3592
- import_react6.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
3593
- return getSnapshot();
3594
- };
3595
3422
  var NOOP_SUB = (_) => () => {
3596
3423
  };
3597
3424
  var ZERO_SNAP = () => 0;
@@ -3625,14 +3452,14 @@ function getWebWidth() {
3625
3452
  return typeof window !== "undefined" ? window.innerWidth : 0;
3626
3453
  }
3627
3454
  function useGlobalWidth() {
3628
- return useSyncExternalStore2(
3455
+ return useSyncExternalStore(
3629
3456
  isWeb ? subscribeWebWidth : subscribeGlobalWidth,
3630
3457
  isWeb ? getWebWidth : getGlobalWidth,
3631
3458
  ZERO_SNAP
3632
3459
  );
3633
3460
  }
3634
3461
  function useConditionalWidth(active) {
3635
- return useSyncExternalStore2(
3462
+ return useSyncExternalStore(
3636
3463
  active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
3637
3464
  active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
3638
3465
  ZERO_SNAP
@@ -3660,6 +3487,42 @@ function hasInteractiveBuckets(resolved) {
3660
3487
  }
3661
3488
  return false;
3662
3489
  }
3490
+ function chain(original, extra) {
3491
+ return (...args) => {
3492
+ original?.(...args);
3493
+ extra();
3494
+ };
3495
+ }
3496
+ function stripInternalMarkers(s) {
3497
+ delete s.__divideX;
3498
+ delete s.__divideY;
3499
+ delete s.__divideColor;
3500
+ delete s.__divideStyle;
3501
+ delete s.__keyframe;
3502
+ }
3503
+ function stripWebOnlyProps(s) {
3504
+ if (s.display === "grid" || s.display === "inline-grid") delete s.display;
3505
+ delete s.gridTemplateColumns;
3506
+ delete s.gridTemplateRows;
3507
+ delete s.gridColumn;
3508
+ delete s.gridRow;
3509
+ delete s.gridArea;
3510
+ delete s.gridColumnStart;
3511
+ delete s.gridColumnEnd;
3512
+ delete s.gridRowStart;
3513
+ delete s.gridRowEnd;
3514
+ delete s.gridAutoFlow;
3515
+ delete s.gridAutoColumns;
3516
+ delete s.gridAutoRows;
3517
+ delete s.placeItems;
3518
+ delete s.placeContent;
3519
+ delete s.justifyItems;
3520
+ delete s.placeSelf;
3521
+ delete s.justifySelf;
3522
+ if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
3523
+ delete s.position;
3524
+ }
3525
+ }
3663
3526
 
3664
3527
  // src/web-substitute.ts
3665
3528
  var _rnToHtml = {
@@ -3909,13 +3772,11 @@ function transformToWebProps(originalName, tag, props) {
3909
3772
  continue;
3910
3773
  }
3911
3774
  if (k === "resizeMode") {
3912
- const existing = out.style ?? {};
3913
- out.style = { ...existing, objectFit: _resizeModeMap[v] ?? "cover" };
3775
+ pendingStyle = { ...pendingStyle ?? {}, objectFit: _resizeModeMap[v] ?? "cover" };
3914
3776
  continue;
3915
3777
  }
3916
3778
  if (k === "contentFit") {
3917
- const existing = out.style ?? {};
3918
- out.style = { ...existing, objectFit: v };
3779
+ pendingStyle = { ...pendingStyle ?? {}, objectFit: v };
3919
3780
  continue;
3920
3781
  }
3921
3782
  if (k === "defaultSource") continue;
@@ -3940,7 +3801,7 @@ function transformToWebProps(originalName, tag, props) {
3940
3801
 
3941
3802
  // src/styled.tsx
3942
3803
  function styled(Component, baseClasses = "") {
3943
- const Styled = (0, import_react7.forwardRef)(
3804
+ const Styled = (0, import_react5.forwardRef)(
3944
3805
  (props, ref) => {
3945
3806
  const {
3946
3807
  kb: extraClasses,
@@ -3950,6 +3811,7 @@ function styled(Component, baseClasses = "") {
3950
3811
  onPointerDown,
3951
3812
  onPointerUp,
3952
3813
  onPointerLeave,
3814
+ onPointerCancel,
3953
3815
  onMouseEnter,
3954
3816
  onMouseLeave,
3955
3817
  onFocus,
@@ -3960,52 +3822,26 @@ function styled(Component, baseClasses = "") {
3960
3822
  const checked = !!props.checked;
3961
3823
  const { config } = useTheme();
3962
3824
  const isDark = useGlobalDarkMode();
3963
- const [pressed, setPressed] = (0, import_react7.useState)(false);
3964
- const [hovered, setHovered] = (0, import_react7.useState)(false);
3965
- const [focused, setFocused] = (0, import_react7.useState)(false);
3966
- const handlePressIn = (0, import_react7.useCallback)((e) => {
3967
- setPressed(true);
3968
- onPressIn?.(e);
3969
- }, [onPressIn]);
3970
- const handlePressOut = (0, import_react7.useCallback)((e) => {
3971
- setPressed(false);
3972
- onPressOut?.(e);
3973
- }, [onPressOut]);
3974
- const handlePointerDown = (0, import_react7.useCallback)((e) => {
3975
- setPressed(true);
3976
- onPointerDown?.(e);
3977
- }, [onPointerDown]);
3978
- const handlePointerUp = (0, import_react7.useCallback)((e) => {
3979
- setPressed(false);
3980
- onPointerUp?.(e);
3981
- }, [onPointerUp]);
3982
- const handlePointerLeave = (0, import_react7.useCallback)((e) => {
3983
- setPressed(false);
3984
- onPointerLeave?.(e);
3985
- }, [onPointerLeave]);
3986
- const handleMouseEnter = (0, import_react7.useCallback)((e) => {
3987
- setHovered(true);
3988
- onMouseEnter?.(e);
3989
- }, [onMouseEnter]);
3990
- const handleMouseLeave = (0, import_react7.useCallback)((e) => {
3991
- setHovered(false);
3992
- onMouseLeave?.(e);
3993
- }, [onMouseLeave]);
3994
- const handleFocus = (0, import_react7.useCallback)((e) => {
3995
- setFocused(true);
3996
- onFocus?.(e);
3997
- }, [onFocus]);
3998
- const handleBlur = (0, import_react7.useCallback)((e) => {
3999
- setFocused(false);
4000
- onBlur?.(e);
4001
- }, [onBlur]);
3825
+ const [pressed, setPressed] = (0, import_react5.useState)(false);
3826
+ const [hovered, setHovered] = (0, import_react5.useState)(false);
3827
+ const [focused, setFocused] = (0, import_react5.useState)(false);
3828
+ const handlePressIn = (0, import_react5.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
3829
+ const handlePressOut = (0, import_react5.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
3830
+ const handlePointerDown = (0, import_react5.useCallback)(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
3831
+ const handlePointerUp = (0, import_react5.useCallback)(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
3832
+ const handlePointerLeave = (0, import_react5.useCallback)(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
3833
+ const handlePointerCancel = (0, import_react5.useCallback)(chain(onPointerCancel, () => setPressed(false)), [onPointerCancel]);
3834
+ const handleMouseEnter = (0, import_react5.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
3835
+ const handleMouseLeave = (0, import_react5.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
3836
+ const handleFocus = (0, import_react5.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
3837
+ const handleBlur = (0, import_react5.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
4002
3838
  const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
4003
- const resolved = (0, import_react7.useMemo)(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
4004
- const hasInteractive = (0, import_react7.useMemo)(() => hasInteractiveBuckets(resolved), [resolved]);
3839
+ const resolved = (0, import_react5.useMemo)(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
3840
+ const hasInteractive = (0, import_react5.useMemo)(() => hasInteractiveBuckets(resolved), [resolved]);
4005
3841
  const needsWidth = hasResponsiveBuckets(resolved);
4006
3842
  const width = useConditionalWidth(needsWidth);
4007
3843
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
4008
- const computedStyle = (0, import_react7.useMemo)(
3844
+ const computedStyle = (0, import_react5.useMemo)(
4009
3845
  () => isWeb ? {} : flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
4010
3846
  [resolved, isDark, pressed, hovered, focused, disabled, checked, width]
4011
3847
  // eslint-disable-line react-hooks/exhaustive-deps
@@ -4016,7 +3852,7 @@ function styled(Component, baseClasses = "") {
4016
3852
  const effectiveComponent = webTag ?? Component;
4017
3853
  const componentName2 = Component.displayName ?? Component.name ?? "";
4018
3854
  const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, webTag, rest) : rest;
4019
- return import_react7.default.createElement(effectiveComponent, {
3855
+ return import_react5.default.createElement(effectiveComponent, {
4020
3856
  ref,
4021
3857
  ...effectiveRest,
4022
3858
  style: finalStyle,
@@ -4026,7 +3862,7 @@ function styled(Component, baseClasses = "") {
4026
3862
  // Always forward user-provided handlers to avoid silently swallowing them.
4027
3863
  // onPressIn/onPressOut are forwarded on web too (not just native) since
4028
3864
  // react-native-web components rely on receiving them directly.
4029
- ...isWeb ? hasInteractive ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerLeave, onPressIn, onPressOut } : { onPointerDown, onPointerUp, onPointerLeave, onPressIn, onPressOut } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
3865
+ ...isWeb ? hasInteractive ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerCancel, onPressIn, onPressOut } : { onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, onPressIn, onPressOut } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
4030
3866
  onMouseEnter: hasInteractive ? handleMouseEnter : onMouseEnter,
4031
3867
  onMouseLeave: hasInteractive ? handleMouseLeave : onMouseLeave,
4032
3868
  onFocus: hasInteractive ? handleFocus : onFocus,
@@ -4040,12 +3876,12 @@ function styled(Component, baseClasses = "") {
4040
3876
  }
4041
3877
 
4042
3878
  // src/useStyles.ts
4043
- var import_react8 = require("react");
3879
+ var import_react6 = require("react");
4044
3880
  function useStyles(classString, state = {}) {
4045
3881
  const { isDark, config } = useTheme();
4046
3882
  const width = useGlobalWidth();
4047
3883
  const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
4048
- return (0, import_react8.useMemo)(() => {
3884
+ return (0, import_react6.useMemo)(() => {
4049
3885
  const resolved = resolve(normalised, config.theme, config.darkMode);
4050
3886
  const breakpoints = getActiveBreakpoints(width);
4051
3887
  return flatten(resolved, isDark, state, breakpoints);
@@ -4054,20 +3890,20 @@ function useStyles(classString, state = {}) {
4054
3890
  function useResolvedStyle(classString) {
4055
3891
  const { config } = useTheme();
4056
3892
  const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
4057
- return (0, import_react8.useMemo)(
3893
+ return (0, import_react6.useMemo)(
4058
3894
  () => resolve(normalised, config.theme, config.darkMode),
4059
3895
  [normalised, config]
4060
3896
  );
4061
3897
  }
4062
3898
 
4063
3899
  // src/useBreakpoint.ts
4064
- var import_react9 = require("react");
3900
+ var import_react7 = require("react");
4065
3901
  function useBreakpoint() {
4066
3902
  const { config } = useTheme();
4067
3903
  const width = useGlobalWidth();
4068
3904
  const screens = config.theme.screens;
4069
- const sorted = (0, import_react9.useMemo)(
4070
- () => Object.entries(screens).filter((entry) => typeof entry[1] === "number").sort(([, a], [, b]) => b - a),
3905
+ const sorted = (0, import_react7.useMemo)(
3906
+ () => Object.entries(screens).map(([name, v]) => [name, typeof v === "number" ? v : parseInt(String(v), 10)]).filter(([, minW]) => !Number.isNaN(minW)).sort(([, a], [, b]) => b - a),
4071
3907
  [screens]
4072
3908
  );
4073
3909
  for (const [name, minW] of sorted) {
@@ -4079,24 +3915,19 @@ function useResponsive() {
4079
3915
  const { config } = useTheme();
4080
3916
  const width = useGlobalWidth();
4081
3917
  const screens = config.theme.screens;
4082
- return (0, import_react9.useMemo)(() => {
3918
+ return (0, import_react7.useMemo)(() => {
4083
3919
  const result = {};
4084
- for (const [name, minW] of Object.entries(screens)) {
4085
- if (typeof minW === "number") result[name] = width >= minW;
3920
+ for (const [name, v] of Object.entries(screens)) {
3921
+ const minW = typeof v === "number" ? v : parseInt(String(v), 10);
3922
+ if (!Number.isNaN(minW)) result[name] = width >= minW;
4086
3923
  }
4087
3924
  return result;
4088
3925
  }, [screens, width]);
4089
3926
  }
4090
3927
 
4091
3928
  // src/InteractiveWrapper.tsx
4092
- var import_react10 = __toESM(require("react"));
4093
- function chain(original, extra) {
4094
- return (...args) => {
4095
- original?.(...args);
4096
- extra();
4097
- };
4098
- }
4099
- var InteractiveWrapper = (0, import_react10.forwardRef)(
3929
+ var import_react8 = __toESM(require("react"));
3930
+ var InteractiveWrapper = (0, import_react8.forwardRef)(
4100
3931
  function InteractiveWrapper2({
4101
3932
  Component,
4102
3933
  resolvedStyle,
@@ -4107,6 +3938,7 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
4107
3938
  onPointerDown,
4108
3939
  onPointerUp,
4109
3940
  onPointerLeave,
3941
+ onPointerCancel,
4110
3942
  onMouseEnter,
4111
3943
  onMouseLeave,
4112
3944
  onFocus,
@@ -4117,51 +3949,26 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
4117
3949
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
4118
3950
  const width = useConditionalWidth(needsWidth);
4119
3951
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
4120
- const [pressed, setPressed] = (0, import_react10.useState)(false);
4121
- const [hovered, setHovered] = (0, import_react10.useState)(false);
4122
- const [focused, setFocused] = (0, import_react10.useState)(false);
4123
- const handlePressIn = (0, import_react10.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
4124
- const handlePressOut = (0, import_react10.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
4125
- const handlePointerDown = (0, import_react10.useCallback)(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
4126
- const handlePointerUp = (0, import_react10.useCallback)(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
4127
- const handlePointerLeave = (0, import_react10.useCallback)(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
4128
- const handleMouseEnter = (0, import_react10.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
4129
- const handleMouseLeave = (0, import_react10.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
4130
- const handleFocus = (0, import_react10.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
4131
- const handleBlur = (0, import_react10.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3952
+ const [pressed, setPressed] = (0, import_react8.useState)(false);
3953
+ const [hovered, setHovered] = (0, import_react8.useState)(false);
3954
+ const [focused, setFocused] = (0, import_react8.useState)(false);
3955
+ const handlePressIn = (0, import_react8.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
3956
+ const handlePressOut = (0, import_react8.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
3957
+ const handlePointerDown = (0, import_react8.useCallback)(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
3958
+ const handlePointerUp = (0, import_react8.useCallback)(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
3959
+ const handlePointerLeave = (0, import_react8.useCallback)(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
3960
+ const handlePointerCancel = (0, import_react8.useCallback)(chain(onPointerCancel, () => setPressed(false)), [onPointerCancel]);
3961
+ const handleMouseEnter = (0, import_react8.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
3962
+ const handleMouseLeave = (0, import_react8.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
3963
+ const handleFocus = (0, import_react8.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
3964
+ const handleBlur = (0, import_react8.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
4132
3965
  const { children, disabled, checked, ...restForComponent } = rest;
4133
- const computedStyle = (0, import_react10.useMemo)(
3966
+ const computedStyle = (0, import_react8.useMemo)(
4134
3967
  () => {
4135
3968
  if (isWeb) return {};
4136
3969
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
4137
- delete s.__divideX;
4138
- delete s.__divideY;
4139
- delete s.__divideColor;
4140
- delete s.__divideStyle;
4141
- delete s.__keyframe;
4142
- if (typeof Component !== "string") {
4143
- if (s.display === "grid" || s.display === "inline-grid") delete s.display;
4144
- delete s.gridTemplateColumns;
4145
- delete s.gridTemplateRows;
4146
- delete s.gridColumn;
4147
- delete s.gridRow;
4148
- delete s.gridArea;
4149
- delete s.gridColumnStart;
4150
- delete s.gridColumnEnd;
4151
- delete s.gridRowStart;
4152
- delete s.gridRowEnd;
4153
- delete s.gridAutoFlow;
4154
- delete s.gridAutoColumns;
4155
- delete s.gridAutoRows;
4156
- delete s.placeItems;
4157
- delete s.placeContent;
4158
- delete s.justifyItems;
4159
- delete s.placeSelf;
4160
- delete s.justifySelf;
4161
- if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
4162
- delete s.position;
4163
- }
4164
- }
3970
+ stripInternalMarkers(s);
3971
+ if (typeof Component !== "string") stripWebOnlyProps(s);
4165
3972
  return s;
4166
3973
  },
4167
3974
  [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
@@ -4178,13 +3985,13 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
4178
3985
  // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
4179
3986
  // but onPressIn/onPressOut are still forwarded unchanged — react-native-web components
4180
3987
  // (and any component that accepts both prop names) depend on receiving them directly.
4181
- ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerLeave, onPressIn, onPressOut } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3988
+ ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerCancel, onPressIn, onPressOut } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
4182
3989
  onMouseEnter: handleMouseEnter,
4183
3990
  onMouseLeave: handleMouseLeave,
4184
3991
  onFocus: handleFocus,
4185
3992
  onBlur: handleBlur
4186
3993
  };
4187
- return Array.isArray(children) ? import_react10.default.createElement(Component, componentProps, ...children) : import_react10.default.createElement(Component, componentProps, children);
3994
+ return Array.isArray(children) ? import_react8.default.createElement(Component, componentProps, ...children) : import_react8.default.createElement(Component, componentProps, children);
4188
3995
  }
4189
3996
  );
4190
3997
  InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
@@ -4206,8 +4013,8 @@ function cx(...classes) {
4206
4013
  InteractiveWrapper,
4207
4014
  ThemeContext,
4208
4015
  ThemeProvider,
4209
- ThemeToggle,
4210
4016
  buildConfig,
4017
+ clearCache,
4211
4018
  cx,
4212
4019
  defaultColors,
4213
4020
  defaultTheme,
@@ -4221,6 +4028,7 @@ function cx(...classes) {
4221
4028
  parseClasses,
4222
4029
  registerWebElement,
4223
4030
  resolve,
4031
+ setResolveTarget,
4224
4032
  splitClassTokens,
4225
4033
  styled,
4226
4034
  updateConfig,