@kbach/react 0.6.1 → 0.6.2
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/{chunk-MPHPB357.mjs → chunk-GRZ6MVIL.mjs} +518 -19
- package/dist/{chunk-6ZORO3BP.mjs → chunk-NWW57Q5Q.mjs} +10 -11
- package/dist/index.d.mts +131 -3
- package/dist/index.d.ts +131 -3
- package/dist/index.js +1 -0
- package/dist/index.mjs +15 -16
- package/dist/jsx-dev-runtime.js +1 -0
- package/dist/jsx-dev-runtime.mjs +3 -3
- package/dist/jsx-runtime.js +1 -0
- package/dist/jsx-runtime.mjs +3 -3
- package/dist/vite-plugin.d.mts +102 -1
- package/dist/vite-plugin.d.ts +102 -1
- package/dist/vite-plugin.mjs +2881 -11
- package/jsx-dev-runtime.js +1 -0
- package/jsx-runtime.js +1 -0
- package/kbach-react.md +1 -8
- package/package.json +3 -3
- package/dist/chunk-36QRQNPL.mjs +0 -528
- package/dist/types-BESBQANS.d.mts +0 -131
- package/dist/types-BESBQANS.d.ts +0 -131
package/jsx-dev-runtime.js
CHANGED
package/jsx-runtime.js
CHANGED
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
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kbach/react",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
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
|
|
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
|
|
44
|
+
"dev": "tsup --watch",
|
|
45
45
|
"test": "vitest run --passWithNoTests",
|
|
46
46
|
"lint": "tsc --noEmit",
|
|
47
47
|
"postinstall": "node scripts/postinstall.js"
|
package/dist/chunk-36QRQNPL.mjs
DELETED
|
@@ -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
|
-
};
|