@kbach/react 0.6.0 → 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.
@@ -541,12 +541,16 @@ var defaultTheme = {
541
541
  // src/core/platform.ts
542
542
  var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
543
543
  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;
544
+ var _resolveTargetOverride = null;
545
+ function setResolveTarget(target) {
546
+ _resolveTargetOverride = target;
547
+ }
545
548
  function setCSSGenMode(on) {
546
- _cssGenMode = on;
549
+ _resolveTargetOverride = on ? "web" : null;
547
550
  }
548
551
  function getEffectiveIsWeb() {
549
- return isWeb || _cssGenMode || !isNative;
552
+ if (_resolveTargetOverride) return _resolveTargetOverride === "web";
553
+ return isWeb || !isNative;
550
554
  }
551
555
  function toNativeValue(raw) {
552
556
  if (/^-?\d+(\.\d+)?px$/.test(raw)) return parseFloat(raw);
@@ -733,18 +737,28 @@ function resolveColor(value, colors, isArbitrary) {
733
737
  if (isNaN(alpha)) return hex;
734
738
  return hexToRgba(hex, alpha);
735
739
  }
736
- function hexToRgba(hex, alpha) {
740
+ function parseHexRgb(hex) {
737
741
  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);
742
+ if (h.length === 3 || h.length === 4) {
743
+ return [
744
+ parseInt(h[0] + h[0], 16),
745
+ parseInt(h[1] + h[1], 16),
746
+ parseInt(h[2] + h[2], 16)
747
+ ];
748
+ }
749
+ if (h.length === 6 || h.length === 8) {
750
+ return [
751
+ parseInt(h.slice(0, 2), 16),
752
+ parseInt(h.slice(2, 4), 16),
753
+ parseInt(h.slice(4, 6), 16)
754
+ ];
747
755
  }
756
+ return null;
757
+ }
758
+ function hexToRgba(hex, alpha) {
759
+ const rgb = parseHexRgb(hex);
760
+ if (!rgb) return hex;
761
+ const [r, g, b] = rgb;
748
762
  return `rgba(${r},${g},${b},${alpha})`;
749
763
  }
750
764
  function resolveSpacing(value, negative, spacing, isArbitrary) {
@@ -788,8 +802,8 @@ function resolveFontSize(value, fontSizes, isArbitrary) {
788
802
  if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
789
803
  return fontSizes[value] ?? null;
790
804
  }
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,)";
805
+ 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,)";
806
+ 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
807
  var _standalone = null;
794
808
  function buildStandalone() {
795
809
  const web = getEffectiveIsWeb();
@@ -1051,9 +1065,9 @@ function buildStandalone() {
1051
1065
  "backface-visible": { backfaceVisibility: "visible" },
1052
1066
  "backface-hidden": { backfaceVisibility: "hidden" },
1053
1067
  // 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,
1068
+ grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1069
+ invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1070
+ sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1057
1071
  // Divide none
1058
1072
  "divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
1059
1073
  // Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
@@ -1138,6 +1152,48 @@ function getStandalone() {
1138
1152
  if (!_standalone) _standalone = buildStandalone();
1139
1153
  return _standalone;
1140
1154
  }
1155
+ function makeSpacingResolver(prop) {
1156
+ return ({ value, negative, isArbitrary }, { spacing }) => {
1157
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1158
+ return v !== null ? { [prop]: v } : null;
1159
+ };
1160
+ }
1161
+ var PADDING_MARGIN_PROPS = {
1162
+ p: "padding",
1163
+ px: "paddingHorizontal",
1164
+ py: "paddingVertical",
1165
+ pt: "paddingTop",
1166
+ pr: "paddingRight",
1167
+ pb: "paddingBottom",
1168
+ pl: "paddingLeft",
1169
+ m: "margin",
1170
+ mx: "marginHorizontal",
1171
+ my: "marginVertical",
1172
+ mt: "marginTop",
1173
+ mr: "marginRight",
1174
+ mb: "marginBottom",
1175
+ ml: "marginLeft"
1176
+ };
1177
+ function makeBorderSideResolver(widthProp, colorProp) {
1178
+ return ({ value, isArbitrary }, { colors, borderWidth }) => {
1179
+ if (!value) return { [widthProp]: 1 };
1180
+ if (isArbitrary) {
1181
+ const w2 = toNativeValue(value);
1182
+ if (typeof w2 === "number") return { [widthProp]: w2 };
1183
+ return { [colorProp]: value };
1184
+ }
1185
+ const color = resolveColor(value, colors, false);
1186
+ if (color) return { [colorProp]: color };
1187
+ const w = borderWidth[value];
1188
+ return w !== void 0 ? { [widthProp]: w } : null;
1189
+ };
1190
+ }
1191
+ var BORDER_SIDE_PROPS = {
1192
+ "border-t": ["borderTopWidth", "borderTopColor"],
1193
+ "border-r": ["borderRightWidth", "borderRightColor"],
1194
+ "border-b": ["borderBottomWidth", "borderBottomColor"],
1195
+ "border-l": ["borderLeftWidth", "borderLeftColor"]
1196
+ };
1141
1197
  var RESOLVERS = {
1142
1198
  // ── Background ─────────────────────────────────────────────────────────────
1143
1199
  bg: ({ value, isArbitrary }, { colors }) => {
@@ -1171,64 +1227,8 @@ var RESOLVERS = {
1171
1227
  const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
1172
1228
  return { "--text-opacity": v };
1173
1229
  },
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
- },
1230
+ // ── Padding & margin ───────────────────────────────────────────────────────
1231
+ // Generated below via makeSpacingResolver() — see PADDING_MARGIN_PROPS.
1232
1232
  // ── Sizing ─────────────────────────────────────────────────────────────────
1233
1233
  w: ({ value, isArbitrary }, { spacing }) => {
1234
1234
  const v = resolveSizing(value, spacing, isArbitrary);
@@ -1272,54 +1272,7 @@ var RESOLVERS = {
1272
1272
  }
1273
1273
  return null;
1274
1274
  },
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
- },
1275
+ // border-t/-r/-b/-l generated below via makeBorderSideResolver() — see BORDER_SIDE_PROPS.
1323
1276
  // ── Border radius ──────────────────────────────────────────────────────────
1324
1277
  rounded: ({ value, isArbitrary }, { borderRadius }) => {
1325
1278
  const r = resolveRadius(value, borderRadius, isArbitrary);
@@ -1551,49 +1504,49 @@ var RESOLVERS = {
1551
1504
  "2xl": "blur(40px)",
1552
1505
  "3xl": "blur(64px)"
1553
1506
  };
1554
- if (value === "none") return { "--tw-blur": "", filter: FILTER_COMPOSE };
1507
+ if (value === "none") return { "--kb-blur": "", filter: FILTER_COMPOSE };
1555
1508
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1556
- return v !== void 0 ? { "--tw-blur": v, filter: FILTER_COMPOSE } : null;
1509
+ return v !== void 0 ? { "--kb-blur": v, filter: FILTER_COMPOSE } : null;
1557
1510
  },
1558
1511
  brightness: ({ value, isArbitrary }) => {
1559
1512
  if (!getEffectiveIsWeb()) return null;
1560
1513
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1561
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-brightness": v, filter: FILTER_COMPOSE };
1514
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-brightness": v, filter: FILTER_COMPOSE };
1562
1515
  },
1563
1516
  contrast: ({ value, isArbitrary }) => {
1564
1517
  if (!getEffectiveIsWeb()) return null;
1565
1518
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1566
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-contrast": v, filter: FILTER_COMPOSE };
1519
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
1567
1520
  },
1568
1521
  grayscale: ({ value }) => {
1569
1522
  if (!getEffectiveIsWeb()) return null;
1570
1523
  const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
1571
- return { "--tw-grayscale": v, filter: FILTER_COMPOSE };
1524
+ return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
1572
1525
  },
1573
1526
  "hue-rotate": ({ value, negative, isArbitrary }) => {
1574
1527
  if (!getEffectiveIsWeb()) return null;
1575
1528
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1576
1529
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1577
- return { "--tw-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1530
+ return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1578
1531
  },
1579
1532
  invert: ({ value }) => {
1580
1533
  if (!getEffectiveIsWeb()) return null;
1581
1534
  const v = value === "0" ? "invert(0)" : "invert(100%)";
1582
- return { "--tw-invert": v, filter: FILTER_COMPOSE };
1535
+ return { "--kb-invert": v, filter: FILTER_COMPOSE };
1583
1536
  },
1584
1537
  saturate: ({ value, isArbitrary }) => {
1585
1538
  if (!getEffectiveIsWeb()) return null;
1586
1539
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1587
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-saturate": v, filter: FILTER_COMPOSE };
1540
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
1588
1541
  },
1589
1542
  sepia: ({ value }) => {
1590
1543
  if (!getEffectiveIsWeb()) return null;
1591
1544
  const v = value === "0" ? "sepia(0)" : "sepia(100%)";
1592
- return { "--tw-sepia": v, filter: FILTER_COMPOSE };
1545
+ return { "--kb-sepia": v, filter: FILTER_COMPOSE };
1593
1546
  },
1594
1547
  "drop-shadow": ({ value, isArbitrary }) => {
1595
1548
  if (!getEffectiveIsWeb()) return null;
1596
- if (isArbitrary) return { "--tw-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1549
+ if (isArbitrary) return { "--kb-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1597
1550
  const presets = {
1598
1551
  "": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
1599
1552
  sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
@@ -1604,7 +1557,7 @@ var RESOLVERS = {
1604
1557
  none: "drop-shadow(0 0 #0000)"
1605
1558
  };
1606
1559
  const v = presets[value];
1607
- return v !== void 0 ? { "--tw-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1560
+ return v !== void 0 ? { "--kb-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1608
1561
  },
1609
1562
  // Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
1610
1563
  filter: ({ value, isArbitrary }) => {
@@ -1625,47 +1578,47 @@ var RESOLVERS = {
1625
1578
  "2xl": "blur(40px)",
1626
1579
  "3xl": "blur(64px)"
1627
1580
  };
1628
- if (value === "none") return { "--tw-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1581
+ if (value === "none") return { "--kb-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1629
1582
  const v = isArbitrary ? `blur(${value})` : sizes[value];
1630
- return v !== void 0 ? { "--tw-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1583
+ return v !== void 0 ? { "--kb-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1631
1584
  },
1632
1585
  "backdrop-brightness": ({ value, isArbitrary }) => {
1633
1586
  if (!getEffectiveIsWeb()) return null;
1634
1587
  const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1635
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1588
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1636
1589
  },
1637
1590
  "backdrop-contrast": ({ value, isArbitrary }) => {
1638
1591
  if (!getEffectiveIsWeb()) return null;
1639
1592
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1640
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1593
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1641
1594
  },
1642
1595
  "backdrop-grayscale": ({ value }) => {
1643
1596
  if (!getEffectiveIsWeb()) return null;
1644
- return { "--tw-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1597
+ return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1645
1598
  },
1646
1599
  "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
1647
1600
  if (!getEffectiveIsWeb()) return null;
1648
1601
  const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1649
1602
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1650
- return { "--tw-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1603
+ return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1651
1604
  },
1652
1605
  "backdrop-invert": ({ value }) => {
1653
1606
  if (!getEffectiveIsWeb()) return null;
1654
- return { "--tw-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1607
+ return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1655
1608
  },
1656
1609
  "backdrop-opacity": ({ value, isArbitrary }) => {
1657
1610
  if (!getEffectiveIsWeb()) return null;
1658
1611
  const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
1659
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1612
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1660
1613
  },
1661
1614
  "backdrop-saturate": ({ value, isArbitrary }) => {
1662
1615
  if (!getEffectiveIsWeb()) return null;
1663
1616
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1664
- return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1617
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1665
1618
  },
1666
1619
  "backdrop-sepia": ({ value }) => {
1667
1620
  if (!getEffectiveIsWeb()) return null;
1668
- return { "--tw-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1621
+ return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1669
1622
  },
1670
1623
  "backdrop-filter": ({ value, isArbitrary }) => {
1671
1624
  if (!getEffectiveIsWeb()) return null;
@@ -1689,7 +1642,7 @@ var RESOLVERS = {
1689
1642
  const dir = directions[value];
1690
1643
  if (!dir) return null;
1691
1644
  return {
1692
- backgroundImage: `linear-gradient(${dir}, var(--tw-gradient-from, transparent), var(--tw-gradient-stops, transparent))`
1645
+ backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
1693
1646
  };
1694
1647
  },
1695
1648
  from: ({ value, isArbitrary }, { colors }) => {
@@ -1697,8 +1650,8 @@ var RESOLVERS = {
1697
1650
  const color = resolveColor(value, colors, isArbitrary);
1698
1651
  if (!color) return null;
1699
1652
  return {
1700
- "--tw-gradient-from": color,
1701
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, transparent)`
1653
+ "--kb-gradient-from": color,
1654
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
1702
1655
  };
1703
1656
  },
1704
1657
  via: ({ value, isArbitrary }, { colors }) => {
@@ -1706,15 +1659,15 @@ var RESOLVERS = {
1706
1659
  const color = resolveColor(value, colors, isArbitrary);
1707
1660
  if (!color) return null;
1708
1661
  return {
1709
- "--tw-gradient-via": color,
1710
- "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to, transparent)`
1662
+ "--kb-gradient-via": color,
1663
+ "--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
1711
1664
  };
1712
1665
  },
1713
1666
  to: ({ value, isArbitrary }, { colors }) => {
1714
1667
  if (!getEffectiveIsWeb()) return null;
1715
1668
  const color = resolveColor(value, colors, isArbitrary);
1716
1669
  if (!color) return null;
1717
- return { "--tw-gradient-to": color };
1670
+ return { "--kb-gradient-to": color };
1718
1671
  },
1719
1672
  // ── Transform extras (web-only) ───────────────────────────────────────────
1720
1673
  "skew-x": ({ value, negative, isArbitrary }) => {
@@ -2318,6 +2271,12 @@ var RESOLVERS = {
2318
2271
  return { rowGap: v };
2319
2272
  }
2320
2273
  };
2274
+ for (const [utility, prop] of Object.entries(PADDING_MARGIN_PROPS)) {
2275
+ RESOLVERS[utility] = makeSpacingResolver(prop);
2276
+ }
2277
+ for (const [utility, [widthProp, colorProp]] of Object.entries(BORDER_SIDE_PROPS)) {
2278
+ RESOLVERS[utility] = makeBorderSideResolver(widthProp, colorProp);
2279
+ }
2321
2280
  function resolveUtility(parsed, theme) {
2322
2281
  if (!parsed.value) {
2323
2282
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
@@ -2515,10 +2474,11 @@ var BASE_RESET = [
2515
2474
 
2516
2475
  // src/core/cache.ts
2517
2476
  var LRUCache = class {
2518
- constructor(capacity = 1e4) {
2477
+ constructor(capacity = 1e4, onEvict) {
2519
2478
  this.capacity = capacity;
2520
2479
  if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
2521
2480
  this.cache = /* @__PURE__ */ new Map();
2481
+ this.onEvict = onEvict;
2522
2482
  }
2523
2483
  get(key) {
2524
2484
  if (!this.cache.has(key)) return void 0;
@@ -2531,7 +2491,10 @@ var LRUCache = class {
2531
2491
  if (this.cache.has(key)) {
2532
2492
  this.cache.delete(key);
2533
2493
  } else if (this.cache.size >= this.capacity) {
2534
- this.cache.delete(this.cache.keys().next().value);
2494
+ const oldestKey = this.cache.keys().next().value;
2495
+ const oldestValue = this.cache.get(oldestKey);
2496
+ this.cache.delete(oldestKey);
2497
+ this.onEvict?.(oldestKey, oldestValue);
2535
2498
  }
2536
2499
  this.cache.set(key, value);
2537
2500
  return this;
@@ -2625,7 +2588,20 @@ function getDefaultFontFamily() {
2625
2588
  return globalThis[FONT_KEY];
2626
2589
  }
2627
2590
  var _styleEl = null;
2628
- var _injectedRules = new LRUCache(5e4);
2591
+ function evictInjectedRule(rule) {
2592
+ const sheet = _styleEl?.sheet;
2593
+ if (!sheet) return;
2594
+ for (let i = 0; i < sheet.cssRules.length; i++) {
2595
+ if (sheet.cssRules[i].cssText === rule) {
2596
+ try {
2597
+ sheet.deleteRule(i);
2598
+ } catch {
2599
+ }
2600
+ return;
2601
+ }
2602
+ }
2603
+ }
2604
+ var _injectedRules = new LRUCache(5e4, evictInjectedRule);
2629
2605
  var _CSS_DISABLED_KEY = "__kbach_runtime_css_disabled__";
2630
2606
  function disableRuntimeCSS() {
2631
2607
  globalThis[_CSS_DISABLED_KEY] = true;
@@ -2662,8 +2638,7 @@ function injectGlobalStyles(theme) {
2662
2638
  if (typeof document === "undefined" || isRuntimeCSSDisabled()) return;
2663
2639
  const rules = [BASE_RESET];
2664
2640
  const ff = theme.fontFamily;
2665
- if (!ff) return;
2666
- if (ff.sans && ff.sans !== "System") {
2641
+ if (ff?.sans && ff.sans !== "System") {
2667
2642
  const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
2668
2643
  rules.push(`body { font-family: ${family}; }`);
2669
2644
  }
@@ -2826,7 +2801,7 @@ function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens
2826
2801
  else rule = `[data-theme="dark"] ${selector} { ${decls} }`;
2827
2802
  } else if (darkScheme === "light") {
2828
2803
  if (darkMode === "media") rule = `@media (prefers-color-scheme: light) { ${selector} { ${decls} } }`;
2829
- else if (darkMode === "class") rule = `:not(.dark) ${selector} { ${decls} }`;
2804
+ else if (darkMode === "class") rule = `.light ${selector} { ${decls} }`;
2830
2805
  else rule = `[data-theme="light"] ${selector} { ${decls} }`;
2831
2806
  } else {
2832
2807
  rule = `${selector} { ${decls} }`;
@@ -2967,11 +2942,14 @@ function getConfig() {
2967
2942
  return store.resolved;
2968
2943
  }
2969
2944
  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]];
2945
+ const lastDash = ref.lastIndexOf("-");
2946
+ if (lastDash <= 0) return null;
2947
+ const name = ref.slice(0, lastDash);
2948
+ const shade = ref.slice(lastDash + 1);
2949
+ if (!/^\d+$/.test(shade)) return null;
2950
+ const entry = colors[name];
2973
2951
  if (!entry || typeof entry !== "object") return null;
2974
- return entry[m[2]] ?? null;
2952
+ return entry[shade] ?? null;
2975
2953
  }
2976
2954
  function resolveColorRefs(colors) {
2977
2955
  const MAX_DEPTH = 5;
@@ -3001,7 +2979,7 @@ function resolveColorRefs(colors) {
3001
2979
  function buildConfig(userConfig) {
3002
2980
  let theme = { ...defaultTheme };
3003
2981
  if (userConfig.theme) {
3004
- theme = deepMerge(theme, userConfig.theme);
2982
+ theme = { ...theme, ...userConfig.theme };
3005
2983
  }
3006
2984
  if (userConfig.extend) {
3007
2985
  const extendConfig = userConfig.extend;
@@ -3128,10 +3106,12 @@ export {
3128
3106
  defaultTheme,
3129
3107
  isWeb,
3130
3108
  isNative,
3109
+ setResolveTarget,
3131
3110
  setCSSGenMode,
3132
3111
  getInteractiveModifiers,
3133
3112
  getModeModifiers,
3134
3113
  getResponsiveModifiers,
3114
+ parseHexRgb,
3135
3115
  parseClass,
3136
3116
  splitClassTokens,
3137
3117
  normalizeClassString,
@@ -3150,6 +3130,7 @@ export {
3150
3130
  generateClassCSS,
3151
3131
  resolve,
3152
3132
  flatten,
3133
+ clearCache,
3153
3134
  getConfig,
3154
3135
  buildConfig,
3155
3136
  onConfigChange,
package/dist/index.d.mts CHANGED
@@ -7,6 +7,8 @@ export { r as registerWebElement } from './web-substitute-CfpYFnE7.mjs';
7
7
  declare const defaultColors: ThemeColors;
8
8
  declare const defaultTheme: ThemeConfig;
9
9
 
10
+ declare function setResolveTarget(target: 'web' | 'native' | null): void;
11
+
10
12
  declare function parseClass(className: string): ParsedClass | null;
11
13
  /**
12
14
  * Split a class string into tokens. Whitespace at bracket depth > 0 is STRIPPED
@@ -48,6 +50,14 @@ declare function flatten(resolved: ResolvedStyle, isDark: boolean, state?: {
48
50
  visited?: boolean;
49
51
  placeholder?: boolean;
50
52
  }, breakpoints?: Set<string>): StyleValue;
53
+ /**
54
+ * Clear CSS injection state so stale rules are re-injected when the theme changes.
55
+ *
56
+ * The per-theme style cache (WeakMap) does not need to be cleared manually:
57
+ * updateConfig() creates a new theme object, making the old cache entry
58
+ * automatically unreachable for GC.
59
+ */
60
+ declare function clearCache(): void;
51
61
 
52
62
  /**
53
63
  * Load, merge, and cache the resolved config.
@@ -229,6 +239,7 @@ interface InteractiveWrapperProps {
229
239
  onPointerDown?: (...args: any[]) => void;
230
240
  onPointerUp?: (...args: any[]) => void;
231
241
  onPointerLeave?: (...args: any[]) => void;
242
+ onPointerCancel?: (...args: any[]) => void;
232
243
  onMouseEnter?: (...args: any[]) => void;
233
244
  onMouseLeave?: (...args: any[]) => void;
234
245
  onFocus?: (...args: any[]) => void;
@@ -278,4 +289,4 @@ declare function kb(classString: string, isDark?: boolean): StyleValue | string;
278
289
  */
279
290
  declare function cx(...classes: Array<string | false | null | undefined>): string;
280
291
 
281
- export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
292
+ export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export { r as registerWebElement } from './web-substitute-CfpYFnE7.js';
7
7
  declare const defaultColors: ThemeColors;
8
8
  declare const defaultTheme: ThemeConfig;
9
9
 
10
+ declare function setResolveTarget(target: 'web' | 'native' | null): void;
11
+
10
12
  declare function parseClass(className: string): ParsedClass | null;
11
13
  /**
12
14
  * Split a class string into tokens. Whitespace at bracket depth > 0 is STRIPPED
@@ -48,6 +50,14 @@ declare function flatten(resolved: ResolvedStyle, isDark: boolean, state?: {
48
50
  visited?: boolean;
49
51
  placeholder?: boolean;
50
52
  }, breakpoints?: Set<string>): StyleValue;
53
+ /**
54
+ * Clear CSS injection state so stale rules are re-injected when the theme changes.
55
+ *
56
+ * The per-theme style cache (WeakMap) does not need to be cleared manually:
57
+ * updateConfig() creates a new theme object, making the old cache entry
58
+ * automatically unreachable for GC.
59
+ */
60
+ declare function clearCache(): void;
51
61
 
52
62
  /**
53
63
  * Load, merge, and cache the resolved config.
@@ -229,6 +239,7 @@ interface InteractiveWrapperProps {
229
239
  onPointerDown?: (...args: any[]) => void;
230
240
  onPointerUp?: (...args: any[]) => void;
231
241
  onPointerLeave?: (...args: any[]) => void;
242
+ onPointerCancel?: (...args: any[]) => void;
232
243
  onMouseEnter?: (...args: any[]) => void;
233
244
  onMouseLeave?: (...args: any[]) => void;
234
245
  onFocus?: (...args: any[]) => void;
@@ -278,4 +289,4 @@ declare function kb(classString: string, isDark?: boolean): StyleValue | string;
278
289
  */
279
290
  declare function cx(...classes: Array<string | false | null | undefined>): string;
280
291
 
281
- export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
292
+ export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };