@kbach/react 0.6.0 → 0.6.2

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.
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  // src/core/theme.ts
2
4
  var defaultColors = {
3
5
  transparent: "transparent",
@@ -541,12 +543,13 @@ var defaultTheme = {
541
543
  // src/core/platform.ts
542
544
  var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
543
545
  var isNative = !isWeb && (typeof globalThis.HermesInternal !== "undefined" || typeof globalThis.__fbBatchedBridge !== "undefined" || typeof navigator !== "undefined" && navigator.product === "ReactNative" || typeof globalThis.__REACT_NATIVE__ !== "undefined");
544
- var _cssGenMode = false;
545
- function setCSSGenMode(on) {
546
- _cssGenMode = on;
546
+ var _resolveTargetOverride = null;
547
+ function setResolveTarget(target) {
548
+ _resolveTargetOverride = target;
547
549
  }
548
550
  function getEffectiveIsWeb() {
549
- return isWeb || _cssGenMode || !isNative;
551
+ if (_resolveTargetOverride) return _resolveTargetOverride === "web";
552
+ return isWeb || !isNative;
550
553
  }
551
554
  function toNativeValue(raw) {
552
555
  if (/^-?\d+(\.\d+)?px$/.test(raw)) return parseFloat(raw);
@@ -733,18 +736,28 @@ function resolveColor(value, colors, isArbitrary) {
733
736
  if (isNaN(alpha)) return hex;
734
737
  return hexToRgba(hex, alpha);
735
738
  }
736
- function hexToRgba(hex, alpha) {
739
+ function parseHexRgb(hex) {
737
740
  const h = hex.replace("#", "");
738
- let r, g, b;
739
- if (h.length === 3) {
740
- r = parseInt(h[0] + h[0], 16);
741
- g = parseInt(h[1] + h[1], 16);
742
- b = parseInt(h[2] + h[2], 16);
743
- } else {
744
- r = parseInt(h.slice(0, 2), 16);
745
- g = parseInt(h.slice(2, 4), 16);
746
- b = parseInt(h.slice(4, 6), 16);
741
+ if (h.length === 3 || h.length === 4) {
742
+ return [
743
+ parseInt(h[0] + h[0], 16),
744
+ parseInt(h[1] + h[1], 16),
745
+ parseInt(h[2] + h[2], 16)
746
+ ];
747
+ }
748
+ if (h.length === 6 || h.length === 8) {
749
+ return [
750
+ parseInt(h.slice(0, 2), 16),
751
+ parseInt(h.slice(2, 4), 16),
752
+ parseInt(h.slice(4, 6), 16)
753
+ ];
747
754
  }
755
+ return null;
756
+ }
757
+ function hexToRgba(hex, alpha) {
758
+ const rgb = parseHexRgb(hex);
759
+ if (!rgb) return hex;
760
+ const [r, g, b] = rgb;
748
761
  return `rgba(${r},${g},${b},${alpha})`;
749
762
  }
750
763
  function resolveSpacing(value, negative, spacing, isArbitrary) {
@@ -788,8 +801,8 @@ function resolveFontSize(value, fontSizes, isArbitrary) {
788
801
  if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
789
802
  return fontSizes[value] ?? null;
790
803
  }
791
- 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,)";
792
- 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,)";
804
+ 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,)";
805
+ 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,)";
793
806
  var _standalone = null;
794
807
  function buildStandalone() {
795
808
  const web = getEffectiveIsWeb();
@@ -1051,9 +1064,9 @@ function buildStandalone() {
1051
1064
  "backface-visible": { backfaceVisibility: "visible" },
1052
1065
  "backface-hidden": { backfaceVisibility: "hidden" },
1053
1066
  // CSS filters — standalone = default/full effect (web-only)
1054
- grayscale: web ? { "--tw-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1055
- invert: web ? { "--tw-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1056
- sepia: web ? { "--tw-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1067
+ grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1068
+ invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1069
+ sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1057
1070
  // Divide none
1058
1071
  "divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
1059
1072
  // Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
@@ -1138,6 +1151,48 @@ function getStandalone() {
1138
1151
  if (!_standalone) _standalone = buildStandalone();
1139
1152
  return _standalone;
1140
1153
  }
1154
+ function makeSpacingResolver(prop) {
1155
+ return ({ value, negative, isArbitrary }, { spacing }) => {
1156
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1157
+ return v !== null ? { [prop]: v } : null;
1158
+ };
1159
+ }
1160
+ var PADDING_MARGIN_PROPS = {
1161
+ p: "padding",
1162
+ px: "paddingHorizontal",
1163
+ py: "paddingVertical",
1164
+ pt: "paddingTop",
1165
+ pr: "paddingRight",
1166
+ pb: "paddingBottom",
1167
+ pl: "paddingLeft",
1168
+ m: "margin",
1169
+ mx: "marginHorizontal",
1170
+ my: "marginVertical",
1171
+ mt: "marginTop",
1172
+ mr: "marginRight",
1173
+ mb: "marginBottom",
1174
+ ml: "marginLeft"
1175
+ };
1176
+ function makeBorderSideResolver(widthProp, colorProp) {
1177
+ return ({ value, isArbitrary }, { colors, borderWidth }) => {
1178
+ if (!value) return { [widthProp]: 1 };
1179
+ if (isArbitrary) {
1180
+ const w2 = toNativeValue(value);
1181
+ if (typeof w2 === "number") return { [widthProp]: w2 };
1182
+ return { [colorProp]: value };
1183
+ }
1184
+ const color = resolveColor(value, colors, false);
1185
+ if (color) return { [colorProp]: color };
1186
+ const w = borderWidth[value];
1187
+ return w !== void 0 ? { [widthProp]: w } : null;
1188
+ };
1189
+ }
1190
+ var BORDER_SIDE_PROPS = {
1191
+ "border-t": ["borderTopWidth", "borderTopColor"],
1192
+ "border-r": ["borderRightWidth", "borderRightColor"],
1193
+ "border-b": ["borderBottomWidth", "borderBottomColor"],
1194
+ "border-l": ["borderLeftWidth", "borderLeftColor"]
1195
+ };
1141
1196
  var RESOLVERS = {
1142
1197
  // ── Background ─────────────────────────────────────────────────────────────
1143
1198
  bg: ({ value, isArbitrary }, { colors }) => {
@@ -1171,64 +1226,8 @@ var RESOLVERS = {
1171
1226
  const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
1172
1227
  return { "--text-opacity": v };
1173
1228
  },
1174
- // ── Padding ────────────────────────────────────────────────────────────────
1175
- p: ({ value, negative, isArbitrary }, { spacing }) => {
1176
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1177
- return v !== null ? { padding: v } : null;
1178
- },
1179
- px: ({ value, negative, isArbitrary }, { spacing }) => {
1180
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1181
- return v !== null ? { paddingHorizontal: v } : null;
1182
- },
1183
- py: ({ value, negative, isArbitrary }, { spacing }) => {
1184
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1185
- return v !== null ? { paddingVertical: v } : null;
1186
- },
1187
- pt: ({ value, negative, isArbitrary }, { spacing }) => {
1188
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1189
- return v !== null ? { paddingTop: v } : null;
1190
- },
1191
- pr: ({ value, negative, isArbitrary }, { spacing }) => {
1192
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1193
- return v !== null ? { paddingRight: v } : null;
1194
- },
1195
- pb: ({ value, negative, isArbitrary }, { spacing }) => {
1196
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1197
- return v !== null ? { paddingBottom: v } : null;
1198
- },
1199
- pl: ({ value, negative, isArbitrary }, { spacing }) => {
1200
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1201
- return v !== null ? { paddingLeft: v } : null;
1202
- },
1203
- // ── Margin ─────────────────────────────────────────────────────────────────
1204
- m: ({ value, negative, isArbitrary }, { spacing }) => {
1205
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1206
- return v !== null ? { margin: v } : null;
1207
- },
1208
- mx: ({ value, negative, isArbitrary }, { spacing }) => {
1209
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1210
- return v !== null ? { marginHorizontal: v } : null;
1211
- },
1212
- my: ({ value, negative, isArbitrary }, { spacing }) => {
1213
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1214
- return v !== null ? { marginVertical: v } : null;
1215
- },
1216
- mt: ({ value, negative, isArbitrary }, { spacing }) => {
1217
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1218
- return v !== null ? { marginTop: v } : null;
1219
- },
1220
- mr: ({ value, negative, isArbitrary }, { spacing }) => {
1221
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1222
- return v !== null ? { marginRight: v } : null;
1223
- },
1224
- mb: ({ value, negative, isArbitrary }, { spacing }) => {
1225
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1226
- return v !== null ? { marginBottom: v } : null;
1227
- },
1228
- ml: ({ value, negative, isArbitrary }, { spacing }) => {
1229
- const v = resolveSpacing(value, negative, spacing, isArbitrary);
1230
- return v !== null ? { marginLeft: v } : null;
1231
- },
1229
+ // ── Padding & margin ───────────────────────────────────────────────────────
1230
+ // Generated below via makeSpacingResolver() — see PADDING_MARGIN_PROPS.
1232
1231
  // ── Sizing ─────────────────────────────────────────────────────────────────
1233
1232
  w: ({ value, isArbitrary }, { spacing }) => {
1234
1233
  const v = resolveSizing(value, spacing, isArbitrary);
@@ -1272,54 +1271,7 @@ var RESOLVERS = {
1272
1271
  }
1273
1272
  return null;
1274
1273
  },
1275
- "border-t": ({ value, isArbitrary }, { colors, borderWidth }) => {
1276
- if (!value) return { borderTopWidth: 1 };
1277
- if (isArbitrary) {
1278
- const w2 = toNativeValue(value);
1279
- if (typeof w2 === "number") return { borderTopWidth: w2 };
1280
- return { borderTopColor: value };
1281
- }
1282
- const color = resolveColor(value, colors, false);
1283
- if (color) return { borderTopColor: color };
1284
- const w = borderWidth[value];
1285
- return w !== void 0 ? { borderTopWidth: w } : null;
1286
- },
1287
- "border-r": ({ value, isArbitrary }, { colors, borderWidth }) => {
1288
- if (!value) return { borderRightWidth: 1 };
1289
- if (isArbitrary) {
1290
- const w2 = toNativeValue(value);
1291
- if (typeof w2 === "number") return { borderRightWidth: w2 };
1292
- return { borderRightColor: value };
1293
- }
1294
- const color = resolveColor(value, colors, false);
1295
- if (color) return { borderRightColor: color };
1296
- const w = borderWidth[value];
1297
- return w !== void 0 ? { borderRightWidth: w } : null;
1298
- },
1299
- "border-b": ({ value, isArbitrary }, { colors, borderWidth }) => {
1300
- if (!value) return { borderBottomWidth: 1 };
1301
- if (isArbitrary) {
1302
- const w2 = toNativeValue(value);
1303
- if (typeof w2 === "number") return { borderBottomWidth: w2 };
1304
- return { borderBottomColor: value };
1305
- }
1306
- const color = resolveColor(value, colors, false);
1307
- if (color) return { borderBottomColor: color };
1308
- const w = borderWidth[value];
1309
- return w !== void 0 ? { borderBottomWidth: w } : null;
1310
- },
1311
- "border-l": ({ value, isArbitrary }, { colors, borderWidth }) => {
1312
- if (!value) return { borderLeftWidth: 1 };
1313
- if (isArbitrary) {
1314
- const w2 = toNativeValue(value);
1315
- if (typeof w2 === "number") return { borderLeftWidth: w2 };
1316
- return { borderLeftColor: value };
1317
- }
1318
- const color = resolveColor(value, colors, false);
1319
- if (color) return { borderLeftColor: color };
1320
- const w = borderWidth[value];
1321
- return w !== void 0 ? { borderLeftWidth: w } : null;
1322
- },
1274
+ // border-t/-r/-b/-l generated below via makeBorderSideResolver() — see BORDER_SIDE_PROPS.
1323
1275
  // ── Border radius ──────────────────────────────────────────────────────────
1324
1276
  rounded: ({ value, isArbitrary }, { borderRadius }) => {
1325
1277
  const r = resolveRadius(value, borderRadius, isArbitrary);
@@ -1551,49 +1503,49 @@ var RESOLVERS = {
1551
1503
  "2xl": "blur(40px)",
1552
1504
  "3xl": "blur(64px)"
1553
1505
  };
1554
- if (value === "none") return { "--tw-blur": "", filter: FILTER_COMPOSE };
1506
+ if (value === "none") return { "--kb-blur": "", filter: FILTER_COMPOSE };
1555
1507
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1556
- return v !== void 0 ? { "--tw-blur": v, filter: FILTER_COMPOSE } : null;
1508
+ return v !== void 0 ? { "--kb-blur": v, filter: FILTER_COMPOSE } : null;
1557
1509
  },
1558
1510
  brightness: ({ value, isArbitrary }) => {
1559
1511
  if (!getEffectiveIsWeb()) return null;
1560
1512
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1561
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-brightness": v, filter: FILTER_COMPOSE };
1513
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-brightness": v, filter: FILTER_COMPOSE };
1562
1514
  },
1563
1515
  contrast: ({ value, isArbitrary }) => {
1564
1516
  if (!getEffectiveIsWeb()) return null;
1565
1517
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1566
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-contrast": v, filter: FILTER_COMPOSE };
1518
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
1567
1519
  },
1568
1520
  grayscale: ({ value }) => {
1569
1521
  if (!getEffectiveIsWeb()) return null;
1570
1522
  const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
1571
- return { "--tw-grayscale": v, filter: FILTER_COMPOSE };
1523
+ return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
1572
1524
  },
1573
1525
  "hue-rotate": ({ value, negative, isArbitrary }) => {
1574
1526
  if (!getEffectiveIsWeb()) return null;
1575
1527
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1576
1528
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1577
- return { "--tw-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1529
+ return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1578
1530
  },
1579
1531
  invert: ({ value }) => {
1580
1532
  if (!getEffectiveIsWeb()) return null;
1581
1533
  const v = value === "0" ? "invert(0)" : "invert(100%)";
1582
- return { "--tw-invert": v, filter: FILTER_COMPOSE };
1534
+ return { "--kb-invert": v, filter: FILTER_COMPOSE };
1583
1535
  },
1584
1536
  saturate: ({ value, isArbitrary }) => {
1585
1537
  if (!getEffectiveIsWeb()) return null;
1586
1538
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1587
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-saturate": v, filter: FILTER_COMPOSE };
1539
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
1588
1540
  },
1589
1541
  sepia: ({ value }) => {
1590
1542
  if (!getEffectiveIsWeb()) return null;
1591
1543
  const v = value === "0" ? "sepia(0)" : "sepia(100%)";
1592
- return { "--tw-sepia": v, filter: FILTER_COMPOSE };
1544
+ return { "--kb-sepia": v, filter: FILTER_COMPOSE };
1593
1545
  },
1594
1546
  "drop-shadow": ({ value, isArbitrary }) => {
1595
1547
  if (!getEffectiveIsWeb()) return null;
1596
- if (isArbitrary) return { "--tw-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1548
+ if (isArbitrary) return { "--kb-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1597
1549
  const presets = {
1598
1550
  "": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
1599
1551
  sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
@@ -1604,7 +1556,7 @@ var RESOLVERS = {
1604
1556
  none: "drop-shadow(0 0 #0000)"
1605
1557
  };
1606
1558
  const v = presets[value];
1607
- return v !== void 0 ? { "--tw-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1559
+ return v !== void 0 ? { "--kb-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1608
1560
  },
1609
1561
  // Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
1610
1562
  filter: ({ value, isArbitrary }) => {
@@ -1625,47 +1577,47 @@ var RESOLVERS = {
1625
1577
  "2xl": "blur(40px)",
1626
1578
  "3xl": "blur(64px)"
1627
1579
  };
1628
- if (value === "none") return { "--tw-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1580
+ if (value === "none") return { "--kb-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1629
1581
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1630
- return v !== void 0 ? { "--tw-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1582
+ return v !== void 0 ? { "--kb-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1631
1583
  },
1632
1584
  "backdrop-brightness": ({ value, isArbitrary }) => {
1633
1585
  if (!getEffectiveIsWeb()) return null;
1634
1586
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1635
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1587
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1636
1588
  },
1637
1589
  "backdrop-contrast": ({ value, isArbitrary }) => {
1638
1590
  if (!getEffectiveIsWeb()) return null;
1639
1591
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1640
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1592
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1641
1593
  },
1642
1594
  "backdrop-grayscale": ({ value }) => {
1643
1595
  if (!getEffectiveIsWeb()) return null;
1644
- return { "--tw-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1596
+ return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1645
1597
  },
1646
1598
  "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
1647
1599
  if (!getEffectiveIsWeb()) return null;
1648
1600
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1649
1601
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1650
- return { "--tw-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1602
+ return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1651
1603
  },
1652
1604
  "backdrop-invert": ({ value }) => {
1653
1605
  if (!getEffectiveIsWeb()) return null;
1654
- return { "--tw-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1606
+ return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1655
1607
  },
1656
1608
  "backdrop-opacity": ({ value, isArbitrary }) => {
1657
1609
  if (!getEffectiveIsWeb()) return null;
1658
1610
  const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
1659
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1611
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1660
1612
  },
1661
1613
  "backdrop-saturate": ({ value, isArbitrary }) => {
1662
1614
  if (!getEffectiveIsWeb()) return null;
1663
1615
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1664
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1616
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1665
1617
  },
1666
1618
  "backdrop-sepia": ({ value }) => {
1667
1619
  if (!getEffectiveIsWeb()) return null;
1668
- return { "--tw-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1620
+ return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1669
1621
  },
1670
1622
  "backdrop-filter": ({ value, isArbitrary }) => {
1671
1623
  if (!getEffectiveIsWeb()) return null;
@@ -1689,7 +1641,7 @@ var RESOLVERS = {
1689
1641
  const dir = directions[value];
1690
1642
  if (!dir) return null;
1691
1643
  return {
1692
- backgroundImage: `linear-gradient(${dir}, var(--tw-gradient-from, transparent), var(--tw-gradient-stops, transparent))`
1644
+ backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
1693
1645
  };
1694
1646
  },
1695
1647
  from: ({ value, isArbitrary }, { colors }) => {
@@ -1697,8 +1649,8 @@ var RESOLVERS = {
1697
1649
  const color = resolveColor(value, colors, isArbitrary);
1698
1650
  if (!color) return null;
1699
1651
  return {
1700
- "--tw-gradient-from": color,
1701
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, transparent)`
1652
+ "--kb-gradient-from": color,
1653
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
1702
1654
  };
1703
1655
  },
1704
1656
  via: ({ value, isArbitrary }, { colors }) => {
@@ -1706,15 +1658,15 @@ var RESOLVERS = {
1706
1658
  const color = resolveColor(value, colors, isArbitrary);
1707
1659
  if (!color) return null;
1708
1660
  return {
1709
- "--tw-gradient-via": color,
1710
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to, transparent)`
1661
+ "--kb-gradient-via": color,
1662
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
1711
1663
  };
1712
1664
  },
1713
1665
  to: ({ value, isArbitrary }, { colors }) => {
1714
1666
  if (!getEffectiveIsWeb()) return null;
1715
1667
  const color = resolveColor(value, colors, isArbitrary);
1716
1668
  if (!color) return null;
1717
- return { "--tw-gradient-to": color };
1669
+ return { "--kb-gradient-to": color };
1718
1670
  },
1719
1671
  // ── Transform extras (web-only) ───────────────────────────────────────────
1720
1672
  "skew-x": ({ value, negative, isArbitrary }) => {
@@ -2318,6 +2270,12 @@ var RESOLVERS = {
2318
2270
  return { rowGap: v };
2319
2271
  }
2320
2272
  };
2273
+ for (const [utility, prop] of Object.entries(PADDING_MARGIN_PROPS)) {
2274
+ RESOLVERS[utility] = makeSpacingResolver(prop);
2275
+ }
2276
+ for (const [utility, [widthProp, colorProp]] of Object.entries(BORDER_SIDE_PROPS)) {
2277
+ RESOLVERS[utility] = makeBorderSideResolver(widthProp, colorProp);
2278
+ }
2321
2279
  function resolveUtility(parsed, theme) {
2322
2280
  if (!parsed.value) {
2323
2281
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
@@ -2515,10 +2473,11 @@ var BASE_RESET = [
2515
2473
 
2516
2474
  // src/core/cache.ts
2517
2475
  var LRUCache = class {
2518
- constructor(capacity = 1e4) {
2476
+ constructor(capacity = 1e4, onEvict) {
2519
2477
  this.capacity = capacity;
2520
2478
  if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
2521
2479
  this.cache = /* @__PURE__ */ new Map();
2480
+ this.onEvict = onEvict;
2522
2481
  }
2523
2482
  get(key) {
2524
2483
  if (!this.cache.has(key)) return void 0;
@@ -2531,7 +2490,10 @@ var LRUCache = class {
2531
2490
  if (this.cache.has(key)) {
2532
2491
  this.cache.delete(key);
2533
2492
  } else if (this.cache.size >= this.capacity) {
2534
- this.cache.delete(this.cache.keys().next().value);
2493
+ const oldestKey = this.cache.keys().next().value;
2494
+ const oldestValue = this.cache.get(oldestKey);
2495
+ this.cache.delete(oldestKey);
2496
+ this.onEvict?.(oldestKey, oldestValue);
2535
2497
  }
2536
2498
  this.cache.set(key, value);
2537
2499
  return this;
@@ -2625,7 +2587,20 @@ function getDefaultFontFamily() {
2625
2587
  return globalThis[FONT_KEY];
2626
2588
  }
2627
2589
  var _styleEl = null;
2628
- var _injectedRules = new LRUCache(5e4);
2590
+ function evictInjectedRule(rule) {
2591
+ const sheet = _styleEl?.sheet;
2592
+ if (!sheet) return;
2593
+ for (let i = 0; i < sheet.cssRules.length; i++) {
2594
+ if (sheet.cssRules[i].cssText === rule) {
2595
+ try {
2596
+ sheet.deleteRule(i);
2597
+ } catch {
2598
+ }
2599
+ return;
2600
+ }
2601
+ }
2602
+ }
2603
+ var _injectedRules = new LRUCache(5e4, evictInjectedRule);
2629
2604
  var _CSS_DISABLED_KEY = "__kbach_runtime_css_disabled__";
2630
2605
  function disableRuntimeCSS() {
2631
2606
  globalThis[_CSS_DISABLED_KEY] = true;
@@ -2662,8 +2637,7 @@ function injectGlobalStyles(theme) {
2662
2637
  if (typeof document === "undefined" || isRuntimeCSSDisabled()) return;
2663
2638
  const rules = [BASE_RESET];
2664
2639
  const ff = theme.fontFamily;
2665
- if (!ff) return;
2666
- if (ff.sans && ff.sans !== "System") {
2640
+ if (ff?.sans && ff.sans !== "System") {
2667
2641
  const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
2668
2642
  rules.push(`body { font-family: ${family}; }`);
2669
2643
  }
@@ -2826,7 +2800,7 @@ function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens
2826
2800
  else rule = `[data-theme="dark"] ${selector} { ${decls} }`;
2827
2801
  } else if (darkScheme === "light") {
2828
2802
  if (darkMode === "media") rule = `@media (prefers-color-scheme: light) { ${selector} { ${decls} } }`;
2829
- else if (darkMode === "class") rule = `:not(.dark) ${selector} { ${decls} }`;
2803
+ else if (darkMode === "class") rule = `.light ${selector} { ${decls} }`;
2830
2804
  else rule = `[data-theme="light"] ${selector} { ${decls} }`;
2831
2805
  } else {
2832
2806
  rule = `${selector} { ${decls} }`;
@@ -2840,16 +2814,6 @@ function injectClassRule(cls, bucketKey, styles, darkMode, important) {
2840
2814
  const cssRules = buildClassCSSRules(cls, bucketKey, styles, darkMode, important, getGlobalScreens());
2841
2815
  for (const r of cssRules) injectRule(r);
2842
2816
  }
2843
- function generateClassCSS(classString, theme, darkMode = "attribute", screens = {}) {
2844
- const rules = [];
2845
- for (const parsed of parseClasses(classString)) {
2846
- const styles = resolveUtility(parsed, theme);
2847
- if (!styles) continue;
2848
- const bucketKey = parsed.modifiers.length === 0 ? "base" : parsed.modifiers.join(":");
2849
- rules.push(...buildClassCSSRules(parsed.original, bucketKey, styles, darkMode, parsed.important, screens));
2850
- }
2851
- return rules.join("\n");
2852
- }
2853
2817
  function resolve(classString, theme, darkMode = "attribute") {
2854
2818
  const cache = getThemeCache(theme);
2855
2819
  const cacheKey = `${classString}::${darkMode}`;
@@ -2967,11 +2931,14 @@ function getConfig() {
2967
2931
  return store.resolved;
2968
2932
  }
2969
2933
  function resolveOneRef(ref, colors) {
2970
- const m = /^([a-z][a-z0-9]*)-(\d+)$/.exec(ref);
2971
- if (!m) return null;
2972
- const entry = colors[m[1]];
2934
+ const lastDash = ref.lastIndexOf("-");
2935
+ if (lastDash <= 0) return null;
2936
+ const name = ref.slice(0, lastDash);
2937
+ const shade = ref.slice(lastDash + 1);
2938
+ if (!/^\d+$/.test(shade)) return null;
2939
+ const entry = colors[name];
2973
2940
  if (!entry || typeof entry !== "object") return null;
2974
- return entry[m[2]] ?? null;
2941
+ return entry[shade] ?? null;
2975
2942
  }
2976
2943
  function resolveColorRefs(colors) {
2977
2944
  const MAX_DEPTH = 5;
@@ -3001,7 +2968,7 @@ function resolveColorRefs(colors) {
3001
2968
  function buildConfig(userConfig) {
3002
2969
  let theme = { ...defaultTheme };
3003
2970
  if (userConfig.theme) {
3004
- theme = deepMerge(theme, userConfig.theme);
2971
+ theme = { ...theme, ...userConfig.theme };
3005
2972
  }
3006
2973
  if (userConfig.extend) {
3007
2974
  const extendConfig = userConfig.extend;
@@ -3123,36 +3090,549 @@ var customVariants = new Proxy(
3123
3090
  }
3124
3091
  );
3125
3092
 
3093
+ // src/core/darkModeStore.ts
3094
+ var KEY = "__kbach_dark_store__";
3095
+ function getStore2() {
3096
+ const g = globalThis;
3097
+ if (!g[KEY]) {
3098
+ g[KEY] = { isDark: false, subscribers: /* @__PURE__ */ new Set() };
3099
+ }
3100
+ return g[KEY];
3101
+ }
3102
+ function syncGlobalDarkMode(isDark) {
3103
+ getStore2().isDark = isDark;
3104
+ }
3105
+ function setGlobalDarkMode(isDark) {
3106
+ const store = getStore2();
3107
+ if (store.isDark === isDark) return;
3108
+ store.isDark = isDark;
3109
+ for (const sub of store.subscribers) sub();
3110
+ }
3111
+ function getGlobalDarkMode() {
3112
+ return getStore2().isDark;
3113
+ }
3114
+ function subscribeGlobalDarkMode(callback) {
3115
+ const store = getStore2();
3116
+ store.subscribers.add(callback);
3117
+ return () => store.subscribers.delete(callback);
3118
+ }
3119
+
3120
+ // src/useSyncExternalStoreShim.ts
3121
+ import React from "react";
3122
+ var useSyncExternalStore = React.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
3123
+ const [, forceUpdate] = React.useReducer((n) => n + 1, 0);
3124
+ React.useEffect(() => subscribe(forceUpdate), [subscribe]);
3125
+ return getSnapshot();
3126
+ };
3127
+
3128
+ // src/useGlobalDarkMode.ts
3129
+ function useGlobalDarkMode() {
3130
+ return useSyncExternalStore(
3131
+ subscribeGlobalDarkMode,
3132
+ getGlobalDarkMode,
3133
+ () => false
3134
+ // SSR: default light
3135
+ );
3136
+ }
3137
+
3138
+ // src/shared-utils.ts
3139
+ function hasResponsiveBuckets(resolved) {
3140
+ const responsiveMods = getResponsiveModifiers();
3141
+ for (const key of Object.keys(resolved)) {
3142
+ if (key === "base") continue;
3143
+ for (const mod of key.split(":")) {
3144
+ if (responsiveMods.has(mod)) return true;
3145
+ }
3146
+ }
3147
+ return false;
3148
+ }
3149
+ function hasInteractiveBuckets(resolved) {
3150
+ const interactiveMods = getInteractiveModifiers();
3151
+ for (const key of Object.keys(resolved)) {
3152
+ if (key === "base") continue;
3153
+ for (const mod of key.split(":")) {
3154
+ if (interactiveMods.has(mod)) return true;
3155
+ }
3156
+ }
3157
+ return false;
3158
+ }
3159
+ function chain(original, extra) {
3160
+ return (...args) => {
3161
+ original?.(...args);
3162
+ extra();
3163
+ };
3164
+ }
3165
+ function stripInternalMarkers(s) {
3166
+ delete s.__divideX;
3167
+ delete s.__divideY;
3168
+ delete s.__divideColor;
3169
+ delete s.__divideStyle;
3170
+ delete s.__keyframe;
3171
+ }
3172
+ function stripWebOnlyProps(s) {
3173
+ if (s.display === "grid" || s.display === "inline-grid") delete s.display;
3174
+ delete s.gridTemplateColumns;
3175
+ delete s.gridTemplateRows;
3176
+ delete s.gridColumn;
3177
+ delete s.gridRow;
3178
+ delete s.gridArea;
3179
+ delete s.gridColumnStart;
3180
+ delete s.gridColumnEnd;
3181
+ delete s.gridRowStart;
3182
+ delete s.gridRowEnd;
3183
+ delete s.gridAutoFlow;
3184
+ delete s.gridAutoColumns;
3185
+ delete s.gridAutoRows;
3186
+ delete s.placeItems;
3187
+ delete s.placeContent;
3188
+ delete s.justifyItems;
3189
+ delete s.placeSelf;
3190
+ delete s.justifySelf;
3191
+ if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
3192
+ delete s.position;
3193
+ }
3194
+ }
3195
+
3196
+ // src/web-substitute.ts
3197
+ var _rnToHtml = {
3198
+ View: "div",
3199
+ SafeAreaView: "div",
3200
+ KeyboardAvoidingView: "div",
3201
+ ScrollView: "div",
3202
+ VirtualizedList: "div",
3203
+ FlatList: "div",
3204
+ SectionList: "div",
3205
+ Text: "span",
3206
+ TextInput: "input",
3207
+ Image: "img",
3208
+ ImageBackground: "div",
3209
+ Pressable: "div",
3210
+ TouchableOpacity: "div",
3211
+ TouchableHighlight: "div",
3212
+ TouchableWithoutFeedback: "div",
3213
+ TouchableNativeFeedback: "div"
3214
+ };
3215
+ var _userMap = /* @__PURE__ */ new Map();
3216
+ var _cache = /* @__PURE__ */ new WeakMap();
3217
+ function registerWebElement(rnComponent, htmlTag) {
3218
+ if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
3219
+ _userMap.set(rnComponent, htmlTag);
3220
+ _cache.delete(rnComponent);
3221
+ }
3222
+ function getWebTag(type, props) {
3223
+ if (typeof type === "string") return null;
3224
+ if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3225
+ const obj = type;
3226
+ if (_userMap.has(obj)) return _userMap.get(obj);
3227
+ const name = obj.displayName ?? obj.name;
3228
+ if (!name) {
3229
+ _cache.set(obj, null);
3230
+ return null;
3231
+ }
3232
+ if (name === "TextInput") {
3233
+ const multiline = !!props && (props.multiline === true || Number(props.numberOfLines) > 1);
3234
+ return multiline ? "textarea" : "input";
3235
+ }
3236
+ if (_cache.has(obj)) return _cache.get(obj);
3237
+ const tag = _rnToHtml[name] ?? null;
3238
+ _cache.set(obj, tag);
3239
+ return tag;
3240
+ }
3241
+ var _rnOnlyProps = /* @__PURE__ */ new Set([
3242
+ // Interaction
3243
+ "onLongPress",
3244
+ "delayLongPress",
3245
+ "activeOpacity",
3246
+ "underlayColor",
3247
+ "hitSlop",
3248
+ "pressRetentionOffset",
3249
+ "android_ripple",
3250
+ "android_disableSound",
3251
+ "onHoverIn",
3252
+ "onHoverOut",
3253
+ "onHoverStart",
3254
+ "onHoverEnd",
3255
+ // Layout event
3256
+ "onLayout",
3257
+ // Accessibility
3258
+ "accessible",
3259
+ "accessibilityState",
3260
+ "accessibilityLiveRegion",
3261
+ "importantForAccessibility",
3262
+ // Platform
3263
+ "nativeID",
3264
+ "collapsable",
3265
+ "needsOffscreenAlphaCompositing",
3266
+ "renderToHardwareTextureAndroid",
3267
+ "shouldRasterizeIOS",
3268
+ "focusable",
3269
+ "hasTVPreferredFocus",
3270
+ // 'pointerEvents' is handled in transformToWebProps (mapped to CSS style)
3271
+ // Text
3272
+ "selectable",
3273
+ "allowFontScaling",
3274
+ "adjustsFontSizeToFit",
3275
+ "minimumFontScale",
3276
+ "ellipsizeMode",
3277
+ "numberOfLines",
3278
+ "onTextLayout",
3279
+ "textBreakStrategy",
3280
+ "lineBreakStrategyIOS",
3281
+ // TextInput
3282
+ "multiline",
3283
+ "resizeMode",
3284
+ // handled separately
3285
+ "blurOnSubmit",
3286
+ "clearButtonMode",
3287
+ "clearTextOnFocus",
3288
+ "enablesReturnKeyAutomatically",
3289
+ "returnKeyType",
3290
+ "spellCheck",
3291
+ // ScrollView
3292
+ "scrollEnabled",
3293
+ "showsVerticalScrollIndicator",
3294
+ "showsHorizontalScrollIndicator",
3295
+ "contentContainerStyle",
3296
+ // 'horizontal' is handled in transformToWebProps (converted to CSS overflow-x).
3297
+ "keyboardShouldPersistTaps",
3298
+ "keyboardDismissMode",
3299
+ "pagingEnabled",
3300
+ "scrollEventThrottle",
3301
+ "decelerationRate",
3302
+ "bounces",
3303
+ "alwaysBounceHorizontal",
3304
+ "alwaysBounceVertical",
3305
+ "snapToAlignment",
3306
+ "snapToInterval",
3307
+ "snapToOffsets",
3308
+ "removeClippedSubviews",
3309
+ "overScrollMode",
3310
+ "stickyHeaderIndices",
3311
+ "invertStickyHeaders",
3312
+ "onScrollBeginDrag",
3313
+ "onScrollEndDrag",
3314
+ "onMomentumScrollBegin",
3315
+ "onMomentumScrollEnd",
3316
+ "contentInset",
3317
+ "contentInsetAdjustmentBehavior",
3318
+ "automaticallyAdjustContentInsets",
3319
+ "automaticallyAdjustsScrollIndicatorInsets",
3320
+ // expo-image
3321
+ "contentPosition",
3322
+ "cachePolicy",
3323
+ "recyclingKey",
3324
+ "blurRadius",
3325
+ "fadeDuration",
3326
+ "responsivePolicy",
3327
+ "tintColor",
3328
+ "allowDownscaling",
3329
+ "placeholderContentFit",
3330
+ // FlatList / SectionList
3331
+ "data",
3332
+ "renderItem",
3333
+ "keyExtractor",
3334
+ "getItemLayout",
3335
+ "initialScrollIndex",
3336
+ "initialNumToRender",
3337
+ "maxToRenderPerBatch",
3338
+ "windowSize",
3339
+ "updateCellsBatchingPeriod",
3340
+ "onEndReached",
3341
+ "onEndReachedThreshold",
3342
+ "ListHeaderComponent",
3343
+ "ListFooterComponent",
3344
+ "ListEmptyComponent",
3345
+ "ListHeaderComponentStyle",
3346
+ "ListFooterComponentStyle",
3347
+ "ItemSeparatorComponent",
3348
+ "SectionSeparatorComponent",
3349
+ "inverted",
3350
+ "getItem",
3351
+ "getItemCount"
3352
+ ]);
3353
+ var _pressableNames = /* @__PURE__ */ new Set([
3354
+ "Pressable",
3355
+ "TouchableOpacity",
3356
+ "TouchableHighlight",
3357
+ "TouchableWithoutFeedback",
3358
+ "TouchableNativeFeedback"
3359
+ ]);
3360
+ var _keyboardTypeMap = {
3361
+ "numeric": "number",
3362
+ "number-pad": "number",
3363
+ "decimal-pad": "decimal",
3364
+ "email-address": "email",
3365
+ "phone-pad": "tel",
3366
+ "url": "url"
3367
+ };
3368
+ var _resizeModeMap = {
3369
+ "contain": "contain",
3370
+ "cover": "cover",
3371
+ "stretch": "fill",
3372
+ "center": "none",
3373
+ "repeat": "none"
3374
+ };
3375
+ function transformToWebProps(originalName, tag, props) {
3376
+ const out = {};
3377
+ const isPressable = _pressableNames.has(originalName);
3378
+ const isTextInput = originalName === "TextInput";
3379
+ const isImage = originalName === "Image" || originalName === "ImageBackground";
3380
+ const isScrollable = originalName === "ScrollView" || originalName === "FlatList" || originalName === "SectionList";
3381
+ let pendingStyle = null;
3382
+ for (const [k, v] of Object.entries(props)) {
3383
+ if (_rnOnlyProps.has(k)) continue;
3384
+ if (k === "onPress") {
3385
+ if (!("onClick" in props)) out.onClick = v;
3386
+ continue;
3387
+ }
3388
+ if (k === "accessibilityLabel") {
3389
+ if (out["aria-label"] == null) out["aria-label"] = v;
3390
+ continue;
3391
+ }
3392
+ if (k === "accessibilityRole") {
3393
+ if (out.role == null) out.role = v;
3394
+ continue;
3395
+ }
3396
+ if (k === "testID") {
3397
+ if (out["data-testid"] == null) out["data-testid"] = v;
3398
+ continue;
3399
+ }
3400
+ if (isTextInput) {
3401
+ if (k === "onChangeText") {
3402
+ if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
3403
+ continue;
3404
+ }
3405
+ if (k === "secureTextEntry") {
3406
+ if (v && !("type" in props)) out.type = "password";
3407
+ continue;
3408
+ }
3409
+ if (k === "keyboardType") {
3410
+ if (!("type" in props) && !("secureTextEntry" in props)) {
3411
+ const mapped = _keyboardTypeMap[v];
3412
+ if (mapped) out.type = mapped;
3413
+ }
3414
+ continue;
3415
+ }
3416
+ if (k === "editable") {
3417
+ if (v === false) out.readOnly = true;
3418
+ continue;
3419
+ }
3420
+ if (k === "maxLength") {
3421
+ out.maxLength = v;
3422
+ continue;
3423
+ }
3424
+ }
3425
+ if (isScrollable && k === "horizontal") {
3426
+ if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
3427
+ continue;
3428
+ }
3429
+ if (k === "pointerEvents") {
3430
+ if (v === "none" || v === "auto") pendingStyle = { ...pendingStyle ?? {}, pointerEvents: v };
3431
+ continue;
3432
+ }
3433
+ if (isImage) {
3434
+ if (k === "source") {
3435
+ if (typeof v === "string") {
3436
+ out.src = v;
3437
+ } else if (v && typeof v === "object" && "uri" in v) {
3438
+ out.src = v.uri;
3439
+ if (v.headers) out["crossOrigin"] = "anonymous";
3440
+ }
3441
+ continue;
3442
+ }
3443
+ if (k === "resizeMode") {
3444
+ pendingStyle = { ...pendingStyle ?? {}, objectFit: _resizeModeMap[v] ?? "cover" };
3445
+ continue;
3446
+ }
3447
+ if (k === "contentFit") {
3448
+ pendingStyle = { ...pendingStyle ?? {}, objectFit: v };
3449
+ continue;
3450
+ }
3451
+ if (k === "defaultSource") continue;
3452
+ }
3453
+ if (k === "style") {
3454
+ if (Array.isArray(v)) {
3455
+ out.style = Object.assign({}, ...v.filter(Boolean));
3456
+ } else if (v != null) {
3457
+ out.style = v;
3458
+ }
3459
+ continue;
3460
+ }
3461
+ out[k] = v;
3462
+ }
3463
+ if (pendingStyle) {
3464
+ out.style = out.style ? { ...pendingStyle, ...out.style } : pendingStyle;
3465
+ }
3466
+ if (isPressable && !out.role) out.role = "button";
3467
+ if (isImage && tag === "img" && out.alt == null) out.alt = "";
3468
+ return out;
3469
+ }
3470
+
3471
+ // src/InteractiveWrapper.tsx
3472
+ import React2, { forwardRef, useState, useCallback, useMemo } from "react";
3473
+
3474
+ // src/useGlobalWidth.ts
3475
+ var NOOP_SUB = (_) => () => {
3476
+ };
3477
+ var ZERO_SNAP = () => 0;
3478
+ var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
3479
+ var _webListeners = null;
3480
+ var _webRaf = 0;
3481
+ function _webResizeHandler() {
3482
+ cancelAnimationFrame(_webRaf);
3483
+ _webRaf = requestAnimationFrame(() => {
3484
+ if (_webListeners) for (const cb of _webListeners) cb();
3485
+ });
3486
+ }
3487
+ function subscribeWebWidth(cb) {
3488
+ if (typeof window === "undefined") return () => {
3489
+ };
3490
+ if (!_webListeners) {
3491
+ _webListeners = /* @__PURE__ */ new Set();
3492
+ window.addEventListener("resize", _webResizeHandler);
3493
+ }
3494
+ _webListeners.add(cb);
3495
+ return () => {
3496
+ _webListeners.delete(cb);
3497
+ if (_webListeners.size === 0) {
3498
+ window.removeEventListener("resize", _webResizeHandler);
3499
+ cancelAnimationFrame(_webRaf);
3500
+ _webListeners = null;
3501
+ }
3502
+ };
3503
+ }
3504
+ function getWebWidth() {
3505
+ return typeof window !== "undefined" ? window.innerWidth : 0;
3506
+ }
3507
+ function useGlobalWidth() {
3508
+ return useSyncExternalStore(
3509
+ isWeb ? subscribeWebWidth : subscribeGlobalWidth,
3510
+ isWeb ? getWebWidth : getGlobalWidth,
3511
+ ZERO_SNAP
3512
+ );
3513
+ }
3514
+ function useConditionalWidth(active) {
3515
+ return useSyncExternalStore(
3516
+ active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
3517
+ active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
3518
+ ZERO_SNAP
3519
+ );
3520
+ }
3521
+
3522
+ // src/InteractiveWrapper.tsx
3523
+ var InteractiveWrapper = forwardRef(
3524
+ function InteractiveWrapper2({
3525
+ Component,
3526
+ resolvedStyle,
3527
+ className,
3528
+ style: styleProp,
3529
+ onPressIn,
3530
+ onPressOut,
3531
+ onPointerDown,
3532
+ onPointerUp,
3533
+ onPointerLeave,
3534
+ onPointerCancel,
3535
+ onMouseEnter,
3536
+ onMouseLeave,
3537
+ onFocus,
3538
+ onBlur,
3539
+ ...rest
3540
+ }, ref) {
3541
+ const isDark = useGlobalDarkMode();
3542
+ const needsWidth = hasResponsiveBuckets(resolvedStyle);
3543
+ const width = useConditionalWidth(needsWidth);
3544
+ const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3545
+ const [pressed, setPressed] = useState(false);
3546
+ const [hovered, setHovered] = useState(false);
3547
+ const [focused, setFocused] = useState(false);
3548
+ const handlePressIn = useCallback(chain(onPressIn, () => setPressed(true)), [onPressIn]);
3549
+ const handlePressOut = useCallback(chain(onPressOut, () => setPressed(false)), [onPressOut]);
3550
+ const handlePointerDown = useCallback(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
3551
+ const handlePointerUp = useCallback(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
3552
+ const handlePointerLeave = useCallback(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
3553
+ const handlePointerCancel = useCallback(chain(onPointerCancel, () => setPressed(false)), [onPointerCancel]);
3554
+ const handleMouseEnter = useCallback(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
3555
+ const handleMouseLeave = useCallback(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
3556
+ const handleFocus = useCallback(chain(onFocus, () => setFocused(true)), [onFocus]);
3557
+ const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
3558
+ const { children, disabled, checked, ...restForComponent } = rest;
3559
+ const computedStyle = useMemo(
3560
+ () => {
3561
+ if (isWeb) return {};
3562
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
3563
+ stripInternalMarkers(s);
3564
+ if (typeof Component !== "string") stripWebOnlyProps(s);
3565
+ return s;
3566
+ },
3567
+ [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
3568
+ );
3569
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3570
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3571
+ const componentProps = {
3572
+ ref,
3573
+ ...restForComponent,
3574
+ ...disabled !== void 0 ? { disabled } : {},
3575
+ ...checked !== void 0 ? { checked } : {},
3576
+ style: finalStyle,
3577
+ ...!isNative && className ? { className } : {},
3578
+ // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
3579
+ // but onPressIn/onPressOut are still forwarded unchanged — react-native-web components
3580
+ // (and any component that accepts both prop names) depend on receiving them directly.
3581
+ ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerCancel, onPressIn, onPressOut } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3582
+ onMouseEnter: handleMouseEnter,
3583
+ onMouseLeave: handleMouseLeave,
3584
+ onFocus: handleFocus,
3585
+ onBlur: handleBlur
3586
+ };
3587
+ return Array.isArray(children) ? React2.createElement(Component, componentProps, ...children) : React2.createElement(Component, componentProps, children);
3588
+ }
3589
+ );
3590
+ InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
3591
+
3126
3592
  export {
3127
3593
  defaultColors,
3128
3594
  defaultTheme,
3129
3595
  isWeb,
3130
3596
  isNative,
3131
- setCSSGenMode,
3597
+ setResolveTarget,
3132
3598
  getInteractiveModifiers,
3133
3599
  getModeModifiers,
3134
3600
  getResponsiveModifiers,
3601
+ parseHexRgb,
3135
3602
  parseClass,
3136
3603
  splitClassTokens,
3137
3604
  normalizeClassString,
3138
3605
  parseClasses,
3139
- BASE_RESET,
3140
3606
  syncGlobalWidth,
3141
3607
  syncGlobalScreens,
3142
3608
  getGlobalScreens,
3143
3609
  setGlobalWidth,
3144
- getGlobalWidth,
3145
- subscribeGlobalWidth,
3146
3610
  getActiveBreakpoints,
3147
3611
  getDefaultFontFamily,
3148
3612
  disableRuntimeCSS,
3149
3613
  isRuntimeCSSDisabled,
3150
- generateClassCSS,
3151
3614
  resolve,
3152
3615
  flatten,
3616
+ clearCache,
3153
3617
  getConfig,
3154
3618
  buildConfig,
3155
3619
  onConfigChange,
3156
3620
  updateConfig,
3157
- initConfig
3621
+ initConfig,
3622
+ syncGlobalDarkMode,
3623
+ setGlobalDarkMode,
3624
+ useSyncExternalStore,
3625
+ useGlobalDarkMode,
3626
+ EMPTY_BREAKPOINTS,
3627
+ useGlobalWidth,
3628
+ useConditionalWidth,
3629
+ hasResponsiveBuckets,
3630
+ hasInteractiveBuckets,
3631
+ chain,
3632
+ stripInternalMarkers,
3633
+ stripWebOnlyProps,
3634
+ registerWebElement,
3635
+ getWebTag,
3636
+ transformToWebProps,
3637
+ InteractiveWrapper
3158
3638
  };