@kbach/react 0.5.48 → 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.js CHANGED
@@ -3536,7 +3536,91 @@ function hasInteractiveBuckets(resolved) {
3536
3536
  }
3537
3537
  return false;
3538
3538
  }
3539
- var EMPTY_BREAKPOINTS2 = /* @__PURE__ */ new Set();
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
+ }
3540
3624
 
3541
3625
  // src/styled.tsx
3542
3626
  function styled(Component, baseClasses = "") {
@@ -3611,9 +3695,13 @@ function styled(Component, baseClasses = "") {
3611
3695
  );
3612
3696
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
3613
3697
  const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
3614
- return import_react6.default.createElement(Component, {
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, {
3615
3703
  ref,
3616
- ...rest,
3704
+ ...effectiveRest,
3617
3705
  style: finalStyle,
3618
3706
  // className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
3619
3707
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
@@ -3807,72 +3895,6 @@ function kb(classString, isDark = false) {
3807
3895
  function cx(...classes) {
3808
3896
  return classes.filter(Boolean).join(" ");
3809
3897
  }
3810
-
3811
- // src/jsx-runtime.tsx
3812
- var import_jsx_runtime2 = require("react/jsx-runtime");
3813
- var import_react12 = require("react");
3814
-
3815
- // src/DarkWrapper.tsx
3816
- var import_react11 = __toESM(require("react"));
3817
- var DarkWrapper = import_react11.default.forwardRef(
3818
- function DarkWrapper2({ Component, resolvedStyle, style: styleProp, children, ...rest }, ref) {
3819
- const isDark = useGlobalDarkMode();
3820
- const needsWidth = hasResponsiveBuckets(resolvedStyle);
3821
- const width = useConditionalWidth(needsWidth);
3822
- const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS2;
3823
- const isNonStringComponent = typeof Component !== "string";
3824
- const computedStyle = (0, import_react11.useMemo)(() => {
3825
- const s = flatten(resolvedStyle, isDark, {}, breakpoints);
3826
- stripInternalMarkers(s);
3827
- if (isNonStringComponent) stripWebOnlyProps(s);
3828
- return s;
3829
- }, [resolvedStyle, isDark, width, isNonStringComponent]);
3830
- const skipComputedInline = isWeb || !isNative && typeof Component === "string";
3831
- const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
3832
- const props = { ref, ...rest, style: finalStyle };
3833
- return Array.isArray(children) ? import_react11.default.createElement(Component, props, ...children) : import_react11.default.createElement(Component, props, children);
3834
- }
3835
- );
3836
- DarkWrapper.displayName = "Kbach.DarkWrapper";
3837
- function stripInternalMarkers(s) {
3838
- delete s.__divideX;
3839
- delete s.__divideY;
3840
- delete s.__divideColor;
3841
- delete s.__divideStyle;
3842
- delete s.__keyframe;
3843
- }
3844
- function stripWebOnlyProps(s) {
3845
- if (s.display === "grid" || s.display === "inline-grid") delete s.display;
3846
- delete s.gridTemplateColumns;
3847
- delete s.gridTemplateRows;
3848
- delete s.gridColumn;
3849
- delete s.gridRow;
3850
- delete s.gridArea;
3851
- delete s.gridColumnStart;
3852
- delete s.gridColumnEnd;
3853
- delete s.gridRowStart;
3854
- delete s.gridRowEnd;
3855
- delete s.gridAutoFlow;
3856
- delete s.gridAutoColumns;
3857
- delete s.gridAutoRows;
3858
- delete s.placeItems;
3859
- delete s.placeContent;
3860
- delete s.justifyItems;
3861
- delete s.placeSelf;
3862
- delete s.justifySelf;
3863
- if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
3864
- delete s.position;
3865
- }
3866
- }
3867
-
3868
- // src/jsx-runtime.tsx
3869
- var _userWebTypeMap = /* @__PURE__ */ new Map();
3870
- var _webTypeCache = /* @__PURE__ */ new WeakMap();
3871
- function registerWebElement(rnComponent, htmlTag) {
3872
- if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
3873
- _userWebTypeMap.set(rnComponent, htmlTag);
3874
- _webTypeCache.delete(rnComponent);
3875
- }
3876
3898
  // Annotate the CommonJS export names for ESM import in node:
3877
3899
  0 && (module.exports = {
3878
3900
  InteractiveWrapper,
package/dist/index.mjs CHANGED
@@ -1,15 +1,17 @@
1
1
  import {
2
2
  EMPTY_BREAKPOINTS,
3
3
  InteractiveWrapper,
4
+ getWebTag,
4
5
  hasInteractiveBuckets,
5
6
  hasResponsiveBuckets,
6
7
  registerWebElement,
7
8
  setGlobalDarkMode,
8
9
  syncGlobalDarkMode,
10
+ transformToWebProps,
9
11
  useConditionalWidth,
10
12
  useGlobalDarkMode,
11
13
  useGlobalWidth
12
- } from "./chunk-YZNSWFJT.mjs";
14
+ } from "./chunk-3UUTNNWV.mjs";
13
15
  import {
14
16
  __require,
15
17
  buildConfig,
@@ -480,9 +482,13 @@ function styled(Component, baseClasses = "") {
480
482
  );
481
483
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
482
484
  const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
483
- return React3.createElement(Component, {
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, {
484
490
  ref,
485
- ...rest,
491
+ ...effectiveRest,
486
492
  style: finalStyle,
487
493
  // className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
488
494
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
@@ -3255,6 +3255,86 @@ function stripWebOnlyProps(s) {
3255
3255
  }
3256
3256
  }
3257
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
+
3258
3338
  // src/jsx-runtime.tsx
3259
3339
  var _cachedDefaultFont = void 0;
3260
3340
  var _defaultFontVersion = 0;
@@ -3333,84 +3413,6 @@ function stripWebOnlyInlineProps(s) {
3333
3413
  delete s.position;
3334
3414
  }
3335
3415
  }
3336
- var _rnToHtml = {
3337
- View: "div",
3338
- SafeAreaView: "div",
3339
- KeyboardAvoidingView: "div",
3340
- ScrollView: "div",
3341
- VirtualizedList: "div",
3342
- Text: "span",
3343
- Pressable: "div",
3344
- TouchableOpacity: "div",
3345
- TouchableHighlight: "div",
3346
- TouchableWithoutFeedback: "div",
3347
- TouchableNativeFeedback: "div"
3348
- };
3349
- var _userWebTypeMap = /* @__PURE__ */ new Map();
3350
- var _webTypeCache = /* @__PURE__ */ new WeakMap();
3351
- function getWebTag(type) {
3352
- if (typeof type === "string") return null;
3353
- if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3354
- const obj = type;
3355
- if (_userWebTypeMap.has(obj)) return _userWebTypeMap.get(obj);
3356
- if (_webTypeCache.has(obj)) return _webTypeCache.get(obj);
3357
- const name = obj.displayName ?? obj.name;
3358
- const tag = name ? _rnToHtml[name] ?? null : null;
3359
- _webTypeCache.set(obj, tag);
3360
- return tag;
3361
- }
3362
- var _rnOnlyProps = /* @__PURE__ */ new Set([
3363
- "onLongPress",
3364
- "delayLongPress",
3365
- "activeOpacity",
3366
- "underlayColor",
3367
- "hitSlop",
3368
- "pressRetentionOffset",
3369
- "accessible",
3370
- "accessibilityState",
3371
- "accessibilityLiveRegion",
3372
- "importantForAccessibility",
3373
- "nativeID",
3374
- "collapsable",
3375
- "needsOffscreenAlphaCompositing",
3376
- "renderToHardwareTextureAndroid",
3377
- "shouldRasterizeIOS",
3378
- "pointerEvents"
3379
- // RN prop — values differ from HTML pointer-events CSS
3380
- ]);
3381
- var _pressableDisplayNames = /* @__PURE__ */ new Set([
3382
- "Pressable",
3383
- "TouchableOpacity",
3384
- "TouchableHighlight",
3385
- "TouchableWithoutFeedback",
3386
- "TouchableNativeFeedback"
3387
- ]);
3388
- function transformToWebProps(originalName, props) {
3389
- const out = {};
3390
- const isPressable = _pressableDisplayNames.has(originalName);
3391
- for (const [k, v] of Object.entries(props)) {
3392
- if (_rnOnlyProps.has(k)) continue;
3393
- if (k === "onPress") {
3394
- if (!("onClick" in props)) out.onClick = v;
3395
- continue;
3396
- }
3397
- if (k === "accessibilityLabel") {
3398
- if (out["aria-label"] == null) out["aria-label"] = v;
3399
- continue;
3400
- }
3401
- if (k === "accessibilityRole") {
3402
- if (out.role == null) out.role = v;
3403
- continue;
3404
- }
3405
- if (k === "testID") {
3406
- if (out["data-testid"] == null) out["data-testid"] = v;
3407
- continue;
3408
- }
3409
- out[k] = v;
3410
- }
3411
- if (isPressable && !out.role) out.role = "button";
3412
- return out;
3413
- }
3414
3416
  function processElement(type, rawProps, key, isStaticChildren) {
3415
3417
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3416
3418
  const webTag = isWeb ? getWebTag(type) : null;
@@ -3429,6 +3431,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
3429
3431
  }, key);
3430
3432
  }
3431
3433
  if (!classStr && !__kbachStyles) {
3434
+ if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
3432
3435
  const defaultFont = getCachedDefaultFont();
3433
3436
  if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
3434
3437
  const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
@@ -2,7 +2,8 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-YZNSWFJT.mjs";
5
+ } from "./chunk-KWB2XQSF.mjs";
6
+ import "./chunk-3UUTNNWV.mjs";
6
7
  import "./chunk-BKSXIWL7.mjs";
7
8
 
8
9
  // src/jsx-dev-runtime.tsx
@@ -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
@@ -10,18 +11,7 @@ export { Fragment, JSX } from 'react';
10
11
  */
11
12
 
12
13
  declare function _invalidateDefaultFontCache(): void;
13
- /**
14
- * Register a custom React Native component → HTML tag substitution.
15
- * Call this once at app startup (before first render).
16
- *
17
- * ```ts
18
- * import { Animated } from 'react-native';
19
- * import { registerWebElement } from '@kbach/react/jsx-runtime';
20
- * registerWebElement(Animated.View, 'div');
21
- * ```
22
- */
23
- declare function registerWebElement(rnComponent: unknown, htmlTag: string): void;
24
14
  declare function jsx(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
25
15
  declare function jsxs(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
26
16
 
27
- export { _invalidateDefaultFontCache, jsx, jsxs, registerWebElement };
17
+ export { _invalidateDefaultFontCache, jsx, jsxs };
@@ -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
@@ -10,18 +11,7 @@ export { Fragment, JSX } from 'react';
10
11
  */
11
12
 
12
13
  declare function _invalidateDefaultFontCache(): void;
13
- /**
14
- * Register a custom React Native component → HTML tag substitution.
15
- * Call this once at app startup (before first render).
16
- *
17
- * ```ts
18
- * import { Animated } from 'react-native';
19
- * import { registerWebElement } from '@kbach/react/jsx-runtime';
20
- * registerWebElement(Animated.View, 'div');
21
- * ```
22
- */
23
- declare function registerWebElement(rnComponent: unknown, htmlTag: string): void;
24
14
  declare function jsx(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
25
15
  declare function jsxs(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
26
16
 
27
- export { _invalidateDefaultFontCache, jsx, jsxs, registerWebElement };
17
+ export { _invalidateDefaultFontCache, jsx, jsxs };
@@ -3256,6 +3256,91 @@ function stripWebOnlyProps(s) {
3256
3256
  }
3257
3257
  }
3258
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
+
3259
3344
  // src/jsx-runtime.tsx
3260
3345
  var _cachedDefaultFont = void 0;
3261
3346
  var _defaultFontVersion = 0;
@@ -3337,89 +3422,6 @@ function stripWebOnlyInlineProps(s) {
3337
3422
  delete s.position;
3338
3423
  }
3339
3424
  }
3340
- var _rnToHtml = {
3341
- View: "div",
3342
- SafeAreaView: "div",
3343
- KeyboardAvoidingView: "div",
3344
- ScrollView: "div",
3345
- VirtualizedList: "div",
3346
- Text: "span",
3347
- Pressable: "div",
3348
- TouchableOpacity: "div",
3349
- TouchableHighlight: "div",
3350
- TouchableWithoutFeedback: "div",
3351
- TouchableNativeFeedback: "div"
3352
- };
3353
- var _userWebTypeMap = /* @__PURE__ */ new Map();
3354
- var _webTypeCache = /* @__PURE__ */ new WeakMap();
3355
- function registerWebElement(rnComponent, htmlTag) {
3356
- if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
3357
- _userWebTypeMap.set(rnComponent, htmlTag);
3358
- _webTypeCache.delete(rnComponent);
3359
- }
3360
- function getWebTag(type) {
3361
- if (typeof type === "string") return null;
3362
- if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3363
- const obj = type;
3364
- if (_userWebTypeMap.has(obj)) return _userWebTypeMap.get(obj);
3365
- if (_webTypeCache.has(obj)) return _webTypeCache.get(obj);
3366
- const name = obj.displayName ?? obj.name;
3367
- const tag = name ? _rnToHtml[name] ?? null : null;
3368
- _webTypeCache.set(obj, tag);
3369
- return tag;
3370
- }
3371
- var _rnOnlyProps = /* @__PURE__ */ new Set([
3372
- "onLongPress",
3373
- "delayLongPress",
3374
- "activeOpacity",
3375
- "underlayColor",
3376
- "hitSlop",
3377
- "pressRetentionOffset",
3378
- "accessible",
3379
- "accessibilityState",
3380
- "accessibilityLiveRegion",
3381
- "importantForAccessibility",
3382
- "nativeID",
3383
- "collapsable",
3384
- "needsOffscreenAlphaCompositing",
3385
- "renderToHardwareTextureAndroid",
3386
- "shouldRasterizeIOS",
3387
- "pointerEvents"
3388
- // RN prop — values differ from HTML pointer-events CSS
3389
- ]);
3390
- var _pressableDisplayNames = /* @__PURE__ */ new Set([
3391
- "Pressable",
3392
- "TouchableOpacity",
3393
- "TouchableHighlight",
3394
- "TouchableWithoutFeedback",
3395
- "TouchableNativeFeedback"
3396
- ]);
3397
- function transformToWebProps(originalName, props) {
3398
- const out = {};
3399
- const isPressable = _pressableDisplayNames.has(originalName);
3400
- for (const [k, v] of Object.entries(props)) {
3401
- if (_rnOnlyProps.has(k)) continue;
3402
- if (k === "onPress") {
3403
- if (!("onClick" in props)) out.onClick = v;
3404
- continue;
3405
- }
3406
- if (k === "accessibilityLabel") {
3407
- if (out["aria-label"] == null) out["aria-label"] = v;
3408
- continue;
3409
- }
3410
- if (k === "accessibilityRole") {
3411
- if (out.role == null) out.role = v;
3412
- continue;
3413
- }
3414
- if (k === "testID") {
3415
- if (out["data-testid"] == null) out["data-testid"] = v;
3416
- continue;
3417
- }
3418
- out[k] = v;
3419
- }
3420
- if (isPressable && !out.role) out.role = "button";
3421
- return out;
3422
- }
3423
3425
  function processElement(type, rawProps, key, isStaticChildren) {
3424
3426
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3425
3427
  const webTag = isWeb ? getWebTag(type) : null;
@@ -3438,6 +3440,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
3438
3440
  }, key);
3439
3441
  }
3440
3442
  if (!classStr && !__kbachStyles) {
3443
+ if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
3441
3444
  const defaultFont = getCachedDefaultFont();
3442
3445
  if (!defaultFont) return makeElement(isStaticChildren, effectiveType, workingProps, key);
3443
3446
  const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
@@ -2,9 +2,11 @@ import {
2
2
  Fragment,
3
3
  _invalidateDefaultFontCache,
4
4
  jsx,
5
- jsxs,
5
+ jsxs
6
+ } from "./chunk-KWB2XQSF.mjs";
7
+ import {
6
8
  registerWebElement
7
- } from "./chunk-YZNSWFJT.mjs";
9
+ } from "./chunk-3UUTNNWV.mjs";
8
10
  import "./chunk-BKSXIWL7.mjs";
9
11
  export {
10
12
  Fragment,
@@ -0,0 +1,22 @@
1
+ /**
2
+ * React Native → HTML element substitution for web rendering.
3
+ *
4
+ * When isWeb is true, known React Native component types (View, Text, Pressable, …)
5
+ * are replaced with plain HTML element strings ('div', 'span', …) so the DOM shows
6
+ * clean Kbach class names instead of React Native Web's generated css-view-* classes.
7
+ *
8
+ * Used by: jsx-runtime (bare JSX), styled(), DarkWrapper, InteractiveWrapper.
9
+ */
10
+ /**
11
+ * Register a custom React Native component → HTML tag substitution.
12
+ * Call once at app startup before first render.
13
+ *
14
+ * ```ts
15
+ * import { Animated } from 'react-native';
16
+ * import { registerWebElement } from '@kbach/react';
17
+ * registerWebElement(Animated.View, 'div');
18
+ * ```
19
+ */
20
+ declare function registerWebElement(rnComponent: unknown, htmlTag: string): void;
21
+
22
+ export { registerWebElement as r };