@platform-blocks/ui 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/esm/index.js CHANGED
@@ -4,11 +4,9 @@ import React__default, { createContext, useContext, useMemo, useEffect, useState
4
4
  import { Platform, Modal, StyleSheet, View, Pressable, I18nManager, Dimensions, Text as Text$1, AccessibilityInfo, findNodeHandle, Animated as Animated$1, Easing, AppState, useWindowDimensions, PanResponder, BackHandler, TextInput, ScrollView, ImageBackground, TouchableOpacity, Image as Image$1, FlatList, Keyboard, InteractionManager, Linking, StatusBar as StatusBar$1, UIManager, NativeModules } 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, SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context';
7
- import { LinearGradient as LinearGradient$1 } from 'expo-linear-gradient';
8
- import Svg, { Path, Defs, LinearGradient as LinearGradient$2, Stop, Circle, Line, G, Text as Text$2, Rect, RadialGradient, ClipPath } from 'react-native-svg';
7
+ import Svg, { Path, Defs, LinearGradient, Stop, Circle, Line, G, Text as Text$2, Rect, RadialGradient, ClipPath } from 'react-native-svg';
9
8
  import { FlashList } from '@shopify/flash-list';
10
9
  import MaskedView from '@react-native-masked-view/masked-view';
11
- import * as DocumentPicker from 'expo-document-picker';
12
10
  import ReanimatedCarousel from 'react-native-reanimated-carousel';
13
11
 
14
12
  /**
@@ -658,7 +656,7 @@ const DARK_THEME = {
658
656
  '#8E8E93',
659
657
  '#AEAEB2',
660
658
  '#C7C7CC',
661
- '#D1D16',
659
+ '#D1D1D6',
662
660
  '#E5E5EA'
663
661
  ],
664
662
  success: [
@@ -3149,6 +3147,21 @@ const convertToWebStyles = (rnStyles) => {
3149
3147
  });
3150
3148
  return webStyles;
3151
3149
  };
3150
+ const containsPlatformText = (node) => {
3151
+ return React__default.Children.toArray(node).some(child => {
3152
+ if (React__default.isValidElement(child)) {
3153
+ const childType = child.type;
3154
+ if ((childType === null || childType === void 0 ? void 0 : childType.__PLATFORM_BLOCKS_TEXT__) === true) {
3155
+ return true;
3156
+ }
3157
+ const childProps = child.props;
3158
+ if (childProps === null || childProps === void 0 ? void 0 : childProps.children) {
3159
+ return containsPlatformText(childProps.children);
3160
+ }
3161
+ }
3162
+ return false;
3163
+ });
3164
+ };
3152
3165
  const Text = (allProps) => {
3153
3166
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
3154
3167
  const { children, tx, txParams, variant = 'p', size, weight, align = 'left', color, colorVariant, lineHeight, tracking, uppercase, style, fontFamily, as, selectable = true, onPress, onLayout, value, numberOfLines, ellipsizeMode } = otherProps;
@@ -3189,6 +3202,10 @@ const Text = (allProps) => {
3189
3202
  // Switch to div to prevent <h*> inside <p> DOM nesting warning / hydration error
3190
3203
  htmlTag = 'div';
3191
3204
  }
3205
+ if (htmlTag === 'p' && containsPlatformText(children)) {
3206
+ // Avoid nested paragraphs when Text components are nested
3207
+ htmlTag = 'div';
3208
+ }
3192
3209
  }
3193
3210
  // Platform-specific rendering
3194
3211
  if (Platform.OS === 'web' && isHTMLVariant(htmlTag)) {
@@ -3226,6 +3243,7 @@ const Text = (allProps) => {
3226
3243
  // Fallback to React Native Text for mobile or non-HTML variants
3227
3244
  return (jsx(Text$1, { style: [textStyles, spacingStyles, style], selectable: selectable, onPress: onPress, onLayout: onLayout, numberOfLines: numberOfLines, ellipsizeMode: ellipsizeMode, children: content }));
3228
3245
  };
3246
+ Text.__PLATFORM_BLOCKS_TEXT__ = true;
3229
3247
  // Helper function to check if variant is a valid HTML tag
3230
3248
  const isHTMLVariant = (variant) => {
3231
3249
  const htmlTags = [
@@ -4155,6 +4173,12 @@ const actionIcons = {
4155
4173
  variant: 'outlined',
4156
4174
  description: 'Magnifying glass and highlight circle to represent spotlight search.',
4157
4175
  },
4176
+ highlight: {
4177
+ content: 'm15.728 3.514 4.758 4.758-7.071 7.071-2.474.353a1 1 0 0 1-1.118-1.118l.353-2.474 7.552-7.03Zm-9.95 8.486 3.222 3.222-3 3H3a1 1 0 0 1-1-1v-2.999l3.778-3.223Z',
4178
+ viewBox: '0 0 24 24',
4179
+ variant: 'outlined',
4180
+ description: 'Highlighter marker illustrating text emphasis.',
4181
+ },
4158
4182
  minus: {
4159
4183
  content: 'M5 12h14',
4160
4184
  viewBox: '0 0 24 24',
@@ -4641,6 +4665,12 @@ const uiIcons = {
4641
4665
  variant: 'outlined',
4642
4666
  description: 'Tooltip badge with question mark for contextual hints.',
4643
4667
  },
4668
+ popover: {
4669
+ content: 'M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-5.17L12 19.17 9.17 16H6a2 2 0 0 1-2-2V6z',
4670
+ viewBox: '0 0 24 24',
4671
+ variant: 'outlined',
4672
+ description: 'Popover surface with speech arrow for contextual overlays.',
4673
+ },
4644
4674
  'layer-mask': {
4645
4675
  content: 'M5 4h4 M4 5v4 M19 4h-4 M20 5v4 M19 20h-4 M20 19v-4 M5 20h4 M4 19v-4 M9 9h12v10H9z M13 13h4v4h-4z',
4646
4676
  viewBox: '0 0 24 24',
@@ -4648,10 +4678,22 @@ const uiIcons = {
4648
4678
  description: 'Layered frame with inset window representing an overlay mask.',
4649
4679
  },
4650
4680
  slider: {
4651
- content: 'M7 14H5v5h5v-2H7v-3zM5 10h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z',
4681
+ content: 'M12 3a1 1 0 0 1 .993 .883l.007 .117v9.171a3.001 3.001 0 0 1 0 5.658v1.171a1 1 0 0 1 -1.993 .117l-.007 -.117v-1.17a3.002 3.002 0 0 1 -1.995 -2.654l-.005 -.176l.005 -.176a3.002 3.002 0 0 1 1.995 -2.654v-9.17a1 1 0 0 1 1 -1z',
4652
4682
  viewBox: '0 0 24 24',
4653
4683
  variant: 'outlined',
4654
- description: 'Slider control handles for adjustable inputs.',
4684
+ description: 'Horizontal slider track with centered thumb knob.',
4685
+ },
4686
+ hook: {
4687
+ content: 'M6 3v7a6 6 0 1 0 12 0v-2M6 6h6M10 13c0 2 1.5 3 3 3s3-1 3-3',
4688
+ viewBox: '0 0 24 24',
4689
+ variant: 'outlined',
4690
+ description: 'Fishing hook silhouette for representing hooks utilities.',
4691
+ },
4692
+ support: {
4693
+ content: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 4a6 6 0 1 1 0 12 6 6 0 0 1 0-12Zm-4.95-.95 2.12 2.12-1.06 1.06-2.12-2.12 1.06-1.06Zm9.9 0 1.06 1.06-2.12 2.12-1.06-1.06 2.12-2.12ZM7.05 16.95l-1.06-1.06 2.12-2.12 1.06 1.06-2.12 2.12Zm9.9 0-2.12-2.12 1.06-1.06 2.12 2.12-1.06 1.06Z',
4694
+ viewBox: '0 0 24 24',
4695
+ variant: 'outlined',
4696
+ description: 'Life preserver style icon to represent support resources.',
4655
4697
  },
4656
4698
  input: {
4657
4699
  content: 'M4 6h16v2H4zM4 12h16v6H4z',
@@ -5597,6 +5639,65 @@ const createAccessibilityProps = (options) => {
5597
5639
  return accessibilityProps;
5598
5640
  };
5599
5641
 
5642
+ let linearGradientCache;
5643
+ let linearGradientAvailable = false;
5644
+ let warnedLinearGradient = false;
5645
+ const LinearGradientFallback = ({ children, style, colors }) => {
5646
+ if (__DEV__ && !warnedLinearGradient) {
5647
+ console.warn('expo-linear-gradient not installed; gradient-based components fall back to solid colors.');
5648
+ warnedLinearGradient = true;
5649
+ }
5650
+ const styles = [
5651
+ (colors === null || colors === void 0 ? void 0 : colors[0]) ? { backgroundColor: colors[0] } : undefined,
5652
+ ...(Array.isArray(style) ? style : style ? [style] : []),
5653
+ ].filter(Boolean);
5654
+ return React__default.createElement(View, { style: styles }, children);
5655
+ };
5656
+ function resolveLinearGradient() {
5657
+ var _a, _b;
5658
+ if (linearGradientCache === undefined) {
5659
+ try {
5660
+ const mod = require('expo-linear-gradient');
5661
+ linearGradientCache = (_b = (_a = mod === null || mod === void 0 ? void 0 : mod.LinearGradient) !== null && _a !== void 0 ? _a : mod === null || mod === void 0 ? void 0 : mod.default) !== null && _b !== void 0 ? _b : mod;
5662
+ linearGradientAvailable = !!linearGradientCache;
5663
+ }
5664
+ catch (_c) {
5665
+ linearGradientCache = LinearGradientFallback;
5666
+ linearGradientAvailable = false;
5667
+ }
5668
+ }
5669
+ if (!linearGradientCache) {
5670
+ linearGradientCache = LinearGradientFallback;
5671
+ linearGradientAvailable = false;
5672
+ }
5673
+ return {
5674
+ LinearGradient: linearGradientCache,
5675
+ hasLinearGradient: linearGradientAvailable,
5676
+ };
5677
+ }
5678
+ let documentPickerCache;
5679
+ let warnedDocumentPicker = false;
5680
+ function resolveDocumentPicker() {
5681
+ if (documentPickerCache === undefined) {
5682
+ try {
5683
+ documentPickerCache = require('expo-document-picker');
5684
+ }
5685
+ catch (_a) {
5686
+ documentPickerCache = null;
5687
+ }
5688
+ }
5689
+ const hasDocumentPicker = !!(documentPickerCache === null || documentPickerCache === void 0 ? void 0 : documentPickerCache.getDocumentAsync);
5690
+ if (!hasDocumentPicker && __DEV__ && !warnedDocumentPicker) {
5691
+ console.warn('expo-document-picker not installed; native file picker support is disabled.');
5692
+ warnedDocumentPicker = true;
5693
+ }
5694
+ return {
5695
+ DocumentPicker: documentPickerCache,
5696
+ hasDocumentPicker,
5697
+ };
5698
+ }
5699
+
5700
+ const { LinearGradient: OptionalLinearGradient$4, hasLinearGradient: hasLinearGradient$3 } = resolveLinearGradient();
5600
5701
  const getButtonStyles = (theme, variant = 'filled', size = 'md', disabled = false, loading = false, height, radiusStyles, shadowStyles, customColor, isIconButton = false, fullWidth = false) => {
5601
5702
  const sizeConfig = getComponentSize(size);
5602
5703
  const horizontalSpacing = isIconButton ? 0 : sizeConfig.padding;
@@ -5720,6 +5821,7 @@ const Button = (allProps) => {
5720
5821
  const { title, children, onPress, onPressIn, onPressOut, onHoverIn, onHoverOut, onLongPress, onLayout, variant = 'filled', size = 'md', disabled = false, loading = false, loadingTitle, colorVariant, textColor: textColorProp, icon, startIcon, endIcon, tooltip, tooltipPosition = 'top', radius, style, testID, accessibilityLabel: accessibilityLabelProp, accessibilityHint: accessibilityHintProp, } = otherProps;
5721
5822
  // Theme
5722
5823
  const theme = useTheme();
5824
+ const effectiveVariant = variant === 'gradient' && !hasLinearGradient$3 ? 'filled' : variant;
5723
5825
  // Accessibility hooks
5724
5826
  const { getDuration } = useReducedMotion$1();
5725
5827
  const { announce } = useAnnouncer();
@@ -5783,7 +5885,7 @@ const Button = (allProps) => {
5783
5885
  const height = getHeight(size);
5784
5886
  const radiusStyles = createRadiusStyles(radius, height, 'button');
5785
5887
  // Handle shadow prop - use default 'sm' for primary/filled/secondary/gradient variants if no shadow specified
5786
- const effectiveShadow = (_a = shadowProps.shadow) !== null && _a !== void 0 ? _a : ((variant === 'filled' || variant === 'secondary' || variant === 'gradient') ? 'sm' : 'none');
5888
+ const effectiveShadow = (_a = shadowProps.shadow) !== null && _a !== void 0 ? _a : ((effectiveVariant === 'filled' || effectiveVariant === 'secondary' || effectiveVariant === 'gradient') ? 'sm' : 'none');
5787
5889
  const shadowStyles = getShadowStyles({ shadow: effectiveShadow }, theme, 'button');
5788
5890
  const spacingStyles = getSpacingStyles(spacingProps);
5789
5891
  const baseLayoutStyles = getLayoutStyles(layoutProps);
@@ -5818,7 +5920,7 @@ const Button = (allProps) => {
5818
5920
  return token; // raw css color
5819
5921
  };
5820
5922
  const resolvedCustomColor = resolveTokenColor(colorVariant);
5821
- const buttonStyles = getButtonStyles(theme, variant, size, disabled, loading, height, radiusStyles, shadowStyles, resolvedCustomColor, isIconButton, layoutProps.fullWidth || false);
5923
+ const buttonStyles = getButtonStyles(theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, resolvedCustomColor, isIconButton, layoutProps.fullWidth || false);
5822
5924
  // derive contrasted text color if filled/filled background
5823
5925
  const pickContrast = (bg) => {
5824
5926
  if (!bg)
@@ -5837,12 +5939,12 @@ const Button = (allProps) => {
5837
5939
  if (textColorProp)
5838
5940
  return resolveTokenColor(textColorProp) || textColorProp;
5839
5941
  if (resolvedCustomColor) {
5840
- if (variant === 'filled' || variant === 'gradient')
5942
+ if (effectiveVariant === 'filled' || effectiveVariant === 'gradient')
5841
5943
  return pickContrast(resolvedCustomColor);
5842
- if (variant === 'outline' || variant === 'ghost' || variant === 'none' || variant === 'secondary')
5944
+ if (effectiveVariant === 'outline' || effectiveVariant === 'ghost' || effectiveVariant === 'none' || effectiveVariant === 'secondary')
5843
5945
  return resolvedCustomColor;
5844
5946
  }
5845
- switch (variant) {
5947
+ switch (effectiveVariant) {
5846
5948
  case 'filled': return '#FFFFFF';
5847
5949
  case 'gradient': return '#FFFFFF';
5848
5950
  case 'secondary': return theme.colors.gray[7];
@@ -5852,7 +5954,7 @@ const Button = (allProps) => {
5852
5954
  case 'none': return 'currentColor';
5853
5955
  default: return '#FFFFFF';
5854
5956
  }
5855
- }, [textColorProp, resolvedCustomColor, variant, theme.colors.gray, theme.colors.primary]);
5957
+ }, [textColorProp, resolvedCustomColor, effectiveVariant, theme.colors.gray, theme.colors.primary]);
5856
5958
  // Memoize text props
5857
5959
  const textProps = useMemo(() => ({
5858
5960
  size,
@@ -5868,11 +5970,11 @@ const Button = (allProps) => {
5868
5970
  // Memoize loader color calculation
5869
5971
  const loaderColor = useMemo(() => {
5870
5972
  if (resolvedCustomColor) {
5871
- if (variant === 'filled')
5973
+ if (effectiveVariant === 'filled')
5872
5974
  return pickContrast(resolvedCustomColor);
5873
5975
  return resolvedCustomColor;
5874
5976
  }
5875
- switch (variant) {
5977
+ switch (effectiveVariant) {
5876
5978
  case 'filled': return '#FFFFFF';
5877
5979
  case 'secondary': return theme.colors.gray[7];
5878
5980
  case 'outline': return theme.colors.primary[5];
@@ -5882,7 +5984,7 @@ const Button = (allProps) => {
5882
5984
  case 'none': return 'currentColor';
5883
5985
  default: return '#FFFFFF';
5884
5986
  }
5885
- }, [resolvedCustomColor, variant, theme.colors.gray, theme.colors.primary]);
5987
+ }, [resolvedCustomColor, effectiveVariant, theme.colors.gray, theme.colors.primary]);
5886
5988
  // Helper function to inject color into icon components
5887
5989
  const renderIconWithColor = (iconElement) => {
5888
5990
  if (!iconElement)
@@ -5983,14 +6085,14 @@ const Button = (allProps) => {
5983
6085
  },
5984
6086
  // subtle visual feedback beyond scale on supported platforms
5985
6087
  pressed && !isInteractionDisabled ? {
5986
- opacity: variant === 'ghost' || variant === 'none' ? 0.6 : 0.9,
6088
+ opacity: effectiveVariant === 'ghost' || effectiveVariant === 'none' ? 0.6 : 0.9,
5987
6089
  ...(Platform.OS !== 'web' ? { transform: [{ translateY: 1 }] } : {})
5988
6090
  } : null,
5989
6091
  style,
5990
6092
  { minWidth: calculatedMinWidth }
5991
- ], onPress: handleInternalPress, onLayout: onLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && jsx(LinearGradient$1, { colors: variant === 'gradient'
5992
- ? (resolvedCustomColor ? [resolvedCustomColor, theme.colors.primary[7]] : [theme.colors.primary[5], theme.colors.primary[7]])
5993
- : ['transparent', 'transparent'], style: { position: 'absolute', zIndex: -1, top: 0, left: 0, right: 0, bottom: 0, borderRadius: radiusStyles.borderRadius }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 } }), loading ? (jsxs(Fragment, { children: [jsx(Loader, { size: size, color: getLoaderColor(), style: !isIconButton ? { marginRight: iconSpacing } : undefined }), !isIconButton && renderButtonContent(displayContent)] })) : isIconButton ? (
6093
+ ], onPress: handleInternalPress, onLayout: onLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && hasLinearGradient$3 && (jsx(OptionalLinearGradient$4, { colors: resolvedCustomColor
6094
+ ? [resolvedCustomColor, theme.colors.primary[7]]
6095
+ : [theme.colors.primary[5], theme.colors.primary[7]], style: { position: 'absolute', zIndex: -1, top: 0, left: 0, right: 0, bottom: 0, borderRadius: radiusStyles.borderRadius }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 } })), loading ? (jsxs(Fragment, { children: [jsx(Loader, { size: size, color: getLoaderColor(), style: !isIconButton ? { marginRight: iconSpacing } : undefined }), !isIconButton && renderButtonContent(displayContent)] })) : isIconButton ? (
5994
6096
  // Icon-only button
5995
6097
  renderIconWithColor(icon)) : (
5996
6098
  // Regular button with text and optional side icons
@@ -6865,7 +6967,6 @@ const Flex = factory((props, ref) => {
6865
6967
  * Automatically mirrors to row-reverse in RTL
6866
6968
  */
6867
6969
  const Row$1 = React__default.forwardRef((props, ref) => {
6868
- // @ts-expect-error - factory components handle refs differently
6869
6970
  return jsx(Flex, { ...props, direction: "row", ref: ref });
6870
6971
  });
6871
6972
  Row$1.displayName = 'Row';
@@ -6874,7 +6975,6 @@ Row$1.displayName = 'Row';
6874
6975
  * Not affected by RTL (columns are vertical)
6875
6976
  */
6876
6977
  const Column$1 = React__default.forwardRef((props, ref) => {
6877
- // @ts-expect-error - factory components handle refs differently
6878
6978
  return jsx(Flex, { ...props, direction: "column", ref: ref });
6879
6979
  });
6880
6980
  Column$1.displayName = 'Column';
@@ -6931,6 +7031,280 @@ function useSimpleDialog() {
6931
7031
  };
6932
7032
  }
6933
7033
 
7034
+ const escapeRegExp$1 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7035
+ const toHighlightArray = (value, trim) => {
7036
+ if (value === undefined || value === null) {
7037
+ return [];
7038
+ }
7039
+ const rawValues = Array.isArray(value) ? value : [value];
7040
+ return rawValues
7041
+ .filter((item) => item !== undefined && item !== null)
7042
+ .map((item) => String(item))
7043
+ .map((item) => (trim ? item.trim() : item))
7044
+ .filter((item) => item.length > 0);
7045
+ };
7046
+ const flattenStyleArray = (style) => {
7047
+ if (!Array.isArray(style)) {
7048
+ return style ? [style] : [];
7049
+ }
7050
+ return style.reduce((acc, item) => {
7051
+ acc.push(...flattenStyleArray(item));
7052
+ return acc;
7053
+ }, []);
7054
+ };
7055
+ const extractColorFromStyle = (style) => {
7056
+ for (const entry of flattenStyleArray(style)) {
7057
+ if (entry && typeof entry === 'object' && typeof entry.color === 'string') {
7058
+ return entry.color;
7059
+ }
7060
+ }
7061
+ return undefined;
7062
+ };
7063
+ const parseColor = (value) => {
7064
+ if (!value || typeof value !== 'string') {
7065
+ return undefined;
7066
+ }
7067
+ const trimmed = value.trim();
7068
+ if (trimmed.startsWith('#')) {
7069
+ let hex = trimmed.slice(1);
7070
+ if (hex.length === 3) {
7071
+ hex = hex.split('').map(char => char + char).join('');
7072
+ }
7073
+ if (hex.length === 6) {
7074
+ const r = parseInt(hex.slice(0, 2), 16);
7075
+ const g = parseInt(hex.slice(2, 4), 16);
7076
+ const b = parseInt(hex.slice(4, 6), 16);
7077
+ if ([r, g, b].every(component => !Number.isNaN(component))) {
7078
+ return { r, g, b };
7079
+ }
7080
+ }
7081
+ if (hex.length === 8) {
7082
+ const r = parseInt(hex.slice(0, 2), 16);
7083
+ const g = parseInt(hex.slice(2, 4), 16);
7084
+ const b = parseInt(hex.slice(4, 6), 16);
7085
+ if ([r, g, b].every(component => !Number.isNaN(component))) {
7086
+ return { r, g, b };
7087
+ }
7088
+ }
7089
+ }
7090
+ const rgbMatch = trimmed.match(/^rgba?\(([^)]+)\)$/i);
7091
+ if (rgbMatch) {
7092
+ const parts = rgbMatch[1].split(',').map(part => part.trim()).slice(0, 3);
7093
+ if (parts.length === 3) {
7094
+ const [r, g, b] = parts.map(part => parseFloat(part));
7095
+ if ([r, g, b].every(component => !Number.isNaN(component))) {
7096
+ return { r: Math.round(r), g: Math.round(g), b: Math.round(b) };
7097
+ }
7098
+ }
7099
+ }
7100
+ return undefined;
7101
+ };
7102
+ const getRelativeLuminance = ({ r, g, b }) => {
7103
+ const srgb = [r, g, b].map(channel => {
7104
+ const normalized = channel / 255;
7105
+ return normalized <= 0.03928 ? normalized / 12.92 : Math.pow((normalized + 0.055) / 1.055, 2.4);
7106
+ });
7107
+ return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
7108
+ };
7109
+ const mixRgb = (color, target, weight) => ({
7110
+ r: Math.round(color.r * (1 - weight) + target.r * weight),
7111
+ g: Math.round(color.g * (1 - weight) + target.g * weight),
7112
+ b: Math.round(color.b * (1 - weight) + target.b * weight),
7113
+ });
7114
+ const toRgba$1 = ({ r, g, b }, alpha) => `rgba(${r}, ${g}, ${b}, ${alpha})`;
7115
+ const resolvePaletteShade = (palette, preferredIndex, fallbackIndex) => {
7116
+ if (!palette || palette.length === 0) {
7117
+ return undefined;
7118
+ }
7119
+ const safePreferred = palette[Math.min(Math.max(preferredIndex, 0), palette.length - 1)];
7120
+ if (safePreferred) {
7121
+ return safePreferred;
7122
+ }
7123
+ return palette[Math.min(Math.max(fallbackIndex, 0), palette.length - 1)];
7124
+ };
7125
+ const createAdaptiveBackground = (baseColor, isTextLight, colorScheme) => {
7126
+ const rgb = parseColor(baseColor);
7127
+ if (!rgb) {
7128
+ return baseColor;
7129
+ }
7130
+ const target = isTextLight ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 };
7131
+ const mixAmount = isTextLight ? (colorScheme === 'dark' ? 0.4 : 0.3) : (colorScheme === 'dark' ? 0.25 : 0.15);
7132
+ const alpha = isTextLight ? (colorScheme === 'dark' ? 0.7 : 0.8) : (colorScheme === 'dark' ? 0.55 : 0.88);
7133
+ const mixed = mixRgb(rgb, target, mixAmount);
7134
+ return toRgba$1(mixed, alpha);
7135
+ };
7136
+ const resolveHighlightBackground = (theme, highlightColor, isTextLight) => {
7137
+ var _a;
7138
+ const themeColors = theme.colors;
7139
+ const paletteFromProp = highlightColor ? themeColors[highlightColor] : undefined;
7140
+ const defaultPalette = theme.colors.highlight || theme.colors.amber || theme.colors.primary;
7141
+ const preferredPalette = paletteFromProp || defaultPalette;
7142
+ const highlightStateColor = (_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightBackground;
7143
+ let baseColor = paletteFromProp
7144
+ ? resolvePaletteShade(paletteFromProp, isTextLight ? 8 : 2, isTextLight ? 7 : 3)
7145
+ : undefined;
7146
+ if (!baseColor && highlightColor && !paletteFromProp) {
7147
+ baseColor = highlightColor;
7148
+ }
7149
+ if (!baseColor && highlightStateColor) {
7150
+ baseColor = highlightStateColor;
7151
+ }
7152
+ if (!baseColor && preferredPalette) {
7153
+ baseColor = resolvePaletteShade(preferredPalette, isTextLight ? 8 : 2, isTextLight ? 7 : 3);
7154
+ }
7155
+ if (!baseColor) {
7156
+ baseColor = isTextLight ? '#92400E' : '#FDE68A';
7157
+ }
7158
+ return createAdaptiveBackground(baseColor, isTextLight, theme.colorScheme);
7159
+ };
7160
+ const createBaseHighlightStyle = (theme, backgroundColor, textColor, includeColor) => ({
7161
+ backgroundColor,
7162
+ ...(includeColor ? { color: textColor } : {}),
7163
+ borderRadius: 4,
7164
+ paddingHorizontal: 4,
7165
+ paddingVertical: Platform.OS === 'web' ? 0 : 2,
7166
+ });
7167
+ const Highlight = ({ children, highlight, highlightStyles, highlightColor, caseSensitive = false, trim = true, highlightProps, variant, ...rest }) => {
7168
+ var _a, _b;
7169
+ const theme = useTheme();
7170
+ const outerVariant = variant !== null && variant !== void 0 ? variant : 'span';
7171
+ const textContent = useMemo(() => {
7172
+ if (typeof children === 'string' || typeof children === 'number') {
7173
+ return String(children);
7174
+ }
7175
+ const parts = React__default.Children.toArray(children);
7176
+ if (parts.length === 0) {
7177
+ return '';
7178
+ }
7179
+ if (parts.every((part) => typeof part === 'string' || typeof part === 'number')) {
7180
+ return parts.map((part) => String(part)).join('');
7181
+ }
7182
+ return null;
7183
+ }, [children]);
7184
+ const highlightValues = useMemo(() => toHighlightArray(highlight, trim), [highlight, trim]);
7185
+ const highlightPropsValue = useMemo(() => highlightProps !== null && highlightProps !== void 0 ? highlightProps : {}, [highlightProps]);
7186
+ const highlightDerived = useMemo(() => {
7187
+ var _a, _b;
7188
+ const { style, as, variant: innerVariant, color: colorProp, ...restProps } = highlightPropsValue;
7189
+ return {
7190
+ style,
7191
+ color: colorProp,
7192
+ as: (_a = as) !== null && _a !== void 0 ? _a : (Platform.OS === 'web' ? 'mark' : 'span'),
7193
+ variant: (_b = innerVariant) !== null && _b !== void 0 ? _b : 'span',
7194
+ rest: restProps,
7195
+ };
7196
+ }, [highlightPropsValue]);
7197
+ const outerColor = useMemo(() => {
7198
+ const restProps = rest;
7199
+ if ((restProps === null || restProps === void 0 ? void 0 : restProps.color) && typeof restProps.color === 'string') {
7200
+ return restProps.color;
7201
+ }
7202
+ const colorVariantKey = restProps === null || restProps === void 0 ? void 0 : restProps.colorVariant;
7203
+ if (typeof colorVariantKey === 'string') {
7204
+ const fromText = theme.text[colorVariantKey];
7205
+ if (fromText) {
7206
+ return fromText;
7207
+ }
7208
+ const palette = theme.colors[colorVariantKey];
7209
+ const paletteColor = resolvePaletteShade(palette, 6, palette ? palette.length - 1 : 6);
7210
+ if (paletteColor) {
7211
+ return paletteColor;
7212
+ }
7213
+ }
7214
+ return extractColorFromStyle(restProps === null || restProps === void 0 ? void 0 : restProps.style);
7215
+ }, [rest, theme]);
7216
+ const fallbackTextColor = (_b = (_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightText) !== null && _b !== void 0 ? _b : theme.text.primary;
7217
+ const { resolvedTextColor, isTextColorLight } = useMemo(() => {
7218
+ var _a, _b;
7219
+ const candidate = (_b = (_a = highlightDerived.color) !== null && _a !== void 0 ? _a : outerColor) !== null && _b !== void 0 ? _b : fallbackTextColor;
7220
+ const parsedCandidate = parseColor(candidate);
7221
+ if (parsedCandidate) {
7222
+ return {
7223
+ resolvedTextColor: candidate,
7224
+ isTextColorLight: getRelativeLuminance(parsedCandidate) > 0.6,
7225
+ };
7226
+ }
7227
+ const parsedFallback = parseColor(fallbackTextColor);
7228
+ if (parsedFallback) {
7229
+ return {
7230
+ resolvedTextColor: fallbackTextColor,
7231
+ isTextColorLight: getRelativeLuminance(parsedFallback) > 0.6,
7232
+ };
7233
+ }
7234
+ return {
7235
+ resolvedTextColor: candidate !== null && candidate !== void 0 ? candidate : fallbackTextColor,
7236
+ isTextColorLight: theme.colorScheme === 'dark',
7237
+ };
7238
+ }, [highlightDerived.color, outerColor, fallbackTextColor, theme.colorScheme]);
7239
+ const highlightBackground = useMemo(() => resolveHighlightBackground(theme, highlightColor, isTextColorLight), [theme, highlightColor, isTextColorLight]);
7240
+ const highlightColorProp = highlightDerived.color;
7241
+ const baseHighlightStyle = useMemo(() => createBaseHighlightStyle(theme, highlightBackground, resolvedTextColor, !highlightColorProp), [theme, highlightBackground, resolvedTextColor, highlightColorProp]);
7242
+ const overrideHighlightStyle = useMemo(() => (typeof highlightStyles === 'function' ? highlightStyles(theme) : highlightStyles), [highlightStyles, theme]);
7243
+ const highlightNodeStyle = useMemo(() => StyleSheet.flatten([
7244
+ baseHighlightStyle,
7245
+ overrideHighlightStyle,
7246
+ highlightDerived.style,
7247
+ ]), [baseHighlightStyle, overrideHighlightStyle, highlightDerived.style]);
7248
+ const highlightVariant = highlightDerived.variant;
7249
+ const highlightAs = highlightDerived.as;
7250
+ const highlightRest = highlightDerived.rest;
7251
+ const highlightRegex = useMemo(() => {
7252
+ if (textContent === null || highlightValues.length === 0) {
7253
+ return null;
7254
+ }
7255
+ const escaped = highlightValues
7256
+ .map((value) => escapeRegExp$1(value))
7257
+ .filter((value) => value.length > 0)
7258
+ .sort((a, b) => b.length - a.length);
7259
+ if (escaped.length === 0) {
7260
+ return null;
7261
+ }
7262
+ return new RegExp(`(${escaped.join('|')})`, caseSensitive ? 'g' : 'gi');
7263
+ }, [textContent, highlightValues, caseSensitive]);
7264
+ const highlightNormalizedSet = useMemo(() => {
7265
+ if (caseSensitive) {
7266
+ return new Set(highlightValues);
7267
+ }
7268
+ return new Set(highlightValues.map((value) => value.toLowerCase()));
7269
+ }, [highlightValues, caseSensitive]);
7270
+ const renderedChildren = useMemo(() => {
7271
+ if (textContent === null) {
7272
+ return children;
7273
+ }
7274
+ if (!highlightRegex || highlightValues.length === 0) {
7275
+ return textContent;
7276
+ }
7277
+ const segments = textContent.split(highlightRegex);
7278
+ if (segments.length <= 1) {
7279
+ return textContent;
7280
+ }
7281
+ return segments.map((segment, index) => {
7282
+ if (!segment) {
7283
+ return null;
7284
+ }
7285
+ const normalizedSegment = caseSensitive ? segment : segment.toLowerCase();
7286
+ if (highlightNormalizedSet.has(normalizedSegment)) {
7287
+ return (jsx(Text, { variant: highlightVariant, as: highlightAs, color: highlightColorProp, ...highlightRest, style: highlightNodeStyle, children: segment }, `highlight-${index}`));
7288
+ }
7289
+ return (jsx(React__default.Fragment, { children: segment }, `text-${index}`));
7290
+ }).filter((item) => item !== null);
7291
+ }, [
7292
+ children,
7293
+ textContent,
7294
+ highlightRegex,
7295
+ highlightValues,
7296
+ caseSensitive,
7297
+ highlightNormalizedSet,
7298
+ highlightVariant,
7299
+ highlightAs,
7300
+ highlightRest,
7301
+ highlightNodeStyle,
7302
+ highlightColorProp,
7303
+ ]);
7304
+ return (jsx(Text, { variant: outerVariant, ...rest, children: renderedChildren }));
7305
+ };
7306
+ Highlight.displayName = 'Highlight';
7307
+
6934
7308
  function isAction(item) {
6935
7309
  return 'id' in item && 'label' in item;
6936
7310
  }
@@ -7349,7 +7723,7 @@ function SpotlightActionsList({ children, scrollable = true, maxHeight, style, s
7349
7723
  // Always use ScrollView for consistent behavior
7350
7724
  return (jsx(ScrollView, { ref: scrollRef, style: [containerStyle, { maxHeight: calculatedMaxHeight }], showsVerticalScrollIndicator: true, onScroll: onScrollChange ? (e) => onScrollChange(e.nativeEvent.contentOffset.y) : undefined, scrollEventThrottle: 16, contentContainerStyle: undefined, children: children }));
7351
7725
  }
7352
- function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled = false, selected = false, children, style, innerRef, }) {
7726
+ function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled = false, selected = false, children, style, innerRef, highlightQuery, }) {
7353
7727
  const theme = useTheme();
7354
7728
  const [isHovered, setIsHovered] = React__default.useState(false);
7355
7729
  // Truncate long descriptions for cleaner list appearance
@@ -7402,7 +7776,7 @@ function SpotlightAction({ label, description, leftSection, rightSection, onPres
7402
7776
  !selected && pressed && pressedStyle,
7403
7777
  !selected && !pressed && isHovered && hoverStyle,
7404
7778
  style,
7405
- ], ...webHoverProps, children: jsxs(Block, { direction: "row", align: "center", style: styles$c.actionContent, children: [leftSection && (jsx(View, { style: styles$c.actionLeftSection, children: leftSection })), jsxs(Block, { direction: "column", style: { flex: 1 }, children: [jsx(Text, { weight: "500", children: label }), truncatedDescription ? (jsx(Text, { variant: "small", children: truncatedDescription })) : null, children] }), rightSection ? (jsx(View, { style: styles$c.actionRightSection, children: rightSection })) : null] }) }));
7779
+ ], ...webHoverProps, children: jsxs(Block, { direction: "row", align: "center", style: styles$c.actionContent, children: [leftSection && (jsx(View, { style: styles$c.actionLeftSection, children: leftSection })), jsxs(Block, { direction: "column", style: { flex: 1 }, children: [jsx(Highlight, { highlight: highlightQuery, style: styles$c.actionLabel, highlightProps: { style: styles$c.actionLabel }, children: label }), truncatedDescription ? (jsx(Highlight, { highlight: highlightQuery, style: styles$c.actionDescription, highlightProps: { style: styles$c.actionDescription }, children: truncatedDescription })) : null, children] }), rightSection ? (jsx(View, { style: styles$c.actionRightSection, children: rightSection })) : null] }) }));
7406
7780
  }
7407
7781
  function SpotlightActionsGroup({ label, children, style, }) {
7408
7782
  const theme = useTheme();
@@ -7420,7 +7794,7 @@ function SpotlightEmpty({ children, style }) {
7420
7794
  return (jsx(View, { style: [styles$c.empty, style], children: jsx(Text, { size: "md", color: theme.text.secondary, style: styles$c.emptyText, children: children }) }));
7421
7795
  }
7422
7796
  // Main Spotlight component
7423
- function Spotlight({ actions, nothingFound = 'Nothing found...', highlightQuery = false, limit, scrollable = false, maxHeight, // Remove default - let it be calculated dynamically
7797
+ function Spotlight({ actions, nothingFound = 'Nothing found...', highlightQuery = true, limit, scrollable = false, maxHeight, // Remove default - let it be calculated dynamically
7424
7798
  shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', width = 600, height, }) {
7425
7799
  const spotlightStore = useSpotlightStore();
7426
7800
  // Set as default store if no custom store provided
@@ -7441,6 +7815,23 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
7441
7815
  }, [shouldHandleToggleHotkey, currentStore]);
7442
7816
  useGlobalHotkeys('spotlight-toggle', ['mod+k', handleToggleHotkey]);
7443
7817
  const filteredActions = filterActions(actions, query, limit);
7818
+ const highlightValue = React__default.useMemo(() => {
7819
+ if (!highlightQuery) {
7820
+ return undefined;
7821
+ }
7822
+ if (highlightQuery !== true) {
7823
+ return highlightQuery;
7824
+ }
7825
+ const trimmed = query.trim();
7826
+ if (!trimmed) {
7827
+ return undefined;
7828
+ }
7829
+ const parts = trimmed.split(/\s+/).filter(Boolean);
7830
+ if (parts.length === 0) {
7831
+ return undefined;
7832
+ }
7833
+ return parts.length === 1 ? parts[0] : parts;
7834
+ }, [highlightQuery, query]);
7444
7835
  // Flatten all actions for keyboard navigation
7445
7836
  const flatActions = React__default.useMemo(() => {
7446
7837
  const flat = [];
@@ -7568,7 +7959,7 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
7568
7959
  if (isAction(item)) {
7569
7960
  const isSelected = flatIndex === selectedIndex;
7570
7961
  flatIndex++; // Increment after checking
7571
- return (jsx(SpotlightAction, { label: item.label, description: item.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, leftSection: typeof item.icon === 'string' ? (jsx(Icon, { name: item.icon, size: "md", color: "pink" })) : (item.icon), onPress: () => {
7962
+ return (jsx(SpotlightAction, { label: item.label, description: item.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, highlightQuery: highlightValue, leftSection: typeof item.icon === 'string' ? (jsx(Icon, { name: item.icon, size: "md", color: "pink" })) : (item.icon), onPress: () => {
7572
7963
  var _a;
7573
7964
  (_a = item.onPress) === null || _a === void 0 ? void 0 : _a.call(item);
7574
7965
  currentStore.close();
@@ -7578,7 +7969,7 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
7578
7969
  return (jsx(SpotlightActionsGroup, { label: item.group, children: item.actions.map((action) => {
7579
7970
  const isSelected = flatIndex === selectedIndex;
7580
7971
  flatIndex++; // Increment after checking
7581
- return (jsx(SpotlightAction, { label: action.label, description: action.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, leftSection: typeof action.icon === 'string' ? (jsx(Icon, { name: action.icon, size: "md" })) : (action.icon), onPress: () => {
7972
+ return (jsx(SpotlightAction, { label: action.label, description: action.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, highlightQuery: highlightValue, leftSection: typeof action.icon === 'string' ? (jsx(Icon, { name: action.icon, size: "md" })) : (action.icon), onPress: () => {
7582
7973
  var _a;
7583
7974
  (_a = action.onPress) === null || _a === void 0 ? void 0 : _a.call(action);
7584
7975
  currentStore.close();
@@ -7728,27 +8119,27 @@ class DirectSpotlightStateManager {
7728
8119
  return { ...this.state };
7729
8120
  }
7730
8121
  setState(updates) {
7731
- console.log('[DirectSpotlightStateManager] Setting state:', updates, 'from:', this.state);
8122
+ // console.log('[DirectSpotlightStateManager] Setting state:', updates, 'from:', this.state);
7732
8123
  this.state = { ...this.state, ...updates };
7733
8124
  this.notifyListeners();
7734
8125
  }
7735
8126
  open(query) {
7736
- console.log('[DirectSpotlightStateManager] Opening spotlight');
8127
+ // console.log('[DirectSpotlightStateManager] Opening spotlight');
7737
8128
  this.setState({
7738
8129
  opened: true,
7739
8130
  ...(query !== undefined && { query })
7740
8131
  });
7741
8132
  }
7742
8133
  close() {
7743
- console.log('[DirectSpotlightStateManager] Closing spotlight');
8134
+ // console.log('[DirectSpotlightStateManager] Closing spotlight');
7744
8135
  this.setState({ opened: false, query: '', selectedIndex: -1 });
7745
8136
  }
7746
8137
  setQuery(query) {
7747
- console.log('[DirectSpotlightStateManager] Setting query:', query);
8138
+ // console.log('[DirectSpotlightStateManager] Setting query:', query);
7748
8139
  this.setState({ query });
7749
8140
  }
7750
8141
  toggle() {
7751
- console.log('[DirectSpotlightStateManager] Toggling spotlight');
8142
+ // console.log('[DirectSpotlightStateManager] Toggling spotlight');
7752
8143
  this.setState({ opened: !this.state.opened });
7753
8144
  }
7754
8145
  subscribe(listener) {
@@ -7774,7 +8165,7 @@ const directSpotlightStateManager = new DirectSpotlightStateManager();
7774
8165
  function useDirectSpotlightState() {
7775
8166
  const [state, setState] = useState(() => {
7776
8167
  const globalState = directSpotlightStateManager.getState();
7777
- console.log('[useDirectSpotlightState] Initializing with:', globalState);
8168
+ // console.log('[useDirectSpotlightState] Initializing with:', globalState);
7778
8169
  return {
7779
8170
  opened: globalState.opened,
7780
8171
  query: globalState.query,
@@ -7782,9 +8173,9 @@ function useDirectSpotlightState() {
7782
8173
  };
7783
8174
  });
7784
8175
  useEffect(() => {
7785
- console.log('[useDirectSpotlightState] Setting up subscription');
8176
+ // console.log('[useDirectSpotlightState] Setting up subscription');
7786
8177
  const unsubscribe = directSpotlightStateManager.subscribe((globalState) => {
7787
- console.log('[useDirectSpotlightState] Global state changed:', globalState);
8178
+ // console.log('[useDirectSpotlightState] Global state changed:', globalState);
7788
8179
  setState({
7789
8180
  opened: globalState.opened,
7790
8181
  query: globalState.query,
@@ -7793,14 +8184,14 @@ function useDirectSpotlightState() {
7793
8184
  });
7794
8185
  // Sync with current state
7795
8186
  const currentState = directSpotlightStateManager.getState();
7796
- console.log('[useDirectSpotlightState] Syncing with current state:', currentState);
8187
+ // console.log('[useDirectSpotlightState] Syncing with current state:', currentState);
7797
8188
  setState({
7798
8189
  opened: currentState.opened,
7799
8190
  query: currentState.query,
7800
8191
  selectedIndex: currentState.selectedIndex
7801
8192
  });
7802
8193
  return () => {
7803
- console.log('[useDirectSpotlightState] Cleaning up subscription');
8194
+ // console.log('[useDirectSpotlightState] Cleaning up subscription');
7804
8195
  unsubscribe();
7805
8196
  };
7806
8197
  }, []);
@@ -9325,10 +9716,9 @@ const useTitleRegistration = (options) => {
9325
9716
  return { elementRef, id };
9326
9717
  };
9327
9718
 
9328
- // Mock LinearGradient for now - in a real app you'd use expo-linear-gradient or react-native-linear-gradient
9329
- const LinearGradient = ({ children, style, ...props }) => (jsx(View, { style: [style, { backgroundColor: props.colors[0] }], children: children }));
9719
+ const { LinearGradient: OptionalLinearGradient$3, hasLinearGradient: hasLinearGradient$2 } = resolveLinearGradient();
9330
9720
  function Container(props) {
9331
- var _a, _b;
9721
+ var _a, _b, _c, _d;
9332
9722
  const theme = useTheme();
9333
9723
  // Extract spacing props and other props
9334
9724
  const { spacingProps, otherProps } = extractSpacingProps(props);
@@ -9359,7 +9749,10 @@ function Container(props) {
9359
9749
  opacity: (_b = backgroundImage.overlay.opacity) !== null && _b !== void 0 ? _b : 0.3,
9360
9750
  }
9361
9751
  : {};
9362
- return (jsxs(ImageBackground, { source: { uri: backgroundImage.uri }, style: containerStyle, imageStyle: imageStyle, resizeMode: "cover", children: [backgroundImage.overlay && jsx(View, { style: overlayStyle }), backgroundImage.gradient && (jsx(LinearGradient, { colors: backgroundImage.gradient.colors, locations: backgroundImage.gradient.locations, start: backgroundImage.gradient.start || { x: 0, y: 0 }, end: backgroundImage.gradient.end || { x: 0, y: 1 }, style: StyleSheet.absoluteFillObject })), children] }));
9752
+ return (jsxs(ImageBackground, { source: { uri: backgroundImage.uri }, style: containerStyle, imageStyle: imageStyle, resizeMode: "cover", children: [backgroundImage.overlay && jsx(View, { style: overlayStyle }), backgroundImage.gradient && (hasLinearGradient$2 ? (jsx(OptionalLinearGradient$3, { colors: backgroundImage.gradient.colors, locations: backgroundImage.gradient.locations, start: backgroundImage.gradient.start || { x: 0, y: 0 }, end: backgroundImage.gradient.end || { x: 0, y: 1 }, style: StyleSheet.absoluteFillObject })) : (jsx(View, { style: [
9753
+ StyleSheet.absoluteFillObject,
9754
+ { backgroundColor: (_d = (_c = backgroundImage.gradient.colors) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : 'transparent' },
9755
+ ] }))), children] }));
9363
9756
  }
9364
9757
 
9365
9758
  const Grid = factory((props, ref) => {
@@ -10491,6 +10884,7 @@ const Column = ({ direction = 'column', gap = 'sm', ...props }) => {
10491
10884
  };
10492
10885
  Row.displayName = 'Row';
10493
10886
 
10887
+ const { LinearGradient: OptionalLinearGradient$2, hasLinearGradient: hasLinearGradient$1 } = resolveLinearGradient();
10494
10888
  /**
10495
10889
  * GradientText Component
10496
10890
  *
@@ -10680,6 +11074,9 @@ const GradientText = React__default.forwardRef(({ children, colors, locations, a
10680
11074
  return (jsx(Text, { ...textProps, children: children }));
10681
11075
  }
10682
11076
  // Web-specific gradient implementation with animation
11077
+ if (!hasLinearGradient$1) {
11078
+ return (jsx(View, { ref: ref, testID: testID, style: styles$b.container, children: jsx(Text, { ...textProps, children: children }) }));
11079
+ }
10683
11080
  if (isWeb) {
10684
11081
  return (jsx(View, { ref: containerRef, "data-testid": testID, style: { display: 'inline-block' }, children: jsx(Text, { ...textProps, "data-text-inner": "true", children: children }) }));
10685
11082
  }
@@ -10693,7 +11090,7 @@ const GradientText = React__default.forwardRef(({ children, colors, locations, a
10693
11090
  const gradientLocations = colorLocations.length >= 2
10694
11091
  ? colorLocations
10695
11092
  : [0, 1];
10696
- return (jsx(MaskedView, { ref: ref, testID: testID, style: styles$b.container, maskElement: jsx(View, { style: styles$b.maskContainer, children: jsx(Text, { ...textProps, style: [textProps.style, styles$b.maskText], children: children }) }), children: jsx(LinearGradient$1, { colors: gradientColors, locations: gradientLocations, start: gradientStart, end: gradientEnd, style: styles$b.gradient, children: jsx(Text, { ...textProps, style: [textProps.style, styles$b.transparentText], children: children }) }) }));
11093
+ return (jsx(MaskedView, { ref: ref, testID: testID, style: styles$b.container, maskElement: jsx(View, { style: styles$b.maskContainer, children: jsx(Text, { ...textProps, style: [textProps.style, styles$b.maskText], children: children }) }), children: jsx(OptionalLinearGradient$2, { colors: gradientColors, locations: gradientLocations, start: gradientStart, end: gradientEnd, style: styles$b.gradient, children: jsx(Text, { ...textProps, style: [textProps.style, styles$b.transparentText], children: children }) }) }));
10697
11094
  });
10698
11095
  GradientText.displayName = 'GradientText';
10699
11096
  const styles$b = StyleSheet.create({
@@ -10739,6 +11136,7 @@ const styles$a = StyleSheet.create({
10739
11136
  height: '100%',
10740
11137
  },
10741
11138
  });
11139
+ const { LinearGradient: OptionalLinearGradient$1} = resolveLinearGradient();
10742
11140
  const stripColorFromStyle = (styleValue) => {
10743
11141
  if (!styleValue) {
10744
11142
  return styleValue;
@@ -10808,10 +11206,13 @@ function ShimmerText(props) {
10808
11206
  const { spacingProps, otherProps } = extractSpacingProps(props);
10809
11207
  const spacingStyles = getSpacingStyles(spacingProps);
10810
11208
  const { children, text, color: baseColor = '#999999', colors, shimmerColor, duration = 1.8, delay = 0, repeatDelay = 0, repeat = true, once = false, direction = 'ltr', spread = 2, debug = false, onLayout: externalOnLayout, style, ...textProps } = otherProps;
11209
+ const isWeb = Platform.OS === 'web';
11210
+ const gradientModuleAvailable = Boolean(OptionalLinearGradient$1);
10811
11211
  const content = (_a = children !== null && children !== void 0 ? children : text) !== null && _a !== void 0 ? _a : null;
10812
11212
  const normalizedSpread = Math.max(spread, MIN_SPREAD);
10813
11213
  const shouldRepeat = repeat && !once;
10814
- const shouldAnimate = once || shouldRepeat;
11214
+ const supportsShimmer = isWeb || gradientModuleAvailable;
11215
+ const shouldAnimate = supportsShimmer && (once || shouldRepeat);
10815
11216
  const extraDistance = normalizedSpread - 1;
10816
11217
  const minPosition = -extraDistance;
10817
11218
  const maxPosition = 1 + extraDistance;
@@ -10822,7 +11223,6 @@ function ShimmerText(props) {
10822
11223
  const debugFlag = useSharedValue(debug ? 1 : 0);
10823
11224
  const startX = useSharedValue(0);
10824
11225
  const endX = useSharedValue(0);
10825
- const isWeb = Platform.OS === 'web';
10826
11226
  const [layout, setLayout] = useState({ width: 0, height: 0 });
10827
11227
  const [gradientWidth, setGradientWidth] = useState(0);
10828
11228
  const mountCountRef = useRef(0);
@@ -10855,7 +11255,7 @@ function ShimmerText(props) {
10855
11255
  console.log(`[ShimmerText] ${message}`);
10856
11256
  }, [debug]);
10857
11257
  useEffect(() => {
10858
- if (isWeb) {
11258
+ if (isWeb || !gradientModuleAvailable) {
10859
11259
  return;
10860
11260
  }
10861
11261
  mountCountRef.current += 1;
@@ -10898,7 +11298,7 @@ function ShimmerText(props) {
10898
11298
  logEvent('cleanup -> cancel animation');
10899
11299
  cancelAnimation(progress);
10900
11300
  };
10901
- }, [delay, duration, repeat, once, repeatDelay, progress, logEvent, debugFlag, isWeb, shouldAnimate, shouldRepeat]);
11301
+ }, [delay, duration, repeat, once, repeatDelay, progress, logEvent, debugFlag, isWeb, shouldAnimate, shouldRepeat, gradientModuleAvailable]);
10902
11302
  const handleLayout = useCallback((event) => {
10903
11303
  const { width, height } = event.nativeEvent.layout;
10904
11304
  setLayout((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));
@@ -10984,6 +11384,9 @@ function ShimmerText(props) {
10984
11384
  };
10985
11385
  }, [isWeb, shouldAnimate, shouldRepeat, duration, delay, repeatDelay, direction, initialWebPosition, finalWebPosition, maxPosition, positionRange, minPosition]);
10986
11386
  const renderNative = () => {
11387
+ if (!gradientModuleAvailable || !OptionalLinearGradient$1) {
11388
+ return (jsx(Text, { ...textProps, color: baseColor, onLayout: externalOnLayout, style: style, children: content }));
11389
+ }
10987
11390
  if (layout.width === 0 || layout.height === 0) {
10988
11391
  return (jsx(Text, { ...textProps, color: baseColor, onLayout: handleLayout, style: style, children: content }));
10989
11392
  }
@@ -10996,7 +11399,7 @@ function ShimmerText(props) {
10996
11399
  height: layout.height,
10997
11400
  },
10998
11401
  gradientAnimatedStyle,
10999
- ], children: jsx(LinearGradient$1, { colors: resolvedColors, locations: gradientLocations, start: { x: direction === 'rtl' ? 1 : 0, y: 0.5 }, end: { x: direction === 'rtl' ? 0 : 1, y: 0.5 }, style: styles$a.linearGradient }) }) }) })] }));
11402
+ ], children: jsx(OptionalLinearGradient$1, { colors: resolvedColors, locations: gradientLocations, start: { x: direction === 'rtl' ? 1 : 0, y: 0.5 }, end: { x: direction === 'rtl' ? 0 : 1, y: 0.5 }, style: styles$a.linearGradient }) }) }) })] }));
11000
11403
  };
11001
11404
  const renderWeb = () => {
11002
11405
  var _a;
@@ -11117,6 +11520,7 @@ const Heading4 = (props) => jsx(Title, { order: 4, ...props });
11117
11520
  const Heading5 = (props) => jsx(Title, { order: 5, ...props });
11118
11521
  const Heading6 = (props) => jsx(Title, { order: 6, ...props });
11119
11522
 
11523
+ const { LinearGradient: OptionalLinearGradient, hasLinearGradient } = resolveLinearGradient();
11120
11524
  const getIconButtonStyles = (theme, variant = 'filled', size = 'md', disabled = false, loading = false, height, radiusStyles, shadowStyles, customColor) => {
11121
11525
  const baseStyles = {
11122
11526
  flexDirection: 'row',
@@ -11281,6 +11685,7 @@ const IconButton = (allProps) => {
11281
11685
  ...restProps } = otherProps;
11282
11686
  const theme = useTheme();
11283
11687
  const { impactPressIn, impactPressOut } = useHaptics$1();
11688
+ const effectiveVariant = variant === 'gradient' && !hasLinearGradient ? 'filled' : variant;
11284
11689
  // Animation values
11285
11690
  const scaleAnim = useRef(new Animated$1.Value(1)).current;
11286
11691
  const [isPressed, setIsPressed] = useState(false);
@@ -11291,9 +11696,9 @@ const IconButton = (allProps) => {
11291
11696
  // Create shadow styles
11292
11697
  const shadowStyles = getShadowStyles(shadowProps, theme);
11293
11698
  // Get button styles
11294
- const buttonStyles = useMemo(() => getIconButtonStyles(theme, variant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant), [theme, variant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant]);
11699
+ const buttonStyles = useMemo(() => getIconButtonStyles(theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant), [theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant]);
11295
11700
  // Get icon color
11296
- const resolvedIconColor = useMemo(() => getIconColor(theme, variant, colorVariant, iconColor), [theme, variant, colorVariant, iconColor]);
11701
+ const resolvedIconColor = useMemo(() => getIconColor(theme, effectiveVariant, colorVariant, iconColor), [theme, effectiveVariant, colorVariant, iconColor]);
11297
11702
  // Get icon size
11298
11703
  const resolvedIconSize = iconSize || getDefaultIconSize(size);
11299
11704
  const handlePressIn = () => {
@@ -11334,7 +11739,7 @@ const IconButton = (allProps) => {
11334
11739
  getLayoutStyles(layoutProps),
11335
11740
  { transform: [{ scale: scaleAnim }] },
11336
11741
  style,
11337
- ], children: variant === 'gradient' ? (jsx(LinearGradient$1, { colors: [theme.colors.primary[4], theme.colors.primary[6]], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: [buttonStyles, { borderWidth: 0 }], children: jsx(Pressable, { onPress: handlePress, onPressIn: handlePressIn, onPressOut: handlePressOut, onLayout: onLayout, disabled: disabled || loading, style: {
11742
+ ], children: variant === 'gradient' && hasLinearGradient ? (jsx(OptionalLinearGradient, { colors: [theme.colors.primary[4], theme.colors.primary[6]], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: [buttonStyles, { borderWidth: 0 }], children: jsx(Pressable, { onPress: handlePress, onPressIn: handlePressIn, onPressOut: handlePressOut, onLayout: onLayout, disabled: disabled || loading, style: {
11338
11743
  width: '100%',
11339
11744
  height: '100%',
11340
11745
  alignItems: 'center',
@@ -11345,9 +11750,9 @@ const IconButton = (allProps) => {
11345
11750
  }, testID: testID, ...restProps, children: renderContent() }) })) : (jsx(Pressable, { onPress: handlePress, onPressIn: handlePressIn, onPressOut: handlePressOut, onLayout: onLayout, disabled: disabled || loading, style: [
11346
11751
  buttonStyles,
11347
11752
  isPressed && !disabled && !loading && {
11348
- backgroundColor: variant === 'filled'
11753
+ backgroundColor: effectiveVariant === 'filled'
11349
11754
  ? theme.colors.primary[6]
11350
- : variant === 'secondary'
11755
+ : effectiveVariant === 'secondary'
11351
11756
  ? theme.colors.gray[2]
11352
11757
  : buttonStyles.backgroundColor,
11353
11758
  },
@@ -11393,7 +11798,8 @@ const getSeverityColor$1 = (severity) => {
11393
11798
  }
11394
11799
  };
11395
11800
  function ToastBase(props, ref) {
11396
- const { variant = 'filled', color = 'gray', sev, title, children, icon, withCloseButton = true, loading = false, closeButtonLabel = 'Close notification', onClose, visible = false, animationDuration = 300, autoHide = 4000, position = 'top', style, testID, radius, actions, dismissOnTap = false, maxWidth, persistent = false, animationConfig, swipeConfig, onSwipeDismiss, ...rest } = props;
11801
+ var _a, _b, _c;
11802
+ const { variant = 'filled', color = 'gray', sev, title, children, icon, withCloseButton = true, loading = false, closeButtonLabel = 'Close notification', onClose, visible = false, animationDuration = 300, autoHide = 4000, position = 'top', style, testID, radius, actions, dismissOnTap = false, maxWidth, persistent = false, animationConfig, swipeConfig, onSwipeDismiss, keepMounted = true, ...rest } = props;
11397
11803
  const { spacingProps, otherProps } = extractSpacingProps(rest);
11398
11804
  const spacingStyles = getSpacingStyles(spacingProps);
11399
11805
  const theme = useTheme();
@@ -11456,7 +11862,13 @@ function ToastBase(props, ref) {
11456
11862
  return { finalColor, isThemeColor, colorConfig };
11457
11863
  }, [sev, color, theme.colors]);
11458
11864
  const { finalColor, isThemeColor, colorConfig } = memoizedColors;
11459
- const [shouldRender, setShouldRender] = React__default.useState(visible);
11865
+ const shouldUnmountOnHide = !keepMounted;
11866
+ const [shouldRender, setShouldRender] = React__default.useState(shouldUnmountOnHide ? visible : true);
11867
+ useEffect(() => {
11868
+ if (!shouldUnmountOnHide) {
11869
+ setShouldRender(true);
11870
+ }
11871
+ }, [shouldUnmountOnHide]);
11460
11872
  const transformProperty = React__default.useMemo(() => (position === 'left' || position === 'right' ? 'translateX' : 'translateY'), [position]);
11461
11873
  // Animation styles
11462
11874
  const animatedStyle = useAnimatedStyle(() => {
@@ -11485,7 +11897,10 @@ function ToastBase(props, ref) {
11485
11897
  opacity: fadeAnimation.value,
11486
11898
  };
11487
11899
  }, [transformProperty, screenWidth, finalSwipeConfig, finalAnimationConfig]);
11488
- const { notifySuccess, notifyWarning, notifyError } = useHaptics$1();
11900
+ const haptics = useHaptics$1();
11901
+ const notifySuccess = (_a = haptics.notifySuccess) !== null && _a !== void 0 ? _a : (() => { });
11902
+ const notifyWarning = (_b = haptics.notifyWarning) !== null && _b !== void 0 ? _b : (() => { });
11903
+ const notifyError = (_c = haptics.notifyError) !== null && _c !== void 0 ? _c : (() => { });
11489
11904
  // Improved haptic feedback with error handling
11490
11905
  const triggerHapticFeedback = React__default.useCallback((severity) => {
11491
11906
  try {
@@ -11572,7 +11987,9 @@ function ToastBase(props, ref) {
11572
11987
  }, []);
11573
11988
  useEffect(() => {
11574
11989
  if (visible) {
11575
- setShouldRender(true);
11990
+ if (shouldUnmountOnHide) {
11991
+ setShouldRender(true);
11992
+ }
11576
11993
  // Reset swipe positions
11577
11994
  swipeX.value = 0;
11578
11995
  swipeY.value = 0;
@@ -11617,7 +12034,7 @@ function ToastBase(props, ref) {
11617
12034
  easing: Easing$1.in(Easing$1.back(1.1))
11618
12035
  }, (finished) => {
11619
12036
  'worklet';
11620
- if (finished) {
12037
+ if (finished && shouldUnmountOnHide) {
11621
12038
  runOnJS(handleShouldRenderUpdate)(false);
11622
12039
  }
11623
12040
  });
@@ -11631,7 +12048,7 @@ function ToastBase(props, ref) {
11631
12048
  clearTimeout(autoHideTimeoutRef.current);
11632
12049
  }
11633
12050
  };
11634
- }, [visible, finalAnimationConfig, autoHide, onClose, slideAnimation, fadeAnimation, swipeX, swipeY, position, persistent, triggerHapticFeedback, sev, getHiddenPosition, handleShouldRenderUpdate]);
12051
+ }, [visible, finalAnimationConfig, autoHide, onClose, slideAnimation, fadeAnimation, swipeX, swipeY, position, persistent, triggerHapticFeedback, sev, getHiddenPosition, handleShouldRenderUpdate, shouldUnmountOnHide]);
11635
12052
  const getToastStyles = () => {
11636
12053
  const baseStyles = {
11637
12054
  ...radiusStyles,
@@ -11756,7 +12173,7 @@ function ToastBase(props, ref) {
11756
12173
  const toastStyles = getToastStyles();
11757
12174
  const textColor = getTextColor();
11758
12175
  const iconColor = getIconColor();
11759
- if (!shouldRender) {
12176
+ if (shouldUnmountOnHide && !shouldRender) {
11760
12177
  return null;
11761
12178
  }
11762
12179
  // Check if swipe is enabled and gesture handler is available
@@ -13933,7 +14350,7 @@ const BrandIcon = ({ brand, size = 'md', color, variant, style, label, decorativ
13933
14350
  const defs = brandIconDef.defs;
13934
14351
  if (!defs)
13935
14352
  return null;
13936
- return (jsx(Defs, { children: (_a = defs.linearGradients) === null || _a === void 0 ? void 0 : _a.map((g, idx) => (jsx(LinearGradient$2, { id: g.id, x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2, gradientUnits: g.gradientUnits, gradientTransform: g.gradientTransform, children: g.stops.map((s, sidx) => (jsx(Stop, { offset: s.offset, stopColor: color || transformColorForDarkMode(s.stopColor, isDarkMode, shouldInvert), stopOpacity: s.stopOpacity }, `stop-${sidx}`))) }, `lg-${g.id || idx}`))) }));
14353
+ return (jsx(Defs, { children: (_a = defs.linearGradients) === null || _a === void 0 ? void 0 : _a.map((g, idx) => (jsx(LinearGradient, { id: g.id, x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2, gradientUnits: g.gradientUnits, gradientTransform: g.gradientTransform, children: g.stops.map((s, sidx) => (jsx(Stop, { offset: s.offset, stopColor: color || transformColorForDarkMode(s.stopColor, isDarkMode, shouldInvert), stopOpacity: s.stopOpacity }, `stop-${sidx}`))) }, `lg-${g.id || idx}`))) }));
13937
14354
  })(), Array.isArray(iconContent) ? (
13938
14355
  // Multi-shape brand icon (paths, circles, etc.)
13939
14356
  iconContent.map((item, index) => {
@@ -14665,7 +15082,7 @@ const createInputStyles = (theme, isRTL = false) => {
14665
15082
  color: props.disabled ? theme.text.disabled : theme.text.primary,
14666
15083
  fontSize: px(theme.fontSizes.sm),
14667
15084
  fontWeight: '600',
14668
- marginBottom: 4
15085
+ marginBottom: 0
14669
15086
  },
14670
15087
  leftSection: {
14671
15088
  ...(isRTL ? { paddingLeft: px(theme.spacing.xs) } : { paddingRight: px(theme.spacing.xs) })
@@ -14693,8 +15110,15 @@ const FieldHeader = ({ label, description, required, withAsterisk, disabled, err
14693
15110
  const styles = getInputStyles({ size, disabled, error });
14694
15111
  if (!label && !description)
14695
15112
  return null;
14696
- const mb = marginBottom !== undefined ? marginBottom : (description ? 4 : 4);
14697
- return (jsxs(View, { style: { marginBottom: mb }, testID: testID, children: [label && (jsxs(Text$1, { style: styles.label, children: [label, required && withAsterisk && (jsx(Text$1, { style: styles.required, accessibilityLabel: "required", children: ' *' }))] })), description && (jsx(Text$1, { style: { fontSize: 12, color: theme.text.muted }, children: description }))] }));
15113
+ const hasDescription = Boolean(description);
15114
+ const resolvedMarginBottom = (() => {
15115
+ if (marginBottom !== undefined)
15116
+ return marginBottom;
15117
+ if (!hasDescription && !error)
15118
+ return 0;
15119
+ return 4;
15120
+ })();
15121
+ return (jsxs(View, { style: { marginBottom: resolvedMarginBottom }, testID: testID, children: [label && (jsxs(Text$1, { style: styles.label, children: [label, required && withAsterisk && (jsx(Text$1, { style: styles.required, accessibilityLabel: "required", children: ' *' }))] })), description && (jsx(Text$1, { style: { fontSize: 12, color: theme.text.muted }, children: description }))] }));
14698
15122
  };
14699
15123
 
14700
15124
  const TextInputBase = factory((props, ref) => {
@@ -17668,7 +18092,7 @@ const getCardStyles = (theme, variant = 'filled', padding, radiusStyles, shadowS
17668
18092
  ...(variant !== 'outline' && {
17669
18093
  ...DESIGN_TOKENS.shadow.sm && { boxShadow: DESIGN_TOKENS.shadow.sm },
17670
18094
  elevation: 1,
17671
- })
18095
+ }),
17672
18096
  };
17673
18097
  const variantStyles = {
17674
18098
  outline: {
@@ -18584,11 +19008,7 @@ const Search = factory((props, ref) => {
18584
19008
  fontSize: size === 'xs' ? 12 : size === 'sm' ? 14 : 16,
18585
19009
  }, children: placeholder }), jsx(Space, { w: 64 }), rightComponent || finalRight] }));
18586
19010
  }
18587
- return jsx(Input
18588
- // @ts-expect-error factory handles ref injection
18589
- , {
18590
- // @ts-expect-error factory handles ref injection
18591
- ref: ref, type: "search", value: internal.value, onChangeText: handleChange, onEnter: handleSubmit, placeholder: placeholder, size: size, radius: radius, leftSection: left, rightSection: finalRight, accessibilityLabel: accessibilityLabel, style: style });
19011
+ return jsx(Input, { ref: ref, type: "search", value: internal.value, onChangeText: handleChange, onEnter: handleSubmit, placeholder: placeholder, size: size, radius: radius, leftSection: left, rightSection: finalRight, accessibilityLabel: accessibilityLabel, style: style });
18592
19012
  });
18593
19013
  Search.displayName = 'Search';
18594
19014
 
@@ -18692,71 +19112,217 @@ const SIZE_CONFIG = {
18692
19112
  md: { fontSize: 'sm', padY: 8, padX: 12, gap: 10, radius: 8, minHeight: 38 },
18693
19113
  lg: { fontSize: 'md', padY: 10, padX: 14, gap: 12, radius: 10, minHeight: 44 },
18694
19114
  };
18695
- const MenuItemButton = (allProps) => {
19115
+ const MenuItemButton = forwardRef((allProps, ref) => {
18696
19116
  var _a;
18697
19117
  const { spacingProps, otherProps } = extractSpacingProps(allProps);
18698
- const { title, children, startIcon, endIcon, onPress, disabled = false, active = false, danger = false, fullWidth = true, size = 'sm', compact = false, rounded = false, style, onPressIn, onPressOut, onMouseDown, ...restProps } = otherProps;
19118
+ const { title, children, startIcon, endIcon, onPress, disabled = false, active = false, danger = false, fullWidth = true, size = 'sm', compact = false, rounded = false, style, onPressIn, onPressOut, onMouseDown, onMouseEnter, onMouseLeave, onHoverIn, onHoverOut, onFocus, onBlur, tone, hoverTone, activeTone, textColor: textColorOverride, hoverTextColor: hoverTextColorOverride, activeTextColor: activeTextColorOverride, testID, ...restProps } = otherProps;
18699
19119
  const theme = useTheme();
18700
19120
  const { isRTL } = useDirection();
18701
19121
  const spacingStyles = getSpacingStyles(spacingProps);
18702
19122
  const cfg = (_a = SIZE_CONFIG[size]) !== null && _a !== void 0 ? _a : SIZE_CONFIG.sm;
18703
19123
  const content = children || title;
18704
- const colors = useMemo(() => {
18705
- const base = {
18706
- text: theme.text.primary,
18707
- bg: 'transparent',
18708
- hoverBg: theme.colors.gray[1],
18709
- activeBg: theme.colors.primary[0],
18710
- activeText: theme.colors.primary[6],
18711
- dangerText: theme.colors.error[6],
18712
- dangerHoverBg: theme.colors.error[0],
18713
- dangerActiveBg: theme.colors.error[1],
18714
- };
18715
- if (danger) {
18716
- return {
18717
- ...base,
18718
- text: base.dangerText,
18719
- hoverBg: base.dangerHoverBg,
18720
- activeBg: base.dangerActiveBg,
18721
- activeText: base.dangerText,
18722
- };
18723
- }
18724
- if (active) {
18725
- return {
18726
- ...base,
18727
- bg: base.activeBg,
18728
- text: base.activeText,
18729
- };
19124
+ const [isHovered, setIsHovered] = useState(false);
19125
+ const [isPressed, setIsPressed] = useState(false);
19126
+ const resolveTone = useCallback((toneKey) => {
19127
+ if (danger)
19128
+ return 'danger';
19129
+ return toneKey !== null && toneKey !== void 0 ? toneKey : 'default';
19130
+ }, [danger]);
19131
+ const getPalette = useCallback((toneKey) => {
19132
+ var _a;
19133
+ const isDark = theme.colorScheme === 'dark';
19134
+ switch (toneKey) {
19135
+ case 'danger':
19136
+ return {
19137
+ text: theme.colors.error[6],
19138
+ bg: 'transparent',
19139
+ hoverBg: isDark ? theme.colors.error[3] : theme.colors.error[0],
19140
+ activeBg: isDark ? theme.colors.error[4] : theme.colors.error[1],
19141
+ activeText: theme.colors.error[6],
19142
+ };
19143
+ case 'success':
19144
+ return {
19145
+ text: isDark ? theme.colors.success[2] : theme.colors.success[6],
19146
+ bg: 'transparent',
19147
+ hoverBg: isDark ? theme.colors.success[4] : theme.colors.success[0],
19148
+ activeBg: isDark ? theme.colors.success[5] : theme.colors.success[1],
19149
+ activeText: isDark ? theme.colors.success[2] : theme.colors.success[6],
19150
+ };
19151
+ case 'warning':
19152
+ return {
19153
+ text: isDark ? theme.colors.warning[2] : theme.colors.warning[6],
19154
+ bg: 'transparent',
19155
+ hoverBg: isDark ? theme.colors.warning[4] : theme.colors.warning[0],
19156
+ activeBg: isDark ? theme.colors.warning[5] : theme.colors.warning[1],
19157
+ activeText: isDark ? theme.colors.warning[2] : theme.colors.warning[6],
19158
+ };
19159
+ default:
19160
+ return {
19161
+ text: theme.text.primary,
19162
+ bg: 'transparent',
19163
+ hoverBg: isDark ? theme.colors.gray[3] : theme.colors.gray[1],
19164
+ activeBg: isDark ? theme.colors.primary[4] : theme.colors.primary[0],
19165
+ activeText: isDark ? ((_a = theme.text.onPrimary) !== null && _a !== void 0 ? _a : theme.text.primary) : theme.colors.primary[6],
19166
+ };
18730
19167
  }
18731
- return base;
18732
- }, [theme, active, danger]);
18733
- const horizontalPad = cfg.padX;
18734
- const verticalPad = compact ? Math.max(2, cfg.padY - 4) : cfg.padY;
18735
- return (jsx(View, { style: [fullWidth && { width: '100%' }, spacingStyles], children: jsxs(Pressable, { disabled: disabled, onPress: disabled ? undefined : onPress, onPressIn: disabled ? undefined : onPressIn, onPressOut: disabled ? undefined : onPressOut, ...(Platform.OS === 'web' && onMouseDown ? { onMouseDown } : {}), style: ({ pressed }) => [
18736
- {
18737
- flexDirection: isRTL ? 'row-reverse' : 'row',
18738
- alignItems: 'center',
18739
- minHeight: cfg.minHeight,
18740
- paddingHorizontal: horizontalPad,
18741
- paddingVertical: verticalPad,
18742
- width: fullWidth ? '100%' : undefined,
18743
- borderRadius: rounded ? 999 : cfg.radius,
18744
- backgroundColor: pressed ? colors.activeBg : colors.bg,
18745
- opacity: disabled ? 0.45 : 1,
18746
- gap: cfg.gap,
18747
- },
18748
- active && !danger && !pressed && { backgroundColor: colors.activeBg },
18749
- style
18750
- ], ...restProps, children: [startIcon && (jsx(View, { style: { opacity: disabled ? 0.6 : 1 }, children: startIcon })), content && (typeof content === 'string' ? (jsx(Text, { size: cfg.fontSize, weight: active ? '600' : '500', color: danger ? colors.text : active ? colors.text : theme.text.primary, style: { flex: 1, overflow: 'hidden' }, children: content })) : content), endIcon && (jsx(View, { style: isRTL ? { marginRight: cfg.gap, opacity: disabled ? 0.6 : 1 } : { marginLeft: cfg.gap, opacity: disabled ? 0.6 : 1 }, children: endIcon }))] }) }));
18751
- };
19168
+ }, [theme]);
19169
+ const baseTone = resolveTone(tone);
19170
+ const hoverToneResolved = resolveTone(hoverTone);
19171
+ const activeToneResolved = resolveTone(activeTone !== null && activeTone !== void 0 ? activeTone : tone);
19172
+ const basePalette = useMemo(() => getPalette(baseTone), [baseTone, getPalette]);
19173
+ const hoverPalette = useMemo(() => getPalette(hoverToneResolved), [hoverToneResolved, getPalette]);
19174
+ const activePalette = useMemo(() => getPalette(activeToneResolved), [activeToneResolved, getPalette]);
19175
+ const buttonBaseStyle = useMemo(() => ({
19176
+ flexDirection: isRTL ? 'row-reverse' : 'row',
19177
+ alignItems: 'center',
19178
+ minHeight: cfg.minHeight,
19179
+ paddingHorizontal: cfg.padX,
19180
+ paddingVertical: compact ? Math.max(2, cfg.padY - 4) : cfg.padY,
19181
+ width: fullWidth ? '100%' : undefined,
19182
+ borderRadius: rounded ? 999 : cfg.radius,
19183
+ opacity: disabled ? 0.45 : 1,
19184
+ gap: cfg.gap,
19185
+ backgroundColor: basePalette.bg,
19186
+ }), [isRTL, cfg, compact, fullWidth, rounded, disabled, basePalette.bg]);
19187
+ const handlePressIn = useCallback((event) => {
19188
+ if (!disabled)
19189
+ setIsPressed(true);
19190
+ onPressIn === null || onPressIn === void 0 ? void 0 : onPressIn(event);
19191
+ }, [disabled, onPressIn]);
19192
+ const handlePressOut = useCallback((event) => {
19193
+ if (!disabled)
19194
+ setIsPressed(false);
19195
+ onPressOut === null || onPressOut === void 0 ? void 0 : onPressOut(event);
19196
+ }, [disabled, onPressOut]);
19197
+ const handleHoverIn = useCallback((event) => {
19198
+ if (!disabled)
19199
+ setIsHovered(true);
19200
+ onHoverIn === null || onHoverIn === void 0 ? void 0 : onHoverIn(event);
19201
+ }, [disabled, onHoverIn]);
19202
+ const handleHoverOut = useCallback((event) => {
19203
+ if (!disabled)
19204
+ setIsHovered(false);
19205
+ onHoverOut === null || onHoverOut === void 0 ? void 0 : onHoverOut(event);
19206
+ }, [disabled, onHoverOut]);
19207
+ const handleMouseEnter = useCallback((event) => {
19208
+ if (!disabled)
19209
+ setIsHovered(true);
19210
+ onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(event);
19211
+ }, [disabled, onMouseEnter]);
19212
+ const handleMouseLeave = useCallback((event) => {
19213
+ if (!disabled)
19214
+ setIsHovered(false);
19215
+ onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(event);
19216
+ }, [disabled, onMouseLeave]);
19217
+ const isActive = active || isPressed;
19218
+ const baseText = textColorOverride !== null && textColorOverride !== void 0 ? textColorOverride : basePalette.text;
19219
+ const hoverText = hoverTextColorOverride !== null && hoverTextColorOverride !== void 0 ? hoverTextColorOverride : hoverPalette.text;
19220
+ const activeText = activeTextColorOverride !== null && activeTextColorOverride !== void 0 ? activeTextColorOverride : activePalette.activeText;
19221
+ const textColor = disabled
19222
+ ? theme.text.disabled
19223
+ : isActive
19224
+ ? activeText
19225
+ : isHovered
19226
+ ? hoverText
19227
+ : baseText;
19228
+ return (jsx(View, { ref: ref, style: [fullWidth && { width: '100%' }, spacingStyles], children: jsxs(Pressable, { disabled: disabled, onPress: disabled ? undefined : onPress, onPressIn: disabled ? undefined : handlePressIn, onPressOut: disabled ? undefined : handlePressOut, ...(Platform.OS === 'web' && onMouseDown ? { onMouseDown } : {}), ...(Platform.OS === 'web' ? { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave } : {}), onHoverIn: handleHoverIn, onHoverOut: handleHoverOut, onFocus: onFocus, onBlur: onBlur, testID: testID, style: (pressableState) => {
19229
+ const { pressed } = pressableState;
19230
+ const hovered = pressableState.hovered || isHovered;
19231
+ const effectiveActive = isActive || pressed;
19232
+ return [
19233
+ buttonBaseStyle,
19234
+ !disabled && effectiveActive && { backgroundColor: activePalette.activeBg },
19235
+ !disabled && !effectiveActive && hovered && { backgroundColor: hoverPalette.hoverBg },
19236
+ style
19237
+ ];
19238
+ }, ...restProps, children: [startIcon && (jsx(View, { style: { opacity: disabled ? 0.6 : 1 }, children: startIcon })), content && (typeof content === 'string' ? (jsx(Text, { size: cfg.fontSize, weight: active ? '600' : '500', color: textColor, style: { flex: 1, overflow: 'hidden' }, children: content })) : content), endIcon && (jsx(View, { style: isRTL ? { marginRight: cfg.gap, opacity: disabled ? 0.6 : 1 } : { marginLeft: cfg.gap, opacity: disabled ? 0.6 : 1 }, children: endIcon }))] }) }));
19239
+ });
18752
19240
  MenuItemButton.displayName = 'MenuItemButton';
18753
19241
 
19242
+ function useMenuStyles() {
19243
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
19244
+ const theme = useTheme();
19245
+ const getPaletteColor = (palette, index) => {
19246
+ if (Array.isArray(palette)) {
19247
+ return palette[index];
19248
+ }
19249
+ return undefined;
19250
+ };
19251
+ const surfacePalette = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.surface;
19252
+ const grayPalette = (_b = theme.colors) === null || _b === void 0 ? void 0 : _b.gray;
19253
+ const lightSurfaceColor = (_h = (_g = (_e = (_c = getPaletteColor(surfacePalette, 4)) !== null && _c !== void 0 ? _c : (typeof ((_d = theme.backgrounds) === null || _d === void 0 ? void 0 : _d.surface) === 'string' ? theme.backgrounds.surface : undefined)) !== null && _e !== void 0 ? _e : (typeof ((_f = theme.backgrounds) === null || _f === void 0 ? void 0 : _f.base) === 'string' ? theme.backgrounds.base : undefined)) !== null && _g !== void 0 ? _g : getPaletteColor(grayPalette, 0)) !== null && _h !== void 0 ? _h : '#ffffff';
19254
+ const darkSurfaceColor = (_l = (_j = getPaletteColor(surfacePalette, 3)) !== null && _j !== void 0 ? _j : (typeof ((_k = theme.backgrounds) === null || _k === void 0 ? void 0 : _k.elevated) === 'string' ? theme.backgrounds.elevated : undefined)) !== null && _l !== void 0 ? _l : lightSurfaceColor;
19255
+ const fallbackRadius = (_q = (_o = (_m = theme.radii) === null || _m === void 0 ? void 0 : _m.md) !== null && _o !== void 0 ? _o : (_p = theme.radii) === null || _p === void 0 ? void 0 : _p.sm) !== null && _q !== void 0 ? _q : '8';
19256
+ const parsedRadius = typeof fallbackRadius === 'number'
19257
+ ? fallbackRadius
19258
+ : parseInt(`${fallbackRadius}`, 10) || 8;
19259
+ const dropdown = {
19260
+ backgroundColor: theme.colorScheme === 'dark' ? darkSurfaceColor : lightSurfaceColor,
19261
+ borderRadius: parsedRadius,
19262
+ // borderWidth: 3, // Temporarily increased for debugging
19263
+ // borderColor: '#ff0000', // Temporarily red for debugging
19264
+ boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
19265
+ elevation: 8,
19266
+ minWidth: 180,
19267
+ maxWidth: 320,
19268
+ overflow: 'hidden',
19269
+ };
19270
+ const item = {
19271
+ flexDirection: 'row',
19272
+ alignItems: 'center',
19273
+ paddingVertical: 8,
19274
+ paddingHorizontal: 12,
19275
+ minHeight: 36,
19276
+ };
19277
+ const itemPressed = {
19278
+ backgroundColor: theme.colors.gray[1],
19279
+ };
19280
+ const itemDisabled = {
19281
+ opacity: 0.5,
19282
+ };
19283
+ const itemDanger = {
19284
+ backgroundColor: theme.colors.error[0],
19285
+ };
19286
+ const itemDangerPressed = {
19287
+ backgroundColor: theme.colors.error[1],
19288
+ };
19289
+ const label = {
19290
+ paddingVertical: 6,
19291
+ paddingHorizontal: 12,
19292
+ };
19293
+ const divider = {
19294
+ height: 1,
19295
+ // backgroundColor: theme.colors.gray[2],
19296
+ // marginVertical: 4,
19297
+ };
19298
+ const leftSection = {
19299
+ marginRight: 8,
19300
+ };
19301
+ const rightSection = {
19302
+ marginLeft: 'auto',
19303
+ paddingLeft: 12,
19304
+ };
19305
+ return {
19306
+ dropdown,
19307
+ item,
19308
+ itemPressed,
19309
+ itemDisabled,
19310
+ itemDanger,
19311
+ itemDangerPressed,
19312
+ label,
19313
+ divider,
19314
+ leftSection,
19315
+ rightSection,
19316
+ };
19317
+ }
19318
+
18754
19319
  const Select = factory((allProps, ref) => {
18755
19320
  var _a;
18756
19321
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(allProps);
18757
19322
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
18758
19323
  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 } = otherProps;
18759
19324
  const theme = useTheme();
19325
+ const menuStyles = useMenuStyles();
18760
19326
  const { isRTL } = useDirection();
18761
19327
  const [open, setOpen] = useState(false);
18762
19328
  const [value, setValue] = useState((_a = valueProp !== null && valueProp !== void 0 ? valueProp : defaultValue) !== null && _a !== void 0 ? _a : null);
@@ -18764,6 +19330,8 @@ const Select = factory((allProps, ref) => {
18764
19330
  const triggerRef = useRef(null);
18765
19331
  const { openOverlay, closeOverlay, updateOverlay } = useOverlay();
18766
19332
  const overlayIdRef = useRef(null);
19333
+ const menuSignatureRef = useRef('');
19334
+ const menuLayoutRef = useRef(null);
18767
19335
  // keep controlled
18768
19336
  useEffect(() => { if (valueProp !== undefined)
18769
19337
  setValue(valueProp); }, [valueProp]);
@@ -18781,34 +19349,28 @@ const Select = factory((allProps, ref) => {
18781
19349
  const selectedOption = options.find((o) => o.value === value) || null;
18782
19350
  const showClearButton = !!(clearable && selectedOption && !disabled);
18783
19351
  const clearLabel = clearButtonLabel || 'Clear selection';
19352
+ const optionRowHeight = useMemo(() => {
19353
+ switch (size) {
19354
+ case 'xs':
19355
+ return 30;
19356
+ case 'sm':
19357
+ return 34;
19358
+ case 'lg':
19359
+ return 44;
19360
+ case 'xl':
19361
+ return 48;
19362
+ default:
19363
+ return 38;
19364
+ }
19365
+ }, [size]);
18784
19366
  const close = useCallback(() => {
18785
19367
  setOpen(false);
18786
19368
  if (overlayIdRef.current) {
18787
19369
  closeOverlay(overlayIdRef.current);
18788
19370
  overlayIdRef.current = null;
18789
19371
  }
19372
+ menuLayoutRef.current = null;
18790
19373
  }, [closeOverlay]);
18791
- const computeAnchor = useCallback(() => {
18792
- var _a;
18793
- if (Platform.OS !== 'web')
18794
- return undefined;
18795
- if (!triggerRef.current)
18796
- return undefined;
18797
- try {
18798
- const node = triggerRef.current._node || triggerRef.current;
18799
- const rect = (_a = node === null || node === void 0 ? void 0 : node.getBoundingClientRect) === null || _a === void 0 ? void 0 : _a.call(node);
18800
- if (rect) {
18801
- setTriggerWidth(rect.width);
18802
- // In RTL, use rect.right instead of rect.left to align the dropdown
18803
- const xPos = isRTL ? rect.right - rect.width : rect.left;
18804
- return { x: xPos, y: rect.bottom + 4, width: rect.width, height: rect.height };
18805
- }
18806
- }
18807
- catch (_e) {
18808
- /* measurement failures are non-fatal on web */
18809
- }
18810
- return undefined;
18811
- }, [isRTL]);
18812
19374
  const measureTrigger = useCallback(() => {
18813
19375
  var _a, _b;
18814
19376
  if (Platform.OS === 'web')
@@ -18824,29 +19386,167 @@ const Select = factory((allProps, ref) => {
18824
19386
  /* native measurement failures can be ignored safely */
18825
19387
  }
18826
19388
  }, []);
18827
- const getMenuContent = useCallback(() => menu, [ /* menu recomputed below */]);
18828
- const openPortal = useCallback(() => {
19389
+ const resolveDropdownPosition = useCallback(async (preferredSize) => {
19390
+ if (Platform.OS !== 'web')
19391
+ return null;
19392
+ if (!triggerRef.current)
19393
+ return null;
19394
+ try {
19395
+ const anchorRect = await measureElement(triggerRef);
19396
+ if (!anchorRect || anchorRect.height === 0) {
19397
+ return null;
19398
+ }
19399
+ const optionCount = options.length || 1;
19400
+ const estimatedHeight = Math.min(maxHeight, Math.max(optionRowHeight * optionCount, optionRowHeight));
19401
+ const estimatedWidth = (anchorRect.width && anchorRect.width > 0) ? anchorRect.width : (triggerWidth || 200);
19402
+ const overlayWidth = (preferredSize === null || preferredSize === void 0 ? void 0 : preferredSize.width) && preferredSize.width > 0
19403
+ ? preferredSize.width
19404
+ : estimatedWidth;
19405
+ const overlayHeight = (preferredSize === null || preferredSize === void 0 ? void 0 : preferredSize.height) && preferredSize.height > 0
19406
+ ? Math.min(preferredSize.height, maxHeight)
19407
+ : estimatedHeight;
19408
+ const overlaySize = {
19409
+ width: overlayWidth,
19410
+ height: overlayHeight,
19411
+ };
19412
+ const position = calculateOverlayPositionEnhanced(anchorRect, overlaySize, {
19413
+ placement: 'auto',
19414
+ offset: 6,
19415
+ strategy: 'fixed',
19416
+ flip: true,
19417
+ shift: true,
19418
+ boundary: 8,
19419
+ });
19420
+ const finalWidth = position.finalWidth || overlaySize.width;
19421
+ const finalHeight = position.finalHeight || overlaySize.height;
19422
+ setTriggerWidth(prev => {
19423
+ if (prev !== null && Math.abs(prev - finalWidth) < 1) {
19424
+ return prev;
19425
+ }
19426
+ return finalWidth;
19427
+ });
19428
+ return {
19429
+ position,
19430
+ overlaySize: {
19431
+ width: finalWidth,
19432
+ height: finalHeight,
19433
+ },
19434
+ };
19435
+ }
19436
+ catch (error) {
19437
+ console.warn('Select: failed to resolve dropdown position', error);
19438
+ return null;
19439
+ }
19440
+ }, [options, maxHeight, optionRowHeight, triggerWidth]);
19441
+ const handleMenuLayoutChange = useCallback(async (layout) => {
19442
+ const previous = menuLayoutRef.current;
19443
+ if (previous) {
19444
+ const widthDiff = Math.abs(previous.width - (layout.width || 0));
19445
+ const heightDiff = Math.abs(previous.height - (layout.height || 0));
19446
+ if (widthDiff < 1 && heightDiff < 1) {
19447
+ return;
19448
+ }
19449
+ }
19450
+ menuLayoutRef.current = layout;
19451
+ if (!open || Platform.OS !== 'web' || !overlayIdRef.current)
19452
+ return;
19453
+ const resolved = await resolveDropdownPosition({ width: layout.width, height: layout.height });
19454
+ if (!resolved)
19455
+ return;
19456
+ const { position, overlaySize } = resolved;
19457
+ updateOverlay(overlayIdRef.current, {
19458
+ anchor: {
19459
+ x: position.x,
19460
+ y: position.y,
19461
+ width: overlaySize.width,
19462
+ height: overlaySize.height,
19463
+ },
19464
+ });
19465
+ }, [open, resolveDropdownPosition, updateOverlay]);
19466
+ const handleMenuLayoutEvent = useCallback((event) => {
19467
+ const { width, height } = event.nativeEvent.layout || {};
19468
+ if (width === undefined || height === undefined)
19469
+ return;
19470
+ handleMenuLayoutChange({ width, height });
19471
+ }, [handleMenuLayoutChange]);
19472
+ const handleSelect = useCallback((opt) => {
19473
+ if (opt.disabled)
19474
+ return;
19475
+ if (valueProp === undefined)
19476
+ setValue(opt.value);
19477
+ onChange === null || onChange === void 0 ? void 0 : onChange(opt.value, opt);
19478
+ if (closeOnSelect)
19479
+ close();
19480
+ }, [onChange, valueProp, close, closeOnSelect]);
19481
+ const menu = useMemo(() => {
19482
+ const resolvedWidth = triggerWidth && triggerWidth > 0 ? triggerWidth : undefined;
19483
+ return (jsx(View, { style: resolvedWidth ? { width: resolvedWidth, minWidth: resolvedWidth } : undefined, onLayout: Platform.OS === 'web' ? handleMenuLayoutEvent : undefined, children: jsx(ListGroup, { variant: "default", size: "sm", style: {
19484
+ ...menuStyles.dropdown,
19485
+ maxHeight,
19486
+ ...(resolvedWidth ? { width: resolvedWidth, minWidth: resolvedWidth } : {}),
19487
+ }, children: jsx(FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item }) => {
19488
+ const selected = item.value === value;
19489
+ if (renderOption) {
19490
+ return jsx(View, { children: renderOption(item, false, selected) });
19491
+ }
19492
+ const successPalette = theme.colors.success || [];
19493
+ const highlightColor = theme.colorScheme === 'dark'
19494
+ ? successPalette[4] || successPalette[5] || '#30D158'
19495
+ : successPalette[6] || successPalette[5] || '#2f9e44';
19496
+ const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
19497
+ const accentTextColor = item.disabled ? theme.text.disabled : highlightColor;
19498
+ return (jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: selected, tone: selected ? 'success' : 'default', hoverTone: "success", textColor: baseTextColor, hoverTextColor: accentTextColor, activeTextColor: accentTextColor, compact: true, rounded: false, style: { borderRadius: 0 }, children: item.label }));
19499
+ }, ItemSeparatorComponent: renderOption ? undefined : ListGroupDivider, style: { maxHeight }, bounces: false }) }) }));
19500
+ }, [menuStyles.dropdown, maxHeight, triggerWidth, options, value, renderOption, handleSelect, handleMenuLayoutEvent]);
19501
+ const getMenuContent = useCallback(() => menu, [menu]);
19502
+ const menuSignature = useMemo(() => {
19503
+ const optionSignature = options
19504
+ .map(opt => `${String(opt.value)}-${opt.label}-${opt.disabled ? '1' : '0'}`)
19505
+ .join('|');
19506
+ const valueSignature = typeof value === 'object' && value !== null
19507
+ ? JSON.stringify(value)
19508
+ : String(value !== null && value !== void 0 ? value : '');
19509
+ const triggerSig = triggerWidth != null ? `tw:${Math.round(triggerWidth)}` : 'tw:auto';
19510
+ return `${optionSignature}|value:${valueSignature}|${triggerSig}|render:${renderOption ? 'custom' : 'default'}`;
19511
+ }, [options, value, triggerWidth, renderOption]);
19512
+ const openPortal = useCallback(async () => {
18829
19513
  if (disabled || Platform.OS !== 'web')
18830
19514
  return;
18831
- const anchor = computeAnchor();
19515
+ const resolved = await resolveDropdownPosition();
19516
+ if (!resolved) {
19517
+ close();
19518
+ return;
19519
+ }
19520
+ const { position, overlaySize } = resolved;
18832
19521
  const id = openOverlay({
18833
19522
  content: getMenuContent(),
18834
- anchor,
18835
- width: anchor === null || anchor === void 0 ? void 0 : anchor.width,
19523
+ anchor: {
19524
+ x: position.x,
19525
+ y: position.y,
19526
+ width: overlaySize.width,
19527
+ height: overlaySize.height,
19528
+ },
18836
19529
  strategy: 'fixed',
18837
19530
  zIndex: 1300,
18838
19531
  closeOnClickOutside: true,
18839
- onClose: () => { setOpen(false); }
19532
+ closeOnEscape: true,
19533
+ onClose: () => {
19534
+ setOpen(false);
19535
+ }
18840
19536
  });
18841
19537
  overlayIdRef.current = id;
18842
- }, [disabled, computeAnchor, openOverlay, getMenuContent]);
19538
+ menuSignatureRef.current = menuSignature;
19539
+ }, [disabled, resolveDropdownPosition, openOverlay, getMenuContent, close, menuSignature]);
18843
19540
  const toggle = useCallback(() => {
18844
19541
  if (disabled)
18845
19542
  return;
18846
19543
  setOpen(o => {
18847
19544
  const next = !o;
18848
- if (next && Platform.OS === 'web')
18849
- openPortal();
19545
+ if (next && Platform.OS === 'web') {
19546
+ openPortal().catch(() => {
19547
+ close();
19548
+ });
19549
+ }
18850
19550
  if (next && Platform.OS !== 'web')
18851
19551
  measureTrigger();
18852
19552
  if (!next)
@@ -18855,21 +19555,37 @@ const Select = factory((allProps, ref) => {
18855
19555
  });
18856
19556
  }, [disabled, openPortal, close, measureTrigger]);
18857
19557
  useLayoutEffect(() => {
18858
- if (open && Platform.OS === 'web' && overlayIdRef.current) {
18859
- const anchor = computeAnchor();
18860
- if (anchor)
18861
- updateOverlay(overlayIdRef.current, { anchor });
18862
- }
18863
- }, [open, value, options, computeAnchor, updateOverlay]);
18864
- const handleSelect = useCallback((opt) => {
18865
- if (opt.disabled)
19558
+ if (!open || Platform.OS !== 'web' || !overlayIdRef.current)
18866
19559
  return;
18867
- if (valueProp === undefined)
18868
- setValue(opt.value);
18869
- onChange === null || onChange === void 0 ? void 0 : onChange(opt.value, opt);
18870
- if (closeOnSelect)
18871
- close();
18872
- }, [onChange, valueProp, close, closeOnSelect]);
19560
+ let cancelled = false;
19561
+ (async () => {
19562
+ const resolved = await resolveDropdownPosition();
19563
+ if (!resolved || cancelled)
19564
+ return;
19565
+ const { position, overlaySize } = resolved;
19566
+ updateOverlay(overlayIdRef.current, {
19567
+ anchor: {
19568
+ x: position.x,
19569
+ y: position.y,
19570
+ width: overlaySize.width,
19571
+ height: overlaySize.height,
19572
+ },
19573
+ });
19574
+ })();
19575
+ return () => {
19576
+ cancelled = true;
19577
+ };
19578
+ }, [open, value, options, resolveDropdownPosition, updateOverlay]);
19579
+ useEffect(() => {
19580
+ if (!open || Platform.OS !== 'web' || !overlayIdRef.current)
19581
+ return;
19582
+ if (menuSignatureRef.current === menuSignature)
19583
+ return;
19584
+ menuSignatureRef.current = menuSignature;
19585
+ updateOverlay(overlayIdRef.current, {
19586
+ content: getMenuContent(),
19587
+ });
19588
+ }, [open, menuSignature, getMenuContent, updateOverlay]);
18873
19589
  const handleClear = useCallback((event) => {
18874
19590
  var _a;
18875
19591
  (_a = event === null || event === void 0 ? void 0 : event.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(event);
@@ -18882,22 +19598,6 @@ const Select = factory((allProps, ref) => {
18882
19598
  onClear === null || onClear === void 0 ? void 0 : onClear();
18883
19599
  close();
18884
19600
  }, [disabled, valueProp, onChange, onClear, close]);
18885
- const menu = (jsx(ListGroup, { variant: "default", size: "sm", style: {
18886
- maxHeight,
18887
- width: triggerWidth || undefined,
18888
- minWidth: triggerWidth || undefined,
18889
- }, children: jsx(FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item, index }) => {
18890
- const selected = item.value === value;
18891
- if (renderOption) {
18892
- return jsx(View, { children: renderOption(item, false, selected) });
18893
- }
18894
- const isLast = index === options.length - 1;
18895
- return (jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: selected, compact: true, rounded: false, style: {
18896
- borderRadius: 0,
18897
- borderBottomWidth: isLast ? 0 : StyleSheet.hairlineWidth,
18898
- borderBottomColor: theme.colorScheme === 'dark' ? theme.colors.gray[4] : theme.colors.gray[2],
18899
- }, children: item.label }));
18900
- }, style: { maxHeight }, bounces: false }) }));
18901
19601
  const fieldContent = selectedOption ? (jsx(Text$1, { style: { color: disabled ? theme.text.disabled : theme.text.primary }, children: selectedOption.label })) : (jsx(Text$1, { style: { color: disabled ? theme.text.disabled : theme.text.muted }, children: placeholder }));
18902
19602
  return (jsxs(View, { style: [defaultMinWidthStyle, fullWidthStyle, spacingStyles, layoutStyles,], children: [jsx(FieldHeader, { label: label, description: description, disabled: disabled, error: !!error, size: size }), jsxs(Pressable, { ref: (node) => { triggerRef.current = node; if (typeof ref === 'function')
18903
19603
  ref(node);
@@ -18915,36 +19615,6 @@ const Select = factory((allProps, ref) => {
18915
19615
  });
18916
19616
 
18917
19617
  const debounce = require('lodash.debounce');
18918
- const HighlightedText = ({ text, query, highlight = false }) => {
18919
- const theme = useTheme();
18920
- const baseStyle = {
18921
- color: theme.text.primary,
18922
- fontSize: 15,
18923
- fontFamily: theme.fontFamily,
18924
- };
18925
- if (!highlight || !query) {
18926
- return (jsx(Text, { as: "span", variant: "span", style: baseStyle, children: text }));
18927
- }
18928
- const safeQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
18929
- const regex = new RegExp(`(${safeQuery})`, 'gi');
18930
- const parts = text.split(regex);
18931
- const normalizedQuery = query.toLowerCase();
18932
- return (jsx(Text, { as: "span", variant: "span", style: baseStyle, children: parts.map((part, index) => {
18933
- var _a, _b, _c, _d;
18934
- if (!part) {
18935
- return null;
18936
- }
18937
- if (part.toLowerCase() === normalizedQuery) {
18938
- return (jsx(Text, { as: "span", variant: "span", style: {
18939
- backgroundColor: ((_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightBackground) || ((_b = theme.colors.highlight) === null || _b === void 0 ? void 0 : _b[2]) || theme.colors.primary[1],
18940
- fontWeight: '600',
18941
- color: ((_c = theme.states) === null || _c === void 0 ? void 0 : _c.highlightText) || ((_d = theme.colors.highlight) === null || _d === void 0 ? void 0 : _d[8]) || theme.colors.primary[7],
18942
- fontFamily: theme.fontFamily,
18943
- }, children: part }, `match-${index}`));
18944
- }
18945
- return (jsx(React__default.Fragment, { children: part }, `text-${index}`));
18946
- }) }));
18947
- };
18948
19618
  const DEFAULT_FALLBACK_PLACEMENTS$1 = ['top-start', 'top-end', 'top', 'bottom-start', 'bottom-end', 'bottom'];
18949
19619
  const defaultFilter = (item, query) => {
18950
19620
  return item.label.toLowerCase().includes(query.toLowerCase()) ||
@@ -19301,6 +19971,7 @@ const AutoComplete = factory((props, ref) => {
19301
19971
  }, [multiSelect, onSelect, useModal, displayProperty, onChangeText]);
19302
19972
  // Default item renderer - use stable reference to prevent loops
19303
19973
  const defaultRenderItem = useCallback((item, index, isSelected = false) => {
19974
+ const highlightQuery = highlightMatches ? currentQueryRef.current : undefined;
19304
19975
  return (jsx(MenuItemButton, { onPress: () => handleSelectSuggestion(item), disabled: item.disabled, active: isSelected, compact: true, rounded: false, style: [styles.menuItemButton, suggestionItemStyle], ...(Platform.OS === 'web' ? {
19305
19976
  onMouseDown: (event) => {
19306
19977
  if (event === null || event === void 0 ? void 0 : event.preventDefault) {
@@ -19310,7 +19981,7 @@ const AutoComplete = factory((props, ref) => {
19310
19981
  event.stopPropagation();
19311
19982
  }
19312
19983
  },
19313
- } : {}), children: jsx(HighlightedText, { text: item.label, query: currentQueryRef.current, highlight: highlightMatches }) }));
19984
+ } : {}), children: jsx(Highlight, { highlight: highlightQuery, children: item.label }) }));
19314
19985
  }, [handleSelectSuggestion, highlightMatches, suggestionItemStyle]);
19315
19986
  // Render item with enhanced parameters - use refs to prevent infinite loops
19316
19987
  const renderSuggestionItem = useCallback((item, index) => {
@@ -19711,6 +20382,7 @@ const AutoComplete = factory((props, ref) => {
19711
20382
  });
19712
20383
  AutoComplete.displayName = 'AutoComplete';
19713
20384
 
20385
+ const { DocumentPicker: DocumentPickerModule, hasDocumentPicker } = resolveDocumentPicker();
19714
20386
  const isDocumentPickerAsset = (file) => typeof (file === null || file === void 0 ? void 0 : file.uri) === 'string';
19715
20387
  const getFileMetadata = (file) => {
19716
20388
  var _a, _b, _c, _d, _e;
@@ -19833,7 +20505,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
19833
20505
  });
19834
20506
  }, [imagePreview]);
19835
20507
  const processFiles = useCallback(async (fileList) => {
19836
- var _a;
20508
+ var _a, _b, _c;
19837
20509
  const filesToProcess = Array.isArray(fileList)
19838
20510
  ? [...fileList]
19839
20511
  : Array.from(fileList !== null && fileList !== void 0 ? fileList : []);
@@ -19852,7 +20524,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
19852
20524
  let previewUrl = await createFilePreview(file);
19853
20525
  const metadata = getFileMetadata(file);
19854
20526
  if (!previewUrl && Platform.OS !== 'web' && isDocumentPickerAsset(file) && ((_a = metadata.type) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
19855
- previewUrl = metadata.uri;
20527
+ previewUrl = (_b = metadata.uri) !== null && _b !== void 0 ? _b : undefined;
19856
20528
  }
19857
20529
  const fileInput = {
19858
20530
  file,
@@ -19860,7 +20532,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
19860
20532
  name: metadata.name,
19861
20533
  size: metadata.size,
19862
20534
  type: metadata.type,
19863
- uri: metadata.uri,
20535
+ uri: (_c = metadata.uri) !== null && _c !== void 0 ? _c : undefined,
19864
20536
  previewUrl,
19865
20537
  status: validationError ? 'error' : 'pending',
19866
20538
  error: validationError || undefined,
@@ -19916,9 +20588,14 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
19916
20588
  }
19917
20589
  return;
19918
20590
  }
20591
+ const picker = DocumentPickerModule;
20592
+ if (!hasDocumentPicker || !(picker === null || picker === void 0 ? void 0 : picker.getDocumentAsync)) {
20593
+ console.warn('FileInput: expo-document-picker not installed, native file picker is disabled.');
20594
+ return;
20595
+ }
19919
20596
  try {
19920
20597
  const pickerTypes = accept.filter(type => !type.startsWith('.'));
19921
- const result = await DocumentPicker.getDocumentAsync({
20598
+ const result = await picker.getDocumentAsync({
19922
20599
  multiple,
19923
20600
  copyToCacheDirectory: true,
19924
20601
  type: pickerTypes.length > 0 ? pickerTypes : undefined,
@@ -22133,14 +22810,12 @@ const TimePicker = ({ value, defaultValue, onChange, format = 24, withSeconds =
22133
22810
  marginBottom: 12,
22134
22811
  textAlign: 'center',
22135
22812
  }, children: "Minute" }), jsx(FlatList, { data: minuteOptions, keyExtractor: (item) => 'm-' + item, renderItem: ({ item }) => renderNumber(item, internal.minutes === item, () => commit({ minutes: item }, autoClose && !withSeconds)), style: [listCommon, { borderRadius: 12, backgroundColor: theme.colors.gray[1] }], contentContainerStyle: { paddingVertical: 8 }, showsVerticalScrollIndicator: false })] }), withSeconds && (jsxs(View, { style: { width: columnWidth, alignItems: 'center' }, children: [jsx(Text, { size: "sm", weight: "medium", style: {
22136
- color: theme.colors.gray[6],
22137
22813
  marginBottom: 12,
22138
22814
  textAlign: 'center',
22139
22815
  }, children: "Second" }), jsx(FlatList, { data: secondOptions, keyExtractor: (item) => 's-' + item, renderItem: ({ item }) => {
22140
22816
  var _a;
22141
22817
  return renderNumber(item, ((_a = internal.seconds) !== null && _a !== void 0 ? _a : 0) === item, () => commit({ seconds: item }, autoClose));
22142
22818
  }, style: [listCommon, { borderRadius: 12, backgroundColor: theme.colors.gray[1] }], contentContainerStyle: { paddingVertical: 8 }, showsVerticalScrollIndicator: false })] })), is12h && (jsxs(View, { style: { alignItems: 'center' }, children: [jsx(Text, { size: "sm", weight: "medium", style: {
22143
- color: theme.colors.gray[6],
22144
22819
  marginBottom: 12,
22145
22820
  textAlign: 'center',
22146
22821
  }, children: "Period" }), jsx(Flex, { align: "center", justify: "center", style: {
@@ -23844,68 +24519,6 @@ const Breadcrumbs = factory((props, ref) => {
23844
24519
  });
23845
24520
  Breadcrumbs.displayName = 'Breadcrumbs';
23846
24521
 
23847
- function useMenuStyles() {
23848
- const theme = useTheme();
23849
- const dropdown = {
23850
- backgroundColor: theme.colorScheme === 'dark' ? theme.colors.surface[3] : theme.colors.surface[4],
23851
- borderRadius: parseInt(theme.radii.md),
23852
- // borderWidth: 3, // Temporarily increased for debugging
23853
- // borderColor: '#ff0000', // Temporarily red for debugging
23854
- boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
23855
- elevation: 8,
23856
- minWidth: 180,
23857
- maxWidth: 320,
23858
- overflow: 'hidden',
23859
- };
23860
- const item = {
23861
- flexDirection: 'row',
23862
- alignItems: 'center',
23863
- paddingVertical: 8,
23864
- paddingHorizontal: 12,
23865
- minHeight: 36,
23866
- };
23867
- const itemPressed = {
23868
- backgroundColor: theme.colors.gray[1],
23869
- };
23870
- const itemDisabled = {
23871
- opacity: 0.5,
23872
- };
23873
- const itemDanger = {
23874
- backgroundColor: theme.colors.error[0],
23875
- };
23876
- const itemDangerPressed = {
23877
- backgroundColor: theme.colors.error[1],
23878
- };
23879
- const label = {
23880
- paddingVertical: 6,
23881
- paddingHorizontal: 12,
23882
- };
23883
- const divider = {
23884
- height: 1,
23885
- // backgroundColor: theme.colors.gray[2],
23886
- // marginVertical: 4,
23887
- };
23888
- const leftSection = {
23889
- marginRight: 8,
23890
- };
23891
- const rightSection = {
23892
- marginLeft: 'auto',
23893
- paddingLeft: 12,
23894
- };
23895
- return {
23896
- dropdown,
23897
- item,
23898
- itemPressed,
23899
- itemDisabled,
23900
- itemDanger,
23901
- itemDangerPressed,
23902
- label,
23903
- divider,
23904
- leftSection,
23905
- rightSection,
23906
- };
23907
- }
23908
-
23909
24522
  const MenuContext = createContext(null);
23910
24523
  function useMenuContext() {
23911
24524
  const context = useContext(MenuContext);
@@ -24134,7 +24747,7 @@ function MenuBase(props, ref) {
24134
24747
  // Create a callback ref that works better with React Native Web
24135
24748
  const triggerCallbackRef = useCallback((node) => {
24136
24749
  triggerRef.current = node;
24137
- console.log('Trigger ref set to:', node);
24750
+ // console.log('Trigger ref set to:', node);
24138
24751
  }, []);
24139
24752
  const enhancedTrigger = isValidElement(triggerElement)
24140
24753
  ? cloneElement(triggerElement, {
@@ -24164,7 +24777,7 @@ function MenuBase(props, ref) {
24164
24777
  else if (ref) {
24165
24778
  ref.current = node;
24166
24779
  }
24167
- console.log('Combined ref set to:', node);
24780
+ // console.log('Combined ref set to:', node);
24168
24781
  }, [ref]);
24169
24782
  return (jsx(MenuContext.Provider, { value: { closeMenu: handleClose, opened: isOpened }, children: jsx(View, { ref: combinedRef, style: getSpacingStyles(extractSpacingProps(spacingProps).spacingProps), testID: testID, ...(trigger === 'contextmenu' && Platform.OS === 'web'
24170
24783
  ? {
@@ -24181,16 +24794,14 @@ function MenuBase(props, ref) {
24181
24794
  }
24182
24795
  : {}), onLayout: () => {
24183
24796
  // Force a re-render to ensure ref is available
24184
- if (containerRef.current) {
24185
- console.log('Menu container onLayout - container ref available:', containerRef.current);
24186
- }
24797
+ if (containerRef.current) ;
24187
24798
  }, children: enhancedTrigger }) }));
24188
24799
  }
24189
24800
  // Menu.Item component
24190
24801
  function MenuItemBase(props, ref) {
24191
- const { children, onPress, disabled = false, leftSection, rightSection, color = 'default', closeMenuOnClick = true, testID, ...spacingProps } = props;
24802
+ const { spacingProps, otherProps } = extractSpacingProps(props);
24803
+ const { children, onPress, disabled = false, leftSection, rightSection, color = 'default', closeMenuOnClick = true, testID, ...restProps } = otherProps;
24192
24804
  const { closeMenu } = useMenuContext();
24193
- const theme = useTheme();
24194
24805
  const handlePress = useCallback(() => {
24195
24806
  if (disabled)
24196
24807
  return;
@@ -24198,7 +24809,14 @@ function MenuItemBase(props, ref) {
24198
24809
  if (closeMenuOnClick)
24199
24810
  closeMenu();
24200
24811
  }, [disabled, onPress, closeMenuOnClick, closeMenu]);
24201
- return (jsx(ListGroupItem, { ref: ref, onPress: handlePress, disabled: disabled, danger: color === 'danger', leftSection: leftSection, rightSection: rightSection, textStyle: { color: color === 'danger' ? theme.colors.error[6] : theme.text.primary }, style: {}, ...spacingProps, testID: testID, children: children }));
24812
+ const tone = color === 'danger'
24813
+ ? 'danger'
24814
+ : color === 'success'
24815
+ ? 'success'
24816
+ : color === 'warning'
24817
+ ? 'warning'
24818
+ : 'default';
24819
+ return (jsx(MenuItemButton, { ref: ref, onPress: handlePress, disabled: disabled, startIcon: leftSection, endIcon: rightSection, tone: tone, testID: testID, ...spacingProps, ...restProps, children: children }));
24202
24820
  }
24203
24821
  // Menu.Label component
24204
24822
  function MenuLabelBase(props, ref) {
@@ -25743,6 +26361,467 @@ function Blockquote({ children, variant = 'default', size = 'md', color, quoteIc
25743
26361
  return content;
25744
26362
  }
25745
26363
 
26364
+ const createPopoverStyles = (theme) => (params) => {
26365
+ const radiusStyles = createRadiusStyles(params.radius);
26366
+ const shadowStyles = createShadowStyles(params.shadow, theme, 'popover');
26367
+ return StyleSheet.create({
26368
+ wrapper: {
26369
+ position: 'relative',
26370
+ alignSelf: 'flex-start',
26371
+ overflow: 'visible',
26372
+ ...shadowStyles,
26373
+ },
26374
+ dropdown: {
26375
+ backgroundColor: theme.backgrounds.surface,
26376
+ borderColor: theme.backgrounds.border,
26377
+ borderWidth: 1,
26378
+ ...radiusStyles,
26379
+ overflow: 'hidden',
26380
+ minWidth: 0,
26381
+ },
26382
+ arrow: {
26383
+ position: 'absolute',
26384
+ width: params.arrowSize * 2,
26385
+ height: params.arrowSize * 2,
26386
+ backgroundColor: theme.backgrounds.surface,
26387
+ transform: [{ rotate: '45deg' }],
26388
+ },
26389
+ });
26390
+ };
26391
+
26392
+ const PopoverContext = createContext(null);
26393
+ function usePopoverContext(component) {
26394
+ const context = useContext(PopoverContext);
26395
+ if (!context) {
26396
+ throw new Error(`${component} must be used within Popover`);
26397
+ }
26398
+ return context;
26399
+ }
26400
+ const DEFAULT_ARROW_SIZE = 7;
26401
+ const PopoverBase = (props, ref) => {
26402
+ var _a;
26403
+ const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
26404
+ 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, fallbackPlacements, boundary, withRoles = true, id, withArrow = false, arrowSize = DEFAULT_ARROW_SIZE, arrowRadius = 0, arrowOffset = 5, arrowPosition = 'center', onPositionChange, testID, ...rest } = props;
26405
+ const theme = useTheme();
26406
+ const { spacingProps } = extractSpacingProps(rest);
26407
+ const spacingStyles = getSpacingStyles(spacingProps);
26408
+ const isControlled = controlledOpened !== undefined;
26409
+ const [internalOpened, setInternalOpened] = useState(defaultOpened);
26410
+ const [dropdownState, setDropdownState] = useState(null);
26411
+ const opened = isControlled ? !!controlledOpened : internalOpened;
26412
+ const openedRef = useRef(opened);
26413
+ const closingReasonRef = useRef(null);
26414
+ const anchorMeasurementsRef = useRef(null);
26415
+ useEffect(() => {
26416
+ openedRef.current = opened;
26417
+ }, [opened]);
26418
+ const resolvedOffset = typeof offset === 'number' ? offset : (_a = offset === null || offset === void 0 ? void 0 : offset.mainAxis) !== null && _a !== void 0 ? _a : 8;
26419
+ const resolvedFlip = preventPositionChangeWhenVisible
26420
+ ? false
26421
+ : (middlewares === null || middlewares === void 0 ? void 0 : middlewares.flip) === false
26422
+ ? false
26423
+ : true;
26424
+ const resolvedShift = preventPositionChangeWhenVisible
26425
+ ? false
26426
+ : (middlewares === null || middlewares === void 0 ? void 0 : middlewares.shift) === false
26427
+ ? false
26428
+ : true;
26429
+ const resolvedStrategy = floatingStrategy !== null && floatingStrategy !== void 0 ? floatingStrategy : 'fixed';
26430
+ const { position: positioningResult, anchorRef, popoverRef, showOverlay, hideOverlay, updatePosition } = useDropdownPositioning({
26431
+ isOpen: opened && !disabled && !!dropdownState,
26432
+ placement: position,
26433
+ offset: resolvedOffset,
26434
+ strategy: resolvedStrategy,
26435
+ flip: resolvedFlip,
26436
+ shift: resolvedShift,
26437
+ boundary,
26438
+ fallbackPlacements,
26439
+ viewport,
26440
+ onClose: () => handleOverlayClose('dismiss'),
26441
+ closeOnClickOutside,
26442
+ closeOnEscape,
26443
+ });
26444
+ const popoverStyles = useMemo(() => createPopoverStyles(theme)({
26445
+ radius,
26446
+ shadow,
26447
+ arrowSize,
26448
+ }), [theme, radius, shadow, arrowSize]);
26449
+ const layoutUpdateTimeoutRef = useRef(null);
26450
+ const hasMeasuredLayoutRef = useRef(false);
26451
+ // Defer re-measuring to the next frame so overlay position uses final layout metrics
26452
+ const schedulePositionUpdate = useCallback(() => {
26453
+ if (layoutUpdateTimeoutRef.current) {
26454
+ clearTimeout(layoutUpdateTimeoutRef.current);
26455
+ }
26456
+ layoutUpdateTimeoutRef.current = setTimeout(() => {
26457
+ updatePosition();
26458
+ }, 16);
26459
+ }, [updatePosition]);
26460
+ useEffect(() => {
26461
+ return () => {
26462
+ if (layoutUpdateTimeoutRef.current) {
26463
+ clearTimeout(layoutUpdateTimeoutRef.current);
26464
+ layoutUpdateTimeoutRef.current = null;
26465
+ }
26466
+ };
26467
+ }, []);
26468
+ useEffect(() => {
26469
+ if (!opened) {
26470
+ hasMeasuredLayoutRef.current = false;
26471
+ if (layoutUpdateTimeoutRef.current) {
26472
+ clearTimeout(layoutUpdateTimeoutRef.current);
26473
+ layoutUpdateTimeoutRef.current = null;
26474
+ }
26475
+ }
26476
+ }, [opened]);
26477
+ useEffect(() => {
26478
+ hasMeasuredLayoutRef.current = false;
26479
+ }, [dropdownState]);
26480
+ const handleDropdownLayout = useCallback(() => {
26481
+ if (hasMeasuredLayoutRef.current) {
26482
+ return;
26483
+ }
26484
+ hasMeasuredLayoutRef.current = true;
26485
+ schedulePositionUpdate();
26486
+ }, [schedulePositionUpdate]);
26487
+ const updateAnchorMeasurements = useCallback(async () => {
26488
+ if (!anchorRef.current)
26489
+ return;
26490
+ try {
26491
+ const rect = await measureElement(anchorRef);
26492
+ anchorMeasurementsRef.current = { width: rect.width, height: rect.height };
26493
+ }
26494
+ catch (_a) {
26495
+ // noop – measurement failed (likely not mounted yet)
26496
+ }
26497
+ }, [anchorRef]);
26498
+ const commitOpen = useCallback(() => {
26499
+ if (openedRef.current || disabled)
26500
+ return;
26501
+ if (!isControlled) {
26502
+ setInternalOpened(true);
26503
+ }
26504
+ onChange === null || onChange === void 0 ? void 0 : onChange(true);
26505
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen();
26506
+ openedRef.current = true;
26507
+ }, [disabled, isControlled, onChange, onOpen]);
26508
+ const commitClose = useCallback((reason) => {
26509
+ if (!openedRef.current)
26510
+ return;
26511
+ if (!isControlled) {
26512
+ setInternalOpened(false);
26513
+ }
26514
+ onChange === null || onChange === void 0 ? void 0 : onChange(false);
26515
+ onClose === null || onClose === void 0 ? void 0 : onClose();
26516
+ if (reason === 'dismiss') {
26517
+ onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss();
26518
+ }
26519
+ openedRef.current = false;
26520
+ }, [isControlled, onChange, onClose, onDismiss]);
26521
+ const handleOverlayClose = useCallback((reason) => {
26522
+ var _a;
26523
+ const closingReason = (_a = closingReasonRef.current) !== null && _a !== void 0 ? _a : reason;
26524
+ closingReasonRef.current = null;
26525
+ commitClose(closingReason);
26526
+ }, [commitClose]);
26527
+ const openPopover = useCallback(() => {
26528
+ if (disabled)
26529
+ return;
26530
+ closingReasonRef.current = null;
26531
+ commitOpen();
26532
+ }, [commitOpen, disabled]);
26533
+ const closePopover = useCallback((reason = 'programmatic') => {
26534
+ if (!openedRef.current)
26535
+ return;
26536
+ closingReasonRef.current = reason;
26537
+ hideOverlay();
26538
+ }, [hideOverlay]);
26539
+ const togglePopover = useCallback(() => {
26540
+ if (openedRef.current) {
26541
+ closePopover('programmatic');
26542
+ }
26543
+ else {
26544
+ openPopover();
26545
+ }
26546
+ }, [closePopover, openPopover]);
26547
+ useEffect(() => {
26548
+ if (opened) {
26549
+ updateAnchorMeasurements();
26550
+ }
26551
+ }, [opened, updateAnchorMeasurements]);
26552
+ useEffect(() => {
26553
+ if (!opened) {
26554
+ closingReasonRef.current = null;
26555
+ hideOverlay();
26556
+ if (returnFocus && anchorRef.current && typeof anchorRef.current.focus === 'function') {
26557
+ anchorRef.current.focus();
26558
+ }
26559
+ return;
26560
+ }
26561
+ if (!dropdownState)
26562
+ return;
26563
+ updatePosition();
26564
+ }, [opened, dropdownState, updatePosition, hideOverlay, anchorRef, returnFocus]);
26565
+ useEffect(() => {
26566
+ var _a;
26567
+ if (!opened || !dropdownState) {
26568
+ hideOverlay();
26569
+ return;
26570
+ }
26571
+ if (!positioningResult) {
26572
+ return;
26573
+ }
26574
+ const computedFinalWidth = positioningResult.finalWidth && positioningResult.finalWidth > 0
26575
+ ? positioningResult.finalWidth
26576
+ : undefined;
26577
+ const widthOverride = (() => {
26578
+ var _a, _b;
26579
+ if (typeof width === 'number')
26580
+ return width;
26581
+ if (width === 'target') {
26582
+ return (_b = (_a = anchorMeasurementsRef.current) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : computedFinalWidth;
26583
+ }
26584
+ return computedFinalWidth;
26585
+ })();
26586
+ const sizeStyles = {};
26587
+ if (typeof minWidth === 'number')
26588
+ sizeStyles.minWidth = minWidth;
26589
+ if (typeof minHeight === 'number')
26590
+ sizeStyles.minHeight = minHeight;
26591
+ if (typeof maxWidth === 'number')
26592
+ sizeStyles.maxWidth = maxWidth;
26593
+ const resolvedMaxHeight = typeof maxHeight === 'number' ? maxHeight : (_a = positioningResult.maxHeight) !== null && _a !== void 0 ? _a : maxHeight;
26594
+ if (typeof resolvedMaxHeight === 'number')
26595
+ sizeStyles.maxHeight = resolvedMaxHeight;
26596
+ const dropdownStyle = [popoverStyles.dropdown, dropdownState.style, sizeStyles];
26597
+ const content = (jsxs(View, { ref: popoverRef, style: [popoverStyles.wrapper, widthOverride ? { width: widthOverride } : null], pointerEvents: dropdownState.trapFocus ? 'auto' : 'box-none', testID: dropdownState.testID, onLayout: handleDropdownLayout, ...dropdownState.containerProps, children: [jsx(View, { style: dropdownStyle, children: dropdownState.content }), withArrow && (jsx(View, { style: getArrowStyle(positioningResult.placement, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme) }))] }));
26598
+ showOverlay(content, {
26599
+ width: widthOverride,
26600
+ maxHeight: resolvedMaxHeight,
26601
+ zIndex,
26602
+ });
26603
+ onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(positioningResult.placement);
26604
+ }, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, width, maxHeight, minWidth, minHeight, maxWidth, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate]);
26605
+ useEffect(() => {
26606
+ return () => {
26607
+ hideOverlay();
26608
+ };
26609
+ }, [hideOverlay]);
26610
+ const registerDropdown = useCallback((dropdown) => {
26611
+ setDropdownState(dropdown);
26612
+ }, []);
26613
+ const unregisterDropdown = useCallback(() => {
26614
+ if (!keepMounted) {
26615
+ setDropdownState(null);
26616
+ }
26617
+ }, [keepMounted]);
26618
+ const targetId = useMemo(() => id ? `${id}-target` : `popover-target-${Math.random().toString(36).slice(2)}`, [id]);
26619
+ const dropdownId = useMemo(() => id ? `${id}-dropdown` : `popover-dropdown-${Math.random().toString(36).slice(2)}`, [id]);
26620
+ const contextValue = useMemo(() => ({
26621
+ opened,
26622
+ open: openPopover,
26623
+ close: () => closePopover('programmatic'),
26624
+ toggle: togglePopover,
26625
+ registerDropdown,
26626
+ unregisterDropdown,
26627
+ anchorRef,
26628
+ targetId,
26629
+ dropdownId,
26630
+ withRoles,
26631
+ disabled,
26632
+ returnFocus,
26633
+ }), [opened, openPopover, closePopover, togglePopover, registerDropdown, unregisterDropdown, anchorRef, targetId, dropdownId, withRoles, disabled, returnFocus]);
26634
+ const setContainerRef = useCallback((node) => {
26635
+ if (typeof ref === 'function') {
26636
+ ref(node);
26637
+ }
26638
+ else if (ref && 'current' in ref) {
26639
+ ref.current = node;
26640
+ }
26641
+ }, [ref]);
26642
+ return (jsx(PopoverContext.Provider, { value: contextValue, children: jsx(View, { ref: setContainerRef, style: spacingStyles, testID: testID, children: children }) }));
26643
+ };
26644
+ function mergeRefs(...refs) {
26645
+ return (value) => {
26646
+ refs.forEach(ref => {
26647
+ if (!ref)
26648
+ return;
26649
+ if (typeof ref === 'function') {
26650
+ ref(value);
26651
+ }
26652
+ else if ('current' in ref) {
26653
+ ref.current = value;
26654
+ }
26655
+ });
26656
+ };
26657
+ }
26658
+ const PopoverTargetBase = (props, ref) => {
26659
+ var _a;
26660
+ const { children, popupType = 'dialog', refProp = 'ref', targetProps } = props;
26661
+ const context = usePopoverContext('Popover.Target');
26662
+ if (!isValidElement(children)) {
26663
+ throw new Error('Popover.Target expects a single React element child');
26664
+ }
26665
+ const childProps = children.props;
26666
+ const sanitizedTargetProps = { ...(targetProps !== null && targetProps !== void 0 ? targetProps : {}) };
26667
+ let externalTargetRef;
26668
+ if (refProp && Object.prototype.hasOwnProperty.call(sanitizedTargetProps, refProp)) {
26669
+ externalTargetRef = sanitizedTargetProps[refProp];
26670
+ delete sanitizedTargetProps[refProp];
26671
+ }
26672
+ const accessibilityProps = context.withRoles && Platform.OS === 'web'
26673
+ ? {
26674
+ role: (_a = childProps.role) !== null && _a !== void 0 ? _a : 'button',
26675
+ 'aria-haspopup': popupType,
26676
+ 'aria-expanded': context.opened,
26677
+ 'aria-controls': context.opened ? context.dropdownId : undefined,
26678
+ id: context.targetId,
26679
+ }
26680
+ : { id: context.targetId };
26681
+ const composedRef = mergeRefs(children.ref, externalTargetRef);
26682
+ const triggerHandlers = {};
26683
+ triggerHandlers.onPress = (...args) => {
26684
+ const tgt = targetProps;
26685
+ if (tgt && typeof tgt.onPress === 'function') {
26686
+ tgt.onPress(...args);
26687
+ }
26688
+ if (typeof childProps.onPress === 'function') {
26689
+ childProps.onPress(...args);
26690
+ }
26691
+ context.toggle();
26692
+ };
26693
+ if (Platform.OS === 'web') {
26694
+ triggerHandlers.onKeyDown = (event) => {
26695
+ const tgt = targetProps;
26696
+ if (tgt && typeof tgt.onKeyDown === 'function') {
26697
+ tgt.onKeyDown(event);
26698
+ }
26699
+ if (typeof childProps.onKeyDown === 'function') {
26700
+ childProps.onKeyDown(event);
26701
+ }
26702
+ if (event.defaultPrevented)
26703
+ return;
26704
+ if (event.key === 'Escape' && context.opened) {
26705
+ context.close();
26706
+ }
26707
+ if ((event.key === 'Enter' || event.key === ' ') && !context.opened) {
26708
+ event.preventDefault();
26709
+ context.open();
26710
+ }
26711
+ };
26712
+ }
26713
+ const dynamicRefProp = { [refProp]: composedRef };
26714
+ delete sanitizedTargetProps.onPress;
26715
+ delete sanitizedTargetProps.onKeyDown;
26716
+ const mergedProps = {
26717
+ ...sanitizedTargetProps,
26718
+ ...triggerHandlers,
26719
+ ...accessibilityProps,
26720
+ ...dynamicRefProp,
26721
+ };
26722
+ if (context.disabled) {
26723
+ mergedProps.disabled = true;
26724
+ }
26725
+ const anchorWrapperRef = mergeRefs(context.anchorRef, ref);
26726
+ return (jsx(View, { ref: anchorWrapperRef, collapsable: false, children: cloneElement(children, mergedProps) }));
26727
+ };
26728
+ const PopoverDropdownBase = (props, _ref) => {
26729
+ const { children, trapFocus = false, keepMounted, style, testID, ...rest } = props;
26730
+ const context = usePopoverContext('Popover.Dropdown');
26731
+ const dropdownValue = useMemo(() => ({
26732
+ content: children,
26733
+ style,
26734
+ trapFocus,
26735
+ keepMounted,
26736
+ testID,
26737
+ containerProps: rest,
26738
+ }), [children, rest, style, trapFocus, keepMounted, testID]);
26739
+ useEffect(() => {
26740
+ context.registerDropdown(dropdownValue);
26741
+ return () => context.unregisterDropdown();
26742
+ }, [context, dropdownValue]);
26743
+ if (keepMounted) {
26744
+ return (jsx(View, { style: { display: 'none' }, children: children }));
26745
+ }
26746
+ return null;
26747
+ };
26748
+ function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme) {
26749
+ if (Platform.OS !== 'web') {
26750
+ return {
26751
+ width: 0,
26752
+ height: 0,
26753
+ opacity: 0,
26754
+ };
26755
+ }
26756
+ const base = {
26757
+ position: 'absolute',
26758
+ width: arrowSize * 2,
26759
+ height: arrowSize * 2,
26760
+ backgroundColor: theme.backgrounds.surface,
26761
+ transform: [{ rotate: '45deg' }],
26762
+ borderRadius: arrowRadius,
26763
+ borderColor: theme.backgrounds.border,
26764
+ borderWidth: 1,
26765
+ };
26766
+ const [side, alignment] = placement.split('-');
26767
+ switch (side) {
26768
+ case 'top':
26769
+ return {
26770
+ ...base,
26771
+ bottom: -arrowSize,
26772
+ left: alignment === 'end'
26773
+ ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
26774
+ : alignment === 'start'
26775
+ ? (arrowPosition === 'side' ? arrowOffset : arrowSize)
26776
+ : '50%',
26777
+ marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
26778
+ };
26779
+ case 'bottom':
26780
+ return {
26781
+ ...base,
26782
+ top: -arrowSize,
26783
+ left: alignment === 'end'
26784
+ ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
26785
+ : alignment === 'start'
26786
+ ? (arrowPosition === 'side' ? arrowOffset : arrowSize)
26787
+ : '50%',
26788
+ marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
26789
+ };
26790
+ case 'left':
26791
+ return {
26792
+ ...base,
26793
+ right: -arrowSize,
26794
+ top: alignment === 'end'
26795
+ ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
26796
+ : alignment === 'start'
26797
+ ? (arrowPosition === 'side' ? arrowOffset : arrowSize)
26798
+ : '50%',
26799
+ marginTop: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
26800
+ };
26801
+ case 'right':
26802
+ return {
26803
+ ...base,
26804
+ left: -arrowSize,
26805
+ top: alignment === 'end'
26806
+ ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
26807
+ : alignment === 'start'
26808
+ ? (arrowPosition === 'side' ? arrowOffset : arrowSize)
26809
+ : '50%',
26810
+ marginTop: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
26811
+ };
26812
+ default:
26813
+ return base;
26814
+ }
26815
+ }
26816
+ const Popover = factory(PopoverBase);
26817
+ const PopoverTarget = factory(PopoverTargetBase);
26818
+ const PopoverDropdown = factory(PopoverDropdownBase);
26819
+ Popover.Target = PopoverTarget;
26820
+ Popover.Dropdown = PopoverDropdown;
26821
+ Popover.displayName = 'Popover';
26822
+ PopoverTarget.displayName = 'Popover.Target';
26823
+ PopoverDropdown.displayName = 'Popover.Dropdown';
26824
+
25746
26825
  const getSpacingValue = (spacing, theme) => {
25747
26826
  if (typeof spacing === 'number')
25748
26827
  return spacing;
@@ -26837,7 +27916,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
26837
27916
  else {
26838
27917
  setInternalSearchValue(value);
26839
27918
  }
26840
- setForceUpdateCounter(c => c + 1);
26841
27919
  }, [onSearchChange]);
26842
27920
  const handleSort = useCallback((columnKey) => {
26843
27921
  if (!onSortChange)
@@ -26975,43 +28053,44 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
26975
28053
  alignItems: 'center',
26976
28054
  marginBottom: DESIGN_TOKENS.spacing.md,
26977
28055
  paddingHorizontal: DESIGN_TOKENS.spacing.xs
26978
- }, 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: "caption", 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(Menu, { position: "bottom-end", offset: 4, children: [jsxs(MenuDropdown, { children: [jsx(MenuLabel, { children: "Search & Filter" }), searchable && (jsxs(View, { style: { borderBottomWidth: 1, borderBottomColor: theme.colors.gray[2] }, children: [jsx(Text, { variant: "caption", weight: "semibold", style: { marginBottom: 8 }, children: "Search" }), jsx(Input, { placeholder: searchPlaceholder, value: searchValue, onChangeText: handleSearchChange, leftSection: jsx(Icon, { name: "menu", size: 16 }), size: "sm" }, `search-input-${searchValue}`)] })), columns.some(c => c.filterable) && (jsxs(View, { style: { padding: 12 }, children: [jsxs(Flex, { direction: "row", justify: "space-between", align: "center", style: { marginBottom: 8 }, children: [jsx(Text, { variant: "caption", weight: "semibold", children: "Filters" }), activeFilters.length > 0 && (jsx(Button, { variant: "ghost", size: "xs", onPress: () => {
26979
- setInternalFilters([]);
26980
- setForceUpdateCounter(c => c + 1);
26981
- }, children: "Clear all" }))] }), activeFilters.length > 0 && (jsx(View, { style: { marginBottom: DESIGN_TOKENS.spacing.md, gap: DESIGN_TOKENS.spacing.xs }, children: activeFilters.map((filter, idx) => {
26982
- const column = columns.find(c => c.key === filter.column);
26983
- return (jsxs(View, { style: {
26984
- flexDirection: 'row',
26985
- alignItems: 'center',
26986
- backgroundColor: theme.colors.primary[1],
26987
- paddingHorizontal: DESIGN_TOKENS.spacing.sm,
26988
- paddingVertical: DESIGN_TOKENS.spacing.xs,
26989
- borderRadius: DESIGN_TOKENS.radius.sm,
26990
- gap: DESIGN_TOKENS.spacing.xs
26991
- }, children: [jsxs(Text, { variant: "caption", style: { color: theme.colors.primary[7] }, children: [(column === null || column === void 0 ? void 0 : column.header) || filter.column, ": ", filter.operator, " \"", filter.value, "\""] }), jsx(Pressable, { onPress: () => {
26992
- setInternalFilters(filters => filters.filter((_, i) => i !== idx));
26993
- setForceUpdateCounter(c => c + 1);
26994
- }, children: jsx(Icon, { name: "x", size: 12, color: theme.colors.primary[6] }) })] }, idx));
26995
- }) })), jsx(View, { style: { gap: DESIGN_TOKENS.spacing.sm }, children: columns.filter(c => c.filterable).map(column => {
26996
- const currentFilter = getColumnFilter(column.key);
26997
- return (jsx(View, { children: renderFilterControl(column) }, `${column.key}-${(currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.value) || 'no-filter'}`));
26998
- }) })] }))] }), jsxs(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsx(View, { style: {
26999
- width: 6,
27000
- height: 6,
27001
- borderRadius: 3,
27002
- backgroundColor: theme.colors.primary[5],
27003
- marginLeft: 4
27004
- } }))] })] }, `search-filter-${forceUpdateCounter}`)), onEditModeChange && (jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxs(Menu, { position: "bottom-end", offset: 4, children: [jsxs(MenuDropdown, { children: [jsx(MenuLabel, { children: "Column Visibility" }), jsxs(View, { style: { padding: 8, maxHeight: 300 }, 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,
27005
- // checked={!hiddenColumns.includes(col.key)}
27006
- // disabled={col.disableHiding}
27007
- onChange: () => {
27008
- if (hiddenColumns.includes(col.key)) {
27009
- setHiddenColumns(prev => prev.filter(h => h !== col.key));
27010
- }
27011
- else {
27012
- setHiddenColumns(prev => [...prev, col.key]);
27013
- }
27014
- }, style: { marginBottom: 4 } }, col.key))) })] })] }), jsx(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "eye", size: 14 }), children: "Columns" })] }, `col-vis-${forceUpdateCounter}`))] })] }));
28056
+ }, 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: "caption", 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(PopoverTarget, { children: jsxs(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsx(View, { style: {
28057
+ width: 6,
28058
+ height: 6,
28059
+ borderRadius: 3,
28060
+ backgroundColor: theme.colors.primary[5],
28061
+ marginLeft: 4
28062
+ } }))] }) }), jsx(PopoverDropdown, { children: jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.md, style: { width: 320 }, children: [jsx(Text, { variant: "caption", weight: "semibold", children: "Search & Filter" }), searchable && (jsx(View, { style: {
28063
+ borderBottomWidth: 1,
28064
+ borderBottomColor: theme.colors.gray[2],
28065
+ paddingBottom: DESIGN_TOKENS.spacing.sm,
28066
+ }, children: jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, children: [jsx(Text, { variant: "caption", weight: "semibold", children: "Search" }), jsx(Input, { placeholder: searchPlaceholder, value: searchValue, onChangeText: handleSearchChange, leftSection: jsx(Icon, { name: "menu", size: 16 }), size: "sm" })] }) })), columns.some(c => c.filterable) && (jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: [jsxs(Flex, { direction: "row", justify: "space-between", align: "center", children: [jsx(Text, { variant: "caption", weight: "semibold", children: "Filters" }), activeFilters.length > 0 && (jsx(Button, { variant: "ghost", size: "xs", onPress: () => {
28067
+ setInternalFilters([]);
28068
+ setForceUpdateCounter(c => c + 1);
28069
+ }, children: "Clear all" }))] }), activeFilters.length > 0 && (jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, style: { marginBottom: DESIGN_TOKENS.spacing.sm }, children: activeFilters.map((filter, idx) => {
28070
+ const column = columns.find(c => c.key === filter.column);
28071
+ return (jsxs(View, { style: {
28072
+ flexDirection: 'row',
28073
+ alignItems: 'center',
28074
+ backgroundColor: theme.colors.primary[1],
28075
+ paddingHorizontal: DESIGN_TOKENS.spacing.sm,
28076
+ paddingVertical: DESIGN_TOKENS.spacing.xs,
28077
+ borderRadius: DESIGN_TOKENS.radius.sm,
28078
+ gap: DESIGN_TOKENS.spacing.xs
28079
+ }, children: [jsxs(Text, { variant: "caption", style: { color: theme.colors.primary[7] }, children: [(column === null || column === void 0 ? void 0 : column.header) || filter.column, ": ", filter.operator, " \"", filter.value, "\""] }), jsx(Pressable, { onPress: () => {
28080
+ setInternalFilters(filters => filters.filter((_, i) => i !== idx));
28081
+ setForceUpdateCounter(c => c + 1);
28082
+ }, children: jsx(Icon, { name: "x", size: 12, color: theme.colors.primary[6] }) })] }, idx));
28083
+ }) })), jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: columns.filter(c => c.filterable).map(column => {
28084
+ const currentFilter = getColumnFilter(column.key);
28085
+ return (jsx(View, { children: renderFilterControl(column) }, `${column.key}-${(currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.value) || 'no-filter'}`));
28086
+ }) })] }))] }) })] })), 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(PopoverTarget, { children: jsx(Button, { variant: "outline", size: "sm", startIcon: jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsx(PopoverDropdown, { 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: () => {
28087
+ if (hiddenColumns.includes(col.key)) {
28088
+ setHiddenColumns(prev => prev.filter(h => h !== col.key));
28089
+ }
28090
+ else {
28091
+ setHiddenColumns(prev => [...prev, col.key]);
28092
+ }
28093
+ }, style: { marginBottom: 4 } }, col.key))) })] }) })] }))] })] }));
27015
28094
  const renderCell = useCallback((column, row, rowIndex) => {
27016
28095
  const value = getValue(row, column.accessor);
27017
28096
  const isEditing = (editingCell === null || editingCell === void 0 ? void 0 : editingCell.row) === rowIndex && (editingCell === null || editingCell === void 0 ? void 0 : editingCell.column) === column.key;
@@ -30455,7 +31534,7 @@ loading = false, error, loadingProgress, selection, onSelectionChange, zoomLevel
30455
31534
  };
30456
31535
  const gradientId = useMemo(() => `waveform-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
30457
31536
  const renderGradient = () => {
30458
- return (jsxs(Fragment, { children: [jsx(Defs, { children: jsx(LinearGradient$2, { 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) => {
31537
+ 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) => {
30459
31538
  const x = index * (barWidth + barGap);
30460
31539
  const barHeight = Math.max(minBarHeight, Math.abs(peak) * height * 0.8);
30461
31540
  const y = (height - barHeight) / 2;
@@ -33063,7 +34142,7 @@ function QRCodeSVG(props) {
33063
34142
  const logoSize = (_a = logo === null || logo === void 0 ? void 0 : logo.size) !== null && _a !== void 0 ? _a : 40;
33064
34143
  const logoX = (size - logoSize) / 2;
33065
34144
  const logoY = (size - logoSize) / 2;
33066
- return (jsxs(View, { style: containerStyle, testID: testID, ...rest, children: [jsxs(Svg, { width: size, height: size, viewBox: `0 0 ${size} ${size}`, accessibilityLabel: accessibilityLabel || `QR Code containing: ${value}`, children: [jsxs(Defs, { children: [gradient && gradient.type !== 'radial' && (jsxs(LinearGradient$2, { id: "qrGradient", x1: "0%", y1: "0%", x2: gradient.rotation ? '100%' : '100%', y2: gradient.rotation ? '0%' : '100%', children: [jsx(Stop, { offset: "0%", stopColor: gradient.from }), jsx(Stop, { offset: "100%", stopColor: gradient.to })] })), gradient && gradient.type === 'radial' && (jsxs(RadialGradient, { id: "qrGradient", cx: "50%", cy: "50%", r: "50%", children: [jsx(Stop, { offset: "0%", stopColor: gradient.from }), jsx(Stop, { offset: "100%", stopColor: gradient.to })] })), logo && (jsx(ClipPath, { id: "logoClip", children: jsx(Rect, { x: logoX, y: logoY, width: logoSize, height: logoSize, rx: logo.borderRadius || 8, ry: logo.borderRadius || 8 }) }))] }), jsx(Rect, { x: 0, y: 0, width: size, height: size, fill: backgroundColor }), jsx(Path, { d: qrPath, fill: gradient ? 'url(#qrGradient)' : color, fillRule: "evenodd" }), moduleShape === 'rounded' && roundedRects.length > 0 && (roundedRects.map((d, i) => jsx(Path, { d: d, fill: gradient ? 'url(#qrGradient)' : color }, `rounded-${i}`))), moduleShape === 'diamond' && diamondPaths.length > 0 && (diamondPaths.map((d, i) => jsx(Path, { d: d, fill: gradient ? 'url(#qrGradient)' : color }, `diamond-${i}`))), logo && (jsx(Rect
34145
+ return (jsxs(View, { style: containerStyle, testID: testID, ...rest, children: [jsxs(Svg, { width: size, height: size, viewBox: `0 0 ${size} ${size}`, accessibilityLabel: accessibilityLabel || `QR Code containing: ${value}`, children: [jsxs(Defs, { children: [gradient && gradient.type !== 'radial' && (jsxs(LinearGradient, { id: "qrGradient", x1: "0%", y1: "0%", x2: gradient.rotation ? '100%' : '100%', y2: gradient.rotation ? '0%' : '100%', children: [jsx(Stop, { offset: "0%", stopColor: gradient.from }), jsx(Stop, { offset: "100%", stopColor: gradient.to })] })), gradient && gradient.type === 'radial' && (jsxs(RadialGradient, { id: "qrGradient", cx: "50%", cy: "50%", r: "50%", children: [jsx(Stop, { offset: "0%", stopColor: gradient.from }), jsx(Stop, { offset: "100%", stopColor: gradient.to })] })), logo && (jsx(ClipPath, { id: "logoClip", children: jsx(Rect, { x: logoX, y: logoY, width: logoSize, height: logoSize, rx: logo.borderRadius || 8, ry: logo.borderRadius || 8 }) }))] }), jsx(Rect, { x: 0, y: 0, width: size, height: size, fill: backgroundColor }), jsx(Path, { d: qrPath, fill: gradient ? 'url(#qrGradient)' : color, fillRule: "evenodd" }), moduleShape === 'rounded' && roundedRects.length > 0 && (roundedRects.map((d, i) => jsx(Path, { d: d, fill: gradient ? 'url(#qrGradient)' : color }, `rounded-${i}`))), moduleShape === 'diamond' && diamondPaths.length > 0 && (diamondPaths.map((d, i) => jsx(Path, { d: d, fill: gradient ? 'url(#qrGradient)' : color }, `diamond-${i}`))), logo && (jsx(Rect
33067
34146
  // Clear area under logo (white rect) for better scan reliability
33068
34147
  , {
33069
34148
  // Clear area under logo (white rect) for better scan reliability
@@ -35205,5 +36284,5 @@ function withPressAnimation(Component, animationProps) {
35205
36284
  */
35206
36285
  const AnimatedPressable = PressAnimation;
35207
36286
 
35208
- export { AbilityCore, AccessibilityProvider, Accordion, Alert, 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, Calendar, Can, CanWithConditions, Cannot, Card, Carousel, Checkbox, Chip, ChromeWebStoreBadge, Cite, Code, CodeBlock, ColorPicker, ColorSwatch, Column, ComponentWithDisclaimer, Container, ContextMenu, CopyButton, DARK_THEME, DEFAULT_BREAKPOINTS, 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, HoverCard, HuaweiAppGalleryBadge, I18nProvider, Icon, IconButton, Image, Indicator, Input, Italic, Kbd, KeyCap, Link, ListGroup, ListGroupBody, ListGroupDivider, ListGroupItem, Loader, LoadingOverlay, Lottie, MacAppStoreButton, Mark, Markdown, Masonry, Menu, MenuDivider, MenuDropdown, MenuItem, MenuItemButton, MenuLabel, MicrosoftStoreButton, MicrosoftStoreDownloadBadge, MiniCalendar, Month, MonthPicker, MonthPickerInput, NavigationProgress, NumberInput, Overlay, OverlayProvider, P, Pagination, PasswordInput, PermissionBuilder, PermissionGate, PermissionPatterns, PermissionProvider, PhoneInput, PinInput, PlatformBlocksProvider, PressAnimation, Progress, QRCode, Radio, RadioGroup, RangeSlider, Rating, RedditJoinBadge, RichTextEditor, RoleBuilder, 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, TimePicker, TimePicker as TimePickerInput, TimelineWithItems as Timeline, Title, TitleRegistryProvider, Toast, ToastProvider, ToggleBar, ToggleButton, ToggleGroup, Tooltip, Tree, TwitchWatchBadge, Underline, Video, Waveform, YearPicker, YearPickerInput, YouTubeMusicListenBadge, YouTubeWatchBadge, calculateOverlayPosition, calculateOverlayPositionEnhanced, clearOverlayPositionCache, createSound, createSpotlightStore, createTheme, debounce$1 as debounce, defineAbility, defineAppLayout, defineRoleAbility, 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, navigationProgress, onDialogsRequested, onSpotlightRequested, onToastsRequested, permissions, pointInRect, polymorphicFactory, px, rem, resolveResponsiveProp, resolveResponsiveValue, resolveSize, spotlight, throttle, toast, useAbility, useAccessibility, useAppLayoutContext, useAppShell, useAppShellApi, useAppShellLayout, useBreakpoint, useColorScheme, useDialog, useDialogApi, useDialogs, useDirectSpotlightState, useDirection, useDirectionSafe, useDisclaimer, useDropdownPositioning, useEscapeKey, useFormContext, useGlobalHotkeys, useHaptics, useHapticsSettings, useHotkeys, useI18n, useNavbarHover, useOptionalFormContext, useOverlay, useOverlayApi, useOverlays, usePermissions, usePopoverPositioning, useSimpleDialog, useSound, useSpotlightStore, useSpotlightStoreInstance, useSpotlightToggle, useTheme, useThemeMode, useTitleRegistry, useTitleRegistryOptional, useToast, useToastApi, useToggleColorScheme, useTooltipPositioning, withCan, withCannot, withDisclaimer, withPressAnimation };
36287
+ export { AbilityCore, AccessibilityProvider, Accordion, Alert, 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, Calendar, Can, CanWithConditions, Cannot, Card, Carousel, Checkbox, Chip, ChromeWebStoreBadge, Cite, Code, CodeBlock, ColorPicker, ColorSwatch, Column, ComponentWithDisclaimer, Container, ContextMenu, CopyButton, DARK_THEME, DEFAULT_BREAKPOINTS, 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, HoverCard, HuaweiAppGalleryBadge, I18nProvider, Icon, IconButton, Image, Indicator, Input, Italic, Kbd, KeyCap, Link, ListGroup, ListGroupBody, ListGroupDivider, ListGroupItem, Loader, LoadingOverlay, Lottie, MacAppStoreButton, Mark, Markdown, Masonry, Menu, MenuDivider, MenuDropdown, MenuItem, MenuItemButton, MenuLabel, MicrosoftStoreButton, MicrosoftStoreDownloadBadge, MiniCalendar, Month, MonthPicker, MonthPickerInput, NavigationProgress, NumberInput, Overlay, OverlayProvider, P, Pagination, PasswordInput, PermissionBuilder, PermissionGate, PermissionPatterns, PermissionProvider, PhoneInput, PinInput, PlatformBlocksProvider, Popover, PopoverDropdown, PopoverTarget, PressAnimation, Progress, QRCode, Radio, RadioGroup, RangeSlider, Rating, RedditJoinBadge, RichTextEditor, RoleBuilder, 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, TimePicker, TimePicker as TimePickerInput, TimelineWithItems as Timeline, Title, TitleRegistryProvider, Toast, ToastProvider, ToggleBar, ToggleButton, ToggleGroup, Tooltip, Tree, TwitchWatchBadge, Underline, Video, Waveform, YearPicker, YearPickerInput, YouTubeMusicListenBadge, YouTubeWatchBadge, calculateOverlayPosition, calculateOverlayPositionEnhanced, clearOverlayPositionCache, createSound, createSpotlightStore, createTheme, debounce$1 as debounce, defineAbility, defineAppLayout, defineRoleAbility, 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, navigationProgress, onDialogsRequested, onSpotlightRequested, onToastsRequested, permissions, pointInRect, polymorphicFactory, px, rem, resolveResponsiveProp, resolveResponsiveValue, resolveSize, spotlight, throttle, toast, useAbility, useAccessibility, useAppLayoutContext, useAppShell, useAppShellApi, useAppShellLayout, useBreakpoint, useColorScheme, useDialog, useDialogApi, useDialogs, useDirectSpotlightState, useDirection, useDirectionSafe, useDisclaimer, useDropdownPositioning, useEscapeKey, useFormContext, useGlobalHotkeys, useHaptics, useHapticsSettings, useHotkeys, useI18n, useNavbarHover, useOptionalFormContext, useOverlay, useOverlayApi, useOverlays, usePermissions, usePopoverPositioning, useSimpleDialog, useSound, useSpotlightStore, useSpotlightStoreInstance, useSpotlightToggle, useTheme, useThemeMode, useTitleRegistry, useTitleRegistryOptional, useToast, useToastApi, useToggleColorScheme, useTooltipPositioning, withCan, withCannot, withDisclaimer, withPressAnimation };
35209
36288
  //# sourceMappingURL=index.js.map