@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.
package/dist/index.mjs CHANGED
@@ -1,13 +1,17 @@
1
1
  import {
2
2
  EMPTY_BREAKPOINTS,
3
3
  InteractiveWrapper,
4
+ getWebTag,
5
+ hasInteractiveBuckets,
4
6
  hasResponsiveBuckets,
7
+ registerWebElement,
5
8
  setGlobalDarkMode,
6
9
  syncGlobalDarkMode,
10
+ transformToWebProps,
7
11
  useConditionalWidth,
8
12
  useGlobalDarkMode,
9
13
  useGlobalWidth
10
- } from "./chunk-U3GY5Y6J.mjs";
14
+ } from "./chunk-3UUTNNWV.mjs";
11
15
  import {
12
16
  __require,
13
17
  buildConfig,
@@ -29,7 +33,7 @@ import {
29
33
  syncGlobalScreens,
30
34
  syncGlobalWidth,
31
35
  updateConfig
32
- } from "./chunk-NIBECTRQ.mjs";
36
+ } from "./chunk-BKSXIWL7.mjs";
33
37
 
34
38
  // src/context.tsx
35
39
  import { createContext, useContext } from "react";
@@ -166,16 +170,23 @@ function ThemeProvider({
166
170
  () => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
167
171
  );
168
172
  const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
169
- const numericScreens = {};
170
- for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
171
- numericScreens[k] = typeof v === "number" ? v : parseInt(String(v), 10);
172
- }
173
+ const numericScreens = useMemo2(() => {
174
+ const out = {};
175
+ for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
176
+ out[k] = typeof v === "number" ? v : parseInt(String(v), 10);
177
+ }
178
+ return out;
179
+ }, [resolvedConfig.theme.screens]);
173
180
  const _prevWidthRef = useRef(-1);
174
181
  if (_prevWidthRef.current !== effectiveWidth) {
175
182
  _prevWidthRef.current = effectiveWidth;
176
183
  syncGlobalWidth(effectiveWidth);
177
184
  }
178
- syncGlobalScreens(numericScreens);
185
+ const _prevScreensRef = useRef(null);
186
+ if (_prevScreensRef.current !== numericScreens) {
187
+ _prevScreensRef.current = numericScreens;
188
+ syncGlobalScreens(numericScreens);
189
+ }
179
190
  useEffect(() => {
180
191
  setGlobalWidth(effectiveWidth);
181
192
  }, [effectiveWidth]);
@@ -416,6 +427,8 @@ function styled(Component, baseClasses = "") {
416
427
  onBlur,
417
428
  ...rest
418
429
  } = props;
430
+ const disabled = !!props.disabled;
431
+ const checked = !!props.checked;
419
432
  const { isDark, config } = useTheme();
420
433
  const [pressed, setPressed] = useState2(false);
421
434
  const [hovered, setHovered] = useState2(false);
@@ -458,28 +471,34 @@ function styled(Component, baseClasses = "") {
458
471
  }, [onBlur]);
459
472
  const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
460
473
  const resolved = useMemo3(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
474
+ const hasInteractive = useMemo3(() => hasInteractiveBuckets(resolved), [resolved]);
461
475
  const needsWidth = hasResponsiveBuckets(resolved);
462
476
  const width = useConditionalWidth(needsWidth);
463
477
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
464
478
  const computedStyle = useMemo3(
465
- () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused }, breakpoints),
466
- [resolved, isDark, pressed, hovered, focused, width]
479
+ () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
480
+ [resolved, isDark, pressed, hovered, focused, disabled, checked, width]
467
481
  // eslint-disable-line react-hooks/exhaustive-deps
468
482
  );
469
483
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
470
- const finalStyle = extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
471
- return React3.createElement(Component, {
484
+ const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
485
+ const webTag = isWeb ? getWebTag(Component) : null;
486
+ const effectiveComponent = webTag ?? Component;
487
+ const componentName2 = Component.displayName ?? Component.name ?? "";
488
+ const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, rest) : rest;
489
+ return React3.createElement(effectiveComponent, {
472
490
  ref,
473
- ...rest,
491
+ ...effectiveRest,
474
492
  style: finalStyle,
475
493
  // className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
476
494
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
477
- // onPressIn / onPressOut are React Native-only; on web use Pointer Events instead.
478
- ...isWeb ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
479
- onMouseEnter: handleMouseEnter,
480
- onMouseLeave: handleMouseLeave,
481
- onFocus: handleFocus,
482
- onBlur: handleBlur
495
+ // Only attach state-tracking handlers when interactive modifiers are present.
496
+ // Always forward user-provided handlers to avoid silently swallowing them.
497
+ ...isWeb ? hasInteractive ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave } : { onPointerDown, onPointerUp, onPointerLeave } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
498
+ onMouseEnter: hasInteractive ? handleMouseEnter : onMouseEnter,
499
+ onMouseLeave: hasInteractive ? handleMouseLeave : onMouseLeave,
500
+ onFocus: hasInteractive ? handleFocus : onFocus,
501
+ onBlur: hasInteractive ? handleBlur : onBlur
483
502
  });
484
503
  }
485
504
  );
@@ -566,6 +585,7 @@ export {
566
585
  normalizeClassString,
567
586
  parseClass,
568
587
  parseClasses,
588
+ registerWebElement,
569
589
  resolve,
570
590
  splitClassTokens,
571
591
  styled,
@@ -787,7 +787,12 @@ function resolveColor(value, colors, isArbitrary) {
787
787
  }
788
788
  }
789
789
  if (!hex) return null;
790
- if (!opacityPart) return hex;
790
+ if (!opacityPart) {
791
+ if (!isWeb && hex.startsWith("#") && hex.length === 9) {
792
+ return hexToRgba(hex, Math.round(parseInt(hex.slice(7, 9), 16) / 255 * 1e3) / 1e3);
793
+ }
794
+ return hex;
795
+ }
791
796
  let alpha;
792
797
  if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
793
798
  const v = parseFloat(opacityPart.slice(1, -1));
@@ -2350,12 +2355,6 @@ var RESOLVERS = {
2350
2355
  function resolveUtility(parsed, theme) {
2351
2356
  if (!parsed.value) {
2352
2357
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
2353
- if (parsed.utility === "grd" || parsed.utility === "grid") {
2354
- return getEffectiveIsWeb() ? { display: "grid" } : null;
2355
- }
2356
- if (parsed.utility === "inline-grid") {
2357
- return getEffectiveIsWeb() ? { display: "inline-grid" } : null;
2358
- }
2359
2358
  if (parsed.utility in getStandalone()) return getStandalone()[parsed.utility] ?? null;
2360
2359
  }
2361
2360
  const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
@@ -2940,6 +2939,8 @@ function buildConfig(userConfig) {
2940
2939
  };
2941
2940
  clearPluginUtilities();
2942
2941
  clearPluginModifiers();
2942
+ const _store = getConfigStore();
2943
+ for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
2943
2944
  const pluginAPI = makePluginAPI(resolved.theme);
2944
2945
  for (const plugin of resolved.plugins) {
2945
2946
  plugin(pluginAPI);
@@ -3146,7 +3147,7 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3146
3147
  const handleBlur = (0, import_react3.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3147
3148
  const computedStyle = (0, import_react3.useMemo)(
3148
3149
  () => {
3149
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints);
3150
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3150
3151
  delete s.__divideX;
3151
3152
  delete s.__divideY;
3152
3153
  delete s.__divideColor;
@@ -3180,8 +3181,8 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3180
3181
  [resolvedStyle, isDark, pressed, hovered, focused, width]
3181
3182
  // eslint-disable-line react-hooks/exhaustive-deps
3182
3183
  );
3183
- const isWebHTMLElement = !isNative && typeof Component === "string";
3184
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3184
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3185
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3185
3186
  const { children, ...restWithoutChildren } = rest;
3186
3187
  const componentProps = {
3187
3188
  ref,
@@ -3209,11 +3210,15 @@ var DarkWrapper = import_react4.default.forwardRef(
3209
3210
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
3210
3211
  const width = useConditionalWidth(needsWidth);
3211
3212
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS2;
3212
- const computedStyle = flatten(resolvedStyle, isDark, {}, breakpoints);
3213
- stripInternalMarkers(computedStyle);
3214
- if (typeof Component !== "string") stripWebOnlyProps(computedStyle);
3215
- const isWebHTMLElement = !isNative && typeof Component === "string";
3216
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3213
+ const isNonStringComponent = typeof Component !== "string";
3214
+ const computedStyle = (0, import_react4.useMemo)(() => {
3215
+ const s = flatten(resolvedStyle, isDark, {}, breakpoints);
3216
+ stripInternalMarkers(s);
3217
+ if (isNonStringComponent) stripWebOnlyProps(s);
3218
+ return s;
3219
+ }, [resolvedStyle, isDark, width, isNonStringComponent]);
3220
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3221
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3217
3222
  const props = { ref, ...rest, style: finalStyle };
3218
3223
  return Array.isArray(children) ? import_react4.default.createElement(Component, props, ...children) : import_react4.default.createElement(Component, props, children);
3219
3224
  }
@@ -3250,6 +3255,86 @@ function stripWebOnlyProps(s) {
3250
3255
  }
3251
3256
  }
3252
3257
 
3258
+ // src/web-substitute.ts
3259
+ var _rnToHtml = {
3260
+ View: "div",
3261
+ SafeAreaView: "div",
3262
+ KeyboardAvoidingView: "div",
3263
+ ScrollView: "div",
3264
+ VirtualizedList: "div",
3265
+ Text: "span",
3266
+ Pressable: "div",
3267
+ TouchableOpacity: "div",
3268
+ TouchableHighlight: "div",
3269
+ TouchableWithoutFeedback: "div",
3270
+ TouchableNativeFeedback: "div"
3271
+ };
3272
+ var _userMap = /* @__PURE__ */ new Map();
3273
+ var _cache = /* @__PURE__ */ new WeakMap();
3274
+ function getWebTag(type) {
3275
+ if (typeof type === "string") return null;
3276
+ if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3277
+ const obj = type;
3278
+ if (_userMap.has(obj)) return _userMap.get(obj);
3279
+ if (_cache.has(obj)) return _cache.get(obj);
3280
+ const name = obj.displayName ?? obj.name;
3281
+ const tag = name ? _rnToHtml[name] ?? null : null;
3282
+ _cache.set(obj, tag);
3283
+ return tag;
3284
+ }
3285
+ var _rnOnlyProps = /* @__PURE__ */ new Set([
3286
+ "onLongPress",
3287
+ "delayLongPress",
3288
+ "activeOpacity",
3289
+ "underlayColor",
3290
+ "hitSlop",
3291
+ "pressRetentionOffset",
3292
+ "accessible",
3293
+ "accessibilityState",
3294
+ "accessibilityLiveRegion",
3295
+ "importantForAccessibility",
3296
+ "nativeID",
3297
+ "collapsable",
3298
+ "needsOffscreenAlphaCompositing",
3299
+ "renderToHardwareTextureAndroid",
3300
+ "shouldRasterizeIOS",
3301
+ "pointerEvents"
3302
+ // RN and HTML values differ
3303
+ ]);
3304
+ var _pressableNames = /* @__PURE__ */ new Set([
3305
+ "Pressable",
3306
+ "TouchableOpacity",
3307
+ "TouchableHighlight",
3308
+ "TouchableWithoutFeedback",
3309
+ "TouchableNativeFeedback"
3310
+ ]);
3311
+ function transformToWebProps(originalName, props) {
3312
+ const out = {};
3313
+ const isPressable = _pressableNames.has(originalName);
3314
+ for (const [k, v] of Object.entries(props)) {
3315
+ if (_rnOnlyProps.has(k)) continue;
3316
+ if (k === "onPress") {
3317
+ if (!("onClick" in props)) out.onClick = v;
3318
+ continue;
3319
+ }
3320
+ if (k === "accessibilityLabel") {
3321
+ if (out["aria-label"] == null) out["aria-label"] = v;
3322
+ continue;
3323
+ }
3324
+ if (k === "accessibilityRole") {
3325
+ if (out.role == null) out.role = v;
3326
+ continue;
3327
+ }
3328
+ if (k === "testID") {
3329
+ if (out["data-testid"] == null) out["data-testid"] = v;
3330
+ continue;
3331
+ }
3332
+ out[k] = v;
3333
+ }
3334
+ if (isPressable && !out.role) out.role = "button";
3335
+ return out;
3336
+ }
3337
+
3253
3338
  // src/jsx-runtime.tsx
3254
3339
  var _cachedDefaultFont = void 0;
3255
3340
  var _defaultFontVersion = 0;
@@ -3330,31 +3415,36 @@ function stripWebOnlyInlineProps(s) {
3330
3415
  }
3331
3416
  function processElement(type, rawProps, key, isStaticChildren) {
3332
3417
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3333
- if (!rawProps) return (0, import_jsx_runtime.jsx)(type, null, key);
3334
- const { className, kb: kbProp, __kbachStyles, __kbachClasses } = rawProps;
3418
+ const webTag = isWeb ? getWebTag(type) : null;
3419
+ const effectiveType = webTag ?? type;
3420
+ const originalName = webTag ? type?.displayName ?? type?.name : void 0;
3421
+ if (!rawProps) return (0, import_jsx_runtime.jsx)(effectiveType, null, key);
3422
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
3423
+ const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
3335
3424
  const classStr = className ?? kbProp ?? __kbachClasses;
3336
3425
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
3337
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
3338
- return makeElement(isStaticChildren, type, {
3426
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
3427
+ return makeElement(isStaticChildren, effectiveType, {
3339
3428
  ...passProps2,
3340
3429
  className: normalizeClassString(classStr),
3341
3430
  ...userStyle2 !== void 0 ? { style: userStyle2 } : {}
3342
3431
  }, key);
3343
3432
  }
3344
3433
  if (!classStr && !__kbachStyles) {
3434
+ if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
3345
3435
  const defaultFont = getCachedDefaultFont();
3346
- if (!defaultFont) return makeElement(isStaticChildren, type, rawProps, key);
3347
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
3436
+ if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
3437
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
3348
3438
  const finalStyle2 = userStyle2 ? Array.isArray(userStyle2) ? { fontFamily: defaultFont, ...Object.assign({}, ...userStyle2) } : { fontFamily: defaultFont, ...userStyle2 } : { fontFamily: defaultFont };
3349
- return makeElement(isStaticChildren, type, { ...passProps2, style: finalStyle2 }, key);
3439
+ return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
3350
3440
  }
3351
3441
  const config = getConfig();
3352
3442
  const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
3353
- const { style: userStyle, ...passProps } = omitConsumed(rawProps);
3443
+ const { style: userStyle, ...passProps } = omitConsumed(workingProps);
3354
3444
  const { interactive, modeOrResponsive } = bucketMods(resolved);
3355
3445
  if (interactive) {
3356
3446
  return (0, import_jsx_runtime.jsx)(InteractiveWrapper, {
3357
- Component: type,
3447
+ Component: effectiveType,
3358
3448
  resolvedStyle: resolved,
3359
3449
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
3360
3450
  style: userStyle,
@@ -3363,24 +3453,24 @@ function processElement(type, rawProps, key, isStaticChildren) {
3363
3453
  }
3364
3454
  if (modeOrResponsive) {
3365
3455
  return (0, import_jsx_runtime.jsx)(DarkWrapper, {
3366
- Component: type,
3456
+ Component: effectiveType,
3367
3457
  resolvedStyle: resolved,
3368
3458
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
3369
3459
  style: userStyle,
3370
3460
  ...passProps
3371
3461
  }, key);
3372
3462
  }
3373
- const isWebHTMLElement = !isNative && typeof type === "string";
3463
+ const skipComputedInline = isWeb || !isNative && typeof effectiveType === "string";
3374
3464
  let finalStyle;
3375
- if (!isWebHTMLElement) {
3465
+ if (!skipComputedInline) {
3376
3466
  const computedStyle = flatten(resolved, false);
3377
3467
  stripInternalMarkers2(computedStyle);
3378
- if (typeof type !== "string") stripWebOnlyInlineProps(computedStyle);
3468
+ if (typeof effectiveType !== "string") stripWebOnlyInlineProps(computedStyle);
3379
3469
  finalStyle = mergeStyle(computedStyle, userStyle);
3380
3470
  } else {
3381
3471
  finalStyle = userStyle ?? void 0;
3382
3472
  }
3383
- return makeElement(isStaticChildren, type, {
3473
+ return makeElement(isStaticChildren, effectiveType, {
3384
3474
  ...passProps,
3385
3475
  style: finalStyle,
3386
3476
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {}
@@ -2,9 +2,9 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-LCK5OGHT.mjs";
6
- import "./chunk-U3GY5Y6J.mjs";
7
- import "./chunk-NIBECTRQ.mjs";
5
+ } from "./chunk-KWB2XQSF.mjs";
6
+ import "./chunk-3UUTNNWV.mjs";
7
+ import "./chunk-BKSXIWL7.mjs";
8
8
 
9
9
  // src/jsx-dev-runtime.tsx
10
10
  function jsxDEV(type, props, key, isStaticChildren, source, self) {
@@ -1,5 +1,6 @@
1
1
  import { ReactElement } from 'react';
2
2
  export { Fragment, JSX } from 'react';
3
+ export { r as registerWebElement } from './web-substitute-CfpYFnE7.mjs';
3
4
 
4
5
  /**
5
6
  * @kbach/react/jsx-runtime
@@ -1,5 +1,6 @@
1
1
  import { ReactElement } from 'react';
2
2
  export { Fragment, JSX } from 'react';
3
+ export { r as registerWebElement } from './web-substitute-CfpYFnE7.js';
3
4
 
4
5
  /**
5
6
  * @kbach/react/jsx-runtime
@@ -33,7 +33,8 @@ __export(jsx_runtime_exports, {
33
33
  Fragment: () => import_react5.Fragment,
34
34
  _invalidateDefaultFontCache: () => _invalidateDefaultFontCache,
35
35
  jsx: () => jsx,
36
- jsxs: () => jsxs
36
+ jsxs: () => jsxs,
37
+ registerWebElement: () => registerWebElement
37
38
  });
38
39
  module.exports = __toCommonJS(jsx_runtime_exports);
39
40
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -787,7 +788,12 @@ function resolveColor(value, colors, isArbitrary) {
787
788
  }
788
789
  }
789
790
  if (!hex) return null;
790
- if (!opacityPart) return hex;
791
+ if (!opacityPart) {
792
+ if (!isWeb && hex.startsWith("#") && hex.length === 9) {
793
+ return hexToRgba(hex, Math.round(parseInt(hex.slice(7, 9), 16) / 255 * 1e3) / 1e3);
794
+ }
795
+ return hex;
796
+ }
791
797
  let alpha;
792
798
  if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
793
799
  const v = parseFloat(opacityPart.slice(1, -1));
@@ -2350,12 +2356,6 @@ var RESOLVERS = {
2350
2356
  function resolveUtility(parsed, theme) {
2351
2357
  if (!parsed.value) {
2352
2358
  if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
2353
- if (parsed.utility === "grd" || parsed.utility === "grid") {
2354
- return getEffectiveIsWeb() ? { display: "grid" } : null;
2355
- }
2356
- if (parsed.utility === "inline-grid") {
2357
- return getEffectiveIsWeb() ? { display: "inline-grid" } : null;
2358
- }
2359
2359
  if (parsed.utility in getStandalone()) return getStandalone()[parsed.utility] ?? null;
2360
2360
  }
2361
2361
  const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
@@ -2940,6 +2940,8 @@ function buildConfig(userConfig) {
2940
2940
  };
2941
2941
  clearPluginUtilities();
2942
2942
  clearPluginModifiers();
2943
+ const _store = getConfigStore();
2944
+ for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
2943
2945
  const pluginAPI = makePluginAPI(resolved.theme);
2944
2946
  for (const plugin of resolved.plugins) {
2945
2947
  plugin(pluginAPI);
@@ -3146,7 +3148,7 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3146
3148
  const handleBlur = (0, import_react3.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3147
3149
  const computedStyle = (0, import_react3.useMemo)(
3148
3150
  () => {
3149
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints);
3151
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3150
3152
  delete s.__divideX;
3151
3153
  delete s.__divideY;
3152
3154
  delete s.__divideColor;
@@ -3180,8 +3182,8 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3180
3182
  [resolvedStyle, isDark, pressed, hovered, focused, width]
3181
3183
  // eslint-disable-line react-hooks/exhaustive-deps
3182
3184
  );
3183
- const isWebHTMLElement = !isNative && typeof Component === "string";
3184
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3185
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3186
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3185
3187
  const { children, ...restWithoutChildren } = rest;
3186
3188
  const componentProps = {
3187
3189
  ref,
@@ -3209,11 +3211,15 @@ var DarkWrapper = import_react4.default.forwardRef(
3209
3211
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
3210
3212
  const width = useConditionalWidth(needsWidth);
3211
3213
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS2;
3212
- const computedStyle = flatten(resolvedStyle, isDark, {}, breakpoints);
3213
- stripInternalMarkers(computedStyle);
3214
- if (typeof Component !== "string") stripWebOnlyProps(computedStyle);
3215
- const isWebHTMLElement = !isNative && typeof Component === "string";
3216
- const finalStyle = isWebHTMLElement ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3214
+ const isNonStringComponent = typeof Component !== "string";
3215
+ const computedStyle = (0, import_react4.useMemo)(() => {
3216
+ const s = flatten(resolvedStyle, isDark, {}, breakpoints);
3217
+ stripInternalMarkers(s);
3218
+ if (isNonStringComponent) stripWebOnlyProps(s);
3219
+ return s;
3220
+ }, [resolvedStyle, isDark, width, isNonStringComponent]);
3221
+ const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3222
+ const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3217
3223
  const props = { ref, ...rest, style: finalStyle };
3218
3224
  return Array.isArray(children) ? import_react4.default.createElement(Component, props, ...children) : import_react4.default.createElement(Component, props, children);
3219
3225
  }
@@ -3250,6 +3256,91 @@ function stripWebOnlyProps(s) {
3250
3256
  }
3251
3257
  }
3252
3258
 
3259
+ // src/web-substitute.ts
3260
+ var _rnToHtml = {
3261
+ View: "div",
3262
+ SafeAreaView: "div",
3263
+ KeyboardAvoidingView: "div",
3264
+ ScrollView: "div",
3265
+ VirtualizedList: "div",
3266
+ Text: "span",
3267
+ Pressable: "div",
3268
+ TouchableOpacity: "div",
3269
+ TouchableHighlight: "div",
3270
+ TouchableWithoutFeedback: "div",
3271
+ TouchableNativeFeedback: "div"
3272
+ };
3273
+ var _userMap = /* @__PURE__ */ new Map();
3274
+ var _cache = /* @__PURE__ */ new WeakMap();
3275
+ function registerWebElement(rnComponent, htmlTag) {
3276
+ if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
3277
+ _userMap.set(rnComponent, htmlTag);
3278
+ _cache.delete(rnComponent);
3279
+ }
3280
+ function getWebTag(type) {
3281
+ if (typeof type === "string") return null;
3282
+ if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3283
+ const obj = type;
3284
+ if (_userMap.has(obj)) return _userMap.get(obj);
3285
+ if (_cache.has(obj)) return _cache.get(obj);
3286
+ const name = obj.displayName ?? obj.name;
3287
+ const tag = name ? _rnToHtml[name] ?? null : null;
3288
+ _cache.set(obj, tag);
3289
+ return tag;
3290
+ }
3291
+ var _rnOnlyProps = /* @__PURE__ */ new Set([
3292
+ "onLongPress",
3293
+ "delayLongPress",
3294
+ "activeOpacity",
3295
+ "underlayColor",
3296
+ "hitSlop",
3297
+ "pressRetentionOffset",
3298
+ "accessible",
3299
+ "accessibilityState",
3300
+ "accessibilityLiveRegion",
3301
+ "importantForAccessibility",
3302
+ "nativeID",
3303
+ "collapsable",
3304
+ "needsOffscreenAlphaCompositing",
3305
+ "renderToHardwareTextureAndroid",
3306
+ "shouldRasterizeIOS",
3307
+ "pointerEvents"
3308
+ // RN and HTML values differ
3309
+ ]);
3310
+ var _pressableNames = /* @__PURE__ */ new Set([
3311
+ "Pressable",
3312
+ "TouchableOpacity",
3313
+ "TouchableHighlight",
3314
+ "TouchableWithoutFeedback",
3315
+ "TouchableNativeFeedback"
3316
+ ]);
3317
+ function transformToWebProps(originalName, props) {
3318
+ const out = {};
3319
+ const isPressable = _pressableNames.has(originalName);
3320
+ for (const [k, v] of Object.entries(props)) {
3321
+ if (_rnOnlyProps.has(k)) continue;
3322
+ if (k === "onPress") {
3323
+ if (!("onClick" in props)) out.onClick = v;
3324
+ continue;
3325
+ }
3326
+ if (k === "accessibilityLabel") {
3327
+ if (out["aria-label"] == null) out["aria-label"] = v;
3328
+ continue;
3329
+ }
3330
+ if (k === "accessibilityRole") {
3331
+ if (out.role == null) out.role = v;
3332
+ continue;
3333
+ }
3334
+ if (k === "testID") {
3335
+ if (out["data-testid"] == null) out["data-testid"] = v;
3336
+ continue;
3337
+ }
3338
+ out[k] = v;
3339
+ }
3340
+ if (isPressable && !out.role) out.role = "button";
3341
+ return out;
3342
+ }
3343
+
3253
3344
  // src/jsx-runtime.tsx
3254
3345
  var _cachedDefaultFont = void 0;
3255
3346
  var _defaultFontVersion = 0;
@@ -3333,31 +3424,36 @@ function stripWebOnlyInlineProps(s) {
3333
3424
  }
3334
3425
  function processElement(type, rawProps, key, isStaticChildren) {
3335
3426
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3336
- if (!rawProps) return (0, import_jsx_runtime.jsx)(type, null, key);
3337
- const { className, kb: kbProp, __kbachStyles, __kbachClasses } = rawProps;
3427
+ const webTag = isWeb ? getWebTag(type) : null;
3428
+ const effectiveType = webTag ?? type;
3429
+ const originalName = webTag ? type?.displayName ?? type?.name : void 0;
3430
+ if (!rawProps) return (0, import_jsx_runtime.jsx)(effectiveType, null, key);
3431
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
3432
+ const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
3338
3433
  const classStr = className ?? kbProp ?? __kbachClasses;
3339
3434
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
3340
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
3341
- return makeElement(isStaticChildren, type, {
3435
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
3436
+ return makeElement(isStaticChildren, effectiveType, {
3342
3437
  ...passProps2,
3343
3438
  className: normalizeClassString(classStr),
3344
3439
  ...userStyle2 !== void 0 ? { style: userStyle2 } : {}
3345
3440
  }, key);
3346
3441
  }
3347
3442
  if (!classStr && !__kbachStyles) {
3443
+ if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
3348
3444
  const defaultFont = getCachedDefaultFont();
3349
- if (!defaultFont) return makeElement(isStaticChildren, type, rawProps, key);
3350
- const { style: userStyle2, ...passProps2 } = omitConsumed(rawProps);
3445
+ if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
3446
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
3351
3447
  const finalStyle2 = userStyle2 ? Array.isArray(userStyle2) ? { fontFamily: defaultFont, ...Object.assign({}, ...userStyle2) } : { fontFamily: defaultFont, ...userStyle2 } : { fontFamily: defaultFont };
3352
- return makeElement(isStaticChildren, type, { ...passProps2, style: finalStyle2 }, key);
3448
+ return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
3353
3449
  }
3354
3450
  const config = getConfig();
3355
3451
  const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
3356
- const { style: userStyle, ...passProps } = omitConsumed(rawProps);
3452
+ const { style: userStyle, ...passProps } = omitConsumed(workingProps);
3357
3453
  const { interactive, modeOrResponsive } = bucketMods(resolved);
3358
3454
  if (interactive) {
3359
3455
  return (0, import_jsx_runtime.jsx)(InteractiveWrapper, {
3360
- Component: type,
3456
+ Component: effectiveType,
3361
3457
  resolvedStyle: resolved,
3362
3458
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
3363
3459
  style: userStyle,
@@ -3366,24 +3462,24 @@ function processElement(type, rawProps, key, isStaticChildren) {
3366
3462
  }
3367
3463
  if (modeOrResponsive) {
3368
3464
  return (0, import_jsx_runtime.jsx)(DarkWrapper, {
3369
- Component: type,
3465
+ Component: effectiveType,
3370
3466
  resolvedStyle: resolved,
3371
3467
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {},
3372
3468
  style: userStyle,
3373
3469
  ...passProps
3374
3470
  }, key);
3375
3471
  }
3376
- const isWebHTMLElement = !isNative && typeof type === "string";
3472
+ const skipComputedInline = isWeb || !isNative && typeof effectiveType === "string";
3377
3473
  let finalStyle;
3378
- if (!isWebHTMLElement) {
3474
+ if (!skipComputedInline) {
3379
3475
  const computedStyle = flatten(resolved, false);
3380
3476
  stripInternalMarkers2(computedStyle);
3381
- if (typeof type !== "string") stripWebOnlyInlineProps(computedStyle);
3477
+ if (typeof effectiveType !== "string") stripWebOnlyInlineProps(computedStyle);
3382
3478
  finalStyle = mergeStyle(computedStyle, userStyle);
3383
3479
  } else {
3384
3480
  finalStyle = userStyle ?? void 0;
3385
3481
  }
3386
- return makeElement(isStaticChildren, type, {
3482
+ return makeElement(isStaticChildren, effectiveType, {
3387
3483
  ...passProps,
3388
3484
  style: finalStyle,
3389
3485
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {}
@@ -3400,5 +3496,6 @@ function jsxs(type, props, key) {
3400
3496
  Fragment,
3401
3497
  _invalidateDefaultFontCache,
3402
3498
  jsx,
3403
- jsxs
3499
+ jsxs,
3500
+ registerWebElement
3404
3501
  });
@@ -3,12 +3,15 @@ import {
3
3
  _invalidateDefaultFontCache,
4
4
  jsx,
5
5
  jsxs
6
- } from "./chunk-LCK5OGHT.mjs";
7
- import "./chunk-U3GY5Y6J.mjs";
8
- import "./chunk-NIBECTRQ.mjs";
6
+ } from "./chunk-KWB2XQSF.mjs";
7
+ import {
8
+ registerWebElement
9
+ } from "./chunk-3UUTNNWV.mjs";
10
+ import "./chunk-BKSXIWL7.mjs";
9
11
  export {
10
12
  Fragment,
11
13
  _invalidateDefaultFontCache,
12
14
  jsx,
13
- jsxs
15
+ jsxs,
16
+ registerWebElement
14
17
  };