@kbach/react 0.5.49 → 0.5.52

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.
@@ -6,7 +6,7 @@ import {
6
6
  transformToWebProps,
7
7
  useConditionalWidth,
8
8
  useGlobalDarkMode
9
- } from "./chunk-3UUTNNWV.mjs";
9
+ } from "./chunk-7EUNJFX7.mjs";
10
10
  import {
11
11
  flatten,
12
12
  getActiveBreakpoints,
@@ -20,7 +20,7 @@ import {
20
20
  isWeb,
21
21
  normalizeClassString,
22
22
  resolve
23
- } from "./chunk-BKSXIWL7.mjs";
23
+ } from "./chunk-JBV2R655.mjs";
24
24
 
25
25
  // src/jsx-runtime.tsx
26
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -36,6 +36,7 @@ var DarkWrapper = React.forwardRef(
36
36
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
37
37
  const isNonStringComponent = typeof Component !== "string";
38
38
  const computedStyle = useMemo(() => {
39
+ if (isWeb) return {};
39
40
  const s = flatten(resolvedStyle, isDark, {}, breakpoints);
40
41
  stripInternalMarkers(s);
41
42
  if (isNonStringComponent) stripWebOnlyProps(s);
@@ -162,11 +163,11 @@ function stripWebOnlyInlineProps(s) {
162
163
  }
163
164
  function processElement(type, rawProps, key, isStaticChildren) {
164
165
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
165
- const webTag = isWeb ? getWebTag(type) : null;
166
+ const webTag = isWeb ? getWebTag(type, rawProps ?? void 0) : null;
166
167
  const effectiveType = webTag ?? type;
167
168
  const originalName = webTag ? type?.displayName ?? type?.name : void 0;
168
169
  if (!rawProps) return _jsx(effectiveType, null, key);
169
- const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
170
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, webTag, rawProps) : rawProps;
170
171
  const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
171
172
  const classStr = className ?? kbProp ?? __kbachClasses;
172
173
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
@@ -186,7 +187,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
186
187
  return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
187
188
  }
188
189
  const config = getConfig();
189
- const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
190
+ const resolved = !isWeb && __kbachStyles != null ? __kbachStyles : classStr ? resolve(classStr, config.theme, config.darkMode) : {};
190
191
  const { style: userStyle, ...passProps } = omitConsumed(workingProps);
191
192
  const { interactive, modeOrResponsive } = bucketMods(resolved);
192
193
  if (interactive) {
@@ -7,7 +7,7 @@ import {
7
7
  isNative,
8
8
  isWeb,
9
9
  subscribeGlobalWidth
10
- } from "./chunk-BKSXIWL7.mjs";
10
+ } from "./chunk-JBV2R655.mjs";
11
11
 
12
12
  // src/core/darkModeStore.ts
13
13
  var KEY = "__kbach_dark_store__";
@@ -44,7 +44,12 @@ var _rnToHtml = {
44
44
  KeyboardAvoidingView: "div",
45
45
  ScrollView: "div",
46
46
  VirtualizedList: "div",
47
+ FlatList: "div",
48
+ SectionList: "div",
47
49
  Text: "span",
50
+ TextInput: "input",
51
+ Image: "img",
52
+ ImageBackground: "div",
48
53
  Pressable: "div",
49
54
  TouchableOpacity: "div",
50
55
  TouchableHighlight: "div",
@@ -58,14 +63,22 @@ function registerWebElement(rnComponent, htmlTag) {
58
63
  _userMap.set(rnComponent, htmlTag);
59
64
  _cache.delete(rnComponent);
60
65
  }
61
- function getWebTag(type) {
66
+ function getWebTag(type, props) {
62
67
  if (typeof type === "string") return null;
63
68
  if (type === null || typeof type !== "function" && typeof type !== "object") return null;
64
69
  const obj = type;
65
70
  if (_userMap.has(obj)) return _userMap.get(obj);
66
- if (_cache.has(obj)) return _cache.get(obj);
67
71
  const name = obj.displayName ?? obj.name;
68
- const tag = name ? _rnToHtml[name] ?? null : null;
72
+ if (!name) {
73
+ _cache.set(obj, null);
74
+ return null;
75
+ }
76
+ if (name === "TextInput" && props) {
77
+ const multiline = props.multiline === true || Number(props.numberOfLines) > 1;
78
+ return multiline ? "textarea" : "input";
79
+ }
80
+ if (_cache.has(obj)) return _cache.get(obj);
81
+ const tag = _rnToHtml[name] ?? null;
69
82
  _cache.set(obj, tag);
70
83
  return tag;
71
84
  }
@@ -85,8 +98,19 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
85
98
  "needsOffscreenAlphaCompositing",
86
99
  "renderToHardwareTextureAndroid",
87
100
  "shouldRasterizeIOS",
88
- "pointerEvents"
101
+ "pointerEvents",
89
102
  // RN and HTML values differ
103
+ "multiline",
104
+ "numberOfLines",
105
+ // handled separately
106
+ "resizeMode",
107
+ // handled separately
108
+ "blurOnSubmit",
109
+ "clearButtonMode",
110
+ "clearTextOnFocus",
111
+ "enablesReturnKeyAutomatically",
112
+ "returnKeyType",
113
+ "spellCheck"
90
114
  ]);
91
115
  var _pressableNames = /* @__PURE__ */ new Set([
92
116
  "Pressable",
@@ -95,9 +119,26 @@ var _pressableNames = /* @__PURE__ */ new Set([
95
119
  "TouchableWithoutFeedback",
96
120
  "TouchableNativeFeedback"
97
121
  ]);
98
- function transformToWebProps(originalName, props) {
122
+ var _keyboardTypeMap = {
123
+ "numeric": "number",
124
+ "number-pad": "number",
125
+ "decimal-pad": "decimal",
126
+ "email-address": "email",
127
+ "phone-pad": "tel",
128
+ "url": "url"
129
+ };
130
+ var _resizeModeMap = {
131
+ "contain": "contain",
132
+ "cover": "cover",
133
+ "stretch": "fill",
134
+ "center": "none",
135
+ "repeat": "none"
136
+ };
137
+ function transformToWebProps(originalName, tag, props) {
99
138
  const out = {};
100
139
  const isPressable = _pressableNames.has(originalName);
140
+ const isTextInput = originalName === "TextInput";
141
+ const isImage = originalName === "Image" || originalName === "ImageBackground";
101
142
  for (const [k, v] of Object.entries(props)) {
102
143
  if (_rnOnlyProps.has(k)) continue;
103
144
  if (k === "onPress") {
@@ -116,9 +157,50 @@ function transformToWebProps(originalName, props) {
116
157
  if (out["data-testid"] == null) out["data-testid"] = v;
117
158
  continue;
118
159
  }
160
+ if (isTextInput) {
161
+ if (k === "onChangeText") {
162
+ if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
163
+ continue;
164
+ }
165
+ if (k === "secureTextEntry") {
166
+ if (v && !("type" in props)) out.type = "password";
167
+ continue;
168
+ }
169
+ if (k === "keyboardType") {
170
+ if (!("type" in props) && !("secureTextEntry" in props)) {
171
+ const mapped = _keyboardTypeMap[v];
172
+ if (mapped) out.type = mapped;
173
+ }
174
+ continue;
175
+ }
176
+ if (k === "editable") {
177
+ if (v === false) out.readOnly = true;
178
+ continue;
179
+ }
180
+ if (k === "maxLength") {
181
+ out.maxLength = v;
182
+ continue;
183
+ }
184
+ }
185
+ if (isImage) {
186
+ if (k === "source") {
187
+ if (v && typeof v === "object" && "uri" in v) {
188
+ out.src = v.uri;
189
+ if (v.headers) out["crossOrigin"] = "anonymous";
190
+ }
191
+ continue;
192
+ }
193
+ if (k === "resizeMode") {
194
+ const existing = out.style ?? {};
195
+ out.style = { ...existing, objectFit: _resizeModeMap[v] ?? "cover" };
196
+ continue;
197
+ }
198
+ if (k === "alt" || k === "defaultSource") continue;
199
+ }
119
200
  out[k] = v;
120
201
  }
121
202
  if (isPressable && !out.role) out.role = "button";
203
+ if (isImage && tag === "img" && out.alt == null) out.alt = "";
122
204
  return out;
123
205
  }
124
206
 
@@ -260,6 +342,7 @@ var InteractiveWrapper = forwardRef(
260
342
  const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
261
343
  const computedStyle = useMemo(
262
344
  () => {
345
+ if (isWeb) return {};
263
346
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
264
347
  delete s.__divideX;
265
348
  delete s.__divideY;
@@ -2805,9 +2805,11 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
2805
2805
  Object.assign(result, styles);
2806
2806
  }
2807
2807
  }
2808
- const defaultFont = getDefaultFontFamily();
2809
- if (defaultFont && !("fontFamily" in result)) {
2810
- result.fontFamily = defaultFont;
2808
+ if (isNative) {
2809
+ const defaultFont = getDefaultFontFamily();
2810
+ if (defaultFont && !("fontFamily" in result)) {
2811
+ result.fontFamily = defaultFont;
2812
+ }
2811
2813
  }
2812
2814
  if (!isNative) {
2813
2815
  const r = result;
package/dist/index.js CHANGED
@@ -2933,9 +2933,11 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
2933
2933
  Object.assign(result, styles);
2934
2934
  }
2935
2935
  }
2936
- const defaultFont = getDefaultFontFamily();
2937
- if (defaultFont && !("fontFamily" in result)) {
2938
- result.fontFamily = defaultFont;
2936
+ if (isNative) {
2937
+ const defaultFont = getDefaultFontFamily();
2938
+ if (defaultFont && !("fontFamily" in result)) {
2939
+ result.fontFamily = defaultFont;
2940
+ }
2939
2941
  }
2940
2942
  if (!isNative) {
2941
2943
  const r = result;
@@ -3544,7 +3546,12 @@ var _rnToHtml = {
3544
3546
  KeyboardAvoidingView: "div",
3545
3547
  ScrollView: "div",
3546
3548
  VirtualizedList: "div",
3549
+ FlatList: "div",
3550
+ SectionList: "div",
3547
3551
  Text: "span",
3552
+ TextInput: "input",
3553
+ Image: "img",
3554
+ ImageBackground: "div",
3548
3555
  Pressable: "div",
3549
3556
  TouchableOpacity: "div",
3550
3557
  TouchableHighlight: "div",
@@ -3558,14 +3565,22 @@ function registerWebElement(rnComponent, htmlTag) {
3558
3565
  _userMap.set(rnComponent, htmlTag);
3559
3566
  _cache.delete(rnComponent);
3560
3567
  }
3561
- function getWebTag(type) {
3568
+ function getWebTag(type, props) {
3562
3569
  if (typeof type === "string") return null;
3563
3570
  if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3564
3571
  const obj = type;
3565
3572
  if (_userMap.has(obj)) return _userMap.get(obj);
3566
- if (_cache.has(obj)) return _cache.get(obj);
3567
3573
  const name = obj.displayName ?? obj.name;
3568
- const tag = name ? _rnToHtml[name] ?? null : null;
3574
+ if (!name) {
3575
+ _cache.set(obj, null);
3576
+ return null;
3577
+ }
3578
+ if (name === "TextInput" && props) {
3579
+ const multiline = props.multiline === true || Number(props.numberOfLines) > 1;
3580
+ return multiline ? "textarea" : "input";
3581
+ }
3582
+ if (_cache.has(obj)) return _cache.get(obj);
3583
+ const tag = _rnToHtml[name] ?? null;
3569
3584
  _cache.set(obj, tag);
3570
3585
  return tag;
3571
3586
  }
@@ -3585,8 +3600,19 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
3585
3600
  "needsOffscreenAlphaCompositing",
3586
3601
  "renderToHardwareTextureAndroid",
3587
3602
  "shouldRasterizeIOS",
3588
- "pointerEvents"
3603
+ "pointerEvents",
3589
3604
  // RN and HTML values differ
3605
+ "multiline",
3606
+ "numberOfLines",
3607
+ // handled separately
3608
+ "resizeMode",
3609
+ // handled separately
3610
+ "blurOnSubmit",
3611
+ "clearButtonMode",
3612
+ "clearTextOnFocus",
3613
+ "enablesReturnKeyAutomatically",
3614
+ "returnKeyType",
3615
+ "spellCheck"
3590
3616
  ]);
3591
3617
  var _pressableNames = /* @__PURE__ */ new Set([
3592
3618
  "Pressable",
@@ -3595,9 +3621,26 @@ var _pressableNames = /* @__PURE__ */ new Set([
3595
3621
  "TouchableWithoutFeedback",
3596
3622
  "TouchableNativeFeedback"
3597
3623
  ]);
3598
- function transformToWebProps(originalName, props) {
3624
+ var _keyboardTypeMap = {
3625
+ "numeric": "number",
3626
+ "number-pad": "number",
3627
+ "decimal-pad": "decimal",
3628
+ "email-address": "email",
3629
+ "phone-pad": "tel",
3630
+ "url": "url"
3631
+ };
3632
+ var _resizeModeMap = {
3633
+ "contain": "contain",
3634
+ "cover": "cover",
3635
+ "stretch": "fill",
3636
+ "center": "none",
3637
+ "repeat": "none"
3638
+ };
3639
+ function transformToWebProps(originalName, tag, props) {
3599
3640
  const out = {};
3600
3641
  const isPressable = _pressableNames.has(originalName);
3642
+ const isTextInput = originalName === "TextInput";
3643
+ const isImage = originalName === "Image" || originalName === "ImageBackground";
3601
3644
  for (const [k, v] of Object.entries(props)) {
3602
3645
  if (_rnOnlyProps.has(k)) continue;
3603
3646
  if (k === "onPress") {
@@ -3616,9 +3659,50 @@ function transformToWebProps(originalName, props) {
3616
3659
  if (out["data-testid"] == null) out["data-testid"] = v;
3617
3660
  continue;
3618
3661
  }
3662
+ if (isTextInput) {
3663
+ if (k === "onChangeText") {
3664
+ if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
3665
+ continue;
3666
+ }
3667
+ if (k === "secureTextEntry") {
3668
+ if (v && !("type" in props)) out.type = "password";
3669
+ continue;
3670
+ }
3671
+ if (k === "keyboardType") {
3672
+ if (!("type" in props) && !("secureTextEntry" in props)) {
3673
+ const mapped = _keyboardTypeMap[v];
3674
+ if (mapped) out.type = mapped;
3675
+ }
3676
+ continue;
3677
+ }
3678
+ if (k === "editable") {
3679
+ if (v === false) out.readOnly = true;
3680
+ continue;
3681
+ }
3682
+ if (k === "maxLength") {
3683
+ out.maxLength = v;
3684
+ continue;
3685
+ }
3686
+ }
3687
+ if (isImage) {
3688
+ if (k === "source") {
3689
+ if (v && typeof v === "object" && "uri" in v) {
3690
+ out.src = v.uri;
3691
+ if (v.headers) out["crossOrigin"] = "anonymous";
3692
+ }
3693
+ continue;
3694
+ }
3695
+ if (k === "resizeMode") {
3696
+ const existing = out.style ?? {};
3697
+ out.style = { ...existing, objectFit: _resizeModeMap[v] ?? "cover" };
3698
+ continue;
3699
+ }
3700
+ if (k === "alt" || k === "defaultSource") continue;
3701
+ }
3619
3702
  out[k] = v;
3620
3703
  }
3621
3704
  if (isPressable && !out.role) out.role = "button";
3705
+ if (isImage && tag === "img" && out.alt == null) out.alt = "";
3622
3706
  return out;
3623
3707
  }
3624
3708
 
@@ -3689,16 +3773,16 @@ function styled(Component, baseClasses = "") {
3689
3773
  const width = useConditionalWidth(needsWidth);
3690
3774
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3691
3775
  const computedStyle = (0, import_react6.useMemo)(
3692
- () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
3776
+ () => isWeb ? {} : flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
3693
3777
  [resolved, isDark, pressed, hovered, focused, disabled, checked, width]
3694
3778
  // eslint-disable-line react-hooks/exhaustive-deps
3695
3779
  );
3696
3780
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
3697
3781
  const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
3698
- const webTag = isWeb ? getWebTag(Component) : null;
3782
+ const webTag = isWeb ? getWebTag(Component, rest) : null;
3699
3783
  const effectiveComponent = webTag ?? Component;
3700
3784
  const componentName2 = Component.displayName ?? Component.name ?? "";
3701
- const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, rest) : rest;
3785
+ const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, webTag, rest) : rest;
3702
3786
  return import_react6.default.createElement(effectiveComponent, {
3703
3787
  ref,
3704
3788
  ...effectiveRest,
@@ -3828,6 +3912,7 @@ var InteractiveWrapper = (0, import_react10.forwardRef)(
3828
3912
  const handleBlur = (0, import_react10.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3829
3913
  const computedStyle = (0, import_react10.useMemo)(
3830
3914
  () => {
3915
+ if (isWeb) return {};
3831
3916
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3832
3917
  delete s.__divideX;
3833
3918
  delete s.__divideY;
package/dist/index.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  useConditionalWidth,
12
12
  useGlobalDarkMode,
13
13
  useGlobalWidth
14
- } from "./chunk-3UUTNNWV.mjs";
14
+ } from "./chunk-7EUNJFX7.mjs";
15
15
  import {
16
16
  __require,
17
17
  buildConfig,
@@ -33,7 +33,7 @@ import {
33
33
  syncGlobalScreens,
34
34
  syncGlobalWidth,
35
35
  updateConfig
36
- } from "./chunk-BKSXIWL7.mjs";
36
+ } from "./chunk-JBV2R655.mjs";
37
37
 
38
38
  // src/context.tsx
39
39
  import { createContext, useContext } from "react";
@@ -476,16 +476,16 @@ function styled(Component, baseClasses = "") {
476
476
  const width = useConditionalWidth(needsWidth);
477
477
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
478
478
  const computedStyle = useMemo3(
479
- () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
479
+ () => isWeb ? {} : flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
480
480
  [resolved, isDark, pressed, hovered, focused, disabled, checked, width]
481
481
  // eslint-disable-line react-hooks/exhaustive-deps
482
482
  );
483
483
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
484
484
  const finalStyle = isWeb ? extraStyle ?? void 0 : extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
485
- const webTag = isWeb ? getWebTag(Component) : null;
485
+ const webTag = isWeb ? getWebTag(Component, rest) : null;
486
486
  const effectiveComponent = webTag ?? Component;
487
487
  const componentName2 = Component.displayName ?? Component.name ?? "";
488
- const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, rest) : rest;
488
+ const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, webTag, rest) : rest;
489
489
  return React3.createElement(effectiveComponent, {
490
490
  ref,
491
491
  ...effectiveRest,
@@ -2811,9 +2811,11 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
2811
2811
  Object.assign(result, styles);
2812
2812
  }
2813
2813
  }
2814
- const defaultFont = getDefaultFontFamily();
2815
- if (defaultFont && !("fontFamily" in result)) {
2816
- result.fontFamily = defaultFont;
2814
+ if (isNative) {
2815
+ const defaultFont = getDefaultFontFamily();
2816
+ if (defaultFont && !("fontFamily" in result)) {
2817
+ result.fontFamily = defaultFont;
2818
+ }
2817
2819
  }
2818
2820
  if (!isNative) {
2819
2821
  const r = result;
@@ -3147,6 +3149,7 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3147
3149
  const handleBlur = (0, import_react3.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3148
3150
  const computedStyle = (0, import_react3.useMemo)(
3149
3151
  () => {
3152
+ if (isWeb) return {};
3150
3153
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3151
3154
  delete s.__divideX;
3152
3155
  delete s.__divideY;
@@ -3212,6 +3215,7 @@ var DarkWrapper = import_react4.default.forwardRef(
3212
3215
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS2;
3213
3216
  const isNonStringComponent = typeof Component !== "string";
3214
3217
  const computedStyle = (0, import_react4.useMemo)(() => {
3218
+ if (isWeb) return {};
3215
3219
  const s = flatten(resolvedStyle, isDark, {}, breakpoints);
3216
3220
  stripInternalMarkers(s);
3217
3221
  if (isNonStringComponent) stripWebOnlyProps(s);
@@ -3262,7 +3266,12 @@ var _rnToHtml = {
3262
3266
  KeyboardAvoidingView: "div",
3263
3267
  ScrollView: "div",
3264
3268
  VirtualizedList: "div",
3269
+ FlatList: "div",
3270
+ SectionList: "div",
3265
3271
  Text: "span",
3272
+ TextInput: "input",
3273
+ Image: "img",
3274
+ ImageBackground: "div",
3266
3275
  Pressable: "div",
3267
3276
  TouchableOpacity: "div",
3268
3277
  TouchableHighlight: "div",
@@ -3271,14 +3280,22 @@ var _rnToHtml = {
3271
3280
  };
3272
3281
  var _userMap = /* @__PURE__ */ new Map();
3273
3282
  var _cache = /* @__PURE__ */ new WeakMap();
3274
- function getWebTag(type) {
3283
+ function getWebTag(type, props) {
3275
3284
  if (typeof type === "string") return null;
3276
3285
  if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3277
3286
  const obj = type;
3278
3287
  if (_userMap.has(obj)) return _userMap.get(obj);
3279
- if (_cache.has(obj)) return _cache.get(obj);
3280
3288
  const name = obj.displayName ?? obj.name;
3281
- const tag = name ? _rnToHtml[name] ?? null : null;
3289
+ if (!name) {
3290
+ _cache.set(obj, null);
3291
+ return null;
3292
+ }
3293
+ if (name === "TextInput" && props) {
3294
+ const multiline = props.multiline === true || Number(props.numberOfLines) > 1;
3295
+ return multiline ? "textarea" : "input";
3296
+ }
3297
+ if (_cache.has(obj)) return _cache.get(obj);
3298
+ const tag = _rnToHtml[name] ?? null;
3282
3299
  _cache.set(obj, tag);
3283
3300
  return tag;
3284
3301
  }
@@ -3298,8 +3315,19 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
3298
3315
  "needsOffscreenAlphaCompositing",
3299
3316
  "renderToHardwareTextureAndroid",
3300
3317
  "shouldRasterizeIOS",
3301
- "pointerEvents"
3318
+ "pointerEvents",
3302
3319
  // RN and HTML values differ
3320
+ "multiline",
3321
+ "numberOfLines",
3322
+ // handled separately
3323
+ "resizeMode",
3324
+ // handled separately
3325
+ "blurOnSubmit",
3326
+ "clearButtonMode",
3327
+ "clearTextOnFocus",
3328
+ "enablesReturnKeyAutomatically",
3329
+ "returnKeyType",
3330
+ "spellCheck"
3303
3331
  ]);
3304
3332
  var _pressableNames = /* @__PURE__ */ new Set([
3305
3333
  "Pressable",
@@ -3308,9 +3336,26 @@ var _pressableNames = /* @__PURE__ */ new Set([
3308
3336
  "TouchableWithoutFeedback",
3309
3337
  "TouchableNativeFeedback"
3310
3338
  ]);
3311
- function transformToWebProps(originalName, props) {
3339
+ var _keyboardTypeMap = {
3340
+ "numeric": "number",
3341
+ "number-pad": "number",
3342
+ "decimal-pad": "decimal",
3343
+ "email-address": "email",
3344
+ "phone-pad": "tel",
3345
+ "url": "url"
3346
+ };
3347
+ var _resizeModeMap = {
3348
+ "contain": "contain",
3349
+ "cover": "cover",
3350
+ "stretch": "fill",
3351
+ "center": "none",
3352
+ "repeat": "none"
3353
+ };
3354
+ function transformToWebProps(originalName, tag, props) {
3312
3355
  const out = {};
3313
3356
  const isPressable = _pressableNames.has(originalName);
3357
+ const isTextInput = originalName === "TextInput";
3358
+ const isImage = originalName === "Image" || originalName === "ImageBackground";
3314
3359
  for (const [k, v] of Object.entries(props)) {
3315
3360
  if (_rnOnlyProps.has(k)) continue;
3316
3361
  if (k === "onPress") {
@@ -3329,9 +3374,50 @@ function transformToWebProps(originalName, props) {
3329
3374
  if (out["data-testid"] == null) out["data-testid"] = v;
3330
3375
  continue;
3331
3376
  }
3377
+ if (isTextInput) {
3378
+ if (k === "onChangeText") {
3379
+ if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
3380
+ continue;
3381
+ }
3382
+ if (k === "secureTextEntry") {
3383
+ if (v && !("type" in props)) out.type = "password";
3384
+ continue;
3385
+ }
3386
+ if (k === "keyboardType") {
3387
+ if (!("type" in props) && !("secureTextEntry" in props)) {
3388
+ const mapped = _keyboardTypeMap[v];
3389
+ if (mapped) out.type = mapped;
3390
+ }
3391
+ continue;
3392
+ }
3393
+ if (k === "editable") {
3394
+ if (v === false) out.readOnly = true;
3395
+ continue;
3396
+ }
3397
+ if (k === "maxLength") {
3398
+ out.maxLength = v;
3399
+ continue;
3400
+ }
3401
+ }
3402
+ if (isImage) {
3403
+ if (k === "source") {
3404
+ if (v && typeof v === "object" && "uri" in v) {
3405
+ out.src = v.uri;
3406
+ if (v.headers) out["crossOrigin"] = "anonymous";
3407
+ }
3408
+ continue;
3409
+ }
3410
+ if (k === "resizeMode") {
3411
+ const existing = out.style ?? {};
3412
+ out.style = { ...existing, objectFit: _resizeModeMap[v] ?? "cover" };
3413
+ continue;
3414
+ }
3415
+ if (k === "alt" || k === "defaultSource") continue;
3416
+ }
3332
3417
  out[k] = v;
3333
3418
  }
3334
3419
  if (isPressable && !out.role) out.role = "button";
3420
+ if (isImage && tag === "img" && out.alt == null) out.alt = "";
3335
3421
  return out;
3336
3422
  }
3337
3423
 
@@ -3415,11 +3501,11 @@ function stripWebOnlyInlineProps(s) {
3415
3501
  }
3416
3502
  function processElement(type, rawProps, key, isStaticChildren) {
3417
3503
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3418
- const webTag = isWeb ? getWebTag(type) : null;
3504
+ const webTag = isWeb ? getWebTag(type, rawProps ?? void 0) : null;
3419
3505
  const effectiveType = webTag ?? type;
3420
3506
  const originalName = webTag ? type?.displayName ?? type?.name : void 0;
3421
3507
  if (!rawProps) return (0, import_jsx_runtime.jsx)(effectiveType, null, key);
3422
- const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
3508
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, webTag, rawProps) : rawProps;
3423
3509
  const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
3424
3510
  const classStr = className ?? kbProp ?? __kbachClasses;
3425
3511
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
@@ -3439,7 +3525,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
3439
3525
  return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
3440
3526
  }
3441
3527
  const config = getConfig();
3442
- const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
3528
+ const resolved = !isWeb && __kbachStyles != null ? __kbachStyles : classStr ? resolve(classStr, config.theme, config.darkMode) : {};
3443
3529
  const { style: userStyle, ...passProps } = omitConsumed(workingProps);
3444
3530
  const { interactive, modeOrResponsive } = bucketMods(resolved);
3445
3531
  if (interactive) {
@@ -2,9 +2,9 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-KWB2XQSF.mjs";
6
- import "./chunk-3UUTNNWV.mjs";
7
- import "./chunk-BKSXIWL7.mjs";
5
+ } from "./chunk-6PRTRINF.mjs";
6
+ import "./chunk-7EUNJFX7.mjs";
7
+ import "./chunk-JBV2R655.mjs";
8
8
 
9
9
  // src/jsx-dev-runtime.tsx
10
10
  function jsxDEV(type, props, key, isStaticChildren, source, self) {
@@ -2812,9 +2812,11 @@ function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new
2812
2812
  Object.assign(result, styles);
2813
2813
  }
2814
2814
  }
2815
- const defaultFont = getDefaultFontFamily();
2816
- if (defaultFont && !("fontFamily" in result)) {
2817
- result.fontFamily = defaultFont;
2815
+ if (isNative) {
2816
+ const defaultFont = getDefaultFontFamily();
2817
+ if (defaultFont && !("fontFamily" in result)) {
2818
+ result.fontFamily = defaultFont;
2819
+ }
2818
2820
  }
2819
2821
  if (!isNative) {
2820
2822
  const r = result;
@@ -3148,6 +3150,7 @@ var InteractiveWrapper = (0, import_react3.forwardRef)(
3148
3150
  const handleBlur = (0, import_react3.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
3149
3151
  const computedStyle = (0, import_react3.useMemo)(
3150
3152
  () => {
3153
+ if (isWeb) return {};
3151
3154
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
3152
3155
  delete s.__divideX;
3153
3156
  delete s.__divideY;
@@ -3213,6 +3216,7 @@ var DarkWrapper = import_react4.default.forwardRef(
3213
3216
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS2;
3214
3217
  const isNonStringComponent = typeof Component !== "string";
3215
3218
  const computedStyle = (0, import_react4.useMemo)(() => {
3219
+ if (isWeb) return {};
3216
3220
  const s = flatten(resolvedStyle, isDark, {}, breakpoints);
3217
3221
  stripInternalMarkers(s);
3218
3222
  if (isNonStringComponent) stripWebOnlyProps(s);
@@ -3263,7 +3267,12 @@ var _rnToHtml = {
3263
3267
  KeyboardAvoidingView: "div",
3264
3268
  ScrollView: "div",
3265
3269
  VirtualizedList: "div",
3270
+ FlatList: "div",
3271
+ SectionList: "div",
3266
3272
  Text: "span",
3273
+ TextInput: "input",
3274
+ Image: "img",
3275
+ ImageBackground: "div",
3267
3276
  Pressable: "div",
3268
3277
  TouchableOpacity: "div",
3269
3278
  TouchableHighlight: "div",
@@ -3277,14 +3286,22 @@ function registerWebElement(rnComponent, htmlTag) {
3277
3286
  _userMap.set(rnComponent, htmlTag);
3278
3287
  _cache.delete(rnComponent);
3279
3288
  }
3280
- function getWebTag(type) {
3289
+ function getWebTag(type, props) {
3281
3290
  if (typeof type === "string") return null;
3282
3291
  if (type === null || typeof type !== "function" && typeof type !== "object") return null;
3283
3292
  const obj = type;
3284
3293
  if (_userMap.has(obj)) return _userMap.get(obj);
3285
- if (_cache.has(obj)) return _cache.get(obj);
3286
3294
  const name = obj.displayName ?? obj.name;
3287
- const tag = name ? _rnToHtml[name] ?? null : null;
3295
+ if (!name) {
3296
+ _cache.set(obj, null);
3297
+ return null;
3298
+ }
3299
+ if (name === "TextInput" && props) {
3300
+ const multiline = props.multiline === true || Number(props.numberOfLines) > 1;
3301
+ return multiline ? "textarea" : "input";
3302
+ }
3303
+ if (_cache.has(obj)) return _cache.get(obj);
3304
+ const tag = _rnToHtml[name] ?? null;
3288
3305
  _cache.set(obj, tag);
3289
3306
  return tag;
3290
3307
  }
@@ -3304,8 +3321,19 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
3304
3321
  "needsOffscreenAlphaCompositing",
3305
3322
  "renderToHardwareTextureAndroid",
3306
3323
  "shouldRasterizeIOS",
3307
- "pointerEvents"
3324
+ "pointerEvents",
3308
3325
  // RN and HTML values differ
3326
+ "multiline",
3327
+ "numberOfLines",
3328
+ // handled separately
3329
+ "resizeMode",
3330
+ // handled separately
3331
+ "blurOnSubmit",
3332
+ "clearButtonMode",
3333
+ "clearTextOnFocus",
3334
+ "enablesReturnKeyAutomatically",
3335
+ "returnKeyType",
3336
+ "spellCheck"
3309
3337
  ]);
3310
3338
  var _pressableNames = /* @__PURE__ */ new Set([
3311
3339
  "Pressable",
@@ -3314,9 +3342,26 @@ var _pressableNames = /* @__PURE__ */ new Set([
3314
3342
  "TouchableWithoutFeedback",
3315
3343
  "TouchableNativeFeedback"
3316
3344
  ]);
3317
- function transformToWebProps(originalName, props) {
3345
+ var _keyboardTypeMap = {
3346
+ "numeric": "number",
3347
+ "number-pad": "number",
3348
+ "decimal-pad": "decimal",
3349
+ "email-address": "email",
3350
+ "phone-pad": "tel",
3351
+ "url": "url"
3352
+ };
3353
+ var _resizeModeMap = {
3354
+ "contain": "contain",
3355
+ "cover": "cover",
3356
+ "stretch": "fill",
3357
+ "center": "none",
3358
+ "repeat": "none"
3359
+ };
3360
+ function transformToWebProps(originalName, tag, props) {
3318
3361
  const out = {};
3319
3362
  const isPressable = _pressableNames.has(originalName);
3363
+ const isTextInput = originalName === "TextInput";
3364
+ const isImage = originalName === "Image" || originalName === "ImageBackground";
3320
3365
  for (const [k, v] of Object.entries(props)) {
3321
3366
  if (_rnOnlyProps.has(k)) continue;
3322
3367
  if (k === "onPress") {
@@ -3335,9 +3380,50 @@ function transformToWebProps(originalName, props) {
3335
3380
  if (out["data-testid"] == null) out["data-testid"] = v;
3336
3381
  continue;
3337
3382
  }
3383
+ if (isTextInput) {
3384
+ if (k === "onChangeText") {
3385
+ if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
3386
+ continue;
3387
+ }
3388
+ if (k === "secureTextEntry") {
3389
+ if (v && !("type" in props)) out.type = "password";
3390
+ continue;
3391
+ }
3392
+ if (k === "keyboardType") {
3393
+ if (!("type" in props) && !("secureTextEntry" in props)) {
3394
+ const mapped = _keyboardTypeMap[v];
3395
+ if (mapped) out.type = mapped;
3396
+ }
3397
+ continue;
3398
+ }
3399
+ if (k === "editable") {
3400
+ if (v === false) out.readOnly = true;
3401
+ continue;
3402
+ }
3403
+ if (k === "maxLength") {
3404
+ out.maxLength = v;
3405
+ continue;
3406
+ }
3407
+ }
3408
+ if (isImage) {
3409
+ if (k === "source") {
3410
+ if (v && typeof v === "object" && "uri" in v) {
3411
+ out.src = v.uri;
3412
+ if (v.headers) out["crossOrigin"] = "anonymous";
3413
+ }
3414
+ continue;
3415
+ }
3416
+ if (k === "resizeMode") {
3417
+ const existing = out.style ?? {};
3418
+ out.style = { ...existing, objectFit: _resizeModeMap[v] ?? "cover" };
3419
+ continue;
3420
+ }
3421
+ if (k === "alt" || k === "defaultSource") continue;
3422
+ }
3338
3423
  out[k] = v;
3339
3424
  }
3340
3425
  if (isPressable && !out.role) out.role = "button";
3426
+ if (isImage && tag === "img" && out.alt == null) out.alt = "";
3341
3427
  return out;
3342
3428
  }
3343
3429
 
@@ -3424,11 +3510,11 @@ function stripWebOnlyInlineProps(s) {
3424
3510
  }
3425
3511
  function processElement(type, rawProps, key, isStaticChildren) {
3426
3512
  if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
3427
- const webTag = isWeb ? getWebTag(type) : null;
3513
+ const webTag = isWeb ? getWebTag(type, rawProps ?? void 0) : null;
3428
3514
  const effectiveType = webTag ?? type;
3429
3515
  const originalName = webTag ? type?.displayName ?? type?.name : void 0;
3430
3516
  if (!rawProps) return (0, import_jsx_runtime.jsx)(effectiveType, null, key);
3431
- const workingProps = webTag && originalName ? transformToWebProps(originalName, rawProps) : rawProps;
3517
+ const workingProps = webTag && originalName ? transformToWebProps(originalName, webTag, rawProps) : rawProps;
3432
3518
  const { className, kb: kbProp, __kbachStyles, __kbachClasses } = workingProps;
3433
3519
  const classStr = className ?? kbProp ?? __kbachClasses;
3434
3520
  if (!isNative && isRuntimeCSSDisabled() && classStr && !__kbachStyles) {
@@ -3448,7 +3534,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
3448
3534
  return makeElement(isStaticChildren, effectiveType, { ...passProps2, style: finalStyle2 }, key);
3449
3535
  }
3450
3536
  const config = getConfig();
3451
- const resolved = __kbachStyles ?? (classStr ? resolve(classStr, config.theme, config.darkMode) : {});
3537
+ const resolved = !isWeb && __kbachStyles != null ? __kbachStyles : classStr ? resolve(classStr, config.theme, config.darkMode) : {};
3452
3538
  const { style: userStyle, ...passProps } = omitConsumed(workingProps);
3453
3539
  const { interactive, modeOrResponsive } = bucketMods(resolved);
3454
3540
  if (interactive) {
@@ -3,11 +3,11 @@ import {
3
3
  _invalidateDefaultFontCache,
4
4
  jsx,
5
5
  jsxs
6
- } from "./chunk-KWB2XQSF.mjs";
6
+ } from "./chunk-6PRTRINF.mjs";
7
7
  import {
8
8
  registerWebElement
9
- } from "./chunk-3UUTNNWV.mjs";
10
- import "./chunk-BKSXIWL7.mjs";
9
+ } from "./chunk-7EUNJFX7.mjs";
10
+ import "./chunk-JBV2R655.mjs";
11
11
  export {
12
12
  Fragment,
13
13
  _invalidateDefaultFontCache,
@@ -4,7 +4,7 @@ import {
4
4
  generateClassCSS,
5
5
  setCSSGenMode,
6
6
  splitClassTokens
7
- } from "./chunk-BKSXIWL7.mjs";
7
+ } from "./chunk-JBV2R655.mjs";
8
8
 
9
9
  // src/vite-plugin.ts
10
10
  import { readFileSync, writeFileSync, readdirSync, statSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.5.49",
3
+ "version": "0.5.52",
4
4
  "description": "React / React Native components and hooks for the Kbach framework",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./dist/index.js",