@kbach/react 0.6.15 → 0.6.16

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.
@@ -737,25 +737,6 @@ function resolveColor(value, colors, isArbitrary) {
737
737
  }
738
738
  }
739
739
  }
740
- if (hex && !hex.startsWith("#") && !hex.startsWith("rgb") && hex !== "transparent" && hex !== "currentColor") {
741
- if (hex in colors) {
742
- const alias = colors[hex];
743
- if (typeof alias === "string") hex = alias;
744
- else if (typeof alias === "object" && "6" in alias) hex = alias["6"] ?? hex;
745
- } else {
746
- const aliasLastDash = hex.lastIndexOf("-");
747
- if (aliasLastDash > 0) {
748
- const aliasColorName = hex.slice(0, aliasLastDash);
749
- const aliasShade = hex.slice(aliasLastDash + 1);
750
- const aliasScale = colors[aliasColorName];
751
- if (aliasScale && typeof aliasScale === "object") {
752
- hex = aliasScale[aliasShade] ?? null;
753
- } else if (typeof aliasScale === "string") {
754
- hex = aliasScale;
755
- }
756
- }
757
- }
758
- }
759
740
  if (!hex) return null;
760
741
  if (!opacityPart) {
761
742
  if (!getEffectiveIsWeb() && hex.startsWith("#") && hex.length === 9) {
@@ -771,6 +752,8 @@ function resolveColor(value, colors, isArbitrary) {
771
752
  alpha = parseFloat(opacityPart) / 100;
772
753
  }
773
754
  if (isNaN(alpha)) return hex;
755
+ if (alpha < 0) alpha = 0;
756
+ else if (alpha > 1) alpha = 1;
774
757
  return hexToRgba(hex, alpha);
775
758
  }
776
759
  function parseHexRgb(hex) {
@@ -2468,6 +2451,14 @@ function getBuiltinStandaloneNames() {
2468
2451
  }
2469
2452
 
2470
2453
  // src/core/parser.ts
2454
+ var UNSAFE_ARBITRARY_VALUE = /[{};\\]|\/\*|\*\//;
2455
+ function isSafeArbitraryValue(value) {
2456
+ if (!UNSAFE_ARBITRARY_VALUE.test(value)) return true;
2457
+ if (process.env.NODE_ENV !== "production") {
2458
+ kbachWarn(`Unsafe arbitrary value rejected: "${value}"`);
2459
+ }
2460
+ return false;
2461
+ }
2471
2462
  function parseClass(className) {
2472
2463
  const trimmed = className.trim();
2473
2464
  if (!trimmed) return null;
@@ -2506,6 +2497,7 @@ function parseClass(className) {
2506
2497
  if (bracketStart > 0 && remaining[bracketStart - 1] === "-" && remaining.endsWith("]")) {
2507
2498
  const utility = remaining.slice(0, bracketStart - 1);
2508
2499
  const value = remaining.slice(bracketStart + 1, -1).replace(/_/g, " ");
2500
+ if (!isSafeArbitraryValue(value)) return null;
2509
2501
  return { original: trimmed, modifiers, negative, important, utility, value, isArbitrary: true };
2510
2502
  }
2511
2503
  if (remaining.endsWith("]") && bracketStart === -1) {
@@ -2515,6 +2507,7 @@ function parseClass(className) {
2515
2507
  }
2516
2508
  if (remaining.startsWith("[") && remaining.endsWith("]")) {
2517
2509
  const value = remaining.slice(1, -1).replace(/_/g, " ");
2510
+ if (!isSafeArbitraryValue(value)) return null;
2518
2511
  return { original: trimmed, modifiers, negative, important, utility: "", value, isArbitrary: true };
2519
2512
  }
2520
2513
  if (getBuiltinStandaloneNames().has(remaining)) {
@@ -2763,17 +2756,20 @@ function getDefaultFontFamily() {
2763
2756
  return globalThis[FONT_KEY];
2764
2757
  }
2765
2758
  var _styleEl = null;
2759
+ var _ruleIndexByKey = /* @__PURE__ */ new Map();
2766
2760
  function evictInjectedRule(rule) {
2761
+ const idx = _ruleIndexByKey.get(rule);
2762
+ _ruleIndexByKey.delete(rule);
2763
+ if (idx === void 0) return;
2767
2764
  const sheet = _styleEl?.sheet;
2768
2765
  if (!sheet) return;
2769
- for (let i = 0; i < sheet.cssRules.length; i++) {
2770
- if (sheet.cssRules[i].cssText === rule) {
2771
- try {
2772
- sheet.deleteRule(i);
2773
- } catch {
2774
- }
2775
- return;
2776
- }
2766
+ try {
2767
+ sheet.deleteRule(idx);
2768
+ } catch {
2769
+ return;
2770
+ }
2771
+ for (const [key, i] of _ruleIndexByKey) {
2772
+ if (i > idx) _ruleIndexByKey.set(key, i - 1);
2777
2773
  }
2778
2774
  }
2779
2775
  var _injectedRules = new LRUCache(5e4, evictInjectedRule);
@@ -2793,11 +2789,15 @@ function getStyleEl() {
2793
2789
  }
2794
2790
  function injectRule(rule) {
2795
2791
  if (isRuntimeCSSDisabled()) return;
2796
- if (_injectedRules.has(rule)) return;
2797
- _injectedRules.set(rule, true);
2792
+ if (_injectedRules.get(rule)) return;
2798
2793
  try {
2799
2794
  const sheet = getStyleEl().sheet;
2800
- if (sheet) sheet.insertRule(rule, sheet.cssRules.length);
2795
+ if (sheet) {
2796
+ const idx = sheet.cssRules.length;
2797
+ sheet.insertRule(rule, idx);
2798
+ _ruleIndexByKey.set(rule, idx);
2799
+ _injectedRules.set(rule, true);
2800
+ }
2801
2801
  } catch {
2802
2802
  }
2803
2803
  }
@@ -3066,6 +3066,7 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
3066
3066
  }
3067
3067
  function clearCache() {
3068
3068
  _injectedRules.clear();
3069
+ _ruleIndexByKey.clear();
3069
3070
  if (_styleEl) {
3070
3071
  _styleEl.remove();
3071
3072
  _styleEl = null;
@@ -3303,6 +3304,9 @@ var useSyncExternalStore = React.useSyncExternalStore ?? function useSyncExterna
3303
3304
  };
3304
3305
 
3305
3306
  // src/useGlobalDarkMode.ts
3307
+ var NOOP_SUB = (_) => () => {
3308
+ };
3309
+ var FALSE_SNAP = () => false;
3306
3310
  function useGlobalDarkMode() {
3307
3311
  return useSyncExternalStore(
3308
3312
  subscribeGlobalDarkMode,
@@ -3311,6 +3315,13 @@ function useGlobalDarkMode() {
3311
3315
  // SSR: default light
3312
3316
  );
3313
3317
  }
3318
+ function useConditionalGlobalDarkMode(active) {
3319
+ return useSyncExternalStore(
3320
+ active ? subscribeGlobalDarkMode : NOOP_SUB,
3321
+ active ? getGlobalDarkMode : FALSE_SNAP,
3322
+ FALSE_SNAP
3323
+ );
3324
+ }
3314
3325
 
3315
3326
  // src/shared-utils.ts
3316
3327
  function hasResponsiveBuckets(resolved) {
@@ -3649,7 +3660,7 @@ function transformToWebProps(originalName, tag, props) {
3649
3660
  import React2, { forwardRef, useState, useCallback, useMemo } from "react";
3650
3661
 
3651
3662
  // src/useGlobalWidth.ts
3652
- var NOOP_SUB = (_) => () => {
3663
+ var NOOP_SUB2 = (_) => () => {
3653
3664
  };
3654
3665
  var ZERO_SNAP = () => 0;
3655
3666
  var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
@@ -3690,7 +3701,7 @@ function useGlobalWidth() {
3690
3701
  }
3691
3702
  function useConditionalWidth(active) {
3692
3703
  return useSyncExternalStore(
3693
- active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
3704
+ active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB2,
3694
3705
  active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
3695
3706
  ZERO_SNAP
3696
3707
  );
@@ -3715,27 +3726,48 @@ var InteractiveWrapper = forwardRef(
3715
3726
  onBlur,
3716
3727
  ...rest
3717
3728
  }, ref) {
3718
- const isDark = useGlobalDarkMode();
3729
+ const isWebPlatform = getEffectiveIsWeb();
3730
+ const isDark = useConditionalGlobalDarkMode(!isWebPlatform);
3719
3731
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
3720
- const width = useConditionalWidth(needsWidth);
3732
+ const width = useConditionalWidth(needsWidth && !isWebPlatform);
3721
3733
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3722
3734
  const [pressed, setPressed] = useState(false);
3723
3735
  const [hovered, setHovered] = useState(false);
3724
3736
  const [focused, setFocused] = useState(false);
3725
- const handlePressIn = useCallback(chain(onPressIn, () => setPressed(true)), [onPressIn]);
3726
- const handlePressOut = useCallback(chain(onPressOut, () => setPressed(false)), [onPressOut]);
3727
- const handlePointerDown = useCallback(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
3728
- const handlePointerUp = useCallback(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
3729
- const handlePointerLeave = useCallback(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
3730
- const handlePointerCancel = useCallback(chain(onPointerCancel, () => setPressed(false)), [onPointerCancel]);
3731
- const handleMouseEnter = useCallback(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
3732
- const handleMouseLeave = useCallback(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
3733
- const handleFocus = useCallback(chain(onFocus, () => setFocused(true)), [onFocus]);
3734
- const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
3737
+ const handlePressIn = useCallback(chain(onPressIn, () => {
3738
+ if (!isWebPlatform) setPressed(true);
3739
+ }), [onPressIn, isWebPlatform]);
3740
+ const handlePressOut = useCallback(chain(onPressOut, () => {
3741
+ if (!isWebPlatform) setPressed(false);
3742
+ }), [onPressOut, isWebPlatform]);
3743
+ const handlePointerDown = useCallback(chain(onPointerDown, () => {
3744
+ if (!isWebPlatform) setPressed(true);
3745
+ }), [onPointerDown, isWebPlatform]);
3746
+ const handlePointerUp = useCallback(chain(onPointerUp, () => {
3747
+ if (!isWebPlatform) setPressed(false);
3748
+ }), [onPointerUp, isWebPlatform]);
3749
+ const handlePointerLeave = useCallback(chain(onPointerLeave, () => {
3750
+ if (!isWebPlatform) setPressed(false);
3751
+ }), [onPointerLeave, isWebPlatform]);
3752
+ const handlePointerCancel = useCallback(chain(onPointerCancel, () => {
3753
+ if (!isWebPlatform) setPressed(false);
3754
+ }), [onPointerCancel, isWebPlatform]);
3755
+ const handleMouseEnter = useCallback(chain(onMouseEnter, () => {
3756
+ if (!isWebPlatform) setHovered(true);
3757
+ }), [onMouseEnter, isWebPlatform]);
3758
+ const handleMouseLeave = useCallback(chain(onMouseLeave, () => {
3759
+ if (!isWebPlatform) setHovered(false);
3760
+ }), [onMouseLeave, isWebPlatform]);
3761
+ const handleFocus = useCallback(chain(onFocus, () => {
3762
+ if (!isWebPlatform) setFocused(true);
3763
+ }), [onFocus, isWebPlatform]);
3764
+ const handleBlur = useCallback(chain(onBlur, () => {
3765
+ if (!isWebPlatform) setFocused(false);
3766
+ }), [onBlur, isWebPlatform]);
3735
3767
  const { children, disabled, checked, ...restForComponent } = rest;
3736
3768
  const computedStyle = useMemo(
3737
3769
  () => {
3738
- if (isWeb) return {};
3770
+ if (isWebPlatform) return {};
3739
3771
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
3740
3772
  stripInternalMarkers(s);
3741
3773
  if (typeof Component !== "string") stripWebOnlyProps(s);
@@ -3743,7 +3775,7 @@ var InteractiveWrapper = forwardRef(
3743
3775
  },
3744
3776
  [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
3745
3777
  );
3746
- const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3778
+ const skipComputedInline = isWebPlatform;
3747
3779
  const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3748
3780
  const componentProps = {
3749
3781
  ref,
@@ -3789,6 +3821,8 @@ export {
3789
3821
  isWeb,
3790
3822
  isNative,
3791
3823
  setResolveTarget,
3824
+ getEffectiveIsWeb,
3825
+ kbachWarn,
3792
3826
  getInteractiveModifiers,
3793
3827
  getModeModifiers,
3794
3828
  getResponsiveModifiers,
@@ -3817,6 +3851,7 @@ export {
3817
3851
  setGlobalDarkMode,
3818
3852
  useSyncExternalStore,
3819
3853
  useGlobalDarkMode,
3854
+ useConditionalGlobalDarkMode,
3820
3855
  EMPTY_BREAKPOINTS,
3821
3856
  useGlobalWidth,
3822
3857
  useConditionalWidth,
@@ -6,6 +6,7 @@ import {
6
6
  getActiveBreakpoints,
7
7
  getConfig,
8
8
  getDefaultFontFamily,
9
+ getEffectiveIsWeb,
9
10
  getGlobalScreens,
10
11
  getInteractiveModifiers,
11
12
  getModeModifiers,
@@ -21,9 +22,9 @@ import {
21
22
  stripInternalMarkers,
22
23
  stripWebOnlyProps,
23
24
  transformToWebProps,
24
- useConditionalWidth,
25
- useGlobalDarkMode
26
- } from "./chunk-YH2IOSKT.mjs";
25
+ useConditionalGlobalDarkMode,
26
+ useConditionalWidth
27
+ } from "./chunk-GJSZUC6Q.mjs";
27
28
 
28
29
  // src/jsx-runtime.tsx
29
30
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -33,20 +34,21 @@ import { Fragment } from "react";
33
34
  import React, { useMemo } from "react";
34
35
  var DarkWrapper = React.forwardRef(
35
36
  function DarkWrapper2({ Component, resolvedStyle, style: styleProp, children, ...rest }, ref) {
36
- const isDark = useGlobalDarkMode();
37
+ const isWebPlatform = getEffectiveIsWeb();
38
+ const isDark = useConditionalGlobalDarkMode(!isWebPlatform);
37
39
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
38
- const width = useConditionalWidth(needsWidth);
40
+ const width = useConditionalWidth(needsWidth && !isWebPlatform);
39
41
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
40
42
  const screens = getGlobalScreens();
41
43
  const isNonStringComponent = typeof Component !== "string";
42
44
  const computedStyle = useMemo(() => {
43
- if (isWeb) return {};
45
+ if (isWebPlatform) return {};
44
46
  const s = flatten(resolvedStyle, isDark, {}, breakpoints);
45
47
  stripInternalMarkers(s);
46
48
  if (isNonStringComponent) stripWebOnlyProps(s);
47
49
  return s;
48
50
  }, [resolvedStyle, isDark, width, screens, isNonStringComponent]);
49
- const skipComputedInline = isWeb || !isNative && typeof Component === "string";
51
+ const skipComputedInline = isWebPlatform;
50
52
  const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
51
53
  const props = { ref, ...rest, style: finalStyle };
52
54
  return Array.isArray(children) ? React.createElement(Component, props, ...children) : React.createElement(Component, props, children);
@@ -113,7 +115,7 @@ function makeElement(isStaticChildren, type, props, key) {
113
115
  }
114
116
  function processElement(type, rawProps, key, isStaticChildren) {
115
117
  if (type === null || typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
116
- const webTag = isWeb ? getWebTag(type, rawProps ?? void 0) : null;
118
+ const webTag = getEffectiveIsWeb() ? getWebTag(type, rawProps ?? void 0) : null;
117
119
  const effectiveType = webTag ?? type;
118
120
  const originalName = webTag ? type?.displayName ?? type?.name : void 0;
119
121
  if (!rawProps) return _jsx(effectiveType, null, key);
@@ -137,7 +139,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
137
139
  }, key);
138
140
  }
139
141
  if (!classStr && !__kbachStyles) {
140
- if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
142
+ if (getEffectiveIsWeb()) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
141
143
  const defaultFont = getCachedDefaultFont();
142
144
  if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
143
145
  const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
@@ -166,7 +168,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
166
168
  ...passProps
167
169
  }, key);
168
170
  }
169
- const skipComputedInline = isWeb || !isNative && typeof effectiveType === "string";
171
+ const skipComputedInline = getEffectiveIsWeb();
170
172
  let finalStyle;
171
173
  if (!skipComputedInline) {
172
174
  const computedStyle = flatten(resolved, false);