@kbach/react 0.5.47 → 0.5.49

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.
@@ -2,11 +2,12 @@ import {
2
2
  flatten,
3
3
  getActiveBreakpoints,
4
4
  getGlobalWidth,
5
+ getInteractiveModifiers,
5
6
  getResponsiveModifiers,
6
7
  isNative,
7
8
  isWeb,
8
9
  subscribeGlobalWidth
9
- } from "./chunk-NIBECTRQ.mjs";
10
+ } from "./chunk-BKSXIWL7.mjs";
10
11
 
11
12
  // src/core/darkModeStore.ts
12
13
  var KEY = "__kbach_dark_store__";
@@ -36,6 +37,91 @@ function subscribeGlobalDarkMode(callback) {
36
37
  return () => store.subscribers.delete(callback);
37
38
  }
38
39
 
40
+ // src/web-substitute.ts
41
+ var _rnToHtml = {
42
+ View: "div",
43
+ SafeAreaView: "div",
44
+ KeyboardAvoidingView: "div",
45
+ ScrollView: "div",
46
+ VirtualizedList: "div",
47
+ Text: "span",
48
+ Pressable: "div",
49
+ TouchableOpacity: "div",
50
+ TouchableHighlight: "div",
51
+ TouchableWithoutFeedback: "div",
52
+ TouchableNativeFeedback: "div"
53
+ };
54
+ var _userMap = /* @__PURE__ */ new Map();
55
+ var _cache = /* @__PURE__ */ new WeakMap();
56
+ function registerWebElement(rnComponent, htmlTag) {
57
+ if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
58
+ _userMap.set(rnComponent, htmlTag);
59
+ _cache.delete(rnComponent);
60
+ }
61
+ function getWebTag(type) {
62
+ if (typeof type === "string") return null;
63
+ if (type === null || typeof type !== "function" && typeof type !== "object") return null;
64
+ const obj = type;
65
+ if (_userMap.has(obj)) return _userMap.get(obj);
66
+ if (_cache.has(obj)) return _cache.get(obj);
67
+ const name = obj.displayName ?? obj.name;
68
+ const tag = name ? _rnToHtml[name] ?? null : null;
69
+ _cache.set(obj, tag);
70
+ return tag;
71
+ }
72
+ var _rnOnlyProps = /* @__PURE__ */ new Set([
73
+ "onLongPress",
74
+ "delayLongPress",
75
+ "activeOpacity",
76
+ "underlayColor",
77
+ "hitSlop",
78
+ "pressRetentionOffset",
79
+ "accessible",
80
+ "accessibilityState",
81
+ "accessibilityLiveRegion",
82
+ "importantForAccessibility",
83
+ "nativeID",
84
+ "collapsable",
85
+ "needsOffscreenAlphaCompositing",
86
+ "renderToHardwareTextureAndroid",
87
+ "shouldRasterizeIOS",
88
+ "pointerEvents"
89
+ // RN and HTML values differ
90
+ ]);
91
+ var _pressableNames = /* @__PURE__ */ new Set([
92
+ "Pressable",
93
+ "TouchableOpacity",
94
+ "TouchableHighlight",
95
+ "TouchableWithoutFeedback",
96
+ "TouchableNativeFeedback"
97
+ ]);
98
+ function transformToWebProps(originalName, props) {
99
+ const out = {};
100
+ const isPressable = _pressableNames.has(originalName);
101
+ for (const [k, v] of Object.entries(props)) {
102
+ if (_rnOnlyProps.has(k)) continue;
103
+ if (k === "onPress") {
104
+ if (!("onClick" in props)) out.onClick = v;
105
+ continue;
106
+ }
107
+ if (k === "accessibilityLabel") {
108
+ if (out["aria-label"] == null) out["aria-label"] = v;
109
+ continue;
110
+ }
111
+ if (k === "accessibilityRole") {
112
+ if (out.role == null) out.role = v;
113
+ continue;
114
+ }
115
+ if (k === "testID") {
116
+ if (out["data-testid"] == null) out["data-testid"] = v;
117
+ continue;
118
+ }
119
+ out[k] = v;
120
+ }
121
+ if (isPressable && !out.role) out.role = "button";
122
+ return out;
123
+ }
124
+
39
125
  // src/useGlobalDarkMode.ts
40
126
  import React from "react";
41
127
  var useSyncExternalStore = React.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
@@ -120,6 +206,16 @@ function hasResponsiveBuckets(resolved) {
120
206
  }
121
207
  return false;
122
208
  }
209
+ function hasInteractiveBuckets(resolved) {
210
+ const interactiveMods = getInteractiveModifiers();
211
+ for (const key of Object.keys(resolved)) {
212
+ if (key === "base") continue;
213
+ for (const mod of key.split(":")) {
214
+ if (interactiveMods.has(mod)) return true;
215
+ }
216
+ }
217
+ return false;
218
+ }
123
219
  var EMPTY_BREAKPOINTS2 = /* @__PURE__ */ new Set();
124
220
 
125
221
  // src/InteractiveWrapper.tsx
@@ -164,7 +260,7 @@ var InteractiveWrapper = forwardRef(
164
260
  const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
165
261
  const computedStyle = useMemo(
166
262
  () => {
167
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints);
263
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
168
264
  delete s.__divideX;
169
265
  delete s.__divideY;
170
266
  delete s.__divideColor;
@@ -198,8 +294,8 @@ var InteractiveWrapper = forwardRef(
198
294
  [resolvedStyle, isDark, pressed, hovered, focused, width]
199
295
  // eslint-disable-line react-hooks/exhaustive-deps
200
296
  );
201
- const isWebHTMLElement = !isNative && typeof Component === "string";
202
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
297
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
298
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
203
299
  const { children, ...restWithoutChildren } = rest;
204
300
  const componentProps = {
205
301
  ref,
@@ -226,7 +322,11 @@ export {
226
322
  useGlobalWidth,
227
323
  useConditionalWidth,
228
324
  hasResponsiveBuckets,
325
+ hasInteractiveBuckets,
229
326
  EMPTY_BREAKPOINTS2,
327
+ registerWebElement,
328
+ getWebTag,
329
+ transformToWebProps,
230
330
  useGlobalDarkMode,
231
331
  InteractiveWrapper
232
332
  };
@@ -716,7 +716,12 @@ function resolveColor(value, colors, isArbitrary) {
716
716
  }
717
717
  }
718
718
  if (!hex) return null;
719
- if (!opacityPart) return hex;
719
+ if (!opacityPart) {
720
+ if (!isWeb && hex.startsWith("#") && hex.length === 9) {
721
+ return hexToRgba(hex, Math.round(parseInt(hex.slice(7, 9), 16) / 255 * 1e3) / 1e3);
722
+ }
723
+ return hex;
724
+ }
720
725
  let alpha;
721
726
  if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
722
727
  const v = parseFloat(opacityPart.slice(1, -1));
@@ -2279,12 +2284,6 @@ var RESOLVERS = {
2279
2284
  function resolveUtility(parsed, theme) {
2280
2285
  if (!parsed.value) {
2281
2286
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
2282
- if (parsed.utility === "grd" || parsed.utility === "grid") {
2283
- return getEffectiveIsWeb() ? { display: "grid" } : null;
2284
- }
2285
- if (parsed.utility === "inline-grid") {
2286
- return getEffectiveIsWeb() ? { display: "inline-grid" } : null;
2287
- }
2288
2287
  if (parsed.utility in getStandalone()) return getStandalone()[parsed.utility] ?? null;
2289
2288
  }
2290
2289
  const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
@@ -2941,6 +2940,8 @@ function buildConfig(userConfig) {
2941
2940
  };
2942
2941
  clearPluginUtilities();
2943
2942
  clearPluginModifiers();
2943
+ const _store = getConfigStore();
2944
+ for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
2944
2945
  const pluginAPI = makePluginAPI(resolved.theme);
2945
2946
  for (const plugin of resolved.plugins) {
2946
2947
  plugin(pluginAPI);
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  EMPTY_BREAKPOINTS2 as EMPTY_BREAKPOINTS,
3
3
  InteractiveWrapper,
4
+ getWebTag,
4
5
  hasResponsiveBuckets,
6
+ transformToWebProps,
5
7
  useConditionalWidth,
6
8
  useGlobalDarkMode
7
- } from "./chunk-U3GY5Y6J.mjs";
9
+ } from "./chunk-3UUTNNWV.mjs";
8
10
  import {
9
11
  flatten,
10
12
  getActiveBreakpoints,
@@ -15,27 +17,32 @@ import {
15
17
  getResponsiveModifiers,
16
18
  isNative,
17
19
  isRuntimeCSSDisabled,
20
+ isWeb,
18
21
  normalizeClassString,
19
22
  resolve
20
- } from "./chunk-NIBECTRQ.mjs";
23
+ } from "./chunk-BKSXIWL7.mjs";
21
24
 
22
25
  // src/jsx-runtime.tsx
23
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
27
  import { Fragment } from "react";
25
28
 
26
29
  // src/DarkWrapper.tsx
27
- import React from "react";
30
+ import React, { useMemo } from "react";
28
31
  var DarkWrapper = React.forwardRef(
29
32
  function DarkWrapper2({ Component, resolvedStyle, style: styleProp, children, ...rest }, ref) {
30
33
  const isDark = useGlobalDarkMode();
31
34
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
32
35
  const width = useConditionalWidth(needsWidth);
33
36
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
34
- const computedStyle = flatten(resolvedStyle, isDark, {}, breakpoints);
35
- stripInternalMarkers(computedStyle);
36
- if (typeof Component !== "string") stripWebOnlyProps(computedStyle);
37
- const isWebHTMLElement = !isNative && typeof Component === "string";
38
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
37
+ const isNonStringComponent = typeof Component !== "string";
38
+ const computedStyle = useMemo(() => {
39
+ const s = flatten(resolvedStyle, isDark, {}, breakpoints);
40
+ stripInternalMarkers(s);
41
+ if (isNonStringComponent) stripWebOnlyProps(s);
42
+ return s;
43
+ }, [resolvedStyle, isDark, width, isNonStringComponent]);
44
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
45
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
39
46
  const props = { ref, ...rest, style: finalStyle };
40
47
  return Array.isArray(children) ? React.createElement(Component, props, ...children) : React.createElement(Component, props, children);
41
48
  }
@@ -155,31 +162,36 @@ function stripWebOnlyInlineProps(s) {
155
162
  }
156
163
  function processElement(type, rawProps, key, isStaticChildren) {
157
164
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
158
- if (!rawProps) return _jsx(type, null, key);
159
- const { className, kb: kbProp, __kbachStyles, __kbachClasses } = rawProps;
165
+ const webTag = isWeb ? getWebTag(type) : null;
166
+ const effectiveType = webTag ?? type;
167
+ const originalName = webTag ? type?.displayName ?? type?.name : void 0;
168
+ if (!rawProps) return _jsx(effectiveType, null, key);
169
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
170
+ const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
160
171
  const classStr = className ?? kbProp ?? __kbachClasses;
161
172
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
162
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
163
- return makeElement(isStaticChildren, type, {
173
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
174
+ return makeElement(isStaticChildren, effectiveType, {
164
175
  ...passProps2,
165
176
  className: normalizeClassString(classStr),
166
177
  ...userStyle2 !== void 0 ? { style: userStyle2 } : {}
167
178
  }, key);
168
179
  }
169
180
  if (!classStr && !__kbachStyles) {
181
+ if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
170
182
  const defaultFont = getCachedDefaultFont();
171
- if (!defaultFont) return makeElement(isStaticChildren, type, rawProps, key);
172
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
183
+ if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
184
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
173
185
  const finalStyle2 = userStyle2 ? Array.isArray(userStyle2) ? { fontFamily: defaultFont, ...Object.assign({}, ...userStyle2) } : { fontFamily: defaultFont, ...userStyle2 } : { fontFamily: defaultFont };
174
- return makeElement(isStaticChildren, type, { ...passProps2, style: finalStyle2 }, key);
186
+ return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
175
187
  }
176
188
  const config = getConfig();
177
189
  const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
178
- const { style: userStyle, ...passProps } = omitConsumed(rawProps);
190
+ const { style: userStyle, ...passProps } = omitConsumed(workingProps);
179
191
  const { interactive, modeOrResponsive } = bucketMods(resolved);
180
192
  if (interactive) {
181
193
  return _jsx(InteractiveWrapper, {
182
- Component: type,
194
+ Component: effectiveType,
183
195
  resolvedStyle: resolved,
184
196
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
185
197
  style: userStyle,
@@ -188,24 +200,24 @@ function processElement(type, rawProps, key, isStaticChildren) {
188
200
  }
189
201
  if (modeOrResponsive) {
190
202
  return _jsx(DarkWrapper, {
191
- Component: type,
203
+ Component: effectiveType,
192
204
  resolvedStyle: resolved,
193
205
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
194
206
  style: userStyle,
195
207
  ...passProps
196
208
  }, key);
197
209
  }
198
- const isWebHTMLElement = !isNative && typeof type === "string";
210
+ const skipComputedInline = isWeb || !isNative && typeof effectiveType === "string";
199
211
  let finalStyle;
200
- if (!isWebHTMLElement) {
212
+ if (!skipComputedInline) {
201
213
  const computedStyle = flatten(resolved, false);
202
214
  stripInternalMarkers2(computedStyle);
203
- if (typeof type !== "string") stripWebOnlyInlineProps(computedStyle);
215
+ if (typeof effectiveType !== "string") stripWebOnlyInlineProps(computedStyle);
204
216
  finalStyle = mergeStyle(computedStyle, userStyle);
205
217
  } else {
206
218
  finalStyle = userStyle ?? void 0;
207
219
  }
208
- return makeElement(isStaticChildren, type, {
220
+ return makeElement(isStaticChildren, effectiveType, {
209
221
  ...passProps,
210
222
  style: finalStyle,
211
223
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {}
package/dist/index.d.mts CHANGED
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
3
3
  import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-D-24rbXu.mjs';
4
4
  export { d as PluginAPI } from './types-D-24rbXu.mjs';
5
+ export { r as registerWebElement } from './web-substitute-CfpYFnE7.mjs';
5
6
 
6
7
  declare const defaultColors: ThemeColors;
7
8
  declare const defaultTheme: ThemeConfig;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
3
3
  import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-D-24rbXu.js';
4
4
  export { d as PluginAPI } from './types-D-24rbXu.js';
5
+ export { r as registerWebElement } from './web-substitute-CfpYFnE7.js';
5
6
 
6
7
  declare const defaultColors: ThemeColors;
7
8
  declare const defaultTheme: ThemeConfig;
package/dist/index.js CHANGED
@@ -46,6 +46,7 @@ __export(index_exports, {
46
46
  normalizeClassString: () => normalizeClassString,
47
47
  parseClass: () => parseClass,
48
48
  parseClasses: () => parseClasses,
49
+ registerWebElement: () => registerWebElement,
49
50
  resolve: () => resolve,
50
51
  splitClassTokens: () => splitClassTokens,
51
52
  styled: () => styled,
@@ -835,6 +836,12 @@ function isKnownModifier(name) {
835
836
  function _allEntries() {
836
837
  return [...Object.entries(BUILTIN_MODIFIERS), ...Object.entries(_pluginModifiers)];
837
838
  }
839
+ function getInteractiveModifiers() {
840
+ if (!_interactiveNames) {
841
+ _interactiveNames = new Set(_allEntries().filter(([, d]) => d.jsBehavior === "interactive").map(([k]) => k));
842
+ }
843
+ return _interactiveNames;
844
+ }
838
845
  function getResponsiveModifiers() {
839
846
  if (!_responsiveNames) {
840
847
  _responsiveNames = new Set(_allEntries().filter(([, d]) => d.jsBehavior === "responsive").map(([k]) => k));
@@ -887,7 +894,12 @@ function resolveColor(value, colors, isArbitrary) {
887
894
  }
888
895
  }
889
896
  if (!hex) return null;
890
- if (!opacityPart) return hex;
897
+ if (!opacityPart) {
898
+ if (!isWeb && hex.startsWith("#") && hex.length === 9) {
899
+ return hexToRgba(hex, Math.round(parseInt(hex.slice(7, 9), 16) / 255 * 1e3) / 1e3);
900
+ }
901
+ return hex;
902
+ }
891
903
  let alpha;
892
904
  if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
893
905
  const v = parseFloat(opacityPart.slice(1, -1));
@@ -2450,12 +2462,6 @@ var RESOLVERS = {
2450
2462
  function resolveUtility(parsed, theme) {
2451
2463
  if (!parsed.value) {
2452
2464
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
2453
- if (parsed.utility === "grd" || parsed.utility === "grid") {
2454
- return getEffectiveIsWeb() ? { display: "grid" } : null;
2455
- }
2456
- if (parsed.utility === "inline-grid") {
2457
- return getEffectiveIsWeb() ? { display: "inline-grid" } : null;
2458
- }
2459
2465
  if (parsed.utility in getStandalone()) return getStandalone()[parsed.utility] ?? null;
2460
2466
  }
2461
2467
  const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
@@ -3062,6 +3068,8 @@ function buildConfig(userConfig) {
3062
3068
  };
3063
3069
  clearPluginUtilities();
3064
3070
  clearPluginModifiers();
3071
+ const _store = getConfigStore();
3072
+ for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
3065
3073
  const pluginAPI = makePluginAPI(resolved.theme);
3066
3074
  for (const plugin of resolved.plugins) {
3067
3075
  plugin(pluginAPI);
@@ -3217,16 +3225,23 @@ function ThemeProvider({
3217
3225
  () => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
3218
3226
  );
3219
3227
  const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
3220
- const numericScreens = {};
3221
- for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
3222
- numericScreens[k] = typeof v === "number" ? v : parseInt(String(v), 10);
3223
- }
3228
+ const numericScreens = (0, import_react3.useMemo)(() => {
3229
+ const out = {};
3230
+ for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
3231
+ out[k] = typeof v === "number" ? v : parseInt(String(v), 10);
3232
+ }
3233
+ return out;
3234
+ }, [resolvedConfig.theme.screens]);
3224
3235
  const _prevWidthRef = (0, import_react3.useRef)(-1);
3225
3236
  if (_prevWidthRef.current !== effectiveWidth) {
3226
3237
  _prevWidthRef.current = effectiveWidth;
3227
3238
  syncGlobalWidth(effectiveWidth);
3228
3239
  }
3229
- syncGlobalScreens(numericScreens);
3240
+ const _prevScreensRef = (0, import_react3.useRef)(null);
3241
+ if (_prevScreensRef.current !== numericScreens) {
3242
+ _prevScreensRef.current = numericScreens;
3243
+ syncGlobalScreens(numericScreens);
3244
+ }
3230
3245
  (0, import_react3.useEffect)(() => {
3231
3246
  setGlobalWidth(effectiveWidth);
3232
3247
  }, [effectiveWidth]);
@@ -3511,6 +3526,101 @@ function hasResponsiveBuckets(resolved) {
3511
3526
  }
3512
3527
  return false;
3513
3528
  }
3529
+ function hasInteractiveBuckets(resolved) {
3530
+ const interactiveMods = getInteractiveModifiers();
3531
+ for (const key of Object.keys(resolved)) {
3532
+ if (key === "base") continue;
3533
+ for (const mod of key.split(":")) {
3534
+ if (interactiveMods.has(mod)) return true;
3535
+ }
3536
+ }
3537
+ return false;
3538
+ }
3539
+
3540
+ // src/web-substitute.ts
3541
+ var _rnToHtml = {
3542
+ View: "div",
3543
+ SafeAreaView: "div",
3544
+ KeyboardAvoidingView: "div",
3545
+ ScrollView: "div",
3546
+ VirtualizedList: "div",
3547
+ Text: "span",
3548
+ Pressable: "div",
3549
+ TouchableOpacity: "div",
3550
+ TouchableHighlight: "div",
3551
+ TouchableWithoutFeedback: "div",
3552
+ TouchableNativeFeedback: "div"
3553
+ };
3554
+ var _userMap = /* @__PURE__ */ new Map();
3555
+ var _cache = /* @__PURE__ */ new WeakMap();
3556
+ function registerWebElement(rnComponent, htmlTag) {
3557
+ if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
3558
+ _userMap.set(rnComponent, htmlTag);
3559
+ _cache.delete(rnComponent);
3560
+ }
3561
+ function getWebTag(type) {
3562
+ if (typeof type === "string") return null;
3563
+ if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3564
+ const obj = type;
3565
+ if (_userMap.has(obj)) return _userMap.get(obj);
3566
+ if (_cache.has(obj)) return _cache.get(obj);
3567
+ const name = obj.displayName ?? obj.name;
3568
+ const tag = name ? _rnToHtml[name] ?? null : null;
3569
+ _cache.set(obj, tag);
3570
+ return tag;
3571
+ }
3572
+ var _rnOnlyProps = /* @__PURE__ */ new Set([
3573
+ "onLongPress",
3574
+ "delayLongPress",
3575
+ "activeOpacity",
3576
+ "underlayColor",
3577
+ "hitSlop",
3578
+ "pressRetentionOffset",
3579
+ "accessible",
3580
+ "accessibilityState",
3581
+ "accessibilityLiveRegion",
3582
+ "importantForAccessibility",
3583
+ "nativeID",
3584
+ "collapsable",
3585
+ "needsOffscreenAlphaCompositing",
3586
+ "renderToHardwareTextureAndroid",
3587
+ "shouldRasterizeIOS",
3588
+ "pointerEvents"
3589
+ // RN and HTML values differ
3590
+ ]);
3591
+ var _pressableNames = /* @__PURE__ */ new Set([
3592
+ "Pressable",
3593
+ "TouchableOpacity",
3594
+ "TouchableHighlight",
3595
+ "TouchableWithoutFeedback",
3596
+ "TouchableNativeFeedback"
3597
+ ]);
3598
+ function transformToWebProps(originalName, props) {
3599
+ const out = {};
3600
+ const isPressable = _pressableNames.has(originalName);
3601
+ for (const [k, v] of Object.entries(props)) {
3602
+ if (_rnOnlyProps.has(k)) continue;
3603
+ if (k === "onPress") {
3604
+ if (!("onClick" in props)) out.onClick = v;
3605
+ continue;
3606
+ }
3607
+ if (k === "accessibilityLabel") {
3608
+ if (out["aria-label"] == null) out["aria-label"] = v;
3609
+ continue;
3610
+ }
3611
+ if (k === "accessibilityRole") {
3612
+ if (out.role == null) out.role = v;
3613
+ continue;
3614
+ }
3615
+ if (k === "testID") {
3616
+ if (out["data-testid"] == null) out["data-testid"] = v;
3617
+ continue;
3618
+ }
3619
+ out[k] = v;
3620
+ }
3621
+ if (isPressable && !out.role) out.role = "button";
3622
+ return out;
3623
+ }
3514
3624
 
3515
3625
  // src/styled.tsx
3516
3626
  function styled(Component, baseClasses = "") {
@@ -3530,6 +3640,8 @@ function styled(Component, baseClasses = "") {
3530
3640
  onBlur,
3531
3641
  ...rest
3532
3642
  } = props;
3643
+ const disabled = !!props.disabled;
3644
+ const checked = !!props.checked;
3533
3645
  const { isDark, config } = useTheme();
3534
3646
  const [pressed, setPressed] = (0, import_react6.useState)(false);
3535
3647
  const [hovered, setHovered] = (0, import_react6.useState)(false);
@@ -3572,28 +3684,34 @@ function styled(Component, baseClasses = "") {
3572
3684
  }, [onBlur]);
3573
3685
  const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
3574
3686
  const resolved = (0, import_react6.useMemo)(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
3687
+ const hasInteractive = (0, import_react6.useMemo)(() => hasInteractiveBuckets(resolved), [resolved]);
3575
3688
  const needsWidth = hasResponsiveBuckets(resolved);
3576
3689
  const width = useConditionalWidth(needsWidth);
3577
3690
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3578
3691
  const computedStyle = (0, import_react6.useMemo)(
3579
- () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused }, breakpoints),
3580
- [resolved, isDark, pressed, hovered, focused, width]
3692
+ () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
3693
+ [resolved, isDark, pressed, hovered, focused, disabled, checked, width]
3581
3694
  // eslint-disable-line react-hooks/exhaustive-deps
3582
3695
  );
3583
3696
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
3584
- const finalStyle = extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
3585
- return import_react6.default.createElement(Component, {
3697
+ const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
3698
+ const webTag = isWeb ? getWebTag(Component) : null;
3699
+ const effectiveComponent = webTag ?? Component;
3700
+ const componentName2 = Component.displayName ?? Component.name ?? "";
3701
+ const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, rest) : rest;
3702
+ return import_react6.default.createElement(effectiveComponent, {
3586
3703
  ref,
3587
- ...rest,
3704
+ ...effectiveRest,
3588
3705
  style: finalStyle,
3589
3706
  // className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
3590
3707
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
3591
- // onPressIn / onPressOut are React Native-only; on web use Pointer Events instead.
3592
- ...isWeb ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3593
- onMouseEnter: handleMouseEnter,
3594
- onMouseLeave: handleMouseLeave,
3595
- onFocus: handleFocus,
3596
- onBlur: handleBlur
3708
+ // Only attach state-tracking handlers when interactive modifiers are present.
3709
+ // Always forward user-provided handlers to avoid silently swallowing them.
3710
+ ...isWeb ? hasInteractive ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave } : { onPointerDown, onPointerUp, onPointerLeave } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
3711
+ onMouseEnter: hasInteractive ? handleMouseEnter : onMouseEnter,
3712
+ onMouseLeave: hasInteractive ? handleMouseLeave : onMouseLeave,
3713
+ onFocus: hasInteractive ? handleFocus : onFocus,
3714
+ onBlur: hasInteractive ? handleBlur : onBlur
3597
3715
  });
3598
3716
  }
3599
3717
  );
@@ -3710,7 +3828,7 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
3710
3828
  const handleBlur = (0, import_react10.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3711
3829
  const computedStyle = (0, import_react10.useMemo)(
3712
3830
  () => {
3713
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints);
3831
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3714
3832
  delete s.__divideX;
3715
3833
  delete s.__divideY;
3716
3834
  delete s.__divideColor;
@@ -3744,8 +3862,8 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
3744
3862
  [resolvedStyle, isDark, pressed, hovered, focused, width]
3745
3863
  // eslint-disable-line react-hooks/exhaustive-deps
3746
3864
  );
3747
- const isWebHTMLElement = !isNative && typeof Component === "string";
3748
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3865
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3866
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3749
3867
  const { children, ...restWithoutChildren } = rest;
3750
3868
  const componentProps = {
3751
3869
  ref,
@@ -3795,6 +3913,7 @@ function cx(...classes) {
3795
3913
  normalizeClassString,
3796
3914
  parseClass,
3797
3915
  parseClasses,
3916
+ registerWebElement,
3798
3917
  resolve,
3799
3918
  splitClassTokens,
3800
3919
  styled,