@kbach/react 0.5.57 → 0.5.59

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.
@@ -7,14 +7,14 @@ import {
7
7
  isNative,
8
8
  isWeb,
9
9
  subscribeGlobalWidth
10
- } from "./chunk-JBV2R655.mjs";
10
+ } from "./chunk-NP4FVE77.mjs";
11
11
 
12
12
  // src/core/darkModeStore.ts
13
13
  var KEY = "__kbach_dark_store__";
14
14
  function getStore() {
15
15
  const g = globalThis;
16
16
  if (!g[KEY]) {
17
- g[KEY] = { isDark: false, lastNotified: false, subscribers: /* @__PURE__ */ new Set() };
17
+ g[KEY] = { isDark: false, subscribers: /* @__PURE__ */ new Set() };
18
18
  }
19
19
  return g[KEY];
20
20
  }
@@ -23,9 +23,8 @@ function syncGlobalDarkMode(isDark) {
23
23
  }
24
24
  function setGlobalDarkMode(isDark) {
25
25
  const store = getStore();
26
+ if (store.isDark === isDark) return;
26
27
  store.isDark = isDark;
27
- if (store.lastNotified === isDark) return;
28
- store.lastNotified = isDark;
29
28
  for (const sub of store.subscribers) sub();
30
29
  }
31
30
  function getGlobalDarkMode() {
@@ -37,6 +36,22 @@ function subscribeGlobalDarkMode(callback) {
37
36
  return () => store.subscribers.delete(callback);
38
37
  }
39
38
 
39
+ // src/useGlobalDarkMode.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
+ function useGlobalDarkMode() {
47
+ return useSyncExternalStore(
48
+ subscribeGlobalDarkMode,
49
+ getGlobalDarkMode,
50
+ () => false
51
+ // SSR: default light
52
+ );
53
+ }
54
+
40
55
  // src/web-substitute.ts
41
56
  var _rnToHtml = {
42
57
  View: "div",
@@ -73,8 +88,8 @@ function getWebTag(type, props) {
73
88
  _cache.set(obj, null);
74
89
  return null;
75
90
  }
76
- if (name === "TextInput" && props) {
77
- const multiline = props.multiline === true || Number(props.numberOfLines) > 1;
91
+ if (name === "TextInput") {
92
+ const multiline = !!props && (props.multiline === true || Number(props.numberOfLines) > 1);
78
93
  return multiline ? "textarea" : "input";
79
94
  }
80
95
  if (_cache.has(obj)) return _cache.get(obj);
@@ -111,8 +126,7 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
111
126
  "shouldRasterizeIOS",
112
127
  "focusable",
113
128
  "hasTVPreferredFocus",
114
- "pointerEvents",
115
- // RN and HTML values differ
129
+ // 'pointerEvents' is handled in transformToWebProps (mapped to CSS style)
116
130
  // Text
117
131
  "selectable",
118
132
  "allowFontScaling",
@@ -223,6 +237,7 @@ function transformToWebProps(originalName, tag, props) {
223
237
  const isTextInput = originalName === "TextInput";
224
238
  const isImage = originalName === "Image" || originalName === "ImageBackground";
225
239
  const isScrollable = originalName === "ScrollView" || originalName === "FlatList" || originalName === "SectionList";
240
+ let pendingStyle = null;
226
241
  for (const [k, v] of Object.entries(props)) {
227
242
  if (_rnOnlyProps.has(k)) continue;
228
243
  if (k === "onPress") {
@@ -267,10 +282,11 @@ function transformToWebProps(originalName, tag, props) {
267
282
  }
268
283
  }
269
284
  if (isScrollable && k === "horizontal") {
270
- if (v) {
271
- const existing = out.style ?? {};
272
- out.style = { display: "flex", flexDirection: "row", overflowX: "auto", ...existing };
273
- }
285
+ if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
286
+ continue;
287
+ }
288
+ if (k === "pointerEvents") {
289
+ if (v === "none" || v === "auto") pendingStyle = { ...pendingStyle ?? {}, pointerEvents: v };
274
290
  continue;
275
291
  }
276
292
  if (isImage) {
@@ -293,7 +309,7 @@ function transformToWebProps(originalName, tag, props) {
293
309
  out.style = { ...existing, objectFit: v };
294
310
  continue;
295
311
  }
296
- if (k === "alt" || k === "defaultSource") continue;
312
+ if (k === "defaultSource") continue;
297
313
  }
298
314
  if (k === "style") {
299
315
  if (Array.isArray(v)) {
@@ -305,27 +321,14 @@ function transformToWebProps(originalName, tag, props) {
305
321
  }
306
322
  out[k] = v;
307
323
  }
324
+ if (pendingStyle) {
325
+ out.style = out.style ? { ...pendingStyle, ...out.style } : pendingStyle;
326
+ }
308
327
  if (isPressable && !out.role) out.role = "button";
309
328
  if (isImage && tag === "img" && out.alt == null) out.alt = "";
310
329
  return out;
311
330
  }
312
331
 
313
- // src/useGlobalDarkMode.ts
314
- import React from "react";
315
- var useSyncExternalStore = React.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
316
- const [, forceUpdate] = React.useReducer((n) => n + 1, 0);
317
- React.useEffect(() => subscribe(forceUpdate), [subscribe]);
318
- return getSnapshot();
319
- };
320
- function useGlobalDarkMode() {
321
- return useSyncExternalStore(
322
- subscribeGlobalDarkMode,
323
- getGlobalDarkMode,
324
- () => false
325
- // SSR: default light
326
- );
327
- }
328
-
329
332
  // src/InteractiveWrapper.tsx
330
333
  import React3, { forwardRef, useState, useCallback, useMemo } from "react";
331
334
 
@@ -446,10 +449,11 @@ var InteractiveWrapper = forwardRef(
446
449
  const handleMouseLeave = useCallback(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
447
450
  const handleFocus = useCallback(chain(onFocus, () => setFocused(true)), [onFocus]);
448
451
  const handleBlur = useCallback(chain(onBlur, () => setFocused(false)), [onBlur]);
452
+ const { children, disabled, checked, ...restForComponent } = rest;
449
453
  const computedStyle = useMemo(
450
454
  () => {
451
455
  if (isWeb) return {};
452
- const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!rest.disabled, checked: !!rest.checked }, breakpoints);
456
+ const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
453
457
  delete s.__divideX;
454
458
  delete s.__divideY;
455
459
  delete s.__divideColor;
@@ -480,20 +484,20 @@ var InteractiveWrapper = forwardRef(
480
484
  }
481
485
  return s;
482
486
  },
483
- [resolvedStyle, isDark, pressed, hovered, focused, width]
484
- // eslint-disable-line react-hooks/exhaustive-deps
487
+ [resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
485
488
  );
486
489
  const skipComputedInline = isWeb || !isNative && typeof Component === "string";
487
490
  const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
488
- const { children, ...restWithoutChildren } = rest;
489
491
  const componentProps = {
490
492
  ref,
491
- ...restWithoutChildren,
493
+ ...restForComponent,
494
+ ...disabled !== void 0 ? { disabled } : {},
495
+ ...checked !== void 0 ? { checked } : {},
492
496
  style: finalStyle,
493
497
  ...!isNative && className ? { className } : {},
494
498
  // onPressIn / onPressOut are React Native-only.
495
499
  // On web, onPointerDown/Up drive the pressed state instead (covers mouse + touch).
496
- ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
500
+ ...!isNative ? { onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onPointerLeave: handlePointerLeave, onPointerCancel: handlePointerLeave } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
497
501
  onMouseEnter: handleMouseEnter,
498
502
  onMouseLeave: handleMouseLeave,
499
503
  onFocus: handleFocus,
@@ -507,6 +511,7 @@ InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
507
511
  export {
508
512
  syncGlobalDarkMode,
509
513
  setGlobalDarkMode,
514
+ useGlobalDarkMode,
510
515
  EMPTY_BREAKPOINTS,
511
516
  useGlobalWidth,
512
517
  useConditionalWidth,
@@ -516,6 +521,5 @@ export {
516
521
  registerWebElement,
517
522
  getWebTag,
518
523
  transformToWebProps,
519
- useGlobalDarkMode,
520
524
  InteractiveWrapper
521
525
  };
@@ -6,12 +6,13 @@ import {
6
6
  transformToWebProps,
7
7
  useConditionalWidth,
8
8
  useGlobalDarkMode
9
- } from "./chunk-VWEYYCBW.mjs";
9
+ } from "./chunk-2MVCYYH5.mjs";
10
10
  import {
11
11
  flatten,
12
12
  getActiveBreakpoints,
13
13
  getConfig,
14
14
  getDefaultFontFamily,
15
+ getGlobalScreens,
15
16
  getInteractiveModifiers,
16
17
  getModeModifiers,
17
18
  getResponsiveModifiers,
@@ -19,8 +20,9 @@ import {
19
20
  isRuntimeCSSDisabled,
20
21
  isWeb,
21
22
  normalizeClassString,
23
+ onConfigChange,
22
24
  resolve
23
- } from "./chunk-JBV2R655.mjs";
25
+ } from "./chunk-NP4FVE77.mjs";
24
26
 
25
27
  // src/jsx-runtime.tsx
26
28
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -34,6 +36,7 @@ var DarkWrapper = React.forwardRef(
34
36
  const needsWidth = hasResponsiveBuckets(resolvedStyle);
35
37
  const width = useConditionalWidth(needsWidth);
36
38
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
39
+ const screens = getGlobalScreens();
37
40
  const isNonStringComponent = typeof Component !== "string";
38
41
  const computedStyle = useMemo(() => {
39
42
  if (isWeb) return {};
@@ -41,7 +44,7 @@ var DarkWrapper = React.forwardRef(
41
44
  stripInternalMarkers(s);
42
45
  if (isNonStringComponent) stripWebOnlyProps(s);
43
46
  return s;
44
- }, [resolvedStyle, isDark, width, isNonStringComponent]);
47
+ }, [resolvedStyle, isDark, width, screens, isNonStringComponent]);
45
48
  const skipComputedInline = isWeb || !isNative && typeof Component === "string";
46
49
  const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
47
50
  const props = { ref, ...rest, style: finalStyle };
@@ -87,6 +90,7 @@ var _lastFontVersion = -1;
87
90
  function _invalidateDefaultFontCache() {
88
91
  _defaultFontVersion++;
89
92
  }
93
+ onConfigChange(_invalidateDefaultFontCache);
90
94
  function getCachedDefaultFont() {
91
95
  if (_lastFontVersion !== _defaultFontVersion) {
92
96
  _cachedDefaultFont = getDefaultFontFamily();
@@ -162,7 +166,7 @@ function stripWebOnlyInlineProps(s) {
162
166
  }
163
167
  }
164
168
  function processElement(type, rawProps, key, isStaticChildren) {
165
- if (typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
169
+ if (type === null || typeof type === "symbol") return makeElement(isStaticChildren, type, rawProps ?? {}, key);
166
170
  const webTag = isWeb ? getWebTag(type, rawProps ?? void 0) : null;
167
171
  const effectiveType = webTag ?? type;
168
172
  const originalName = webTag ? type?.displayName ?? type?.name : void 0;
@@ -178,6 +182,14 @@ function processElement(type, rawProps, key, isStaticChildren) {
178
182
  ...userStyle2 !== void 0 ? { style: userStyle2 } : {}
179
183
  }, key);
180
184
  }
185
+ if (classStr && !__kbachStyles && /^(__[^\s]+\s*)+$/.test(classStr.trim())) {
186
+ const { style: userStyle2, ...passProps2 } = omitConsumed(workingProps);
187
+ return makeElement(isStaticChildren, effectiveType, {
188
+ ...passProps2,
189
+ className: classStr,
190
+ ...userStyle2 !== void 0 ? { style: userStyle2 } : {}
191
+ }, key);
192
+ }
181
193
  if (!classStr && !__kbachStyles) {
182
194
  if (isWeb) return makeElement(isStaticChildren, effectiveType, omitConsumed(workingProps), key);
183
195
  const defaultFont = getCachedDefaultFont();
@@ -220,7 +232,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
220
232
  }
221
233
  return makeElement(isStaticChildren, effectiveType, {
222
234
  ...passProps,
223
- style: finalStyle,
235
+ ...finalStyle !== void 0 ? { style: finalStyle } : {},
224
236
  ...!isNative && classStr ? { className: normalizeClassString(classStr) } : {}
225
237
  }, key);
226
238
  }