@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/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { createContext, useContext, useMemo, useEffect, useState, useRef, useCallback, forwardRef, memo, useReducer, isValidElement, cloneElement, useImperativeHandle } from 'react';
4
- import { Platform, Modal, StyleSheet, View, Pressable, I18nManager, Keyboard, Dimensions, Text as Text$1, AccessibilityInfo, findNodeHandle, Animated as Animated$1, Easing, AppState, useWindowDimensions, PanResponder, BackHandler, Appearance, PixelRatio, NativeModules, TextInput, ScrollView, KeyboardAvoidingView, TouchableOpacity, FlatList, Linking, Image as Image$1, InteractionManager, StatusBar as StatusBar$1, UIManager } from 'react-native';
4
+ import { Platform, Modal, StyleSheet, View, Pressable, I18nManager, Keyboard, Dimensions, Text as Text$1, AccessibilityInfo, findNodeHandle, Animated as Animated$1, Easing, AppState, useWindowDimensions, PanResponder, BackHandler, Appearance, PixelRatio, NativeModules, TextInput, ScrollView, KeyboardAvoidingView, TouchableOpacity, FlatList, Linking, Image as Image$1, InteractionManager, StatusBar as StatusBar$1 } from 'react-native';
5
5
  import Animated, { useSharedValue, withRepeat, withTiming, cancelAnimation, useAnimatedStyle, interpolate, Extrapolation, withSpring, Easing as Easing$1, runOnJS, withSequence, withDelay, interpolateColor, useDerivedValue, ReduceMotion } from 'react-native-reanimated';
6
6
  import { useSafeAreaInsets, SafeAreaInsetsContext, SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context';
7
7
  import Svg, { Path, Defs, LinearGradient, Stop, Circle, Line, G, Text as Text$2, Rect, RadialGradient, ClipPath } from 'react-native-svg';
@@ -706,16 +706,16 @@ const DARK_THEME = {
706
706
  '#F2F2F7'
707
707
  ],
708
708
  highlight: [
709
- '#2A2313',
710
- '#3D3320',
711
- '#4F422D',
712
- '#61523A',
713
- '#736247',
714
- '#FBBF24', // Keep same base as light mode for consistency
715
- '#FCD34D',
716
- '#FDE68A',
717
- '#FEF3C7',
718
- '#FFFBEB'
709
+ '#1E3A5F', // Deep blue
710
+ '#1E4976', //
711
+ '#1D5A8F', //
712
+ '#2563EB', // Bright blue
713
+ '#3B82F6', // Primary blue
714
+ '#60A5FA', // Light blue
715
+ '#93C5FD', //
716
+ '#BFDBFE', //
717
+ '#DBEAFE', //
718
+ '#EFF6FF' // Very light blue
719
719
  ],
720
720
  pink: [
721
721
  '#831843', '#9D174D', '#BE185D', '#DB2777', '#EC4899',
@@ -771,9 +771,9 @@ const DARK_THEME = {
771
771
  },
772
772
  states: {
773
773
  focusRing: 'rgba(10,132,255,0.55)',
774
- textSelection: 'rgba(251, 191, 36, 0.2)', // Slightly more subtle for dark mode
775
- highlightText: '#FDE68A', // highlight[7] for good contrast on dark
776
- highlightBackground: 'rgba(97, 82, 58, 0.8)' // Darker highlight[3] with more opacity
774
+ textSelection: 'rgba(10, 132, 255, 0.25)', // Primary blue for selection
775
+ highlightText: '#60A5FA', // primary[4] - bright blue for good contrast on dark
776
+ highlightBackground: 'rgba(59, 130, 246, 0.35)' // primary[5] with transparency
777
777
  },
778
778
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
779
779
  fontSizes: {
@@ -862,6 +862,8 @@ const DARK_THEME = {
862
862
  const optionalModuleCache = new Map();
863
863
  const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production';
864
864
  // Metro bundler requires static string literals for require; keep all optional modules here.
865
+ // NOTE: Do NOT add react-syntax-highlighter here - it causes Metro to fail on native
866
+ // when the package isn't installed. Instead, pass the loader dynamically from web-only code.
865
867
  const optionalModuleLoaders = {
866
868
  'react-native': () => require('react-native'),
867
869
  'expo-clipboard': () => require('expo-clipboard'),
@@ -870,21 +872,9 @@ const optionalModuleLoaders = {
870
872
  'expo-document-picker': () => require('expo-document-picker'),
871
873
  'react-native-webview': () => require('react-native-webview'),
872
874
  'lodash.debounce': () => require('lodash.debounce'),
873
- 'react-syntax-highlighter': () => require('react-syntax-highlighter'),
874
- 'react-syntax-highlighter/dist/esm/languages/prism/jsx': () => require('react-syntax-highlighter/dist/esm/languages/prism/jsx'),
875
- 'react-syntax-highlighter/dist/esm/languages/prism/tsx': () => require('react-syntax-highlighter/dist/esm/languages/prism/tsx'),
876
- 'react-syntax-highlighter/dist/esm/languages/prism/typescript': () => require('react-syntax-highlighter/dist/esm/languages/prism/typescript'),
877
- 'react-syntax-highlighter/dist/esm/languages/prism/javascript': () => require('react-syntax-highlighter/dist/esm/languages/prism/javascript'),
878
- 'react-syntax-highlighter/dist/esm/languages/prism/json': () => require('react-syntax-highlighter/dist/esm/languages/prism/json'),
879
- 'react-syntax-highlighter/dist/esm/languages/prism/bash': () => require('react-syntax-highlighter/dist/esm/languages/prism/bash'),
880
- 'react-syntax-highlighter/dist/esm/styles/prism/prism': () => require('react-syntax-highlighter/dist/esm/styles/prism/prism'),
881
- 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus': () => require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus'),
882
875
  'expo-audio': () => require('expo-audio'),
883
876
  'react-native-gesture-handler': () => require('react-native-gesture-handler'),
884
877
  'expo-status-bar': () => require('expo-status-bar'),
885
- 'lottie-react': () => require('lottie-react'),
886
- '@lottiefiles/dotlottie-react': () => require('@lottiefiles/dotlottie-react'),
887
- 'lottie-react-native': () => require('lottie-react-native'),
888
878
  'expo-navigation-bar': () => require('expo-navigation-bar'),
889
879
  };
890
880
  /**
@@ -1972,7 +1962,6 @@ function resolveComponentSize(value, scale, options = {}) {
1972
1962
  }
1973
1963
  const firstAvailable = allowed.find(key => scale[key] !== undefined);
1974
1964
  if (firstAvailable && scale[firstAvailable] !== undefined) {
1975
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1976
1965
  return scale[firstAvailable];
1977
1966
  }
1978
1967
  throw new Error('resolveComponentSize: no matching size found in provided scale.');
@@ -2334,18 +2323,17 @@ function extractSpacingProps(props) {
2334
2323
  *
2335
2324
  * @param props - The layout properties object
2336
2325
  * @param props.fullWidth - When true, sets width to 100%
2337
- * @param props.w - Shorthand width property (overrides fullWidth)
2338
- * @param props.width - Specific width value (overrides fullWidth and w)
2339
- * @param props.height - Height value
2340
- * @param props.maxWidth - Maximum width constraint
2341
- * @param props.minWidth - Minimum width constraint
2342
- * @param props.maxHeight - Maximum height constraint
2343
- * @param props.minHeight - Minimum height constraint
2326
+ * @param props.w - Width property (overrides fullWidth)
2327
+ * @param props.h - Height value
2328
+ * @param props.maxW - Maximum width constraint
2329
+ * @param props.minW - Minimum width constraint
2330
+ * @param props.maxH - Maximum height constraint
2331
+ * @param props.minH - Minimum height constraint
2344
2332
  *
2345
2333
  * @returns A partial ViewStyle object containing the computed layout styles
2346
2334
  *
2347
2335
  * @remarks
2348
- * Property precedence for width: width > w > fullWidth
2336
+ * Property precedence for width: w > fullWidth
2349
2337
  * The function processes width properties in order of specificity, with more specific
2350
2338
  * properties overriding more general ones.
2351
2339
  */
@@ -2355,43 +2343,38 @@ function getLayoutStyles(props) {
2355
2343
  if (props.fullWidth) {
2356
2344
  styles.width = '100%';
2357
2345
  }
2358
- // Handle shorthand width prop first
2346
+ // Handle width prop (overrides fullWidth)
2359
2347
  if (props.w !== undefined) {
2360
2348
  styles.width = props.w;
2361
2349
  }
2362
- // Handle specific dimensions (override fullWidth and w if specified)
2363
- if (props.width !== undefined) {
2364
- styles.width = props.width;
2365
- }
2366
- if (props.height !== undefined) {
2367
- styles.height = props.height;
2350
+ if (props.h !== undefined) {
2351
+ styles.height = props.h;
2368
2352
  }
2369
- if (props.maxWidth !== undefined) {
2370
- styles.maxWidth = props.maxWidth;
2353
+ if (props.maxW !== undefined) {
2354
+ styles.maxWidth = props.maxW;
2371
2355
  }
2372
- if (props.minWidth !== undefined) {
2373
- styles.minWidth = props.minWidth;
2356
+ if (props.minW !== undefined) {
2357
+ styles.minWidth = props.minW;
2374
2358
  }
2375
- if (props.maxHeight !== undefined) {
2376
- styles.maxHeight = props.maxHeight;
2359
+ if (props.maxH !== undefined) {
2360
+ styles.maxHeight = props.maxH;
2377
2361
  }
2378
- if (props.minHeight !== undefined) {
2379
- styles.minHeight = props.minHeight;
2362
+ if (props.minH !== undefined) {
2363
+ styles.minHeight = props.minH;
2380
2364
  }
2381
2365
  return styles;
2382
2366
  }
2383
2367
  // Helper to extract layout props from component props
2384
2368
  function extractLayoutProps(props) {
2385
- const { fullWidth, w, width, height, maxWidth, minWidth, maxHeight, minHeight, ...otherProps } = props;
2369
+ const { fullWidth, w, h, maxW, minW, maxH, minH, ...otherProps } = props;
2386
2370
  const layoutProps = {
2387
2371
  fullWidth,
2388
2372
  w,
2389
- width,
2390
- height,
2391
- maxWidth,
2392
- minWidth,
2393
- maxHeight,
2394
- minHeight
2373
+ h,
2374
+ maxW,
2375
+ minW,
2376
+ maxH,
2377
+ minH
2395
2378
  };
2396
2379
  return { layoutProps, otherProps };
2397
2380
  }
@@ -2660,7 +2643,7 @@ async function measureAsyncPerformance(name, fn) {
2660
2643
  const OVERLAY_CACHE_LIMIT = 200;
2661
2644
  const overlayPositionCache = new Map();
2662
2645
  const formatNumber = (value) => Number.isFinite(value) ? Math.round(value * 100) / 100 : 0;
2663
- const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary) => {
2646
+ const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary, matchAnchorWidth) => {
2664
2647
  return [
2665
2648
  formatNumber(anchorX),
2666
2649
  formatNumber(anchorY),
@@ -2677,6 +2660,7 @@ const createOverlayCacheKey = (anchorX, anchorY, anchorWidth, anchorHeight, over
2677
2660
  flip ? '1' : '0',
2678
2661
  shift ? '1' : '0',
2679
2662
  formatNumber(boundary),
2663
+ matchAnchorWidth ? '1' : '0',
2680
2664
  Platform.OS,
2681
2665
  ].join('|');
2682
2666
  };
@@ -2722,11 +2706,12 @@ registerViewportListeners();
2722
2706
  * Enhanced overlay positioning that prevents off-screen rendering with intelligent caching
2723
2707
  */
2724
2708
  function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2725
- const { placement = 'auto', offset = 8, viewport = getViewport(), strategy = 'fixed', flip = true, shift = true, boundary = 8, fallbackPlacements = ['bottom', 'top', 'right', 'left'] } = options;
2709
+ const { placement = 'auto', offset = 8, viewport = getViewport(), strategy = 'fixed', flip = true, shift = true, boundary = 8, fallbackPlacements = ['bottom', 'top', 'right', 'left'], matchAnchorWidth = false, } = options;
2726
2710
  // If overlay height is unknown/small (pre-measure), use a heuristic height for decision-making
2727
2711
  // This helps avoid choosing "bottom" when near the bottom of the viewport.
2728
2712
  const heuristicHeight = Math.max(overlay.height || 0, 240);
2729
- const overlayWidth = overlay.width;
2713
+ // When matchAnchorWidth is true, use anchor width for overlay width calculations
2714
+ const overlayWidth = matchAnchorWidth ? anchor.width : overlay.width;
2730
2715
  const overlayHeight = overlay.height > 0 ? overlay.height : heuristicHeight;
2731
2716
  // Account for scroll if using absolute positioning
2732
2717
  const scrollX = (Platform.OS === 'web' && strategy === 'absolute')
@@ -2737,7 +2722,7 @@ function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2737
2722
  const anchorX = anchor.x + scrollX;
2738
2723
  const anchorY = anchor.y + scrollY;
2739
2724
  // Check cache first
2740
- const cacheKey = createOverlayCacheKey(anchorX, anchorY, anchor.width, anchor.height, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary);
2725
+ const cacheKey = createOverlayCacheKey(anchorX, anchorY, anchor.width, anchor.height, overlayWidth, overlayHeight, placement, offset, viewport, strategy, flip, shift, boundary, matchAnchorWidth);
2741
2726
  const cached = getCachedOverlayPosition(cacheKey);
2742
2727
  if (cached) {
2743
2728
  return cached;
@@ -2805,10 +2790,14 @@ function calculateOverlayPositionEnhanced(anchor, overlay, options = {}) {
2805
2790
  // If enforcement moved the overlay to the opposite vertical side to avoid covering the anchor,
2806
2791
  // reflect that in the returned placement so arrows/styles are consistent.
2807
2792
  const resolvedPlacement = adjustPlacementIfMoved(finalPlacement, result, anchorRect);
2793
+ // When matchAnchorWidth is true, preserve anchor width without constraining to maxWidth
2794
+ const computedFinalWidth = matchAnchorWidth
2795
+ ? anchor.width
2796
+ : Math.min(result.finalWidth || overlay.width, result.maxWidth || overlay.width);
2808
2797
  const finalResult = {
2809
2798
  ...result,
2810
2799
  placement: resolvedPlacement,
2811
- finalWidth: Math.min(result.finalWidth || overlay.width, result.maxWidth || overlay.width),
2800
+ finalWidth: computedFinalWidth,
2812
2801
  finalHeight: Math.min(result.finalHeight || overlay.height, result.maxHeight || overlay.height),
2813
2802
  };
2814
2803
  // Cache the result
@@ -3565,9 +3554,14 @@ const Text = (allProps) => {
3565
3554
  }
3566
3555
  // Platform-specific rendering
3567
3556
  if (Platform.OS === 'web' && isHTMLVariant(htmlTag)) {
3568
- const webStyles = convertToWebStyles([textStyles, spacingStyles, style,
3569
- // make sure text is side to side
3570
- { display: 'inline' }
3557
+ const styleArray = Array.isArray(style) ? style : [style];
3558
+ const hasDisplayOverride = styleArray.some((item) => item && ((item.display !== undefined) || (item.whiteSpace !== undefined)));
3559
+ const webStyles = convertToWebStyles([
3560
+ textStyles,
3561
+ spacingStyles,
3562
+ style,
3563
+ // default to inline unless caller explicitly requests display/whitespace behavior
3564
+ ...(hasDisplayOverride ? [] : [{ display: 'inline' }]),
3571
3565
  ]);
3572
3566
  // Handle text selection for web
3573
3567
  if (!selectable) {
@@ -6243,7 +6237,7 @@ const Button = (allProps) => {
6243
6237
  // Use the actual measured width instead of character-based estimates
6244
6238
  const layoutStyles = {
6245
6239
  ...baseLayoutStyles,
6246
- ...(loading && measuredWidth && !layoutProps.width && !layoutProps.w && !layoutProps.fullWidth
6240
+ ...(loading && measuredWidth && !layoutProps.w && !layoutProps.fullWidth
6247
6241
  ? { width: measuredWidth, minWidth: measuredWidth }
6248
6242
  : {})
6249
6243
  };
@@ -6677,18 +6671,22 @@ const useSafeSafeAreaInsets = () => {
6677
6671
  return { top: 0, bottom: 0, left: 0, right: 0 };
6678
6672
  }
6679
6673
  };
6680
- function Dialog({ visible, variant = 'modal', title, children, closable = true, backdrop = true, backdropClosable = true, shouldClose = false, onClose, width, height, style, bottomSheetSwipeZone = 'container', }) {
6674
+ function Dialog({ visible, variant = 'modal', title, children, closable = true, backdrop = true, backdropClosable = true, shouldClose = false, onClose, w, h, radius, style, showHeader = true, bottomSheetSwipeZone = 'container', }) {
6681
6675
  const theme = useTheme();
6682
6676
  const { isRTL } = useDirection();
6683
6677
  const insets = useSafeSafeAreaInsets();
6684
6678
  const { width: screenWidth, height: screenHeight } = useWindowDimensions();
6685
6679
  const horizontalMargin = 32; // safety margin so dialog never touches edges
6686
6680
  const isNativePlatform = Platform.OS === 'ios' || Platform.OS === 'android';
6687
- const defaultModalMaxWidth = Math.min((width || 500), Math.max(200, screenWidth - horizontalMargin));
6681
+ const defaultModalMaxWidth = Math.min((w || 500), Math.max(200, screenWidth - horizontalMargin));
6688
6682
  const modalEffectiveWidth = variant !== 'modal'
6689
6683
  ? undefined
6690
6684
  : Math.min(defaultModalMaxWidth, screenWidth - horizontalMargin);
6691
- const bottomSheetMaxWidth = Math.min(width ? width : (isNativePlatform ? 720 : Math.min(600, screenWidth - horizontalMargin)), screenWidth);
6685
+ const bottomSheetMaxWidth = Math.min(w ? w : (isNativePlatform ? 720 : Math.min(600, screenWidth - horizontalMargin)), screenWidth);
6686
+ const resolvedRadius = radius !== null && radius !== void 0 ? radius : (variant === 'bottomsheet' ? 20 : 16);
6687
+ const resolvedMaxHeight = variant === 'bottomsheet'
6688
+ ? (h !== null && h !== void 0 ? h : Math.max(200, screenHeight - insets.top - 24))
6689
+ : (variant === 'fullscreen' ? '100%' : (h || '90%'));
6692
6690
  const invokeOnClose = useCallback(() => {
6693
6691
  onClose === null || onClose === void 0 ? void 0 : onClose();
6694
6692
  }, [onClose]);
@@ -6744,20 +6742,12 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6744
6742
  event.preventDefault();
6745
6743
  }
6746
6744
  }
6747
- // Allow dragging in both directions but apply rubber band for upward movement
6748
- const dragDistance = gestureState.dy;
6749
- if (dragDistance >= 0) {
6750
- // Downward movement - apply subtle resistance for better feel
6751
- const resistance = 0.8;
6752
- const resistedDistance = dragDistance * resistance + (dragDistance > 100 ? (dragDistance - 100) * 0.2 : 0);
6753
- slideAnim.value = resistedDistance;
6754
- }
6755
- else {
6756
- // Upward movement - apply rubber band effect
6757
- const upwardResistance = 0.3;
6758
- const rubberBandDistance = dragDistance * upwardResistance;
6759
- slideAnim.value = rubberBandDistance;
6760
- }
6745
+ // Only allow downward movement (dismiss gesture)
6746
+ const dragDistance = Math.max(0, gestureState.dy);
6747
+ // Downward movement - apply subtle resistance for better feel
6748
+ const resistance = 0.8;
6749
+ const resistedDistance = dragDistance * resistance + (dragDistance > 100 ? (dragDistance - 100) * 0.2 : 0);
6750
+ slideAnim.value = resistedDistance;
6761
6751
  }
6762
6752
  },
6763
6753
  onPanResponderRelease: (_, gestureState) => {
@@ -6914,8 +6904,8 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6914
6904
  }, [shouldClose]);
6915
6905
  const isDark = theme.colorScheme === 'dark';
6916
6906
  const surfaceColor = isDark ? theme.backgrounds.surface : '#FFFFFF';
6917
- const borderColor = isDark ? theme.colors.gray[6] : '#E1E3E6';
6918
- const headerBg = isDark ? theme.backgrounds.subtle : surfaceColor;
6907
+ isDark ? theme.colors.gray[6] : '#E1E3E6';
6908
+ const headerBg = surfaceColor;
6919
6909
  const contentBg = surfaceColor;
6920
6910
  const dynamicStyles = StyleSheet.create({
6921
6911
  backdrop: {
@@ -6926,24 +6916,28 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6926
6916
  }, // Allow backdropFilter on web
6927
6917
  modalContainer: {
6928
6918
  backgroundColor: contentBg,
6929
- borderRadius: variant === 'fullscreen' ? 0 : (variant === 'bottomsheet' ? 20 : 16),
6930
- borderBottomLeftRadius: variant === 'bottomsheet' ? 0 : undefined,
6931
- borderBottomRightRadius: variant === 'bottomsheet' ? 0 : undefined,
6919
+ borderRadius: variant === 'fullscreen' ? 0 : resolvedRadius,
6920
+ ...(variant === 'bottomsheet' ? {
6921
+ borderBottomLeftRadius: 0,
6922
+ borderBottomRightRadius: 0,
6923
+ } : {}),
6924
+ overflow: 'hidden', // Clip content to border radius
6932
6925
  // Clamp width to viewport (minus margins) while respecting provided width
6933
6926
  maxWidth: variant === 'fullscreen'
6934
6927
  ? '100%'
6935
6928
  : variant === 'bottomsheet'
6936
6929
  ? bottomSheetMaxWidth
6937
6930
  : defaultModalMaxWidth,
6938
- maxHeight: variant === 'fullscreen' ? '100%' : (height || '90%'),
6931
+ maxHeight: resolvedMaxHeight,
6939
6932
  width: variant === 'fullscreen'
6940
6933
  ? '100%'
6941
6934
  : variant === 'modal'
6942
6935
  ? modalEffectiveWidth || 'auto'
6943
6936
  : '100%',
6944
- height: variant === 'fullscreen' ? '100%' : (variant === 'modal' ? undefined : undefined),
6945
- // For modal variant, remove flex to allow fit-content behavior
6946
- ...(variant === 'modal' ? {} : { flex: 1 }),
6937
+ // Fullscreen uses 100% height, others auto-size to content
6938
+ height: variant === 'fullscreen' ? '100%' : undefined,
6939
+ // Only fullscreen should stretch to fill
6940
+ ...(variant === 'fullscreen' ? { flex: 1 } : {}),
6947
6941
  // Ensure minWidth never exceeds viewport clamp
6948
6942
  minWidth: variant === 'modal' ? Math.min(300, Math.max(200, screenWidth - horizontalMargin)) : undefined,
6949
6943
  alignSelf: variant === 'bottomsheet' ? 'center' : 'center',
@@ -6969,24 +6963,27 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
6969
6963
  }
6970
6964
  : Platform.OS === 'android' && variant !== 'fullscreen'
6971
6965
  ? { elevation: 16, }
6972
- : {
6973
- boxShadow: 'none',
6974
- height: '100%',
6975
- position: 'absolute',
6976
- }),
6966
+ : variant === 'fullscreen'
6967
+ ? {
6968
+ boxShadow: 'none',
6969
+ height: '100%',
6970
+ position: 'absolute',
6971
+ }
6972
+ : { boxShadow: 'none' }),
6977
6973
  }, // Allow boxShadow on web
6978
6974
  header: {
6979
6975
  alignItems: 'center',
6980
- backgroundColor: headerBg,
6981
- borderBottomColor: borderColor,
6982
- borderBottomWidth: variant === 'fullscreen' ? 0 : 1,
6976
+ backgroundColor: showHeader ? headerBg : 'transparent',
6977
+ // borderBottomColor: showHeader ? borderColor : 'transparent',
6978
+ // borderBottomWidth: showHeader && variant !== 'fullscreen' ? 1 : 0,
6983
6979
  flexDirection: isRTL ? 'row-reverse' : 'row',
6984
6980
  justifyContent: 'space-between',
6985
6981
  padding: 20,
6982
+ paddingBottom: title ? 0 : 20,
6986
6983
  },
6987
6984
  content: {
6988
- // For modal variant, remove flex to allow fit-content behavior
6989
- ...(variant === 'modal' ? {} : { flex: 1 }),
6985
+ // Only fullscreen content should stretch
6986
+ ...(variant === 'fullscreen' ? { flex: 1 } : {}),
6990
6987
  alignSelf: 'stretch',
6991
6988
  backgroundColor: contentBg,
6992
6989
  padding: variant === 'fullscreen' ? 0 : 20,
@@ -7042,8 +7039,10 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
7042
7039
  });
7043
7040
  const bottomSheetAnimatedStyle = useAnimatedStyle(() => {
7044
7041
  if (variant === 'bottomsheet') {
7042
+ // Clamp to 0 minimum to prevent seeing "under" the sheet
7043
+ const clampedY = Math.max(0, slideAnim.value);
7045
7044
  return {
7046
- transform: [{ translateY: slideAnim.value }],
7045
+ transform: [{ translateY: clampedY }],
7047
7046
  };
7048
7047
  }
7049
7048
  return {};
@@ -7060,7 +7059,7 @@ function Dialog({ visible, variant = 'modal', title, children, closable = true,
7060
7059
  animatedStyle = bottomSheetAnimatedStyle;
7061
7060
  }
7062
7061
  return (jsxs(Animated.View, { style: [dynamicStyles.modalContainer, animatedStyle], ...(variant === 'bottomsheet' && bottomSheetSwipeZone === 'container' && panHandlers ? panHandlers : {}), children: [variant === 'bottomsheet' && (jsx(View, { style: dynamicStyles.dragHandleContainer, ...(bottomSheetSwipeZone === 'handle' && panHandlers ? panHandlers : {}), children: jsx(View, { style: dynamicStyles.dragHandle }) })), (title !== null &&
7063
- title && closable) && (jsxs(View, { style: dynamicStyles.header, children: [jsx(Text, { variant: "h3", color: "text", children: title || '' }), closable && (jsx(Button, { variant: "ghost", onPress: handleClose, style: dynamicStyles.closeButton, children: jsx(Icon, { name: "x", size: "md" }) }))] })), jsx(View, { style: [dynamicStyles.content, style], children: children })] }));
7062
+ title && closable) && (jsxs(View, { style: dynamicStyles.header, children: [jsx(Text, { variant: "h3", color: "text", children: title || '' }), closable && variant !== 'bottomsheet' && (jsx(Button, { variant: "ghost", onPress: handleClose, style: dynamicStyles.closeButton, children: jsx(Icon, { name: "x", size: "md" }) }))] })), jsx(View, { style: [dynamicStyles.content, style], children: children })] }));
7064
7063
  };
7065
7064
  return (jsx(Modal, { visible: visible, transparent: true, animationType: "none", statusBarTranslucent: variant === 'fullscreen', children: jsxs(Animated.View, { style: [
7066
7065
  dynamicStyles.backdrop,
@@ -7269,7 +7268,7 @@ function DialogRenderer() {
7269
7268
  return null;
7270
7269
  // Render the topmost dialog
7271
7270
  const topDialog = dialogs[dialogs.length - 1];
7272
- return (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 }));
7271
+ return (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 }));
7273
7272
  }
7274
7273
 
7275
7274
  const Flex = factory((props, ref) => {
@@ -8354,7 +8353,14 @@ const getContrastPreference = () => {
8354
8353
  return 'less';
8355
8354
  return 'no-preference';
8356
8355
  };
8357
- const getColorScheme = () => { var _a, _b; return (_b = (_a = Appearance === null || Appearance === void 0 ? void 0 : Appearance.getColorScheme) === null || _a === void 0 ? void 0 : _a.call(Appearance)) !== null && _b !== void 0 ? _b : 'no-preference'; };
8356
+ const getColorScheme = () => {
8357
+ var _a;
8358
+ const scheme = (_a = Appearance === null || Appearance === void 0 ? void 0 : Appearance.getColorScheme) === null || _a === void 0 ? void 0 : _a.call(Appearance);
8359
+ // Handle 'unspecified' from newer React Native versions
8360
+ if (scheme === 'light' || scheme === 'dark')
8361
+ return scheme;
8362
+ return 'no-preference';
8363
+ };
8358
8364
  const getReducedMotion = async () => {
8359
8365
  if (Platform.OS === 'web') {
8360
8366
  if (typeof window === 'undefined' || typeof window.matchMedia !== 'function')
@@ -8579,7 +8585,13 @@ function useDeviceInfo(options = {}) {
8579
8585
  useEffect(() => {
8580
8586
  var _a;
8581
8587
  const colorSubscription = (_a = Appearance === null || Appearance === void 0 ? void 0 : Appearance.addChangeListener) === null || _a === void 0 ? void 0 : _a.call(Appearance, ({ colorScheme: scheme }) => {
8582
- setColorScheme(scheme !== null && scheme !== void 0 ? scheme : 'no-preference');
8588
+ // Handle 'unspecified' from newer React Native versions
8589
+ if (scheme === 'light' || scheme === 'dark') {
8590
+ setColorScheme(scheme);
8591
+ }
8592
+ else {
8593
+ setColorScheme('no-preference');
8594
+ }
8583
8595
  });
8584
8596
  const mediaListeners = [];
8585
8597
  let boldSubscription;
@@ -9124,7 +9136,7 @@ function SpotlightRoot({ query, onQueryChange, children, opened = false, onClose
9124
9136
  const targetWidth = Math.min(560, Math.max(280, screenWidth - horizontalMargin));
9125
9137
  // (Hotkey registration moved to main Spotlight component for access to store.toggle())
9126
9138
  const fullscreen = shouldUseModal;
9127
- return (jsx(Dialog, { visible: opened, onClose: onClose, variant: fullscreen ? 'fullscreen' : 'modal', backdrop: true, backdropClosable: true, width: fullscreen ? undefined : targetWidth, title: null, style: [
9139
+ return (jsx(Dialog, { visible: opened, onClose: onClose, variant: fullscreen ? 'fullscreen' : 'modal', backdrop: true, backdropClosable: true, w: fullscreen ? undefined : targetWidth, title: null, style: [
9128
9140
  styles$e.spotlightModal,
9129
9141
  fullscreen && { width: '100%', height: '100%', maxHeight: '100%', borderRadius: 0, position: 'fixed', top: 0, left: 0 },
9130
9142
  !fullscreen && {
@@ -9686,6 +9698,23 @@ function generateUniversalCSS() {
9686
9698
  xl: '88em'
9687
9699
  };
9688
9700
  const universalCSS = `
9701
+ /* Reset browser default input styles to prevent double borders */
9702
+ input, textarea, select {
9703
+ outline: none !important;
9704
+ -webkit-appearance: none !important;
9705
+ -moz-appearance: none !important;
9706
+ appearance: none !important;
9707
+ }
9708
+
9709
+ input:focus, textarea:focus, select:focus {
9710
+ outline: none !important;
9711
+ }
9712
+
9713
+ /* Ensure React Native Web focusable elements don't show browser outlines */
9714
+ [data-focusable="true"]:focus {
9715
+ outline: none !important;
9716
+ }
9717
+
9689
9718
  /* Color scheme based visibility */
9690
9719
  .platform-blocks-light-hidden {
9691
9720
  display: none !important;
@@ -9732,12 +9761,14 @@ function UniversalCSS() {
9732
9761
  return;
9733
9762
  }
9734
9763
  // Check if styles are already injected
9735
- const existingStyle = document.getElementById('platform-blocks-universal-css');
9736
- if (existingStyle) {
9764
+ let styleElement = document.getElementById('platform-blocks-universal-css');
9765
+ if (styleElement) {
9766
+ // Update content if it exists (in case CSS changed)
9767
+ styleElement.textContent = css;
9737
9768
  return;
9738
9769
  }
9739
9770
  // Create and inject styles
9740
- const styleElement = document.createElement('style');
9771
+ styleElement = document.createElement('style');
9741
9772
  styleElement.id = 'platform-blocks-universal-css';
9742
9773
  styleElement.textContent = css;
9743
9774
  document.head.appendChild(styleElement);
@@ -11861,9 +11892,10 @@ const Row = ({ direction = 'row', gap = 'sm', ...props }) => {
11861
11892
  };
11862
11893
  /**
11863
11894
  * Column component - alias for Flex with direction="column"
11895
+ * Defaults to fullWidth={true} since vertical layouts typically fill available width
11864
11896
  */
11865
- const Column = ({ direction = 'column', gap = 'sm', ...props }) => {
11866
- return jsx(Flex, { direction: direction, gap: gap, ...props });
11897
+ const Column = ({ direction = 'column', gap = 'sm', fullWidth = true, ...props }) => {
11898
+ return jsx(Flex, { direction: direction, gap: gap, fullWidth: fullWidth, ...props });
11867
11899
  };
11868
11900
  Row.displayName = 'Row';
11869
11901
 
@@ -13978,35 +14010,101 @@ function createNativeHighlighter(theme, isDark, variant = 'code', overrides) {
13978
14010
  };
13979
14011
  }
13980
14012
 
13981
- // Prism light build for JSX/TSX (react-syntax-highlighter)
14013
+ // Syntax highlighter - only loaded on web, native uses built-in tokenizer
14014
+ // These are initialized lazily on first use to avoid Metro bundling issues
13982
14015
  let PrismSyntaxHighlighter = null;
13983
14016
  let prismLightTheme = null;
13984
14017
  let prismDarkTheme = null;
13985
- if (Platform.OS === 'web') {
13986
- PrismSyntaxHighlighter = resolveOptionalModule('react-syntax-highlighter', {
13987
- accessor: (module) => module.PrismLight,
13988
- devWarning: 'react-syntax-highlighter not found, CodeBlock will use basic formatting',
13989
- });
13990
- if (PrismSyntaxHighlighter) {
13991
- const registerLanguage = (moduleId, name) => {
13992
- const languageModule = resolveOptionalModule(moduleId, { accessor: (mod) => mod.default });
13993
- if (languageModule) {
13994
- PrismSyntaxHighlighter.registerLanguage(name, languageModule);
14018
+ let syntaxHighlighterInitialized = false;
14019
+ // Use indirect require via new Function to prevent Metro from statically analyzing imports
14020
+ // Metro bundles ALL require() calls it finds, even in try-catch blocks
14021
+ // new Function() creates a runtime-evaluated require that Metro can't see
14022
+ const safeRequire = (() => {
14023
+ try {
14024
+ // This creates: function(moduleName) { return require(moduleName); }
14025
+ // The string 'require' is not statically analyzable by Metro
14026
+ return new Function('moduleName', 'return require(moduleName)');
14027
+ }
14028
+ catch (_a) {
14029
+ return null;
14030
+ }
14031
+ })();
14032
+ function initSyntaxHighlighter() {
14033
+ if (syntaxHighlighterInitialized)
14034
+ return;
14035
+ syntaxHighlighterInitialized = true;
14036
+ // Only attempt to load on web
14037
+ if (Platform.OS !== 'web')
14038
+ return;
14039
+ if (!safeRequire)
14040
+ return;
14041
+ try {
14042
+ const rsh = safeRequire('react-syntax-highlighter');
14043
+ PrismSyntaxHighlighter = rsh.PrismLight;
14044
+ if (PrismSyntaxHighlighter) {
14045
+ // Register languages
14046
+ try {
14047
+ const jsx = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/jsx').default;
14048
+ PrismSyntaxHighlighter.registerLanguage('jsx', jsx);
13995
14049
  }
13996
- };
13997
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/jsx', 'jsx');
13998
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/tsx', 'tsx');
13999
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/typescript', 'typescript');
14000
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/javascript', 'javascript');
14001
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/json', 'json');
14002
- registerLanguage('react-syntax-highlighter/dist/esm/languages/prism/bash', 'bash');
14003
- prismLightTheme = resolveOptionalModule('react-syntax-highlighter/dist/esm/styles/prism/prism', {
14004
- accessor: (mod) => mod.default,
14005
- });
14006
- prismDarkTheme = resolveOptionalModule('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus', {
14007
- accessor: (mod) => mod.default,
14008
- devWarning: 'Failed to load prism vsc-dark-plus theme, falling back to prism',
14009
- });
14050
+ catch (_a) {
14051
+ // Language not available
14052
+ }
14053
+ try {
14054
+ const tsx = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/tsx').default;
14055
+ PrismSyntaxHighlighter.registerLanguage('tsx', tsx);
14056
+ }
14057
+ catch (_b) {
14058
+ // Language not available
14059
+ }
14060
+ try {
14061
+ const ts = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/typescript').default;
14062
+ PrismSyntaxHighlighter.registerLanguage('typescript', ts);
14063
+ }
14064
+ catch (_c) {
14065
+ // Language not available
14066
+ }
14067
+ try {
14068
+ const js = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/javascript').default;
14069
+ PrismSyntaxHighlighter.registerLanguage('javascript', js);
14070
+ }
14071
+ catch (_d) {
14072
+ // Language not available
14073
+ }
14074
+ try {
14075
+ const json = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/json').default;
14076
+ PrismSyntaxHighlighter.registerLanguage('json', json);
14077
+ }
14078
+ catch (_e) {
14079
+ // Language not available
14080
+ }
14081
+ try {
14082
+ const bash = safeRequire('react-syntax-highlighter/dist/esm/languages/prism/bash').default;
14083
+ PrismSyntaxHighlighter.registerLanguage('bash', bash);
14084
+ }
14085
+ catch (_f) {
14086
+ // Language not available
14087
+ }
14088
+ // Load themes
14089
+ try {
14090
+ prismLightTheme = safeRequire('react-syntax-highlighter/dist/esm/styles/prism/prism').default;
14091
+ }
14092
+ catch (_g) {
14093
+ // Theme not available
14094
+ }
14095
+ try {
14096
+ prismDarkTheme = safeRequire('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus').default;
14097
+ }
14098
+ catch (_h) {
14099
+ // Theme not available
14100
+ }
14101
+ }
14102
+ }
14103
+ catch (_j) {
14104
+ // react-syntax-highlighter not installed, will use native fallback
14105
+ if (__DEV__) {
14106
+ console.warn('[platform-blocks] react-syntax-highlighter not found, CodeBlock will use basic formatting');
14107
+ }
14010
14108
  }
14011
14109
  }
14012
14110
  const NO_HIGHLIGHTS = new Set();
@@ -14230,6 +14328,8 @@ const FloatingCopyControls = ({ visible, code, onCopy, topOffset, isWeb }) => (j
14230
14328
  }, children: jsx(CopyButton, { value: code, onCopy: onCopy, iconOnly: true, size: "sm", tooltip: "Copy code", tooltipPosition: "left", style: { minHeight: 32, minWidth: 32 } }) }));
14231
14329
  const CodeBlock = (props) => {
14232
14330
  var _a, _b, _c;
14331
+ // Initialize syntax highlighter on first render (web only)
14332
+ React__default.useMemo(() => initSyntaxHighlighter(), []);
14233
14333
  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;
14234
14334
  const { spacingProps, otherProps } = extractSpacingProps(rest);
14235
14335
  const spacingStyles = getSpacingStyles(spacingProps);
@@ -14244,6 +14344,7 @@ const CodeBlock = (props) => {
14244
14344
  const [hovered, setHovered] = React__default.useState(false);
14245
14345
  const [codeHeight, setCodeHeight] = React__default.useState(null);
14246
14346
  const isWeb = Platform.OS === 'web';
14347
+ const webWhitespaceStyle = React__default.useMemo(() => (isWeb ? { whiteSpace: wrap ? 'pre-wrap' : 'pre', display: 'block' } : null), [isWeb, wrap]);
14247
14348
  const showFloatingCopy = showCopyButton && !title && !fileName;
14248
14349
  const showCopyVisible = !isWeb ? showFloatingCopy : showFloatingCopy && hovered;
14249
14350
  const codeData = React__default.useMemo(() => {
@@ -14277,6 +14378,7 @@ const CodeBlock = (props) => {
14277
14378
  boxSizing: 'border-box',
14278
14379
  paddingLeft: showLineNumbers ? 0 : 12,
14279
14380
  paddingRight: showLineNumbers ? 0 : 12,
14381
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14280
14382
  }), [showLineNumbers, wrap]);
14281
14383
  const highlightedLineStyle = React__default.useMemo(() => ({
14282
14384
  backgroundColor: highlightBackgroundColor,
@@ -14288,6 +14390,18 @@ const CodeBlock = (props) => {
14288
14390
  const tokenLines = React__default.useMemo(() => (highlight ? nativeHighlighter(codeData.transformed) : null), [highlight, nativeHighlighter, codeData.transformed]);
14289
14391
  const shouldVirtualizeNative = !isWeb && codeData.lineCount >= LONG_LIST_THRESHOLD;
14290
14392
  const lineHeight = (_c = styles.codeText.lineHeight) !== null && _c !== void 0 ? _c : 18;
14393
+ const normalizeTokenText = React__default.useCallback((text, tokenIndex) => {
14394
+ if (!isWeb || !text)
14395
+ return text;
14396
+ const replaceSpaces = (value) => value.replace(/\t/g, ' ').replace(/ /g, '\u00A0');
14397
+ if (tokenIndex === 0) {
14398
+ return text.replace(/^[\t ]+/, (match) => replaceSpaces(match));
14399
+ }
14400
+ if (text.trim().length === 0) {
14401
+ return replaceSpaces(text);
14402
+ }
14403
+ return text;
14404
+ }, [isWeb]);
14291
14405
  const buildNativeLine = React__default.useCallback((line, index, appendNewline, includeKey) => {
14292
14406
  var _a;
14293
14407
  const lineNumber = index + 1;
@@ -14296,13 +14410,14 @@ const CodeBlock = (props) => {
14296
14410
  const lineStyles = [
14297
14411
  styles.codeText,
14298
14412
  textStyle,
14413
+ webWhitespaceStyle,
14299
14414
  wrap ? { flexWrap: 'wrap' } : { flexWrap: 'nowrap', width: 'auto' },
14300
14415
  ];
14301
14416
  if (isLineHighlighted) {
14302
14417
  lineStyles.push(styles.highlightedLine(isDark, highlightColors));
14303
14418
  }
14304
- return (jsxs(Text, { selectable: true, style: lineStyles, children: [showLineNumbers ? (jsx(Text, { style: { color: lineNumberColor, opacity: 0.7 }, children: `${String(lineNumber).padStart(lineNumberWidth, ' ')} | ` })) : null, tokens.map((token, tokenIdx) => (jsx(Text, { style: { color: token.color }, children: token.text || ' ' }, `${lineNumber}-${tokenIdx}`))), appendNewline ? '\n' : null] }, includeKey ? `line-${lineNumber}` : undefined));
14305
- }, [fallbackColor, highlightColors, highlightSet, isDark, lineNumberColor, lineNumberWidth, showLineNumbers, styles.codeText, styles.highlightedLine, textStyle, tokenLines, wrap]);
14419
+ return (jsxs(Text, { selectable: true, style: lineStyles, children: [showLineNumbers ? (jsx(Text, { style: { color: lineNumberColor, opacity: 0.7 }, children: `${String(lineNumber).padStart(lineNumberWidth, ' ')} | ` })) : null, tokens.map((token, tokenIdx) => (jsx(Text, { style: { color: token.color }, children: normalizeTokenText(token.text || ' ', tokenIdx) }, `${lineNumber}-${tokenIdx}`))), appendNewline ? '\n' : null] }, includeKey ? `line-${lineNumber}` : undefined));
14420
+ }, [fallbackColor, highlightColors, highlightSet, isDark, lineNumberColor, lineNumberWidth, normalizeTokenText, showLineNumbers, styles.codeText, styles.highlightedLine, textStyle, tokenLines, webWhitespaceStyle, wrap]);
14306
14421
  const renderWebCode = React__default.useMemo(() => {
14307
14422
  if (!(isWeb && highlight && PrismSyntaxHighlighter)) {
14308
14423
  return null;
@@ -14316,7 +14431,13 @@ const CodeBlock = (props) => {
14316
14431
  lineHeight: '18px',
14317
14432
  display: 'block',
14318
14433
  width: '100%',
14319
- }, codeTagProps: { style: { fontFamily: styles.codeText.fontFamily } }, wrapLongLines: wrap, wrapLines: wrap, showLineNumbers: prismShowLineNumbers, lineNumberStyle: hideLineNumbersVisually
14434
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14435
+ }, codeTagProps: {
14436
+ style: {
14437
+ fontFamily: styles.codeText.fontFamily,
14438
+ whiteSpace: wrap ? 'pre-wrap' : 'pre',
14439
+ },
14440
+ }, wrapLongLines: wrap, wrapLines: wrap, showLineNumbers: prismShowLineNumbers, lineNumberStyle: hideLineNumbersVisually
14320
14441
  ? { display: 'none' }
14321
14442
  : { opacity: 0.55, paddingRight: 12, userSelect: 'none' }, lineProps: (lineNumber) => {
14322
14443
  const style = { ...baseLineStyle };
@@ -14349,13 +14470,13 @@ const CodeBlock = (props) => {
14349
14470
  ]);
14350
14471
  const renderNativeCode = React__default.useMemo(() => {
14351
14472
  if (!codeData.lineCount) {
14352
- return (jsx(Text, { selectable: true, style: [styles.codeText, textStyle], children: ' ' }));
14473
+ return (jsx(Text, { selectable: true, style: [styles.codeText, textStyle, webWhitespaceStyle], children: ' ' }));
14353
14474
  }
14354
14475
  if (shouldVirtualizeNative) {
14355
14476
  return (jsx(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 }) }));
14356
14477
  }
14357
- return (jsx(Text, { selectable: true, style: [styles.codeText, textStyle], children: codeData.lines.map((line, idx) => buildNativeLine(line, idx, idx < codeData.lineCount - 1, true)) }));
14358
- }, [buildNativeLine, codeData.lineCount, codeData.lines, lineHeight, shouldVirtualizeNative, styles.codeText, textStyle]);
14478
+ return (jsx(Text, { selectable: true, style: [styles.codeText, textStyle, webWhitespaceStyle], children: codeData.lines.map((line, idx) => buildNativeLine(line, idx, idx < codeData.lineCount - 1, true)) }));
14479
+ }, [buildNativeLine, codeData.lineCount, codeData.lines, lineHeight, shouldVirtualizeNative, styles.codeText, textStyle, webWhitespaceStyle]);
14359
14480
  const codeContent = renderWebCode !== null && renderWebCode !== void 0 ? renderWebCode : renderNativeCode;
14360
14481
  const scrollableCodeContent = wrap ? (codeContent) : (jsx(ScrollView, { horizontal: true, bounces: false, showsHorizontalScrollIndicator: true, showsVerticalScrollIndicator: false, contentContainerStyle: { flexGrow: 1 }, style: { width: '100%' }, children: jsx(View, { style: { flexGrow: 1 }, children: codeContent }) }));
14361
14482
  let wrappedCodeContent = scrollableCodeContent;
@@ -15960,11 +16081,13 @@ const BrandButton = (props) => {
15960
16081
  return {
15961
16082
  backgroundColor: 'transparent',
15962
16083
  borderColor: brandConfig.borderColor || brandConfig.backgroundColor,
16084
+ paddingHorizontal: 16,
15963
16085
  };
15964
16086
  case 'ghost':
15965
16087
  return {
15966
16088
  backgroundColor: 'transparent',
15967
16089
  borderColor: 'transparent',
16090
+ paddingHorizontal: 16,
15968
16091
  };
15969
16092
  case 'link':
15970
16093
  return { backgroundColor: 'transparent', borderColor: 'transparent' };
@@ -15972,7 +16095,7 @@ const BrandButton = (props) => {
15972
16095
  return {
15973
16096
  backgroundColor: 'white',
15974
16097
  borderColor: 'transparent',
15975
- paddingHorizontal: 0,
16098
+ paddingHorizontal: 16,
15976
16099
  minWidth: 0,
15977
16100
  height: 'auto',
15978
16101
  color: 'black'
@@ -15981,6 +16104,7 @@ const BrandButton = (props) => {
15981
16104
  return {
15982
16105
  backgroundColor: brandConfig.backgroundColor,
15983
16106
  borderColor: brandConfig.borderColor || brandConfig.backgroundColor,
16107
+ paddingHorizontal: 16,
15984
16108
  };
15985
16109
  }
15986
16110
  })();
@@ -16557,8 +16681,12 @@ const createInputStyles = (theme, isRTL = false) => {
16557
16681
  // Remove any web-specific styling that could interfere
16558
16682
  ...(typeof window !== 'undefined' && {
16559
16683
  outlineWidth: 0,
16684
+ outlineStyle: 'none',
16560
16685
  border: 'none',
16686
+ borderWidth: 0,
16687
+ boxShadow: 'none',
16561
16688
  backgroundColor: 'transparent',
16689
+ boxSizing: 'border-box',
16562
16690
  }),
16563
16691
  },
16564
16692
  inputContainer: {
@@ -17486,7 +17614,7 @@ const TextArea = factory((props, ref) => {
17486
17614
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(props);
17487
17615
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
17488
17616
  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;
17489
- const { height } = layoutProps;
17617
+ const { h } = layoutProps;
17490
17618
  const theme = useTheme();
17491
17619
  const { getTextAreaStyles } = useTextAreaStyles({ theme });
17492
17620
  const [focused, setFocused] = useState(false);
@@ -17550,11 +17678,11 @@ const TextArea = factory((props, ref) => {
17550
17678
  const inputContainerStyles = [
17551
17679
  styles.inputContainer,
17552
17680
  radiusStyles,
17553
- { height }
17681
+ { height: h }
17554
17682
  ];
17555
17683
  const textInputStyles = [
17556
17684
  styles.textInput,
17557
- { height: height || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17685
+ { height: h || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17558
17686
  textAlignVertical: resize === 'none' ? 'top' : undefined,
17559
17687
  // Disable resizing by user if resize is 'none'
17560
17688
  ...(resize === 'none' ? { resizeMode: 'none' } : {})
@@ -17582,7 +17710,7 @@ const TextArea = factory((props, ref) => {
17582
17710
  const clearLabel = clearButtonLabel || 'Clear input';
17583
17711
  return (jsxs(View, { style: containerStyles, testID: testID, children: [(label || description) && (jsx(FieldHeader, { label: label, description: description, required: required, disabled: disabled, error: !!error })), jsxs(View, { style: [inputContainerStyles, { position: 'relative' }], children: [jsx(TextInput, { ref: assignRef,
17584
17712
  // style={]}
17585
- style: { height: height || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17713
+ style: { height: h || (autoResize ? currentRows * 24 : rows * 24), // Approximate row height
17586
17714
  ...textInputStyles.reduce((acc, style) => ({ ...acc, ...style }), {}),
17587
17715
  textAlignVertical: resize === 'none' ? 'top' : undefined,
17588
17716
  // Disable resizing by user if resize is 'none'
@@ -23908,7 +24036,7 @@ const Select = factory((allProps, ref) => {
23908
24036
  var _a;
23909
24037
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(allProps);
23910
24038
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
23911
- 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;
24039
+ 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;
23912
24040
  const theme = useTheme();
23913
24041
  const { shouldUseModal, shouldUseOverlay } = useOverlayMode();
23914
24042
  const menuStyles = useMenuStyles();
@@ -23930,6 +24058,7 @@ const Select = factory((allProps, ref) => {
23930
24058
  keyboardAvoidance,
23931
24059
  closeOnClickOutside: true,
23932
24060
  closeOnEscape: true,
24061
+ matchAnchorWidth: true,
23933
24062
  onClose: () => setOpen(false),
23934
24063
  });
23935
24064
  const hasMeasuredDropdownRef = useRef(false);
@@ -24063,11 +24192,11 @@ const Select = factory((allProps, ref) => {
24063
24192
  }, [position === null || position === void 0 ? void 0 : position.finalWidth, triggerWidth]);
24064
24193
  const resolvedDropdownMaxHeight = useMemo(() => {
24065
24194
  const keyboardMax = typeof (position === null || position === void 0 ? void 0 : position.maxHeight) === 'number' ? position.maxHeight : undefined;
24066
- if (typeof maxHeight === 'number') {
24067
- return keyboardMax ? Math.min(maxHeight, keyboardMax) : maxHeight;
24195
+ if (typeof maxH === 'number') {
24196
+ return keyboardMax ? Math.min(maxH, keyboardMax) : maxH;
24068
24197
  }
24069
- return keyboardMax !== null && keyboardMax !== void 0 ? keyboardMax : maxHeight;
24070
- }, [maxHeight, position === null || position === void 0 ? void 0 : position.maxHeight]);
24198
+ return keyboardMax !== null && keyboardMax !== void 0 ? keyboardMax : maxH;
24199
+ }, [maxH, position === null || position === void 0 ? void 0 : position.maxHeight]);
24071
24200
  const handleSelect = useCallback((opt) => {
24072
24201
  if (opt.disabled)
24073
24202
  return;
@@ -24089,7 +24218,7 @@ const Select = factory((allProps, ref) => {
24089
24218
  close();
24090
24219
  }
24091
24220
  }, [closeOnSelect, close, onChange, valueProp, refocusAfterSelect, keyboardManager, focusTrigger, blurTrigger]);
24092
- const listMaxHeight = resolvedDropdownMaxHeight !== null && resolvedDropdownMaxHeight !== void 0 ? resolvedDropdownMaxHeight : maxHeight;
24221
+ const listMaxHeight = resolvedDropdownMaxHeight !== null && resolvedDropdownMaxHeight !== void 0 ? resolvedDropdownMaxHeight : maxH;
24093
24222
  const menu = useMemo(() => {
24094
24223
  const widthStyle = resolvedDropdownWidth && resolvedDropdownWidth > 0
24095
24224
  ? { width: resolvedDropdownWidth, minWidth: resolvedDropdownWidth }
@@ -24102,18 +24231,17 @@ const Select = factory((allProps, ref) => {
24102
24231
  ...(maxHeightStyle !== null && maxHeightStyle !== void 0 ? maxHeightStyle : {}),
24103
24232
  ...(widthStyle !== null && widthStyle !== void 0 ? widthStyle : {}),
24104
24233
  }, children: jsx(FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item }) => {
24105
- var _a;
24106
24234
  const selected = item.value === value;
24107
24235
  if (renderOption) {
24108
24236
  return jsx(View, { children: renderOption(item, false, selected) });
24109
24237
  }
24110
24238
  const primaryPalette = theme.colors.primary || [];
24111
24239
  const highlightColor = theme.colorScheme === 'dark'
24112
- ? primaryPalette[2] || primaryPalette[3] || theme.text.onPrimary || theme.text.primary
24113
- : primaryPalette[6] || primaryPalette[5] || ((_a = theme.colors.secondary) === null || _a === void 0 ? void 0 : _a[6]) || '#6941C6';
24240
+ ? primaryPalette[5] || primaryPalette[4] || '#60A5FA'
24241
+ : primaryPalette[6] || primaryPalette[5] || '#3B82F6';
24114
24242
  const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
24115
- const accentTextColor = item.disabled ? theme.text.disabled : highlightColor;
24116
- return (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 }));
24243
+ item.disabled ? theme.text.disabled : highlightColor;
24244
+ return (jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: false, tone: "default", hoverTone: "default", activeTone: "default", textColor: baseTextColor, hoverTextColor: baseTextColor, activeTextColor: baseTextColor, startIcon: selected ? jsx(Icon, { name: "check", size: 16, color: highlightColor }) : jsx(View, { style: { width: 16 } }), compact: true, rounded: false, style: { borderRadius: 0 }, children: item.label }));
24117
24245
  }, ItemSeparatorComponent: renderOption ? undefined : ListGroupDivider, style: maxHeightStyle, bounces: false }) }) }));
24118
24246
  }, [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]);
24119
24247
  useEffect(() => {
@@ -24295,6 +24423,7 @@ const AutoComplete = factory((props, ref) => {
24295
24423
  offset,
24296
24424
  autoUpdate: autoReposition,
24297
24425
  fallbackPlacements,
24426
+ matchAnchorWidth: true,
24298
24427
  });
24299
24428
  // Guard: remember last popover size to avoid re-triggering updatePosition on position-only changes
24300
24429
  const lastPopoverSizeRef = useRef(null);
@@ -24318,13 +24447,12 @@ const AutoComplete = factory((props, ref) => {
24318
24447
  }, radiusStyles), [inputStyleFactory, size, focused, error, disabled, showClearButton, radiusStyles]);
24319
24448
  const clearLabel = clearButtonLabel || 'Clear input';
24320
24449
  const menuHighlightColor = useMemo(() => {
24321
- var _a;
24322
24450
  const primaryPalette = theme.colors.primary || [];
24323
24451
  if (theme.colorScheme === 'dark') {
24324
- return primaryPalette[2] || primaryPalette[3] || theme.text.onPrimary || theme.text.primary;
24452
+ return primaryPalette[5] || primaryPalette[4] || '#60A5FA';
24325
24453
  }
24326
- return primaryPalette[6] || primaryPalette[5] || ((_a = theme.colors.secondary) === null || _a === void 0 ? void 0 : _a[6]) || '#6941C6';
24327
- }, [theme.colors.primary, theme.colors.secondary, theme.colorScheme, theme.text.onPrimary, theme.text.primary]);
24454
+ return primaryPalette[6] || primaryPalette[5] || '#3B82F6';
24455
+ }, [theme.colors.primary, theme.colorScheme]);
24328
24456
  const selectedCount = (_a = selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.length) !== null && _a !== void 0 ? _a : 0;
24329
24457
  const hasSelectedValues = multiSelect && selectedCount > 0;
24330
24458
  const currentQueryRef = useRef(query);
@@ -24642,8 +24770,8 @@ const AutoComplete = factory((props, ref) => {
24642
24770
  const defaultRenderItem = useCallback((item, index, isSelected = false) => {
24643
24771
  const highlightQuery = highlightMatches ? currentQueryRef.current : undefined;
24644
24772
  const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
24645
- const accentTextColor = item.disabled ? theme.text.disabled : menuHighlightColor;
24646
- return (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], ...(Platform.OS === 'web' ? {
24773
+ item.disabled ? theme.text.disabled : menuHighlightColor;
24774
+ return (jsx(MenuItemButton, { onPress: () => handleSelectSuggestion(item), disabled: item.disabled, active: false, tone: "default", hoverTone: "default", activeTone: "default", textColor: baseTextColor, hoverTextColor: baseTextColor, activeTextColor: baseTextColor, startIcon: isSelected ? jsx(Icon, { name: "check", size: 16, color: menuHighlightColor }) : jsx(View, { style: { width: 16 } }), compact: true, rounded: false, style: [styles.menuItemButton, suggestionItemStyle], ...(Platform.OS === 'web' ? {
24647
24775
  onMouseDown: (event) => {
24648
24776
  if (event === null || event === void 0 ? void 0 : event.preventDefault) {
24649
24777
  event.preventDefault();
@@ -27152,7 +27280,7 @@ const DatePickerInput = forwardRef(function DatePickerInputInner({ value, defaul
27152
27280
  } }));
27153
27281
  }
27154
27282
  if (dropdownType === 'modal') {
27155
- return (jsxs(View, { ref: ref, children: [renderInput(), jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, width: numberOfMonths > 1 ? Math.min(700, 380 * numberOfMonths + 40) : 400, title: type === 'range'
27283
+ return (jsxs(View, { ref: ref, children: [renderInput(), jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, w: numberOfMonths > 1 ? Math.min(700, 380 * numberOfMonths + 40) : 400, title: type === 'range'
27156
27284
  ? 'Select Date Range'
27157
27285
  : type === 'multiple'
27158
27286
  ? 'Select Dates'
@@ -27181,7 +27309,7 @@ const DatePickerInput = forwardRef(function DatePickerInputInner({ value, defaul
27181
27309
  backgroundColor: pressed ? theme.colors.primary[6] : theme.colors.primary[5],
27182
27310
  }), children: jsx(Text, { size: "sm", weight: "semibold", style: { color: 'white' }, children: "Done" }) })] })] }) }))] }) })] }));
27183
27311
  }
27184
- return (jsxs(View, { ref: ref, children: [renderInput(), jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, width: numberOfMonths > 1 ? Math.min(600, 320 * numberOfMonths + 40) : 350, children: jsxs(View, { ref: focusTrapRef, style: { padding: DESIGN_TOKENS.spacing.lg }, accessible: true, accessibilityLabel: type === 'range'
27312
+ return (jsxs(View, { ref: ref, children: [renderInput(), jsx(Dialog, { visible: isOpen, variant: "modal", onClose: handleClose, w: numberOfMonths > 1 ? Math.min(600, 320 * numberOfMonths + 40) : 350, children: jsxs(View, { ref: focusTrapRef, style: { padding: DESIGN_TOKENS.spacing.lg }, accessible: true, accessibilityLabel: type === 'range'
27185
27313
  ? 'Date range picker dialog'
27186
27314
  : type === 'multiple'
27187
27315
  ? 'Multiple date picker dialog'
@@ -27276,7 +27404,7 @@ const MonthPickerInput = forwardRef(function MonthPickerInput({ value, defaultVa
27276
27404
  pointerEvents: 'none',
27277
27405
  accessible: false,
27278
27406
  focusable: false,
27279
- } }) }), jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, width: 360, children: jsx(View, { style: {
27407
+ } }) }), jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, w: 360, children: jsx(View, { style: {
27280
27408
  padding: DESIGN_TOKENS.spacing.lg,
27281
27409
  }, children: jsx(MonthPicker, { ...restMonthPickerProps, value: currentValue, onChange: handleMonthChange, locale: resolvedLocale, size: resolvedSize }) }) })] }));
27282
27410
  });
@@ -27339,7 +27467,7 @@ const YearPickerInput = forwardRef(function YearPickerInput({ value, defaultValu
27339
27467
  pointerEvents: 'none',
27340
27468
  accessible: false,
27341
27469
  focusable: false,
27342
- } }) }), jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, width: 360, children: jsx(View, { style: {
27470
+ } }) }), jsx(Dialog, { visible: opened, variant: "modal", onClose: handleClose, title: modalTitle, w: 360, children: jsx(View, { style: {
27343
27471
  padding: DESIGN_TOKENS.spacing.lg,
27344
27472
  }, children: jsx(YearPicker, { ...restYearPickerProps, value: currentValue, onChange: handleYearChange, size: resolvedSize }) }) })] }));
27345
27473
  });
@@ -27504,7 +27632,7 @@ const TimePickerInput = ({ value, defaultValue, onChange, format = 24, withSecon
27504
27632
  }
27505
27633
  }, label: label, placeholder: is12h ? 'hh:mm AM' : 'hh:mm', endSection: 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 }) }), jsx(Dialog, { visible: open,
27506
27634
  // variant="fullscreen"
27507
- onClose: handleClose, width: typeof computedPanelWidth === 'number' ? computedPanelWidth : 360, title: title || 'Select Time', children: jsxs(Pressable, { style: {
27635
+ onClose: handleClose, w: typeof computedPanelWidth === 'number' ? computedPanelWidth : 360, title: title || 'Select Time', children: jsxs(Pressable, { style: {
27508
27636
  flex: 1,
27509
27637
  width: '100%',
27510
27638
  justifyContent: 'center',
@@ -28456,303 +28584,6 @@ const EmojiPicker = factory((props, ref) => {
28456
28584
  });
28457
28585
  EmojiPicker.displayName = 'EmojiPicker';
28458
28586
 
28459
- function useRichTextEditorStyles() {
28460
- const theme = useTheme();
28461
- return useMemo(() => StyleSheet.create({
28462
- characterCount: {
28463
- fontSize: 12,
28464
- marginTop: 4,
28465
- textAlign: 'right',
28466
- },
28467
- container: {
28468
- width: '100%',
28469
- },
28470
- disabled: {
28471
- opacity: 0.5,
28472
- },
28473
- editorContainer: {
28474
- backgroundColor: theme.backgrounds.surface,
28475
- borderColor: theme.backgrounds.border,
28476
- borderRadius: parseInt(theme.radii.md, 10),
28477
- borderWidth: 1,
28478
- overflow: 'hidden',
28479
- },
28480
- errorText: {
28481
- fontSize: 12,
28482
- marginTop: 4,
28483
- },
28484
- helperText: {
28485
- fontSize: 12,
28486
- marginTop: 4,
28487
- },
28488
- textInput: {
28489
- fontSize: 16,
28490
- lineHeight: 24,
28491
- padding: parseInt(theme.spacing.md, 10),
28492
- },
28493
- toolButton: {
28494
- alignItems: 'center',
28495
- backgroundColor: 'transparent',
28496
- borderColor: theme.backgrounds.border,
28497
- borderRadius: parseInt(theme.radii.sm, 10),
28498
- borderWidth: 1,
28499
- height: 32,
28500
- justifyContent: 'center',
28501
- width: 32,
28502
- },
28503
- toolSeparator: {
28504
- backgroundColor: theme.backgrounds.border,
28505
- height: 24,
28506
- marginHorizontal: 4,
28507
- width: 1,
28508
- },
28509
- toolbar: {
28510
- backgroundColor: theme.backgrounds.elevated,
28511
- borderBottomColor: theme.backgrounds.border,
28512
- borderBottomWidth: 1,
28513
- },
28514
- toolbarContent: {
28515
- alignItems: 'center',
28516
- flexDirection: 'row',
28517
- gap: 4,
28518
- paddingHorizontal: parseInt(theme.spacing.sm, 10),
28519
- paddingVertical: parseInt(theme.spacing.xs, 10),
28520
- },
28521
- }), [theme]);
28522
- }
28523
-
28524
- // Default toolbar configuration
28525
- const DEFAULT_TOOLBAR_TOOLS = [
28526
- 'bold',
28527
- 'italic',
28528
- 'underline',
28529
- 'separator',
28530
- 'heading',
28531
- 'separator',
28532
- 'align',
28533
- 'separator',
28534
- 'list',
28535
- 'separator',
28536
- 'link',
28537
- 'separator',
28538
- 'color',
28539
- ];
28540
- const RichTextEditor = React__default.memo(({ defaultValue, value, onChange, onSelectionChange, onFocus, onBlur, placeholder = 'Start typing...', readOnly = false, disabled = false, toolbar = {
28541
- enabled: true,
28542
- position: 'top',
28543
- tools: DEFAULT_TOOLBAR_TOOLS,
28544
- }, formats = {
28545
- fontFamilies: ['Arial', 'Georgia', 'Times New Roman', 'Courier New'],
28546
- fontSizes: [12, 14, 16, 18, 20, 24, 28, 32],
28547
- colors: ['#000000', '#333333', '#666666', '#999999', '#CCCCCC', '#FF0000', '#00FF00', '#0000FF'],
28548
- headings: [1, 2, 3, 4, 5, 6],
28549
- }, 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 }) => {
28550
- const theme = useTheme();
28551
- const styles = useRichTextEditorStyles();
28552
- const [content, setContent] = useState(value || defaultValue || { html: '', text: '' });
28553
- const [selection, setSelection] = useState({
28554
- index: 0,
28555
- length: 0,
28556
- });
28557
- const [activeFormats, setActiveFormats] = useState({});
28558
- const [isFocused, setIsFocused] = useState(false);
28559
- const editorRef = useRef(null);
28560
- const autosaveTimerRef = useRef(null);
28561
- // Update content when value prop changes
28562
- useEffect(() => {
28563
- if (value && value !== content) {
28564
- setContent(value);
28565
- }
28566
- }, [value]);
28567
- // Autosave functionality
28568
- useEffect(() => {
28569
- if ((autosave === null || autosave === void 0 ? void 0 : autosave.enabled) && autosave.onSave) {
28570
- if (autosaveTimerRef.current) {
28571
- clearTimeout(autosaveTimerRef.current);
28572
- }
28573
- autosaveTimerRef.current = setTimeout(() => {
28574
- autosave.onSave(content);
28575
- }, autosave.interval || 5000);
28576
- return () => {
28577
- if (autosaveTimerRef.current) {
28578
- clearTimeout(autosaveTimerRef.current);
28579
- }
28580
- };
28581
- }
28582
- }, [content, autosave]);
28583
- const handleContentChange = useCallback((text) => {
28584
- const newContent = {
28585
- text,
28586
- html: text, // For now, treating as plain text
28587
- };
28588
- setContent(newContent);
28589
- onChange === null || onChange === void 0 ? void 0 : onChange(newContent);
28590
- }, [onChange]);
28591
- const handleSelectionChange = useCallback((selection) => {
28592
- const newSelection = {
28593
- index: selection.start,
28594
- length: selection.end - selection.start,
28595
- format: activeFormats,
28596
- };
28597
- setSelection(newSelection);
28598
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(newSelection);
28599
- }, [activeFormats, onSelectionChange]);
28600
- const handleFocus = useCallback(() => {
28601
- setIsFocused(true);
28602
- onFocus === null || onFocus === void 0 ? void 0 : onFocus();
28603
- }, [onFocus]);
28604
- const handleBlur = useCallback(() => {
28605
- setIsFocused(false);
28606
- onBlur === null || onBlur === void 0 ? void 0 : onBlur();
28607
- }, [onBlur]);
28608
- const applyFormat = useCallback((format) => {
28609
- if (readOnly || disabled)
28610
- return;
28611
- const newFormats = { ...activeFormats, ...format };
28612
- setActiveFormats(newFormats);
28613
- // In a real implementation, this would apply formatting to the selected text
28614
- // For this demo, we'll just track the format state
28615
- }, [activeFormats, readOnly, disabled]);
28616
- const toggleFormat = useCallback((formatKey) => {
28617
- if (readOnly || disabled)
28618
- return;
28619
- const currentValue = activeFormats[formatKey];
28620
- applyFormat({ [formatKey]: !currentValue });
28621
- }, [activeFormats, applyFormat, readOnly, disabled]);
28622
- const insertText = useCallback((text) => {
28623
- if (readOnly || disabled)
28624
- return;
28625
- const currentText = content.text;
28626
- const { index } = selection;
28627
- const newText = currentText.slice(0, index) + text + currentText.slice(index);
28628
- handleContentChange(newText);
28629
- }, [content.text, selection, handleContentChange, readOnly, disabled]);
28630
- const insertLink = useCallback(() => {
28631
- if (!(links === null || links === void 0 ? void 0 : links.enabled) || readOnly || disabled)
28632
- return;
28633
- // In a real implementation, this would show a link dialog
28634
- const url = prompt('Enter URL:');
28635
- if (url && (!links.validate || links.validate(url))) {
28636
- applyFormat({ link: url });
28637
- }
28638
- }, [links, applyFormat, readOnly, disabled]);
28639
- useCallback(async () => {
28640
- if (!(images === null || images === void 0 ? void 0 : images.enabled) || readOnly || disabled)
28641
- return;
28642
- // In a real implementation, this would show a file picker
28643
- // For now, we'll just insert a placeholder
28644
- insertText('[Image]');
28645
- }, [images, insertText, readOnly, disabled]);
28646
- useCallback((level) => {
28647
- applyFormat({ heading: level });
28648
- }, [applyFormat]);
28649
- const setAlignment = useCallback((align) => {
28650
- applyFormat({ align });
28651
- }, [applyFormat]);
28652
- const setList = useCallback((listType) => {
28653
- applyFormat({ list: listType });
28654
- }, [applyFormat]);
28655
- const getToolButtonStyle = useCallback((isActive) => [
28656
- styles.toolButton,
28657
- {
28658
- backgroundColor: isActive
28659
- ? (theme.colorScheme === 'dark' ? theme.colors.primary[7] : theme.colors.primary[1])
28660
- : 'transparent',
28661
- borderColor: isActive ? theme.colors.primary[4] : theme.backgrounds.border,
28662
- },
28663
- (disabled || readOnly) && styles.disabled,
28664
- ], [styles.toolButton, theme, disabled, readOnly]);
28665
- const renderToolButton = useCallback((tool, icon, onPress, isActive = false) => (jsx(TouchableOpacity, { onPress: onPress, disabled: disabled || readOnly, style: getToolButtonStyle(isActive), children: jsx(Icon, { name: icon, size: 16, color: isActive ? theme.colors.primary[5] : theme.text.secondary }) }, tool)), [theme, disabled, readOnly, getToolButtonStyle]);
28666
- const renderToolSeparator = useCallback((index) => (jsx(View, { style: styles.toolSeparator }, `separator-${index}`)), [styles.toolSeparator]);
28667
- const renderToolbar = useCallback(() => {
28668
- if (!(toolbar === null || toolbar === void 0 ? void 0 : toolbar.enabled))
28669
- return null;
28670
- const tools = toolbar.tools || DEFAULT_TOOLBAR_TOOLS;
28671
- return (jsx(View, { style: styles.toolbar, children: jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.toolbarContent, children: tools.map((tool, index) => {
28672
- if (tool === 'separator') {
28673
- return renderToolSeparator(index);
28674
- }
28675
- switch (tool) {
28676
- case 'bold':
28677
- return renderToolButton('bold', 'bold', () => toggleFormat('bold'), !!activeFormats.bold);
28678
- case 'italic':
28679
- return renderToolButton('italic', 'italic', () => toggleFormat('italic'), !!activeFormats.italic);
28680
- case 'underline':
28681
- return renderToolButton('underline', 'underline', () => toggleFormat('underline'), !!activeFormats.underline);
28682
- case 'strikethrough':
28683
- return renderToolButton('strikethrough', 'strikethrough', () => toggleFormat('strikethrough'), !!activeFormats.strikethrough);
28684
- case 'heading':
28685
- return renderToolButton('heading', 'heading', () => applyFormat({ heading: activeFormats.heading ? null : 2 }), !!activeFormats.heading);
28686
- case 'align':
28687
- return renderToolButton('align', 'alignLeft', // Default to left align icon, could be dynamic based on current align
28688
- () => setAlignment(activeFormats.align === 'left' ? 'center' : 'left'), !!activeFormats.align);
28689
- case 'list':
28690
- return renderToolButton('list', 'listUnordered', // Default to unordered list icon, could be dynamic
28691
- () => setList(activeFormats.list === 'unordered' ? 'ordered' : 'unordered'), !!activeFormats.list);
28692
- case 'link':
28693
- return renderToolButton('link', 'link', insertLink, !!activeFormats.link);
28694
- case 'image':
28695
- return renderToolButton('image', 'image', () => { }, // TODO: Implement image insertion
28696
- false);
28697
- case 'code':
28698
- return renderToolButton('code', 'code', () => toggleFormat('code'), !!activeFormats.code);
28699
- case 'quote':
28700
- return renderToolButton('quote', 'quote', () => toggleFormat('quote'), !!activeFormats.quote);
28701
- case 'color':
28702
- return renderToolButton('color', 'color', () => { }, // TODO: Implement color picker
28703
- !!activeFormats.color);
28704
- default:
28705
- return null;
28706
- }
28707
- }) }) }));
28708
- }, [toolbar, theme, activeFormats, renderToolButton, renderToolSeparator, toggleFormat, insertLink, styles.toolbar, styles.toolbarContent]);
28709
- const renderEditor = useCallback(() => (jsx(View, { style: [
28710
- styles.editorContainer,
28711
- {
28712
- borderColor: isFocused ? theme.colors.primary[5] : theme.backgrounds.border,
28713
- minHeight,
28714
- maxHeight,
28715
- },
28716
- error && { borderColor: theme.colors.error[5] },
28717
- (disabled || readOnly) && styles.disabled,
28718
- ], children: jsx(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: [
28719
- styles.textInput,
28720
- Platform.OS === 'web' ? { outlineWidth: 0 } : null,
28721
- {
28722
- color: theme.text.primary,
28723
- fontSize: activeFormats.fontSize || 16,
28724
- fontFamily: activeFormats.fontFamily || theme.fontFamily,
28725
- fontWeight: activeFormats.bold ? 'bold' : 'normal',
28726
- fontStyle: activeFormats.italic ? 'italic' : 'normal',
28727
- textDecorationLine: activeFormats.underline ? 'underline' : 'none',
28728
- textAlign: activeFormats.align || 'left',
28729
- },
28730
- ], ...props }) })), [
28731
- content.text,
28732
- handleContentChange,
28733
- handleSelectionChange,
28734
- handleFocus,
28735
- handleBlur,
28736
- placeholder,
28737
- disabled,
28738
- readOnly,
28739
- spellCheck,
28740
- maxLength,
28741
- isFocused,
28742
- theme,
28743
- minHeight,
28744
- maxHeight,
28745
- error,
28746
- activeFormats,
28747
- props,
28748
- styles.editorContainer,
28749
- styles.disabled,
28750
- styles.textInput,
28751
- ]);
28752
- return (jsxs(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 && (jsxs(Text$1, { style: [styles.characterCount, { color: theme.text.secondary }], children: [content.text.length, "/", maxLength] })), error && (jsx(Text$1, { style: [styles.errorText, { color: theme.colors.error[5] }], children: error })), helperText && !error && (jsx(Text$1, { style: [styles.helperText, { color: theme.text.secondary }], children: helperText }))] }));
28753
- });
28754
- RichTextEditor.displayName = 'RichTextEditor';
28755
-
28756
28587
  function RatingBase(rawProps, ref) {
28757
28588
  const { disclaimerProps: disclaimerData, otherProps: propsAfterDisclaimer } = extractDisclaimerProps(rawProps);
28758
28589
  const { spacingProps, otherProps: props } = extractSpacingProps(propsAfterDisclaimer);
@@ -29504,7 +29335,7 @@ function useMenuContext() {
29504
29335
  return context;
29505
29336
  }
29506
29337
  function MenuBase(props, ref) {
29507
- 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 = Platform.OS === 'web' ? 'fixed' : 'portal', ...spacingProps } = props;
29338
+ 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 = Platform.OS === 'web' ? 'fixed' : 'portal', ...spacingProps } = props;
29508
29339
  const [internalOpened, setInternalOpened] = useState(false);
29509
29340
  // Derive menu dropdown items from children each render for reactivity
29510
29341
  const { menuItems, menuDropdownProps } = useMemo(() => {
@@ -29579,11 +29410,11 @@ function MenuBase(props, ref) {
29579
29410
  const listGroupStyle = {
29580
29411
  ...styles.dropdown,
29581
29412
  ...(dropdownSpacingStyles || {}),
29582
- maxHeight,
29413
+ maxHeight: maxH,
29583
29414
  width: resolvedWidth,
29584
29415
  };
29585
- return (jsx(MenuContext.Provider, { value: menuContextValueOpened, children: jsx(ListGroup, { variant: "default", size: "sm", style: listGroupStyle, children: scrollable ? (jsx(ScrollView, { showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "handled", style: { maxHeight }, children: jsx(ListGroupBody, { children: menuItems }) })) : (jsx(View, { style: { maxHeight, overflow: 'hidden' }, children: jsx(ListGroupBody, { children: menuItems }) })) }) }));
29586
- }, [menuItems, menuDropdownProps, styles.dropdown, dropdownSpacingStyles, maxHeight, menuContextValueOpened]);
29416
+ return (jsx(MenuContext.Provider, { value: menuContextValueOpened, children: jsx(ListGroup, { variant: "default", size: "sm", style: listGroupStyle, children: scrollable ? (jsx(ScrollView, { showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "handled", style: { maxHeight: maxH }, children: jsx(ListGroupBody, { children: menuItems }) })) : (jsx(View, { style: { maxHeight: maxH, overflow: 'hidden' }, children: jsx(ListGroupBody, { children: menuItems }) })) }) }));
29417
+ }, [menuItems, menuDropdownProps, styles.dropdown, dropdownSpacingStyles, maxH, menuContextValueOpened]);
29587
29418
  const handleOpen = useCallback(async (opts) => {
29588
29419
  var _a, _b, _c, _d, _e, _f;
29589
29420
  // Use ref to avoid stale isOpened value after async close from backdrop click
@@ -29615,7 +29446,7 @@ function MenuBase(props, ref) {
29615
29446
  }
29616
29447
  // Calculate base overlay size
29617
29448
  const estimatedMenuHeight = 120; // Estimate for typical menu with 3-4 items
29618
- const resolvedWidth = width === 'target' ? triggerRect.width : (typeof width === 'number' ? width : (width === 'auto' ? 200 : 200));
29449
+ const resolvedWidth = w === 'target' ? triggerRect.width : (typeof w === 'number' ? w : (w === 'auto' ? 200 : 200));
29619
29450
  const overlaySize = {
29620
29451
  width: resolvedWidth,
29621
29452
  height: estimatedMenuHeight,
@@ -29683,7 +29514,7 @@ function MenuBase(props, ref) {
29683
29514
  catch (error) {
29684
29515
  console.warn('Failed to open menu:', error);
29685
29516
  }
29686
- }, [disabled, width, position, offset, strategy, closeOnClickOutside, closeOnEscape, onOpen, menuItems, trigger, buildMenuDropdown, onClose]);
29517
+ }, [disabled, w, position, offset, strategy, closeOnClickOutside, closeOnEscape, onOpen, menuItems, trigger, buildMenuDropdown, onClose]);
29687
29518
  // When menu content changes while open, update overlay content in place
29688
29519
  useEffect(() => {
29689
29520
  var _a;
@@ -29695,14 +29526,14 @@ function MenuBase(props, ref) {
29695
29526
  return; // no structural change
29696
29527
  lastSignatureRef.current = menuItemsSignature;
29697
29528
  const currentId = overlayIdRef.current;
29698
- const resolvedWidth = (_a = lastResolvedWidthRef.current) !== null && _a !== void 0 ? _a : (typeof width === 'number' ? width : undefined);
29529
+ const resolvedWidth = (_a = lastResolvedWidthRef.current) !== null && _a !== void 0 ? _a : (typeof w === 'number' ? w : undefined);
29699
29530
  const menuDropdown = buildMenuDropdown(resolvedWidth);
29700
29531
  if (!menuDropdown)
29701
29532
  return;
29702
29533
  updateOverlay(currentId, {
29703
29534
  content: menuDropdown,
29704
29535
  });
29705
- }, [menuItemsSignature, menuItems, updateOverlay, width, buildMenuDropdown]);
29536
+ }, [menuItemsSignature, menuItems, updateOverlay, w, buildMenuDropdown]);
29706
29537
  const handleToggle = useCallback(() => {
29707
29538
  if (isOpenedRef.current) {
29708
29539
  handleClose();
@@ -31634,7 +31465,7 @@ const DEFAULT_ARROW_SIZE = 7;
31634
31465
  const PopoverBase = (props, ref) => {
31635
31466
  var _a;
31636
31467
  const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, trigger = 'click', disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
31637
- 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;
31468
+ 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;
31638
31469
  const theme = useTheme();
31639
31470
  const { spacingProps } = extractSpacingProps(rest);
31640
31471
  const spacingStyles = getSpacingStyles(spacingProps);
@@ -31851,29 +31682,29 @@ const PopoverBase = (props, ref) => {
31851
31682
  : undefined;
31852
31683
  const widthOverride = (() => {
31853
31684
  var _a, _b;
31854
- if (typeof width === 'number')
31855
- return width;
31856
- if (width === 'target') {
31685
+ if (typeof w === 'number')
31686
+ return w;
31687
+ if (w === 'target') {
31857
31688
  return (_b = (_a = anchorMeasurementsRef.current) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : computedFinalWidth;
31858
31689
  }
31859
31690
  return computedFinalWidth;
31860
31691
  })();
31861
31692
  const sizeStyles = {};
31862
- if (typeof minWidth === 'number')
31863
- sizeStyles.minWidth = minWidth;
31864
- if (typeof minHeight === 'number')
31865
- sizeStyles.minHeight = minHeight;
31866
- if (typeof maxWidth === 'number')
31867
- sizeStyles.maxWidth = maxWidth;
31693
+ if (typeof minW === 'number')
31694
+ sizeStyles.minWidth = minW;
31695
+ if (typeof minH === 'number')
31696
+ sizeStyles.minHeight = minH;
31697
+ if (typeof maxW === 'number')
31698
+ sizeStyles.maxWidth = maxW;
31868
31699
  const computedMaxHeight = positioningResult.maxHeight;
31869
31700
  const resolvedMaxHeight = (() => {
31870
- if (typeof maxHeight === 'number') {
31701
+ if (typeof maxH === 'number') {
31871
31702
  if (typeof computedMaxHeight === 'number') {
31872
- return Math.min(maxHeight, computedMaxHeight);
31703
+ return Math.min(maxH, computedMaxHeight);
31873
31704
  }
31874
- return maxHeight;
31705
+ return maxH;
31875
31706
  }
31876
- return typeof computedMaxHeight === 'number' ? computedMaxHeight : maxHeight;
31707
+ return typeof computedMaxHeight === 'number' ? computedMaxHeight : maxH;
31877
31708
  })();
31878
31709
  if (typeof resolvedMaxHeight === 'number')
31879
31710
  sizeStyles.maxHeight = resolvedMaxHeight;
@@ -31897,7 +31728,7 @@ const PopoverBase = (props, ref) => {
31897
31728
  zIndex,
31898
31729
  });
31899
31730
  onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(positioningResult.placement);
31900
- }, [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]);
31731
+ }, [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]);
31901
31732
  useEffect(() => {
31902
31733
  return () => {
31903
31734
  hideOverlay();
@@ -32185,7 +32016,7 @@ const getSpacingValue = (spacing, theme) => {
32185
32016
  // Table Cell Components
32186
32017
  const TableTh = (allProps) => {
32187
32018
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32188
- const { children, w, align = 'left', minWidth, maxWidth, flex, widthStrategy = 'auto', style } = otherProps;
32019
+ const { children, w, align = 'left', minW, maxW, flex, widthStrategy = 'auto', style } = otherProps;
32189
32020
  const theme = useTheme();
32190
32021
  const { isRTL } = useDirection();
32191
32022
  // Swap alignment in RTL
@@ -32216,10 +32047,10 @@ const TableTh = (allProps) => {
32216
32047
  else if (widthStrategy === 'auto') {
32217
32048
  widthStyle.flex = 1;
32218
32049
  }
32219
- if (minWidth)
32220
- widthStyle.minWidth = minWidth;
32221
- if (maxWidth)
32222
- widthStyle.maxWidth = maxWidth;
32050
+ if (minW)
32051
+ widthStyle.minWidth = minW;
32052
+ if (maxW)
32053
+ widthStyle.maxWidth = maxW;
32223
32054
  return widthStyle;
32224
32055
  };
32225
32056
  const cellStyle = [
@@ -32240,7 +32071,7 @@ const TableTh = (allProps) => {
32240
32071
  };
32241
32072
  const TableTd = (allProps) => {
32242
32073
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32243
- const { children, w, align = 'left', minWidth, maxWidth, flex, widthStrategy = 'auto', style } = otherProps;
32074
+ const { children, w, align = 'left', minW, maxW, flex, widthStrategy = 'auto', style } = otherProps;
32244
32075
  const theme = useTheme();
32245
32076
  const { isRTL } = useDirection();
32246
32077
  // Swap alignment in RTL
@@ -32271,10 +32102,10 @@ const TableTd = (allProps) => {
32271
32102
  else if (widthStrategy === 'auto') {
32272
32103
  widthStyle.flex = 1;
32273
32104
  }
32274
- if (minWidth)
32275
- widthStyle.minWidth = minWidth;
32276
- if (maxWidth)
32277
- widthStyle.maxWidth = maxWidth;
32105
+ if (minW)
32106
+ widthStyle.minWidth = minW;
32107
+ if (maxW)
32108
+ widthStyle.maxWidth = maxW;
32278
32109
  return widthStyle;
32279
32110
  };
32280
32111
  const cellStyle = [
@@ -32353,16 +32184,16 @@ const TableCaption = (allProps) => {
32353
32184
  // Scroll Container Component
32354
32185
  const TableScrollContainer = (allProps) => {
32355
32186
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
32356
- const { children, minWidth = 500, maxHeight, type = 'native', style } = otherProps;
32187
+ const { children, minW = 500, maxH, type = 'native', style } = otherProps;
32357
32188
  const containerStyle = [
32358
32189
  {
32359
32190
  width: '100%',
32360
- maxHeight
32191
+ maxHeight: maxH
32361
32192
  },
32362
32193
  getSpacingStyles(spacingProps),
32363
32194
  style
32364
32195
  ];
32365
- const scrollViewStyle = minWidth ? { minWidth } : undefined;
32196
+ const scrollViewStyle = minW ? { minWidth: minW } : undefined;
32366
32197
  return (jsx(View, { style: containerStyle, children: jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: Platform.OS === 'web', contentContainerStyle: scrollViewStyle, children: jsx(ScrollView, { style: { flex: 1 }, showsVerticalScrollIndicator: Platform.OS === 'web', children: children }) }) }));
32367
32198
  };
32368
32199
  // Main Table Component
@@ -33300,7 +33131,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33300
33131
  alignItems: 'center',
33301
33132
  marginBottom: DESIGN_TOKENS.spacing.md,
33302
33133
  paddingHorizontal: DESIGN_TOKENS.spacing.xs
33303
- }, children: [jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxs(Flex, { gap: 8, children: [jsxs(Text, { variant: "small", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 320, trapFocus: true, children: [jsx(Popover.Target, { children: jsxs(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsx(View, { style: {
33134
+ }, children: [jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxs(Flex, { gap: 8, children: [jsxs(Text, { variant: "small", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, w: 320, trapFocus: true, children: [jsx(Popover.Target, { children: jsxs(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsx(View, { style: {
33304
33135
  width: 6,
33305
33136
  height: 6,
33306
33137
  borderRadius: 3,
@@ -33330,7 +33161,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33330
33161
  }) })), jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: columns.filter(c => c.filterable).map(column => {
33331
33162
  const currentFilter = getColumnFilter(column.key);
33332
33163
  return (jsx(View, { children: renderFilterControl(column) }, `${column.key}-${(currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.value) || 'no-filter'}`));
33333
- }) })] }))] }) })] })), onEditModeChange && (jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 280, trapFocus: true, children: [jsx(Popover.Target, { children: jsx(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsx(Popover.Dropdown, { children: jsxs(View, { style: { padding: 8, maxHeight: 300, width: 260 }, children: [jsx(ComponentWithDisclaimer, { disclaimer: "Selected view determines the layout style", disclaimerProps: { colorVariant: 'muted', size: 'sm' }, children: jsxs(Row, { children: [jsx(Button, { size: "xs", title: "Deselect All", variant: hiddenColumns.length === columns.length ? 'filled' : 'outline', onPress: () => setHiddenColumns(columns.map(c => c.key)), style: { marginBottom: 8 } }), jsx(Button, { size: "xs", title: "Select All", variant: hiddenColumns.length === 0 ? 'filled' : 'outline', onPress: () => setHiddenColumns([]), style: { marginBottom: 8 } })] }) }), jsx(ScrollView, { style: { maxHeight: 200 }, children: columns.map(col => (jsx(Checkbox, { label: tempHeaderEdits[col.key] || col.header, onChange: () => {
33164
+ }) })] }))] }) })] })), onEditModeChange && (jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, w: 280, trapFocus: true, children: [jsx(Popover.Target, { children: jsx(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsx(Popover.Dropdown, { children: jsxs(View, { style: { padding: 8, maxHeight: 300, width: 260 }, children: [jsx(ComponentWithDisclaimer, { disclaimer: "Selected view determines the layout style", disclaimerProps: { colorVariant: 'muted', size: 'sm' }, children: jsxs(Row, { children: [jsx(Button, { size: "xs", title: "Deselect All", variant: hiddenColumns.length === columns.length ? 'filled' : 'outline', onPress: () => setHiddenColumns(columns.map(c => c.key)), style: { marginBottom: 8 } }), jsx(Button, { size: "xs", title: "Select All", variant: hiddenColumns.length === 0 ? 'filled' : 'outline', onPress: () => setHiddenColumns([]), style: { marginBottom: 8 } })] }) }), jsx(ScrollView, { style: { maxHeight: 200 }, children: columns.map(col => (jsx(Checkbox, { label: tempHeaderEdits[col.key] || col.header, onChange: () => {
33334
33165
  if (hiddenColumns.includes(col.key)) {
33335
33166
  setHiddenColumns(prev => prev.filter(h => h !== col.key));
33336
33167
  }
@@ -33704,9 +33535,9 @@ const resolveTokenColor = (token, theme) => {
33704
33535
  return token; // assume raw color string
33705
33536
  };
33706
33537
  // Item
33707
- const TimelineItem = forwardRef(({ children, title, bullet, colorVariant, lineVariant = 'solid', color, active, itemIndex = 0, isLastItem = false, itemAlign, ...rest }, ref) => {
33538
+ const TimelineItem = forwardRef(({ children, title, timestamp, bullet, colorVariant, lineVariant = 'solid', color, titleColor, descriptionColor, timestampColor, active, itemIndex = 0, isLastItem = false, itemAlign, ...rest }, ref) => {
33708
33539
  const theme = useTheme();
33709
- const { active: timelineActive, color: timelineColor, lineWidth, bulletSize: contextBulletSize, align, reverseActive, size, centerMode, metrics, } = useTimelineContext();
33540
+ const { active: timelineActive, color: timelineColor, lineWidth, bulletSize: contextBulletSize, align, reverseActive, size, centerMode, metrics, titleColor: timelineTitleColor, descriptionColor: timelineDescriptionColor, timestampColor: timelineTimestampColor, } = useTimelineContext();
33710
33541
  const sizeConfig = metrics;
33711
33542
  const finalBulletSize = contextBulletSize || sizeConfig.bulletSize;
33712
33543
  const showAllColored = timelineActive === undefined;
@@ -33721,6 +33552,9 @@ const TimelineItem = forwardRef(({ children, title, bullet, colorVariant, lineVa
33721
33552
  const resolvedItemColor = color
33722
33553
  ? color
33723
33554
  : (colorVariant ? resolveTokenColor(colorVariant, theme) : timelineColor);
33555
+ const resolvedTitleColor = titleColor !== null && titleColor !== void 0 ? titleColor : timelineTitleColor;
33556
+ const resolvedDescriptionColor = descriptionColor !== null && descriptionColor !== void 0 ? descriptionColor : timelineDescriptionColor;
33557
+ const resolvedTimestampColor = timestampColor !== null && timestampColor !== void 0 ? timestampColor : timelineTimestampColor;
33724
33558
  // Active logic
33725
33559
  const isActive = showAllColored
33726
33560
  ? true
@@ -33806,10 +33640,16 @@ const TimelineItem = forwardRef(({ children, title, bullet, colorVariant, lineVa
33806
33640
  const getTitleStyle = () => ({
33807
33641
  fontSize: sizeConfig.fontSize,
33808
33642
  fontWeight: '600',
33809
- color: theme.text.primary,
33643
+ color: resolvedTitleColor !== null && resolvedTitleColor !== void 0 ? resolvedTitleColor : theme.text.primary,
33810
33644
  marginBottom: title && children ? 4 : 0,
33811
33645
  textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33812
33646
  });
33647
+ const getTimestampStyle = () => ({
33648
+ fontSize: Math.max(10, Math.round(sizeConfig.fontSize * 0.8)),
33649
+ color: resolvedTimestampColor !== null && resolvedTimestampColor !== void 0 ? resolvedTimestampColor : theme.text.secondary,
33650
+ marginBottom: (title || children) ? 4 : 0,
33651
+ textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33652
+ });
33813
33653
  const getItemWrapperStyle = () => {
33814
33654
  if (centerMode) {
33815
33655
  return {
@@ -33825,36 +33665,53 @@ const TimelineItem = forwardRef(({ children, title, bullet, colorVariant, lineVa
33825
33665
  alignItems: 'flex-start',
33826
33666
  };
33827
33667
  };
33668
+ const applyTextStyle = (nodes, styleOverride) => {
33669
+ if (!styleOverride)
33670
+ return nodes;
33671
+ return React__default.Children.map(nodes, (child) => {
33672
+ var _a;
33673
+ if (typeof child === 'string' || typeof child === 'number') {
33674
+ return jsx(Text$1, { style: styleOverride, children: child });
33675
+ }
33676
+ if (!React__default.isValidElement(child))
33677
+ return child;
33678
+ const props = child.props || {};
33679
+ const isTextLike = ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === 'Text' || child.type === Text$1 || typeof props.children === 'string';
33680
+ if (isTextLike) {
33681
+ const mergedStyle = Array.isArray(props.style)
33682
+ ? [...props.style, styleOverride]
33683
+ : [props.style, styleOverride];
33684
+ return React__default.cloneElement(child, { style: mergedStyle });
33685
+ }
33686
+ if (props.children) {
33687
+ return React__default.cloneElement(child, { children: applyTextStyle(props.children, styleOverride) });
33688
+ }
33689
+ return child;
33690
+ });
33691
+ };
33828
33692
  if (centerMode) {
33829
33693
  // Three column layout: left content | bullet/line | right content
33830
33694
  const leftContent = effectiveAlign === 'left' && (title || children);
33831
33695
  const rightContent = effectiveAlign === 'right' && (title || children);
33832
33696
  // Helper to clone Text children with alignment
33833
33697
  const alignChildText = (nodes, side) => {
33834
- return React__default.Children.map(nodes, (child) => {
33835
- var _a;
33836
- if (!React__default.isValidElement(child))
33837
- return child;
33838
- const props = child.props || {};
33839
- const isTextLike = ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === 'Text' || (typeof props.children === 'string');
33840
- if (isTextLike) {
33841
- const mergedStyle = Array.isArray(props.style)
33842
- ? [...props.style, { textAlign: side }]
33843
- : [props.style, { textAlign: side }];
33844
- return React__default.cloneElement(child, { style: mergedStyle });
33845
- }
33846
- if (props.children) {
33847
- return React__default.cloneElement(child, { children: alignChildText(props.children, side) });
33848
- }
33849
- return child;
33850
- });
33698
+ const styleOverride = {
33699
+ textAlign: side,
33700
+ ...(resolvedDescriptionColor ? { color: resolvedDescriptionColor } : {}),
33701
+ };
33702
+ return applyTextStyle(nodes, styleOverride);
33851
33703
  };
33852
- return (jsxs(View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [jsx(View, { style: { flex: 1, paddingRight: sizeConfig.spacing, alignItems: 'flex-end' }, children: leftContent && (jsxs(View, { style: { width: '100%', alignItems: 'flex-end' }, children: [title && jsx(Text$1, { style: [getTitleStyle(), { textAlign: 'right' }], children: title }), alignChildText(children, 'right')] })) }), jsxs(View, { style: { width: finalBulletSize, alignItems: 'center', position: 'relative' }, children: [getLine(), jsx(View, { style: getBulletStyle(), children: bullet })] }), jsx(View, { style: { flex: 1, paddingLeft: sizeConfig.spacing, alignItems: 'flex-start' }, children: rightContent && (jsxs(View, { style: { width: '100%', alignItems: 'flex-start' }, children: [title && jsx(Text$1, { style: [getTitleStyle(), { textAlign: 'left' }], children: title }), alignChildText(children, 'left')] })) })] }));
33704
+ return (jsxs(View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [jsx(View, { style: { flex: 1, paddingRight: sizeConfig.spacing, alignItems: 'flex-end' }, children: leftContent && (jsxs(View, { style: { width: '100%', alignItems: 'flex-end' }, children: [timestamp && (jsx(Text$1, { style: [getTimestampStyle(), { textAlign: 'right' }], children: timestamp })), title && jsx(Text$1, { style: [getTitleStyle(), { textAlign: 'right' }], children: title }), alignChildText(children, 'right')] })) }), jsxs(View, { style: { width: finalBulletSize, alignItems: 'center', position: 'relative' }, children: [getLine(), jsx(View, { style: getBulletStyle(), children: bullet })] }), jsx(View, { style: { flex: 1, paddingLeft: sizeConfig.spacing, alignItems: 'flex-start' }, children: rightContent && (jsxs(View, { style: { width: '100%', alignItems: 'flex-start' }, children: [timestamp && (jsx(Text$1, { style: [getTimestampStyle(), { textAlign: 'left' }], children: timestamp })), title && jsx(Text$1, { style: [getTitleStyle(), { textAlign: 'left' }], children: title }), alignChildText(children, 'left')] })) })] }));
33853
33705
  }
33854
- return (jsxs(View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [getLine(), jsx(View, { style: getBulletStyle(), children: bullet }), (title || children) && (jsxs(View, { style: getContentStyle(), children: [title && jsx(Text$1, { style: getTitleStyle(), children: title }), children] }))] }));
33706
+ return (jsxs(View, { ref: ref, style: getItemWrapperStyle(), ...rest, children: [getLine(), jsx(View, { style: getBulletStyle(), children: bullet }), (title || children) && (jsxs(View, { style: getContentStyle(), children: [timestamp && jsx(Text$1, { style: getTimestampStyle(), children: timestamp }), title && jsx(Text$1, { style: getTitleStyle(), children: title }), resolvedDescriptionColor
33707
+ ? applyTextStyle(children, {
33708
+ color: resolvedDescriptionColor,
33709
+ textAlign: effectiveAlign === 'right' ? 'right' : 'left',
33710
+ })
33711
+ : children] }))] }));
33855
33712
  });
33856
33713
  // Root Timeline
33857
- const Timeline = forwardRef(({ children, active, color, colorVariant, lineWidth, bulletSize, align = 'left', reverseActive = false, size = 'md', centerMode = false, ...rest }, ref) => {
33714
+ const Timeline = forwardRef(({ children, active, color, colorVariant, titleColor, descriptionColor, timestampColor, lineWidth, bulletSize, align = 'left', reverseActive = false, size = 'md', centerMode = false, ...rest }, ref) => {
33858
33715
  const theme = useTheme();
33859
33716
  const clampedSize = clampComponentSize(size, TIMELINE_ALLOWED_SIZES);
33860
33717
  const baseMetrics = resolveTimelineMetrics(clampedSize);
@@ -33876,6 +33733,9 @@ const Timeline = forwardRef(({ children, active, color, colorVariant, lineWidth,
33876
33733
  size: clampedSize,
33877
33734
  metrics,
33878
33735
  centerMode,
33736
+ titleColor,
33737
+ descriptionColor,
33738
+ timestampColor,
33879
33739
  };
33880
33740
  const items = [];
33881
33741
  React__default.Children.forEach(children, (child, index) => {
@@ -34593,7 +34453,7 @@ const Notice = factory(NoticeBase);
34593
34453
  Notice.displayName = 'Notice';
34594
34454
 
34595
34455
  function SkeletonBase(props, ref) {
34596
- const { shape = 'rectangle', width, height, size = 'md', radius, animate = true, animationDuration = 1500, colors, style, testID, ...rest } = props;
34456
+ const { shape = 'rectangle', w, h, size = 'md', radius, animate = true, animationDuration = 1500, colors, style, testID, ...rest } = props;
34597
34457
  const { spacingProps, otherProps } = extractSpacingProps(rest);
34598
34458
  const spacingStyles = getSpacingStyles(spacingProps);
34599
34459
  const theme = useTheme();
@@ -34614,36 +34474,36 @@ function SkeletonBase(props, ref) {
34614
34474
  switch (shape) {
34615
34475
  case 'text':
34616
34476
  return {
34617
- width: width || '100%',
34618
- height: height || getSpacing('md')
34477
+ width: w || '100%',
34478
+ height: h || getSpacing('md')
34619
34479
  };
34620
34480
  case 'chip':
34621
34481
  return {
34622
- width: width || (sizeValue * 3),
34623
- height: height || sizeValue
34482
+ width: w || (sizeValue * 3),
34483
+ height: h || sizeValue
34624
34484
  };
34625
34485
  case 'avatar':
34626
34486
  case 'circle':
34627
34487
  return {
34628
- width: width || sizeValue,
34629
- height: height || sizeValue
34488
+ width: w || sizeValue,
34489
+ height: h || sizeValue
34630
34490
  };
34631
34491
  case 'button':
34632
34492
  return {
34633
- width: width || (sizeValue * 4),
34634
- height: height || sizeValue
34493
+ width: w || (sizeValue * 4),
34494
+ height: h || sizeValue
34635
34495
  };
34636
34496
  case 'card':
34637
34497
  return {
34638
- width: width || '100%',
34639
- height: height || (sizeValue * 6)
34498
+ width: w || '100%',
34499
+ height: h || (sizeValue * 6)
34640
34500
  };
34641
34501
  case 'rectangle':
34642
34502
  case 'rounded':
34643
34503
  default:
34644
34504
  return {
34645
- width: width || '100%',
34646
- height: height || sizeValue
34505
+ width: w || '100%',
34506
+ height: h || sizeValue
34647
34507
  };
34648
34508
  }
34649
34509
  };
@@ -35711,7 +35571,7 @@ const styles$6 = StyleSheet.create({
35711
35571
  },
35712
35572
  });
35713
35573
 
35714
- const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCount = 20, }) => {
35574
+ const WaveformSkeleton = ({ w = 300, h = 60, fullWidth = false, barsCount = 20, }) => {
35715
35575
  const theme = useTheme();
35716
35576
  const styles = StyleSheet.create({
35717
35577
  animatedBar: {
@@ -35727,18 +35587,18 @@ const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCou
35727
35587
  backgroundColor: theme.colors.gray[1],
35728
35588
  borderRadius: 4,
35729
35589
  flexDirection: 'row',
35730
- height,
35590
+ height: h,
35731
35591
  justifyContent: 'space-between',
35732
35592
  paddingHorizontal: 4,
35733
- width: fullWidth ? '100%' : width,
35593
+ width: fullWidth ? '100%' : w,
35734
35594
  },
35735
35595
  });
35736
35596
  // Generate random heights for skeleton bars
35737
35597
  const barHeights = Array.from({ length: barsCount }, () => Math.random() * 0.6 + 0.2 // Heights between 20% and 80% of container
35738
35598
  );
35739
- const barWidth = fullWidth ? 'auto' : Math.max(1, (width - 40) / barsCount - 2);
35599
+ const barWidth = fullWidth ? 'auto' : Math.max(1, (w - 40) / barsCount - 2);
35740
35600
  return (jsx(View, { style: styles.container, children: barHeights.map((heightRatio, index) => {
35741
- const barHeight = height * heightRatio;
35601
+ const barHeight = h * heightRatio;
35742
35602
  const isAnimated = index % 3 === 0; // Animate every 3rd bar for shimmer effect
35743
35603
  return (jsx(View, { style: [
35744
35604
  styles.bar,
@@ -35753,7 +35613,7 @@ const WaveformSkeleton = ({ width = 300, height = 60, fullWidth = false, barsCou
35753
35613
  }) }));
35754
35614
  };
35755
35615
 
35756
- const Waveform = React__default.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,
35616
+ const Waveform = React__default.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,
35757
35617
  // New features
35758
35618
  loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel = 1, zoomCenter = 0.5, onZoomChange, enableAnimations = true, showRMS = false, rmsData, markers = [], enablePerformanceMonitoring = false, onPerformanceMetrics, ...restProps }) => {
35759
35619
  const theme = useTheme();
@@ -35840,12 +35700,12 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35840
35700
  targetBars = maxVisibleBars || peaks.length;
35841
35701
  }
35842
35702
  else {
35843
- // For fixed width, calculate how many bars fit
35844
- const maxBars = Math.floor(width / totalBarSpace);
35703
+ // For fixed w, calculate how many bars fit
35704
+ const maxBars = Math.floor(w / totalBarSpace);
35845
35705
  targetBars = maxVisibleBars ? Math.min(maxBars, maxVisibleBars) : maxBars;
35846
35706
  }
35847
35707
  if (targetBars <= 0) {
35848
- console.warn('Waveform: Not enough width to render any bars');
35708
+ console.warn('Waveform: Not enough w to render any bars');
35849
35709
  return [];
35850
35710
  }
35851
35711
  // If we have fewer peaks than target bars, return all peaks
@@ -35868,7 +35728,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35868
35728
  downsampled.push(maxValue);
35869
35729
  }
35870
35730
  return downsampled;
35871
- }, [peaks, width, barWidth, barGap, fullWidth, maxVisibleBars]);
35731
+ }, [peaks, w, barWidth, barGap, fullWidth, maxVisibleBars]);
35872
35732
  // Normalize peaks if requested
35873
35733
  const normalizedPeaks = useMemo(() => {
35874
35734
  if (!normalize || processedPeaks.length === 0) {
@@ -35891,16 +35751,16 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35891
35751
  if (fullWidth) {
35892
35752
  return {
35893
35753
  width: '100%',
35894
- height: height,
35895
- viewBox: `0 0 ${actualWaveformWidth} ${height}`,
35754
+ height: h,
35755
+ viewBox: `0 0 ${actualWaveformWidth} ${h}`,
35896
35756
  preserveAspectRatio: 'none'
35897
35757
  };
35898
35758
  }
35899
35759
  return {
35900
- width: width,
35901
- height: height
35760
+ width: w,
35761
+ height: h
35902
35762
  };
35903
- }, [fullWidth, actualWaveformWidth, height, width]);
35763
+ }, [fullWidth, actualWaveformWidth, h, w]);
35904
35764
  const handleLayout = useCallback((event) => {
35905
35765
  const { width: containerWidth, height: containerHeight } = event.nativeEvent.layout;
35906
35766
  setContainerDimensions({ width: containerWidth, height: containerHeight });
@@ -35915,7 +35775,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35915
35775
  }
35916
35776
  else {
35917
35777
  // Fallback if container hasn't been measured yet
35918
- position = locationX / (width || 300);
35778
+ position = locationX / (w || 300);
35919
35779
  }
35920
35780
  }
35921
35781
  else {
@@ -35923,7 +35783,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
35923
35783
  position = Math.min(locationX, actualWaveformWidth) / actualWaveformWidth;
35924
35784
  }
35925
35785
  return Math.max(0, Math.min(1, position));
35926
- }, [fullWidth, containerDimensions.width, width, actualWaveformWidth]);
35786
+ }, [fullWidth, containerDimensions.width, w, actualWaveformWidth]);
35927
35787
  const handleResponderGrant = useCallback((event) => {
35928
35788
  var _a, _b, _c;
35929
35789
  if (!interactive)
@@ -36010,8 +35870,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36010
35870
  const renderBars = () => {
36011
35871
  return normalizedPeaks.map((peak, index) => {
36012
35872
  const x = index * (barWidth + barGap);
36013
- const barHeight = Math.max(minBarHeight, Math.abs(peak) * height * 0.8);
36014
- const y = (height - barHeight) / 2;
35873
+ const barHeight = Math.max(minBarHeight, Math.abs(peak) * h * 0.8);
35874
+ const y = (h - barHeight) / 2;
36015
35875
  const isProgress = x < progressX;
36016
35876
  const fillColor = isProgress ? actualProgressColor : waveformColor;
36017
35877
  return (jsx(Rect, { x: x, y: y, width: barWidth, height: barHeight, fill: fillColor, rx: variant === 'rounded' ? barWidth / 2 : 0 }, index));
@@ -36025,7 +35885,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36025
35885
  const stepX = actualWaveformWidth / (normalizedPeaks.length - 1);
36026
35886
  normalizedPeaks.forEach((peak, index) => {
36027
35887
  const x = index * stepX;
36028
- const y = height / 2 + (peak * height * 0.4);
35888
+ const y = h / 2 + (peak * h * 0.4);
36029
35889
  const lineCommand = index === 0 ? `M ${x} ${y}` : ` L ${x} ${y}`;
36030
35890
  pathData += lineCommand;
36031
35891
  // Build progress path up to the progress position
@@ -36039,8 +35899,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36039
35899
  const renderGradient = () => {
36040
35900
  return (jsxs(Fragment, { children: [jsx(Defs, { children: jsx(LinearGradient, { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: resolvedGradientColors.map((color, index) => (jsx(Stop, { offset: `${(index / (resolvedGradientColors.length - 1 || 1)) * 100}%`, stopColor: color }, index))) }) }), normalizedPeaks.map((peak, index) => {
36041
35901
  const x = index * (barWidth + barGap);
36042
- const barHeight = Math.max(minBarHeight, Math.abs(peak) * height * 0.8);
36043
- const y = (height - barHeight) / 2;
35902
+ const barHeight = Math.max(minBarHeight, Math.abs(peak) * h * 0.8);
35903
+ const y = (h - barHeight) / 2;
36044
35904
  return (jsx(Rect, { x: x, y: y, width: barWidth, height: barHeight, fill: `url(#${gradientId})` }, index));
36045
35905
  })] }));
36046
35906
  };
@@ -36050,8 +35910,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36050
35910
  return null;
36051
35911
  const clampedProgress = Math.max(0, Math.min(1, progress));
36052
35912
  const progressX = clampedProgress * actualWaveformWidth;
36053
- return (jsx(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 }));
36054
- }, [showProgressLine, progress, actualWaveformWidth, height, progressLineStyle, theme.colors.gray]);
35913
+ return (jsx(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 }));
35914
+ }, [showProgressLine, progress, actualWaveformWidth, h, progressLineStyle, theme.colors.gray]);
36055
35915
  // Timestamp markers component
36056
35916
  const TimeStamps = useMemo(() => {
36057
35917
  if (!showTimeStamps || !duration || !timeStampInterval)
@@ -36072,10 +35932,10 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36072
35932
  }
36073
35933
  return `${mins}:${secs.toString().padStart(2, '0')}`;
36074
35934
  };
36075
- timestamps.push(jsxs(G, { children: [jsx(Line, { x1: x, y1: height - 10, x2: x, y2: height, stroke: theme.colors.gray[5], strokeWidth: 1, strokeOpacity: 0.6 }), jsx(Text$2, { x: x, y: height + 15, fill: theme.colors.gray[6], fontSize: 10, textAnchor: "middle", opacity: 0.8, children: formatTime(time) })] }, i));
35935
+ timestamps.push(jsxs(G, { children: [jsx(Line, { x1: x, y1: h - 10, x2: x, y2: h, stroke: theme.colors.gray[5], strokeWidth: 1, strokeOpacity: 0.6 }), jsx(Text$2, { x: x, y: h + 15, fill: theme.colors.gray[6], fontSize: 10, textAnchor: "middle", opacity: 0.8, children: formatTime(time) })] }, i));
36076
35936
  }
36077
35937
  return jsx(G, { children: timestamps });
36078
- }, [showTimeStamps, duration, timeStampInterval, actualWaveformWidth, height, theme.colors]);
35938
+ }, [showTimeStamps, duration, timeStampInterval, actualWaveformWidth, h, theme.colors]);
36079
35939
  // Selection overlay component
36080
35940
  const SelectionOverlay = useMemo(() => {
36081
35941
  if (!selection || selection[0] === selection[1])
@@ -36084,8 +35944,8 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36084
35944
  const startX = start * actualWaveformWidth;
36085
35945
  const endX = end * actualWaveformWidth;
36086
35946
  const selectionWidth = endX - startX;
36087
- return (jsx(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 }));
36088
- }, [selection, actualWaveformWidth, height, theme.colors.primary]);
35947
+ return (jsx(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 }));
35948
+ }, [selection, actualWaveformWidth, h, theme.colors.primary]);
36089
35949
  // Markers component
36090
35950
  const Markers = useMemo(() => {
36091
35951
  if (!markers || markers.length === 0)
@@ -36095,16 +35955,16 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36095
35955
  const markerColor = marker.color || theme.colors.warning[5];
36096
35956
  switch (marker.type || 'line') {
36097
35957
  case 'line':
36098
- return (jsxs(G, { children: [jsx(Line, { x1: x, y1: 0, x2: x, y2: height, stroke: markerColor, strokeWidth: 2, strokeOpacity: 0.8 }), marker.label && (jsx(Text$2, { x: x, y: -5, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
35958
+ return (jsxs(G, { children: [jsx(Line, { x1: x, y1: 0, x2: x, y2: h, stroke: markerColor, strokeWidth: 2, strokeOpacity: 0.8 }), marker.label && (jsx(Text$2, { x: x, y: -5, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
36099
35959
  case 'flag':
36100
- return (jsxs(G, { children: [jsx(Line, { x1: x, y1: 0, x2: x, y2: height, stroke: markerColor, strokeWidth: 1, strokeOpacity: 0.6 }), jsx(Rect, { x: x + 2, y: 2, width: marker.label ? marker.label.length * 6 + 4 : 20, height: 14, fill: markerColor, rx: 2 }), marker.label && (jsx(Text$2, { x: x + 4, y: 12, fill: "white", fontSize: 9, fontWeight: "bold", children: marker.label }))] }, index));
35960
+ return (jsxs(G, { children: [jsx(Line, { x1: x, y1: 0, x2: x, y2: h, stroke: markerColor, strokeWidth: 1, strokeOpacity: 0.6 }), jsx(Rect, { x: x + 2, y: 2, width: marker.label ? marker.label.length * 6 + 4 : 20, height: 14, fill: markerColor, rx: 2 }), marker.label && (jsx(Text$2, { x: x + 4, y: 12, fill: "white", fontSize: 9, fontWeight: "bold", children: marker.label }))] }, index));
36101
35961
  case 'dot':
36102
- return (jsxs(G, { children: [jsx("circle", { cx: x, cy: height / 2, r: 4, fill: markerColor, stroke: "white", strokeWidth: 1 }), marker.label && (jsx(Text$2, { x: x, y: height / 2 + 20, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
35962
+ return (jsxs(G, { children: [jsx("circle", { cx: x, cy: h / 2, r: 4, fill: markerColor, stroke: "white", strokeWidth: 1 }), marker.label && (jsx(Text$2, { x: x, y: h / 2 + 20, fill: markerColor, fontSize: 10, textAnchor: "middle", fontWeight: "bold", children: marker.label }))] }, index));
36103
35963
  default:
36104
35964
  return null;
36105
35965
  }
36106
35966
  }) }));
36107
- }, [markers, actualWaveformWidth, height, theme.colors.warning]);
35967
+ }, [markers, actualWaveformWidth, h, theme.colors.warning]);
36108
35968
  // RMS visualization component
36109
35969
  const RMSBars = useMemo(() => {
36110
35970
  if (!showRMS || !rmsData || rmsData.length === 0)
@@ -36112,11 +35972,11 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36112
35972
  const processedRMS = rmsData.slice(0, normalizedPeaks.length);
36113
35973
  return (jsx(G, { opacity: 0.5, children: processedRMS.map((rms, index) => {
36114
35974
  const x = index * (barWidth + barGap);
36115
- const rmsHeight = Math.max(minBarHeight, Math.abs(rms) * height * 0.4); // RMS bars are shorter
36116
- const y = (height - rmsHeight) / 2;
35975
+ const rmsHeight = Math.max(minBarHeight, Math.abs(rms) * h * 0.4); // RMS bars are shorter
35976
+ const y = (h - rmsHeight) / 2;
36117
35977
  return (jsx(Rect, { x: x, y: y, width: barWidth, height: rmsHeight, fill: theme.colors.gray[4], rx: variant === 'rounded' ? barWidth / 2 : 0 }, `rms-${index}`));
36118
35978
  }) }));
36119
- }, [showRMS, rmsData, normalizedPeaks, barWidth, barGap, minBarHeight, height, variant, theme.colors.gray]);
35979
+ }, [showRMS, rmsData, normalizedPeaks, barWidth, barGap, minBarHeight, h, variant, theme.colors.gray]);
36120
35980
  const renderWaveform = () => {
36121
35981
  switch (variant) {
36122
35982
  case 'line':
@@ -36153,17 +36013,17 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36153
36013
  };
36154
36014
  // Early return for empty state
36155
36015
  if (normalizedPeaks.length === 0) {
36156
- return (jsx(View, { style: [style, fullWidth ? { width: '100%' } : { width }, { height, justifyContent: 'center', alignItems: 'center' }], accessibilityRole: "image", accessibilityLabel: accessibilityLabel || 'Empty waveform', ...restProps, children: jsx(Svg, { ...svgProps, children: jsx(Rect, { x: 0, y: height / 2 - 1, width: fullWidth ? '100%' : width, height: 2, fill: waveformColor, opacity: 0.3 }) }) }));
36016
+ return (jsx(View, { style: [style, fullWidth ? { width: '100%' } : { width: w }, { height: h, justifyContent: 'center', alignItems: 'center' }], accessibilityRole: "image", accessibilityLabel: accessibilityLabel || 'Empty waveform', ...restProps, children: jsx(Svg, { ...svgProps, children: jsx(Rect, { x: 0, y: h / 2 - 1, width: fullWidth ? '100%' : w, height: 2, fill: waveformColor, opacity: 0.3 }) }) }));
36157
36017
  }
36158
36018
  if (loading) {
36159
- return (jsx(WaveformSkeleton, { width: width, height: height, fullWidth: fullWidth, barsCount: maxVisibleBars || 20 }));
36019
+ return (jsx(WaveformSkeleton, { w: w, h: h, fullWidth: fullWidth, barsCount: maxVisibleBars || 20 }));
36160
36020
  }
36161
36021
  if (error) {
36162
36022
  return (jsx(View, { style: [
36163
36023
  style,
36164
- fullWidth ? { width: '100%' } : { width },
36024
+ fullWidth ? { width: '100%' } : { width: w },
36165
36025
  {
36166
- height,
36026
+ height: h,
36167
36027
  justifyContent: 'center',
36168
36028
  alignItems: 'center',
36169
36029
  backgroundColor: theme.colors.error[1],
@@ -36173,7 +36033,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
36173
36033
  }
36174
36034
  ], accessibilityRole: "alert", accessibilityLabel: `Waveform error: ${error}`, ...restProps, children: jsx(Text$1, { style: { color: theme.colors.error[7], fontSize: 12, textAlign: 'center' }, children: error }) }));
36175
36035
  }
36176
- return (jsx(WrapperComponent, { ref: containerRef, style: [style, fullWidth ? { width: '100%' } : { width }], accessible: true, focusable: interactive, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), ...wrapperProps, ...restProps, children: jsxs(Svg, { ...svgProps, children: [SelectionOverlay, RMSBars, renderWaveform(), ProgressLine, TimeStamps, Markers] }) }));
36036
+ return (jsx(WrapperComponent, { ref: containerRef, style: [style, fullWidth ? { width: '100%' } : { width: w }], accessible: true, focusable: interactive, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), ...wrapperProps, ...restProps, children: jsxs(Svg, { ...svgProps, children: [SelectionOverlay, RMSBars, renderWaveform(), ProgressLine, TimeStamps, Markers] }) }));
36177
36037
  });
36178
36038
  Waveform.displayName = 'Waveform';
36179
36039
 
@@ -36195,7 +36055,7 @@ const AudioPlayer = forwardRef(({ source, peaks: providedPeaks, autoPlay = false
36195
36055
  channel: 'mix',
36196
36056
  }, showTime = true, timeFormat = 'mm:ss', showMetadata = false, metadata, showSpectrum = false, spectrumOptions, enableKeyboardShortcuts = true, enableGestures = true, onLoad, onPlaybackStateChange, onProgress, onEnd, onError, onBuffer,
36197
36057
  // Waveform props
36198
- width = 300, height = 60, color = 'primary', interactive = true, onSeek, style, ...waveformProps }, ref) => {
36058
+ w = 300, h = 60, color = 'primary', interactive = true, onSeek, style, ...waveformProps }, ref) => {
36199
36059
  const theme = useTheme();
36200
36060
  const { playSound } = useSound();
36201
36061
  // Refs
@@ -36542,7 +36402,7 @@ width = 300, height = 60, color = 'primary', interactive = true, onSeek, style,
36542
36402
  alignSelf: 'flex-start',
36543
36403
  }, children: jsx(Text$1, { style: { color: 'white', fontSize: DESIGN_TOKENS.typography.fontSize.sm }, children: "Retry" }) }))] }));
36544
36404
  }
36545
- return (jsxs(View, { style: [{ width: '100%' }, style], children: [controlsPosition === 'top' && renderMetadata(), controlsPosition === 'top' && renderControls(), controls.waveform && peaks.length > 0 && (jsx(View, { style: { marginVertical: DESIGN_TOKENS.spacing.sm }, children: jsx(Waveform, { peaks: peaks, width: width, height: height, color: color, progress: progress, interactive: interactive, onSeek: handleWaveformSeek, showProgressLine: true, progressLineStyle: {
36405
+ return (jsxs(View, { style: [{ width: '100%' }, style], children: [controlsPosition === 'top' && renderMetadata(), controlsPosition === 'top' && renderControls(), controls.waveform && peaks.length > 0 && (jsx(View, { style: { marginVertical: DESIGN_TOKENS.spacing.sm }, children: jsx(Waveform, { peaks: peaks, w: w, h: h, color: color, progress: progress, interactive: interactive, onSeek: handleWaveformSeek, showProgressLine: true, progressLineStyle: {
36546
36406
  color: theme.colors.primary[5],
36547
36407
  width: 2,
36548
36408
  opacity: 0.8,
@@ -37271,14 +37131,14 @@ const IMAGE_SIZES = {
37271
37131
  '2xl': 80,
37272
37132
  '3xl': 96,
37273
37133
  };
37274
- 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 }) {
37134
+ 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 }) {
37275
37135
  const theme = useTheme();
37276
37136
  const [loadError, setLoadError] = useState(false);
37277
37137
  const [isLoading, setIsLoading] = useState(true);
37278
37138
  const { spacingProps } = extractSpacingProps(rest);
37279
37139
  // Determine dimensions
37280
- let finalWidth = width;
37281
- let finalHeight = height;
37140
+ let finalWidth = w;
37141
+ let finalHeight = h;
37282
37142
  if (size && typeof size === 'string' && IMAGE_SIZES[size]) {
37283
37143
  finalWidth = finalWidth || IMAGE_SIZES[size];
37284
37144
  finalHeight = finalHeight || IMAGE_SIZES[size];
@@ -39086,7 +38946,7 @@ function QRCode(props) {
39086
38946
  });
39087
38947
  }
39088
38948
  }, [copy, copyValue, toast, otherProps.copyToastMessage, otherProps.copyToastTitle]);
39089
- const content = (jsxs(View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [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 && (jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
38949
+ const content = (jsxs(View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [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 && (jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
39090
38950
  if (shouldCopyOnPress) {
39091
38951
  return (jsx(Pressable, { onPress: handleCopy, accessibilityLabel: accessibilityLabel || 'QR code', children: content }));
39092
38952
  }
@@ -39736,111 +39596,6 @@ const styles$2 = StyleSheet.create({
39736
39596
  },
39737
39597
  });
39738
39598
 
39739
- // Optional imports for web compatibility
39740
- const LottieReact = Platform.OS === 'web'
39741
- ? resolveOptionalModule('lottie-react', {
39742
- accessor: mod => { var _a; return (_a = mod.default) !== null && _a !== void 0 ? _a : mod; },
39743
- })
39744
- : null;
39745
- const DotLottieReact = Platform.OS === 'web'
39746
- ? resolveOptionalModule('@lottiefiles/dotlottie-react', {
39747
- accessor: mod => mod.DotLottieReact,
39748
- })
39749
- : null;
39750
- let cachedNativeStatus = null;
39751
- let nativeLottieComponent;
39752
- let nativeModuleLoadWarningLogged = false;
39753
- let nativeModuleConfigWarningLogged = false;
39754
- const loadNativeLottieComponent = () => {
39755
- if (nativeLottieComponent !== undefined) {
39756
- return nativeLottieComponent;
39757
- }
39758
- const module = resolveOptionalModule('lottie-react-native', {
39759
- accessor: mod => { var _a; return (_a = mod === null || mod === void 0 ? void 0 : mod.default) !== null && _a !== void 0 ? _a : mod; },
39760
- });
39761
- if (!module && !nativeModuleLoadWarningLogged && __DEV__) {
39762
- console.warn('[Lottie] Failed to load lottie-react-native module. Rendering fallback instead.');
39763
- nativeModuleLoadWarningLogged = true;
39764
- }
39765
- nativeLottieComponent = module !== null && module !== void 0 ? module : null;
39766
- return nativeLottieComponent;
39767
- };
39768
- const getNativeLottieStatus = () => {
39769
- var _a, _b, _c;
39770
- if (cachedNativeStatus) {
39771
- return cachedNativeStatus;
39772
- }
39773
- if (Platform.OS === 'web') {
39774
- cachedNativeStatus = { component: null, available: false };
39775
- return cachedNativeStatus;
39776
- }
39777
- const component = loadNativeLottieComponent();
39778
- if (!component) {
39779
- cachedNativeStatus = { component: null, available: false };
39780
- return cachedNativeStatus;
39781
- }
39782
- let viewManagerAvailable = false;
39783
- try {
39784
- const viewManager = (_c = (_b = (_a = UIManager === null || UIManager === void 0 ? void 0 : UIManager.getViewManagerConfig) === null || _a === void 0 ? void 0 : _a.call(UIManager, 'LottieAnimationView')) !== null && _b !== void 0 ? _b : UIManager === null || UIManager === void 0 ? void 0 : UIManager.LottieAnimationView) !== null && _c !== void 0 ? _c : NativeModules === null || NativeModules === void 0 ? void 0 : NativeModules.LottieAnimationView;
39785
- viewManagerAvailable = !!viewManager;
39786
- }
39787
- catch (error) {
39788
- viewManagerAvailable = false;
39789
- }
39790
- if (!viewManagerAvailable && !nativeModuleConfigWarningLogged && __DEV__) {
39791
- console.warn('[Lottie] Native LottieAnimationView is unavailable. Run `npx expo install lottie-react-native` and rebuild to enable animations.');
39792
- nativeModuleConfigWarningLogged = true;
39793
- }
39794
- cachedNativeStatus = {
39795
- component,
39796
- available: viewManagerAvailable,
39797
- };
39798
- return cachedNativeStatus;
39799
- };
39800
- /**
39801
- * Lottie component with safe fallback when native module not present or on unsupported platforms.
39802
- */
39803
- const Lottie = forwardRef(function LottieCmp(props, ref) {
39804
- const { source, autoPlay = true, loop = true, progress, speed = 1, style, testID, paused, resizeMode = 'contain', onAnimationFinish } = props;
39805
- const internalRef = useRef(null);
39806
- const nativeStatus = getNativeLottieStatus();
39807
- const NativeLottieView = nativeStatus.component;
39808
- useImperativeHandle(ref, () => ({
39809
- 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); },
39810
- 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); },
39811
- 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); },
39812
- 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); },
39813
- }), []);
39814
- useEffect(() => {
39815
- var _a;
39816
- if (progress != null && ((_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.setProgress)) {
39817
- internalRef.current.setProgress(progress);
39818
- }
39819
- }, [progress]);
39820
- // Web implementation
39821
- if (Platform.OS === 'web') {
39822
- // Check if source is a string (URL) and ends with .lottie
39823
- const isLottieFile = typeof source === 'string' && source.endsWith('.lottie');
39824
- if (isLottieFile && DotLottieReact) {
39825
- // Use DotLottieReact for .lottie files
39826
- return (jsx(DotLottieReact, { src: source, autoplay: autoPlay, loop: loop, speed: speed, style: style, "data-testid": testID }));
39827
- }
39828
- else if (LottieReact) {
39829
- // Use lottie-react for standard Lottie JSON
39830
- return (jsx(LottieReact, { animationData: source, autoplay: autoPlay, loop: loop, style: style, "data-testid": testID }));
39831
- }
39832
- else {
39833
- return jsx(Text, { children: "Lottie not available on web" });
39834
- }
39835
- }
39836
- // Native implementation using lottie-react-native
39837
- if (!nativeStatus.available || !NativeLottieView) {
39838
- return (jsx(View, { style: [{ justifyContent: 'center', alignItems: 'center' }, style], testID: testID, children: 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." }) }));
39839
- }
39840
- return (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 } : {}) }));
39841
- });
39842
- Lottie.displayName = 'Lottie';
39843
-
39844
39599
  const PLAYBACK_RATES = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
39845
39600
  function formatTime(seconds) {
39846
39601
  const hours = Math.floor(seconds / 3600);
@@ -40788,7 +40543,7 @@ const DEFAULT_CONTROLS = {
40788
40543
  autoHide: true,
40789
40544
  autoHideTimeout: 3000,
40790
40545
  };
40791
- const Video = 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) => {
40546
+ const Video = 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) => {
40792
40547
  const theme = useTheme();
40793
40548
  const { spacingProps } = extractSpacingProps(rest);
40794
40549
  // Internal state
@@ -41038,24 +40793,24 @@ const Video = forwardRef(({ source, width, height, aspectRatio = 16 / 9, poster,
41038
40793
  // overflow: 'hidden',
41039
40794
  // position: 'relative',
41040
40795
  };
41041
- if (width && height) {
41042
- baseStyle.width = width;
41043
- baseStyle.height = height;
40796
+ if (w && h) {
40797
+ baseStyle.width = w;
40798
+ baseStyle.height = h;
41044
40799
  }
41045
- else if (width) {
41046
- baseStyle.width = width;
41047
- baseStyle.height = typeof width === 'number' ? width / aspectRatio : '100%';
40800
+ else if (w) {
40801
+ baseStyle.width = w;
40802
+ baseStyle.height = typeof w === 'number' ? w / aspectRatio : '100%';
41048
40803
  }
41049
- else if (height) {
41050
- baseStyle.height = height;
41051
- baseStyle.width = typeof height === 'number' ? height * aspectRatio : '100%';
40804
+ else if (h) {
40805
+ baseStyle.height = h;
40806
+ baseStyle.width = typeof h === 'number' ? h * aspectRatio : '100%';
41052
40807
  }
41053
40808
  else {
41054
40809
  baseStyle.width = '100%';
41055
40810
  baseStyle.aspectRatio = aspectRatio;
41056
40811
  }
41057
40812
  return baseStyle;
41058
- }, [theme.colors.surface, width, height, aspectRatio]);
40813
+ }, [theme.colors.surface, w, h, aspectRatio]);
41059
40814
  // Handle touch events for control visibility
41060
40815
  const handleContainerPress = useCallback(() => {
41061
40816
  if (controlsConfig && controlsConfig.autoHide) {
@@ -41159,5 +40914,5 @@ function withPressAnimation(Component, animationProps) {
41159
40914
  */
41160
40915
  const AnimatedPressable = PressAnimation;
41161
40916
 
41162
- export { AccessibilityProvider, Accordion, AmazonAppstoreBadge, AmazonAppstoreButton, AmazonMusicListenBadge, AmazonPrimeVideoBadge, AmazonStoreBadge, AnimatedPressable, AppLayoutProvider, AppLayoutRenderer, AppShell, AppShellAside, AppShellBottomNav, AppShellFooter, AppShellHeader, AppShellMain, AppShellNavbar, AppShellSection, AppStoreBadge, AppStoreButton, AppStoreDownloadBadge, AppleAppStoreButton, AppleMusicListenBadge, ApplePodcastsListenBadge, AutoComplete, Avatar, AvatarGroup, Badge, Block, Blockquote, Bold, BottomAppBar, BrandButton, BrandIcon, Breadcrumbs, Button, COMPONENT_SIZES$1 as COMPONENT_SIZES, COMPONENT_SIZE_ORDER, Calendar, Card, Carousel, Checkbox, Chip, ChromeWebStoreBadge, Cite, Code, CodeBlock, Collapse, ColorPicker, ColorSwatch, Column, ComponentWithDisclaimer, ContextMenu, CopyButton, DARK_THEME, DEFAULT_BREAKPOINTS, DEFAULT_COMPONENT_SIZE, DEFAULT_SOUND_IDS, DEFAULT_THEME, DataTable, DatePicker, DatePickerInput, Day, Dialog, DialogProvider, DialogRenderer, DirectionProvider, Disclaimer, DiscordJoinBadge, Divider, EmojiPicker, Emphasis, FDroidButton, FileInput, Flex, FloatingActions, Form, GalaxyStoreDownloadBadge, Gallery, Gauge, GitHubViewBadge, GooglePlayButton, GooglePlayDownloadBadge, Grid, GridItem, H1, H2, H3, H4, H5, H6, HapticsProvider, Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, Highlight, HuaweiAppGalleryBadge, I18nProvider, Icon, IconButton, Image, Indicator, Input, Italic, Kbd, KeyCap, KeyboardAwareLayout, KeyboardManagerProvider, Knob, Link, ListGroup, ListGroupBody, ListGroupDivider, ListGroupItem, Loader, LoadingOverlay, Lottie, MacAppStoreButton, Mark, Markdown, Masonry, Menu, MenuDivider, MenuDropdown, MenuItem, MenuItemButton, MenuLabel, MicrosoftStoreButton, MicrosoftStoreDownloadBadge, MiniCalendar, Month, MonthPicker, MonthPickerInput, Notice, NumberInput, Overlay, OverlayProvider, P, Pagination, PasswordInput, PhoneInput, PinInput, PlatformBlocksProvider, Popover, PressAnimation, Progress, QRCode, Radio, RadioGroup, RangeSlider, Rating, RedditJoinBadge, RichTextEditor, Ring, Row, SIZE_SCALES, Search, SegmentedControl, Select, ShimmerText, Skeleton, Slider, Small, SoundCloudListenBadge, SoundProvider, Space, Spoiler, SpotifyListenBadge, Spotlight, SpotlightProvider, StatusBarManager, StepperWithSubComponents as Stepper, Strong, Sub, Sup, Switch, Table, TableOfContents, Tabs, Text, TextArea, TextInputBase, ThemeModeProvider, TikTokWatchBadge, TimePickerInput as TimePicker, TimePickerInput, TimelineWithItems as Timeline, Title, TitleRegistryProvider, Toast, ToastProvider, ToggleBar, ToggleButton, ToggleGroup, Tooltip, Tree, TwitchWatchBadge, Underline, Video, Waveform, YearPicker, YearPickerInput, YouTubeMusicListenBadge, YouTubeWatchBadge, calculateOverlayPositionEnhanced, clampComponentSize, clearOverlayPositionCache, createSound, createSpotlightStore, createTheme, debounce$1 as debounce, defineAppLayout, directSpotlight, extractDisclaimerProps, factory, getAllSounds, getColor, getFontSize, getHeight, getIconSize$1 as getIconSize, getLineHeight, getRadius$1 as getRadius, getScrollPosition, getShadow$1 as getShadow, getSize, getSoundsByCategory, getSpacing, getViewport, globalHotkeys, measureAsyncPerformance, measureElement, measurePerformance, onDialogsRequested, onSpotlightRequested, onToastsRequested, pointInRect, polymorphicFactory, px, rem, resolveComponentSize, resolveResponsiveProp, resolveResponsiveValue, resolveSize, spotlight, throttle, useAccessibility, useAppLayoutContext, useAppShell, useAppShellApi, useAppShellLayout, useBreakpoint, useColorScheme, useDialog, useDialogApi, useDialogs, useDirectSpotlightState, useDirection, useDirectionSafe, useDisclaimer, useDropdownPositioning, useEscapeKey, useFormContext, useGlobalHotkeys, useHaptics, useHapticsSettings, useHotkeys, useI18n, useKeyboardManager, useKeyboardManagerOptional, useNavbarHover, useOptionalFormContext, useOverlay, useOverlayApi, useOverlays, usePopoverPositioning, useSimpleDialog, useSound, useSpotlightStore, useSpotlightStoreInstance, useSpotlightToggle, useTheme, useThemeMode, useTitleRegistry, useTitleRegistryOptional, useToast, useToastApi, useToggleColorScheme, useTooltipPositioning, withDisclaimer, withPressAnimation };
40917
+ export { AccessibilityProvider, Accordion, AmazonAppstoreBadge, AmazonAppstoreButton, AmazonMusicListenBadge, AmazonPrimeVideoBadge, AmazonStoreBadge, AnimatedPressable, AppLayoutProvider, AppLayoutRenderer, AppShell, AppShellAside, AppShellBottomNav, AppShellFooter, AppShellHeader, AppShellMain, AppShellNavbar, AppShellSection, AppStoreBadge, AppStoreButton, AppStoreDownloadBadge, AppleAppStoreButton, AppleMusicListenBadge, ApplePodcastsListenBadge, AutoComplete, Avatar, AvatarGroup, Badge, Block, Blockquote, Bold, BottomAppBar, BrandButton, BrandIcon, Breadcrumbs, Button, COMPONENT_SIZES$1 as COMPONENT_SIZES, COMPONENT_SIZE_ORDER, Calendar, Card, Carousel, Checkbox, Chip, ChromeWebStoreBadge, Cite, Code, CodeBlock, Collapse, ColorPicker, ColorSwatch, Column, ComponentWithDisclaimer, ContextMenu, CopyButton, DARK_THEME, DEFAULT_BREAKPOINTS, DEFAULT_COMPONENT_SIZE, DEFAULT_SOUND_IDS, DEFAULT_THEME, DataTable, DatePicker, DatePickerInput, Day, Dialog, DialogProvider, DialogRenderer, DirectionProvider, Disclaimer, DiscordJoinBadge, Divider, EmojiPicker, Emphasis, FDroidButton, FileInput, Flex, FloatingActions, Form, GalaxyStoreDownloadBadge, Gallery, Gauge, GitHubViewBadge, GooglePlayButton, GooglePlayDownloadBadge, Grid, GridItem, H1, H2, H3, H4, H5, H6, HapticsProvider, Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, Highlight, HuaweiAppGalleryBadge, I18nProvider, Icon, IconButton, Image, Indicator, Input, Italic, Kbd, KeyCap, KeyboardAwareLayout, KeyboardManagerProvider, Knob, Link, ListGroup, ListGroupBody, ListGroupDivider, ListGroupItem, Loader, LoadingOverlay, MacAppStoreButton, Mark, Markdown, Masonry, Menu, MenuDivider, MenuDropdown, MenuItem, MenuItemButton, MenuLabel, MicrosoftStoreButton, MicrosoftStoreDownloadBadge, MiniCalendar, Month, MonthPicker, MonthPickerInput, Notice, NumberInput, Overlay, OverlayProvider, P, Pagination, PasswordInput, PhoneInput, PinInput, PlatformBlocksProvider, Popover, PressAnimation, Progress, QRCode, Radio, RadioGroup, RangeSlider, Rating, RedditJoinBadge, Ring, Row, SIZE_SCALES, Search, SegmentedControl, Select, ShimmerText, Skeleton, Slider, Small, SoundCloudListenBadge, SoundProvider, Space, Spoiler, SpotifyListenBadge, Spotlight, SpotlightProvider, StatusBarManager, StepperWithSubComponents as Stepper, Strong, Sub, Sup, Switch, Table, TableOfContents, Tabs, Text, TextArea, TextInputBase, ThemeModeProvider, TikTokWatchBadge, TimePickerInput as TimePicker, TimePickerInput, TimelineWithItems as Timeline, Title, TitleRegistryProvider, Toast, ToastProvider, ToggleBar, ToggleButton, ToggleGroup, Tooltip, Tree, TwitchWatchBadge, Underline, Video, Waveform, YearPicker, YearPickerInput, YouTubeMusicListenBadge, YouTubeWatchBadge, calculateOverlayPositionEnhanced, clampComponentSize, clearOverlayPositionCache, createSound, createSpotlightStore, createTheme, debounce$1 as debounce, defineAppLayout, directSpotlight, extractDisclaimerProps, factory, getAllSounds, getColor, getFontSize, getHeight, getIconSize$1 as getIconSize, getLineHeight, getRadius$1 as getRadius, getScrollPosition, getShadow$1 as getShadow, getSize, getSoundsByCategory, getSpacing, getViewport, globalHotkeys, measureAsyncPerformance, measureElement, measurePerformance, onDialogsRequested, onSpotlightRequested, onToastsRequested, pointInRect, polymorphicFactory, px, rem, resolveComponentSize, resolveResponsiveProp, resolveResponsiveValue, resolveSize, spotlight, throttle, useAccessibility, useAppLayoutContext, useAppShell, useAppShellApi, useAppShellLayout, useBreakpoint, useColorScheme, useDialog, useDialogApi, useDialogs, useDirectSpotlightState, useDirection, useDirectionSafe, useDisclaimer, useDropdownPositioning, useEscapeKey, useFormContext, useGlobalHotkeys, useHaptics, useHapticsSettings, useHotkeys, useI18n, useKeyboardManager, useKeyboardManagerOptional, useNavbarHover, useOptionalFormContext, useOverlay, useOverlayApi, useOverlays, usePopoverPositioning, useSimpleDialog, useSound, useSpotlightStore, useSpotlightStoreInstance, useSpotlightToggle, useTheme, useThemeMode, useTitleRegistry, useTitleRegistryOptional, useToast, useToastApi, useToggleColorScheme, useTooltipPositioning, withDisclaimer, withPressAnimation };
41163
40918
  //# sourceMappingURL=index.js.map