@platform-blocks/ui 0.7.2 → 0.8.0

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/lib/cjs/index.js CHANGED
@@ -486,8 +486,10 @@ function createTheme(themeOverride) {
486
486
 
487
487
  // Debug flag (only logs when in dev mode AND explicit debug env flag is set)
488
488
  typeof __DEV__ !== 'undefined' && __DEV__ && !!process.env.EXPO_PUBLIC_DEBUG;
489
- // Theme Context
489
+ // Full theme context (backwards compatible)
490
490
  const PlatformBlocksThemeContext = React.createContext(null);
491
+ const ThemeVisualsContext = React.createContext(null);
492
+ const ThemeLayoutContext = React.createContext(null);
491
493
  function PlatformBlocksThemeProvider({ theme, inherit = true, children }) {
492
494
  const parentTheme = useTheme();
493
495
  const mergedTheme = React.useMemo(() => {
@@ -507,11 +509,45 @@ function PlatformBlocksThemeProvider({ theme, inherit = true, children }) {
507
509
  // debugLog('[PlatformBlocksThemeProvider] Creating merged theme with override, colorScheme:', result.colorScheme);
508
510
  return result;
509
511
  }, [theme, parentTheme, inherit]);
512
+ // Derive stable sub-context values — only create new objects when the
513
+ // relevant subset of the theme actually changes.
514
+ const visuals = React.useMemo(() => ({
515
+ colorScheme: mergedTheme.colorScheme,
516
+ primaryColor: mergedTheme.primaryColor,
517
+ colors: mergedTheme.colors,
518
+ text: mergedTheme.text,
519
+ backgrounds: mergedTheme.backgrounds,
520
+ states: mergedTheme.states,
521
+ }), [
522
+ mergedTheme.colorScheme,
523
+ mergedTheme.primaryColor,
524
+ mergedTheme.colors,
525
+ mergedTheme.text,
526
+ mergedTheme.backgrounds,
527
+ mergedTheme.states,
528
+ ]);
529
+ const layout = React.useMemo(() => ({
530
+ fontFamily: mergedTheme.fontFamily,
531
+ fontSizes: mergedTheme.fontSizes,
532
+ spacing: mergedTheme.spacing,
533
+ radii: mergedTheme.radii,
534
+ shadows: mergedTheme.shadows,
535
+ breakpoints: mergedTheme.breakpoints,
536
+ designTokens: mergedTheme.designTokens,
537
+ }), [
538
+ mergedTheme.fontFamily,
539
+ mergedTheme.fontSizes,
540
+ mergedTheme.spacing,
541
+ mergedTheme.radii,
542
+ mergedTheme.shadows,
543
+ mergedTheme.breakpoints,
544
+ mergedTheme.designTokens,
545
+ ]);
510
546
  // debugLog('[PlatformBlocksThemeProvider] Rendering with theme colorScheme:', mergedTheme.colorScheme);
511
- return (jsxRuntime.jsx(PlatformBlocksThemeContext.Provider, { value: mergedTheme, children: children }));
547
+ return (jsxRuntime.jsx(PlatformBlocksThemeContext.Provider, { value: mergedTheme, children: jsxRuntime.jsx(ThemeVisualsContext.Provider, { value: visuals, children: jsxRuntime.jsx(ThemeLayoutContext.Provider, { value: layout, children: children }) }) }));
512
548
  }
513
549
  /**
514
- * Hook to access the current theme
550
+ * Hook to access the current theme (full object — backwards compatible)
515
551
  */
516
552
  function useTheme() {
517
553
  const theme = React.useContext(PlatformBlocksThemeContext);
@@ -521,6 +557,45 @@ function useTheme() {
521
557
  }
522
558
  return theme;
523
559
  }
560
+ /**
561
+ * Granular hook: subscribe only to visual / color-related properties.
562
+ * Components using this will NOT re-render when layout tokens change.
563
+ */
564
+ function useThemeVisuals() {
565
+ const visuals = React.useContext(ThemeVisualsContext);
566
+ if (!visuals) {
567
+ const t = DEFAULT_THEME;
568
+ return {
569
+ colorScheme: t.colorScheme,
570
+ primaryColor: t.primaryColor,
571
+ colors: t.colors,
572
+ text: t.text,
573
+ backgrounds: t.backgrounds,
574
+ states: t.states,
575
+ };
576
+ }
577
+ return visuals;
578
+ }
579
+ /**
580
+ * Granular hook: subscribe only to layout / token properties.
581
+ * Components using this will NOT re-render when colors change.
582
+ */
583
+ function useThemeLayout() {
584
+ const layout = React.useContext(ThemeLayoutContext);
585
+ if (!layout) {
586
+ const t = DEFAULT_THEME;
587
+ return {
588
+ fontFamily: t.fontFamily,
589
+ fontSizes: t.fontSizes,
590
+ spacing: t.spacing,
591
+ radii: t.radii,
592
+ shadows: t.shadows,
593
+ breakpoints: t.breakpoints,
594
+ designTokens: t.designTokens,
595
+ };
596
+ }
597
+ return layout;
598
+ }
524
599
 
525
600
  /**
526
601
  * Component that injects CSS variables based on the current theme
@@ -1526,6 +1601,58 @@ function useKeyboardManagerOptional() {
1526
1601
  return React.useContext(KeyboardManagerContext);
1527
1602
  }
1528
1603
 
1604
+ const BREAKPOINTS = {
1605
+ xs: 480, // Extra small devices
1606
+ sm: 576, // Small devices (landscape phones)
1607
+ md: 768, // Medium devices (tablets)
1608
+ lg: 992, // Large devices (desktops)
1609
+ xl: 1200, // Extra large devices (large desktops)
1610
+ };
1611
+ // Shared breakpoint context — a single resize listener feeds all consumers
1612
+ const BreakpointContext = React.createContext(null);
1613
+ function computeBreakpoint() {
1614
+ let width;
1615
+ if (reactNative.Platform.OS === 'web') {
1616
+ width = window.innerWidth;
1617
+ }
1618
+ else {
1619
+ width = reactNative.Dimensions.get('window').width;
1620
+ }
1621
+ if (width >= BREAKPOINTS.xl)
1622
+ return 'xl';
1623
+ if (width >= BREAKPOINTS.lg)
1624
+ return 'lg';
1625
+ if (width >= BREAKPOINTS.md)
1626
+ return 'md';
1627
+ if (width >= BREAKPOINTS.sm)
1628
+ return 'sm';
1629
+ if (width >= BREAKPOINTS.xs)
1630
+ return 'xs';
1631
+ return 'base';
1632
+ }
1633
+ /**
1634
+ * Provider that maintains a single resize / Dimensions listener and shares
1635
+ * the current breakpoint with all descendants via context.
1636
+ * Mount once near the root of the app (PlatformBlocksProvider does this automatically).
1637
+ */
1638
+ function BreakpointProvider({ children }) {
1639
+ const [breakpoint, setBreakpoint] = React.useState(computeBreakpoint);
1640
+ React.useEffect(() => {
1641
+ const update = () => {
1642
+ setBreakpoint(computeBreakpoint());
1643
+ };
1644
+ if (reactNative.Platform.OS === 'web') {
1645
+ window.addEventListener('resize', update);
1646
+ return () => window.removeEventListener('resize', update);
1647
+ }
1648
+ else {
1649
+ const subscription = reactNative.Dimensions.addEventListener('change', update);
1650
+ return () => subscription === null || subscription === void 0 ? void 0 : subscription.remove();
1651
+ }
1652
+ }, []);
1653
+ return React.createElement(BreakpointContext.Provider, { value: breakpoint }, children);
1654
+ }
1655
+
1529
1656
  /**
1530
1657
  * Global Spotlight Hook for Direct State Access
1531
1658
  *
@@ -1886,26 +2013,33 @@ function useSpotlightStoreInstance() {
1886
2013
  query: '',
1887
2014
  selectedIndex: -1
1888
2015
  });
1889
- const store = {
2016
+ const open = React.useCallback(() => setState(prev => ({ ...prev, opened: true })), []);
2017
+ const close = React.useCallback(() => setState(prev => ({ ...prev, opened: false, query: '', selectedIndex: -1 })), []);
2018
+ const toggle = React.useCallback(() => setState(prev => ({ ...prev, opened: !prev.opened })), []);
2019
+ const setQuery = React.useCallback((query) => setState(prev => ({ ...prev, query })), []);
2020
+ const setSelectedIndex = React.useCallback((selectedIndex) => setState(prev => ({ ...prev, selectedIndex })), []);
2021
+ const navigateUp = React.useCallback(() => setState(prev => ({ ...prev, selectedIndex: prev.selectedIndex > 0 ? prev.selectedIndex - 1 : -1 })), []);
2022
+ const navigateDown = React.useCallback((maxIndex = 0) => setState(prev => ({ ...prev, selectedIndex: prev.selectedIndex < maxIndex - 1 ? prev.selectedIndex + 1 : maxIndex - 1 })), []);
2023
+ const store = React.useMemo(() => ({
1890
2024
  state,
1891
- open: () => setState(prev => ({ ...prev, opened: true })),
1892
- close: () => setState(prev => ({ ...prev, opened: false, query: '', selectedIndex: -1 })),
1893
- toggle: () => setState(prev => ({ ...prev, opened: !prev.opened })),
1894
- setQuery: (query) => setState(prev => ({ ...prev, query })),
1895
- setSelectedIndex: (selectedIndex) => setState(prev => ({ ...prev, selectedIndex })),
1896
- navigateUp: () => setState(prev => ({ ...prev, selectedIndex: prev.selectedIndex > 0 ? prev.selectedIndex - 1 : -1 })),
1897
- navigateDown: (maxIndex = 0) => setState(prev => ({ ...prev, selectedIndex: prev.selectedIndex < maxIndex - 1 ? prev.selectedIndex + 1 : maxIndex - 1 })),
1898
- };
1899
- const actions = {
1900
- state: store.state,
1901
- open: store.open,
1902
- close: store.close,
1903
- toggle: store.toggle,
1904
- setQuery: store.setQuery,
1905
- setSelectedIndex: store.setSelectedIndex,
1906
- navigateUp: store.navigateUp,
1907
- navigateDown: store.navigateDown,
1908
- };
2025
+ open,
2026
+ close,
2027
+ toggle,
2028
+ setQuery,
2029
+ setSelectedIndex,
2030
+ navigateUp,
2031
+ navigateDown,
2032
+ }), [state, open, close, toggle, setQuery, setSelectedIndex, navigateUp, navigateDown]);
2033
+ const actions = React.useMemo(() => ({
2034
+ state,
2035
+ open,
2036
+ close,
2037
+ toggle,
2038
+ setQuery,
2039
+ setSelectedIndex,
2040
+ navigateUp,
2041
+ navigateDown,
2042
+ }), [state, open, close, toggle, setQuery, setSelectedIndex, navigateUp, navigateDown]);
1909
2043
  return [store, actions];
1910
2044
  }
1911
2045
  const createSpotlightStore = useSpotlightStoreInstance;
@@ -3774,13 +3908,27 @@ function factory(ui, options = {}) {
3774
3908
  /**
3775
3909
  * Factory function for creating polymorphic PlatformBlocks components
3776
3910
  */
3777
- function polymorphicFactory(ui) {
3778
- const Component = React.forwardRef(ui);
3911
+ function polymorphicFactory(ui, options = {}) {
3912
+ const { displayName, memo: shouldMemo = true, arePropsEqual } = options;
3913
+ const ForwardComponent = React.forwardRef(ui);
3914
+ if (displayName) {
3915
+ ForwardComponent.displayName = displayName;
3916
+ }
3917
+ const MemoizedComponent = shouldMemo
3918
+ ? React.memo(ForwardComponent, arePropsEqual)
3919
+ : ForwardComponent;
3920
+ const Component = MemoizedComponent;
3779
3921
  Component.withProps = (fixedProps) => {
3780
- const Extended = React.forwardRef((props, ref) => (jsxRuntime.jsx(Component, { ...fixedProps, ...props, ref: ref })));
3781
- Extended.extend = Component.extend;
3782
- Extended.displayName = `WithProps(${Component.displayName})`;
3783
- return Extended;
3922
+ const Extended = React.forwardRef((props, ref) => (jsxRuntime.jsx(ForwardComponent, { ...fixedProps, ...props, ref: ref })));
3923
+ const baseName = ForwardComponent.displayName || ui.name || 'PolymorphicComponent';
3924
+ Extended.displayName = `WithProps(${baseName})`;
3925
+ const ExtendedComponent = shouldMemo
3926
+ ? React.memo(Extended, arePropsEqual)
3927
+ : Extended;
3928
+ const Result = ExtendedComponent;
3929
+ Result.extend = Component.extend;
3930
+ Result.withProps = Component.withProps;
3931
+ return Result;
3784
3932
  };
3785
3933
  Component.extend = ((input) => input);
3786
3934
  return Component;
@@ -6959,10 +7107,10 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6959
7107
  }, [shouldClose]);
6960
7108
  const isDark = theme.colorScheme === 'dark';
6961
7109
  const surfaceColor = isDark ? theme.backgrounds.surface : '#FFFFFF';
6962
- isDark ? theme.colors.gray[6] : '#E1E3E6';
7110
+ const borderColor = isDark ? theme.colors.gray[6] : '#E1E3E6';
6963
7111
  const headerBg = surfaceColor;
6964
7112
  const contentBg = surfaceColor;
6965
- const dynamicStyles = reactNative.StyleSheet.create({
7113
+ const dynamicStyles = React.useMemo(() => reactNative.StyleSheet.create({
6966
7114
  backdrop: {
6967
7115
  ...reactNative.StyleSheet.absoluteFillObject,
6968
7116
  backgroundColor: variant === 'fullscreen' ? 'transparent' : 'rgba(0, 0, 0, 0.5)',
@@ -7072,7 +7220,9 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
7072
7220
  msUserSelect: 'none',
7073
7221
  }),
7074
7222
  },
7075
- });
7223
+ }), [variant, contentBg, resolvedRadius, resolvedMaxHeight, bottomSheetMaxWidth, defaultModalMaxWidth,
7224
+ modalEffectiveWidth, screenWidth, horizontalMargin, insets.top, insets.bottom,
7225
+ headerBg, borderColor, isRTL, isDark, theme.colors.gray, title]);
7076
7226
  // Animated styles using reanimated
7077
7227
  const backdropAnimatedStyle = Animated.useAnimatedStyle(() => {
7078
7228
  const opacity = backdropOpacity.value;
@@ -7840,12 +7990,13 @@ const TitleRegistryProvider = ({ children }) => {
7840
7990
  const clearTitles = React.useCallback(() => {
7841
7991
  setTitles([]);
7842
7992
  }, []);
7843
- return (jsxRuntime.jsx(TitleRegistryContext.Provider, { value: {
7844
- titles,
7845
- registerTitle,
7846
- unregisterTitle,
7847
- clearTitles
7848
- }, children: children }));
7993
+ const value = React.useMemo(() => ({
7994
+ titles,
7995
+ registerTitle,
7996
+ unregisterTitle,
7997
+ clearTitles
7998
+ }), [titles, registerTitle, unregisterTitle, clearTitles]);
7999
+ return (jsxRuntime.jsx(TitleRegistryContext.Provider, { value: value, children: children }));
7849
8000
  };
7850
8001
 
7851
8002
  const DEFAULT_SELECTOR = 'h1, h2, h3, h4, h5, h6';
@@ -8172,14 +8323,97 @@ function createMask(definition) {
8172
8323
  })
8173
8324
  });
8174
8325
 
8326
+ function useMaskedInput(options) {
8327
+ const { mask: maskDefinition, initialValue = '', onValueChange, onUnmaskedValueChange } = options;
8328
+ // Create mask function if needed
8329
+ const maskRef = React.useRef(typeof maskDefinition === 'function' || 'applyMask' in maskDefinition
8330
+ ? maskDefinition
8331
+ : createMask(maskDefinition));
8332
+ const mask = maskRef.current;
8333
+ // Initialize state
8334
+ const initialResult = mask.applyMask(initialValue);
8335
+ const [state, setState] = React.useState({
8336
+ value: initialResult.value,
8337
+ unmaskedValue: initialResult.unmaskedValue,
8338
+ isComplete: initialResult.isComplete,
8339
+ cursorPosition: initialResult.cursorPosition,
8340
+ previousValue: initialResult.value
8341
+ });
8342
+ const selectionRef = React.useRef({ start: 0, end: 0 });
8343
+ const updateState = React.useCallback((newResult) => {
8344
+ setState(prevState => {
8345
+ if (prevState.value === newResult.value &&
8346
+ prevState.unmaskedValue === newResult.unmaskedValue &&
8347
+ prevState.isComplete === newResult.isComplete &&
8348
+ prevState.cursorPosition === newResult.cursorPosition) {
8349
+ return prevState;
8350
+ }
8351
+ return {
8352
+ value: newResult.value,
8353
+ unmaskedValue: newResult.unmaskedValue,
8354
+ isComplete: newResult.isComplete,
8355
+ cursorPosition: newResult.cursorPosition,
8356
+ previousValue: prevState.value
8357
+ };
8358
+ });
8359
+ }, []);
8360
+ // Handle callbacks in useEffect to avoid calling them during render
8361
+ const prevUnmaskedValueRef = React.useRef(state.unmaskedValue);
8362
+ React.useEffect(() => {
8363
+ if (state.unmaskedValue !== prevUnmaskedValueRef.current) {
8364
+ prevUnmaskedValueRef.current = state.unmaskedValue;
8365
+ const result = {
8366
+ value: state.value,
8367
+ unmaskedValue: state.unmaskedValue,
8368
+ isComplete: state.isComplete,
8369
+ cursorPosition: state.cursorPosition
8370
+ };
8371
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(result);
8372
+ onUnmaskedValueChange === null || onUnmaskedValueChange === void 0 ? void 0 : onUnmaskedValueChange(state.unmaskedValue, result);
8373
+ }
8374
+ }, [state.value, state.unmaskedValue, state.isComplete, state.cursorPosition, onValueChange, onUnmaskedValueChange]);
8375
+ const handleChangeText = React.useCallback((text) => {
8376
+ const result = mask.processInput(text, state.previousValue, selectionRef.current.start);
8377
+ updateState(result);
8378
+ }, [mask, state.previousValue, updateState]);
8379
+ const handleSelectionChange = React.useCallback((selection) => {
8380
+ selectionRef.current = selection;
8381
+ }, []);
8382
+ const reset = React.useCallback(() => {
8383
+ const result = mask.applyMask(initialValue);
8384
+ updateState(result);
8385
+ }, [mask, initialValue, updateState]);
8386
+ const setValue = React.useCallback((value) => {
8387
+ const result = mask.applyMask(value);
8388
+ updateState(result);
8389
+ }, [mask, updateState]);
8390
+ const setUnmaskedValue = React.useCallback((unmaskedValue) => {
8391
+ const result = mask.applyMask(unmaskedValue);
8392
+ updateState(result);
8393
+ }, [mask, updateState]);
8394
+ return {
8395
+ value: state.value,
8396
+ unmaskedValue: state.unmaskedValue,
8397
+ isComplete: state.isComplete,
8398
+ handleChangeText,
8399
+ handleSelectionChange,
8400
+ cursorPosition: state.cursorPosition,
8401
+ reset,
8402
+ setValue,
8403
+ setUnmaskedValue
8404
+ };
8405
+ }
8406
+
8175
8407
  const useTitleRegistration = (options) => {
8176
8408
  const registry = useTitleRegistryOptional();
8177
8409
  const elementRef = React.useRef(null);
8178
8410
  const { text, order, id: providedId, autoRegister = true } = options;
8179
8411
  // Generate ID from text if not provided
8180
8412
  const id = providedId || text.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
8413
+ const registerTitle = registry === null || registry === void 0 ? void 0 : registry.registerTitle;
8414
+ const unregisterTitle = registry === null || registry === void 0 ? void 0 : registry.unregisterTitle;
8181
8415
  React.useEffect(() => {
8182
- if (!registry || !autoRegister || !text)
8416
+ if (!registerTitle || !unregisterTitle || !autoRegister || !text)
8183
8417
  return;
8184
8418
  const titleItem = {
8185
8419
  id,
@@ -8187,11 +8421,11 @@ const useTitleRegistration = (options) => {
8187
8421
  order,
8188
8422
  ref: elementRef,
8189
8423
  };
8190
- registry.registerTitle(titleItem);
8424
+ registerTitle(titleItem);
8191
8425
  return () => {
8192
- registry.unregisterTitle(id);
8426
+ unregisterTitle(id);
8193
8427
  };
8194
- }, [registry, id, text, order, autoRegister]);
8428
+ }, [registerTitle, unregisterTitle, id, text, order, autoRegister]);
8195
8429
  return { elementRef, id };
8196
8430
  };
8197
8431
 
@@ -9460,7 +9694,7 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
9460
9694
  // Reset selection when query changes
9461
9695
  React.useEffect(() => {
9462
9696
  currentStore.setSelectedIndex(-1);
9463
- }, [query, currentStore]);
9697
+ }, [query, currentStore.setSelectedIndex]);
9464
9698
  const handleNavigateUp = () => {
9465
9699
  if (!flatActions.length)
9466
9700
  return;
@@ -10027,7 +10261,7 @@ function PlatformBlocksProvider({ children, theme, inherit = true, withCSSVariab
10027
10261
  if (directionConfig) {
10028
10262
  enhancedTree = (jsxRuntime.jsx(DirectionProvider, { ...directionConfig, children: enhancedTree }));
10029
10263
  }
10030
- return (jsxRuntime.jsx(I18nBoundary, { locale: locale, fallbackLocale: fallbackLocale, resources: i18nStore, children: enhancedTree }));
10264
+ return (jsxRuntime.jsx(I18nBoundary, { locale: locale, fallbackLocale: fallbackLocale, resources: i18nStore, children: jsxRuntime.jsx(BreakpointProvider, { children: enhancedTree }) }));
10031
10265
  }
10032
10266
  PlatformBlocksProvider.displayName = 'PlatformBlocksProvider';
10033
10267
 
@@ -10762,7 +10996,9 @@ function resolveResponsiveProp(value, width, breakpoints = DEFAULT_BREAKPOINTS)
10762
10996
  const DEFAULT_EXTRA_SCROLL_HEIGHT = 24;
10763
10997
  const KeyboardAwareLayout = React.forwardRef((props, ref) => {
10764
10998
  var _a, _b;
10765
- const { children, behavior, keyboardVerticalOffset = 0, enabled = true, scrollable = true, extraScrollHeight = DEFAULT_EXTRA_SCROLL_HEIGHT, style, contentContainerStyle, keyboardShouldPersistTaps = 'handled', scrollRef, scrollViewProps, ...rest } = props;
10999
+ const { children, behavior, keyboardVerticalOffset = 0, enabled = true, scrollable = true, extraScrollHeight = DEFAULT_EXTRA_SCROLL_HEIGHT, style, contentContainerStyle, keyboardShouldPersistTaps = 'handled', scrollRef, scrollViewProps,
11000
+ // Native ScrollView passthrough props
11001
+ scrollEnabled, bounces, onScroll, scrollEventThrottle, onMomentumScrollBegin, onMomentumScrollEnd, showsVerticalScrollIndicator, showsHorizontalScrollIndicator, decelerationRate, overScrollMode: overScrollModeProp, refreshControl, ...rest } = props;
10766
11002
  const { spacingProps, otherProps } = extractSpacingProps(rest);
10767
11003
  const spacingStyles = getSpacingStyles(spacingProps);
10768
11004
  const keyboard = useKeyboardManagerOptional();
@@ -10800,7 +11036,7 @@ const KeyboardAwareLayout = React.forwardRef((props, ref) => {
10800
11036
  }
10801
11037
  return stylesArray;
10802
11038
  }, [spacingStyles, style]);
10803
- return (jsxRuntime.jsx(reactNative.KeyboardAvoidingView, { ref: ref, behavior: resolvedBehavior, keyboardVerticalOffset: keyboardVerticalOffset, enabled: enabled, style: containerStyles, ...otherProps, children: scrollable ? (jsxRuntime.jsx(reactNative.ScrollView, { ref: scrollRef, contentContainerStyle: contentStyles, keyboardShouldPersistTaps: keyboardShouldPersistTaps, showsVerticalScrollIndicator: false, overScrollMode: "never", ...restScrollViewProps, children: children })) : (jsxRuntime.jsx(reactNative.View, { style: contentStyles, children: children })) }));
11039
+ return (jsxRuntime.jsx(reactNative.KeyboardAvoidingView, { ref: ref, behavior: resolvedBehavior, keyboardVerticalOffset: keyboardVerticalOffset, enabled: enabled, style: containerStyles, ...otherProps, children: scrollable ? (jsxRuntime.jsx(reactNative.ScrollView, { ref: scrollRef, contentContainerStyle: contentStyles, keyboardShouldPersistTaps: keyboardShouldPersistTaps, showsVerticalScrollIndicator: showsVerticalScrollIndicator !== null && showsVerticalScrollIndicator !== void 0 ? showsVerticalScrollIndicator : false, showsHorizontalScrollIndicator: showsHorizontalScrollIndicator, overScrollMode: overScrollModeProp !== null && overScrollModeProp !== void 0 ? overScrollModeProp : 'never', scrollEnabled: scrollEnabled, bounces: bounces, onScroll: onScroll, scrollEventThrottle: scrollEventThrottle, onMomentumScrollBegin: onMomentumScrollBegin, onMomentumScrollEnd: onMomentumScrollEnd, decelerationRate: decelerationRate, refreshControl: refreshControl, ...restScrollViewProps, children: children })) : (jsxRuntime.jsx(reactNative.View, { style: contentStyles, children: children })) }));
10804
11040
  });
10805
11041
  KeyboardAwareLayout.displayName = 'KeyboardAwareLayout';
10806
11042
  const styles$d = reactNative.StyleSheet.create({
@@ -10853,18 +11089,41 @@ const DefaultItemRenderer = ({ item, index, gap }) => {
10853
11089
  const Masonry = factory((props, ref) => {
10854
11090
  // const { width } = useWindowDimensions();
10855
11091
  const { spacingProps, otherProps } = extractSpacingProps(props);
10856
- const { data = [], numColumns = 2, gap = 'sm', optimizeItemArrangement = true, renderItem, contentContainerStyle, style, testID, loading = false, emptyContent, flashListProps = {}, ...restProps } = otherProps;
11092
+ const { data = [], numColumns = 2, gap = 'sm', optimizeItemArrangement = true, renderItem, contentContainerStyle, style, testID, loading = false, emptyContent, flashListProps = {},
11093
+ // Native FlashList passthrough props
11094
+ onEndReached, onEndReachedThreshold, onViewableItemsChanged, scrollEnabled, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, estimatedItemSize, refreshControl, onScroll, scrollEventThrottle, ...restProps } = otherProps;
10857
11095
  const resolvedGap = getSpacing(gap);
10858
11096
  const spacingStyle = getSpacingStyles(spacingProps);
10859
11097
  // FlashList performance hints (overridable via flashListProps). Use loose typing to avoid version/type mismatches.
10860
11098
  const finalFlashListProps = React.useMemo(() => {
10861
11099
  const p = { ...flashListProps };
10862
11100
  if (p.estimatedItemSize == null)
10863
- p.estimatedItemSize = 180;
11101
+ p.estimatedItemSize = estimatedItemSize !== null && estimatedItemSize !== void 0 ? estimatedItemSize : 180;
10864
11102
  if (p.keyExtractor == null)
10865
11103
  p.keyExtractor = (item) => item.id;
11104
+ // Merge first-class passthrough props (explicit flashListProps overrides these)
11105
+ if (onEndReached !== undefined && p.onEndReached == null)
11106
+ p.onEndReached = onEndReached;
11107
+ if (onEndReachedThreshold !== undefined && p.onEndReachedThreshold == null)
11108
+ p.onEndReachedThreshold = onEndReachedThreshold;
11109
+ if (onViewableItemsChanged !== undefined && p.onViewableItemsChanged == null)
11110
+ p.onViewableItemsChanged = onViewableItemsChanged;
11111
+ if (scrollEnabled !== undefined && p.scrollEnabled == null)
11112
+ p.scrollEnabled = scrollEnabled;
11113
+ if (ListEmptyComponent !== undefined && p.ListEmptyComponent == null)
11114
+ p.ListEmptyComponent = ListEmptyComponent;
11115
+ if (ListFooterComponent !== undefined && p.ListFooterComponent == null)
11116
+ p.ListFooterComponent = ListFooterComponent;
11117
+ if (ListHeaderComponent !== undefined && p.ListHeaderComponent == null)
11118
+ p.ListHeaderComponent = ListHeaderComponent;
11119
+ if (refreshControl !== undefined && p.refreshControl == null)
11120
+ p.refreshControl = refreshControl;
11121
+ if (onScroll !== undefined && p.onScroll == null)
11122
+ p.onScroll = onScroll;
11123
+ if (scrollEventThrottle !== undefined && p.scrollEventThrottle == null)
11124
+ p.scrollEventThrottle = scrollEventThrottle;
10866
11125
  return p;
10867
- }, [flashListProps]);
11126
+ }, [flashListProps, estimatedItemSize, onEndReached, onEndReachedThreshold, onViewableItemsChanged, scrollEnabled, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, refreshControl, onScroll, scrollEventThrottle]);
10868
11127
  const renderMasonryItem = ({ item, index }) => {
10869
11128
  if (renderItem) {
10870
11129
  return (jsxRuntime.jsx(reactNative.View, { children: renderItem(item, index) }));
@@ -13778,12 +14037,17 @@ const Collapse = ({ isCollapsed, children, duration = 300, timing = 'ease-out',
13778
14037
  }
13779
14038
  setContentHeight(prev => {
13780
14039
  if (Math.abs(prev - height) > 0.5) {
13781
- heightAnimation.setValue(isCollapsed ? height : Math.min(height, collapsedHeight));
13782
14040
  return height;
13783
14041
  }
13784
14042
  return prev;
13785
14043
  });
13786
14044
  };
14045
+ // Sync animated value when contentHeight changes outside of initial measurement
14046
+ React.useEffect(() => {
14047
+ if (!hasMeasuredRef.current || contentHeight === 0)
14048
+ return;
14049
+ heightAnimation.setValue(isCollapsed ? contentHeight : Math.min(contentHeight, collapsedHeight));
14050
+ }, [contentHeight, isCollapsed, collapsedHeight, heightAnimation]);
13787
14051
  return (jsxRuntime.jsx(reactNative.Animated.View, { style: [
13788
14052
  {
13789
14053
  overflow: 'hidden',
@@ -14566,7 +14830,7 @@ const CodeBlock = (props) => {
14566
14830
 
14567
14831
  const createDefaultComponents = (theme, handleLinkPress) => ({
14568
14832
  heading: ({ level, children }) => (jsxRuntime.jsx(Text, { variant: `h${Math.min(level, 6)}`, style: { marginTop: level === 1 ? 24 : 16, marginBottom: 8 }, weight: level <= 2 ? '700' : '600', children: children })),
14569
- paragraph: ({ children }) => (jsxRuntime.jsx(Text, { variant: "p", style: { marginBottom: 12 }, children: children })),
14833
+ paragraph: ({ children }) => (jsxRuntime.jsx(Text, { variant: "p", as: "div", style: { marginBottom: 12 }, children: children })),
14570
14834
  strong: ({ children }) => (jsxRuntime.jsx(Text, { variant: "strong", children: children })),
14571
14835
  em: ({ children }) => (jsxRuntime.jsx(Text, { variant: "em", children: children })),
14572
14836
  codeInline: ({ children }) => (jsxRuntime.jsx(Text, { variant: "code", style: {
@@ -17058,7 +17322,7 @@ const TextInputBase = factory((props, ref) => {
17058
17322
  height: styles.input.fontSize || 16,
17059
17323
  backgroundColor: textColor,
17060
17324
  marginLeft: 1,
17061
- } }))] }))] }), (showClearButton || endSection) && (jsxRuntime.jsxs(reactNative.View, { style: styles.endSection, children: [showClearButton && (jsxRuntime.jsx(ClearButton, { onPress: handleClear, size: size, accessibilityLabel: clearButtonLabelText, hasRightSection: !!endSection })), endSection] }))] }), disclaimerNode, error && (jsxRuntime.jsx(reactNative.Text, { style: styles.error, role: "alert", accessibilityLiveRegion: "polite", children: error })), helperText && !error && (jsxRuntime.jsx(reactNative.Text, { style: styles.helperText, children: helperText }))] }));
17325
+ } }))] }))] }), (showClearButton || endSection) && (jsxRuntime.jsxs(reactNative.View, { style: styles.endSection, children: [showClearButton && (jsxRuntime.jsx(ClearButton, { onPress: handleClear, size: size, accessibilityLabel: clearButtonLabelText, hasRightSection: !!endSection })), endSection] }))] }), disclaimerNode, error ? (jsxRuntime.jsx(reactNative.Text, { style: styles.error, role: "alert", accessibilityLiveRegion: "polite", children: error })) : null, helperText && !error ? (jsxRuntime.jsx(reactNative.Text, { style: styles.helperText, children: helperText })) : null] }));
17062
17326
  });
17063
17327
 
17064
17328
  const getInputTypeConfig = (type) => {
@@ -17110,7 +17374,9 @@ const getInputTypeConfig = (type) => {
17110
17374
  return configs[type || 'text'];
17111
17375
  };
17112
17376
  const Input = factory((props, ref) => {
17113
- const { type = 'text', validation, autoComplete, keyboardType, multiline, numberOfLines, minLines = 1, maxLines, maxLength, secureTextEntry, textInputProps, required, withAsterisk, endSection, inputRef, value, onChangeText, ...baseProps } = props;
17377
+ const { type = 'text', validation, autoComplete, keyboardType, multiline, numberOfLines, minLines = 1, maxLines, maxLength, secureTextEntry, textInputProps, required, withAsterisk, endSection, inputRef, value, onChangeText,
17378
+ // Native TextInput passthrough props
17379
+ autoCapitalize, autoCorrect, autoFocus, returnKeyType, blurOnSubmit, selectTextOnFocus, textContentType, textAlign, spellCheck, inputMode, enterKeyHint, selectionColor, showSoftInputOnFocus, editable, ...baseProps } = props;
17114
17380
  const theme = useTheme();
17115
17381
  // State for password visibility
17116
17382
  const [showPassword, setShowPassword] = React.useState(false);
@@ -17157,8 +17423,39 @@ const Input = factory((props, ref) => {
17157
17423
  }, [numberOfLines, multiline, currentLines]);
17158
17424
  // Merge type config with explicit props
17159
17425
  const mergedTextInputProps = React.useMemo(() => {
17426
+ // Collect native passthrough props (only include if explicitly set)
17427
+ const nativePassthrough = {};
17428
+ if (autoCapitalize !== undefined)
17429
+ nativePassthrough.autoCapitalize = autoCapitalize;
17430
+ if (autoCorrect !== undefined)
17431
+ nativePassthrough.autoCorrect = autoCorrect;
17432
+ if (autoFocus !== undefined)
17433
+ nativePassthrough.autoFocus = autoFocus;
17434
+ if (returnKeyType !== undefined)
17435
+ nativePassthrough.returnKeyType = returnKeyType;
17436
+ if (blurOnSubmit !== undefined)
17437
+ nativePassthrough.blurOnSubmit = blurOnSubmit;
17438
+ if (selectTextOnFocus !== undefined)
17439
+ nativePassthrough.selectTextOnFocus = selectTextOnFocus;
17440
+ if (textContentType !== undefined)
17441
+ nativePassthrough.textContentType = textContentType;
17442
+ if (textAlign !== undefined)
17443
+ nativePassthrough.textAlign = textAlign;
17444
+ if (spellCheck !== undefined)
17445
+ nativePassthrough.spellCheck = spellCheck;
17446
+ if (inputMode !== undefined)
17447
+ nativePassthrough.inputMode = inputMode;
17448
+ if (enterKeyHint !== undefined)
17449
+ nativePassthrough.enterKeyHint = enterKeyHint;
17450
+ if (selectionColor !== undefined)
17451
+ nativePassthrough.selectionColor = selectionColor;
17452
+ if (showSoftInputOnFocus !== undefined)
17453
+ nativePassthrough.showSoftInputOnFocus = showSoftInputOnFocus;
17454
+ if (editable !== undefined)
17455
+ nativePassthrough.editable = editable;
17160
17456
  const baseProps = {
17161
17457
  ...typeConfig,
17458
+ ...nativePassthrough,
17162
17459
  ...textInputProps,
17163
17460
  // Override secureTextEntry for password visibility toggle
17164
17461
  secureTextEntry: actualSecureTextEntry,
@@ -17202,7 +17499,21 @@ const Input = factory((props, ref) => {
17202
17499
  effectiveNumberOfLines,
17203
17500
  maxLength,
17204
17501
  isPasswordType,
17205
- showPassword
17502
+ showPassword,
17503
+ autoCapitalize,
17504
+ autoCorrect,
17505
+ autoFocus,
17506
+ returnKeyType,
17507
+ blurOnSubmit,
17508
+ selectTextOnFocus,
17509
+ textContentType,
17510
+ textAlign,
17511
+ spellCheck,
17512
+ inputMode,
17513
+ enterKeyHint,
17514
+ selectionColor,
17515
+ showSoftInputOnFocus,
17516
+ editable,
17206
17517
  ]);
17207
17518
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(TextInputBase, { ...baseProps, value: value, onChangeText: handleChangeText, inputRef: inputRef || ref, required: required, withAsterisk: finalWithAsterisk, endSection: finalRightSection, textInputProps: mergedTextInputProps, secureTextEntry:
17208
17519
  // Ensure secureTextEntry is only passed when not controlled by password toggle
@@ -18602,7 +18913,9 @@ const NumberInput = factory((props, ref) => {
18602
18913
  NumberInput.displayName = 'NumberInput';
18603
18914
 
18604
18915
  const PinInput = factory((props, ref) => {
18605
- const { length = 4, value = '', onChange, mask = false, maskChar = '•', manageFocus = true, type = 'numeric', placeholder = '', allowPaste = true, oneTimeCode = false, spacing = 8, disabled = false, error, size = 'md', onComplete, textInputProps, label, helperText, style, keyboardFocusId, name, testID, ...spacingProps } = props;
18916
+ const { length = 4, value = '', onChange, mask = false, maskChar = '•', manageFocus = true, type = 'numeric', placeholder = '', allowPaste = true, oneTimeCode = false, spacing = 8, disabled = false, error, size = 'md', onComplete, textInputProps, label, helperText, style, keyboardFocusId, name, testID,
18917
+ // Native TextInput passthrough props
18918
+ autoCapitalize, autoCorrect, autoFocus, selectTextOnFocus: selectTextOnFocusProp, textContentType: textContentTypeProp, textAlign, spellCheck, selectionColor, showSoftInputOnFocus, ...spacingProps } = props;
18606
18919
  const theme = useTheme();
18607
18920
  const inputRefs = React.useRef([]);
18608
18921
  const [focusedIndex, setFocusedIndex] = React.useState(-1);
@@ -18801,15 +19114,15 @@ const PinInput = factory((props, ref) => {
18801
19114
  inputRefs.current[index] = ref;
18802
19115
  }, style: getInputStyle(index), value: mask && digit ? maskChar : digit, onChangeText: (text) => handleChangeText(text, index), onKeyPress: reactNative.Platform.OS === 'web' ? ({ nativeEvent }) => {
18803
19116
  handleKeyPress(nativeEvent.key, index);
18804
- } : undefined, onFocus: () => handleFocus(index), onBlur: handleBlur, maxLength: allowPaste ? undefined : 1, keyboardType: type === 'numeric' ? 'number-pad' : 'default', textContentType: oneTimeCode ? 'oneTimeCode' : undefined, autoComplete: oneTimeCode ? 'one-time-code' : 'off', selectTextOnFocus: true, editable: !disabled, placeholder: placeholder, placeholderTextColor: theme.text.muted, ...textInputProps }, index))) }), error && (jsxRuntime.jsx(Text, { style: {
19117
+ } : undefined, onFocus: () => handleFocus(index), onBlur: handleBlur, maxLength: allowPaste ? undefined : 1, keyboardType: type === 'numeric' ? 'number-pad' : 'default', textContentType: oneTimeCode ? 'oneTimeCode' : (textContentTypeProp !== null && textContentTypeProp !== void 0 ? textContentTypeProp : undefined), autoComplete: oneTimeCode ? 'one-time-code' : 'off', selectTextOnFocus: selectTextOnFocusProp !== null && selectTextOnFocusProp !== void 0 ? selectTextOnFocusProp : true, editable: !disabled, placeholder: placeholder, placeholderTextColor: theme.text.muted, autoCapitalize: autoCapitalize, autoCorrect: autoCorrect, autoFocus: autoFocus && index === 0, textAlign: textAlign, spellCheck: spellCheck, selectionColor: selectionColor, showSoftInputOnFocus: showSoftInputOnFocus, ...textInputProps }, index))) }), error ? (jsxRuntime.jsx(Text, { style: {
18805
19118
  marginTop: 4,
18806
19119
  fontSize: 12,
18807
19120
  color: theme.colors.error[5]
18808
- }, children: error })), helperText && !error && (jsxRuntime.jsx(Text, { style: {
19121
+ }, children: error })) : null, helperText && !error ? (jsxRuntime.jsx(Text, { style: {
18809
19122
  marginTop: 4,
18810
19123
  fontSize: 12,
18811
19124
  color: theme.text.muted
18812
- }, children: helperText }))] }));
19125
+ }, children: helperText })) : null] }));
18813
19126
  });
18814
19127
  PinInput.displayName = 'PinInput';
18815
19128
 
@@ -18980,7 +19293,7 @@ const Checkbox = React.forwardRef((props, ref) => {
18980
19293
  }
18981
19294
  return null;
18982
19295
  };
18983
- const labelContent = children || label;
19296
+ const labelContent = children || label || undefined;
18984
19297
  // Determine layout direction based on label position
18985
19298
  const isVertical = labelPosition === 'top' || labelPosition === 'bottom';
18986
19299
  const checkboxElement = (jsxRuntime.jsx(reactNative.View, { style: styles.checkboxContainer, children: jsxRuntime.jsx(reactNative.Pressable, { ref: ref, style: [styles.checkbox, style], onPress: handlePress, disabled: disabled, testID: testID, hitSlop: 12, accessibilityRole: "checkbox", accessibilityState: {
@@ -24345,7 +24658,7 @@ const Select = factory((allProps, ref) => {
24345
24658
  close();
24346
24659
  }, [disabled, valueProp, onChange, onClear, close]);
24347
24660
  const fieldContent = selectedOption ? (jsxRuntime.jsx(reactNative.Text, { style: { color: disabled ? theme.text.disabled : theme.text.primary }, children: selectedOption.label })) : (jsxRuntime.jsx(reactNative.Text, { style: { color: disabled ? theme.text.disabled : theme.text.muted }, children: placeholder }));
24348
- return (jsxRuntime.jsxs(reactNative.View, { style: [defaultMinWidthStyle, fullWidthStyle, spacingStyles, layoutStyles], children: [jsxRuntime.jsx(FieldHeader, { label: label, description: description, disabled: disabled, error: !!error, size: size }), jsxRuntime.jsxs(reactNative.Pressable, { ref: setTriggerNode, onPress: toggle, accessibilityRole: "button", accessibilityLabel: label || placeholder, disabled: disabled, style: [
24661
+ return (jsxRuntime.jsxs(reactNative.View, { style: [defaultMinWidthStyle, fullWidthStyle, spacingStyles, layoutStyles], children: [jsxRuntime.jsx(FieldHeader, { label: label, description: description, disabled: disabled, error: !!error, size: size }), jsxRuntime.jsxs(reactNative.Pressable, { ref: setTriggerNode, onPress: toggle, ...(reactNative.Platform.OS === 'web' ? { role: 'combobox' } : { accessibilityRole: 'button' }), accessibilityLabel: label || placeholder, disabled: disabled, style: [
24349
24662
  inputStyles.inputContainer,
24350
24663
  {
24351
24664
  flexDirection: isRTL ? 'row-reverse' : 'row',
@@ -27661,7 +27974,7 @@ const TimePickerInput = ({ value, defaultValue, onChange, format = 24, withSecon
27661
27974
  color: active ? 'white' : theme.colors.gray[8],
27662
27975
  fontSize: 16,
27663
27976
  }, children: pad(n) }) }, n));
27664
- return (jsxRuntime.jsxs(reactNative.View, { ref: containerRef, style: [containerStyles, inputWidth != null ? { width: inputWidth } : null, style], children: [jsxRuntime.jsx(reactNative.Pressable, { onPress: handleOpen, disabled: disabled, accessibilityRole: "button", children: jsxRuntime.jsx(Input, { value: display, onChangeText: (text) => {
27977
+ return (jsxRuntime.jsxs(reactNative.View, { ref: containerRef, style: [containerStyles, inputWidth != null ? { width: inputWidth } : null, style], children: [jsxRuntime.jsx(reactNative.Pressable, { onPress: handleOpen, disabled: disabled, ...(reactNative.Platform.OS === 'web' ? { role: 'group' } : { accessibilityRole: 'button' }), children: jsxRuntime.jsx(Input, { value: display, onChangeText: (text) => {
27665
27978
  var _a, _b;
27666
27979
  if (!allowInput)
27667
27980
  return;
@@ -30817,7 +31130,10 @@ const StepperStep = React.forwardRef(({ children, label, description, icon, comp
30817
31130
  });
30818
31131
  // Completed Component
30819
31132
  const StepperCompleted = ({ children }) => {
30820
- return jsxRuntime.jsx(reactNative.View, { children: children });
31133
+ const content = typeof children === 'string' || typeof children === 'number'
31134
+ ? jsxRuntime.jsx(reactNative.Text, { children: children })
31135
+ : children;
31136
+ return jsxRuntime.jsx(reactNative.View, { children: content });
30821
31137
  };
30822
31138
  // Main Stepper Component
30823
31139
  const Stepper = React.forwardRef(({ active, onStepClick, orientation = 'horizontal', iconPosition = 'left', iconSize, size = 'md', color, completedIcon, allowNextStepsSelect = true, children, 'aria-label': ariaLabel, ...props }, ref) => {
@@ -30886,7 +31202,10 @@ const Stepper = React.forwardRef(({ active, onStepClick, orientation = 'horizont
30886
31202
  return completedContent;
30887
31203
  }
30888
31204
  if (currentStepContent) {
30889
- return jsxRuntime.jsx(reactNative.View, { style: getContentStyles(), children: currentStepContent });
31205
+ const content = typeof currentStepContent === 'string' || typeof currentStepContent === 'number'
31206
+ ? jsxRuntime.jsx(reactNative.Text, { children: currentStepContent })
31207
+ : currentStepContent;
31208
+ return jsxRuntime.jsx(reactNative.View, { style: getContentStyles(), children: content });
30890
31209
  }
30891
31210
  return null;
30892
31211
  };
@@ -32970,8 +33289,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
32970
33289
  const [editValue, setEditValue] = React.useState('');
32971
33290
  // Uncontrolled column filters state (used when onFilterChange not provided)
32972
33291
  const [internalFilters, setInternalFilters] = React.useState([]);
32973
- // Force re-render counter for portal components
32974
- const [forceUpdateCounter, setForceUpdateCounter] = React.useState(0);
32975
33292
  const [tempHeaderEdits, setTempHeaderEdits] = React.useState({});
32976
33293
  const [columnWidths, setColumnWidths] = React.useState(() => {
32977
33294
  const initial = {};
@@ -33199,7 +33516,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33199
33516
  paddingBottom: DESIGN_TOKENS.spacing.sm,
33200
33517
  }, children: jsxRuntime.jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, children: [jsxRuntime.jsx(Text, { variant: "small", weight: "semibold", children: "Search" }), jsxRuntime.jsx(Input, { placeholder: searchPlaceholder, value: searchValue, onChangeText: handleSearchChange, startSection: jsxRuntime.jsx(Icon, { name: "menu", size: 16 }), size: "sm" })] }) })), columns.some(c => c.filterable) && (jsxRuntime.jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: [jsxRuntime.jsxs(Flex, { direction: "row", justify: "space-between", align: "center", children: [jsxRuntime.jsx(Text, { variant: "small", weight: "semibold", children: "Filters" }), activeFilters.length > 0 && (jsxRuntime.jsx(Button, { variant: "ghost", size: "xs", onPress: () => {
33201
33518
  setInternalFilters([]);
33202
- setForceUpdateCounter(c => c + 1);
33203
33519
  }, children: "Clear all" }))] }), activeFilters.length > 0 && (jsxRuntime.jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, style: { marginBottom: DESIGN_TOKENS.spacing.sm }, children: activeFilters.map((filter, idx) => {
33204
33520
  const column = columns.find(c => c.key === filter.column);
33205
33521
  return (jsxRuntime.jsxs(reactNative.View, { style: {
@@ -33212,7 +33528,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33212
33528
  gap: DESIGN_TOKENS.spacing.xs
33213
33529
  }, children: [jsxRuntime.jsxs(Text, { variant: "small", style: { color: theme.colors.primary[7] }, children: [(column === null || column === void 0 ? void 0 : column.header) || filter.column, ": ", filter.operator, " \"", filter.value, "\""] }), jsxRuntime.jsx(reactNative.Pressable, { onPress: () => {
33214
33530
  setInternalFilters(filters => filters.filter((_, i) => i !== idx));
33215
- setForceUpdateCounter(c => c + 1);
33216
33531
  }, children: jsxRuntime.jsx(Icon, { name: "x", size: 12, color: theme.colors.primary[6] }) })] }, idx));
33217
33532
  }) })), jsxRuntime.jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: columns.filter(c => c.filterable).map(column => {
33218
33533
  const currentFilter = getColumnFilter(column.key);
@@ -33268,7 +33583,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33268
33583
  return next;
33269
33584
  });
33270
33585
  }
33271
- setForceUpdateCounter(c => c + 1);
33272
33586
  }, [onFilterChange, filters]);
33273
33587
  const clearFilter = React.useCallback((columnKey) => {
33274
33588
  updateFilter(columnKey, undefined);
@@ -39711,7 +40025,7 @@ function VideoControls({ config, state, onPlay, onPause, onSeek, onVolumeChange,
39711
40025
  const displayTime = isScrubbing
39712
40026
  ? (scrubbingValue / 100) * state.duration
39713
40027
  : state.currentTime;
39714
- const styles = reactNative.StyleSheet.create({
40028
+ const styles = React.useMemo(() => reactNative.StyleSheet.create({
39715
40029
  activeRate: {
39716
40030
  backgroundColor: theme.colors.primary[5],
39717
40031
  },
@@ -39792,7 +40106,7 @@ function VideoControls({ config, state, onPlay, onPause, onSeek, onVolumeChange,
39792
40106
  padding: 8,
39793
40107
  width: 120,
39794
40108
  },
39795
- });
40109
+ }), [theme.colors.primary, isRTL]);
39796
40110
  return (jsxRuntime.jsxs(reactNative.View, { style: [styles.container, style], children: [config.progress && (jsxRuntime.jsx(reactNative.View, { style: styles.topRow, children: jsxRuntime.jsx(reactNative.View, { style: styles.progressContainer, children: jsxRuntime.jsx(Slider, { value: progressPercentage, min: 0, max: 100, step: 0.1, onChange: handleProgressChange, trackColor: "rgba(255, 255, 255, 0.3)", thumbColor: "white", activeTrackColor: theme.colors.primary[5] }) }) })), jsxRuntime.jsxs(reactNative.View, { style: styles.bottomRow, children: [jsxRuntime.jsxs(reactNative.View, { style: styles.leftControls, children: [(config.play || config.pause) && (jsxRuntime.jsx(reactNative.TouchableOpacity, { style: styles.playPauseButton, onPress: state.playing ? onPause : onPlay, accessible: true, accessibilityLabel: state.playing ? 'Pause' : 'Play', children: jsxRuntime.jsx(Icon, { name: state.playing ? 'pause' : 'play', size: 24, color: "white" }) })), config.time && (jsxRuntime.jsxs(Text, { style: styles.timeText, children: [formatTime(displayTime), " / ", formatTime(state.duration)] }))] }), jsxRuntime.jsxs(reactNative.View, { style: styles.rightControls, children: [config.playbackRate && (jsxRuntime.jsxs(reactNative.View, { style: { position: 'relative' }, children: [jsxRuntime.jsx(reactNative.TouchableOpacity, { style: styles.controlButton, onPress: () => setShowRateMenu(!showRateMenu), accessible: true, accessibilityLabel: "Playback speed", children: jsxRuntime.jsxs(Text, { style: styles.timeText, children: [state.playbackRate, "x"] }) }), showRateMenu && (jsxRuntime.jsx(reactNative.View, { style: styles.rateMenu, children: PLAYBACK_RATES.map(rate => (jsxRuntime.jsx(reactNative.TouchableOpacity, { style: [
39797
40111
  styles.rateMenuItem,
39798
40112
  state.playbackRate === rate && styles.activeRate
@@ -39817,13 +40131,10 @@ const EVENT_TYPE_COLORS = {
39817
40131
  function VideoTimeline({ timeline, duration, currentTime, onSeek, style }) {
39818
40132
  useTheme();
39819
40133
  const { isRTL } = useDirection();
39820
- if (duration === 0 || timeline.length === 0) {
39821
- return null;
39822
- }
39823
40134
  const handleMarkerPress = (event) => {
39824
40135
  onSeek(event.time);
39825
40136
  };
39826
- const styles = reactNative.StyleSheet.create({
40137
+ const styles = React.useMemo(() => reactNative.StyleSheet.create({
39827
40138
  activeMarker: {
39828
40139
  borderRadius: 2,
39829
40140
  height: 8,
@@ -39858,7 +40169,10 @@ function VideoTimeline({ timeline, duration, currentTime, onSeek, style }) {
39858
40169
  fontSize: 10,
39859
40170
  textAlign: 'center',
39860
40171
  },
39861
- });
40172
+ }), []);
40173
+ if (duration === 0 || timeline.length === 0) {
40174
+ return null;
40175
+ }
39862
40176
  return (jsxRuntime.jsx(reactNative.View, { style: [styles.container, style], children: timeline.map((event, index) => {
39863
40177
  var _a;
39864
40178
  const position = (event.time / duration) * 100;
@@ -41005,6 +41319,7 @@ exports.BottomAppBar = BottomAppBar;
41005
41319
  exports.BrandButton = BrandButton;
41006
41320
  exports.BrandIcon = BrandIcon;
41007
41321
  exports.Breadcrumbs = Breadcrumbs;
41322
+ exports.BreakpointProvider = BreakpointProvider;
41008
41323
  exports.Button = Button;
41009
41324
  exports.COMPONENT_SIZES = COMPONENT_SIZES$1;
41010
41325
  exports.COMPONENT_SIZE_ORDER = COMPONENT_SIZE_ORDER;
@@ -41222,6 +41537,7 @@ exports.useAppShell = useAppShell;
41222
41537
  exports.useAppShellApi = useAppShellApi;
41223
41538
  exports.useAppShellLayout = useAppShellLayout;
41224
41539
  exports.useBreakpoint = useBreakpoint;
41540
+ exports.useClipboard = useClipboard;
41225
41541
  exports.useColorScheme = useColorScheme;
41226
41542
  exports.useDeviceInfo = useDeviceInfo;
41227
41543
  exports.useDialog = useDialog;
@@ -41241,19 +41557,25 @@ exports.useHotkeys = useHotkeys;
41241
41557
  exports.useI18n = useI18n;
41242
41558
  exports.useKeyboardManager = useKeyboardManager;
41243
41559
  exports.useKeyboardManagerOptional = useKeyboardManagerOptional;
41560
+ exports.useMaskedInput = useMaskedInput;
41244
41561
  exports.useNavbarHover = useNavbarHover;
41245
41562
  exports.useOptionalFormContext = useOptionalFormContext;
41246
41563
  exports.useOverlay = useOverlay;
41247
41564
  exports.useOverlayApi = useOverlayApi;
41565
+ exports.useOverlayMode = useOverlayMode;
41248
41566
  exports.useOverlays = useOverlays;
41249
41567
  exports.usePopoverPositioning = usePopoverPositioning;
41568
+ exports.useScrollSpy = useScrollSpy;
41250
41569
  exports.useSimpleDialog = useSimpleDialog;
41251
41570
  exports.useSound = useSound;
41252
41571
  exports.useSpotlightStore = useSpotlightStore;
41253
41572
  exports.useSpotlightStoreInstance = useSpotlightStoreInstance;
41254
41573
  exports.useSpotlightToggle = useSpotlightToggle;
41255
41574
  exports.useTheme = useTheme;
41575
+ exports.useThemeLayout = useThemeLayout;
41256
41576
  exports.useThemeMode = useThemeMode;
41577
+ exports.useThemeVisuals = useThemeVisuals;
41578
+ exports.useTitleRegistration = useTitleRegistration;
41257
41579
  exports.useTitleRegistry = useTitleRegistry;
41258
41580
  exports.useTitleRegistryOptional = useTitleRegistryOptional;
41259
41581
  exports.useToast = useToast;