@platform-blocks/ui 0.6.0 → 0.6.1

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.
Files changed (33) hide show
  1. package/lib/cjs/index.js +458 -705
  2. package/lib/cjs/index.js.map +1 -1
  3. package/lib/components/Dialog/Dialog.d.ts +1 -1
  4. package/lib/components/Dialog/types.d.ts +23 -2
  5. package/lib/components/HoverCard/types.d.ts +1 -1
  6. package/lib/components/Image/Image.d.ts +1 -1
  7. package/lib/components/Image/types.d.ts +3 -3
  8. package/lib/components/Input/styles.d.ts +1 -12
  9. package/lib/components/Layout/Layout.d.ts +1 -0
  10. package/lib/components/Menu/types.d.ts +2 -2
  11. package/lib/components/Popover/types.d.ts +5 -5
  12. package/lib/components/Select/Select.types.d.ts +1 -1
  13. package/lib/components/Skeleton/types.d.ts +2 -2
  14. package/lib/components/Table/Table.d.ts +4 -4
  15. package/lib/components/TextArea/types.d.ts +2 -2
  16. package/lib/components/Timeline/types.d.ts +20 -0
  17. package/lib/components/Video/types.d.ts +2 -2
  18. package/lib/components/Waveform/WaveformSkeleton.d.ts +2 -2
  19. package/lib/components/Waveform/types.d.ts +2 -2
  20. package/lib/components/index.d.ts +0 -2
  21. package/lib/components/types.d.ts +0 -1
  22. package/lib/core/utils/layout.d.ts +13 -16
  23. package/lib/core/utils/positioning-enhanced.d.ts +2 -0
  24. package/lib/esm/index.js +460 -705
  25. package/lib/esm/index.js.map +1 -1
  26. package/lib/index.d.ts +0 -4
  27. package/package.json +67 -57
  28. package/lib/components/Lottie/Lottie.d.ts +0 -30
  29. package/lib/components/Lottie/index.d.ts +0 -2
  30. package/lib/components/RichTextEditor/RichTextEditor.d.ts +0 -3
  31. package/lib/components/RichTextEditor/index.d.ts +0 -2
  32. package/lib/components/RichTextEditor/styles.d.ts +0 -61
  33. package/lib/components/RichTextEditor/types.d.ts +0 -150
package/lib/cjs/index.js CHANGED
@@ -726,16 +726,16 @@ const DARK_THEME = {
726
726
  '#F2F2F7'
727
727
  ],
728
728
  highlight: [
729
- '#2A2313',
730
- '#3D3320',
731
- '#4F422D',
732
- '#61523A',
733
- '#736247',
734
- '#FBBF24', // Keep same base as light mode for consistency
735
- '#FCD34D',
736
- '#FDE68A',
737
- '#FEF3C7',
738
- '#FFFBEB'
729
+ '#1E3A5F', // Deep blue
730
+ '#1E4976', //
731
+ '#1D5A8F', //
732
+ '#2563EB', // Bright blue
733
+ '#3B82F6', // Primary blue
734
+ '#60A5FA', // Light blue
735
+ '#93C5FD', //
736
+ '#BFDBFE', //
737
+ '#DBEAFE', //
738
+ '#EFF6FF' // Very light blue
739
739
  ],
740
740
  pink: [
741
741
  '#831843', '#9D174D', '#BE185D', '#DB2777', '#EC4899',
@@ -791,9 +791,9 @@ const DARK_THEME = {
791
791
  },
792
792
  states: {
793
793
  focusRing: 'rgba(10,132,255,0.55)',
794
- textSelection: 'rgba(251, 191, 36, 0.2)', // Slightly more subtle for dark mode
795
- highlightText: '#FDE68A', // highlight[7] for good contrast on dark
796
- highlightBackground: 'rgba(97, 82, 58, 0.8)' // Darker highlight[3] with more opacity
794
+ textSelection: 'rgba(10, 132, 255, 0.25)', // Primary blue for selection
795
+ highlightText: '#60A5FA', // primary[4] - bright blue for good contrast on dark
796
+ highlightBackground: 'rgba(59, 130, 246, 0.35)' // primary[5] with transparency
797
797
  },
798
798
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
799
799
  fontSizes: {
@@ -882,6 +882,8 @@ const DARK_THEME = {
882
882
  const optionalModuleCache = new Map();
883
883
  const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production';
884
884
  // Metro bundler requires static string literals for require; keep all optional modules here.
885
+ // NOTE: Do NOT add react-syntax-highlighter here - it causes Metro to fail on native
886
+ // when the package isn't installed. Instead, pass the loader dynamically from web-only code.
885
887
  const optionalModuleLoaders = {
886
888
  'react-native': () => require('react-native'),
887
889
  'expo-clipboard': () => require('expo-clipboard'),
@@ -890,21 +892,9 @@ const optionalModuleLoaders = {
890
892
  'expo-document-picker': () => require('expo-document-picker'),
891
893
  'react-native-webview': () => require('react-native-webview'),
892
894
  'lodash.debounce': () => require('lodash.debounce'),
893
- 'react-syntax-highlighter': () => require('react-syntax-highlighter'),
894
- 'react-syntax-highlighter/dist/esm/languages/prism/jsx': () => require('react-syntax-highlighter/dist/esm/languages/prism/jsx'),
895
- 'react-syntax-highlighter/dist/esm/languages/prism/tsx': () => require('react-syntax-highlighter/dist/esm/languages/prism/tsx'),
896
- 'react-syntax-highlighter/dist/esm/languages/prism/typescript': () => require('react-syntax-highlighter/dist/esm/languages/prism/typescript'),
897
- 'react-syntax-highlighter/dist/esm/languages/prism/javascript': () => require('react-syntax-highlighter/dist/esm/languages/prism/javascript'),
898
- 'react-syntax-highlighter/dist/esm/languages/prism/json': () => require('react-syntax-highlighter/dist/esm/languages/prism/json'),
899
- 'react-syntax-highlighter/dist/esm/languages/prism/bash': () => require('react-syntax-highlighter/dist/esm/languages/prism/bash'),
900
- 'react-syntax-highlighter/dist/esm/styles/prism/prism': () => require('react-syntax-highlighter/dist/esm/styles/prism/prism'),
901
- 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus': () => require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus'),
902
895
  'expo-audio': () => require('expo-audio'),
903
896
  'react-native-gesture-handler': () => require('react-native-gesture-handler'),
904
897
  'expo-status-bar': () => require('expo-status-bar'),
905
- 'lottie-react': () => require('lottie-react'),
906
- '@lottiefiles/dotlottie-react': () => require('@lottiefiles/dotlottie-react'),
907
- 'lottie-react-native': () => require('lottie-react-native'),
908
898
  'expo-navigation-bar': () => require('expo-navigation-bar'),
909
899
  };
910
900
  /**
@@ -1992,7 +1982,6 @@ function resolveComponentSize(value, scale, options = {}) {
1992
1982
  }
1993
1983
  const firstAvailable = allowed.find(key => scale[key] !== undefined);
1994
1984
  if (firstAvailable && scale[firstAvailable] !== undefined) {
1995
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1996
1985
  return scale[firstAvailable];
1997
1986
  }
1998
1987
  throw new Error('resolveComponentSize: no matching size found in provided scale.');
@@ -2354,18 +2343,17 @@ function extractSpacingProps(props) {
2354
2343
  *
2355
2344
  * @param props - The layout properties object
2356
2345
  * @param props.fullWidth - When true, sets width to 100%
2357
- * @param props.w - Shorthand width property (overrides fullWidth)
2358
- * @param props.width - Specific width value (overrides fullWidth and w)
2359
- * @param props.height - Height value
2360
- * @param props.maxWidth - Maximum width constraint
2361
- * @param props.minWidth - Minimum width constraint
2362
- * @param props.maxHeight - Maximum height constraint
2363
- * @param props.minHeight - Minimum height constraint
2346
+ * @param props.w - Width property (overrides fullWidth)
2347
+ * @param props.h - Height value
2348
+ * @param props.maxW - Maximum width constraint
2349
+ * @param props.minW - Minimum width constraint
2350
+ * @param props.maxH - Maximum height constraint
2351
+ * @param props.minH - Minimum height constraint
2364
2352
  *
2365
2353
  * @returns A partial ViewStyle object containing the computed layout styles
2366
2354
  *
2367
2355
  * @remarks
2368
- * Property precedence for width: width > w > fullWidth
2356
+ * Property precedence for width: w > fullWidth
2369
2357
  * The function processes width properties in order of specificity, with more specific
2370
2358
  * properties overriding more general ones.
2371
2359
  */
@@ -2375,43 +2363,38 @@ function getLayoutStyles(props) {
2375
2363
  if (props.fullWidth) {
2376
2364
  styles.width = '100%';
2377
2365
  }
2378
- // Handle shorthand width prop first
2366
+ // Handle width prop (overrides fullWidth)
2379
2367
  if (props.w !== undefined) {
2380
2368
  styles.width = props.w;
2381
2369
  }
2382
- // Handle specific dimensions (override fullWidth and w if specified)
2383
- if (props.width !== undefined) {
2384
- styles.width = props.width;
2385
- }
2386
- if (props.height !== undefined) {
2387
- styles.height = props.height;
2370
+ if (props.h !== undefined) {
2371
+ styles.height = props.h;
2388
2372
  }
2389
- if (props.maxWidth !== undefined) {
2390
- styles.maxWidth = props.maxWidth;
2373
+ if (props.maxW !== undefined) {
2374
+ styles.maxWidth = props.maxW;
2391
2375
  }
2392
- if (props.minWidth !== undefined) {
2393
- styles.minWidth = props.minWidth;
2376
+ if (props.minW !== undefined) {
2377
+ styles.minWidth = props.minW;
2394
2378
  }
2395
- if (props.maxHeight !== undefined) {
2396
- styles.maxHeight = props.maxHeight;
2379
+ if (props.maxH !== undefined) {
2380
+ styles.maxHeight = props.maxH;
2397
2381
  }
2398
- if (props.minHeight !== undefined) {
2399
- styles.minHeight = props.minHeight;
2382
+ if (props.minH !== undefined) {
2383
+ styles.minHeight = props.minH;
2400
2384
  }
2401
2385
  return styles;
2402
2386
  }
2403
2387
  // Helper to extract layout props from component props
2404
2388
  function extractLayoutProps(props) {
2405
- const { fullWidth, w, width, height, maxWidth, minWidth, maxHeight, minHeight, ...otherProps } = props;
2389
+ const { fullWidth, w, h, maxW, minW, maxH, minH, ...otherProps } = props;
2406
2390
  const layoutProps = {
2407
2391
  fullWidth,
2408
2392
  w,
2409
- width,
2410
- height,
2411
- maxWidth,
2412
- minWidth,
2413
- maxHeight,
2414
- minHeight
2393
+ h,
2394
+ maxW,
2395
+ minW,
2396
+ maxH,
2397
+ minH
2415
2398
  };
2416
2399
  return { layoutProps, otherProps };
2417
2400
  }
@@ -2680,7 +2663,7 @@ async function measureAsyncPerformance(name, fn) {
2680
2663
  const OVERLAY_CACHE_LIMIT = 200;
2681
2664
  const overlayPositionCache = new Map();
2682
2665
  const formatNumber = (value) => Number.isFinite(value) ? Math.round(value * 100) / 100 : 0;
2683
- const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary) => {
2666
+ const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary, matchAnchorWidth) => {
2684
2667
  return [
2685
2668
  formatNumber(anchorX),
2686
2669
  formatNumber(anchorY),
@@ -2697,6 +2680,7 @@ const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, over
2697
2680
  flip ? '1' : '0',
2698
2681
  shift ? '1' : '0',
2699
2682
  formatNumber(boundary),
2683
+ matchAnchorWidth ? '1' : '0',
2700
2684
  reactNative.Platform.OS,
2701
2685
  ].join('|');
2702
2686
  };
@@ -2742,11 +2726,12 @@ registerViewportListeners();
2742
2726
  * Enhanced overlay positioning that prevents off-screen rendering with intelligent caching
2743
2727
  */
2744
2728
  function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2745
- const { placement = 'auto', offset = 8, viewport = getViewport(), strategy = 'fixed', flip = true, shift = true, boundary = 8, fallbackPlacements = ['bottom', 'top', 'right', 'left'] } = options;
2729
+ const { placement = 'auto', offset = 8, viewport = getViewport(), strategy = 'fixed', flip = true, shift = true, boundary = 8, fallbackPlacements = ['bottom', 'top', 'right', 'left'], matchAnchorWidth = false, } = options;
2746
2730
  // If overlay height is unknown/small (pre-measure), use a heuristic height for decision-making
2747
2731
  // This helps avoid choosing "bottom" when near the bottom of the viewport.
2748
2732
  const heuristicHeight = Math.max(overlay.height || 0, 240);
2749
- const overlayWidth = overlay.width;
2733
+ // When matchAnchorWidth is true, use anchor width for overlay width calculations
2734
+ const overlayWidth = matchAnchorWidth ? anchor.width : overlay.width;
2750
2735
  const overlayHeight = overlay.height > 0 ? overlay.height : heuristicHeight;
2751
2736
  // Account for scroll if using absolute positioning
2752
2737
  const scrollX = (reactNative.Platform.OS === 'web' && strategy === 'absolute')
@@ -2757,7 +2742,7 @@ function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2757
2742
  const anchorX = anchor.x + scrollX;
2758
2743
  const anchorY = anchor.y + scrollY;
2759
2744
  // Check cache first
2760
- const cacheKey = createOverlayCacheKey(anchorX, anchorY, anchor.width, anchor.height, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary);
2745
+ const cacheKey = createOverlayCacheKey(anchorX, anchorY, anchor.width, anchor.height, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary, matchAnchorWidth);
2761
2746
  const cached = getCachedOverlayPosition(cacheKey);
2762
2747
  if (cached) {
2763
2748
  return cached;
@@ -2825,10 +2810,14 @@ function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2825
2810
  // If enforcement moved the overlay to the opposite vertical side to avoid covering the anchor,
2826
2811
  // reflect that in the returned placement so arrows/styles are consistent.
2827
2812
  const resolvedPlacement = adjustPlacementIfMoved(finalPlacement, result, anchorRect);
2813
+ // When matchAnchorWidth is true, preserve anchor width without constraining to maxWidth
2814
+ const computedFinalWidth = matchAnchorWidth
2815
+ ? anchor.width
2816
+ : Math.min(result.finalWidth || overlay.width, result.maxWidth || overlay.width);
2828
2817
  const finalResult = {
2829
2818
  ...result,
2830
2819
  placement: resolvedPlacement,
2831
- finalWidth: Math.min(result.finalWidth || overlay.width, result.maxWidth || overlay.width),
2820
+ finalWidth: computedFinalWidth,
2832
2821
  finalHeight: Math.min(result.finalHeight || overlay.height, result.maxHeight || overlay.height),
2833
2822
  };
2834
2823
  // Cache the result
@@ -3585,9 +3574,14 @@ const Text = (allProps) => {
3585
3574
  }
3586
3575
  // Platform-specific rendering
3587
3576
  if (reactNative.Platform.OS === 'web' && isHTMLVariant(htmlTag)) {
3588
- const webStyles = convertToWebStyles([textStyles, spacingStyles, style,
3589
- // make sure text is side to side
3590
- { display: 'inline' }
3577
+ const styleArray = Array.isArray(style) ? style : [style];
3578
+ const hasDisplayOverride = styleArray.some((item) => item && ((item.display !== undefined) || (item.whiteSpace !== undefined)));
3579
+ const webStyles = convertToWebStyles([
3580
+ textStyles,
3581
+ spacingStyles,
3582
+ style,
3583
+ // default to inline unless caller explicitly requests display/whitespace behavior
3584
+ ...(hasDisplayOverride ? [] : [{ display: 'inline' }]),
3591
3585
  ]);
3592
3586
  // Handle text selection for web
3593
3587
  if (!selectable) {
@@ -6263,7 +6257,7 @@ const Button = (allProps) => {
6263
6257
  // Use the actual measured width instead of character-based estimates
6264
6258
  const layoutStyles = {
6265
6259
  ...baseLayoutStyles,
6266
- ...(loading && measuredWidth && !layoutProps.width && !layoutProps.w && !layoutProps.fullWidth
6260
+ ...(loading && measuredWidth && !layoutProps.w && !layoutProps.fullWidth
6267
6261
  ? { width: measuredWidth, minWidth: measuredWidth }
6268
6262
  : {})
6269
6263
  };
@@ -6697,18 +6691,22 @@ const useSafeSafeAreaInsets = () => {
6697
6691
  return { top: 0, bottom: 0, left: 0, right: 0 };
6698
6692
  }
6699
6693
  };
6700
- function Dialog({ visible, variant = 'modal', title, children, closable = true, backdrop = true, backdropClosable = true, shouldClose = false, onClose, width, height, style, bottomSheetSwipeZone = 'container', }) {
6694
+ function Dialog({ visible, variant = 'modal', title, children, closable = true, backdrop = true, backdropClosable = true, shouldClose = false, onClose, w, h, radius, style, showHeader = true, bottomSheetSwipeZone = 'container', }) {
6701
6695
  const theme = useTheme();
6702
6696
  const { isRTL } = useDirection();
6703
6697
  const insets = useSafeSafeAreaInsets();
6704
6698
  const { width: screenWidth, height: screenHeight } = reactNative.useWindowDimensions();
6705
6699
  const horizontalMargin = 32; // safety margin so dialog never touches edges
6706
6700
  const isNativePlatform = reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android';
6707
- const defaultModalMaxWidth = Math.min((width || 500), Math.max(200, screenWidth - horizontalMargin));
6701
+ const defaultModalMaxWidth = Math.min((w || 500), Math.max(200, screenWidth - horizontalMargin));
6708
6702
  const modalEffectiveWidth = variant !== 'modal'
6709
6703
  ? undefined
6710
6704
  : Math.min(defaultModalMaxWidth, screenWidth - horizontalMargin);
6711
- const bottomSheetMaxWidth = Math.min(width ? width : (isNativePlatform ? 720 : Math.min(600, screenWidth - horizontalMargin)), screenWidth);
6705
+ const bottomSheetMaxWidth = Math.min(w ? w : (isNativePlatform ? 720 : Math.min(600, screenWidth - horizontalMargin)), screenWidth);
6706
+ const resolvedRadius = radius !== null && radius !== void 0 ? radius : (variant === 'bottomsheet' ? 20 : 16);
6707
+ const resolvedMaxHeight = variant === 'bottomsheet'
6708
+ ? (h !== null && h !== void 0 ? h : Math.max(200, screenHeight - insets.top - 24))
6709
+ : (variant === 'fullscreen' ? '100%' : (h || '90%'));
6712
6710
  const invokeOnClose = React.useCallback(() => {
6713
6711
  onClose === null || onClose === void 0 ? void 0 : onClose();
6714
6712
  }, [onClose]);
@@ -6764,20 +6762,12 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6764
6762
  event.preventDefault();
6765
6763
  }
6766
6764
  }
6767
- // Allow dragging in both directions but apply rubber band for upward movement
6768
- const dragDistance = gestureState.dy;
6769
- if (dragDistance >= 0) {
6770
- // Downward movement - apply subtle resistance for better feel
6771
- const resistance = 0.8;
6772
- const resistedDistance = dragDistance * resistance + (dragDistance > 100 ? (dragDistance - 100) * 0.2 : 0);
6773
- slideAnim.value = resistedDistance;
6774
- }
6775
- else {
6776
- // Upward movement - apply rubber band effect
6777
- const upwardResistance = 0.3;
6778
- const rubberBandDistance = dragDistance * upwardResistance;
6779
- slideAnim.value = rubberBandDistance;
6780
- }
6765
+ // Only allow downward movement (dismiss gesture)
6766
+ const dragDistance = Math.max(0, gestureState.dy);
6767
+ // Downward movement - apply subtle resistance for better feel
6768
+ const resistance = 0.8;
6769
+ const resistedDistance = dragDistance * resistance + (dragDistance > 100 ? (dragDistance - 100) * 0.2 : 0);
6770
+ slideAnim.value = resistedDistance;
6781
6771
  }
6782
6772
  },
6783
6773
  onPanResponderRelease: (_, gestureState) => {
@@ -6934,8 +6924,8 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6934
6924
  }, [shouldClose]);
6935
6925
  const isDark = theme.colorScheme === 'dark';
6936
6926
  const surfaceColor = isDark ? theme.backgrounds.surface : '#FFFFFF';
6937
- const borderColor = isDark ? theme.colors.gray[6] : '#E1E3E6';
6938
- const headerBg = isDark ? theme.backgrounds.subtle : surfaceColor;
6927
+ isDark ? theme.colors.gray[6] : '#E1E3E6';
6928
+ const headerBg = surfaceColor;
6939
6929
  const contentBg = surfaceColor;
6940
6930
  const dynamicStyles = reactNative.StyleSheet.create({
6941
6931
  backdrop: {
@@ -6946,24 +6936,28 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6946
6936
  }, // Allow backdropFilter on web
6947
6937
  modalContainer: {
6948
6938
  backgroundColor: contentBg,
6949
- borderRadius: variant === 'fullscreen' ? 0 : (variant === 'bottomsheet' ? 20 : 16),
6950
- borderBottomLeftRadius: variant === 'bottomsheet' ? 0 : undefined,
6951
- borderBottomRightRadius: variant === 'bottomsheet' ? 0 : undefined,
6939
+ borderRadius: variant === 'fullscreen' ? 0 : resolvedRadius,
6940
+ ...(variant === 'bottomsheet' ? {
6941
+ borderBottomLeftRadius: 0,
6942
+ borderBottomRightRadius: 0,
6943
+ } : {}),
6944
+ overflow: 'hidden', // Clip content to border radius
6952
6945
  // Clamp width to viewport (minus margins) while respecting provided width
6953
6946
  maxWidth: variant === 'fullscreen'
6954
6947
  ? '100%'
6955
6948
  : variant === 'bottomsheet'
6956
6949
  ? bottomSheetMaxWidth
6957
6950
  : defaultModalMaxWidth,
6958
- maxHeight: variant === 'fullscreen' ? '100%' : (height || '90%'),
6951
+ maxHeight: resolvedMaxHeight,
6959
6952
  width: variant === 'fullscreen'
6960
6953
  ? '100%'
6961
6954
  : variant === 'modal'
6962
6955
  ? modalEffectiveWidth || 'auto'
6963
6956
  : '100%',
6964
- height: variant === 'fullscreen' ? '100%' : (variant === 'modal' ? undefined : undefined),
6965
- // For modal variant, remove flex to allow fit-content behavior
6966
- ...(variant === 'modal' ? {} : { flex: 1 }),
6957
+ // Fullscreen uses 100% height, others auto-size to content
6958
+ height: variant === 'fullscreen' ? '100%' : undefined,
6959
+ // Only fullscreen should stretch to fill
6960
+ ...(variant === 'fullscreen' ? { flex: 1 } : {}),
6967
6961
  // Ensure minWidth never exceeds viewport clamp
6968
6962
  minWidth: variant === 'modal' ? Math.min(300, Math.max(200, screenWidth - horizontalMargin)) : undefined,
6969
6963
  alignSelf: variant === 'bottomsheet' ? 'center' : 'center',
@@ -6989,24 +6983,27 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6989
6983
  }
6990
6984
  : reactNative.Platform.OS === 'android' && variant !== 'fullscreen'
6991
6985
  ? { elevation: 16, }
6992
- : {
6993
- boxShadow: 'none',
6994
- height: '100%',
6995
- position: 'absolute',
6996
- }),
6986
+ : variant === 'fullscreen'
6987
+ ? {
6988
+ boxShadow: 'none',
6989
+ height: '100%',
6990
+ position: 'absolute',
6991
+ }
6992
+ : { boxShadow: 'none' }),
6997
6993
  }, // Allow boxShadow on web
6998
6994
  header: {
6999
6995
  alignItems: 'center',
7000
- backgroundColor: headerBg,
7001
- borderBottomColor: borderColor,
7002
- borderBottomWidth: variant === 'fullscreen' ? 0 : 1,
6996
+ backgroundColor: showHeader ? headerBg : 'transparent',
6997
+ // borderBottomColor: showHeader ? borderColor : 'transparent',
6998
+ // borderBottomWidth: showHeader && variant !== 'fullscreen' ? 1 : 0,
7003
6999
  flexDirection: isRTL ? 'row-reverse' : 'row',
7004
7000
  justifyContent: 'space-between',
7005
7001
  padding: 20,
7002
+ paddingBottom: title ? 0 : 20,
7006
7003
  },
7007
7004
  content: {
7008
- // For modal variant, remove flex to allow fit-content behavior
7009
- ...(variant === 'modal' ? {} : { flex: 1 }),
7005
+ // Only fullscreen content should stretch
7006
+ ...(variant === 'fullscreen' ? { flex: 1 } : {}),
7010
7007
  alignSelf: 'stretch',
7011
7008
  backgroundColor: contentBg,
7012
7009
  padding: variant === 'fullscreen' ? 0 : 20,
@@ -7062,8 +7059,10 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
7062
7059
  });
7063
7060
  const bottomSheetAnimatedStyle = Animated.useAnimatedStyle(() => {
7064
7061
  if (variant === 'bottomsheet') {
7062
+ // Clamp to 0 minimum to prevent seeing "under" the sheet
7063
+ const clampedY = Math.max(0, slideAnim.value);
7065
7064
  return {
7066
- transform: [{ translateY: slideAnim.value }],
7065
+ transform: [{ translateY: clampedY }],
7067
7066
  };
7068
7067
  }
7069
7068
  return {};
@@ -7080,7 +7079,7 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
7080
7079
  animatedStyle = bottomSheetAnimatedStyle;
7081
7080
  }
7082
7081
  return (jsxRuntime.jsxs(Animated.View, { style: [dynamicStyles.modalContainer, animatedStyle], ...(variant === 'bottomsheet' && bottomSheetSwipeZone === 'container' && panHandlers ? panHandlers : {}), children: [variant === 'bottomsheet' && (jsxRuntime.jsx(reactNative.View, { style: dynamicStyles.dragHandleContainer, ...(bottomSheetSwipeZone === 'handle' && panHandlers ? panHandlers : {}), children: jsxRuntime.jsx(reactNative.View, { style: dynamicStyles.dragHandle }) })), (title !== null &&
7083
- title && closable) && (jsxRuntime.jsxs(reactNative.View, { style: dynamicStyles.header, children: [jsxRuntime.jsx(Text, { variant: "h3", color: "text", children: title || '' }), closable && (jsxRuntime.jsx(Button, { variant: "ghost", onPress: handleClose, style: dynamicStyles.closeButton, children: jsxRuntime.jsx(Icon, { name: "x", size: "md" }) }))] })), jsxRuntime.jsx(reactNative.View, { style: [dynamicStyles.content, style], children: children })] }));
7082
+ title && closable) && (jsxRuntime.jsxs(reactNative.View, { style: dynamicStyles.header, children: [jsxRuntime.jsx(Text, { variant: "h3", color: "text", children: title || '' }), closable && variant !== 'bottomsheet' && (jsxRuntime.jsx(Button, { variant: "ghost", onPress: handleClose, style: dynamicStyles.closeButton, children: jsxRuntime.jsx(Icon, { name: "x", size: "md" }) }))] })), jsxRuntime.jsx(reactNative.View, { style: [dynamicStyles.content, style], children: children })] }));
7084
7083
  };
7085
7084
  return (jsxRuntime.jsx(reactNative.Modal, { visible: visible, transparent: true, animationType: "none", statusBarTranslucent: variant === 'fullscreen', children: jsxRuntime.jsxs(Animated.View, { style: [
7086
7085
  dynamicStyles.backdrop,
@@ -7289,7 +7288,7 @@ function DialogRenderer() {
7289
7288
  return null;
7290
7289
  // Render the topmost dialog
7291
7290
  const topDialog = dialogs[dialogs.length - 1];
7292
- return (jsxRuntime.jsx(Dialog, { visible: true, variant: topDialog.variant, title: topDialog.title, closable: topDialog.closable, backdrop: topDialog.backdrop, backdropClosable: topDialog.backdropClosable, shouldClose: topDialog.isClosing, onClose: () => removeDialog(topDialog.id), children: topDialog.content }));
7291
+ return (jsxRuntime.jsx(Dialog, { visible: true, variant: topDialog.variant, title: topDialog.title, closable: topDialog.closable, backdrop: topDialog.backdrop, backdropClosable: topDialog.backdropClosable, shouldClose: topDialog.isClosing, onClose: () => removeDialog(topDialog.id), w: topDialog.w, h: topDialog.h, radius: topDialog.radius, style: topDialog.style, showHeader: topDialog.showHeader, children: topDialog.content }));
7293
7292
  }
7294
7293
 
7295
7294
  const Flex = factory((props, ref) => {
@@ -8374,7 +8373,14 @@ const getContrastPreference = () => {
8374
8373
  return 'less';
8375
8374
  return 'no-preference';
8376
8375
  };
8377
- const getColorScheme = () => { var _a, _b; return (_b = (_a = reactNative.Appearance === null || reactNative.Appearance === void 0 ? void 0 : reactNative.Appearance.getColorScheme) === null || _a === void 0 ? void 0 : _a.call(reactNative.Appearance)) !== null && _b !== void 0 ? _b : 'no-preference'; };
8376
+ const getColorScheme = () => {
8377
+ var _a;
8378
+ const scheme = (_a = reactNative.Appearance === null || reactNative.Appearance === void 0 ? void 0 : reactNative.Appearance.getColorScheme) === null || _a === void 0 ? void 0 : _a.call(reactNative.Appearance);
8379
+ // Handle 'unspecified' from newer React Native versions
8380
+ if (scheme === 'light' || scheme === 'dark')
8381
+ return scheme;
8382
+ return 'no-preference';
8383
+ };
8378
8384
  const getReducedMotion = async () => {
8379
8385
  if (reactNative.Platform.OS === 'web') {
8380
8386
  if (typeof window === 'undefined' || typeof window.matchMedia !== 'function')
@@ -8599,7 +8605,13 @@ function useDeviceInfo(options = {}) {
8599
8605
  React.useEffect(() => {
8600
8606
  var _a;
8601
8607
  const colorSubscription = (_a = reactNative.Appearance === null || reactNative.Appearance === void 0 ? void 0 : reactNative.Appearance.addChangeListener) === null || _a === void 0 ? void 0 : _a.call(reactNative.Appearance, ({ colorScheme: scheme }) => {
8602
- setColorScheme(scheme !== null && scheme !== void 0 ? scheme : 'no-preference');
8608
+ // Handle 'unspecified' from newer React Native versions
8609
+ if (scheme === 'light' || scheme === 'dark') {
8610
+ setColorScheme(scheme);
8611
+ }
8612
+ else {
8613
+ setColorScheme('no-preference');
8614
+ }
8603
8615
  });
8604
8616
  const mediaListeners = [];
8605
8617
  let boldSubscription;
@@ -9144,7 +9156,7 @@ function SpotlightRoot({ query, onQueryChange, children, opened = false, onClose
9144
9156
  const targetWidth = Math.min(560, Math.max(280, screenWidth - horizontalMargin));
9145
9157
  // (Hotkey registration moved to main Spotlight component for access to store.toggle())
9146
9158
  const fullscreen = shouldUseModal;
9147
- return (jsxRuntime.jsx(Dialog, { visible: opened, onClose: onClose, variant: fullscreen ? 'fullscreen' : 'modal', backdrop: true, backdropClosable: true, width: fullscreen ? undefined : targetWidth, title: null, style: [
9159
+ return (jsxRuntime.jsx(Dialog, { visible: opened, onClose: onClose, variant: fullscreen ? 'fullscreen' : 'modal', backdrop: true, backdropClosable: true, w: fullscreen ? undefined : targetWidth, title: null, style: [
9148
9160
  styles$e.spotlightModal,
9149
9161
  fullscreen && { width: '100%', height: '100%', maxHeight: '100%', borderRadius: 0, position: 'fixed', top: 0, left: 0 },
9150
9162
  !fullscreen && {
@@ -9706,6 +9718,23 @@ function generateUniversalCSS() {
9706
9718
  xl: '88em'
9707
9719
  };
9708
9720
  const universalCSS = `
9721
+ /* Reset browser default input styles to prevent double borders */
9722
+ input, textarea, select {
9723
+ outline: none !important;
9724
+ -webkit-appearance: none !important;
9725
+ -moz-appearance: none !important;
9726
+ appearance: none !important;
9727
+ }
9728
+
9729
+ input:focus, textarea:focus, select:focus {
9730
+ outline: none !important;
9731
+ }
9732
+
9733
+ /* Ensure React Native Web focusable elements don't show browser outlines */
9734
+ [data-focusable="true"]:focus {
9735
+ outline: none !important;
9736
+ }
9737
+
9709
9738
  /* Color scheme based visibility */
9710
9739
  .platform-blocks-light-hidden {
9711
9740
  display: none !important;
@@ -9752,12 +9781,14 @@ function UniversalCSS() {
9752
9781
  return;
9753
9782
  }
9754
9783
  // Check if styles are already injected
9755
- const existingStyle = document.getElementById('platform-blocks-universal-css');
9756
- if (existingStyle) {
9784
+ let styleElement = document.getElementById('platform-blocks-universal-css');
9785
+ if (styleElement) {
9786
+ // Update content if it exists (in case CSS changed)
9787
+ styleElement.textContent = css;
9757
9788
  return;
9758
9789
  }
9759
9790
  // Create and inject styles
9760
- const styleElement = document.createElement('style');
9791
+ styleElement = document.createElement('style');
9761
9792
  styleElement.id = 'platform-blocks-universal-css';
9762
9793
  styleElement.textContent = css;
9763
9794
  document.head.appendChild(styleElement);
@@ -11881,9 +11912,10 @@ const Row = ({ direction = 'row', gap = 'sm', ...props }) => {
11881
11912
  };
11882
11913
  /**
11883
11914
  * Column component - alias for Flex with direction="column"
11915
+ * Defaults to fullWidth={true} since vertical layouts typically fill available width
11884
11916
  */
11885
- const Column = ({ direction = 'column', gap = 'sm', ...props }) => {
11886
- return jsxRuntime.jsx(Flex, { direction: direction, gap: gap, ...props });
11917
+ const Column = ({ direction = 'column', gap = 'sm', fullWidth = true, ...props }) => {
11918
+ return jsxRuntime.jsx(Flex, { direction: direction, gap: gap, fullWidth: fullWidth, ...props });
11887
11919
  };
11888
11920
  Row.displayName = 'Row';
11889
11921
 
@@ -13998,35 +14030,101 @@ function createNativeHighlighter(theme, isDark, variant = 'code', overrides) {
13998
14030
  };
13999
14031
  }
14000
14032
 
14001
- // Prism light build for JSX/TSX (react-syntax-highlighter)
14033
+ // Syntax highlighter - only loaded on web, native uses built-in tokenizer
14034
+ // These are initialized lazily on first use to avoid Metro bundling issues
14002
14035
  let PrismSyntaxHighlighter = null;
14003
14036
  let prismLightTheme = null;
14004
14037
  let prismDarkTheme = null;
14005
- if (reactNative.Platform.OS === 'web') {
14006
- PrismSyntaxHighlighter = resolveOptionalModule('react-syntax-highlighter', {
14007
- accessor: (module) => module.PrismLight,
14008
- devWarning: 'react-syntax-highlighter not found, CodeBlock will use basic formatting',
14009
- });
14010
- if (PrismSyntaxHighlighter) {
14011
- const registerLanguage = (moduleId, name) => {
14012
- const languageModule = resolveOptionalModule(moduleId, { accessor: (mod) => mod.default });
14013
- if (languageModule) {
14014
- PrismSyntaxHighlighter.registerLanguage(name, languageModule);
14038
+ let syntaxHighlighterInitialized = false;
14039
+ // Use indirect require via new Function to prevent Metro from statically analyzing imports
14040
+ // Metro bundles ALL require() calls it finds, even in try-catch blocks
14041
+ // new Function() creates a runtime-evaluated require that Metro can't see
14042
+ const safeRequire = (() => {
14043
+ try {
14044
+ // This creates: function(moduleName) { return require(moduleName); }
14045
+ // The string 'require' is not statically analyzable by Metro
14046
+ return new Function('moduleName', 'return require(moduleName)');
14047
+ }
14048
+ catch (_a) {
14049
+ return null;
14050
+ }
14051
+ })();
14052
+ function initSyntaxHighlighter() {
14053
+ if (syntaxHighlighterInitialized)
14054
+ return;
14055
+ syntaxHighlighterInitialized = true;
14056
+ // Only attempt to load on web
14057
+ if (reactNative.Platform.OS !== 'web')
14058
+ return;
14059
+ if (!safeRequire)
14060
+ return;
14061
+ try {
14062
+ const rsh = safeRequire('react-syntax-highlighter');
14063
+ PrismSyntaxHighlighter = rsh.PrismLight;
14064
+ if (PrismSyntaxHighlighter) {
14065
+ // Register languages
14066
+ try {
14067
+ const jsx = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/jsx').default;
14068
+ PrismSyntaxHighlighter.registerLanguage('jsx', jsx);
14015
14069
  }
14016
- };
14017
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/jsx', 'jsx');
14018
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/tsx', 'tsx');
14019
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/typescript', 'typescript');
14020
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/javascript', 'javascript');
14021
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/json', 'json');
14022
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/bash', 'bash');
14023
- prismLightTheme = resolveOptionalModule('react-syntax-highlighter/dist/esm/styles/prism/prism', {
14024
- accessor: (mod) => mod.default,
14025
- });
14026
- prismDarkTheme = resolveOptionalModule('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus', {
14027
- accessor: (mod) => mod.default,
14028
- devWarning: 'Failed to load prism vsc-dark-plus theme, falling back to prism',
14029
- });
14070
+ catch (_a) {
14071
+ // Language not available
14072
+ }
14073
+ try {
14074
+ const tsx = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/tsx').default;
14075
+ PrismSyntaxHighlighter.registerLanguage('tsx', tsx);
14076
+ }
14077
+ catch (_b) {
14078
+ // Language not available
14079
+ }
14080
+ try {
14081
+ const ts = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/typescript').default;
14082
+ PrismSyntaxHighlighter.registerLanguage('typescript', ts);
14083
+ }
14084
+ catch (_c) {
14085
+ // Language not available
14086
+ }
14087
+ try {
14088
+ const js = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/javascript').default;
14089
+ PrismSyntaxHighlighter.registerLanguage('javascript', js);
14090
+ }
14091
+ catch (_d) {
14092
+ // Language not available
14093
+ }
14094
+ try {
14095
+ const json = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/json').default;
14096
+ PrismSyntaxHighlighter.registerLanguage('json', json);
14097
+ }
14098
+ catch (_e) {
14099
+ // Language not available
14100
+ }
14101
+ try {
14102
+ const bash = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/bash').default;
14103
+ PrismSyntaxHighlighter.registerLanguage('bash', bash);
14104
+ }
14105
+ catch (_f) {
14106
+ // Language not available
14107
+ }
14108
+ // Load themes
14109
+ try {
14110
+ prismLightTheme = safeRequire('react-syntax-highlighter/dist/esm/styles/prism/prism').default;
14111
+ }
14112
+ catch (_g) {
14113
+ // Theme not available
14114
+ }
14115
+ try {
14116
+ prismDarkTheme = safeRequire('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus').default;
14117
+ }
14118
+ catch (_h) {
14119
+ // Theme not available
14120
+ }
14121
+ }
14122
+ }
14123
+ catch (_j) {
14124
+ // react-syntax-highlighter not installed, will use native fallback
14125
+ if (__DEV__) {
14126
+ console.warn('[platform-blocks] react-syntax-highlighter not found, CodeBlock will use basic formatting');
14127
+ }
14030
14128
  }
14031
14129
  }
14032
14130
  const NO_HIGHLIGHTS = new Set();
@@ -14250,6 +14348,8 @@ const FloatingCopyControls = ({ visible, code, onCopy, topOffset, isWeb }) => (j
14250
14348
  }, children: jsxRuntime.jsx(CopyButton, { value: code, onCopy: onCopy, iconOnly: true, size: "sm", tooltip: "Copy code", tooltipPosition: "left", style: { minHeight: 32, minWidth: 32 } }) }));
14251
14349
  const CodeBlock = (props) => {
14252
14350
  var _a, _b, _c;
14351
+ // Initialize syntax highlighter on first render (web only)
14352
+ React.useMemo(() => initSyntaxHighlighter(), []);
14253
14353
  const { children, title, fileName, fileIcon, language = 'tsx', showLineNumbers = false, highlight = true, fullWidth = true, showCopyButton = true, onCopy, style, textStyle, titleStyle, highlightLines, spoiler = false, spoilerMaxHeight = 160, variant = 'code', promptSymbol = '$', githubUrl, fileHeader = false, colors, wrap = true, ...rest } = props;
14254
14354
  const { spacingProps, otherProps } = extractSpacingProps(rest);
14255
14355
  const spacingStyles = getSpacingStyles(spacingProps);
@@ -14264,6 +14364,7 @@ const CodeBlock = (props) => {
14264
14364
  const [hovered, setHovered] = React.useState(false);
14265
14365
  const [codeHeight, setCodeHeight] = React.useState(null);
14266
14366
  const isWeb = reactNative.Platform.OS === 'web';
14367
+ const webWhitespaceStyle = React.useMemo(() => (isWeb ? { whiteSpace: wrap ? 'pre-wrap' : 'pre', display: 'block' } : null), [isWeb, wrap]);
14267
14368
  const showFloatingCopy = showCopyButton && !title && !fileName;
14268
14369
  const showCopyVisible = !isWeb ? showFloatingCopy : showFloatingCopy && hovered;
14269
14370
  const codeData = React.useMemo(() => {
@@ -14297,6 +14398,7 @@ const CodeBlock = (props) => {
14297
14398
  boxSizing: 'border-box',
14298
14399
  paddingLeft: showLineNumbers ? 0 : 12,
14299
14400
  paddingRight: showLineNumbers ? 0 : 12,
14401
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14300
14402
  }), [showLineNumbers, wrap]);
14301
14403
  const highlightedLineStyle = React.useMemo(() => ({
14302
14404
  backgroundColor: highlightBackgroundColor,
@@ -14308,6 +14410,18 @@ const CodeBlock = (props) => {
14308
14410
  const tokenLines = React.useMemo(() => (highlight ? nativeHighlighter(codeData.transformed) : null), [highlight, nativeHighlighter, codeData.transformed]);
14309
14411
  const shouldVirtualizeNative = !isWeb && codeData.lineCount >= LONG_LIST_THRESHOLD;
14310
14412
  const lineHeight = (_c = styles.codeText.lineHeight) !== null && _c !== void 0 ? _c : 18;
14413
+ const normalizeTokenText = React.useCallback((text, tokenIndex) => {
14414
+ if (!isWeb || !text)
14415
+ return text;
14416
+ const replaceSpaces = (value) => value.replace(/\t/g, ' ').replace(/ /g, '\u00A0');
14417
+ if (tokenIndex === 0) {
14418
+ return text.replace(/^[\t ]+/, (match) => replaceSpaces(match));
14419
+ }
14420
+ if (text.trim().length === 0) {
14421
+ return replaceSpaces(text);
14422
+ }
14423
+ return text;
14424
+ }, [isWeb]);
14311
14425
  const buildNativeLine = React.useCallback((line, index, appendNewline, includeKey) => {
14312
14426
  var _a;
14313
14427
  const lineNumber = index + 1;
@@ -14316,13 +14430,14 @@ const CodeBlock = (props) => {
14316
14430
  const lineStyles = [
14317
14431
  styles.codeText,
14318
14432
  textStyle,
14433
+ webWhitespaceStyle,
14319
14434
  wrap ? { flexWrap: 'wrap' } : { flexWrap: 'nowrap', width: 'auto' },
14320
14435
  ];
14321
14436
  if (isLineHighlighted) {
14322
14437
  lineStyles.push(styles.highlightedLine(isDark, highlightColors));
14323
14438
  }
14324
- return (jsxRuntime.jsxs(Text, { selectable: true, style: lineStyles, children: [showLineNumbers ? (jsxRuntime.jsx(Text, { style: { color: lineNumberColor, opacity: 0.7 }, children: `${String(lineNumber).padStart(lineNumberWidth, ' ')} | ` })) : null, tokens.map((token, tokenIdx) => (jsxRuntime.jsx(Text, { style: { color: token.color }, children: token.text || ' ' }, `${lineNumber}-${tokenIdx}`))), appendNewline ? '\n' : null] }, includeKey ? `line-${lineNumber}` : undefined));
14325
- }, [fallbackColor, highlightColors, highlightSet, isDark, lineNumberColor, lineNumberWidth, showLineNumbers, styles.codeText, styles.highlightedLine, textStyle, tokenLines, wrap]);
14439
+ return (jsxRuntime.jsxs(Text, { selectable: true, style: lineStyles, children: [showLineNumbers ? (jsxRuntime.jsx(Text, { style: { color: lineNumberColor, opacity: 0.7 }, children: `${String(lineNumber).padStart(lineNumberWidth, ' ')} | ` })) : null, tokens.map((token, tokenIdx) => (jsxRuntime.jsx(Text, { style: { color: token.color }, children: normalizeTokenText(token.text || ' ', tokenIdx) }, `${lineNumber}-${tokenIdx}`))), appendNewline ? '\n' : null] }, includeKey ? `line-${lineNumber}` : undefined));
14440
+ }, [fallbackColor, highlightColors, highlightSet, isDark, lineNumberColor, lineNumberWidth, normalizeTokenText, showLineNumbers, styles.codeText, styles.highlightedLine, textStyle, tokenLines, webWhitespaceStyle, wrap]);
14326
14441
  const renderWebCode = React.useMemo(() => {
14327
14442
  if (!(isWeb && highlight && PrismSyntaxHighlighter)) {
14328
14443
  return null;
@@ -14336,7 +14451,13 @@ const CodeBlock = (props) => {
14336
14451
  lineHeight: '18px',
14337
14452
  display: 'block',
14338
14453
  width: '100%',
14339
- }, codeTagProps: { style: { fontFamily: styles.codeText.fontFamily } }, wrapLongLines: wrap, wrapLines: wrap, showLineNumbers: prismShowLineNumbers, lineNumberStyle: hideLineNumbersVisually
14454
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14455
+ }, codeTagProps: {
14456
+ style: {
14457
+ fontFamily: styles.codeText.fontFamily,
14458
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14459
+ },
14460
+ }, wrapLongLines: wrap, wrapLines: wrap, showLineNumbers: prismShowLineNumbers, lineNumberStyle: hideLineNumbersVisually
14340
14461
  ? { display: 'none' }
14341
14462
  : { opacity: 0.55, paddingRight: 12, userSelect: 'none' }, lineProps: (lineNumber) => {
14342
14463
  const style = { ...baseLineStyle };
@@ -14369,13 +14490,13 @@ const CodeBlock = (props) => {
14369
14490
  ]);
14370
14491
  const renderNativeCode = React.useMemo(() => {
14371
14492
  if (!codeData.lineCount) {
14372
- return (jsxRuntime.jsx(Text, { selectable: true, style: [styles.codeText, textStyle], children: ' ' }));
14493
+ return (jsxRuntime.jsx(Text, { selectable: true, style: [styles.codeText, textStyle, webWhitespaceStyle], children: ' ' }));
14373
14494
  }
14374
14495
  if (shouldVirtualizeNative) {
14375
14496
  return (jsxRuntime.jsx(reactNative.FlatList, { data: codeData.lines, keyExtractor: (_, index) => `line-${index}`, renderItem: ({ item, index }) => buildNativeLine(item, index, false, false), initialNumToRender: 20, maxToRenderPerBatch: 40, windowSize: 7, removeClippedSubviews: true, getItemLayout: (_, index) => ({ length: lineHeight, offset: lineHeight * index, index }) }));
14376
14497
  }
14377
- return (jsxRuntime.jsx(Text, { selectable: true, style: [styles.codeText, textStyle], children: codeData.lines.map((line, idx) => buildNativeLine(line, idx, idx < codeData.lineCount - 1, true)) }));
14378
- }, [buildNativeLine, codeData.lineCount, codeData.lines, lineHeight, shouldVirtualizeNative, styles.codeText, textStyle]);
14498
+ return (jsxRuntime.jsx(Text, { selectable: true, style: [styles.codeText, textStyle, webWhitespaceStyle], children: codeData.lines.map((line, idx) => buildNativeLine(line, idx, idx < codeData.lineCount - 1, true)) }));
14499
+ }, [buildNativeLine, codeData.lineCount, codeData.lines, lineHeight, shouldVirtualizeNative, styles.codeText, textStyle, webWhitespaceStyle]);
14379
14500
  const codeContent = renderWebCode !== null && renderWebCode !== void 0 ? renderWebCode : renderNativeCode;
14380
14501
  const scrollableCodeContent = wrap ? (codeContent) : (jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, bounces: false, showsHorizontalScrollIndicator: true, showsVerticalScrollIndicator: false, contentContainerStyle: { flexGrow: 1 }, style: { width: '100%' }, children: jsxRuntime.jsx(reactNative.View, { style: { flexGrow: 1 }, children: codeContent }) }));
14381
14502
  let wrappedCodeContent = scrollableCodeContent;
@@ -15980,11 +16101,13 @@ const BrandButton = (props) => {
15980
16101
  return {
15981
16102
  backgroundColor: 'transparent',
15982
16103
  borderColor: brandConfig.borderColor || brandConfig.backgroundColor,
16104
+ paddingHorizontal: 16,
15983
16105
  };
15984
16106
  case 'ghost':
15985
16107
  return {
15986
16108
  backgroundColor: 'transparent',
15987
16109
  borderColor: 'transparent',
16110
+ paddingHorizontal: 16,
15988
16111
  };
15989
16112
  case 'link':
15990
16113
  return { backgroundColor: 'transparent', borderColor: 'transparent' };
@@ -15992,7 +16115,7 @@ const BrandButton = (props) => {
15992
16115
  return {
15993
16116
  backgroundColor: 'white',
15994
16117
  borderColor: 'transparent',
15995
- paddingHorizontal: 0,
16118
+ paddingHorizontal: 16,
15996
16119
  minWidth: 0,
15997
16120
  height: 'auto',
15998
16121
  color: 'black'
@@ -16001,6 +16124,7 @@ const BrandButton = (props) => {
16001
16124
  return {
16002
16125
  backgroundColor: brandConfig.backgroundColor,
16003
16126
  borderColor: brandConfig.borderColor || brandConfig.backgroundColor,
16127
+ paddingHorizontal: 16,
16004
16128
  };
16005
16129
  }
16006
16130
  })();
@@ -16577,8 +16701,12 @@ const createInputStyles = (theme, isRTL = false) => {
16577
16701
  // Remove any web-specific styling that could interfere
16578
16702
  ...(typeof window !== 'undefined' && {
16579
16703
  outlineWidth: 0,
16704
+ outlineStyle: 'none',
16580
16705
  border: 'none',
16706
+ borderWidth: 0,
16707
+ boxShadow: 'none',
16581
16708
  backgroundColor: 'transparent',
16709
+ boxSizing: 'border-box',
16582
16710
  }),
16583
16711
  },
16584
16712
  inputContainer: {
@@ -17506,7 +17634,7 @@ const TextArea = factory((props, ref) => {
17506
17634
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(props);
17507
17635
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
17508
17636
  const { value, defaultValue = '', onChangeText, label, disabled = false, required = false, placeholder, error, helperText, description, size = 'md', radius = 'md', rows = 3, minRows = 1, maxRows, autoResize = false, maxLength, showCharCounter = false, resize = 'none', textInputProps = {}, style, testID, clearable, clearButtonLabel, onClear, ...rest } = otherProps;
17509
- const { height } = layoutProps;
17637
+ const { h } = layoutProps;
17510
17638
  const theme = useTheme();
17511
17639
  const { getTextAreaStyles } = useTextAreaStyles({ theme });
17512
17640
  const [focused, setFocused] = React.useState(false);
@@ -17570,11 +17698,11 @@ const TextArea = factory((props, ref) => {
17570
17698
  const inputContainerStyles = [
17571
17699
  styles.inputContainer,
17572
17700
  radiusStyles,
17573
- { height }
17701
+ { height: h }
17574
17702
  ];
17575
17703
  const textInputStyles = [
17576
17704
  styles.textInput,
17577
- { height: height || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17705
+ { height: h || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17578
17706
  textAlignVertical: resize === 'none' ? 'top' : undefined,
17579
17707
  // Disable resizing by user if resize is 'none'
17580
17708
  ...(resize === 'none' ? { resizeMode: 'none' } : {})
@@ -17602,7 +17730,7 @@ const TextArea = factory((props, ref) => {
17602
17730
  const clearLabel = clearButtonLabel || 'Clear input';
17603
17731
  return (jsxRuntime.jsxs(reactNative.View, { style: containerStyles, testID: testID, children: [(label || description) && (jsxRuntime.jsx(FieldHeader, { label: label, description: description, required: required, disabled: disabled, error: !!error })), jsxRuntime.jsxs(reactNative.View, { style: [inputContainerStyles, { position: 'relative' }], children: [jsxRuntime.jsx(reactNative.TextInput, { ref: assignRef,
17604
17732
  // style={]}
17605
- style: { height: height || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17733
+ style: { height: h || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17606
17734
  ...textInputStyles.reduce((acc, style) => ({ ...acc, ...style }), {}),
17607
17735
  textAlignVertical: resize === 'none' ? 'top' : undefined,
17608
17736
  // Disable resizing by user if resize is 'none'
@@ -23928,7 +24056,7 @@ const Select = factory((allProps, ref) => {
23928
24056
  var _a;
23929
24057
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(allProps);
23930
24058
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
23931
- const { value: valueProp, defaultValue, onChange, options, placeholder = 'Select…', size = 'md', radius = 'md', disabled, label, helperText, description, error, renderOption, fullWidth, maxHeight = 260, closeOnSelect = true, clearable, clearButtonLabel, onClear, refocusAfterSelect, keyboardAvoidance = true, } = otherProps;
24059
+ const { value: valueProp, defaultValue, onChange, options, placeholder = 'Select…', size = 'md', radius = 'md', disabled, label, helperText, description, error, renderOption, fullWidth, maxH = 260, closeOnSelect = true, clearable, clearButtonLabel, onClear, refocusAfterSelect, keyboardAvoidance = true, } = otherProps;
23932
24060
  const theme = useTheme();
23933
24061
  const { shouldUseModal, shouldUseOverlay } = useOverlayMode();
23934
24062
  const menuStyles = useMenuStyles();
@@ -23950,6 +24078,7 @@ const Select = factory((allProps, ref) => {
23950
24078
  keyboardAvoidance,
23951
24079
  closeOnClickOutside: true,
23952
24080
  closeOnEscape: true,
24081
+ matchAnchorWidth: true,
23953
24082
  onClose: () => setOpen(false),
23954
24083
  });
23955
24084
  const hasMeasuredDropdownRef = React.useRef(false);
@@ -24083,11 +24212,11 @@ const Select = factory((allProps, ref) => {
24083
24212
  }, [position === null || position === void 0 ? void 0 : position.finalWidth, triggerWidth]);
24084
24213
  const resolvedDropdownMaxHeight = React.useMemo(() => {
24085
24214
  const keyboardMax = typeof (position === null || position === void 0 ? void 0 : position.maxHeight) === 'number' ? position.maxHeight : undefined;
24086
- if (typeof maxHeight === 'number') {
24087
- return keyboardMax ? Math.min(maxHeight, keyboardMax) : maxHeight;
24215
+ if (typeof maxH === 'number') {
24216
+ return keyboardMax ? Math.min(maxH, keyboardMax) : maxH;
24088
24217
  }
24089
- return keyboardMax !== null && keyboardMax !== void 0 ? keyboardMax : maxHeight;
24090
- }, [maxHeight, position === null || position === void 0 ? void 0 : position.maxHeight]);
24218
+ return keyboardMax !== null && keyboardMax !== void 0 ? keyboardMax : maxH;
24219
+ }, [maxH, position === null || position === void 0 ? void 0 : position.maxHeight]);
24091
24220
  const handleSelect = React.useCallback((opt) => {
24092
24221
  if (opt.disabled)
24093
24222
  return;
@@ -24109,7 +24238,7 @@ const Select = factory((allProps, ref) => {
24109
24238
  close();
24110
24239
  }
24111
24240
  }, [closeOnSelect, close, onChange, valueProp, refocusAfterSelect, keyboardManager, focusTrigger, blurTrigger]);
24112
- const listMaxHeight = resolvedDropdownMaxHeight !== null && resolvedDropdownMaxHeight !== void 0 ? resolvedDropdownMaxHeight : maxHeight;
24241
+ const listMaxHeight = resolvedDropdownMaxHeight !== null && resolvedDropdownMaxHeight !== void 0 ? resolvedDropdownMaxHeight : maxH;
24113
24242
  const menu = React.useMemo(() => {
24114
24243
  const widthStyle = resolvedDropdownWidth && resolvedDropdownWidth > 0
24115
24244
  ? { width: resolvedDropdownWidth, minWidth: resolvedDropdownWidth }
@@ -24122,18 +24251,17 @@ const Select = factory((allProps, ref) => {
24122
24251
  ...(maxHeightStyle !== null && maxHeightStyle !== void 0 ? maxHeightStyle : {}),
24123
24252
  ...(widthStyle !== null && widthStyle !== void 0 ? widthStyle : {}),
24124
24253
  }, children: jsxRuntime.jsx(reactNative.FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item }) => {
24125
- var _a;
24126
24254
  const selected = item.value === value;
24127
24255
  if (renderOption) {
24128
24256
  return jsxRuntime.jsx(reactNative.View, { children: renderOption(item, false, selected) });
24129
24257
  }
24130
24258
  const primaryPalette = theme.colors.primary || [];
24131
24259
  const highlightColor = theme.colorScheme === 'dark'
24132
- ? primaryPalette[2] || primaryPalette[3] || theme.text.onPrimary || theme.text.primary
24133
- : primaryPalette[6] || primaryPalette[5] || ((_a = theme.colors.secondary) === null || _a === void 0 ? void 0 : _a[6]) || '#6941C6';
24260
+ ? primaryPalette[5] || primaryPalette[4] || '#60A5FA'
24261
+ : primaryPalette[6] || primaryPalette[5] || '#3B82F6';
24134
24262
  const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
24135
- const accentTextColor = item.disabled ? theme.text.disabled : highlightColor;
24136
- return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: selected, tone: selected ? 'primary' : 'default', hoverTone: "primary", activeTone: "primary", textColor: baseTextColor, hoverTextColor: accentTextColor, activeTextColor: accentTextColor, compact: true, rounded: false, style: { borderRadius: 0 }, children: item.label }));
24263
+ item.disabled ? theme.text.disabled : highlightColor;
24264
+ return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: false, tone: "default", hoverTone: "default", activeTone: "default", textColor: baseTextColor, hoverTextColor: baseTextColor, activeTextColor: baseTextColor, startIcon: selected ? jsxRuntime.jsx(Icon, { name: "check", size: 16, color: highlightColor }) : jsxRuntime.jsx(reactNative.View, { style: { width: 16 } }), compact: true, rounded: false, style: { borderRadius: 0 }, children: item.label }));
24137
24265
  }, ItemSeparatorComponent: renderOption ? undefined : ListGroupDivider, style: maxHeightStyle, bounces: false }) }) }));
24138
24266
  }, [resolvedDropdownWidth, listMaxHeight, menuStyles.dropdown, options, value, renderOption, theme.colors.primary, theme.colors.secondary, theme.colorScheme, theme.text.disabled, theme.text.primary, theme.text.onPrimary, handleSelect]);
24139
24267
  React.useEffect(() => {
@@ -24315,6 +24443,7 @@ const AutoComplete = factory((props, ref) => {
24315
24443
  offset,
24316
24444
  autoUpdate: autoReposition,
24317
24445
  fallbackPlacements,
24446
+ matchAnchorWidth: true,
24318
24447
  });
24319
24448
  // Guard: remember last popover size to avoid re-triggering updatePosition on position-only changes
24320
24449
  const lastPopoverSizeRef = React.useRef(null);
@@ -24338,13 +24467,12 @@ const AutoComplete = factory((props, ref) => {
24338
24467
  }, radiusStyles), [inputStyleFactory, size, focused, error, disabled, showClearButton, radiusStyles]);
24339
24468
  const clearLabel = clearButtonLabel || 'Clear input';
24340
24469
  const menuHighlightColor = React.useMemo(() => {
24341
- var _a;
24342
24470
  const primaryPalette = theme.colors.primary || [];
24343
24471
  if (theme.colorScheme === 'dark') {
24344
- return primaryPalette[2] || primaryPalette[3] || theme.text.onPrimary || theme.text.primary;
24472
+ return primaryPalette[5] || primaryPalette[4] || '#60A5FA';
24345
24473
  }
24346
- return primaryPalette[6] || primaryPalette[5] || ((_a = theme.colors.secondary) === null || _a === void 0 ? void 0 : _a[6]) || '#6941C6';
24347
- }, [theme.colors.primary, theme.colors.secondary, theme.colorScheme, theme.text.onPrimary, theme.text.primary]);
24474
+ return primaryPalette[6] || primaryPalette[5] || '#3B82F6';
24475
+ }, [theme.colors.primary, theme.colorScheme]);
24348
24476
  const selectedCount = (_a = selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.length) !== null && _a !== void 0 ? _a : 0;
24349
24477
  const hasSelectedValues = multiSelect && selectedCount > 0;
24350
24478
  const currentQueryRef = React.useRef(query);
@@ -24662,8 +24790,8 @@ const AutoComplete = factory((props, ref) => {
24662
24790
  const defaultRenderItem = React.useCallback((item, index, isSelected = false) => {
24663
24791
  const highlightQuery = highlightMatches ? currentQueryRef.current : undefined;
24664
24792
  const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
24665
- const accentTextColor = item.disabled ? theme.text.disabled : menuHighlightColor;
24666
- return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelectSuggestion(item), disabled: item.disabled, active: isSelected, tone: isSelected ? 'primary' : 'default', hoverTone: "primary", activeTone: "primary", textColor: baseTextColor, hoverTextColor: accentTextColor, activeTextColor: accentTextColor, compact: true, rounded: false, style: [styles.menuItemButton, suggestionItemStyle], ...(reactNative.Platform.OS === 'web' ? {
24793
+ item.disabled ? theme.text.disabled : menuHighlightColor;
24794
+ return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelectSuggestion(item), disabled: item.disabled, active: false, tone: "default", hoverTone: "default", activeTone: "default", textColor: baseTextColor, hoverTextColor: baseTextColor, activeTextColor: baseTextColor, startIcon: isSelected ? jsxRuntime.jsx(Icon, { name: "check", size: 16, color: menuHighlightColor }) : jsxRuntime.jsx(reactNative.View, { style: { width: 16 } }), compact: true, rounded: false, style: [styles.menuItemButton, suggestionItemStyle], ...(reactNative.Platform.OS === 'web' ? {
24667
24795
  onMouseDown: (event) => {
24668
24796
  if (event === null || event === void 0 ? void 0 : event.preventDefault) {
24669
24797
  event.preventDefault();
@@ -27172,7 +27300,7 @@ const DatePickerInput = React.forwardRef(function DatePickerInputInner({ value,
27172
27300
  } }));
27173
27301
  }
27174
27302
  if (dropdownType === 'modal') {
27175
- return (jsxRuntime.jsxs(reactNative.View, { ref: ref, children: [renderInput(), jsxRuntime.jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, width: numberOfMonths > 1 ? Math.min(700, 380 * numberOfMonths + 40) : 400, title: type === 'range'
27303
+ return (jsxRuntime.jsxs(reactNative.View, { ref: ref, children: [renderInput(), jsxRuntime.jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, w: numberOfMonths > 1 ? Math.min(700, 380 * numberOfMonths + 40) : 400, title: type === 'range'
27176
27304
  ? 'Select Date Range'
27177
27305
  : type === 'multiple'
27178
27306
  ? 'Select Dates'
@@ -27201,7 +27329,7 @@ const DatePickerInput = React.forwardRef(function DatePickerInputInner({ value,
27201
27329
  backgroundColor: pressed ? theme.colors.primary[6] : theme.colors.primary[5],
27202
27330
  }), children: jsxRuntime.jsx(Text, { size: "sm", weight: "semibold", style: { color: 'white' }, children: "Done" }) })] })] }) }))] }) })] }));
27203
27331
  }
27204
- return (jsxRuntime.jsxs(reactNative.View, { ref: ref, children: [renderInput(), jsxRuntime.jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, width: numberOfMonths > 1 ? Math.min(600, 320 * numberOfMonths + 40) : 350, children: jsxRuntime.jsxs(reactNative.View, { ref: focusTrapRef, style: { padding: DESIGN_TOKENS.spacing.lg }, accessible: true, accessibilityLabel: type === 'range'
27332
+ return (jsxRuntime.jsxs(reactNative.View, { ref: ref, children: [renderInput(), jsxRuntime.jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, w: numberOfMonths > 1 ? Math.min(600, 320 * numberOfMonths + 40) : 350, children: jsxRuntime.jsxs(reactNative.View, { ref: focusTrapRef, style: { padding: DESIGN_TOKENS.spacing.lg }, accessible: true, accessibilityLabel: type === 'range'
27205
27333
  ? 'Date range picker dialog'
27206
27334
  : type === 'multiple'
27207
27335
  ? 'Multiple date picker dialog'
@@ -27296,7 +27424,7 @@ const MonthPickerInput = React.forwardRef(function MonthPickerInput({ value, def
27296
27424
  pointerEvents: 'none',
27297
27425
  accessible: false,
27298
27426
  focusable: false,
27299
- } }) }), jsxRuntime.jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, width: 360, children: jsxRuntime.jsx(reactNative.View, { style: {
27427
+ } }) }), jsxRuntime.jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, w: 360, children: jsxRuntime.jsx(reactNative.View, { style: {
27300
27428
  padding: DESIGN_TOKENS.spacing.lg,
27301
27429
  }, children: jsxRuntime.jsx(MonthPicker, { ...restMonthPickerProps, value: currentValue, onChange: handleMonthChange, locale: resolvedLocale, size: resolvedSize }) }) })] }));
27302
27430
  });
@@ -27359,7 +27487,7 @@ const YearPickerInput = React.forwardRef(function YearPickerInput({ value, defau
27359
27487
  pointerEvents: 'none',
27360
27488
  accessible: false,
27361
27489
  focusable: false,
27362
- } }) }), jsxRuntime.jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, width: 360, children: jsxRuntime.jsx(reactNative.View, { style: {
27490
+ } }) }), jsxRuntime.jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, w: 360, children: jsxRuntime.jsx(reactNative.View, { style: {
27363
27491
  padding: DESIGN_TOKENS.spacing.lg,
27364
27492
  }, children: jsxRuntime.jsx(YearPicker, { ...restYearPickerProps, value: currentValue, onChange: handleYearChange, size: resolvedSize }) }) })] }));
27365
27493
  });
@@ -27524,7 +27652,7 @@ const TimePickerInput = ({ value, defaultValue, onChange, format = 24, withSecon
27524
27652
  }
27525
27653
  }, label: label, placeholder: is12h ? 'hh:mm AM' : 'hh:mm', endSection: jsxRuntime.jsx(Icon, { name: "clock", size: 16, color: disabled ? theme.text.disabled : theme.text.muted }), disabled: disabled, error: error, helperText: helperText, size: size, fullWidth: fullWidth, clearable: clearable && hasValue, clearButtonLabel: clearButtonLabel, onClear: clearValue }) }), jsxRuntime.jsx(Dialog, { visible: open,
27526
27654
  // variant="fullscreen"
27527
- onClose: handleClose, width: typeof computedPanelWidth === 'number' ? computedPanelWidth : 360, title: title || 'Select Time', children: jsxRuntime.jsxs(reactNative.Pressable, { style: {
27655
+ onClose: handleClose, w: typeof computedPanelWidth === 'number' ? computedPanelWidth : 360, title: title || 'Select Time', children: jsxRuntime.jsxs(reactNative.Pressable, { style: {
27528
27656
  flex: 1,
27529
27657
  width: '100%',
27530
27658
  justifyContent: 'center',
@@ -28476,303 +28604,6 @@ const EmojiPicker = factory((props, ref) => {
28476
28604
  });
28477
28605
  EmojiPicker.displayName = 'EmojiPicker';
28478
28606
 
28479
- function useRichTextEditorStyles() {
28480
- const theme = useTheme();
28481
- return React.useMemo(() => reactNative.StyleSheet.create({
28482
- characterCount: {
28483
- fontSize: 12,
28484
- marginTop: 4,
28485
- textAlign: 'right',
28486
- },
28487
- container: {
28488
- width: '100%',
28489
- },
28490
- disabled: {
28491
- opacity: 0.5,
28492
- },
28493
- editorContainer: {
28494
- backgroundColor: theme.backgrounds.surface,
28495
- borderColor: theme.backgrounds.border,
28496
- borderRadius: parseInt(theme.radii.md, 10),
28497
- borderWidth: 1,
28498
- overflow: 'hidden',
28499
- },
28500
- errorText: {
28501
- fontSize: 12,
28502
- marginTop: 4,
28503
- },
28504
- helperText: {
28505
- fontSize: 12,
28506
- marginTop: 4,
28507
- },
28508
- textInput: {
28509
- fontSize: 16,
28510
- lineHeight: 24,
28511
- padding: parseInt(theme.spacing.md, 10),
28512
- },
28513
- toolButton: {
28514
- alignItems: 'center',
28515
- backgroundColor: 'transparent',
28516
- borderColor: theme.backgrounds.border,
28517
- borderRadius: parseInt(theme.radii.sm, 10),
28518
- borderWidth: 1,
28519
- height: 32,
28520
- justifyContent: 'center',
28521
- width: 32,
28522
- },
28523
- toolSeparator: {
28524
- backgroundColor: theme.backgrounds.border,
28525
- height: 24,
28526
- marginHorizontal: 4,
28527
- width: 1,
28528
- },
28529
- toolbar: {
28530
- backgroundColor: theme.backgrounds.elevated,
28531
- borderBottomColor: theme.backgrounds.border,
28532
- borderBottomWidth: 1,
28533
- },
28534
- toolbarContent: {
28535
- alignItems: 'center',
28536
- flexDirection: 'row',
28537
- gap: 4,
28538
- paddingHorizontal: parseInt(theme.spacing.sm, 10),
28539
- paddingVertical: parseInt(theme.spacing.xs, 10),
28540
- },
28541
- }), [theme]);
28542
- }
28543
-
28544
- // Default toolbar configuration
28545
- const DEFAULT_TOOLBAR_TOOLS = [
28546
- 'bold',
28547
- 'italic',
28548
- 'underline',
28549
- 'separator',
28550
- 'heading',
28551
- 'separator',
28552
- 'align',
28553
- 'separator',
28554
- 'list',
28555
- 'separator',
28556
- 'link',
28557
- 'separator',
28558
- 'color',
28559
- ];
28560
- const RichTextEditor = React.memo(({ defaultValue, value, onChange, onSelectionChange, onFocus, onBlur, placeholder = 'Start typing...', readOnly = false, disabled = false, toolbar = {
28561
- enabled: true,
28562
- position: 'top',
28563
- tools: DEFAULT_TOOLBAR_TOOLS,
28564
- }, formats = {
28565
- fontFamilies: ['Arial', 'Georgia', 'Times New Roman', 'Courier New'],
28566
- fontSizes: [12, 14, 16, 18, 20, 24, 28, 32],
28567
- colors: ['#000000', '#333333', '#666666', '#999999', '#CCCCCC', '#FF0000', '#00FF00', '#0000FF'],
28568
- headings: [1, 2, 3, 4, 5, 6],
28569
- }, images = { enabled: true }, links = { enabled: true, openInNewTab: true }, plugins = [], autosave, spellCheck = true, maxLength, minHeight = 200, maxHeight = 600, className, theme: themeOverride = 'auto', error, helperText, style, ...props }) => {
28570
- const theme = useTheme();
28571
- const styles = useRichTextEditorStyles();
28572
- const [content, setContent] = React.useState(value || defaultValue || { html: '', text: '' });
28573
- const [selection, setSelection] = React.useState({
28574
- index: 0,
28575
- length: 0,
28576
- });
28577
- const [activeFormats, setActiveFormats] = React.useState({});
28578
- const [isFocused, setIsFocused] = React.useState(false);
28579
- const editorRef = React.useRef(null);
28580
- const autosaveTimerRef = React.useRef(null);
28581
- // Update content when value prop changes
28582
- React.useEffect(() => {
28583
- if (value && value !== content) {
28584
- setContent(value);
28585
- }
28586
- }, [value]);
28587
- // Autosave functionality
28588
- React.useEffect(() => {
28589
- if ((autosave === null || autosave === void 0 ? void 0 : autosave.enabled) && autosave.onSave) {
28590
- if (autosaveTimerRef.current) {
28591
- clearTimeout(autosaveTimerRef.current);
28592
- }
28593
- autosaveTimerRef.current = setTimeout(() => {
28594
- autosave.onSave(content);
28595
- }, autosave.interval || 5000);
28596
- return () => {
28597
- if (autosaveTimerRef.current) {
28598
- clearTimeout(autosaveTimerRef.current);
28599
- }
28600
- };
28601
- }
28602
- }, [content, autosave]);
28603
- const handleContentChange = React.useCallback((text) => {
28604
- const newContent = {
28605
- text,
28606
- html: text, // For now, treating as plain text
28607
- };
28608
- setContent(newContent);
28609
- onChange === null || onChange === void 0 ? void 0 : onChange(newContent);
28610
- }, [onChange]);
28611
- const handleSelectionChange = React.useCallback((selection) => {
28612
- const newSelection = {
28613
- index: selection.start,
28614
- length: selection.end - selection.start,
28615
- format: activeFormats,
28616
- };
28617
- setSelection(newSelection);
28618
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(newSelection);
28619
- }, [activeFormats, onSelectionChange]);
28620
- const handleFocus = React.useCallback(() => {
28621
- setIsFocused(true);
28622
- onFocus === null || onFocus === void 0 ? void 0 : onFocus();
28623
- }, [onFocus]);
28624
- const handleBlur = React.useCallback(() => {
28625
- setIsFocused(false);
28626
- onBlur === null || onBlur === void 0 ? void 0 : onBlur();
28627
- }, [onBlur]);
28628
- const applyFormat = React.useCallback((format) => {
28629
- if (readOnly || disabled)
28630
- return;
28631
- const newFormats = { ...activeFormats, ...format };
28632
- setActiveFormats(newFormats);
28633
- // In a real implementation, this would apply formatting to the selected text
28634
- // For this demo, we'll just track the format state
28635
- }, [activeFormats, readOnly, disabled]);
28636
- const toggleFormat = React.useCallback((formatKey) => {
28637
- if (readOnly || disabled)
28638
- return;
28639
- const currentValue = activeFormats[formatKey];
28640
- applyFormat({ [formatKey]: !currentValue });
28641
- }, [activeFormats, applyFormat, readOnly, disabled]);
28642
- const insertText = React.useCallback((text) => {
28643
- if (readOnly || disabled)
28644
- return;
28645
- const currentText = content.text;
28646
- const { index } = selection;
28647
- const newText = currentText.slice(0, index) + text + currentText.slice(index);
28648
- handleContentChange(newText);
28649
- }, [content.text, selection, handleContentChange, readOnly, disabled]);
28650
- const insertLink = React.useCallback(() => {
28651
- if (!(links === null || links === void 0 ? void 0 : links.enabled) || readOnly || disabled)
28652
- return;
28653
- // In a real implementation, this would show a link dialog
28654
- const url = prompt('Enter URL:');
28655
- if (url && (!links.validate || links.validate(url))) {
28656
- applyFormat({ link: url });
28657
- }
28658
- }, [links, applyFormat, readOnly, disabled]);
28659
- React.useCallback(async () => {
28660
- if (!(images === null || images === void 0 ? void 0 : images.enabled) || readOnly || disabled)
28661
- return;
28662
- // In a real implementation, this would show a file picker
28663
- // For now, we'll just insert a placeholder
28664
- insertText('[Image]');
28665
- }, [images, insertText, readOnly, disabled]);
28666
- React.useCallback((level) => {
28667
- applyFormat({ heading: level });
28668
- }, [applyFormat]);
28669
- const setAlignment = React.useCallback((align) => {
28670
- applyFormat({ align });
28671
- }, [applyFormat]);
28672
- const setList = React.useCallback((listType) => {
28673
- applyFormat({ list: listType });
28674
- }, [applyFormat]);
28675
- const getToolButtonStyle = React.useCallback((isActive) => [
28676
- styles.toolButton,
28677
- {
28678
- backgroundColor: isActive
28679
- ? (theme.colorScheme === 'dark' ? theme.colors.primary[7] : theme.colors.primary[1])
28680
- : 'transparent',
28681
- borderColor: isActive ? theme.colors.primary[4] : theme.backgrounds.border,
28682
- },
28683
- (disabled || readOnly) && styles.disabled,
28684
- ], [styles.toolButton, theme, disabled, readOnly]);
28685
- const renderToolButton = React.useCallback((tool, icon, onPress, isActive = false) => (jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: onPress, disabled: disabled || readOnly, style: getToolButtonStyle(isActive), children: jsxRuntime.jsx(Icon, { name: icon, size: 16, color: isActive ? theme.colors.primary[5] : theme.text.secondary }) }, tool)), [theme, disabled, readOnly, getToolButtonStyle]);
28686
- const renderToolSeparator = React.useCallback((index) => (jsxRuntime.jsx(reactNative.View, { style: styles.toolSeparator }, `separator-${index}`)), [styles.toolSeparator]);
28687
- const renderToolbar = React.useCallback(() => {
28688
- if (!(toolbar === null || toolbar === void 0 ? void 0 : toolbar.enabled))
28689
- return null;
28690
- const tools = toolbar.tools || DEFAULT_TOOLBAR_TOOLS;
28691
- return (jsxRuntime.jsx(reactNative.View, { style: styles.toolbar, children: jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.toolbarContent, children: tools.map((tool, index) => {
28692
- if (tool === 'separator') {
28693
- return renderToolSeparator(index);
28694
- }
28695
- switch (tool) {
28696
- case 'bold':
28697
- return renderToolButton('bold', 'bold', () => toggleFormat('bold'), !!activeFormats.bold);
28698
- case 'italic':
28699
- return renderToolButton('italic', 'italic', () => toggleFormat('italic'), !!activeFormats.italic);
28700
- case 'underline':
28701
- return renderToolButton('underline', 'underline', () => toggleFormat('underline'), !!activeFormats.underline);
28702
- case 'strikethrough':
28703
- return renderToolButton('strikethrough', 'strikethrough', () => toggleFormat('strikethrough'), !!activeFormats.strikethrough);
28704
- case 'heading':
28705
- return renderToolButton('heading', 'heading', () => applyFormat({ heading: activeFormats.heading ? null : 2 }), !!activeFormats.heading);
28706
- case 'align':
28707
- return renderToolButton('align', 'alignLeft', // Default to left align icon, could be dynamic based on current align
28708
- () => setAlignment(activeFormats.align === 'left' ? 'center' : 'left'), !!activeFormats.align);
28709
- case 'list':
28710
- return renderToolButton('list', 'listUnordered', // Default to unordered list icon, could be dynamic
28711
- () => setList(activeFormats.list === 'unordered' ? 'ordered' : 'unordered'), !!activeFormats.list);
28712
- case 'link':
28713
- return renderToolButton('link', 'link', insertLink, !!activeFormats.link);
28714
- case 'image':
28715
- return renderToolButton('image', 'image', () => { }, // TODO: Implement image insertion
28716
- false);
28717
- case 'code':
28718
- return renderToolButton('code', 'code', () => toggleFormat('code'), !!activeFormats.code);
28719
- case 'quote':
28720
- return renderToolButton('quote', 'quote', () => toggleFormat('quote'), !!activeFormats.quote);
28721
- case 'color':
28722
- return renderToolButton('color', 'color', () => { }, // TODO: Implement color picker
28723
- !!activeFormats.color);
28724
- default:
28725
- return null;
28726
- }
28727
- }) }) }));
28728
- }, [toolbar, theme, activeFormats, renderToolButton, renderToolSeparator, toggleFormat, insertLink, styles.toolbar, styles.toolbarContent]);
28729
- const renderEditor = React.useCallback(() => (jsxRuntime.jsx(reactNative.View, { style: [
28730
- styles.editorContainer,
28731
- {
28732
- borderColor: isFocused ? theme.colors.primary[5] : theme.backgrounds.border,
28733
- minHeight,
28734
- maxHeight,
28735
- },
28736
- error && { borderColor: theme.colors.error[5] },
28737
- (disabled || readOnly) && styles.disabled,
28738
- ], children: jsxRuntime.jsx(reactNative.TextInput, { ref: editorRef, value: content.text, onChangeText: handleContentChange, onSelectionChange: (event) => handleSelectionChange(event.nativeEvent.selection), onFocus: handleFocus, onBlur: handleBlur, placeholder: placeholder, placeholderTextColor: theme.text.muted, multiline: true, textAlignVertical: "top", editable: !disabled && !readOnly, spellCheck: spellCheck, maxLength: maxLength, style: [
28739
- styles.textInput,
28740
- reactNative.Platform.OS === 'web' ? { outlineWidth: 0 } : null,
28741
- {
28742
- color: theme.text.primary,
28743
- fontSize: activeFormats.fontSize || 16,
28744
- fontFamily: activeFormats.fontFamily || theme.fontFamily,
28745
- fontWeight: activeFormats.bold ? 'bold' : 'normal',
28746
- fontStyle: activeFormats.italic ? 'italic' : 'normal',
28747
- textDecorationLine: activeFormats.underline ? 'underline' : 'none',
28748
- textAlign: activeFormats.align || 'left',
28749
- },
28750
- ], ...props }) })), [
28751
- content.text,
28752
- handleContentChange,
28753
- handleSelectionChange,
28754
- handleFocus,
28755
- handleBlur,
28756
- placeholder,
28757
- disabled,
28758
- readOnly,
28759
- spellCheck,
28760
- maxLength,
28761
- isFocused,
28762
- theme,
28763
- minHeight,
28764
- maxHeight,
28765
- error,
28766
- activeFormats,
28767
- props,
28768
- styles.editorContainer,
28769
- styles.disabled,
28770
- styles.textInput,
28771
- ]);
28772
- return (jsxRuntime.jsxs(reactNative.View, { style: [styles.container, style], children: [(toolbar === null || toolbar === void 0 ? void 0 : toolbar.position) === 'top' && renderToolbar(), renderEditor(), (toolbar === null || toolbar === void 0 ? void 0 : toolbar.position) === 'bottom' && renderToolbar(), maxLength && (jsxRuntime.jsxs(reactNative.Text, { style: [styles.characterCount, { color: theme.text.secondary }], children: [content.text.length, "/", maxLength] })), error && (jsxRuntime.jsx(reactNative.Text, { style: [styles.errorText, { color: theme.colors.error[5] }], children: error })), helperText && !error && (jsxRuntime.jsx(reactNative.Text, { style: [styles.helperText, { color: theme.text.secondary }], children: helperText }))] }));
28773
- });
28774
- RichTextEditor.displayName = 'RichTextEditor';
28775
-
28776
28607
  function RatingBase(rawProps, ref) {
28777
28608
  const { disclaimerProps: disclaimerData, otherProps: propsAfterDisclaimer } = extractDisclaimerProps(rawProps);
28778
28609
  const { spacingProps, otherProps: props } = extractSpacingProps(propsAfterDisclaimer);
@@ -29524,7 +29355,7 @@ function useMenuContext() {
29524
29355
  return context;
29525
29356
  }
29526
29357
  function MenuBase(props, ref) {
29527
- const { opened: controlledOpened, trigger = 'click', position = 'auto', offset = 4, closeOnClickOutside = true, closeOnEscape = true, onOpen, onClose, width = 'auto', maxHeight = 300, shadow = 'md', radius = 'md', children, testID, disabled = false, strategy = reactNative.Platform.OS === 'web' ? 'fixed' : 'portal', ...spacingProps } = props;
29358
+ const { opened: controlledOpened, trigger = 'click', position = 'auto', offset = 4, closeOnClickOutside = true, closeOnEscape = true, onOpen, onClose, w = 'auto', maxH = 300, shadow = 'md', radius = 'md', children, testID, disabled = false, strategy = reactNative.Platform.OS === 'web' ? 'fixed' : 'portal', ...spacingProps } = props;
29528
29359
  const [internalOpened, setInternalOpened] = React.useState(false);
29529
29360
  // Derive menu dropdown items from children each render for reactivity
29530
29361
  const { menuItems, menuDropdownProps } = React.useMemo(() => {
@@ -29599,11 +29430,11 @@ function MenuBase(props, ref) {
29599
29430
  const listGroupStyle = {
29600
29431
  ...styles.dropdown,
29601
29432
  ...(dropdownSpacingStyles || {}),
29602
- maxHeight,
29433
+ maxHeight: maxH,
29603
29434
  width: resolvedWidth,
29604
29435
  };
29605
- return (jsxRuntime.jsx(MenuContext.Provider, { value: menuContextValueOpened, children: jsxRuntime.jsx(ListGroup, { variant: "default", size: "sm", style: listGroupStyle, children: scrollable ? (jsxRuntime.jsx(reactNative.ScrollView, { showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "handled", style: { maxHeight }, children: jsxRuntime.jsx(ListGroupBody, { children: menuItems }) })) : (jsxRuntime.jsx(reactNative.View, { style: { maxHeight, overflow: 'hidden' }, children: jsxRuntime.jsx(ListGroupBody, { children: menuItems }) })) }) }));
29606
- }, [menuItems, menuDropdownProps, styles.dropdown, dropdownSpacingStyles, maxHeight, menuContextValueOpened]);
29436
+ return (jsxRuntime.jsx(MenuContext.Provider, { value: menuContextValueOpened, children: jsxRuntime.jsx(ListGroup, { variant: "default", size: "sm", style: listGroupStyle, children: scrollable ? (jsxRuntime.jsx(reactNative.ScrollView, { showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "handled", style: { maxHeight: maxH }, children: jsxRuntime.jsx(ListGroupBody, { children: menuItems }) })) : (jsxRuntime.jsx(reactNative.View, { style: { maxHeight: maxH, overflow: 'hidden' }, children: jsxRuntime.jsx(ListGroupBody, { children: menuItems }) })) }) }));
29437
+ }, [menuItems, menuDropdownProps, styles.dropdown, dropdownSpacingStyles, maxH, menuContextValueOpened]);
29607
29438
  const handleOpen = React.useCallback(async (opts) => {
29608
29439
  var _a, _b, _c, _d, _e, _f;
29609
29440
  // Use ref to avoid stale isOpened value after async close from backdrop click
@@ -29635,7 +29466,7 @@ function MenuBase(props, ref) {
29635
29466
  }
29636
29467
  // Calculate base overlay size
29637
29468
  const estimatedMenuHeight = 120; // Estimate for typical menu with 3-4 items
29638
- const resolvedWidth = width === 'target' ? triggerRect.width : (typeof width === 'number' ? width : (width === 'auto' ? 200 : 200));
29469
+ const resolvedWidth = w === 'target' ? triggerRect.width : (typeof w === 'number' ? w : (w === 'auto' ? 200 : 200));
29639
29470
  const overlaySize = {
29640
29471
  width: resolvedWidth,
29641
29472
  height: estimatedMenuHeight,
@@ -29703,7 +29534,7 @@ function MenuBase(props, ref) {
29703
29534
  catch (error) {
29704
29535
  console.warn('Failed to open menu:', error);
29705
29536
  }
29706
- }, [disabled, width, position, offset, strategy, closeOnClickOutside, closeOnEscape, onOpen, menuItems, trigger, buildMenuDropdown, onClose]);
29537
+ }, [disabled, w, position, offset, strategy, closeOnClickOutside, closeOnEscape, onOpen, menuItems, trigger, buildMenuDropdown, onClose]);
29707
29538
  // When menu content changes while open, update overlay content in place
29708
29539
  React.useEffect(() => {
29709
29540
  var _a;
@@ -29715,14 +29546,14 @@ function MenuBase(props, ref) {
29715
29546
  return; // no structural change
29716
29547
  lastSignatureRef.current = menuItemsSignature;
29717
29548
  const currentId = overlayIdRef.current;
29718
- const resolvedWidth = (_a = lastResolvedWidthRef.current) !== null && _a !== void 0 ? _a : (typeof width === 'number' ? width : undefined);
29549
+ const resolvedWidth = (_a = lastResolvedWidthRef.current) !== null && _a !== void 0 ? _a : (typeof w === 'number' ? w : undefined);
29719
29550
  const menuDropdown = buildMenuDropdown(resolvedWidth);
29720
29551
  if (!menuDropdown)
29721
29552
  return;
29722
29553
  updateOverlay(currentId, {
29723
29554
  content: menuDropdown,
29724
29555
  });
29725
- }, [menuItemsSignature, menuItems, updateOverlay, width, buildMenuDropdown]);
29556
+ }, [menuItemsSignature, menuItems, updateOverlay, w, buildMenuDropdown]);
29726
29557
  const handleToggle = React.useCallback(() => {
29727
29558
  if (isOpenedRef.current) {
29728
29559
  handleClose();
@@ -31654,7 +31485,7 @@ const DEFAULT_ARROW_SIZE = 7;
31654
31485
  const PopoverBase = (props, ref) => {
31655
31486
  var _a;
31656
31487
  const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, trigger = 'click', disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
31657
- trapFocus = false, keepMounted = false, returnFocus = false, withinPortal = true, withOverlay = false, overlayProps, width, minWidth, minHeight, maxWidth, maxHeight, radius, shadow, zIndex = 300, position = 'bottom', offset = 8, floatingStrategy = 'fixed', middlewares, preventPositionChangeWhenVisible = false, hideDetached = true, viewport, keyboardAvoidance = true, fallbackPlacements, boundary, withRoles = true, id, withArrow = false, arrowSize = DEFAULT_ARROW_SIZE, arrowRadius = 0, arrowOffset = 5, arrowPosition = 'center', onPositionChange, testID, ...rest } = props;
31488
+ trapFocus = false, keepMounted = false, returnFocus = false, withinPortal = true, withOverlay = false, overlayProps, w, minW, minH, maxW, maxH, radius, shadow, zIndex = 300, position = 'bottom', offset = 8, floatingStrategy = 'fixed', middlewares, preventPositionChangeWhenVisible = false, hideDetached = true, viewport, keyboardAvoidance = true, fallbackPlacements, boundary, withRoles = true, id, withArrow = false, arrowSize = DEFAULT_ARROW_SIZE, arrowRadius = 0, arrowOffset = 5, arrowPosition = 'center', onPositionChange, testID, ...rest } = props;
31658
31489
  const theme = useTheme();
31659
31490
  const { spacingProps } = extractSpacingProps(rest);
31660
31491
  const spacingStyles = getSpacingStyles(spacingProps);
@@ -31871,29 +31702,29 @@ const PopoverBase = (props, ref) => {
31871
31702
  : undefined;
31872
31703
  const widthOverride = (() => {
31873
31704
  var _a, _b;
31874
- if (typeof width === 'number')
31875
- return width;
31876
- if (width === 'target') {
31705
+ if (typeof w === 'number')
31706
+ return w;
31707
+ if (w === 'target') {
31877
31708
  return (_b = (_a = anchorMeasurementsRef.current) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : computedFinalWidth;
31878
31709
  }
31879
31710
  return computedFinalWidth;
31880
31711
  })();
31881
31712
  const sizeStyles = {};
31882
- if (typeof minWidth === 'number')
31883
- sizeStyles.minWidth = minWidth;
31884
- if (typeof minHeight === 'number')
31885
- sizeStyles.minHeight = minHeight;
31886
- if (typeof maxWidth === 'number')
31887
- sizeStyles.maxWidth = maxWidth;
31713
+ if (typeof minW === 'number')
31714
+ sizeStyles.minWidth = minW;
31715
+ if (typeof minH === 'number')
31716
+ sizeStyles.minHeight = minH;
31717
+ if (typeof maxW === 'number')
31718
+ sizeStyles.maxWidth = maxW;
31888
31719
  const computedMaxHeight = positioningResult.maxHeight;
31889
31720
  const resolvedMaxHeight = (() => {
31890
- if (typeof maxHeight === 'number') {
31721
+ if (typeof maxH === 'number') {
31891
31722
  if (typeof computedMaxHeight === 'number') {
31892
- return Math.min(maxHeight, computedMaxHeight);
31723
+ return Math.min(maxH, computedMaxHeight);
31893
31724
  }
31894
- return maxHeight;
31725
+ return maxH;
31895
31726
  }
31896
- return typeof computedMaxHeight === 'number' ? computedMaxHeight : maxHeight;
31727
+ return typeof computedMaxHeight === 'number' ? computedMaxHeight : maxH;
31897
31728
  })();
31898
31729
  if (typeof resolvedMaxHeight === 'number')
31899
31730
  sizeStyles.maxHeight = resolvedMaxHeight;
@@ -31917,7 +31748,7 @@ const PopoverBase = (props, ref) => {
31917
31748
  zIndex,
31918
31749
  });
31919
31750
  onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(positioningResult.placement);
31920
- }, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, width, maxHeight, minWidth, minHeight, maxWidth, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate, trigger, isPositioning]);
31751
+ }, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, w, maxH, minW, minH, maxW, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate, trigger, isPositioning]);
31921
31752
  React.useEffect(() => {
31922
31753
  return () => {
31923
31754
  hideOverlay();
@@ -32205,7 +32036,7 @@ const getSpacingValue = (spacing, theme) => {
32205
32036
  // Table Cell Components
32206
32037
  const TableTh = (allProps) => {
32207
32038
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32208
- const { children, w, align = 'left', minWidth, maxWidth, flex, widthStrategy = 'auto', style } = otherProps;
32039
+ const { children, w, align = 'left', minW, maxW, flex, widthStrategy = 'auto', style } = otherProps;
32209
32040
  const theme = useTheme();
32210
32041
  const { isRTL } = useDirection();
32211
32042
  // Swap alignment in RTL
@@ -32236,10 +32067,10 @@ const TableTh = (allProps) => {
32236
32067
  else if (widthStrategy === 'auto') {
32237
32068
  widthStyle.flex = 1;
32238
32069
  }
32239
- if (minWidth)
32240
- widthStyle.minWidth = minWidth;
32241
- if (maxWidth)
32242
- widthStyle.maxWidth = maxWidth;
32070
+ if (minW)
32071
+ widthStyle.minWidth = minW;
32072
+ if (maxW)
32073
+ widthStyle.maxWidth = maxW;
32243
32074
  return widthStyle;
32244
32075
  };
32245
32076
  const cellStyle = [
@@ -32260,7 +32091,7 @@ const TableTh = (allProps) => {
32260
32091
  };
32261
32092
  const TableTd = (allProps) => {
32262
32093
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32263
- const { children, w, align = 'left', minWidth, maxWidth, flex, widthStrategy = 'auto', style } = otherProps;
32094
+ const { children, w, align = 'left', minW, maxW, flex, widthStrategy = 'auto', style } = otherProps;
32264
32095
  const theme = useTheme();
32265
32096
  const { isRTL } = useDirection();
32266
32097
  // Swap alignment in RTL
@@ -32291,10 +32122,10 @@ const TableTd = (allProps) => {
32291
32122
  else if (widthStrategy === 'auto') {
32292
32123
  widthStyle.flex = 1;
32293
32124
  }
32294
- if (minWidth)
32295
- widthStyle.minWidth = minWidth;
32296
- if (maxWidth)
32297
- widthStyle.maxWidth = maxWidth;
32125
+ if (minW)
32126
+ widthStyle.minWidth = minW;
32127
+ if (maxW)
32128
+ widthStyle.maxWidth = maxW;
32298
32129
  return widthStyle;
32299
32130
  };
32300
32131
  const cellStyle = [
@@ -32373,16 +32204,16 @@ const TableCaption = (allProps) => {
32373
32204
  // Scroll Container Component
32374
32205
  const TableScrollContainer = (allProps) => {
32375
32206
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32376
- const { children, minWidth = 500, maxHeight, type = 'native', style } = otherProps;
32207
+ const { children, minW = 500, maxH, type = 'native', style } = otherProps;
32377
32208
  const containerStyle = [
32378
32209
  {
32379
32210
  width: '100%',
32380
- maxHeight
32211
+ maxHeight: maxH
32381
32212
  },
32382
32213
  getSpacingStyles(spacingProps),
32383
32214
  style
32384
32215
  ];
32385
- const scrollViewStyle = minWidth ? { minWidth } : undefined;
32216
+ const scrollViewStyle = minW ? { minWidth: minW } : undefined;
32386
32217
  return (jsxRuntime.jsx(reactNative.View, { style: containerStyle, children: jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: reactNative.Platform.OS === 'web', contentContainerStyle: scrollViewStyle, children: jsxRuntime.jsx(reactNative.ScrollView, { style: { flex: 1 }, showsVerticalScrollIndicator: reactNative.Platform.OS === 'web', children: children }) }) }));
32387
32218
  };
32388
32219
  // Main Table Component
@@ -33320,7 +33151,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33320
33151
  alignItems: 'center',
33321
33152
  marginBottom: DESIGN_TOKENS.spacing.md,
33322
33153
  paddingHorizontal: DESIGN_TOKENS.spacing.xs
33323
- }, children: [jsxRuntime.jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxRuntime.jsxs(Flex, { gap: 8, children: [jsxRuntime.jsxs(Text, { variant: "small", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxRuntime.jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 320, trapFocus: true, children: [jsxRuntime.jsx(Popover.Target, { children: jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsxRuntime.jsx(reactNative.View, { style: {
33154
+ }, children: [jsxRuntime.jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxRuntime.jsxs(Flex, { gap: 8, children: [jsxRuntime.jsxs(Text, { variant: "small", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxRuntime.jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, w: 320, trapFocus: true, children: [jsxRuntime.jsx(Popover.Target, { children: jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsxRuntime.jsx(reactNative.View, { style: {
33324
33155
  width: 6,
33325
33156
  height: 6,
33326
33157
  borderRadius: 3,
@@ -33350,7 +33181,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33350
33181
  }) })), jsxRuntime.jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: columns.filter(c => c.filterable).map(column => {
33351
33182
  const currentFilter = getColumnFilter(column.key);
33352
33183
  return (jsxRuntime.jsx(reactNative.View, { children: renderFilterControl(column) }, `${column.key}-${(currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.value) || 'no-filter'}`));
33353
- }) })] }))] }) })] })), onEditModeChange && (jsxRuntime.jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 280, trapFocus: true, children: [jsxRuntime.jsx(Popover.Target, { children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsxRuntime.jsx(Popover.Dropdown, { children: jsxRuntime.jsxs(reactNative.View, { style: { padding: 8, maxHeight: 300, width: 260 }, children: [jsxRuntime.jsx(ComponentWithDisclaimer, { disclaimer: "Selected view determines the layout style", disclaimerProps: { colorVariant: 'muted', size: 'sm' }, children: jsxRuntime.jsxs(Row, { children: [jsxRuntime.jsx(Button, { size: "xs", title: "Deselect All", variant: hiddenColumns.length === columns.length ? 'filled' : 'outline', onPress: () => setHiddenColumns(columns.map(c => c.key)), style: { marginBottom: 8 } }), jsxRuntime.jsx(Button, { size: "xs", title: "Select All", variant: hiddenColumns.length === 0 ? 'filled' : 'outline', onPress: () => setHiddenColumns([]), style: { marginBottom: 8 } })] }) }), jsxRuntime.jsx(reactNative.ScrollView, { style: { maxHeight: 200 }, children: columns.map(col => (jsxRuntime.jsx(Checkbox, { label: tempHeaderEdits[col.key] || col.header, onChange: () => {
33184
+ }) })] }))] }) })] })), onEditModeChange && (jsxRuntime.jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, w: 280, trapFocus: true, children: [jsxRuntime.jsx(Popover.Target, { children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsxRuntime.jsx(Popover.Dropdown, { children: jsxRuntime.jsxs(reactNative.View, { style: { padding: 8, maxHeight: 300, width: 260 }, children: [jsxRuntime.jsx(ComponentWithDisclaimer, { disclaimer: "Selected view determines the layout style", disclaimerProps: { colorVariant: 'muted', size: 'sm' }, children: jsxRuntime.jsxs(Row, { children: [jsxRuntime.jsx(Button, { size: "xs", title: "Deselect All", variant: hiddenColumns.length === columns.length ? 'filled' : 'outline', onPress: () => setHiddenColumns(columns.map(c => c.key)), style: { marginBottom: 8 } }), jsxRuntime.jsx(Button, { size: "xs", title: "Select All", variant: hiddenColumns.length === 0 ? 'filled' : 'outline', onPress: () => setHiddenColumns([]), style: { marginBottom: 8 } })] }) }), jsxRuntime.jsx(reactNative.ScrollView, { style: { maxHeight: 200 }, children: columns.map(col => (jsxRuntime.jsx(Checkbox, { label: tempHeaderEdits[col.key] || col.header, onChange: () => {
33354
33185
  if (hiddenColumns.includes(col.key)) {
33355
33186
  setHiddenColumns(prev => prev.filter(h => h !== col.key));
33356
33187
  }
@@ -33724,9 +33555,9 @@ const resolveTokenColor = (token, theme) => {
33724
33555
  return token; // assume raw color string
33725
33556
  };
33726
33557
  // Item
33727
- const TimelineItem = React.forwardRef(({ children, title, bullet, colorVariant, lineVariant = 'solid', color, active, itemIndex = 0, isLastItem = false, itemAlign, ...rest }, ref) => {
33558
+ const TimelineItem = React.forwardRef(({ children, title, timestamp, bullet, colorVariant, lineVariant = 'solid', color, titleColor, descriptionColor, timestampColor, active, itemIndex = 0, isLastItem = false, itemAlign, ...rest }, ref) => {
33728
33559
  const theme = useTheme();
33729
- const { active: timelineActive, color: timelineColor, lineWidth, bulletSize: contextBulletSize, align, reverseActive, size, centerMode, metrics, } = useTimelineContext();
33560
+ const { active: timelineActive, color: timelineColor, lineWidth, bulletSize: contextBulletSize, align, reverseActive, size, centerMode, metrics, titleColor: timelineTitleColor, descriptionColor: timelineDescriptionColor, timestampColor: timelineTimestampColor, } = useTimelineContext();
33730
33561
  const sizeConfig = metrics;
33731
33562
  const finalBulletSize = contextBulletSize || sizeConfig.bulletSize;
33732
33563
  const showAllColored = timelineActive === undefined;
@@ -33741,6 +33572,9 @@ const TimelineItem = React.forwardRef(({ children, title, bullet, colorVariant,
33741
33572
  const resolvedItemColor = color
33742
33573
  ? color
33743
33574
  : (colorVariant ? resolveTokenColor(colorVariant, theme) : timelineColor);
33575
+ const resolvedTitleColor = titleColor !== null && titleColor !== void 0 ? titleColor : timelineTitleColor;
33576
+ const resolvedDescriptionColor = descriptionColor !== null && descriptionColor !== void 0 ? descriptionColor : timelineDescriptionColor;
33577
+ const resolvedTimestampColor = timestampColor !== null && timestampColor !== void 0 ? timestampColor : timelineTimestampColor;
33744
33578
  // Active logic
33745
33579
  const isActive = showAllColored
33746
33580
  ? true
@@ -33826,10 +33660,16 @@ const TimelineItem = React.forwardRef(({ children, title, bullet, colorVariant,
33826
33660
  const getTitleStyle = () => ({
33827
33661
  fontSize: sizeConfig.fontSize,
33828
33662
  fontWeight: '600',
33829
- color: theme.text.primary,
33663
+ color: resolvedTitleColor !== null && resolvedTitleColor !== void 0 ? resolvedTitleColor : theme.text.primary,
33830
33664
  marginBottom: title && children ? 4 : 0,
33831
33665
  textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33832
33666
  });
33667
+ const getTimestampStyle = () => ({
33668
+ fontSize: Math.max(10, Math.round(sizeConfig.fontSize * 0.8)),
33669
+ color: resolvedTimestampColor !== null && resolvedTimestampColor !== void 0 ? resolvedTimestampColor : theme.text.secondary,
33670
+ marginBottom: (title || children) ? 4 : 0,
33671
+ textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33672
+ });
33833
33673
  const getItemWrapperStyle = () => {
33834
33674
  if (centerMode) {
33835
33675
  return {
@@ -33845,36 +33685,53 @@ const TimelineItem = React.forwardRef(({ children, title, bullet, colorVariant,
33845
33685
  alignItems: 'flex-start',
33846
33686
  };
33847
33687
  };
33688
+ const applyTextStyle = (nodes, styleOverride) => {
33689
+ if (!styleOverride)
33690
+ return nodes;
33691
+ return React.Children.map(nodes, (child) => {
33692
+ var _a;
33693
+ if (typeof child === 'string' || typeof child === 'number') {
33694
+ return jsxRuntime.jsx(reactNative.Text, { style: styleOverride, children: child });
33695
+ }
33696
+ if (!React.isValidElement(child))
33697
+ return child;
33698
+ const props = child.props || {};
33699
+ const isTextLike = ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === 'Text' || child.type === reactNative.Text || typeof props.children === 'string';
33700
+ if (isTextLike) {
33701
+ const mergedStyle = Array.isArray(props.style)
33702
+ ? [...props.style, styleOverride]
33703
+ : [props.style, styleOverride];
33704
+ return React.cloneElement(child, { style: mergedStyle });
33705
+ }
33706
+ if (props.children) {
33707
+ return React.cloneElement(child, { children: applyTextStyle(props.children, styleOverride) });
33708
+ }
33709
+ return child;
33710
+ });
33711
+ };
33848
33712
  if (centerMode) {
33849
33713
  // Three column layout: left content | bullet/line | right content
33850
33714
  const leftContent = effectiveAlign === 'left' && (title || children);
33851
33715
  const rightContent = effectiveAlign === 'right' && (title || children);
33852
33716
  // Helper to clone Text children with alignment
33853
33717
  const alignChildText = (nodes, side) => {
33854
- return React.Children.map(nodes, (child) => {
33855
- var _a;
33856
- if (!React.isValidElement(child))
33857
- return child;
33858
- const props = child.props || {};
33859
- const isTextLike = ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === 'Text' || (typeof props.children === 'string');
33860
- if (isTextLike) {
33861
- const mergedStyle = Array.isArray(props.style)
33862
- ? [...props.style, { textAlign: side }]
33863
- : [props.style, { textAlign: side }];
33864
- return React.cloneElement(child, { style: mergedStyle });
33865
- }
33866
- if (props.children) {
33867
- return React.cloneElement(child, { children: alignChildText(props.children, side) });
33868
- }
33869
- return child;
33870
- });
33718
+ const styleOverride = {
33719
+ textAlign: side,
33720
+ ...(resolvedDescriptionColor ? { color: resolvedDescriptionColor } : {}),
33721
+ };
33722
+ return applyTextStyle(nodes, styleOverride);
33871
33723
  };
33872
- return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingRight: sizeConfig.spacing, alignItems: 'flex-end' }, children: leftContent && (jsxRuntime.jsxs(reactNative.View, { style: { width: '100%', alignItems: 'flex-end' }, children: [title && jsxRuntime.jsx(reactNative.Text, { style: [getTitleStyle(), { textAlign: 'right' }], children: title }), alignChildText(children, 'right')] })) }), jsxRuntime.jsxs(reactNative.View, { style: { width: finalBulletSize, alignItems: 'center', position: 'relative' }, children: [getLine(), jsxRuntime.jsx(reactNative.View, { style: getBulletStyle(), children: bullet })] }), jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingLeft: sizeConfig.spacing, alignItems: 'flex-start' }, children: rightContent && (jsxRuntime.jsxs(reactNative.View, { style: { width: '100%', alignItems: 'flex-start' }, children: [title && jsxRuntime.jsx(reactNative.Text, { style: [getTitleStyle(), { textAlign: 'left' }], children: title }), alignChildText(children, 'left')] })) })] }));
33724
+ return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingRight: sizeConfig.spacing, alignItems: 'flex-end' }, children: leftContent && (jsxRuntime.jsxs(reactNative.View, { style: { width: '100%', alignItems: 'flex-end' }, children: [timestamp && (jsxRuntime.jsx(reactNative.Text, { style: [getTimestampStyle(), { textAlign: 'right' }], children: timestamp })), title && jsxRuntime.jsx(reactNative.Text, { style: [getTitleStyle(), { textAlign: 'right' }], children: title }), alignChildText(children, 'right')] })) }), jsxRuntime.jsxs(reactNative.View, { style: { width: finalBulletSize, alignItems: 'center', position: 'relative' }, children: [getLine(), jsxRuntime.jsx(reactNative.View, { style: getBulletStyle(), children: bullet })] }), jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingLeft: sizeConfig.spacing, alignItems: 'flex-start' }, children: rightContent && (jsxRuntime.jsxs(reactNative.View, { style: { width: '100%', alignItems: 'flex-start' }, children: [timestamp && (jsxRuntime.jsx(reactNative.Text, { style: [getTimestampStyle(), { textAlign: 'left' }], children: timestamp })), title && jsxRuntime.jsx(reactNative.Text, { style: [getTitleStyle(), { textAlign: 'left' }], children: title }), alignChildText(children, 'left')] })) })] }));
33873
33725
  }
33874
- return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [getLine(), jsxRuntime.jsx(reactNative.View, { style: getBulletStyle(), children: bullet }), (title || children) && (jsxRuntime.jsxs(reactNative.View, { style: getContentStyle(), children: [title && jsxRuntime.jsx(reactNative.Text, { style: getTitleStyle(), children: title }), children] }))] }));
33726
+ return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [getLine(), jsxRuntime.jsx(reactNative.View, { style: getBulletStyle(), children: bullet }), (title || children) && (jsxRuntime.jsxs(reactNative.View, { style: getContentStyle(), children: [timestamp && jsxRuntime.jsx(reactNative.Text, { style: getTimestampStyle(), children: timestamp }), title && jsxRuntime.jsx(reactNative.Text, { style: getTitleStyle(), children: title }), resolvedDescriptionColor
33727
+ ? applyTextStyle(children, {
33728
+ color: resolvedDescriptionColor,
33729
+ textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33730
+ })
33731
+ : children] }))] }));
33875
33732
  });
33876
33733
  // Root Timeline
33877
- const Timeline = React.forwardRef(({ children, active, color, colorVariant, lineWidth, bulletSize, align = 'left', reverseActive = false, size = 'md', centerMode = false, ...rest }, ref) => {
33734
+ const Timeline = React.forwardRef(({ children, active, color, colorVariant, titleColor, descriptionColor, timestampColor, lineWidth, bulletSize, align = 'left', reverseActive = false, size = 'md', centerMode = false, ...rest }, ref) => {
33878
33735
  const theme = useTheme();
33879
33736
  const clampedSize = clampComponentSize(size, TIMELINE_ALLOWED_SIZES);
33880
33737
  const baseMetrics = resolveTimelineMetrics(clampedSize);
@@ -33896,6 +33753,9 @@ const Timeline = React.forwardRef(({ children, active, color, colorVariant, line
33896
33753
  size: clampedSize,
33897
33754
  metrics,
33898
33755
  centerMode,
33756
+ titleColor,
33757
+ descriptionColor,
33758
+ timestampColor,
33899
33759
  };
33900
33760
  const items = [];
33901
33761
  React.Children.forEach(children, (child, index) => {
@@ -34613,7 +34473,7 @@ const Notice = factory(NoticeBase);
34613
34473
  Notice.displayName = 'Notice';
34614
34474
 
34615
34475
  function SkeletonBase(props, ref) {
34616
- const { shape = 'rectangle', width, height, size = 'md', radius, animate = true, animationDuration = 1500, colors, style, testID, ...rest } = props;
34476
+ const { shape = 'rectangle', w, h, size = 'md', radius, animate = true, animationDuration = 1500, colors, style, testID, ...rest } = props;
34617
34477
  const { spacingProps, otherProps } = extractSpacingProps(rest);
34618
34478
  const spacingStyles = getSpacingStyles(spacingProps);
34619
34479
  const theme = useTheme();
@@ -34634,36 +34494,36 @@ function SkeletonBase(props, ref) {
34634
34494
  switch (shape) {
34635
34495
  case 'text':
34636
34496
  return {
34637
- width: width || '100%',
34638
- height: height || getSpacing('md')
34497
+ width: w || '100%',
34498
+ height: h || getSpacing('md')
34639
34499
  };
34640
34500
  case 'chip':
34641
34501
  return {
34642
- width: width || (sizeValue * 3),
34643
- height: height || sizeValue
34502
+ width: w || (sizeValue * 3),
34503
+ height: h || sizeValue
34644
34504
  };
34645
34505
  case 'avatar':
34646
34506
  case 'circle':
34647
34507
  return {
34648
- width: width || sizeValue,
34649
- height: height || sizeValue
34508
+ width: w || sizeValue,
34509
+ height: h || sizeValue
34650
34510
  };
34651
34511
  case 'button':
34652
34512
  return {
34653
- width: width || (sizeValue * 4),
34654
- height: height || sizeValue
34513
+ width: w || (sizeValue * 4),
34514
+ height: h || sizeValue
34655
34515
  };
34656
34516
  case 'card':
34657
34517
  return {
34658
- width: width || '100%',
34659
- height: height || (sizeValue * 6)
34518
+ width: w || '100%',
34519
+ height: h || (sizeValue * 6)
34660
34520
  };
34661
34521
  case 'rectangle':
34662
34522
  case 'rounded':
34663
34523
  default:
34664
34524
  return {
34665
- width: width || '100%',
34666
- height: height || sizeValue
34525
+ width: w || '100%',
34526
+ height: h || sizeValue
34667
34527
  };
34668
34528
  }
34669
34529
  };
@@ -35731,7 +35591,7 @@ const styles$6 = reactNative.StyleSheet.create({
35731
35591
  },
35732
35592
  });
35733
35593
 
35734
- const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCount = 20, }) => {
35594
+ const WaveformSkeleton = ({ w = 300, h = 60, fullWidth = false, barsCount = 20, }) => {
35735
35595
  const theme = useTheme();
35736
35596
  const styles = reactNative.StyleSheet.create({
35737
35597
  animatedBar: {
@@ -35747,18 +35607,18 @@ const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCou
35747
35607
  backgroundColor: theme.colors.gray[1],
35748
35608
  borderRadius: 4,
35749
35609
  flexDirection: 'row',
35750
- height,
35610
+ height: h,
35751
35611
  justifyContent: 'space-between',
35752
35612
  paddingHorizontal: 4,
35753
- width: fullWidth ? '100%' : width,
35613
+ width: fullWidth ? '100%' : w,
35754
35614
  },
35755
35615
  });
35756
35616
  // Generate random heights for skeleton bars
35757
35617
  const barHeights = Array.from({ length: barsCount }, () => Math.random() * 0.6 + 0.2 // Heights between 20% and 80% of container
35758
35618
  );
35759
- const barWidth = fullWidth ? 'auto' : Math.max(1, (width - 40) / barsCount - 2);
35619
+ const barWidth = fullWidth ? 'auto' : Math.max(1, (w - 40) / barsCount - 2);
35760
35620
  return (jsxRuntime.jsx(reactNative.View, { style: styles.container, children: barHeights.map((heightRatio, index) => {
35761
- const barHeight = height * heightRatio;
35621
+ const barHeight = h * heightRatio;
35762
35622
  const isAnimated = index % 3 === 0; // Animate every 3rd bar for shimmer effect
35763
35623
  return (jsxRuntime.jsx(reactNative.View, { style: [
35764
35624
  styles.bar,
@@ -35773,7 +35633,7 @@ const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCou
35773
35633
  }) }));
35774
35634
  };
35775
35635
 
35776
- const Waveform = React.memo(({ peaks, width = 300, height = 60, color = 'primary', barWidth = 2, barGap = 1, strokeWidth = 2, minBarHeight = 1, variant = 'bars', gradientColors, progress = 0, progressColor, interactive = false, normalize = false, fullWidth = false, onSeek, onDragStart, onDrag, onDragEnd, accessibilityLabel, accessibilityHint, style, maxVisibleBars, showProgressLine = false, progressLineStyle, showTimeStamps = false, duration, timeStampInterval,
35636
+ const Waveform = React.memo(({ peaks, w = 300, h = 60, color = 'primary', barWidth = 2, barGap = 1, strokeWidth = 2, minBarHeight = 1, variant = 'bars', gradientColors, progress = 0, progressColor, interactive = false, normalize = false, fullWidth = false, onSeek, onDragStart, onDrag, onDragEnd, accessibilityLabel, accessibilityHint, style, maxVisibleBars, showProgressLine = false, progressLineStyle, showTimeStamps = false, duration, timeStampInterval,
35777
35637
  // New features
35778
35638
  loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel = 1, zoomCenter = 0.5, onZoomChange, enableAnimations = true, showRMS = false, rmsData, markers = [], enablePerformanceMonitoring = false, onPerformanceMetrics, ...restProps }) => {
35779
35639
  const theme = useTheme();
@@ -35860,12 +35720,12 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35860
35720
  targetBars = maxVisibleBars || peaks.length;
35861
35721
  }
35862
35722
  else {
35863
- // For fixed width, calculate how many bars fit
35864
- const maxBars = Math.floor(width / totalBarSpace);
35723
+ // For fixed w, calculate how many bars fit
35724
+ const maxBars = Math.floor(w / totalBarSpace);
35865
35725
  targetBars = maxVisibleBars ? Math.min(maxBars, maxVisibleBars) : maxBars;
35866
35726
  }
35867
35727
  if (targetBars <= 0) {
35868
- console.warn('Waveform: Not enough width to render any bars');
35728
+ console.warn('Waveform: Not enough w to render any bars');
35869
35729
  return [];
35870
35730
  }
35871
35731
  // If we have fewer peaks than target bars, return all peaks
@@ -35888,7 +35748,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35888
35748
  downsampled.push(maxValue);
35889
35749
  }
35890
35750
  return downsampled;
35891
- }, [peaks, width, barWidth, barGap, fullWidth, maxVisibleBars]);
35751
+ }, [peaks, w, barWidth, barGap, fullWidth, maxVisibleBars]);
35892
35752
  // Normalize peaks if requested
35893
35753
  const normalizedPeaks = React.useMemo(() => {
35894
35754
  if (!normalize || processedPeaks.length === 0) {
@@ -35911,16 +35771,16 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35911
35771
  if (fullWidth) {
35912
35772
  return {
35913
35773
  width: '100%',
35914
- height: height,
35915
- viewBox: `0 0 ${actualWaveformWidth} ${height}`,
35774
+ height: h,
35775
+ viewBox: `0 0 ${actualWaveformWidth} ${h}`,
35916
35776
  preserveAspectRatio: 'none'
35917
35777
  };
35918
35778
  }
35919
35779
  return {
35920
- width: width,
35921
- height: height
35780
+ width: w,
35781
+ height: h
35922
35782
  };
35923
- }, [fullWidth, actualWaveformWidth, height, width]);
35783
+ }, [fullWidth, actualWaveformWidth, h, w]);
35924
35784
  const handleLayout = React.useCallback((event) => {
35925
35785
  const { width: containerWidth, height: containerHeight } = event.nativeEvent.layout;
35926
35786
  setContainerDimensions({ width: containerWidth, height: containerHeight });
@@ -35935,7 +35795,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35935
35795
  }
35936
35796
  else {
35937
35797
  // Fallback if container hasn't been measured yet
35938
- position = locationX / (width || 300);
35798
+ position = locationX / (w || 300);
35939
35799
  }
35940
35800
  }
35941
35801
  else {
@@ -35943,7 +35803,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35943
35803
  position = Math.min(locationX, actualWaveformWidth) / actualWaveformWidth;
35944
35804
  }
35945
35805
  return Math.max(0, Math.min(1, position));
35946
- }, [fullWidth, containerDimensions.width, width, actualWaveformWidth]);
35806
+ }, [fullWidth, containerDimensions.width, w, actualWaveformWidth]);
35947
35807
  const handleResponderGrant = React.useCallback((event) => {
35948
35808
  var _a, _b, _c;
35949
35809
  if (!interactive)
@@ -36030,8 +35890,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36030
35890
  const renderBars = () => {
36031
35891
  return normalizedPeaks.map((peak, index) => {
36032
35892
  const x = index * (barWidth + barGap);
36033
- const barHeight = Math.max(minBarHeight, Math.abs(peak) * height * 0.8);
36034
- const y = (height - barHeight) / 2;
35893
+ const barHeight = Math.max(minBarHeight, Math.abs(peak) * h * 0.8);
35894
+ const y = (h - barHeight) / 2;
36035
35895
  const isProgress = x < progressX;
36036
35896
  const fillColor = isProgress ? actualProgressColor : waveformColor;
36037
35897
  return (jsxRuntime.jsx(Svg.Rect, { x: x, y: y, width: barWidth, height: barHeight, fill: fillColor, rx: variant === 'rounded' ? barWidth / 2 : 0 }, index));
@@ -36045,7 +35905,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36045
35905
  const stepX = actualWaveformWidth / (normalizedPeaks.length - 1);
36046
35906
  normalizedPeaks.forEach((peak, index) => {
36047
35907
  const x = index * stepX;
36048
- const y = height / 2 + (peak * height * 0.4);
35908
+ const y = h / 2 + (peak * h * 0.4);
36049
35909
  const lineCommand = index === 0 ? `M ${x} ${y}` : ` L ${x} ${y}`;
36050
35910
  pathData += lineCommand;
36051
35911
  // Build progress path up to the progress position
@@ -36059,8 +35919,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36059
35919
  const renderGradient = () => {
36060
35920
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Svg.Defs, { children: jsxRuntime.jsx(Svg.LinearGradient, { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: resolvedGradientColors.map((color, index) => (jsxRuntime.jsx(Svg.Stop, { offset: `${(index / (resolvedGradientColors.length - 1 || 1)) * 100}%`, stopColor: color }, index))) }) }), normalizedPeaks.map((peak, index) => {
36061
35921
  const x = index * (barWidth + barGap);
36062
- const barHeight = Math.max(minBarHeight, Math.abs(peak) * height * 0.8);
36063
- const y = (height - barHeight) / 2;
35922
+ const barHeight = Math.max(minBarHeight, Math.abs(peak) * h * 0.8);
35923
+ const y = (h - barHeight) / 2;
36064
35924
  return (jsxRuntime.jsx(Svg.Rect, { x: x, y: y, width: barWidth, height: barHeight, fill: `url(#${gradientId})` }, index));
36065
35925
  })] }));
36066
35926
  };
@@ -36070,8 +35930,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36070
35930
  return null;
36071
35931
  const clampedProgress = Math.max(0, Math.min(1, progress));
36072
35932
  const progressX = clampedProgress * actualWaveformWidth;
36073
- return (jsxRuntime.jsx(Svg.Line, { x1: progressX, y1: 0, x2: progressX, y2: height, stroke: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.color) || theme.colors.gray[7], strokeWidth: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.width) || 2, strokeOpacity: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.opacity) || 0.8 }));
36074
- }, [showProgressLine, progress, actualWaveformWidth, height, progressLineStyle, theme.colors.gray]);
35933
+ return (jsxRuntime.jsx(Svg.Line, { x1: progressX, y1: 0, x2: progressX, y2: h, stroke: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.color) || theme.colors.gray[7], strokeWidth: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.width) || 2, strokeOpacity: (progressLineStyle === null || progressLineStyle === void 0 ? void 0 : progressLineStyle.opacity) || 0.8 }));
35934
+ }, [showProgressLine, progress, actualWaveformWidth, h, progressLineStyle, theme.colors.gray]);
36075
35935
  // Timestamp markers component
36076
35936
  const TimeStamps = React.useMemo(() => {
36077
35937
  if (!showTimeStamps || !duration || !timeStampInterval)
@@ -36092,10 +35952,10 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36092
35952
  }
36093
35953
  return `${mins}:${secs.toString().padStart(2, '0')}`;
36094
35954
  };
36095
- timestamps.push(jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: height - 10, x2: x, y2: height, stroke: theme.colors.gray[5], strokeWidth: 1, strokeOpacity: 0.6 }), jsxRuntime.jsx(Svg.Text, { x: x, y: height + 15, fill: theme.colors.gray[6], fontSize: 10, textAnchor: "middle", opacity: 0.8, children: formatTime(time) })] }, i));
35955
+ timestamps.push(jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: h - 10, x2: x, y2: h, stroke: theme.colors.gray[5], strokeWidth: 1, strokeOpacity: 0.6 }), jsxRuntime.jsx(Svg.Text, { x: x, y: h + 15, fill: theme.colors.gray[6], fontSize: 10, textAnchor: "middle", opacity: 0.8, children: formatTime(time) })] }, i));
36096
35956
  }
36097
35957
  return jsxRuntime.jsx(Svg.G, { children: timestamps });
36098
- }, [showTimeStamps, duration, timeStampInterval, actualWaveformWidth, height, theme.colors]);
35958
+ }, [showTimeStamps, duration, timeStampInterval, actualWaveformWidth, h, theme.colors]);
36099
35959
  // Selection overlay component
36100
35960
  const SelectionOverlay = React.useMemo(() => {
36101
35961
  if (!selection || selection[0] === selection[1])
@@ -36104,8 +35964,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36104
35964
  const startX = start * actualWaveformWidth;
36105
35965
  const endX = end * actualWaveformWidth;
36106
35966
  const selectionWidth = endX - startX;
36107
- return (jsxRuntime.jsx(Svg.Rect, { x: startX, y: 0, width: selectionWidth, height: height, fill: theme.colors.primary[3], opacity: 0.3, stroke: theme.colors.primary[5], strokeWidth: 1, strokeOpacity: 0.8 }));
36108
- }, [selection, actualWaveformWidth, height, theme.colors.primary]);
35967
+ return (jsxRuntime.jsx(Svg.Rect, { x: startX, y: 0, width: selectionWidth, height: h, fill: theme.colors.primary[3], opacity: 0.3, stroke: theme.colors.primary[5], strokeWidth: 1, strokeOpacity: 0.8 }));
35968
+ }, [selection, actualWaveformWidth, h, theme.colors.primary]);
36109
35969
  // Markers component
36110
35970
  const Markers = React.useMemo(() => {
36111
35971
  if (!markers || markers.length === 0)
@@ -36115,16 +35975,16 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36115
35975
  const markerColor = marker.color || theme.colors.warning[5];
36116
35976
  switch (marker.type || 'line') {
36117
35977
  case 'line':
36118
- return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: 0, x2: x, y2: height, stroke: markerColor, strokeWidth: 2, strokeOpacity: 0.8 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x, y: -5, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
35978
+ return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: 0, x2: x, y2: h, stroke: markerColor, strokeWidth: 2, strokeOpacity: 0.8 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x, y: -5, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
36119
35979
  case 'flag':
36120
- return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: 0, x2: x, y2: height, stroke: markerColor, strokeWidth: 1, strokeOpacity: 0.6 }), jsxRuntime.jsx(Svg.Rect, { x: x + 2, y: 2, width: marker.label ? marker.label.length * 6 + 4 : 20, height: 14, fill: markerColor, rx: 2 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x + 4, y: 12, fill: "white", fontSize: 9, fontWeight: "bold", children: marker.label }))] }, index));
35980
+ return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx(Svg.Line, { x1: x, y1: 0, x2: x, y2: h, stroke: markerColor, strokeWidth: 1, strokeOpacity: 0.6 }), jsxRuntime.jsx(Svg.Rect, { x: x + 2, y: 2, width: marker.label ? marker.label.length * 6 + 4 : 20, height: 14, fill: markerColor, rx: 2 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x + 4, y: 12, fill: "white", fontSize: 9, fontWeight: "bold", children: marker.label }))] }, index));
36121
35981
  case 'dot':
36122
- return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx("circle", { cx: x, cy: height / 2, r: 4, fill: markerColor, stroke: "white", strokeWidth: 1 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x, y: height / 2 + 20, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
35982
+ return (jsxRuntime.jsxs(Svg.G, { children: [jsxRuntime.jsx("circle", { cx: x, cy: h / 2, r: 4, fill: markerColor, stroke: "white", strokeWidth: 1 }), marker.label && (jsxRuntime.jsx(Svg.Text, { x: x, y: h / 2 + 20, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
36123
35983
  default:
36124
35984
  return null;
36125
35985
  }
36126
35986
  }) }));
36127
- }, [markers, actualWaveformWidth, height, theme.colors.warning]);
35987
+ }, [markers, actualWaveformWidth, h, theme.colors.warning]);
36128
35988
  // RMS visualization component
36129
35989
  const RMSBars = React.useMemo(() => {
36130
35990
  if (!showRMS || !rmsData || rmsData.length === 0)
@@ -36132,11 +35992,11 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36132
35992
  const processedRMS = rmsData.slice(0, normalizedPeaks.length);
36133
35993
  return (jsxRuntime.jsx(Svg.G, { opacity: 0.5, children: processedRMS.map((rms, index) => {
36134
35994
  const x = index * (barWidth + barGap);
36135
- const rmsHeight = Math.max(minBarHeight, Math.abs(rms) * height * 0.4); // RMS bars are shorter
36136
- const y = (height - rmsHeight) / 2;
35995
+ const rmsHeight = Math.max(minBarHeight, Math.abs(rms) * h * 0.4); // RMS bars are shorter
35996
+ const y = (h - rmsHeight) / 2;
36137
35997
  return (jsxRuntime.jsx(Svg.Rect, { x: x, y: y, width: barWidth, height: rmsHeight, fill: theme.colors.gray[4], rx: variant === 'rounded' ? barWidth / 2 : 0 }, `rms-${index}`));
36138
35998
  }) }));
36139
- }, [showRMS, rmsData, normalizedPeaks, barWidth, barGap, minBarHeight, height, variant, theme.colors.gray]);
35999
+ }, [showRMS, rmsData, normalizedPeaks, barWidth, barGap, minBarHeight, h, variant, theme.colors.gray]);
36140
36000
  const renderWaveform = () => {
36141
36001
  switch (variant) {
36142
36002
  case 'line':
@@ -36173,17 +36033,17 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36173
36033
  };
36174
36034
  // Early return for empty state
36175
36035
  if (normalizedPeaks.length === 0) {
36176
- return (jsxRuntime.jsx(reactNative.View, { style: [style, fullWidth ? { width: '100%' } : { width }, { height, justifyContent: 'center', alignItems: 'center' }], accessibilityRole: "image", accessibilityLabel: accessibilityLabel || 'Empty waveform', ...restProps, children: jsxRuntime.jsx(Svg, { ...svgProps, children: jsxRuntime.jsx(Svg.Rect, { x: 0, y: height / 2 - 1, width: fullWidth ? '100%' : width, height: 2, fill: waveformColor, opacity: 0.3 }) }) }));
36036
+ return (jsxRuntime.jsx(reactNative.View, { style: [style, fullWidth ? { width: '100%' } : { width: w }, { height: h, justifyContent: 'center', alignItems: 'center' }], accessibilityRole: "image", accessibilityLabel: accessibilityLabel || 'Empty waveform', ...restProps, children: jsxRuntime.jsx(Svg, { ...svgProps, children: jsxRuntime.jsx(Svg.Rect, { x: 0, y: h / 2 - 1, width: fullWidth ? '100%' : w, height: 2, fill: waveformColor, opacity: 0.3 }) }) }));
36177
36037
  }
36178
36038
  if (loading) {
36179
- return (jsxRuntime.jsx(WaveformSkeleton, { width: width, height: height, fullWidth: fullWidth, barsCount: maxVisibleBars || 20 }));
36039
+ return (jsxRuntime.jsx(WaveformSkeleton, { w: w, h: h, fullWidth: fullWidth, barsCount: maxVisibleBars || 20 }));
36180
36040
  }
36181
36041
  if (error) {
36182
36042
  return (jsxRuntime.jsx(reactNative.View, { style: [
36183
36043
  style,
36184
- fullWidth ? { width: '100%' } : { width },
36044
+ fullWidth ? { width: '100%' } : { width: w },
36185
36045
  {
36186
- height,
36046
+ height: h,
36187
36047
  justifyContent: 'center',
36188
36048
  alignItems: 'center',
36189
36049
  backgroundColor: theme.colors.error[1],
@@ -36193,7 +36053,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36193
36053
  }
36194
36054
  ], accessibilityRole: "alert", accessibilityLabel: `Waveform error: ${error}`, ...restProps, children: jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.error[7], fontSize: 12, textAlign: 'center' }, children: error }) }));
36195
36055
  }
36196
- return (jsxRuntime.jsx(WrapperComponent, { ref: containerRef, style: [style, fullWidth ? { width: '100%' } : { width }], accessible: true, focusable: interactive, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), ...wrapperProps, ...restProps, children: jsxRuntime.jsxs(Svg, { ...svgProps, children: [SelectionOverlay, RMSBars, renderWaveform(), ProgressLine, TimeStamps, Markers] }) }));
36056
+ return (jsxRuntime.jsx(WrapperComponent, { ref: containerRef, style: [style, fullWidth ? { width: '100%' } : { width: w }], accessible: true, focusable: interactive, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), ...wrapperProps, ...restProps, children: jsxRuntime.jsxs(Svg, { ...svgProps, children: [SelectionOverlay, RMSBars, renderWaveform(), ProgressLine, TimeStamps, Markers] }) }));
36197
36057
  });
36198
36058
  Waveform.displayName = 'Waveform';
36199
36059
 
@@ -36215,7 +36075,7 @@ const AudioPlayer = React.forwardRef(({ source, peaks: providedPeaks, autoPlay =
36215
36075
  channel: 'mix',
36216
36076
  }, showTime = true, timeFormat = 'mm:ss', showMetadata = false, metadata, showSpectrum = false, spectrumOptions, enableKeyboardShortcuts = true, enableGestures = true, onLoad, onPlaybackStateChange, onProgress, onEnd, onError, onBuffer,
36217
36077
  // Waveform props
36218
- width = 300, height = 60, color = 'primary', interactive = true, onSeek, style, ...waveformProps }, ref) => {
36078
+ w = 300, h = 60, color = 'primary', interactive = true, onSeek, style, ...waveformProps }, ref) => {
36219
36079
  const theme = useTheme();
36220
36080
  const { playSound } = useSound();
36221
36081
  // Refs
@@ -36562,7 +36422,7 @@ width = 300, height = 60, color = 'primary', interactive = true, onSeek, style,
36562
36422
  alignSelf: 'flex-start',
36563
36423
  }, children: jsxRuntime.jsx(reactNative.Text, { style: { color: 'white', fontSize: DESIGN_TOKENS.typography.fontSize.sm }, children: "Retry" }) }))] }));
36564
36424
  }
36565
- return (jsxRuntime.jsxs(reactNative.View, { style: [{ width: '100%' }, style], children: [controlsPosition === 'top' && renderMetadata(), controlsPosition === 'top' && renderControls(), controls.waveform && peaks.length > 0 && (jsxRuntime.jsx(reactNative.View, { style: { marginVertical: DESIGN_TOKENS.spacing.sm }, children: jsxRuntime.jsx(Waveform, { peaks: peaks, width: width, height: height, color: color, progress: progress, interactive: interactive, onSeek: handleWaveformSeek, showProgressLine: true, progressLineStyle: {
36425
+ return (jsxRuntime.jsxs(reactNative.View, { style: [{ width: '100%' }, style], children: [controlsPosition === 'top' && renderMetadata(), controlsPosition === 'top' && renderControls(), controls.waveform && peaks.length > 0 && (jsxRuntime.jsx(reactNative.View, { style: { marginVertical: DESIGN_TOKENS.spacing.sm }, children: jsxRuntime.jsx(Waveform, { peaks: peaks, w: w, h: h, color: color, progress: progress, interactive: interactive, onSeek: handleWaveformSeek, showProgressLine: true, progressLineStyle: {
36566
36426
  color: theme.colors.primary[5],
36567
36427
  width: 2,
36568
36428
  opacity: 0.8,
@@ -37291,14 +37151,14 @@ const IMAGE_SIZES = {
37291
37151
  '2xl': 80,
37292
37152
  '3xl': 96,
37293
37153
  };
37294
- function Image({ src, source, alt, accessibilityLabel, resizeMode = 'cover', size, width, height, aspectRatio, borderWidth, borderColor, rounded, circle, fallback, loading, onLoad, onError, onLoadStart, onLoadEnd, containerStyle, imageStyle, testID, style, ...rest }) {
37154
+ function Image({ src, source, alt, accessibilityLabel, resizeMode = 'cover', size, w, h, aspectRatio, borderWidth, borderColor, rounded, circle, fallback, loading, onLoad, onError, onLoadStart, onLoadEnd, containerStyle, imageStyle, testID, style, ...rest }) {
37295
37155
  const theme = useTheme();
37296
37156
  const [loadError, setLoadError] = React.useState(false);
37297
37157
  const [isLoading, setIsLoading] = React.useState(true);
37298
37158
  const { spacingProps } = extractSpacingProps(rest);
37299
37159
  // Determine dimensions
37300
- let finalWidth = width;
37301
- let finalHeight = height;
37160
+ let finalWidth = w;
37161
+ let finalHeight = h;
37302
37162
  if (size && typeof size === 'string' && IMAGE_SIZES[size]) {
37303
37163
  finalWidth = finalWidth || IMAGE_SIZES[size];
37304
37164
  finalHeight = finalHeight || IMAGE_SIZES[size];
@@ -39106,7 +38966,7 @@ function QRCode(props) {
39106
38966
  });
39107
38967
  }
39108
38968
  }, [copy, copyValue, toast, otherProps.copyToastMessage, otherProps.copyToastTitle]);
39109
- const content = (jsxRuntime.jsxs(reactNative.View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [jsxRuntime.jsx(QRCodeSVG, { value: value, size: size, maxWidth: '100%', backgroundColor: backgroundColor, color: resolvedColor, errorCorrectionLevel: errorCorrectionLevel, quietZone: quietZone, logo: logo, style: style, testID: testID, accessibilityLabel: accessibilityLabel, onError: onError, ...spacingProps, ...layoutProps, ...rest }), otherProps.showCopyButton && (jsxRuntime.jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
38969
+ const content = (jsxRuntime.jsxs(reactNative.View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [jsxRuntime.jsx(QRCodeSVG, { value: value, size: size, maxW: '100%', backgroundColor: backgroundColor, color: resolvedColor, errorCorrectionLevel: errorCorrectionLevel, quietZone: quietZone, logo: logo, style: style, testID: testID, accessibilityLabel: accessibilityLabel, onError: onError, ...spacingProps, ...layoutProps, ...rest }), otherProps.showCopyButton && (jsxRuntime.jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
39110
38970
  if (shouldCopyOnPress) {
39111
38971
  return (jsxRuntime.jsx(reactNative.Pressable, { onPress: handleCopy, accessibilityLabel: accessibilityLabel || 'QR code', children: content }));
39112
38972
  }
@@ -39756,111 +39616,6 @@ const styles$2 = reactNative.StyleSheet.create({
39756
39616
  },
39757
39617
  });
39758
39618
 
39759
- // Optional imports for web compatibility
39760
- const LottieReact = reactNative.Platform.OS === 'web'
39761
- ? resolveOptionalModule('lottie-react', {
39762
- accessor: mod => { var _a; return (_a = mod.default) !== null && _a !== void 0 ? _a : mod; },
39763
- })
39764
- : null;
39765
- const DotLottieReact = reactNative.Platform.OS === 'web'
39766
- ? resolveOptionalModule('@lottiefiles/dotlottie-react', {
39767
- accessor: mod => mod.DotLottieReact,
39768
- })
39769
- : null;
39770
- let cachedNativeStatus = null;
39771
- let nativeLottieComponent;
39772
- let nativeModuleLoadWarningLogged = false;
39773
- let nativeModuleConfigWarningLogged = false;
39774
- const loadNativeLottieComponent = () => {
39775
- if (nativeLottieComponent !== undefined) {
39776
- return nativeLottieComponent;
39777
- }
39778
- const module = resolveOptionalModule('lottie-react-native', {
39779
- accessor: mod => { var _a; return (_a = mod === null || mod === void 0 ? void 0 : mod.default) !== null && _a !== void 0 ? _a : mod; },
39780
- });
39781
- if (!module && !nativeModuleLoadWarningLogged && __DEV__) {
39782
- console.warn('[Lottie] Failed to load lottie-react-native module. Rendering fallback instead.');
39783
- nativeModuleLoadWarningLogged = true;
39784
- }
39785
- nativeLottieComponent = module !== null && module !== void 0 ? module : null;
39786
- return nativeLottieComponent;
39787
- };
39788
- const getNativeLottieStatus = () => {
39789
- var _a, _b, _c;
39790
- if (cachedNativeStatus) {
39791
- return cachedNativeStatus;
39792
- }
39793
- if (reactNative.Platform.OS === 'web') {
39794
- cachedNativeStatus = { component: null, available: false };
39795
- return cachedNativeStatus;
39796
- }
39797
- const component = loadNativeLottieComponent();
39798
- if (!component) {
39799
- cachedNativeStatus = { component: null, available: false };
39800
- return cachedNativeStatus;
39801
- }
39802
- let viewManagerAvailable = false;
39803
- try {
39804
- const viewManager = (_c = (_b = (_a = reactNative.UIManager === null || reactNative.UIManager === void 0 ? void 0 : reactNative.UIManager.getViewManagerConfig) === null || _a === void 0 ? void 0 : _a.call(reactNative.UIManager, 'LottieAnimationView')) !== null && _b !== void 0 ? _b : reactNative.UIManager === null || reactNative.UIManager === void 0 ? void 0 : reactNative.UIManager.LottieAnimationView) !== null && _c !== void 0 ? _c : reactNative.NativeModules === null || reactNative.NativeModules === void 0 ? void 0 : reactNative.NativeModules.LottieAnimationView;
39805
- viewManagerAvailable = !!viewManager;
39806
- }
39807
- catch (error) {
39808
- viewManagerAvailable = false;
39809
- }
39810
- if (!viewManagerAvailable && !nativeModuleConfigWarningLogged && __DEV__) {
39811
- console.warn('[Lottie] Native LottieAnimationView is unavailable. Run `npx expo install lottie-react-native` and rebuild to enable animations.');
39812
- nativeModuleConfigWarningLogged = true;
39813
- }
39814
- cachedNativeStatus = {
39815
- component,
39816
- available: viewManagerAvailable,
39817
- };
39818
- return cachedNativeStatus;
39819
- };
39820
- /**
39821
- * Lottie component with safe fallback when native module not present or on unsupported platforms.
39822
- */
39823
- const Lottie = React.forwardRef(function LottieCmp(props, ref) {
39824
- const { source, autoPlay = true, loop = true, progress, speed = 1, style, testID, paused, resizeMode = 'contain', onAnimationFinish } = props;
39825
- const internalRef = React.useRef(null);
39826
- const nativeStatus = getNativeLottieStatus();
39827
- const NativeLottieView = nativeStatus.component;
39828
- React.useImperativeHandle(ref, () => ({
39829
- play: (...args) => { var _a, _b; return (_b = (_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.play) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
39830
- pause: () => { var _a, _b; return (_b = (_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.pause) === null || _b === void 0 ? void 0 : _b.call(_a); },
39831
- reset: () => { var _a, _b; return (_b = (_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.reset) === null || _b === void 0 ? void 0 : _b.call(_a); },
39832
- setProgress: (p) => { var _a, _b; return (_b = (_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.setProgress) === null || _b === void 0 ? void 0 : _b.call(_a, p); },
39833
- }), []);
39834
- React.useEffect(() => {
39835
- var _a;
39836
- if (progress != null && ((_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.setProgress)) {
39837
- internalRef.current.setProgress(progress);
39838
- }
39839
- }, [progress]);
39840
- // Web implementation
39841
- if (reactNative.Platform.OS === 'web') {
39842
- // Check if source is a string (URL) and ends with .lottie
39843
- const isLottieFile = typeof source === 'string' && source.endsWith('.lottie');
39844
- if (isLottieFile && DotLottieReact) {
39845
- // Use DotLottieReact for .lottie files
39846
- return (jsxRuntime.jsx(DotLottieReact, { src: source, autoplay: autoPlay, loop: loop, speed: speed, style: style, "data-testid": testID }));
39847
- }
39848
- else if (LottieReact) {
39849
- // Use lottie-react for standard Lottie JSON
39850
- return (jsxRuntime.jsx(LottieReact, { animationData: source, autoplay: autoPlay, loop: loop, style: style, "data-testid": testID }));
39851
- }
39852
- else {
39853
- return jsxRuntime.jsx(Text, { children: "Lottie not available on web" });
39854
- }
39855
- }
39856
- // Native implementation using lottie-react-native
39857
- if (!nativeStatus.available || !NativeLottieView) {
39858
- return (jsxRuntime.jsx(reactNative.View, { style: [{ justifyContent: 'center', alignItems: 'center' }, style], testID: testID, children: jsxRuntime.jsx(Text, { style: { textAlign: 'center', opacity: 0.7 }, children: "Lottie animations require the native `lottie-react-native` module. Install it and rebuild the app, or view this example on the web." }) }));
39859
- }
39860
- return (jsxRuntime.jsx(NativeLottieView, { ref: internalRef, source: source, autoPlay: autoPlay, loop: loop, speed: speed, progress: progress, style: style, testID: testID, resizeMode: resizeMode, onAnimationFinish: onAnimationFinish, ...(paused != null ? { paused } : {}) }));
39861
- });
39862
- Lottie.displayName = 'Lottie';
39863
-
39864
39619
  const PLAYBACK_RATES = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
39865
39620
  function formatTime(seconds) {
39866
39621
  const hours = Math.floor(seconds / 3600);
@@ -40808,7 +40563,7 @@ const DEFAULT_CONTROLS = {
40808
40563
  autoHide: true,
40809
40564
  autoHideTimeout: 3000,
40810
40565
  };
40811
- const Video = React.forwardRef(({ source, width, height, aspectRatio = 16 / 9, poster, autoPlay = false, loop = false, muted = false, volume = 1, playbackRate = 1, quality = 'auto', controls = true, timeline = [], youtubeOptions, onPlay, onPause, onSeek, onTimeUpdate, onDurationChange, onVolumeChange, onPlaybackRateChange, onQualityChange, onFullscreenChange, onError, onLoad, onLoadStart, onBuffer, onTimelineEvent, style, videoStyle, controlsStyle, accessibilityLabel, testID, ...rest }, ref) => {
40566
+ const Video = React.forwardRef(({ source, w, h, aspectRatio = 16 / 9, poster, autoPlay = false, loop = false, muted = false, volume = 1, playbackRate = 1, quality = 'auto', controls = true, timeline = [], youtubeOptions, onPlay, onPause, onSeek, onTimeUpdate, onDurationChange, onVolumeChange, onPlaybackRateChange, onQualityChange, onFullscreenChange, onError, onLoad, onLoadStart, onBuffer, onTimelineEvent, style, videoStyle, controlsStyle, accessibilityLabel, testID, ...rest }, ref) => {
40812
40567
  const theme = useTheme();
40813
40568
  const { spacingProps } = extractSpacingProps(rest);
40814
40569
  // Internal state
@@ -41058,24 +40813,24 @@ const Video = React.forwardRef(({ source, width, height, aspectRatio = 16 / 9, p
41058
40813
  // overflow: 'hidden',
41059
40814
  // position: 'relative',
41060
40815
  };
41061
- if (width && height) {
41062
- baseStyle.width = width;
41063
- baseStyle.height = height;
40816
+ if (w && h) {
40817
+ baseStyle.width = w;
40818
+ baseStyle.height = h;
41064
40819
  }
41065
- else if (width) {
41066
- baseStyle.width = width;
41067
- baseStyle.height = typeof width === 'number' ? width / aspectRatio : '100%';
40820
+ else if (w) {
40821
+ baseStyle.width = w;
40822
+ baseStyle.height = typeof w === 'number' ? w / aspectRatio : '100%';
41068
40823
  }
41069
- else if (height) {
41070
- baseStyle.height = height;
41071
- baseStyle.width = typeof height === 'number' ? height * aspectRatio : '100%';
40824
+ else if (h) {
40825
+ baseStyle.height = h;
40826
+ baseStyle.width = typeof h === 'number' ? h * aspectRatio : '100%';
41072
40827
  }
41073
40828
  else {
41074
40829
  baseStyle.width = '100%';
41075
40830
  baseStyle.aspectRatio = aspectRatio;
41076
40831
  }
41077
40832
  return baseStyle;
41078
- }, [theme.colors.surface, width, height, aspectRatio]);
40833
+ }, [theme.colors.surface, w, h, aspectRatio]);
41079
40834
  // Handle touch events for control visibility
41080
40835
  const handleContainerPress = React.useCallback(() => {
41081
40836
  if (controlsConfig && controlsConfig.autoHide) {
@@ -41298,7 +41053,6 @@ exports.ListGroupDivider = ListGroupDivider;
41298
41053
  exports.ListGroupItem = ListGroupItem;
41299
41054
  exports.Loader = Loader;
41300
41055
  exports.LoadingOverlay = LoadingOverlay;
41301
- exports.Lottie = Lottie;
41302
41056
  exports.MacAppStoreButton = MacAppStoreButton;
41303
41057
  exports.Mark = Mark;
41304
41058
  exports.Markdown = Markdown;
@@ -41334,7 +41088,6 @@ exports.RadioGroup = RadioGroup;
41334
41088
  exports.RangeSlider = RangeSlider;
41335
41089
  exports.Rating = Rating;
41336
41090
  exports.RedditJoinBadge = RedditJoinBadge;
41337
- exports.RichTextEditor = RichTextEditor;
41338
41091
  exports.Ring = Ring;
41339
41092
  exports.Row = Row;
41340
41093
  exports.SIZE_SCALES = SIZE_SCALES;