@kbach/react 0.6.1 → 0.6.3

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.
@@ -1,2 +1,3 @@
1
+ 'use client';
1
2
  'use strict';
2
3
  module.exports = require('./dist/jsx-dev-runtime.js');
package/jsx-runtime.js CHANGED
@@ -1,2 +1,3 @@
1
+ 'use client';
1
2
  'use strict';
2
3
  module.exports = require('./dist/jsx-runtime.js');
package/kbach-react.md CHANGED
@@ -47,14 +47,7 @@ import { ThemeProvider } from '@kbach/react';
47
47
  ```
48
48
 
49
49
  ### Next.js
50
- tsconfig `jsxImportSource` setup above applies as-is. No Vite plugin for Next.js (webpack/Turbopack) — falls back to runtime CSS injection, which only runs client-side, so expect a brief flash of unstyled content on first paint before hydration. `@kbach/react` ships no `'use client'` directive, so wrap `ThemeProvider` in your own client component before using it in App Router:
51
- ```tsx
52
- 'use client';
53
- import { ThemeProvider } from '@kbach/react';
54
- export function Providers({ children }) {
55
- return <ThemeProvider defaultMode="system">{children}</ThemeProvider>;
56
- }
57
- ```
50
+ tsconfig `jsxImportSource` setup above applies as-is. No Vite plugin for Next.js (webpack/Turbopack) — falls back to runtime CSS injection, which only runs client-side, so expect a brief flash of unstyled content on first paint before hydration. `@kbach/react`'s compiled output ships its own `"use client"` directive, so App Router Server Components can use `className`, `styled()`, hooks, and `<ThemeProvider>` directly, with no manual client wrapper needed.
58
51
 
59
52
  ### React Router
60
53
  Framework mode (v7, SSR) builds with Vite, so the setup above works unchanged — default scan dirs include `app/`. Library mode (client-only) needs no special handling beyond the standard Vite setup.
@@ -435,7 +428,7 @@ mx-auto (centers element)
435
428
  ```
436
429
 
437
430
  Spacing scale (1 unit = 4px):
438
- `px(1) 0 0.5(2) 1(4) 1.5(6) 2(8) 2.5(10) 3(12) 3.5(14) 4(16) 5(20) 6(24) 7(28) 8(32) 9(36) 10(40) 11(44) 12(48) 14(56) 16(64) 20(80) 24(96) 28(112) 32(128) 36(144) 40(160) 44(176) 48(192) 52(208) 56(224) 60(240) 64(256) 72(288) 80(320) 96(384) auto full(100%) 1/2 1/3 2/3 1/4 3/4 screen(100vh) min max fit`
431
+ `px(1) 0 0.5(2) 1(4) 1.5(6) 2(8) 2.5(10) 3(12) 3.5(14) 4(16) 5(20) 6(24) 7(28) 8(32) 9(36) 10(40) 11(44) 12(48) 14(56) 16(64) 20(80) 24(96) 28(112) 32(128) 36(144) 40(160) 44(176) 48(192) 52(208) 56(224) 60(240) 64(256) 72(288) 80(320) 96(384) auto full(100%) 1/2 1/3 2/3 1/4 3/4 screen(100dvh) min max fit`
439
432
 
440
433
  ### Sizing
441
434
  ```
@@ -444,7 +437,9 @@ w-{n} h-{n} size-{n} min-w-{n} min-h-{n} max-w-{n} max-h-{n}
444
437
  Named max-w: none xs(320) sm(384) md(448) lg(512) xl(576) 2xl(672) 3xl(768)
445
438
  4xl(896) 5xl(1024) 6xl(1152) 7xl(1280) prose(65ch)
446
439
 
447
- Screen: w-screen(100vw) h-screen(100vh)
440
+ Screen (dvw/dvh — correct on mobile where browser chrome resizes the
441
+ visible viewport; vw/vh are pinned to the largest viewport and overflow
442
+ behind a shown address bar): w-screen(100dvw) h-screen(100dvh)
448
443
  min-w-screen max-w-screen min-h-screen max-h-screen
449
444
  ```
450
445
 
@@ -524,11 +519,15 @@ opacity-0/5/10/15/20/25/30/40/50/60/70/75/80/90/95/100
524
519
  ```
525
520
 
526
521
  ### Ring
522
+ Web: box-shadow ring. Native: approximated via borderWidth/borderColor
523
+ (no box-shadow on RN) — affects layout there and shares properties with
524
+ `border-*` (last class wins if both are used). `ring-offset-*`/`ring-inset`
525
+ stay web-only, with no native equivalent.
527
526
  ```
528
527
  ring / ring-{n}(0 1 2 4 8)
529
528
  ring-{color}
530
- ring-inset
531
- ring-offset-{n}(0 1 2 4 8)
529
+ ring-inset (web only)
530
+ ring-offset-{n}(0 1 2 4 8) (web only)
532
531
  ```
533
532
 
534
533
  ### Outline
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
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",
@@ -39,9 +39,9 @@
39
39
  }
40
40
  },
41
41
  "scripts": {
42
- "build": "tsup src/index.ts src/jsx-runtime.tsx src/jsx-dev-runtime.tsx src/vite-plugin.ts --format esm,cjs --dts --clean --external vite",
42
+ "build": "tsup",
43
43
  "postbuild": "node -e \"const f=require('fs');f.copyFileSync('src/vite-plugin-client.d.ts','dist/vite-plugin-client.d.ts');f.copyFileSync('src/vite-plugin-client.d.ts','dist/vite-plugin-client.d.mts')\"",
44
- "dev": "tsup src/index.ts src/jsx-runtime.tsx src/jsx-dev-runtime.tsx src/vite-plugin.ts --format esm,cjs --dts --watch --external vite",
44
+ "dev": "tsup --watch",
45
45
  "test": "vitest run --passWithNoTests",
46
46
  "lint": "tsc --noEmit",
47
47
  "postinstall": "node scripts/postinstall.js"
@@ -1,528 +0,0 @@
1
- import {
2
- flatten,
3
- getActiveBreakpoints,
4
- getGlobalWidth,
5
- getInteractiveModifiers,
6
- getResponsiveModifiers,
7
- isNative,
8
- isWeb,
9
- subscribeGlobalWidth
10
- } from "./chunk-MPHPB357.mjs";
11
-
12
- // src/core/darkModeStore.ts
13
- var KEY = "__kbach_dark_store__";
14
- function getStore() {
15
- const g = globalThis;
16
- if (!g[KEY]) {
17
- g[KEY] = { isDark: false, subscribers: /* @__PURE__ */ new Set() };
18
- }
19
- return g[KEY];
20
- }
21
- function syncGlobalDarkMode(isDark) {
22
- getStore().isDark = isDark;
23
- }
24
- function setGlobalDarkMode(isDark) {
25
- const store = getStore();
26
- if (store.isDark === isDark) return;
27
- store.isDark = isDark;
28
- for (const sub of store.subscribers) sub();
29
- }
30
- function getGlobalDarkMode() {
31
- return getStore().isDark;
32
- }
33
- function subscribeGlobalDarkMode(callback) {
34
- const store = getStore();
35
- store.subscribers.add(callback);
36
- return () => store.subscribers.delete(callback);
37
- }
38
-
39
- // src/useSyncExternalStoreShim.ts
40
- import React from "react";
41
- var useSyncExternalStore = React.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
42
- const [, forceUpdate] = React.useReducer((n) => n + 1, 0);
43
- React.useEffect(() => subscribe(forceUpdate), [subscribe]);
44
- return getSnapshot();
45
- };
46
-
47
- // src/useGlobalDarkMode.ts
48
- function useGlobalDarkMode() {
49
- return useSyncExternalStore(
50
- subscribeGlobalDarkMode,
51
- getGlobalDarkMode,
52
- () => false
53
- // SSR: default light
54
- );
55
- }
56
-
57
- // src/shared-utils.ts
58
- function hasResponsiveBuckets(resolved) {
59
- const responsiveMods = getResponsiveModifiers();
60
- for (const key of Object.keys(resolved)) {
61
- if (key === "base") continue;
62
- for (const mod of key.split(":")) {
63
- if (responsiveMods.has(mod)) return true;
64
- }
65
- }
66
- return false;
67
- }
68
- function hasInteractiveBuckets(resolved) {
69
- const interactiveMods = getInteractiveModifiers();
70
- for (const key of Object.keys(resolved)) {
71
- if (key === "base") continue;
72
- for (const mod of key.split(":")) {
73
- if (interactiveMods.has(mod)) return true;
74
- }
75
- }
76
- return false;
77
- }
78
- function chain(original, extra) {
79
- return (...args) => {
80
- original?.(...args);
81
- extra();
82
- };
83
- }
84
- function stripInternalMarkers(s) {
85
- delete s.__divideX;
86
- delete s.__divideY;
87
- delete s.__divideColor;
88
- delete s.__divideStyle;
89
- delete s.__keyframe;
90
- }
91
- function stripWebOnlyProps(s) {
92
- if (s.display === "grid" || s.display === "inline-grid") delete s.display;
93
- delete s.gridTemplateColumns;
94
- delete s.gridTemplateRows;
95
- delete s.gridColumn;
96
- delete s.gridRow;
97
- delete s.gridArea;
98
- delete s.gridColumnStart;
99
- delete s.gridColumnEnd;
100
- delete s.gridRowStart;
101
- delete s.gridRowEnd;
102
- delete s.gridAutoFlow;
103
- delete s.gridAutoColumns;
104
- delete s.gridAutoRows;
105
- delete s.placeItems;
106
- delete s.placeContent;
107
- delete s.justifyItems;
108
- delete s.placeSelf;
109
- delete s.justifySelf;
110
- if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
111
- delete s.position;
112
- }
113
- }
114
-
115
- // src/web-substitute.ts
116
- var _rnToHtml = {
117
- View: "div",
118
- SafeAreaView: "div",
119
- KeyboardAvoidingView: "div",
120
- ScrollView: "div",
121
- VirtualizedList: "div",
122
- FlatList: "div",
123
- SectionList: "div",
124
- Text: "span",
125
- TextInput: "input",
126
- Image: "img",
127
- ImageBackground: "div",
128
- Pressable: "div",
129
- TouchableOpacity: "div",
130
- TouchableHighlight: "div",
131
- TouchableWithoutFeedback: "div",
132
- TouchableNativeFeedback: "div"
133
- };
134
- var _userMap = /* @__PURE__ */ new Map();
135
- var _cache = /* @__PURE__ */ new WeakMap();
136
- function registerWebElement(rnComponent, htmlTag) {
137
- if (typeof rnComponent !== "object" && typeof rnComponent !== "function") return;
138
- _userMap.set(rnComponent, htmlTag);
139
- _cache.delete(rnComponent);
140
- }
141
- function getWebTag(type, props) {
142
- if (typeof type === "string") return null;
143
- if (type === null || typeof type !== "function" && typeof type !== "object") return null;
144
- const obj = type;
145
- if (_userMap.has(obj)) return _userMap.get(obj);
146
- const name = obj.displayName ?? obj.name;
147
- if (!name) {
148
- _cache.set(obj, null);
149
- return null;
150
- }
151
- if (name === "TextInput") {
152
- const multiline = !!props && (props.multiline === true || Number(props.numberOfLines) > 1);
153
- return multiline ? "textarea" : "input";
154
- }
155
- if (_cache.has(obj)) return _cache.get(obj);
156
- const tag = _rnToHtml[name] ?? null;
157
- _cache.set(obj, tag);
158
- return tag;
159
- }
160
- var _rnOnlyProps = /* @__PURE__ */ new Set([
161
- // Interaction
162
- "onLongPress",
163
- "delayLongPress",
164
- "activeOpacity",
165
- "underlayColor",
166
- "hitSlop",
167
- "pressRetentionOffset",
168
- "android_ripple",
169
- "android_disableSound",
170
- "onHoverIn",
171
- "onHoverOut",
172
- "onHoverStart",
173
- "onHoverEnd",
174
- // Layout event
175
- "onLayout",
176
- // Accessibility
177
- "accessible",
178
- "accessibilityState",
179
- "accessibilityLiveRegion",
180
- "importantForAccessibility",
181
- // Platform
182
- "nativeID",
183
- "collapsable",
184
- "needsOffscreenAlphaCompositing",
185
- "renderToHardwareTextureAndroid",
186
- "shouldRasterizeIOS",
187
- "focusable",
188
- "hasTVPreferredFocus",
189
- // 'pointerEvents' is handled in transformToWebProps (mapped to CSS style)
190
- // Text
191
- "selectable",
192
- "allowFontScaling",
193
- "adjustsFontSizeToFit",
194
- "minimumFontScale",
195
- "ellipsizeMode",
196
- "numberOfLines",
197
- "onTextLayout",
198
- "textBreakStrategy",
199
- "lineBreakStrategyIOS",
200
- // TextInput
201
- "multiline",
202
- "resizeMode",
203
- // handled separately
204
- "blurOnSubmit",
205
- "clearButtonMode",
206
- "clearTextOnFocus",
207
- "enablesReturnKeyAutomatically",
208
- "returnKeyType",
209
- "spellCheck",
210
- // ScrollView
211
- "scrollEnabled",
212
- "showsVerticalScrollIndicator",
213
- "showsHorizontalScrollIndicator",
214
- "contentContainerStyle",
215
- // 'horizontal' is handled in transformToWebProps (converted to CSS overflow-x).
216
- "keyboardShouldPersistTaps",
217
- "keyboardDismissMode",
218
- "pagingEnabled",
219
- "scrollEventThrottle",
220
- "decelerationRate",
221
- "bounces",
222
- "alwaysBounceHorizontal",
223
- "alwaysBounceVertical",
224
- "snapToAlignment",
225
- "snapToInterval",
226
- "snapToOffsets",
227
- "removeClippedSubviews",
228
- "overScrollMode",
229
- "stickyHeaderIndices",
230
- "invertStickyHeaders",
231
- "onScrollBeginDrag",
232
- "onScrollEndDrag",
233
- "onMomentumScrollBegin",
234
- "onMomentumScrollEnd",
235
- "contentInset",
236
- "contentInsetAdjustmentBehavior",
237
- "automaticallyAdjustContentInsets",
238
- "automaticallyAdjustsScrollIndicatorInsets",
239
- // expo-image
240
- "contentPosition",
241
- "cachePolicy",
242
- "recyclingKey",
243
- "blurRadius",
244
- "fadeDuration",
245
- "responsivePolicy",
246
- "tintColor",
247
- "allowDownscaling",
248
- "placeholderContentFit",
249
- // FlatList / SectionList
250
- "data",
251
- "renderItem",
252
- "keyExtractor",
253
- "getItemLayout",
254
- "initialScrollIndex",
255
- "initialNumToRender",
256
- "maxToRenderPerBatch",
257
- "windowSize",
258
- "updateCellsBatchingPeriod",
259
- "onEndReached",
260
- "onEndReachedThreshold",
261
- "ListHeaderComponent",
262
- "ListFooterComponent",
263
- "ListEmptyComponent",
264
- "ListHeaderComponentStyle",
265
- "ListFooterComponentStyle",
266
- "ItemSeparatorComponent",
267
- "SectionSeparatorComponent",
268
- "inverted",
269
- "getItem",
270
- "getItemCount"
271
- ]);
272
- var _pressableNames = /* @__PURE__ */ new Set([
273
- "Pressable",
274
- "TouchableOpacity",
275
- "TouchableHighlight",
276
- "TouchableWithoutFeedback",
277
- "TouchableNativeFeedback"
278
- ]);
279
- var _keyboardTypeMap = {
280
- "numeric": "number",
281
- "number-pad": "number",
282
- "decimal-pad": "decimal",
283
- "email-address": "email",
284
- "phone-pad": "tel",
285
- "url": "url"
286
- };
287
- var _resizeModeMap = {
288
- "contain": "contain",
289
- "cover": "cover",
290
- "stretch": "fill",
291
- "center": "none",
292
- "repeat": "none"
293
- };
294
- function transformToWebProps(originalName, tag, props) {
295
- const out = {};
296
- const isPressable = _pressableNames.has(originalName);
297
- const isTextInput = originalName === "TextInput";
298
- const isImage = originalName === "Image" || originalName === "ImageBackground";
299
- const isScrollable = originalName === "ScrollView" || originalName === "FlatList" || originalName === "SectionList";
300
- let pendingStyle = null;
301
- for (const [k, v] of Object.entries(props)) {
302
- if (_rnOnlyProps.has(k)) continue;
303
- if (k === "onPress") {
304
- if (!("onClick" in props)) out.onClick = v;
305
- continue;
306
- }
307
- if (k === "accessibilityLabel") {
308
- if (out["aria-label"] == null) out["aria-label"] = v;
309
- continue;
310
- }
311
- if (k === "accessibilityRole") {
312
- if (out.role == null) out.role = v;
313
- continue;
314
- }
315
- if (k === "testID") {
316
- if (out["data-testid"] == null) out["data-testid"] = v;
317
- continue;
318
- }
319
- if (isTextInput) {
320
- if (k === "onChangeText") {
321
- if (!("onChange" in props)) out.onChange = (e) => v(e.target.value);
322
- continue;
323
- }
324
- if (k === "secureTextEntry") {
325
- if (v && !("type" in props)) out.type = "password";
326
- continue;
327
- }
328
- if (k === "keyboardType") {
329
- if (!("type" in props) && !("secureTextEntry" in props)) {
330
- const mapped = _keyboardTypeMap[v];
331
- if (mapped) out.type = mapped;
332
- }
333
- continue;
334
- }
335
- if (k === "editable") {
336
- if (v === false) out.readOnly = true;
337
- continue;
338
- }
339
- if (k === "maxLength") {
340
- out.maxLength = v;
341
- continue;
342
- }
343
- }
344
- if (isScrollable && k === "horizontal") {
345
- if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
346
- continue;
347
- }
348
- if (k === "pointerEvents") {
349
- if (v === "none" || v === "auto") pendingStyle = { ...pendingStyle ?? {}, pointerEvents: v };
350
- continue;
351
- }
352
- if (isImage) {
353
- if (k === "source") {
354
- if (typeof v === "string") {
355
- out.src = v;
356
- } else if (v && typeof v === "object" && "uri" in v) {
357
- out.src = v.uri;
358
- if (v.headers) out["crossOrigin"] = "anonymous";
359
- }
360
- continue;
361
- }
362
- if (k === "resizeMode") {
363
- pendingStyle = { ...pendingStyle ?? {}, objectFit: _resizeModeMap[v] ?? "cover" };
364
- continue;
365
- }
366
- if (k === "contentFit") {
367
- pendingStyle = { ...pendingStyle ?? {}, objectFit: v };
368
- continue;
369
- }
370
- if (k === "defaultSource") continue;
371
- }
372
- if (k === "style") {
373
- if (Array.isArray(v)) {
374
- out.style = Object.assign({}, ...v.filter(Boolean));
375
- } else if (v != null) {
376
- out.style = v;
377
- }
378
- continue;
379
- }
380
- out[k] = v;
381
- }
382
- if (pendingStyle) {
383
- out.style = out.style ? { ...pendingStyle, ...out.style } : pendingStyle;
384
- }
385
- if (isPressable && !out.role) out.role = "button";
386
- if (isImage && tag === "img" && out.alt == null) out.alt = "";
387
- return out;
388
- }
389
-
390
- // src/InteractiveWrapper.tsx
391
- import React2, { forwardRef, useState, useCallback, useMemo } from "react";
392
-
393
- // src/useGlobalWidth.ts
394
- var NOOP_SUB = (_) => () => {
395
- };
396
- var ZERO_SNAP = () => 0;
397
- var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
398
- var _webListeners = null;
399
- var _webRaf = 0;
400
- function _webResizeHandler() {
401
- cancelAnimationFrame(_webRaf);
402
- _webRaf = requestAnimationFrame(() => {
403
- if (_webListeners) for (const cb of _webListeners) cb();
404
- });
405
- }
406
- function subscribeWebWidth(cb) {
407
- if (typeof window === "undefined") return () => {
408
- };
409
- if (!_webListeners) {
410
- _webListeners = /* @__PURE__ */ new Set();
411
- window.addEventListener("resize", _webResizeHandler);
412
- }
413
- _webListeners.add(cb);
414
- return () => {
415
- _webListeners.delete(cb);
416
- if (_webListeners.size === 0) {
417
- window.removeEventListener("resize", _webResizeHandler);
418
- cancelAnimationFrame(_webRaf);
419
- _webListeners = null;
420
- }
421
- };
422
- }
423
- function getWebWidth() {
424
- return typeof window !== "undefined" ? window.innerWidth : 0;
425
- }
426
- function useGlobalWidth() {
427
- return useSyncExternalStore(
428
- isWeb ? subscribeWebWidth : subscribeGlobalWidth,
429
- isWeb ? getWebWidth : getGlobalWidth,
430
- ZERO_SNAP
431
- );
432
- }
433
- function useConditionalWidth(active) {
434
- return useSyncExternalStore(
435
- active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
436
- active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
437
- ZERO_SNAP
438
- );
439
- }
440
-
441
- // src/InteractiveWrapper.tsx
442
- var InteractiveWrapper = forwardRef(
443
- function InteractiveWrapper2({
444
- Component,
445
- resolvedStyle,
446
- className,
447
- style: styleProp,
448
- onPressIn,
449
- onPressOut,
450
- onPointerDown,
451
- onPointerUp,
452
- onPointerLeave,
453
- onPointerCancel,
454
- onMouseEnter,
455
- onMouseLeave,
456
- onFocus,
457
- onBlur,
458
- ...rest
459
- }, ref) {
460
- const isDark = useGlobalDarkMode();
461
- const needsWidth = hasResponsiveBuckets(resolvedStyle);
462
- const width = useConditionalWidth(needsWidth);
463
- const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
464
- const [pressed, setPressed] = useState(false);
465
- const [hovered, setHovered] = useState(false);
466
- const [focused, setFocused] = useState(false);
467
- const handlePressIn = useCallback(chain(onPressIn, () => setPressed(true)), [onPressIn]);
468
- const handlePressOut = useCallback(chain(onPressOut, () => setPressed(false)), [onPressOut]);
469
- const handlePointerDown = useCallback(chain(onPointerDown, () => setPressed(true)), [onPointerDown]);
470
- const handlePointerUp = useCallback(chain(onPointerUp, () => setPressed(false)), [onPointerUp]);
471
- const handlePointerLeave = useCallback(chain(onPointerLeave, () => setPressed(false)), [onPointerLeave]);
472
- const handlePointerCancel = useCallback(chain(onPointerCancel, () => setPressed(false)), [onPointerCancel]);
473
- const handleMouseEnter = useCallback(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
474
- const handleMouseLeave = useCallback(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
475
- const handleFocus = useCallback(chain(onFocus, () => setFocused(true)), [onFocus]);
476
- const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
477
- const { children, disabled, checked, ...restForComponent } = rest;
478
- const computedStyle = useMemo(
479
- () => {
480
- if (isWeb) return {};
481
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
482
- stripInternalMarkers(s);
483
- if (typeof Component !== "string") stripWebOnlyProps(s);
484
- return s;
485
- },
486
- [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
487
- );
488
- const skipComputedInline = isWeb || !isNative && typeof Component === "string";
489
- const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
490
- const componentProps = {
491
- ref,
492
- ...restForComponent,
493
- ...disabled !== void 0 ? { disabled } : {},
494
- ...checked !== void 0 ? { checked } : {},
495
- style: finalStyle,
496
- ...!isNative && className ? { className } : {},
497
- // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
498
- // but onPressIn/onPressOut are still forwarded unchanged — react-native-web components
499
- // (and any component that accepts both prop names) depend on receiving them directly.
500
- ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerCancel, onPressIn, onPressOut } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
501
- onMouseEnter: handleMouseEnter,
502
- onMouseLeave: handleMouseLeave,
503
- onFocus: handleFocus,
504
- onBlur: handleBlur
505
- };
506
- return Array.isArray(children) ? React2.createElement(Component, componentProps, ...children) : React2.createElement(Component, componentProps, children);
507
- }
508
- );
509
- InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
510
-
511
- export {
512
- syncGlobalDarkMode,
513
- setGlobalDarkMode,
514
- useSyncExternalStore,
515
- useGlobalDarkMode,
516
- EMPTY_BREAKPOINTS,
517
- useGlobalWidth,
518
- useConditionalWidth,
519
- hasResponsiveBuckets,
520
- hasInteractiveBuckets,
521
- chain,
522
- stripInternalMarkers,
523
- stripWebOnlyProps,
524
- registerWebElement,
525
- getWebTag,
526
- transformToWebProps,
527
- InteractiveWrapper
528
- };