radix-native-ui 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,5 @@
1
- //#region rolldown:runtime
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -3144,7 +3145,7 @@ const ToastRoot = (0, react.forwardRef)(({ toast, onDismiss, config, index, styl
3144
3145
  opacity,
3145
3146
  transform: [{ translateY }, { translateX }],
3146
3147
  backgroundColor: colors.backgroundColor,
3147
- borderColor: colors.borderColor,
3148
+ borderColor: "transparent",
3148
3149
  borderWidth: 1,
3149
3150
  borderRadius: theme.radii.large,
3150
3151
  padding: theme.space[4],
@@ -3169,23 +3170,23 @@ const ToastRoot = (0, react.forwardRef)(({ toast, onDismiss, config, index, styl
3169
3170
  accessibilityLiveRegion: "polite",
3170
3171
  accessibilityLabel: toast.accessibilityLabel || toast.title,
3171
3172
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
3172
- style: [styles$32.contentContainer, { alignItems: toast.description ? "flex-start" : "center" }],
3173
+ style: [styles$34.contentContainer, { alignItems: toast.description ? "flex-start" : "center" }],
3173
3174
  children: [
3174
3175
  toast.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
3175
- style: styles$32.iconContainer,
3176
+ style: styles$34.iconContainer,
3176
3177
  children: toast.icon
3177
3178
  }),
3178
3179
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
3179
- style: styles$32.textContainer,
3180
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3181
- style: [styles$32.title, {
3180
+ style: styles$34.textContainer,
3181
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3182
+ style: [styles$34.title, {
3182
3183
  color: colors.textColor,
3183
3184
  fontSize: theme.typography.fontSizes[3].fontSize
3184
3185
  }],
3185
3186
  numberOfLines: 1,
3186
3187
  children: toast.title
3187
- }), toast.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3188
- style: [styles$32.description, {
3188
+ }), toast.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3189
+ style: [styles$34.description, {
3189
3190
  fontSize: theme.typography.fontSizes[2].fontSize,
3190
3191
  lineHeight: theme.typography.fontSizes[2].fontSize * 1.5,
3191
3192
  opacity: .8
@@ -3196,14 +3197,14 @@ const ToastRoot = (0, react.forwardRef)(({ toast, onDismiss, config, index, styl
3196
3197
  }),
3197
3198
  toast.action && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
3198
3199
  onPress: toast.action.onPress,
3199
- style: ({ pressed }) => [styles$32.actionButton, { opacity: pressed ? .7 : 1 }],
3200
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3201
- style: [styles$32.actionText, { color: colors.accentColor }],
3200
+ style: ({ pressed }) => [styles$34.actionButton, { opacity: pressed ? .7 : 1 }],
3201
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3202
+ style: [styles$34.actionText, { color: colors.accentColor }],
3202
3203
  children: toast.action.label
3203
3204
  })
3204
3205
  }),
3205
3206
  toast.showClose && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
3206
- style: { backgroundColor: colors.textColor },
3207
+ color: getVariantColorName(toast.variant),
3207
3208
  radius: "large",
3208
3209
  size: 1,
3209
3210
  onPress: () => handleDismiss(true),
@@ -3222,10 +3223,10 @@ const ToastViewport = (0, react.forwardRef)(({ style }, ref) => {
3222
3223
  if (toasts.length === 0) return null;
3223
3224
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
3224
3225
  ref,
3225
- style: [styles$32.viewport, style],
3226
+ style: [styles$34.viewport, style],
3226
3227
  pointerEvents: "box-none",
3227
3228
  children: [topToasts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.SafeAreaView, {
3228
- style: styles$32.topContainer,
3229
+ style: styles$34.topContainer,
3229
3230
  pointerEvents: "box-none",
3230
3231
  children: topToasts.map((toast, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToastRoot, {
3231
3232
  toast,
@@ -3234,7 +3235,7 @@ const ToastViewport = (0, react.forwardRef)(({ style }, ref) => {
3234
3235
  index
3235
3236
  }, toast.id))
3236
3237
  }), bottomToasts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.SafeAreaView, {
3237
- style: styles$32.bottomContainer,
3238
+ style: styles$34.bottomContainer,
3238
3239
  pointerEvents: "box-none",
3239
3240
  children: bottomToasts.map((toast, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToastRoot, {
3240
3241
  toast,
@@ -3248,10 +3249,10 @@ const ToastViewport = (0, react.forwardRef)(({ style }, ref) => {
3248
3249
  ToastViewport.displayName = "Toast.Viewport";
3249
3250
  const ToastTitle = (0, react.forwardRef)(({ children, style }, ref) => {
3250
3251
  const theme = useTheme$1();
3251
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3252
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3252
3253
  ref,
3253
3254
  style: [
3254
- styles$32.title,
3255
+ styles$34.title,
3255
3256
  { fontSize: theme.typography.fontSizes[2].fontSize },
3256
3257
  style
3257
3258
  ],
@@ -3261,10 +3262,10 @@ const ToastTitle = (0, react.forwardRef)(({ children, style }, ref) => {
3261
3262
  ToastTitle.displayName = "Toast.Title";
3262
3263
  const ToastDescription = (0, react.forwardRef)(({ children, style }, ref) => {
3263
3264
  const theme = useTheme$1();
3264
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3265
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3265
3266
  ref,
3266
3267
  style: [
3267
- styles$32.description,
3268
+ styles$34.description,
3268
3269
  { fontSize: theme.typography.fontSizes[1].fontSize },
3269
3270
  style
3270
3271
  ],
@@ -3277,7 +3278,7 @@ const ToastClose = (0, react.forwardRef)(({ children, onPress, style }, ref) =>
3277
3278
  ref,
3278
3279
  onPress,
3279
3280
  style: ({ pressed }) => [
3280
- styles$32.closeButton,
3281
+ styles$34.closeButton,
3281
3282
  { opacity: pressed ? .7 : 1 },
3282
3283
  style
3283
3284
  ],
@@ -3287,7 +3288,7 @@ const ToastClose = (0, react.forwardRef)(({ children, onPress, style }, ref) =>
3287
3288
  left: 8,
3288
3289
  right: 8
3289
3290
  },
3290
- children: children || /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, { children: "✕" })
3291
+ children: children || /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, { children: "✕" })
3291
3292
  });
3292
3293
  });
3293
3294
  ToastClose.displayName = "Toast.Close";
@@ -3297,18 +3298,18 @@ const ToastAction = (0, react.forwardRef)(({ label, onPress, style }, ref) => {
3297
3298
  ref,
3298
3299
  onPress,
3299
3300
  style: ({ pressed }) => [
3300
- styles$32.actionButton,
3301
+ styles$34.actionButton,
3301
3302
  { opacity: pressed ? .7 : 1 },
3302
3303
  style
3303
3304
  ],
3304
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
3305
- style: [styles$32.actionText, { color: theme.accentColor === "indigo" ? theme.colors.indigo[9] : theme.colors[theme.accentColor]?.[9] || theme.colors.indigo[9] }],
3305
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
3306
+ style: [styles$34.actionText, { color: theme.accentColor === "indigo" ? theme.colors.indigo[9] : theme.colors[theme.accentColor]?.[9] || theme.colors.indigo[9] }],
3306
3307
  children: label
3307
3308
  })
3308
3309
  });
3309
3310
  });
3310
3311
  ToastAction.displayName = "Toast.Action";
3311
- const styles$32 = react_native.StyleSheet.create({
3312
+ const styles$34 = react_native.StyleSheet.create({
3312
3313
  viewport: {
3313
3314
  ...react_native.StyleSheet.absoluteFillObject,
3314
3315
  pointerEvents: "box-none"
@@ -3342,7 +3343,7 @@ const styles$32 = react_native.StyleSheet.create({
3342
3343
  },
3343
3344
  title: { fontWeight: "500" },
3344
3345
  description: {
3345
- marginTop: 2,
3346
+ marginTop: 1,
3346
3347
  opacity: .8
3347
3348
  },
3348
3349
  actionButton: {
@@ -3408,7 +3409,7 @@ const useThemeContext = () => {
3408
3409
  * 2. themeOptions object (legacy support)
3409
3410
  * 3. Default values
3410
3411
  */
3411
- const ThemeProvider = ({ children, accentColor, grayColor, radius, scaling, panelBackground, mode: initialMode, appearance, forcedMode, onModeChange, themeOptions = {}, toastConfig: userToastConfig }) => {
3412
+ const ThemeProvider = ({ children, accentColor, grayColor, radius, scaling, panelBackground, mode: initialMode, appearance, forcedMode, onModeChange, themeOptions = {}, toastConfig: userToastConfig, haptics: globalHaptics }) => {
3412
3413
  const parentContext = (0, react.useContext)(ThemeContext);
3413
3414
  const deviceColorScheme = useDeviceColorScheme();
3414
3415
  const resolvedInitialMode = appearance === "inherit" ? void 0 : appearance ?? initialMode;
@@ -3426,9 +3427,10 @@ const ThemeProvider = ({ children, accentColor, grayColor, radius, scaling, pane
3426
3427
  parentContext?.mode,
3427
3428
  deviceColorScheme
3428
3429
  ]);
3429
- const handleSetMode = (newMode) => {
3430
- setMode(newMode);
3431
- onModeChange?.(newMode);
3430
+ const handleSetMode = (newAppearance) => {
3431
+ if (newAppearance === "inherit") setMode(deviceColorScheme ?? "light");
3432
+ else setMode(newAppearance);
3433
+ onModeChange?.(newAppearance === "inherit" ? deviceColorScheme ?? "light" : newAppearance);
3432
3434
  };
3433
3435
  const toggleMode = () => {
3434
3436
  handleSetMode(mode === "light" ? "dark" : "light");
@@ -3499,11 +3501,14 @@ const ThemeProvider = ({ children, accentColor, grayColor, radius, scaling, pane
3499
3501
  ...options
3500
3502
  } : t));
3501
3503
  }, []);
3504
+ const resolvedHaptics = globalHaptics ?? true;
3502
3505
  const value = (0, react.useMemo)(() => ({
3503
3506
  theme,
3504
3507
  mode,
3508
+ appearance: appearance ?? "inherit",
3505
3509
  setMode: handleSetMode,
3506
3510
  toggleMode,
3511
+ haptics: resolvedHaptics,
3507
3512
  toastConfig,
3508
3513
  toasts,
3509
3514
  showToast,
@@ -3513,7 +3518,9 @@ const ThemeProvider = ({ children, accentColor, grayColor, radius, scaling, pane
3513
3518
  }), [
3514
3519
  theme,
3515
3520
  mode,
3521
+ appearance,
3516
3522
  toggleMode,
3523
+ resolvedHaptics,
3517
3524
  toastConfig,
3518
3525
  toasts,
3519
3526
  showToast,
@@ -3542,14 +3549,22 @@ const useThemeMode = () => {
3542
3549
  * Hook to access theme mode setter and toggle
3543
3550
  */
3544
3551
  const useThemeActions = () => {
3545
- const { setMode, toggleMode, mode } = useThemeContext();
3552
+ const { setMode, toggleMode, mode, appearance } = useThemeContext();
3546
3553
  return {
3547
3554
  setMode,
3548
3555
  toggleMode,
3549
- mode
3556
+ mode,
3557
+ appearance
3550
3558
  };
3551
3559
  };
3552
3560
  /**
3561
+ * Hook to access the global haptics setting
3562
+ * @returns boolean - whether haptics are enabled globally
3563
+ */
3564
+ const useHaptics = () => {
3565
+ return useThemeContext().haptics;
3566
+ };
3567
+ /**
3553
3568
  * Hook to access toast functionality
3554
3569
  */
3555
3570
  const useToast = () => {
@@ -3621,6 +3636,15 @@ const useThemeColors = () => {
3621
3636
  panel: isDark ? theme.colors.gray.dark[2] : "#ffffff"
3622
3637
  };
3623
3638
  };
3639
+ /**
3640
+ * Hook to access the global haptics setting
3641
+ * @returns boolean - whether haptics are enabled globally
3642
+ */
3643
+ const useHaptics$1 = () => {
3644
+ const context = (0, react.useContext)(ThemeContext);
3645
+ if (!context) throw new Error("useHaptics must be used within a ThemeProvider");
3646
+ return context.haptics;
3647
+ };
3624
3648
 
3625
3649
  //#endregion
3626
3650
  //#region src/components/primitives/View.tsx
@@ -3638,7 +3662,6 @@ const RnView = react.default.memo(react.default.forwardRef(({ style, wrap, ...re
3638
3662
  });
3639
3663
  }));
3640
3664
  RnView.displayName = "RnView";
3641
- var View_default = RnView;
3642
3665
 
3643
3666
  //#endregion
3644
3667
  //#region src/components/primitives/Text.tsx
@@ -3690,7 +3713,6 @@ const RnPressable = react.default.memo(react.default.forwardRef(({ style, onPres
3690
3713
  });
3691
3714
  }));
3692
3715
  RnPressable.displayName = "RnPressable";
3693
- var Pressable_default = RnPressable;
3694
3716
 
3695
3717
  //#endregion
3696
3718
  //#region src/components/primitives/TouchableOpacity.tsx
@@ -3810,10 +3832,67 @@ const RnActivityIndicator = react.default.memo(react.default.forwardRef(({ color
3810
3832
  }));
3811
3833
  RnActivityIndicator.displayName = "RnActivityIndicator";
3812
3834
 
3835
+ //#endregion
3836
+ //#region src/utils/haptics.ts
3837
+ /**
3838
+ * Try to import expo-haptics, fallback to null if not available
3839
+ */
3840
+ let Haptics = null;
3841
+ (async () => {
3842
+ try {
3843
+ Haptics = await import("expo-haptics");
3844
+ } catch {}
3845
+ })();
3846
+ /**
3847
+ * Triggers haptic feedback with graceful fallback
3848
+ *
3849
+ * On iOS with expo-haptics:
3850
+ * - Uses Taptic Engine for precise, varied feedback (10-20ms)
3851
+ *
3852
+ * On Android or without expo-haptics:
3853
+ * - Falls back to basic vibration (10ms on Android, 400ms on iOS)
3854
+ *
3855
+ * @param type - The type of haptic feedback to trigger (default: 'selection')
3856
+ */
3857
+ const triggerHaptic = (type = "selection") => {
3858
+ if (Haptics) try {
3859
+ switch (type) {
3860
+ case "selection":
3861
+ Haptics.selectionAsync();
3862
+ break;
3863
+ case "press":
3864
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
3865
+ break;
3866
+ case "impactLight":
3867
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
3868
+ break;
3869
+ case "impactMedium":
3870
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
3871
+ break;
3872
+ case "impactHeavy":
3873
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy);
3874
+ break;
3875
+ case "notificationSuccess":
3876
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
3877
+ break;
3878
+ case "notificationWarning":
3879
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
3880
+ break;
3881
+ case "notificationError":
3882
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
3883
+ break;
3884
+ }
3885
+ } catch (error) {
3886
+ react_native.Platform.OS === "android" && react_native.Vibration.vibrate(10);
3887
+ }
3888
+ else react_native.Platform.OS === "android" && react_native.Vibration.vibrate(10);
3889
+ };
3890
+
3813
3891
  //#endregion
3814
3892
  //#region src/components/primitives/AnimatedPressable.tsx
3815
- const AnimatedPressableComponent = react_native.Animated.createAnimatedComponent(Pressable_default);
3893
+ const AnimatedPressableComponent = react_native.Animated.createAnimatedComponent(RnPressable);
3816
3894
  const AnimatedPressable = react.default.memo(react.default.forwardRef(({ children, onPressIn, onPressOut, disabled, pressedScale = .97, pressedOpacity = .9, animationDuration = 100, hapticFeedback = true, style, ...rest }, ref) => {
3895
+ const globalHaptics = useHaptics$1();
3817
3896
  const scaleAnim = (0, react.useRef)(new react_native.Animated.Value(1)).current;
3818
3897
  const opacityAnim = (0, react.useRef)(new react_native.Animated.Value(1)).current;
3819
3898
  const animatePressIn = (0, react.useCallback)(() => {
@@ -3853,12 +3932,13 @@ const AnimatedPressable = react.default.memo(react.default.forwardRef(({ childre
3853
3932
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressableComponent, {
3854
3933
  ref,
3855
3934
  onPressIn: (0, react.useCallback)((event) => {
3856
- if (hapticFeedback && !disabled) react_native.Vibration.vibrate(10);
3935
+ if (globalHaptics && hapticFeedback && !disabled) triggerHaptic("press");
3857
3936
  animatePressIn();
3858
3937
  onPressIn?.(event);
3859
3938
  }, [
3860
3939
  animatePressIn,
3861
3940
  onPressIn,
3941
+ globalHaptics,
3862
3942
  hapticFeedback,
3863
3943
  disabled
3864
3944
  ]),
@@ -3877,7 +3957,6 @@ const AnimatedPressable = react.default.memo(react.default.forwardRef(({ childre
3877
3957
  });
3878
3958
  }));
3879
3959
  AnimatedPressable.displayName = "AnimatedPressable";
3880
- var AnimatedPressable_default = AnimatedPressable;
3881
3960
 
3882
3961
  //#endregion
3883
3962
  //#region src/components/layout/Box.tsx
@@ -4749,12 +4828,12 @@ const Strong = react.default.memo(react.default.forwardRef(({ children, style =
4749
4828
  const colors = useThemeMode$1() === "dark" ? theme.colors.gray.dark : theme.colors.gray;
4750
4829
  const strongFont = theme.typography.fonts.strong;
4751
4830
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
4831
+ color,
4752
4832
  ref,
4753
4833
  style: [(0, react.useMemo)(() => ({
4754
4834
  fontFamily: strongFont.fontFamily,
4755
4835
  fontWeight: strongFont.fontWeight,
4756
- fontStyle: strongFont.fontStyle,
4757
- color: color || colors[12]
4836
+ fontStyle: strongFont.fontStyle
4758
4837
  }), [
4759
4838
  strongFont,
4760
4839
  color,
@@ -5015,7 +5094,7 @@ const areEqual = (prevProps, nextProps) => {
5015
5094
  if (prevProps.children === nextProps.children && prevProps.style === nextProps.style && prevProps.variant === nextProps.variant && prevProps.color === nextProps.color && prevProps.radius === nextProps.radius && prevProps.size === nextProps.size && prevProps.disabled === nextProps.disabled && prevProps.loading === nextProps.loading && prevProps.onPress === nextProps.onPress && prevProps.onLongPress === nextProps.onLongPress && prevProps.delayLongPress === nextProps.delayLongPress && prevProps.width === nextProps.width && prevProps.highContrast === nextProps.highContrast) return true;
5016
5095
  return false;
5017
5096
  };
5018
- const Button = react.default.memo(react.default.forwardRef(({ children, style, variant = "classic", color, radius, size = 2, disabled, loading, onPress, accessibilityLabel, width, highContrast, hapticFeedback, ...rest }, ref) => {
5097
+ const Button = react.default.memo(react.default.forwardRef(({ children, style, variant = "solid", color, radius, size = 2, disabled, loading, onPress, accessibilityLabel, width, highContrast, hapticFeedback, ...rest }, ref) => {
5019
5098
  const theme = useTheme$1();
5020
5099
  const mode = useThemeMode$1();
5021
5100
  const isDark = mode === "dark";
@@ -5169,7 +5248,7 @@ const Button = react.default.memo(react.default.forwardRef(({ children, style, v
5169
5248
  children: labelProps.children
5170
5249
  }, "label");
5171
5250
  };
5172
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
5251
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
5173
5252
  ref,
5174
5253
  style: [buttonStyle, style],
5175
5254
  onPress: handlePress,
@@ -5202,52 +5281,48 @@ Button.Label = ButtonLabel;
5202
5281
 
5203
5282
  //#endregion
5204
5283
  //#region src/components/forms/IconButton.tsx
5205
- const IconButton = react.default.forwardRef(({ children, style = {}, variant = "classic", color, size = 2, radius, asChild = false, disabled, loading, onPress, accessibilityLabel, highContrast, hapticFeedback, ...rest }, ref) => {
5284
+ const IconButton = react.default.forwardRef(({ children, style = {}, variant = "solid", color, size = 2, radius, asChild = false, disabled, loading, onPress, accessibilityLabel, highContrast, hapticFeedback, ...rest }, ref) => {
5206
5285
  const theme = useTheme$1();
5207
5286
  const mode = useThemeMode$1();
5208
5287
  mode === "dark" ? theme.colors.gray.dark : theme.colors.gray;
5209
5288
  const grayAlpha = getGrayAlpha(theme);
5210
5289
  getAccentColor(theme, mode);
5211
5290
  getAccentAlpha(theme);
5212
- const radii = theme.radii;
5213
- const activeColor = color || theme.accentColor;
5214
- const getBorderRadius = () => {
5215
- if (radius) return radius === "full" ? 9999 : radii[radius];
5216
- };
5217
- const variantColors = getVariantColors(theme, activeColor, mode, variant, highContrast);
5291
+ const radii = theme.radii[radius || theme.radius] ?? theme.radii.medium;
5292
+ const selectedRadius = radius || theme.radius;
5293
+ const variantColors = getVariantColors(theme, color || theme.accentColor, mode, variant, highContrast);
5218
5294
  const getSizeValues = () => {
5219
5295
  switch (size) {
5220
5296
  case 1: return {
5221
5297
  size: 32,
5222
5298
  iconSize: 16,
5223
- borderRadius: radii.small
5299
+ borderRadius: selectedRadius === "full" ? 9999 : radii
5224
5300
  };
5225
5301
  case 3: return {
5226
5302
  size: 56,
5227
5303
  iconSize: 24,
5228
- borderRadius: radii.medium
5304
+ borderRadius: selectedRadius === "full" ? 9999 : radii
5229
5305
  };
5230
5306
  case 4: return {
5231
5307
  size: 64,
5232
5308
  iconSize: 28,
5233
- borderRadius: radii.large
5309
+ borderRadius: selectedRadius === "full" ? 9999 : radii
5234
5310
  };
5235
5311
  default: return {
5236
5312
  size: 40,
5237
5313
  iconSize: 20,
5238
- borderRadius: radii.medium
5314
+ borderRadius: selectedRadius === "full" ? 9999 : radii
5239
5315
  };
5240
5316
  }
5241
5317
  };
5242
5318
  const sizeValues = getSizeValues();
5243
- const customBorderRadius = getBorderRadius();
5244
5319
  const buttonStyle = {
5245
5320
  width: sizeValues.size,
5246
5321
  height: sizeValues.size,
5247
5322
  backgroundColor: disabled ? grayAlpha["3"] : variantColors.backgroundColor,
5248
5323
  borderColor: variantColors.borderColor,
5249
5324
  borderWidth: variant === "outline" ? 1 : 0,
5250
- borderRadius: customBorderRadius !== void 0 ? customBorderRadius : sizeValues.borderRadius,
5325
+ borderRadius: sizeValues.borderRadius,
5251
5326
  opacity: disabled ? .5 : 1,
5252
5327
  alignItems: "center",
5253
5328
  justifyContent: "center"
@@ -5270,7 +5345,7 @@ const IconButton = react.default.forwardRef(({ children, style = {}, variant = "
5270
5345
  ...child.props
5271
5346
  });
5272
5347
  }
5273
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
5348
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
5274
5349
  ref,
5275
5350
  style: [buttonStyle, style],
5276
5351
  onPress,
@@ -5287,8 +5362,8 @@ const IconButton = react.default.forwardRef(({ children, style = {}, variant = "
5287
5362
  size: "small",
5288
5363
  color: variantColors.textColor
5289
5364
  }) : react.default.isValidElement(children) ? react.default.cloneElement(children, {
5290
- size: sizeValues.iconSize,
5291
- color: variantColors.textColor
5365
+ size: children.props?.size || sizeValues.iconSize,
5366
+ color: children.props?.color || variantColors.textColor
5292
5367
  }) : children
5293
5368
  });
5294
5369
  });
@@ -5418,7 +5493,6 @@ const TextFieldRoot = react.default.forwardRef(({ children, ...props }, ref) =>
5418
5493
  };
5419
5494
  const inputContainerStyle = {
5420
5495
  width: "100%",
5421
- flex: 1,
5422
5496
  flexDirection: "row",
5423
5497
  alignItems: "center",
5424
5498
  justifyContent: "space-between",
@@ -5442,7 +5516,8 @@ const TextFieldRoot = react.default.forwardRef(({ children, ...props }, ref) =>
5442
5516
  paddingHorizontal: sizeValues.paddingHorizontal / 2,
5443
5517
  minHeight: multiline ? sizeValues.height : void 0,
5444
5518
  height: multiline ? void 0 : sizeValues.height,
5445
- textAlignVertical: multiline ? "top" : "center"
5519
+ textAlignVertical: multiline ? "top" : "center",
5520
+ borderRadius: sizeValues.borderRadius
5446
5521
  };
5447
5522
  const errorStyle = {
5448
5523
  color: theme.colors.ruby[10],
@@ -5468,7 +5543,7 @@ const TextFieldRoot = react.default.forwardRef(({ children, ...props }, ref) =>
5468
5543
  };
5469
5544
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
5470
5545
  style: [
5471
- styles$31.container,
5546
+ styles$33.container,
5472
5547
  containerStyle,
5473
5548
  style
5474
5549
  ],
@@ -5486,7 +5561,7 @@ const TextFieldRoot = react.default.forwardRef(({ children, ...props }, ref) =>
5486
5561
  style: inputInnerContainerStyle,
5487
5562
  children: [
5488
5563
  leftSlots.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
5489
- style: [styles$31.leftSlots, slotWrapperStyle],
5564
+ style: [styles$33.leftSlots, slotWrapperStyle],
5490
5565
  children: leftSlots.map((child, index) => (0, react.isValidElement)(child) ? react.default.cloneElement(child, {
5491
5566
  key: index,
5492
5567
  side: "left"
@@ -5497,11 +5572,11 @@ const TextFieldRoot = react.default.forwardRef(({ children, ...props }, ref) =>
5497
5572
  style: { flex: 1 },
5498
5573
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnTextInput, {
5499
5574
  ...commonInputProps,
5500
- style: [styles$31.input, inputStyle]
5575
+ style: [styles$33.input, inputStyle]
5501
5576
  })
5502
5577
  }),
5503
5578
  rightSlots.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
5504
- style: [styles$31.rightSlots, slotWrapperStyle],
5579
+ style: [styles$33.rightSlots, slotWrapperStyle],
5505
5580
  children: rightSlots.map((child, index) => (0, react.isValidElement)(child) ? react.default.cloneElement(child, {
5506
5581
  key: index,
5507
5582
  side: "right"
@@ -5527,11 +5602,8 @@ const TextField = react.default.forwardRef((props, ref) => {
5527
5602
  TextField.displayName = "TextField";
5528
5603
  TextField.Root = TextFieldRoot;
5529
5604
  TextField.Slot = TextFieldSlot;
5530
- const styles$31 = react_native.StyleSheet.create({
5531
- container: {
5532
- flex: 1,
5533
- width: "100%"
5534
- },
5605
+ const styles$33 = react_native.StyleSheet.create({
5606
+ container: { width: "100%" },
5535
5607
  leftSlots: {
5536
5608
  flexDirection: "row",
5537
5609
  alignItems: "center"
@@ -5543,25 +5615,73 @@ const styles$31 = react_native.StyleSheet.create({
5543
5615
  input: {
5544
5616
  flexDirection: "row",
5545
5617
  width: "100%",
5546
- minWidth: "100%",
5547
- flex: 1
5618
+ minWidth: "100%"
5548
5619
  }
5549
5620
  });
5550
5621
 
5551
5622
  //#endregion
5552
5623
  //#region src/components/forms/TextArea.tsx
5553
- const TextAreaRoot = react.default.forwardRef((props, ref) => {
5624
+ const TextAreaSlot = react.default.forwardRef(({ side, color, gap, paddingHorizontal, paddingLeft, paddingRight, children, ...props }, ref) => {
5625
+ const theme = useTheme$1();
5626
+ const isDark = useThemeMode$1() === "dark";
5627
+ const slotStyle = {
5628
+ ...props.style,
5629
+ gap: gap !== void 0 ? gap : void 0,
5630
+ paddingHorizontal: paddingHorizontal !== void 0 ? paddingHorizontal : void 0,
5631
+ paddingLeft: paddingLeft !== void 0 ? paddingLeft : void 0,
5632
+ paddingRight: paddingRight !== void 0 ? paddingRight : void 0
5633
+ };
5634
+ const coloredChild = (0, react.useMemo)(() => {
5635
+ if (!color || !(0, react.isValidElement)(children)) return children;
5636
+ return react.default.cloneElement(children, { color: theme.colors[color][9] });
5637
+ }, [
5638
+ children,
5639
+ color,
5640
+ theme,
5641
+ isDark
5642
+ ]);
5643
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Slot, {
5644
+ ref,
5645
+ style: slotStyle,
5646
+ ...props,
5647
+ children: coloredChild
5648
+ });
5649
+ });
5650
+ TextAreaSlot.displayName = "TextAreaSlot";
5651
+ const TextAreaRoot = react.default.forwardRef(({ children, ...props }, ref) => {
5554
5652
  const theme = useTheme$1();
5555
5653
  const mode = useThemeMode$1();
5556
5654
  const isDark = mode === "dark";
5557
5655
  const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
5558
5656
  const grayAlpha = getGrayAlpha(theme);
5559
5657
  const { value, onChangeText, placeholder, label, error, disabled = false, color = "gray", highContrast = false, radius = "medium", size = "2", variant = "outline", rows = 4, autoGrow = false, accessibilityLabel, accessibilityHint, style, ...rest } = props;
5658
+ const { leftSlots, rightSlots } = (0, react.useMemo)(() => {
5659
+ const slotChildren = [];
5660
+ react.Children.forEach(children, (child) => {
5661
+ if (!(0, react.isValidElement)(child)) return;
5662
+ if (child.type?.displayName === "TextAreaSlot") slotChildren.push(child);
5663
+ });
5664
+ const leftSlots = [];
5665
+ const rightSlots = [];
5666
+ slotChildren.forEach((child) => {
5667
+ if (!(0, react.isValidElement)(child)) return;
5668
+ const explicitSide = child.props.side;
5669
+ if (explicitSide === "left") leftSlots.push(child);
5670
+ else if (explicitSide === "right") rightSlots.push(child);
5671
+ else if (slotChildren.filter((c) => (0, react.isValidElement)(c) && !c.props?.side).indexOf(child) === 0) leftSlots.push(child);
5672
+ else rightSlots.push(child);
5673
+ });
5674
+ return {
5675
+ leftSlots,
5676
+ rightSlots
5677
+ };
5678
+ }, [children]);
5560
5679
  const [isFocused, setIsFocused] = (0, react.useState)(false);
5561
5680
  const activeColor = color || theme.accentColor;
5562
5681
  const radii = theme.radii[radius] ?? theme.radii.medium;
5563
5682
  const selectedRadius = radius || theme.radius;
5564
5683
  const variantColors = getVariantColors(theme, activeColor, mode, variant, highContrast);
5684
+ const accentColorScale = getColorScale(theme, activeColor, mode);
5565
5685
  const getSizeValues = () => {
5566
5686
  switch (size) {
5567
5687
  case "1": return {
@@ -5590,10 +5710,10 @@ const TextAreaRoot = react.default.forwardRef((props, ref) => {
5590
5710
  };
5591
5711
  const inputContainerBorderColor = () => {
5592
5712
  if (error) return theme.colors.ruby[9];
5593
- else return isFocused ? theme.colors[activeColor]["8"] : "transparent";
5713
+ else return isFocused ? accentColorScale["8"] : "transparent";
5594
5714
  };
5595
5715
  const inputContainerBackgroundColor = () => {
5596
- if (disabled) return isDark ? grayAlpha["3"] : grayAlpha["2"];
5716
+ if (disabled) return isDark ? grayAlpha["2"] : grayAlpha["2"];
5597
5717
  else return variantColors.backgroundColor;
5598
5718
  };
5599
5719
  const inputBorderColor = () => {
@@ -5602,16 +5722,21 @@ const TextAreaRoot = react.default.forwardRef((props, ref) => {
5602
5722
  };
5603
5723
  const inputContainerStyle = {
5604
5724
  width: "100%",
5605
- borderWidth: 2,
5725
+ flexDirection: "row",
5726
+ alignItems: "flex-start",
5727
+ justifyContent: "space-between",
5728
+ borderWidth: variant === "soft" ? 1.4 : 2,
5606
5729
  borderColor: inputContainerBorderColor(),
5607
5730
  backgroundColor: inputContainerBackgroundColor(),
5608
5731
  borderRadius: selectedRadius === "full" ? theme.radii.large : radii,
5609
5732
  opacity: disabled ? .6 : 1
5610
5733
  };
5611
- const inputStyle = {
5734
+ const inputInnerContainerStyle = {
5612
5735
  borderWidth: 1,
5613
5736
  borderColor: inputBorderColor(),
5614
- borderRadius: selectedRadius === "full" ? theme.radii.large : radii,
5737
+ borderRadius: selectedRadius === "full" ? theme.radii.large : radii
5738
+ };
5739
+ const inputStyle = {
5615
5740
  fontSize: sizeValues.fontSize,
5616
5741
  color: color !== "gray" ? variantColors.textColor : grayScale[12],
5617
5742
  padding: sizeValues.padding,
@@ -5625,7 +5750,7 @@ const TextAreaRoot = react.default.forwardRef((props, ref) => {
5625
5750
  };
5626
5751
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
5627
5752
  style: [
5628
- styles$30.container,
5753
+ styles$32.container,
5629
5754
  containerStyle,
5630
5755
  style
5631
5756
  ],
@@ -5637,21 +5762,47 @@ const TextAreaRoot = react.default.forwardRef((props, ref) => {
5637
5762
  }),
5638
5763
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
5639
5764
  style: inputContainerStyle,
5640
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnTextInput, {
5641
- ref,
5642
- value,
5643
- onChangeText,
5644
- placeholder,
5645
- placeholderTextColor: color !== "gray" ? theme.colors[color][12] + "99" : theme.colors.gray[9],
5646
- editable: !disabled,
5647
- multiline: true,
5648
- accessibilityLabel: accessibilityLabel || label,
5649
- accessibilityHint,
5650
- accessibilityState: { disabled },
5651
- style: [styles$30.input, inputStyle],
5652
- onFocus: () => setIsFocused(true),
5653
- onBlur: () => setIsFocused(false),
5654
- ...rest
5765
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Flex, {
5766
+ align: "stretch",
5767
+ direction: "row",
5768
+ style: inputInnerContainerStyle,
5769
+ children: [
5770
+ leftSlots.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
5771
+ style: styles$32.leftSlots,
5772
+ children: leftSlots.map((child, index) => (0, react.isValidElement)(child) ? react.default.cloneElement(child, {
5773
+ key: index,
5774
+ side: "left"
5775
+ }) : child)
5776
+ }),
5777
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Flex, {
5778
+ direction: "row",
5779
+ style: { flex: 1 },
5780
+ wrap: "wrap",
5781
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnTextInput, {
5782
+ ref,
5783
+ value,
5784
+ onChangeText,
5785
+ placeholder,
5786
+ placeholderTextColor: color !== "gray" ? theme.colors[color][12] + "99" : theme.colors.gray[9],
5787
+ editable: !disabled,
5788
+ multiline: true,
5789
+ accessibilityLabel: accessibilityLabel || label,
5790
+ accessibilityHint,
5791
+ accessibilityState: { disabled },
5792
+ style: [styles$32.input, inputStyle],
5793
+ onFocus: () => setIsFocused(true),
5794
+ onBlur: () => setIsFocused(false),
5795
+ ...rest
5796
+ })
5797
+ }),
5798
+ rightSlots.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
5799
+ style: styles$32.rightSlots,
5800
+ children: rightSlots.map((child, index) => (0, react.isValidElement)(child) ? react.default.cloneElement(child, {
5801
+ key: index,
5802
+ side: "right"
5803
+ }) : child)
5804
+ })
5805
+ ]
5655
5806
  })
5656
5807
  }),
5657
5808
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnText, {
@@ -5669,12 +5820,19 @@ const TextArea = react.default.forwardRef((props, ref) => {
5669
5820
  });
5670
5821
  });
5671
5822
  TextArea.displayName = "TextArea";
5672
- const styles$30 = react_native.StyleSheet.create({
5823
+ TextArea.Root = TextAreaRoot;
5824
+ TextArea.Slot = TextAreaSlot;
5825
+ const styles$32 = react_native.StyleSheet.create({
5673
5826
  container: { width: "100%" },
5674
- input: {
5675
- width: "100%",
5676
- minHeight: 100
5677
- }
5827
+ leftSlots: {
5828
+ flexDirection: "row",
5829
+ alignItems: "flex-start"
5830
+ },
5831
+ rightSlots: {
5832
+ flexDirection: "row",
5833
+ alignItems: "flex-start"
5834
+ },
5835
+ input: { minWidth: "100%" }
5678
5836
  });
5679
5837
 
5680
5838
  //#endregion
@@ -5685,6 +5843,7 @@ const Checkbox = react.default.forwardRef(({ checked, defaultChecked = false, on
5685
5843
  const isChecked = isControlled ? checked : internalChecked;
5686
5844
  const theme = useTheme$1();
5687
5845
  const mode = useThemeMode$1();
5846
+ const globalHaptics = useHaptics$1();
5688
5847
  const isDark = mode === "dark";
5689
5848
  const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
5690
5849
  const grayAlpha = getGrayAlpha(theme);
@@ -5730,7 +5889,7 @@ const Checkbox = react.default.forwardRef(({ checked, defaultChecked = false, on
5730
5889
  setInternalChecked(newChecked);
5731
5890
  onCheckedChange?.(newChecked);
5732
5891
  }
5733
- if (hapticFeedback) react_native.Vibration.vibrate(10);
5892
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
5734
5893
  }
5735
5894
  };
5736
5895
  const boxStyle = {
@@ -5752,9 +5911,9 @@ const Checkbox = react.default.forwardRef(({ checked, defaultChecked = false, on
5752
5911
  color: theme.colors.gray || grayScale[12],
5753
5912
  fontSize: sizeValues.fontSize
5754
5913
  };
5755
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
5914
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
5756
5915
  ref,
5757
- style: styles$29.container,
5916
+ style: styles$31.container,
5758
5917
  onPress: handlePress,
5759
5918
  disabled,
5760
5919
  accessibilityRole: "checkbox",
@@ -5770,9 +5929,9 @@ const Checkbox = react.default.forwardRef(({ checked, defaultChecked = false, on
5770
5929
  hapticFeedback: false,
5771
5930
  ...rest,
5772
5931
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
5773
- style: [styles$29.checkbox, boxStyle],
5932
+ style: [styles$31.checkbox, boxStyle],
5774
5933
  children: (isChecked || indeterminate) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
5775
- style: [styles$29.icon, iconStyle],
5934
+ style: [styles$31.icon, iconStyle],
5776
5935
  children: indeterminate ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: {
5777
5936
  width: sizeValues.iconSize * .9,
5778
5937
  height: 2.8,
@@ -5803,13 +5962,13 @@ const Checkbox = react.default.forwardRef(({ checked, defaultChecked = false, on
5803
5962
  } })] })
5804
5963
  })
5805
5964
  }), label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
5806
- style: [styles$29.label, labelStyle],
5965
+ style: [styles$31.label, labelStyle],
5807
5966
  children: label
5808
5967
  })]
5809
5968
  });
5810
5969
  });
5811
5970
  Checkbox.displayName = "Checkbox";
5812
- const styles$29 = react_native.StyleSheet.create({
5971
+ const styles$31 = react_native.StyleSheet.create({
5813
5972
  container: {
5814
5973
  flexDirection: "row",
5815
5974
  alignItems: "center"
@@ -5839,7 +5998,7 @@ const CheckboxGroup = react.default.forwardRef(({ value, onValueChange, items, d
5839
5998
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
5840
5999
  ref,
5841
6000
  style: [
5842
- styles$28.container,
6001
+ styles$30.container,
5843
6002
  containerStyle,
5844
6003
  style
5845
6004
  ],
@@ -5858,7 +6017,7 @@ const CheckboxGroup = react.default.forwardRef(({ value, onValueChange, items, d
5858
6017
  });
5859
6018
  });
5860
6019
  CheckboxGroup.displayName = "CheckboxGroup";
5861
- const styles$28 = react_native.StyleSheet.create({ container: { width: "100%" } });
6020
+ const styles$30 = react_native.StyleSheet.create({ container: { width: "100%" } });
5862
6021
 
5863
6022
  //#endregion
5864
6023
  //#region src/components/forms/CheckboxCards.tsx
@@ -5896,7 +6055,7 @@ const CheckboxCardsRoot = react.default.forwardRef(({ value: controlledValue, de
5896
6055
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
5897
6056
  ref,
5898
6057
  style: [
5899
- styles$27.rootContainer,
6058
+ styles$29.rootContainer,
5900
6059
  containerStyle,
5901
6060
  style
5902
6061
  ],
@@ -5910,6 +6069,7 @@ const CheckboxCardsItem = react.default.forwardRef(({ value, side: itemSide, dis
5910
6069
  const context = useCheckboxCardsContext();
5911
6070
  const theme = useTheme$1();
5912
6071
  const mode = useThemeMode$1();
6072
+ const globalHaptics = useHaptics$1();
5913
6073
  const isDark = mode === "dark";
5914
6074
  const { value: selectedValues, onValueChange, variant, size, color, highContrast, radius, side: rootSide, disabled: rootDisabled } = context;
5915
6075
  const isChecked = selectedValues.includes(value);
@@ -5949,7 +6109,7 @@ const CheckboxCardsItem = react.default.forwardRef(({ value, side: itemSide, dis
5949
6109
  if (!isDisabled) {
5950
6110
  if (isChecked) onValueChange(selectedValues.filter((v) => v !== value));
5951
6111
  else onValueChange([...selectedValues, value]);
5952
- react_native.Vibration.vibrate(10);
6112
+ if (globalHaptics) triggerHaptic("press");
5953
6113
  }
5954
6114
  };
5955
6115
  const cardStyle = {
@@ -5964,10 +6124,10 @@ const CheckboxCardsItem = react.default.forwardRef(({ value, side: itemSide, dis
5964
6124
  gap: theme.space[3]
5965
6125
  };
5966
6126
  sizeValues.indicatorSize, sizeValues.indicatorSize, sizeValues.borderWidth, isChecked ? variantColors.borderColor : grayAlpha["8"], isChecked && variantColors.backgroundColor;
5967
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
6127
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
5968
6128
  ref,
5969
6129
  style: [
5970
- styles$27.itemContainer,
6130
+ styles$29.itemContainer,
5971
6131
  cardStyle,
5972
6132
  style
5973
6133
  ],
@@ -5994,13 +6154,13 @@ const CheckboxCardsItem = react.default.forwardRef(({ value, side: itemSide, dis
5994
6154
  size,
5995
6155
  onCheckedChange: handlePress
5996
6156
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
5997
- style: styles$27.content,
6157
+ style: styles$29.content,
5998
6158
  children
5999
6159
  })]
6000
6160
  });
6001
6161
  });
6002
6162
  CheckboxCardsItem.displayName = "CheckboxCards.Item";
6003
- const styles$27 = react_native.StyleSheet.create({
6163
+ const styles$29 = react_native.StyleSheet.create({
6004
6164
  rootContainer: { width: "100%" },
6005
6165
  itemContainer: { flex: 1 },
6006
6166
  content: { flex: 1 }
@@ -6015,6 +6175,7 @@ const CheckboxCards = {
6015
6175
  const Radio = react.default.forwardRef(({ defaultChecked, value, selected, onSelect, disabled = false, size = "2", variant = "solid", color, label, children, highContrast = false, accessibilityLabel, accessibilityHint, hapticFeedback = true, ...rest }, ref) => {
6016
6176
  const theme = useTheme$1();
6017
6177
  const mode = useThemeMode$1();
6178
+ const globalHaptics = useHaptics$1();
6018
6179
  const grayScale = mode === "dark" ? theme.colors.gray.dark : theme.colors.gray;
6019
6180
  getGrayAlpha(theme);
6020
6181
  const accentScale = getAccentColor(theme, mode);
@@ -6054,7 +6215,7 @@ const Radio = react.default.forwardRef(({ defaultChecked, value, selected, onSel
6054
6215
  if (!disabled) {
6055
6216
  if (onSelect) onSelect(value);
6056
6217
  if (selected === void 0) setIsInternallySelected(true);
6057
- if (hapticFeedback) react_native.Vibration.vibrate(10);
6218
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
6058
6219
  }
6059
6220
  };
6060
6221
  const outerStyle = {
@@ -6078,9 +6239,9 @@ const Radio = react.default.forwardRef(({ defaultChecked, value, selected, onSel
6078
6239
  color: grayScale[12],
6079
6240
  fontSize: sizeValues.fontSize
6080
6241
  };
6081
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
6242
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
6082
6243
  ref,
6083
- style: styles$26.container,
6244
+ style: styles$28.container,
6084
6245
  onPress: handlePress,
6085
6246
  disabled,
6086
6247
  accessibilityRole: "radio",
@@ -6096,19 +6257,19 @@ const Radio = react.default.forwardRef(({ defaultChecked, value, selected, onSel
6096
6257
  hapticFeedback: false,
6097
6258
  ...rest,
6098
6259
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6099
- style: [styles$26.radioOuter, outerStyle],
6100
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$26.radioInner, innerStyle] })
6260
+ style: [styles$28.radioOuter, outerStyle],
6261
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$28.radioInner, innerStyle] })
6101
6262
  }), children ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6102
- style: styles$26.content,
6263
+ style: styles$28.content,
6103
6264
  children
6104
6265
  }) : label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
6105
- style: [styles$26.label, labelStyle],
6266
+ style: [styles$28.label, labelStyle],
6106
6267
  children: label
6107
6268
  }) : null]
6108
6269
  });
6109
6270
  });
6110
6271
  Radio.displayName = "Radio";
6111
- const styles$26 = react_native.StyleSheet.create({
6272
+ const styles$28 = react_native.StyleSheet.create({
6112
6273
  container: {
6113
6274
  flexDirection: "row",
6114
6275
  alignItems: "center"
@@ -6159,7 +6320,7 @@ const RadioGroupRoot = react.default.forwardRef(({ value: controlledValue, defau
6159
6320
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6160
6321
  ref,
6161
6322
  style: [
6162
- styles$25.container,
6323
+ styles$27.container,
6163
6324
  containerStyle,
6164
6325
  style
6165
6326
  ],
@@ -6190,7 +6351,7 @@ const RadioGroupItem = react.default.forwardRef(({ value, disabled: itemDisabled
6190
6351
  });
6191
6352
  });
6192
6353
  RadioGroupItem.displayName = "RadioGroup.Item";
6193
- const styles$25 = react_native.StyleSheet.create({ container: { width: "100%" } });
6354
+ const styles$27 = react_native.StyleSheet.create({ container: { width: "100%" } });
6194
6355
  const RadioGroup = {
6195
6356
  Root: RadioGroupRoot,
6196
6357
  Item: RadioGroupItem
@@ -6232,7 +6393,7 @@ const RadioCardsRoot = react.default.forwardRef(({ value: controlledValue, defau
6232
6393
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6233
6394
  ref,
6234
6395
  style: [
6235
- styles$24.rootContainer,
6396
+ styles$26.rootContainer,
6236
6397
  containerStyle,
6237
6398
  style
6238
6399
  ],
@@ -6246,6 +6407,7 @@ const RadioCardsItem = react.default.forwardRef(({ value, side: itemSide, disabl
6246
6407
  const context = useRadioCardsContext();
6247
6408
  const theme = useTheme$1();
6248
6409
  const mode = useThemeMode$1();
6410
+ const globalHaptics = useHaptics$1();
6249
6411
  const isDark = mode === "dark";
6250
6412
  const { value: selectedValue, onValueChange, variant, size, color, highContrast, radius, side: rootSide, disabled: rootDisabled } = context;
6251
6413
  const isSelected = selectedValue === value;
@@ -6281,14 +6443,14 @@ const RadioCardsItem = react.default.forwardRef(({ value, side: itemSide, disabl
6281
6443
  const handlePress = () => {
6282
6444
  if (!isDisabled) {
6283
6445
  onValueChange(value);
6284
- react_native.Vibration.vibrate(10);
6446
+ if (globalHaptics) triggerHaptic("press");
6285
6447
  }
6286
6448
  };
6287
6449
  const cardStyle = {
6288
6450
  padding: sizeValues.padding,
6289
6451
  borderRadius: radius === "full" ? 9999 : radii,
6290
6452
  borderWidth: isSelected ? 1.5 : 1,
6291
- borderColor: isSelected ? variantColors.borderColor : isDark ? grayAlpha["6"] : grayAlpha["6"],
6453
+ borderColor: isSelected ? variantColors.borderColor : ["outline", "surface"].includes(variant) ? isDark ? grayAlpha["6"] : grayAlpha["6"] : "transparent",
6292
6454
  backgroundColor: isSelected ? variantColors.backgroundColor : isDark ? grayAlpha["2"] : grayAlpha["2"],
6293
6455
  opacity: isDisabled ? .5 : 1,
6294
6456
  flexDirection: indicatorSide === "left" ? "row" : "row-reverse",
@@ -6311,10 +6473,10 @@ const RadioCardsItem = react.default.forwardRef(({ value, side: itemSide, disabl
6311
6473
  borderRadius: sizeValues.innerIndicatorSize / 2,
6312
6474
  backgroundColor: variantColors.textColor
6313
6475
  };
6314
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
6476
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
6315
6477
  ref,
6316
6478
  style: [
6317
- styles$24.itemContainer,
6479
+ styles$26.itemContainer,
6318
6480
  cardStyle,
6319
6481
  style
6320
6482
  ],
@@ -6339,15 +6501,15 @@ const RadioCardsItem = react.default.forwardRef(({ value, side: itemSide, disabl
6339
6501
  style: indicatorStyle,
6340
6502
  children: isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: innerDotStyle })
6341
6503
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6342
- style: styles$24.content,
6504
+ style: styles$26.content,
6343
6505
  children
6344
6506
  })]
6345
6507
  });
6346
6508
  });
6347
6509
  RadioCardsItem.displayName = "RadioCards.Item";
6348
- const styles$24 = react_native.StyleSheet.create({
6510
+ const styles$26 = react_native.StyleSheet.create({
6349
6511
  rootContainer: { width: "100%" },
6350
- itemContainer: { flex: 1 },
6512
+ itemContainer: {},
6351
6513
  content: { flex: 1 }
6352
6514
  });
6353
6515
  const RadioCards = {
@@ -6360,6 +6522,7 @@ const RadioCards = {
6360
6522
  const Switch = react.default.forwardRef(({ defaultChecked, checked, onCheckedChange, disabled = false, radius = "full", size = "2", color, variant = "solid", thumbColor, label, highContrast, accessibilityLabel, accessibilityHint, hapticFeedback = true, ...rest }, ref) => {
6361
6523
  const theme = useTheme$1();
6362
6524
  const mode = useThemeMode$1();
6525
+ const globalHaptics = useHaptics$1();
6363
6526
  const isDark = mode === "dark";
6364
6527
  const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
6365
6528
  const grayAlpha = getGrayAlpha(theme);
@@ -6377,7 +6540,7 @@ const Switch = react.default.forwardRef(({ defaultChecked, checked, onCheckedCha
6377
6540
  const setChecked = (value) => {
6378
6541
  if (checked === void 0) setInternalChecked(value);
6379
6542
  if (onCheckedChange) onCheckedChange(value);
6380
- if (hapticFeedback && !disabled) react_native.Vibration.vibrate(10);
6543
+ if (globalHaptics && hapticFeedback && !disabled) triggerHaptic("press");
6381
6544
  };
6382
6545
  const animatedValue = (0, react.useRef)(new react_native.Animated.Value(isChecked ? 1 : 0));
6383
6546
  (0, react.useEffect)(() => {
@@ -6443,9 +6606,9 @@ const Switch = react.default.forwardRef(({ defaultChecked, checked, onCheckedCha
6443
6606
  color: grayScale[12],
6444
6607
  fontSize: sizeValues.fontSize
6445
6608
  };
6446
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
6609
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
6447
6610
  ref,
6448
- style: styles$23.container,
6611
+ style: styles$25.container,
6449
6612
  onPress: handlePress,
6450
6613
  disabled,
6451
6614
  accessibilityRole: "switch",
@@ -6461,16 +6624,16 @@ const Switch = react.default.forwardRef(({ defaultChecked, checked, onCheckedCha
6461
6624
  hapticFeedback: false,
6462
6625
  ...rest,
6463
6626
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
6464
- style: [styles$23.track, trackStyle],
6465
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: [styles$23.thumb, thumbStyle] })
6627
+ style: [styles$25.track, trackStyle],
6628
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: [styles$25.thumb, thumbStyle] })
6466
6629
  }), label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
6467
- style: [styles$23.label, labelStyle],
6630
+ style: [styles$25.label, labelStyle],
6468
6631
  children: label
6469
6632
  })]
6470
6633
  });
6471
6634
  });
6472
6635
  Switch.displayName = "Switch";
6473
- const styles$23 = react_native.StyleSheet.create({
6636
+ const styles$25 = react_native.StyleSheet.create({
6474
6637
  container: {
6475
6638
  flexDirection: "row",
6476
6639
  alignItems: "center"
@@ -6668,25 +6831,25 @@ function calculateContextMenuPosition(touchPoint, contentSize, screenSize, side
6668
6831
  * ChevronDownIcon - A chevron pointing down using React Native View
6669
6832
  * Can be rotated to point in different directions
6670
6833
  */
6671
- const ChevronDownIcon$1 = react.default.forwardRef(({ width = 9, height = 9, style, color = "currentColor" }, _forwardedRef) => {
6834
+ const ChevronDownIcon = react.default.forwardRef(({ width = 9, height = 9, style, color = "currentColor" }, _forwardedRef) => {
6672
6835
  const armWidth = width * .55;
6673
6836
  const armHeight = 2;
6674
6837
  const armOffset = width * .22;
6675
6838
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
6676
6839
  style: [
6677
- styles$22.chevronContainer,
6840
+ styles$24.chevronContainer,
6678
6841
  {
6679
6842
  width,
6680
6843
  height
6681
6844
  },
6682
6845
  style
6683
6846
  ],
6684
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.chevronArm, {
6847
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.chevronArm, {
6685
6848
  width: armWidth,
6686
6849
  height: armHeight,
6687
6850
  backgroundColor: color,
6688
6851
  transform: [{ rotate: "45deg" }, { translateX: -armOffset }]
6689
- }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.chevronArm, {
6852
+ }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.chevronArm, {
6690
6853
  width: armWidth,
6691
6854
  height: armHeight,
6692
6855
  backgroundColor: color,
@@ -6694,7 +6857,7 @@ const ChevronDownIcon$1 = react.default.forwardRef(({ width = 9, height = 9, sty
6694
6857
  }] })]
6695
6858
  });
6696
6859
  });
6697
- ChevronDownIcon$1.displayName = "ChevronDownIcon";
6860
+ ChevronDownIcon.displayName = "ChevronDownIcon";
6698
6861
  /**
6699
6862
  * ThickChevronRightIcon - A thick chevron pointing right using React Native View
6700
6863
  */
@@ -6703,19 +6866,19 @@ const ThickChevronRightIcon = react.default.forwardRef(({ width = 9, height = 9,
6703
6866
  const armHeight = 2.5;
6704
6867
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
6705
6868
  style: [
6706
- styles$22.chevronContainer,
6869
+ styles$24.chevronContainer,
6707
6870
  {
6708
6871
  width,
6709
6872
  height
6710
6873
  },
6711
6874
  style
6712
6875
  ],
6713
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.chevronArm, {
6876
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.chevronArm, {
6714
6877
  width: armWidth,
6715
6878
  height: armHeight,
6716
6879
  backgroundColor: color,
6717
6880
  transform: [{ rotate: "45deg" }, { translateY: -1 }]
6718
- }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.chevronArm, {
6881
+ }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.chevronArm, {
6719
6882
  width: armWidth,
6720
6883
  height: armHeight,
6721
6884
  backgroundColor: color,
@@ -6730,14 +6893,14 @@ ThickChevronRightIcon.displayName = "ThickChevronRightIcon";
6730
6893
  const ThickCheckIcon = react.default.forwardRef(({ width = 9, height = 9, style, color = "currentColor" }, _forwardedRef) => {
6731
6894
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
6732
6895
  style: [
6733
- styles$22.checkContainer,
6896
+ styles$24.checkContainer,
6734
6897
  {
6735
6898
  width,
6736
6899
  height
6737
6900
  },
6738
6901
  style
6739
6902
  ],
6740
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.checkShortArm, { backgroundColor: color }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.checkLongArm, { backgroundColor: color }] })]
6903
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.checkShortArm, { backgroundColor: color }] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.checkLongArm, { backgroundColor: color }] })]
6741
6904
  });
6742
6905
  });
6743
6906
  ThickCheckIcon.displayName = "ThickCheckIcon";
@@ -6747,21 +6910,21 @@ ThickCheckIcon.displayName = "ThickCheckIcon";
6747
6910
  const ThickDividerHorizontalIcon = react.default.forwardRef(({ width = 9, height = 9, style, color = "currentColor" }, _forwardedRef) => {
6748
6911
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
6749
6912
  style: [
6750
- styles$22.dividerContainer,
6913
+ styles$24.dividerContainer,
6751
6914
  {
6752
6915
  width,
6753
6916
  height
6754
6917
  },
6755
6918
  style
6756
6919
  ],
6757
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$22.dividerLine, {
6920
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$24.dividerLine, {
6758
6921
  width: width * .9,
6759
6922
  backgroundColor: color
6760
6923
  }] })
6761
6924
  });
6762
6925
  });
6763
6926
  ThickDividerHorizontalIcon.displayName = "ThickDividerHorizontalIcon";
6764
- const styles$22 = react_native.StyleSheet.create({
6927
+ const styles$24 = react_native.StyleSheet.create({
6765
6928
  chevronContainer: {
6766
6929
  alignItems: "center",
6767
6930
  justifyContent: "center"
@@ -6915,10 +7078,11 @@ const SelectRoot = ({ defaultValue, value: controlledValue, onValueChange, open:
6915
7078
  };
6916
7079
  const SelectTrigger = ({ children, asChild = false }) => {
6917
7080
  const { onOpenChange, open, anchorRef, measureAnchor, disabled } = useSelect();
7081
+ const globalHaptics = useHaptics$1();
6918
7082
  const handlePress = () => {
6919
7083
  measureAnchor();
6920
7084
  onOpenChange(!open);
6921
- react_native.Vibration.vibrate(10);
7085
+ if (globalHaptics) triggerHaptic("press");
6922
7086
  };
6923
7087
  if (asChild && react.default.isValidElement(children)) {
6924
7088
  const child = children;
@@ -6971,7 +7135,7 @@ const SelectValue = ({ placeholder = "Select an option", style }) => {
6971
7135
  flexShrink: 1
6972
7136
  }, style || {}],
6973
7137
  children: selectedText || placeholder
6974
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon$1, {
7138
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, {
6975
7139
  color: selectedText ? variantColors.textColor : grayAlpha[9],
6976
7140
  width: sizeStyles(),
6977
7141
  height: sizeStyles(),
@@ -6995,7 +7159,7 @@ const SelectOverlay = ({ style }) => {
6995
7159
  const { onOpenChange } = useSelect();
6996
7160
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
6997
7161
  onPress: () => onOpenChange(false),
6998
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$21.overlay, style] })
7162
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$23.overlay, style] })
6999
7163
  });
7000
7164
  };
7001
7165
  const SelectContent = ({ children, side = "bottom", sideOffset = 4, align = "start", alignOffset = 0, avoidCollisions = true, size = 2, style }) => {
@@ -7080,7 +7244,7 @@ const SelectContent = ({ children, side = "bottom", sideOffset = 4, align = "sta
7080
7244
  ref: contentRef,
7081
7245
  onLayout: handleLayout,
7082
7246
  style: [
7083
- styles$21.content,
7247
+ styles$23.content,
7084
7248
  {
7085
7249
  backgroundColor: isDark ? colors[3] : colors[1],
7086
7250
  borderRadius: radii.medium,
@@ -7117,6 +7281,7 @@ const SelectItem = ({ children, value: itemValue, disabled = false, style }) =>
7117
7281
  const { value, onValueChange, colors, onOpenChange, size, registerItem, unregisterItem, setSelectedItemText, color } = useSelect();
7118
7282
  const theme = useTheme$1();
7119
7283
  const mode = useThemeMode$1();
7284
+ const globalHaptics = useHaptics$1();
7120
7285
  const isSelected = value === itemValue;
7121
7286
  const extractText = (0, react.useCallback)((node) => {
7122
7287
  if (typeof node === "string") return node;
@@ -7197,7 +7362,7 @@ const SelectItem = ({ children, value: itemValue, disabled = false, style }) =>
7197
7362
  if (!disabled) {
7198
7363
  setSelectedItemText(extractText(children));
7199
7364
  onValueChange(itemValue);
7200
- react_native.Vibration.vibrate(10);
7365
+ if (globalHaptics) triggerHaptic("press");
7201
7366
  }
7202
7367
  };
7203
7368
  const itemPadding = getItemPadding();
@@ -7212,8 +7377,8 @@ const SelectItem = ({ children, value: itemValue, disabled = false, style }) =>
7212
7377
  onPress: handlePress,
7213
7378
  disabled,
7214
7379
  style: [
7215
- styles$21.item,
7216
- disabled && styles$21.itemDisabled,
7380
+ styles$23.item,
7381
+ disabled && styles$23.itemDisabled,
7217
7382
  itemPadding,
7218
7383
  style,
7219
7384
  {
@@ -7277,7 +7442,7 @@ const SelectItem = ({ children, value: itemValue, disabled = false, style }) =>
7277
7442
  const SelectSeparator = ({ style }) => {
7278
7443
  const { colors } = useSelect();
7279
7444
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
7280
- styles$21.separator,
7445
+ styles$23.separator,
7281
7446
  { backgroundColor: colors[6] },
7282
7447
  style
7283
7448
  ] });
@@ -7321,7 +7486,7 @@ const SelectLabel = ({ children, style = {} }) => {
7321
7486
  children
7322
7487
  });
7323
7488
  };
7324
- const styles$21 = react_native.StyleSheet.create({
7489
+ const styles$23 = react_native.StyleSheet.create({
7325
7490
  overlay: {
7326
7491
  flex: 1,
7327
7492
  backgroundColor: "rgba(0, 0, 0, 0.01)"
@@ -7379,6 +7544,7 @@ const isRangeValue = (value) => {
7379
7544
  const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue, onValueChange, onValueChangeEnd, min = 0, max = 100, step = 1, disabled = false, size = "2", variant = "solid", color, radius = "full", highContrast = false, minStepsBetweenThumbs = 0, label, showValueLabel = false, valueLabelFormatter = (v) => v.toString(), accessibilityLabel, accessibilityHint, style, hapticFeedback = true, ...rest }, ref) => {
7380
7545
  const theme = useTheme$1();
7381
7546
  const mode = useThemeMode$1();
7547
+ const globalHaptics = useHaptics$1();
7382
7548
  const isDark = mode === "dark";
7383
7549
  const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
7384
7550
  const grayAlpha = getGrayAlpha(theme);
@@ -7527,7 +7693,7 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7527
7693
  const touchX = event.nativeEvent.locationX;
7528
7694
  const position = Math.max(0, Math.min(1, touchX / currentTrackLayout.width));
7529
7695
  const newValue = positionToValue(position);
7530
- if (hapticFeedback) react_native.Vibration.vibrate(10);
7696
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
7531
7697
  if (valuesRef.current.length === 1) {
7532
7698
  updateValue([newValue]);
7533
7699
  handleValueChangeEnd([newValue]);
@@ -7583,7 +7749,7 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7583
7749
  const nearestIndex = getNearestThumbIndex(Math.max(0, Math.min(1, touchX / trackLayoutRef2.current.width)));
7584
7750
  setActiveThumbIndex(nearestIndex);
7585
7751
  activeThumbIndexRef.current = nearestIndex;
7586
- if (hapticFeedback) react_native.Vibration.vibrate(10);
7752
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
7587
7753
  },
7588
7754
  onPanResponderMove: (_event, gestureState) => {
7589
7755
  if (activeThumbIndexRef.current !== null) handleDrag(gestureState, activeThumbIndexRef.current);
@@ -7592,13 +7758,13 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7592
7758
  setActiveThumbIndex(null);
7593
7759
  activeThumbIndexRef.current = null;
7594
7760
  handleValueChangeEnd(valuesRef.current);
7595
- if (hapticFeedback) react_native.Vibration.vibrate(10);
7761
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
7596
7762
  },
7597
7763
  onPanResponderTerminate: () => {
7598
7764
  setActiveThumbIndex(null);
7599
7765
  activeThumbIndexRef.current = null;
7600
7766
  handleValueChangeEnd(valuesRef.current);
7601
- if (hapticFeedback) react_native.Vibration.vibrate(10);
7767
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
7602
7768
  },
7603
7769
  onPanResponderTerminationRequest: () => false
7604
7770
  })).current;
@@ -7744,7 +7910,7 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7744
7910
  ]);
7745
7911
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
7746
7912
  ref,
7747
- style: [styles$20.container, style],
7913
+ style: [styles$22.container, style],
7748
7914
  accessibilityRole: "adjustable",
7749
7915
  accessibilityLabel: accessibilityLabel || label || "Slider",
7750
7916
  accessibilityHint: accessibilityHint || `Value: ${formatValueLabel()}, range: ${min} to ${max}`,
@@ -7752,17 +7918,17 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7752
7918
  accessibilityState: { disabled },
7753
7919
  ...rest,
7754
7920
  children: [(label || showValueLabel) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
7755
- style: styles$20.labelContainer,
7921
+ style: styles$22.labelContainer,
7756
7922
  children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
7757
- style: [styles$20.label, labelStyle],
7923
+ style: [styles$22.label, labelStyle],
7758
7924
  children: label
7759
7925
  }), showValueLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
7760
- style: [styles$20.valueLabel, labelStyle],
7926
+ style: [styles$22.valueLabel, labelStyle],
7761
7927
  children: formatValueLabel()
7762
7928
  })]
7763
7929
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
7764
7930
  ref: trackLayoutRef,
7765
- style: [styles$20.track, {
7931
+ style: [styles$22.track, {
7766
7932
  height: sizeValues.trackHeight,
7767
7933
  borderRadius,
7768
7934
  backgroundColor: trackBackgroundColor,
@@ -7775,15 +7941,15 @@ const Slider = react.default.forwardRef(({ value: controlledValue, defaultValue,
7775
7941
  values.length === 1 && thumbAnimations[0] && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: getFilledTrackStyle(thumbAnimations[0], 0) }),
7776
7942
  values.length === 2 && thumbAnimations[0] && thumbAnimations[1] && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: getFilledTrackStyle(thumbAnimations[1], 1) }),
7777
7943
  thumbAnimations.slice(0, values.length).map((animatedValue, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, {
7778
- style: [styles$20.thumb, getThumbStyle(animatedValue)],
7779
- children: !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$20.thumbInner, thumbInnerStyle] })
7944
+ style: [styles$22.thumb, getThumbStyle(animatedValue)],
7945
+ children: !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$22.thumbInner, thumbInnerStyle] })
7780
7946
  }, index))
7781
7947
  ]
7782
7948
  })]
7783
7949
  });
7784
7950
  });
7785
7951
  Slider.displayName = "Slider";
7786
- const styles$20 = react_native.StyleSheet.create({
7952
+ const styles$22 = react_native.StyleSheet.create({
7787
7953
  container: { width: "100%" },
7788
7954
  labelContainer: {
7789
7955
  flexDirection: "row",
@@ -7863,7 +8029,7 @@ const DialogOverlay = ({ style }) => {
7863
8029
  const { grayAlpha } = useDialog();
7864
8030
  const overlayColor = useThemeMode$1() === "dark" ? "rgba(0, 0, 0, 0.6)" : "rgba(10, 10, 10, 0.6)";
7865
8031
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
7866
- styles$19.overlay,
8032
+ styles$21.overlay,
7867
8033
  { backgroundColor: overlayColor },
7868
8034
  style
7869
8035
  ] }) });
@@ -7905,7 +8071,7 @@ const DialogContent = ({ children, style, hideCloseButton = false, size = 2 }) =
7905
8071
  const maxWidth = size <= 2 ? Math.min(screenWidth - 64, 400) : Math.min(screenWidth - 64, 500);
7906
8072
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
7907
8073
  style: [
7908
- styles$19.content,
8074
+ styles$21.content,
7909
8075
  {
7910
8076
  backgroundColor: isDark ? theme.colors.gray.dark[2] : "#ffffff",
7911
8077
  borderRadius: sizeStyles.radius,
@@ -7919,14 +8085,14 @@ const DialogContent = ({ children, style, hideCloseButton = false, size = 2 }) =
7919
8085
  style
7920
8086
  ],
7921
8087
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
7922
- style: styles$19.scrollContent,
7923
- contentContainerStyle: styles$19.scrollContentContainer,
8088
+ style: styles$21.scrollContent,
8089
+ contentContainerStyle: styles$21.scrollContentContainer,
7924
8090
  showsVerticalScrollIndicator: true,
7925
8091
  bounces: true,
7926
8092
  children
7927
8093
  }), !hideCloseButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
7928
8094
  onPress: handleClose,
7929
- style: [styles$19.closeButton, { backgroundColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)" }],
8095
+ style: [styles$21.closeButton, { backgroundColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)" }],
7930
8096
  accessibilityRole: "button",
7931
8097
  accessibilityLabel: "Close dialog",
7932
8098
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
@@ -8011,7 +8177,7 @@ const DialogAction = ({ children, onPress, ...buttonProps }) => {
8011
8177
  children
8012
8178
  });
8013
8179
  };
8014
- const styles$19 = react_native.StyleSheet.create({
8180
+ const styles$21 = react_native.StyleSheet.create({
8015
8181
  overlay: {
8016
8182
  flex: 1,
8017
8183
  backgroundColor: "rgba(0, 0, 0, 0.5)"
@@ -8108,7 +8274,7 @@ const AlertDialogPortal = ({ children, hostId }) => {
8108
8274
  const AlertDialogOverlay = ({ style }) => {
8109
8275
  const overlayColor = useThemeMode$1() === "dark" ? "rgba(0, 0, 0, 0.6)" : "rgba(10, 10, 10, 0.6)";
8110
8276
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
8111
- styles$18.overlay,
8277
+ styles$20.overlay,
8112
8278
  { backgroundColor: overlayColor },
8113
8279
  style
8114
8280
  ] }) });
@@ -8149,7 +8315,7 @@ const AlertDialogContent = ({ children, style, hideCloseButton = true, size = 2
8149
8315
  };
8150
8316
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
8151
8317
  style: [
8152
- styles$18.content,
8318
+ styles$20.content,
8153
8319
  {
8154
8320
  backgroundColor: isDark ? theme.colors.gray.dark[2] : theme.colors.gray[1],
8155
8321
  borderRadius: sizeStyles.radius,
@@ -8163,14 +8329,14 @@ const AlertDialogContent = ({ children, style, hideCloseButton = true, size = 2
8163
8329
  style
8164
8330
  ],
8165
8331
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
8166
- style: styles$18.scrollContent,
8167
- contentContainerStyle: styles$18.scrollContentContainer,
8332
+ style: styles$20.scrollContent,
8333
+ contentContainerStyle: styles$20.scrollContentContainer,
8168
8334
  showsVerticalScrollIndicator: true,
8169
8335
  bounces: true,
8170
8336
  children
8171
8337
  }), !hideCloseButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
8172
8338
  onPress: handleClose,
8173
- style: [styles$18.closeButton, { backgroundColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)" }],
8339
+ style: [styles$20.closeButton, { backgroundColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)" }],
8174
8340
  accessibilityRole: "button",
8175
8341
  accessibilityLabel: "Close dialog",
8176
8342
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
@@ -8260,7 +8426,7 @@ const AlertDialog = ({ open, onOpenChange, title, description, cancel, action, c
8260
8426
  description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlertDialogDescription, { children: description }),
8261
8427
  children,
8262
8428
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
8263
- style: styles$18.actionRow,
8429
+ style: styles$20.actionRow,
8264
8430
  children: [cancel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlertDialogCancel, {
8265
8431
  variant: "ghost",
8266
8432
  children: cancel.label || "Cancel"
@@ -8274,7 +8440,7 @@ const AlertDialog = ({ open, onOpenChange, title, description, cancel, action, c
8274
8440
  ] })] })
8275
8441
  });
8276
8442
  };
8277
- const styles$18 = react_native.StyleSheet.create({
8443
+ const styles$20 = react_native.StyleSheet.create({
8278
8444
  overlay: {
8279
8445
  flex: 1,
8280
8446
  backgroundColor: "rgba(0, 0, 0, 0.5)"
@@ -8468,7 +8634,7 @@ const PopoverOverlay = ({ style }) => {
8468
8634
  const { onOpenChange } = usePopover();
8469
8635
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
8470
8636
  onPress: () => onOpenChange(false),
8471
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$17.overlay, style] })
8637
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$19.overlay, style] })
8472
8638
  });
8473
8639
  };
8474
8640
  const PopoverContent = ({ children, side = "bottom", sideOffset = 4, align = "center", alignOffset = 0, avoidCollisions = true, size = 2, style }) => {
@@ -8537,7 +8703,7 @@ const PopoverContent = ({ children, side = "bottom", sideOffset = 4, align = "ce
8537
8703
  ref: contentRef,
8538
8704
  onLayout: handleLayout,
8539
8705
  style: [
8540
- styles$17.content,
8706
+ styles$19.content,
8541
8707
  {
8542
8708
  backgroundColor: colors["1"] || grayAlpha["12"],
8543
8709
  borderRadius: radii.medium,
@@ -8603,7 +8769,7 @@ const PopoverClose = ({ children, ariaLabel = "Close popover" }) => {
8603
8769
  const { onOpenChange, colors } = usePopover();
8604
8770
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
8605
8771
  onPress: () => onOpenChange(false),
8606
- style: styles$17.closeButton,
8772
+ style: styles$19.closeButton,
8607
8773
  accessibilityLabel: ariaLabel,
8608
8774
  accessibilityRole: "button",
8609
8775
  children: children || /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
@@ -8615,7 +8781,7 @@ const PopoverClose = ({ children, ariaLabel = "Close popover" }) => {
8615
8781
  })
8616
8782
  });
8617
8783
  };
8618
- const styles$17 = react_native.StyleSheet.create({
8784
+ const styles$19 = react_native.StyleSheet.create({
8619
8785
  overlay: {
8620
8786
  flex: 1,
8621
8787
  backgroundColor: "rgba(0, 0, 0, 0.01)"
@@ -8776,7 +8942,7 @@ const TooltipPortal = ({ children }) => {
8776
8942
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
8777
8943
  onPress: () => onOpenChange(false),
8778
8944
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
8779
- style: styles$16.overlay,
8945
+ style: styles$18.overlay,
8780
8946
  children
8781
8947
  })
8782
8948
  })
@@ -8837,7 +9003,7 @@ const TooltipContent = ({ children, side = "top", sideOffset = 8, align = "cente
8837
9003
  ref: contentRef,
8838
9004
  onLayout: handleLayout,
8839
9005
  style: [
8840
- styles$16.content,
9006
+ styles$18.content,
8841
9007
  {
8842
9008
  backgroundColor: tooltipBackground,
8843
9009
  borderRadius,
@@ -8863,15 +9029,15 @@ const TooltipContent = ({ children, side = "top", sideOffset = 8, align = "cente
8863
9029
  },
8864
9030
  children
8865
9031
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
8866
- styles$16.arrow,
8867
- actualSide === "top" && [styles$16.arrowBottom, { borderTopColor: arrowColor }],
8868
- actualSide === "bottom" && [styles$16.arrowTop, { borderBottomColor: arrowColor }],
8869
- actualSide === "left" && [styles$16.arrowRight, {
9032
+ styles$18.arrow,
9033
+ actualSide === "top" && [styles$18.arrowBottom, { borderTopColor: arrowColor }],
9034
+ actualSide === "bottom" && [styles$18.arrowTop, { borderBottomColor: arrowColor }],
9035
+ actualSide === "left" && [styles$18.arrowRight, {
8870
9036
  borderLeftColor: arrowColor,
8871
9037
  borderTopColor: "transparent",
8872
9038
  borderBottomColor: "transparent"
8873
9039
  }],
8874
- actualSide === "right" && [styles$16.arrowLeft, {
9040
+ actualSide === "right" && [styles$18.arrowLeft, {
8875
9041
  borderRightColor: arrowColor,
8876
9042
  borderTopColor: "transparent",
8877
9043
  borderBottomColor: "transparent"
@@ -8910,7 +9076,7 @@ const Tooltip = ({ children, content, side = "top", sideOffset = 8, align = "cen
8910
9076
  }) })]
8911
9077
  });
8912
9078
  };
8913
- const styles$16 = react_native.StyleSheet.create({
9079
+ const styles$18 = react_native.StyleSheet.create({
8914
9080
  overlay: {
8915
9081
  flex: 1,
8916
9082
  backgroundColor: "rgba(0, 0, 0, 0.01)"
@@ -9021,10 +9187,11 @@ const DropdownMenuRoot = ({ children, open: controlledOpen, onOpenChange, defaul
9021
9187
  };
9022
9188
  const DropdownMenuTrigger = ({ children, asChild = false, hapticFeedback = true }) => {
9023
9189
  const { onOpenChange, open, anchorRef, measureAnchor } = useDropdownMenu();
9190
+ const globalHaptics = useHaptics$1();
9024
9191
  const handlePress = () => {
9025
9192
  measureAnchor();
9026
9193
  onOpenChange(!open);
9027
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9194
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9028
9195
  };
9029
9196
  if (asChild && react.default.isValidElement(children)) {
9030
9197
  const child = children;
@@ -9036,7 +9203,7 @@ const DropdownMenuTrigger = ({ children, asChild = false, hapticFeedback = true
9036
9203
  }
9037
9204
  });
9038
9205
  }
9039
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
9206
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
9040
9207
  ref: anchorRef,
9041
9208
  onPress: handlePress,
9042
9209
  pressedScale: .98,
@@ -9046,18 +9213,6 @@ const DropdownMenuTrigger = ({ children, asChild = false, hapticFeedback = true
9046
9213
  children
9047
9214
  });
9048
9215
  };
9049
- /**
9050
- * Default down chevron icon for dropdown menu trigger
9051
- * Uses Unicode character for React Native compatibility
9052
- */
9053
- const ChevronDownIcon = ({ size, color }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
9054
- style: {
9055
- fontSize: size || 16,
9056
- color: color || "currentColor",
9057
- lineHeight: size ? size + 2 : 18
9058
- },
9059
- children: "▾"
9060
- });
9061
9216
  const DropdownMenuTriggerIcon = ({ icon, variant = "ghost", color, size = 2, disabled, accessibilityLabel = "Open menu", highContrast, style }) => {
9062
9217
  const { onOpenChange, open, anchorRef, measureAnchor } = useDropdownMenu();
9063
9218
  const handlePress = () => {
@@ -9093,7 +9248,7 @@ const DropdownMenuOverlay = ({ style }) => {
9093
9248
  const { onOpenChange } = useDropdownMenu();
9094
9249
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
9095
9250
  onPress: () => onOpenChange(false),
9096
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$15.overlay, style] })
9251
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$17.overlay, style] })
9097
9252
  });
9098
9253
  };
9099
9254
  const DropdownMenuContent = ({ children, side = "bottom", sideOffset = 4, align = "start", alignOffset = 0, avoidCollisions = true, size = 2, style }) => {
@@ -9177,7 +9332,7 @@ const DropdownMenuContent = ({ children, side = "bottom", sideOffset = 4, align
9177
9332
  ref: contentRef,
9178
9333
  onLayout: handleLayout,
9179
9334
  style: [
9180
- styles$15.content,
9335
+ styles$17.content,
9181
9336
  {
9182
9337
  backgroundColor: colors[1],
9183
9338
  borderRadius: radii.medium,
@@ -9208,6 +9363,7 @@ const DropdownMenuGroup = ({ children }) => {
9208
9363
  };
9209
9364
  const DropdownMenuItem = ({ children, color, onSelect, disabled = false, shortcut, style, hapticFeedback = true }) => {
9210
9365
  const { colors, onOpenChange, size } = useDropdownMenu();
9366
+ const globalHaptics = useHaptics$1();
9211
9367
  const theme = useTheme$1();
9212
9368
  const mode = useThemeMode$1();
9213
9369
  const activeColor = color || theme.accentColor;
@@ -9252,17 +9408,17 @@ const DropdownMenuItem = ({ children, color, onSelect, disabled = false, shortcu
9252
9408
  if (!disabled) {
9253
9409
  onSelect?.();
9254
9410
  onOpenChange(false);
9255
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9411
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9256
9412
  }
9257
9413
  };
9258
9414
  const itemPadding = getItemPadding();
9259
9415
  const fontSize = getFontSize();
9260
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
9416
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
9261
9417
  onPress: handlePress,
9262
9418
  disabled,
9263
9419
  style: [
9264
- styles$15.item,
9265
- disabled && styles$15.itemDisabled,
9420
+ styles$17.item,
9421
+ disabled && styles$17.itemDisabled,
9266
9422
  { backgroundColor: disabled ? "transparent" : "transparent" },
9267
9423
  itemPadding,
9268
9424
  style
@@ -9292,7 +9448,7 @@ const DropdownMenuItem = ({ children, color, onSelect, disabled = false, shortcu
9292
9448
  const DropdownMenuSeparator = ({ style }) => {
9293
9449
  const { colors } = useDropdownMenu();
9294
9450
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
9295
- styles$15.separator,
9451
+ styles$17.separator,
9296
9452
  { backgroundColor: colors[6] },
9297
9453
  style
9298
9454
  ] });
@@ -9365,7 +9521,7 @@ const DropdownMenuCheckboxItem = ({ children, checked, onCheckedChange, disabled
9365
9521
  alignItems: "center"
9366
9522
  },
9367
9523
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
9368
- style: [styles$15.checkbox, {
9524
+ style: [styles$17.checkbox, {
9369
9525
  width: checkboxSize,
9370
9526
  height: checkboxSize,
9371
9527
  borderColor: colors[9],
@@ -9392,6 +9548,7 @@ const DropdownMenuCheckboxItem = ({ children, checked, onCheckedChange, disabled
9392
9548
  };
9393
9549
  const DropdownMenuRadioItem = ({ children, value, checked, onCheckedChange, disabled = false, hapticFeedback = true }) => {
9394
9550
  const { colors, size } = useDropdownMenu();
9551
+ const globalHaptics = useHaptics$1();
9395
9552
  const theme = useTheme$1();
9396
9553
  const getFontSize = (0, react.useCallback)(() => {
9397
9554
  switch (size) {
@@ -9412,7 +9569,7 @@ const DropdownMenuRadioItem = ({ children, value, checked, onCheckedChange, disa
9412
9569
  const handlePress = () => {
9413
9570
  if (!disabled) {
9414
9571
  onCheckedChange(value);
9415
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9572
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9416
9573
  }
9417
9574
  };
9418
9575
  const itemPadding = (0, react.useCallback)(() => {
@@ -9431,12 +9588,12 @@ const DropdownMenuRadioItem = ({ children, value, checked, onCheckedChange, disa
9431
9588
  };
9432
9589
  }
9433
9590
  }, [size, theme.space])();
9434
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
9591
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
9435
9592
  onPress: handlePress,
9436
9593
  disabled,
9437
9594
  style: [
9438
- styles$15.item,
9439
- disabled && styles$15.itemDisabled,
9595
+ styles$17.item,
9596
+ disabled && styles$17.itemDisabled,
9440
9597
  itemPadding
9441
9598
  ],
9442
9599
  accessibilityRole: "menuitem",
@@ -9455,7 +9612,7 @@ const DropdownMenuRadioItem = ({ children, value, checked, onCheckedChange, disa
9455
9612
  flex: 1
9456
9613
  },
9457
9614
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
9458
- style: [styles$15.radio, {
9615
+ style: [styles$17.radio, {
9459
9616
  width: radioSize,
9460
9617
  height: radioSize,
9461
9618
  borderRadius: radioSize / 2,
@@ -9484,6 +9641,7 @@ const DropdownMenuSub = ({ children }) => {
9484
9641
  };
9485
9642
  const DropdownMenuSubTrigger = ({ children, hapticFeedback = true }) => {
9486
9643
  const { colors, openSubmenu, onOpenSubmenu, size } = useDropdownMenu();
9644
+ const globalHaptics = useHaptics$1();
9487
9645
  const theme = useTheme$1();
9488
9646
  const submenuId = "submenu";
9489
9647
  const getFontSize = (0, react.useCallback)(() => {
@@ -9511,13 +9669,13 @@ const DropdownMenuSubTrigger = ({ children, hapticFeedback = true }) => {
9511
9669
  }, [size, theme.space]);
9512
9670
  const handlePress = () => {
9513
9671
  onOpenSubmenu(openSubmenu === submenuId ? null : submenuId);
9514
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9672
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9515
9673
  };
9516
9674
  const itemPadding = getItemPadding();
9517
9675
  const fontSize = getFontSize();
9518
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
9676
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
9519
9677
  onPress: handlePress,
9520
- style: [styles$15.item, itemPadding],
9678
+ style: [styles$17.item, itemPadding],
9521
9679
  pressedScale: .98,
9522
9680
  pressedOpacity: .95,
9523
9681
  animationDuration: 100,
@@ -9558,7 +9716,7 @@ const DropdownMenuSubContent = ({ children }) => {
9558
9716
  }
9559
9717
  }, [size, theme.space])();
9560
9718
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
9561
- style: [styles$15.content, {
9719
+ style: [styles$17.content, {
9562
9720
  backgroundColor: colors[1],
9563
9721
  borderRadius: radii.medium,
9564
9722
  borderWidth: 1,
@@ -9573,7 +9731,7 @@ const DropdownMenuSubContent = ({ children }) => {
9573
9731
  children
9574
9732
  });
9575
9733
  };
9576
- const styles$15 = react_native.StyleSheet.create({
9734
+ const styles$17 = react_native.StyleSheet.create({
9577
9735
  overlay: {
9578
9736
  flex: 1,
9579
9737
  backgroundColor: "rgba(0, 0, 0, 0.01)"
@@ -9667,6 +9825,7 @@ const ContextMenuRoot = ({ children, open: controlledOpen, onOpenChange, default
9667
9825
  };
9668
9826
  const ContextMenuTrigger = ({ children, onLongPress, asChild = false, hapticFeedback = true }) => {
9669
9827
  const { setPosition, onOpenChange } = useContextMenuContext();
9828
+ const globalHaptics = useHaptics$1();
9670
9829
  const handleLongPress = (event) => {
9671
9830
  const { pageX, pageY } = event.nativeEvent;
9672
9831
  setPosition({
@@ -9675,7 +9834,7 @@ const ContextMenuTrigger = ({ children, onLongPress, asChild = false, hapticFeed
9675
9834
  });
9676
9835
  onOpenChange(true);
9677
9836
  onLongPress?.(event);
9678
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9837
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9679
9838
  };
9680
9839
  if (asChild && react.default.isValidElement(children)) {
9681
9840
  const child = children;
@@ -9684,7 +9843,7 @@ const ContextMenuTrigger = ({ children, onLongPress, asChild = false, hapticFeed
9684
9843
  handleLongPress(e);
9685
9844
  } });
9686
9845
  }
9687
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
9846
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
9688
9847
  onLongPress: handleLongPress,
9689
9848
  pressedScale: .98,
9690
9849
  pressedOpacity: .95,
@@ -9709,7 +9868,7 @@ const ContextMenuOverlay = ({ style }) => {
9709
9868
  const { onOpenChange } = useContextMenuContext();
9710
9869
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
9711
9870
  onPress: () => onOpenChange(false),
9712
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$14.overlay, style] })
9871
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [styles$16.overlay, style] })
9713
9872
  });
9714
9873
  };
9715
9874
  /**
@@ -9746,6 +9905,7 @@ const getSizeStyles$2 = (size, theme) => {
9746
9905
  const ContextMenuContent = ({ children, side = "bottom", sideOffset = 4, align = "start", alignOffset = 0, avoidCollisions = true, size = 2, style }) => {
9747
9906
  const { colors, radii, position } = useContextMenuContext();
9748
9907
  const theme = useTheme$1();
9908
+ const mode = useThemeMode$1();
9749
9909
  const contentRef = (0, react.useRef)(null);
9750
9910
  const [contentSize, setContentSize] = (0, react.useState)({
9751
9911
  width: 0,
@@ -9791,12 +9951,11 @@ const ContextMenuContent = ({ children, side = "bottom", sideOffset = 4, align =
9791
9951
  ref: contentRef,
9792
9952
  onLayout: handleLayout,
9793
9953
  style: [
9794
- styles$14.content,
9954
+ styles$16.content,
9795
9955
  {
9796
- backgroundColor: colors[1],
9797
- borderRadius: radii.medium,
9798
- borderWidth: 1,
9799
- borderColor: colors[6],
9956
+ backgroundColor: mode === "dark" ? colors[3] : colors[1],
9957
+ borderRadius: theme.radii[theme.radius] || radii.medium,
9958
+ borderColor: colors[2],
9800
9959
  paddingVertical: sizeStyles.paddingVertical,
9801
9960
  paddingHorizontal: sizeStyles.paddingHorizontal,
9802
9961
  minWidth: sizeStyles.minWidth,
@@ -9826,11 +9985,12 @@ const ContextMenuGroup = ({ children }) => {
9826
9985
  const ContextMenuItem = ({ children, color, onSelect, disabled = false, destructive = false, icon, shortcut, style, hapticFeedback = true }) => {
9827
9986
  const { colors, onOpenChange, size } = useContextMenuContext();
9828
9987
  const theme = useTheme$1();
9988
+ const globalHaptics = useHaptics$1();
9829
9989
  const handlePress = () => {
9830
9990
  if (!disabled) {
9831
9991
  onSelect?.();
9832
9992
  onOpenChange(false);
9833
- if (hapticFeedback) react_native.Vibration.vibrate(10);
9993
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
9834
9994
  }
9835
9995
  };
9836
9996
  const getFontSize = (0, react.useCallback)(() => {
@@ -9865,12 +10025,12 @@ const ContextMenuItem = ({ children, color, onSelect, disabled = false, destruct
9865
10025
  const itemPadding = getItemPadding();
9866
10026
  const destructiveColor = theme.colors.red[11];
9867
10027
  const textColor = disabled ? colors[8] : destructive ? destructiveColor : colors[12];
9868
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
10028
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
9869
10029
  onPress: handlePress,
9870
10030
  disabled,
9871
10031
  style: [
9872
- styles$14.item,
9873
- disabled && styles$14.itemDisabled,
10032
+ styles$16.item,
10033
+ disabled && styles$16.itemDisabled,
9874
10034
  itemPadding,
9875
10035
  style
9876
10036
  ],
@@ -9906,7 +10066,7 @@ const ContextMenuItem = ({ children, color, onSelect, disabled = false, destruct
9906
10066
  const ContextMenuSeparator = ({ style }) => {
9907
10067
  const { colors } = useContextMenuContext();
9908
10068
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
9909
- styles$14.separator,
10069
+ styles$16.separator,
9910
10070
  { backgroundColor: colors[6] },
9911
10071
  style
9912
10072
  ] });
@@ -9980,7 +10140,7 @@ const ContextMenuCheckboxItem = ({ children, checked, onCheckedChange, disabled
9980
10140
  flex: 1
9981
10141
  },
9982
10142
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
9983
- style: [styles$14.checkbox, {
10143
+ style: [styles$16.checkbox, {
9984
10144
  width: checkboxSize,
9985
10145
  height: checkboxSize,
9986
10146
  borderColor: colors[9],
@@ -10005,9 +10165,10 @@ const ContextMenuCheckboxItem = ({ children, checked, onCheckedChange, disabled
10005
10165
  })
10006
10166
  });
10007
10167
  };
10008
- const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disabled = false }) => {
10168
+ const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disabled = false, hapticFeedback = true }) => {
10009
10169
  const { colors, size } = useContextMenuContext();
10010
10170
  const theme = useTheme$1();
10171
+ const globalHaptics = useHaptics$1();
10011
10172
  const getFontSize = (0, react.useCallback)(() => {
10012
10173
  switch (size) {
10013
10174
  case 1: return theme.typography.fontSizes[1].fontSize;
@@ -10027,7 +10188,7 @@ const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disab
10027
10188
  const handlePress = () => {
10028
10189
  if (!disabled) {
10029
10190
  onCheckedChange(value);
10030
- react_native.Vibration.vibrate(10);
10191
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
10031
10192
  }
10032
10193
  };
10033
10194
  const itemPadding = (0, react.useCallback)(() => {
@@ -10046,12 +10207,12 @@ const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disab
10046
10207
  };
10047
10208
  }
10048
10209
  }, [size, theme.space])();
10049
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
10210
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
10050
10211
  onPress: handlePress,
10051
10212
  disabled,
10052
10213
  style: [
10053
- styles$14.item,
10054
- disabled && styles$14.itemDisabled,
10214
+ styles$16.item,
10215
+ disabled && styles$16.itemDisabled,
10055
10216
  itemPadding
10056
10217
  ],
10057
10218
  accessibilityRole: "menuitem",
@@ -10070,7 +10231,7 @@ const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disab
10070
10231
  flex: 1
10071
10232
  },
10072
10233
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
10073
- style: [styles$14.radio, {
10234
+ style: [styles$16.radio, {
10074
10235
  width: radioSize,
10075
10236
  height: radioSize,
10076
10237
  borderRadius: radioSize / 2,
@@ -10094,7 +10255,7 @@ const ContextMenuRadioItem = ({ children, value, checked, onCheckedChange, disab
10094
10255
  })
10095
10256
  });
10096
10257
  };
10097
- const styles$14 = react_native.StyleSheet.create({
10258
+ const styles$16 = react_native.StyleSheet.create({
10098
10259
  overlay: {
10099
10260
  flex: 1,
10100
10261
  backgroundColor: "rgba(0, 0, 0, 0.01)"
@@ -10259,7 +10420,7 @@ const BottomSheetRoot = ({ children, open: controlledOpen, onOpenChange, snapPoi
10259
10420
  },
10260
10421
  onPanResponderRelease: (_, gestureState) => {
10261
10422
  if (gestureState.dy > 100 || gestureState.vy > 500 / 1e3) {
10262
- react_native.Vibration.vibrate(10);
10423
+ if (globalHaptics) triggerHaptic("selection");
10263
10424
  react_native.Animated.timing(translateY, {
10264
10425
  toValue: targetSnapHeight,
10265
10426
  duration: 200,
@@ -10291,7 +10452,9 @@ const BottomSheetRoot = ({ children, open: controlledOpen, onOpenChange, snapPoi
10291
10452
  }
10292
10453
  }, [open]);
10293
10454
  const theme = useTheme$1();
10294
- const colors = useThemeMode$1() === "dark" ? theme.colors.gray.dark : theme.colors.gray;
10455
+ const mode = useThemeMode$1();
10456
+ const globalHaptics = useHaptics$1();
10457
+ const colors = mode === "dark" ? theme.colors.gray.dark : theme.colors.gray;
10295
10458
  const grayAlpha = getGrayAlpha(theme);
10296
10459
  const radii = theme.radii;
10297
10460
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BottomSheetContext.Provider, {
@@ -10315,15 +10478,16 @@ const BottomSheetRoot = ({ children, open: controlledOpen, onOpenChange, snapPoi
10315
10478
  };
10316
10479
  const BottomSheetTrigger = ({ children, asChild = true, hapticFeedback = false }) => {
10317
10480
  const { onOpenChange, open } = useBottomSheet();
10481
+ const globalHaptics = useHaptics$1();
10318
10482
  const handlePress = () => {
10319
10483
  onOpenChange(true);
10320
- if (hapticFeedback) react_native.Vibration.vibrate(10);
10484
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
10321
10485
  };
10322
10486
  if (asChild && react.default.isValidElement(children)) return react.default.cloneElement(children, { onPress: (e) => {
10323
10487
  children.props?.onPress?.(e);
10324
10488
  handlePress();
10325
10489
  } });
10326
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
10490
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
10327
10491
  onPress: handlePress,
10328
10492
  pressedScale: .98,
10329
10493
  pressedOpacity: .95,
@@ -10345,15 +10509,17 @@ const BottomSheetPortal = ({ children, hostId }) => {
10345
10509
  };
10346
10510
  const BottomSheetOverlay = ({ style, hapticFeedback = true }) => {
10347
10511
  const { onOpenChange } = useBottomSheet();
10348
- const overlayColor = useThemeMode$1() === "dark" ? "rgba(0, 0, 0, 0.6)" : "rgba(10, 10, 10, 0.6)";
10512
+ const mode = useThemeMode$1();
10513
+ const globalHaptics = useHaptics$1();
10514
+ const overlayColor = mode === "dark" ? "rgba(0, 0, 0, 0.6)" : "rgba(10, 10, 10, 0.6)";
10349
10515
  const handlePress = () => {
10350
10516
  onOpenChange(false);
10351
- if (hapticFeedback) react_native.Vibration.vibrate(10);
10517
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
10352
10518
  };
10353
10519
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
10354
10520
  onPress: handlePress,
10355
10521
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
10356
- styles$13.overlay,
10522
+ styles$15.overlay,
10357
10523
  { backgroundColor: overlayColor },
10358
10524
  style
10359
10525
  ] })
@@ -10364,10 +10530,10 @@ const BottomSheetHandle = ({ style }) => {
10364
10530
  const theme = useTheme$1();
10365
10531
  const handleColor = useThemeMode$1() === "dark" ? theme.colors.gray.dark[8] : theme.colors.gray[8];
10366
10532
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
10367
- style: styles$13.handleContainer,
10533
+ style: styles$15.handleContainer,
10368
10534
  ...panHandlers,
10369
10535
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
10370
- styles$13.handle,
10536
+ styles$15.handle,
10371
10537
  { backgroundColor: handleColor },
10372
10538
  style
10373
10539
  ] })
@@ -10377,7 +10543,9 @@ const BottomSheetContent = ({ children, style, snapPoints: localSnapPoints, size
10377
10543
  const { radii, snapPoints: contextSnapPoints, currentSnapIndex, translateY, snapHeights, panHandlers } = useBottomSheet();
10378
10544
  const theme = useTheme$1();
10379
10545
  const isDark = useThemeMode$1() === "dark";
10546
+ const effectiveSnapPoints = localSnapPoints || contextSnapPoints;
10380
10547
  const targetSnapHeight = snapHeights[currentSnapIndex] || snapHeights[0];
10548
+ const maxTargetSnapHeight = snapHeights[effectiveSnapPoints.length - 1] || snapHeights[0];
10381
10549
  const sizeStyles = getSizeStyles$1(size, theme.space, radii);
10382
10550
  const shadow = getShadow(6, isDark);
10383
10551
  const backgroundColor = isDark ? theme.colors.gray.dark[2] : "#ffffff";
@@ -10385,27 +10553,22 @@ const BottomSheetContent = ({ children, style, snapPoints: localSnapPoints, size
10385
10553
  const borderTopRightRadius = radii.large;
10386
10554
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.Animated.View, {
10387
10555
  style: [
10388
- styles$13.content,
10556
+ styles$15.content,
10389
10557
  {
10390
10558
  backgroundColor,
10391
10559
  borderTopLeftRadius,
10392
10560
  borderTopRightRadius,
10393
10561
  flex: 1,
10394
10562
  paddingHorizontal: sizeStyles.paddingHorizontal,
10395
- height: targetSnapHeight,
10563
+ minHeight: targetSnapHeight,
10564
+ maxHeight: maxTargetSnapHeight,
10396
10565
  transform: [{ translateY }],
10397
10566
  ...shadow || {}
10398
10567
  },
10399
10568
  style
10400
10569
  ],
10401
10570
  ...panHandlers,
10402
- children: [!hideHandle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BottomSheetHandle, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
10403
- style: styles$13.scrollContent,
10404
- contentContainerStyle: styles$13.scrollContentContainer,
10405
- showsVerticalScrollIndicator: true,
10406
- bounces: true,
10407
- children
10408
- })]
10571
+ children: [!hideHandle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BottomSheetHandle, {}), children]
10409
10572
  });
10410
10573
  };
10411
10574
  const BottomSheetTitle = ({ children, style = {}, size = 4, weight = "bold", align, color, truncate, numberOfLines, fontFamily, opacity, asChild = false, ...rest }) => {
@@ -10455,7 +10618,7 @@ const BottomSheetFooter = ({ children, style, withBorder = true, withPadding = t
10455
10618
  const borderColor = useThemeMode$1() === "dark" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)";
10456
10619
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
10457
10620
  style: [
10458
- styles$13.footer,
10621
+ styles$15.footer,
10459
10622
  withBorder && {
10460
10623
  borderTopWidth: 1,
10461
10624
  borderTopColor: borderColor
@@ -10467,16 +10630,17 @@ const BottomSheetFooter = ({ children, style, withBorder = true, withPadding = t
10467
10630
  style
10468
10631
  ],
10469
10632
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
10470
- style: styles$13.footerContent,
10633
+ style: styles$15.footerContent,
10471
10634
  children
10472
10635
  })
10473
10636
  });
10474
10637
  };
10475
10638
  const BottomSheetClose = ({ children, asChild = true, hapticFeedback = false, ...buttonProps }) => {
10476
10639
  const { onOpenChange } = useBottomSheet();
10640
+ const globalHaptics = useHaptics$1();
10477
10641
  const handlePress = () => {
10478
10642
  onOpenChange(false);
10479
- if (hapticFeedback) react_native.Vibration.vibrate(10);
10643
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
10480
10644
  };
10481
10645
  if (asChild && children && react.default.isValidElement(children)) return react.default.cloneElement(children, { onPress: (e) => {
10482
10646
  children.props?.onPress?.(e);
@@ -10491,10 +10655,11 @@ const BottomSheetClose = ({ children, asChild = true, hapticFeedback = false, ..
10491
10655
  };
10492
10656
  const BottomSheetAction = ({ children, onPress, hapticFeedback = true, ...buttonProps }) => {
10493
10657
  const { onOpenChange } = useBottomSheet();
10658
+ const globalHaptics = useHaptics$1();
10494
10659
  const handlePress = () => {
10495
10660
  onPress?.();
10496
10661
  onOpenChange(false);
10497
- if (hapticFeedback) react_native.Vibration.vibrate(10);
10662
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
10498
10663
  };
10499
10664
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
10500
10665
  ...buttonProps,
@@ -10502,7 +10667,7 @@ const BottomSheetAction = ({ children, onPress, hapticFeedback = true, ...button
10502
10667
  children
10503
10668
  });
10504
10669
  };
10505
- const styles$13 = react_native.StyleSheet.create({
10670
+ const styles$15 = react_native.StyleSheet.create({
10506
10671
  overlay: {
10507
10672
  flex: 1,
10508
10673
  backgroundColor: "rgba(0, 0, 0, 0.5)"
@@ -10512,7 +10677,8 @@ const styles$13 = react_native.StyleSheet.create({
10512
10677
  left: 0,
10513
10678
  right: 0,
10514
10679
  bottom: 0,
10515
- elevation: 4
10680
+ elevation: 4,
10681
+ paddingBottom: 16
10516
10682
  },
10517
10683
  handleContainer: {
10518
10684
  alignItems: "center",
@@ -10531,8 +10697,7 @@ const styles$13 = react_native.StyleSheet.create({
10531
10697
  footer: {
10532
10698
  flexDirection: "row",
10533
10699
  justifyContent: "flex-end",
10534
- alignItems: "center",
10535
- marginTop: 8
10700
+ alignItems: "center"
10536
10701
  },
10537
10702
  footerContent: {
10538
10703
  flexDirection: "row",
@@ -10554,51 +10719,619 @@ const BottomSheet = {
10554
10719
  };
10555
10720
 
10556
10721
  //#endregion
10557
- //#region src/components/data-display/Avatar.tsx
10558
- const Avatar = react.default.forwardRef(({ src, alt = "Avatar", color, variant = "solid", highContrast, radius, size = 2, fallback, fallbackBehavior = "character", style, accessibilityLabel, children }, ref) => {
10559
- const theme = useTheme$1();
10560
- const mode = useThemeMode$1();
10561
- const isDark = mode === "dark";
10562
- const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
10563
- const grayAlpha = getGrayAlpha(theme);
10564
- const activeColor = color || theme.accentColor;
10565
- const radii = theme.radii[radius] ?? theme.radii.medium;
10566
- const selectedRadius = radius || theme.radius;
10567
- const [imageError, setImageError] = (0, react.useState)(false);
10568
- const variantColors = (0, react.useMemo)(() => getVariantColors(theme, activeColor, mode, variant, highContrast), [
10569
- getVariantColors,
10570
- color,
10571
- variant,
10572
- highContrast,
10573
- isDark,
10574
- theme
10575
- ]);
10576
- const getSizeValues = () => {
10577
- switch (size) {
10578
- case 1: return {
10579
- size: 24,
10580
- fontSize: 10,
10581
- borderWidth: 0,
10582
- borderRadius: selectedRadius === "full" ? 9999 : radii
10583
- };
10584
- case 2: return {
10585
- size: 32,
10586
- fontSize: 12,
10587
- borderWidth: 0,
10588
- borderRadius: selectedRadius === "full" ? 9999 : radii
10589
- };
10590
- case 3: return {
10591
- size: 48,
10592
- fontSize: 18,
10593
- borderWidth: 0,
10594
- borderRadius: selectedRadius === "full" ? 9999 : radii
10595
- };
10596
- case 4: return {
10597
- size: 64,
10598
- fontSize: 24,
10599
- borderWidth: 0,
10600
- borderRadius: selectedRadius === "full" ? 9999 : radii
10601
- };
10722
+ //#region src/components/overlays/Sidebar.tsx
10723
+ const SidebarContext = (0, react.createContext)(null);
10724
+ const useSidebar = () => {
10725
+ const context = (0, react.useContext)(SidebarContext);
10726
+ if (!context) throw new Error("Sidebar components must be used within a Sidebar.Root");
10727
+ return context;
10728
+ };
10729
+ const { width: SCREEN_WIDTH } = react_native.Dimensions.get("window");
10730
+ const SidebarRoot = ({ children, open: controlledOpen, onOpenChange, side = "left", variant = "overlay", width = 280, animationDuration = 300 }) => {
10731
+ const [internalOpen, setInternalOpen] = (0, react.useState)(false);
10732
+ const open = controlledOpen !== void 0 ? controlledOpen : internalOpen;
10733
+ const initialTranslateX = side === "left" ? -width : width;
10734
+ const translateX = (0, react.useRef)(new react_native.Animated.Value(open ? 0 : initialTranslateX)).current;
10735
+ const mainTranslateX = (0, react.useRef)(new react_native.Animated.Value(0)).current;
10736
+ const skipAnimationRef = (0, react.useRef)(false);
10737
+ const swipeDistance = (0, react.useRef)(0);
10738
+ const isSwiping = (0, react.useRef)(false);
10739
+ const startX = (0, react.useRef)(0);
10740
+ const handleOpenChange = (0, react.useCallback)((newOpen, skipAnimation = false) => {
10741
+ skipAnimationRef.current = skipAnimation;
10742
+ if (controlledOpen === void 0) setInternalOpen(newOpen);
10743
+ onOpenChange?.(newOpen);
10744
+ }, [controlledOpen, onOpenChange]);
10745
+ const panResponder = (0, react.useMemo)(() => {
10746
+ return react_native.PanResponder.create({
10747
+ onStartShouldSetPanResponder: () => false,
10748
+ onMoveShouldSetPanResponder: (_, gestureState) => {
10749
+ return Math.abs(gestureState.dx) > 10 && Math.abs(gestureState.dx) > Math.abs(gestureState.dy);
10750
+ },
10751
+ onPanResponderGrant: () => {
10752
+ startX.current = 0;
10753
+ isSwiping.current = true;
10754
+ },
10755
+ onPanResponderMove: (_, gestureState) => {
10756
+ isSwiping.current = true;
10757
+ swipeDistance.current = gestureState.dx;
10758
+ if (side === "left") {
10759
+ const newTranslateX = initialTranslateX + gestureState.dx;
10760
+ const clampedValue = Math.max(-width, Math.min(0, newTranslateX));
10761
+ translateX.setValue(clampedValue);
10762
+ } else {
10763
+ const newTranslateX = initialTranslateX + gestureState.dx;
10764
+ const clampedValue = Math.max(0, Math.min(width, newTranslateX));
10765
+ translateX.setValue(clampedValue);
10766
+ }
10767
+ },
10768
+ onPanResponderRelease: (_, gestureState) => {
10769
+ const threshold = width * .25;
10770
+ const velocityThreshold = 500;
10771
+ if (side === "left") if (gestureState.dx > threshold || gestureState.vx > velocityThreshold / 1e3) react_native.Animated.timing(translateX, {
10772
+ toValue: 0,
10773
+ duration: animationDuration,
10774
+ useNativeDriver: true
10775
+ }).start();
10776
+ else if (gestureState.dx < -threshold || gestureState.vx < -velocityThreshold / 1e3) {
10777
+ if (globalHaptics) triggerHaptic("selection");
10778
+ react_native.Animated.timing(translateX, {
10779
+ toValue: -width,
10780
+ duration: animationDuration,
10781
+ useNativeDriver: true
10782
+ }).start();
10783
+ } else react_native.Animated.spring(translateX, {
10784
+ toValue: open ? 0 : -width,
10785
+ tension: 65,
10786
+ friction: 11,
10787
+ useNativeDriver: true
10788
+ }).start();
10789
+ else if (gestureState.dx < -threshold || gestureState.vx < -velocityThreshold / 1e3) react_native.Animated.timing(translateX, {
10790
+ toValue: 0,
10791
+ duration: animationDuration,
10792
+ useNativeDriver: true
10793
+ }).start();
10794
+ else if (gestureState.dx > threshold || gestureState.vx > velocityThreshold / 1e3) {
10795
+ if (globalHaptics) triggerHaptic("selection");
10796
+ react_native.Animated.timing(translateX, {
10797
+ toValue: width,
10798
+ duration: animationDuration,
10799
+ useNativeDriver: true
10800
+ }).start();
10801
+ } else react_native.Animated.spring(translateX, {
10802
+ toValue: open ? 0 : width,
10803
+ tension: 65,
10804
+ friction: 11,
10805
+ useNativeDriver: true
10806
+ }).start();
10807
+ isSwiping.current = false;
10808
+ }
10809
+ });
10810
+ }, [
10811
+ translateX,
10812
+ width,
10813
+ side,
10814
+ open,
10815
+ initialTranslateX,
10816
+ handleOpenChange,
10817
+ globalHaptics
10818
+ ]);
10819
+ (0, react.useEffect)(() => {
10820
+ if (skipAnimationRef.current) {
10821
+ skipAnimationRef.current = false;
10822
+ return;
10823
+ }
10824
+ if (open) {
10825
+ translateX.setValue(side === "left" ? -width : width);
10826
+ react_native.Animated.timing(translateX, {
10827
+ toValue: 0,
10828
+ duration: animationDuration,
10829
+ useNativeDriver: true
10830
+ }).start();
10831
+ } else react_native.Animated.timing(translateX, {
10832
+ toValue: side === "left" ? -width : width,
10833
+ duration: animationDuration,
10834
+ useNativeDriver: true
10835
+ }).start();
10836
+ }, [
10837
+ open,
10838
+ width,
10839
+ side,
10840
+ translateX,
10841
+ animationDuration
10842
+ ]);
10843
+ (0, react.useEffect)(() => {
10844
+ if (skipAnimationRef.current) return;
10845
+ if (variant === "push") if (open) react_native.Animated.timing(mainTranslateX, {
10846
+ toValue: side === "left" ? width : -width,
10847
+ duration: animationDuration,
10848
+ useNativeDriver: true
10849
+ }).start();
10850
+ else react_native.Animated.timing(mainTranslateX, {
10851
+ toValue: 0,
10852
+ duration: animationDuration,
10853
+ useNativeDriver: true
10854
+ }).start();
10855
+ }, [
10856
+ open,
10857
+ width,
10858
+ side,
10859
+ variant,
10860
+ mainTranslateX,
10861
+ animationDuration
10862
+ ]);
10863
+ const theme = useTheme$1();
10864
+ const mode = useThemeMode$1();
10865
+ const globalHaptics = useHaptics$1();
10866
+ const colors = mode === "dark" ? theme.colors.gray.dark : theme.colors.gray;
10867
+ const grayAlpha = getGrayAlpha(theme);
10868
+ const radii = theme.radii;
10869
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarContext.Provider, {
10870
+ value: {
10871
+ open,
10872
+ onOpenChange: handleOpenChange,
10873
+ side,
10874
+ variant,
10875
+ width,
10876
+ animationDuration,
10877
+ colors,
10878
+ grayAlpha,
10879
+ radii,
10880
+ translateX,
10881
+ mainTranslateX,
10882
+ panHandlers: panResponder.panHandlers,
10883
+ globalHaptics
10884
+ },
10885
+ children
10886
+ });
10887
+ };
10888
+ const SidebarTrigger = ({ children, asChild = true, hapticFeedback = false }) => {
10889
+ const { onOpenChange, globalHaptics } = useSidebar();
10890
+ const handlePress = () => {
10891
+ onOpenChange(true);
10892
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
10893
+ };
10894
+ if (asChild && react.default.isValidElement(children)) return react.default.cloneElement(children, { onPress: (e) => {
10895
+ children.props?.onPress?.(e);
10896
+ handlePress();
10897
+ } });
10898
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
10899
+ onPress: handlePress,
10900
+ pressedScale: .98,
10901
+ pressedOpacity: .95,
10902
+ animationDuration: 100,
10903
+ hapticFeedback: false,
10904
+ children
10905
+ });
10906
+ };
10907
+ const SidebarPortal = ({ children }) => {
10908
+ const { open, variant } = useSidebar();
10909
+ if (variant === "push") return null;
10910
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Modal, {
10911
+ transparent: true,
10912
+ visible: open,
10913
+ animationType: "none",
10914
+ supportedOrientations: ["portrait", "landscape"],
10915
+ onRequestClose: () => {},
10916
+ children
10917
+ });
10918
+ };
10919
+ const SidebarOverlay = ({ style, hapticFeedback = true }) => {
10920
+ const { onOpenChange, variant, globalHaptics } = useSidebar();
10921
+ const isDark = useThemeMode$1() === "dark";
10922
+ if (variant === "push") return null;
10923
+ const overlayColor = isDark ? "rgba(0, 0, 0, 0.6)" : "rgba(10, 10, 10, 0.6)";
10924
+ const handlePress = () => {
10925
+ onOpenChange(false);
10926
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
10927
+ };
10928
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
10929
+ onPress: handlePress,
10930
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
10931
+ styles$14.overlay,
10932
+ { backgroundColor: overlayColor },
10933
+ style
10934
+ ] })
10935
+ });
10936
+ };
10937
+ const SidebarContent = ({ children, style }) => {
10938
+ const { side, variant, width, translateX, panHandlers, radii, colors } = useSidebar();
10939
+ const theme = useTheme$1();
10940
+ const isDark = useThemeMode$1() === "dark";
10941
+ const backgroundColor = isDark ? theme.colors.gray.dark[2] : "#ffffff";
10942
+ const shadow = getShadow(6, isDark);
10943
+ const borderRadius = side === "left" ? {
10944
+ borderTopRightRadius: radii.large,
10945
+ borderBottomRightRadius: radii.large
10946
+ } : {
10947
+ borderTopLeftRadius: radii.large,
10948
+ borderBottomLeftRadius: radii.large
10949
+ };
10950
+ if (variant === "push") {
10951
+ const positionStyle = side === "left" ? { marginRight: -width } : { marginLeft: -width };
10952
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, {
10953
+ style: [{
10954
+ backgroundColor,
10955
+ width,
10956
+ ...borderRadius,
10957
+ transform: [{ translateX }],
10958
+ ...shadow || {},
10959
+ ...positionStyle
10960
+ }, style],
10961
+ ...panHandlers,
10962
+ children
10963
+ });
10964
+ }
10965
+ const positionStyle = side === "left" ? { left: 0 } : { right: 0 };
10966
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, {
10967
+ style: [
10968
+ styles$14.content,
10969
+ {
10970
+ backgroundColor,
10971
+ width,
10972
+ ...borderRadius,
10973
+ ...positionStyle,
10974
+ transform: [{ translateX }],
10975
+ ...shadow || {}
10976
+ },
10977
+ style
10978
+ ],
10979
+ ...panHandlers,
10980
+ children
10981
+ });
10982
+ };
10983
+ const SidebarHeader = ({ children, style }) => {
10984
+ const theme = useTheme$1();
10985
+ const borderColor = useThemeMode$1() === "dark" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)";
10986
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
10987
+ style: [
10988
+ styles$14.header,
10989
+ {
10990
+ paddingHorizontal: theme.space[4],
10991
+ paddingVertical: theme.space[3],
10992
+ borderBottomWidth: 1,
10993
+ borderBottomColor: borderColor
10994
+ },
10995
+ style
10996
+ ],
10997
+ children
10998
+ });
10999
+ };
11000
+ const SidebarItem = ({ children, onPress, style, hapticFeedback = true }) => {
11001
+ const { onOpenChange, globalHaptics } = useSidebar();
11002
+ const theme = useTheme$1();
11003
+ const isDark = useThemeMode$1() === "dark";
11004
+ const handlePress = () => {
11005
+ onPress?.();
11006
+ onOpenChange(false);
11007
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
11008
+ };
11009
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
11010
+ style: ({ pressed }) => [
11011
+ styles$14.item,
11012
+ {
11013
+ paddingHorizontal: theme.space[4],
11014
+ paddingVertical: theme.space[3],
11015
+ backgroundColor: pressed ? isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.05)" : "transparent"
11016
+ },
11017
+ style
11018
+ ],
11019
+ onPress: handlePress,
11020
+ children
11021
+ });
11022
+ };
11023
+ const SidebarSeparator = ({ style }) => {
11024
+ const theme = useTheme$1();
11025
+ const borderColor = useThemeMode$1() === "dark" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)";
11026
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [
11027
+ styles$14.separator,
11028
+ {
11029
+ marginHorizontal: theme.space[4],
11030
+ borderBottomWidth: 1,
11031
+ borderBottomColor: borderColor
11032
+ },
11033
+ style
11034
+ ] });
11035
+ };
11036
+ const SidebarBackdrop = ({ style, hapticFeedback = true }) => {
11037
+ const { onOpenChange, variant, globalHaptics } = useSidebar();
11038
+ const isDark = useThemeMode$1() === "dark";
11039
+ if (variant === "overlay") return null;
11040
+ const overlayColor = isDark ? "rgba(0, 0, 0, 0.3)" : "rgba(0, 0, 0, 0.2)";
11041
+ const handlePress = () => {
11042
+ onOpenChange(false);
11043
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
11044
+ };
11045
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableWithoutFeedback, {
11046
+ onPress: handlePress,
11047
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: [
11048
+ styles$14.backdrop,
11049
+ { backgroundColor: overlayColor },
11050
+ style
11051
+ ] })
11052
+ });
11053
+ };
11054
+ const SidebarContainer = ({ children }) => {
11055
+ const { animationDuration, variant, side, width, open, onOpenChange, translateX, mainTranslateX } = useSidebar();
11056
+ if (variant !== "push") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
11057
+ const containerPanResponder = (0, react.useMemo)(() => {
11058
+ return react_native.PanResponder.create({
11059
+ onStartShouldSetPanResponder: () => false,
11060
+ onMoveShouldSetPanResponder: (_, gestureState) => {
11061
+ if (Math.abs(gestureState.dx) <= 10 || Math.abs(gestureState.dx) <= Math.abs(gestureState.dy)) return false;
11062
+ if (!open) if (side === "left") return gestureState.dx > 10;
11063
+ else return gestureState.dx < -10;
11064
+ return true;
11065
+ },
11066
+ onPanResponderGrant: () => {},
11067
+ onPanResponderMove: (_, gestureState) => {
11068
+ if (side === "left") if (open) {
11069
+ const newTranslateX = gestureState.dx;
11070
+ const clampedValue = Math.max(-width, Math.min(0, newTranslateX));
11071
+ translateX.setValue(clampedValue);
11072
+ mainTranslateX.setValue(clampedValue + width);
11073
+ } else {
11074
+ const newTranslateX = -width + gestureState.dx;
11075
+ const clampedValue = Math.max(-width, Math.min(0, newTranslateX));
11076
+ translateX.setValue(clampedValue);
11077
+ mainTranslateX.setValue(gestureState.dx);
11078
+ }
11079
+ else if (open) {
11080
+ const newTranslateX = width + gestureState.dx;
11081
+ const clampedValue = Math.max(0, Math.min(width, newTranslateX));
11082
+ translateX.setValue(clampedValue);
11083
+ mainTranslateX.setValue(clampedValue - width);
11084
+ } else {
11085
+ const newTranslateX = width + gestureState.dx;
11086
+ const clampedValue = Math.max(0, Math.min(width, newTranslateX));
11087
+ translateX.setValue(clampedValue);
11088
+ mainTranslateX.setValue(gestureState.dx);
11089
+ }
11090
+ },
11091
+ onPanResponderRelease: (_, gestureState) => {
11092
+ const threshold = width * .25;
11093
+ const velocityThreshold = 500;
11094
+ if (side === "left") if (open) if (gestureState.dx < -threshold || gestureState.vx < -velocityThreshold / 1e3) {
11095
+ triggerHaptic("selection");
11096
+ onOpenChange(false, true);
11097
+ react_native.Animated.timing(translateX, {
11098
+ toValue: -width,
11099
+ duration: animationDuration,
11100
+ useNativeDriver: true
11101
+ }).start();
11102
+ react_native.Animated.timing(mainTranslateX, {
11103
+ toValue: 0,
11104
+ duration: animationDuration,
11105
+ useNativeDriver: true
11106
+ }).start();
11107
+ } else {
11108
+ react_native.Animated.spring(translateX, {
11109
+ toValue: 0,
11110
+ tension: 65,
11111
+ friction: 11,
11112
+ useNativeDriver: true
11113
+ }).start();
11114
+ react_native.Animated.spring(mainTranslateX, {
11115
+ toValue: width,
11116
+ tension: 65,
11117
+ friction: 11,
11118
+ useNativeDriver: true
11119
+ }).start();
11120
+ }
11121
+ else if (gestureState.dx > threshold || gestureState.vx > velocityThreshold / 1e3) {
11122
+ react_native.Animated.timing(translateX, {
11123
+ toValue: 0,
11124
+ duration: animationDuration,
11125
+ useNativeDriver: true
11126
+ }).start();
11127
+ react_native.Animated.timing(mainTranslateX, {
11128
+ toValue: width,
11129
+ duration: animationDuration,
11130
+ useNativeDriver: true
11131
+ }).start();
11132
+ onOpenChange(true, true);
11133
+ } else {
11134
+ react_native.Animated.spring(translateX, {
11135
+ toValue: -width,
11136
+ tension: 65,
11137
+ friction: 11,
11138
+ useNativeDriver: true
11139
+ }).start();
11140
+ react_native.Animated.spring(mainTranslateX, {
11141
+ toValue: 0,
11142
+ tension: 65,
11143
+ friction: 11,
11144
+ useNativeDriver: true
11145
+ }).start();
11146
+ }
11147
+ else if (open) if (gestureState.dx > threshold || gestureState.vx > velocityThreshold / 1e3) {
11148
+ triggerHaptic("selection");
11149
+ onOpenChange(false, true);
11150
+ react_native.Animated.timing(translateX, {
11151
+ toValue: width,
11152
+ duration: animationDuration,
11153
+ useNativeDriver: true
11154
+ }).start();
11155
+ react_native.Animated.timing(mainTranslateX, {
11156
+ toValue: 0,
11157
+ duration: animationDuration,
11158
+ useNativeDriver: true
11159
+ }).start();
11160
+ } else {
11161
+ react_native.Animated.spring(translateX, {
11162
+ toValue: 0,
11163
+ tension: 65,
11164
+ friction: 11,
11165
+ useNativeDriver: true
11166
+ }).start();
11167
+ react_native.Animated.spring(mainTranslateX, {
11168
+ toValue: -width,
11169
+ tension: 65,
11170
+ friction: 11,
11171
+ useNativeDriver: true
11172
+ }).start();
11173
+ }
11174
+ else if (gestureState.dx < -threshold || gestureState.vx < -velocityThreshold / 1e3) {
11175
+ react_native.Animated.timing(translateX, {
11176
+ toValue: 0,
11177
+ duration: animationDuration,
11178
+ useNativeDriver: true
11179
+ }).start();
11180
+ react_native.Animated.timing(mainTranslateX, {
11181
+ toValue: -width,
11182
+ duration: animationDuration,
11183
+ useNativeDriver: true
11184
+ }).start();
11185
+ onOpenChange(true, true);
11186
+ } else {
11187
+ react_native.Animated.spring(translateX, {
11188
+ toValue: width,
11189
+ tension: 65,
11190
+ friction: 11,
11191
+ useNativeDriver: true
11192
+ }).start();
11193
+ react_native.Animated.spring(mainTranslateX, {
11194
+ toValue: 0,
11195
+ tension: 65,
11196
+ friction: 11,
11197
+ useNativeDriver: true
11198
+ }).start();
11199
+ }
11200
+ }
11201
+ });
11202
+ }, [
11203
+ side,
11204
+ width,
11205
+ open,
11206
+ onOpenChange,
11207
+ translateX,
11208
+ mainTranslateX,
11209
+ animationDuration
11210
+ ]);
11211
+ const childArray = react.default.Children.toArray(children);
11212
+ let contentChild = null;
11213
+ let mainChild = null;
11214
+ childArray.forEach((child) => {
11215
+ if (react.default.isValidElement(child) && child.type === SidebarContent) contentChild = child;
11216
+ else if (react.default.isValidElement(child) && child.type === SidebarMain) mainChild = child;
11217
+ });
11218
+ if (side === "right" && mainChild && contentChild) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
11219
+ style: styles$14.container,
11220
+ ...containerPanResponder.panHandlers,
11221
+ children: [mainChild, contentChild]
11222
+ });
11223
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
11224
+ style: styles$14.container,
11225
+ ...containerPanResponder.panHandlers,
11226
+ children
11227
+ });
11228
+ };
11229
+ const SidebarMain = ({ children, style }) => {
11230
+ const { side, variant, width, open, mainTranslateX } = useSidebar();
11231
+ useTheme$1();
11232
+ if (variant === "push") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, {
11233
+ style: [
11234
+ styles$14.mainContent,
11235
+ {
11236
+ flex: 1,
11237
+ transform: [{ translateX: mainTranslateX }]
11238
+ },
11239
+ style
11240
+ ],
11241
+ children
11242
+ });
11243
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
11244
+ };
11245
+ const styles$14 = react_native.StyleSheet.create({
11246
+ container: {
11247
+ flexDirection: "row",
11248
+ flex: 1
11249
+ },
11250
+ overlay: {
11251
+ ...react_native.StyleSheet.absoluteFillObject,
11252
+ zIndex: 1
11253
+ },
11254
+ backdrop: {
11255
+ ...react_native.StyleSheet.absoluteFillObject,
11256
+ zIndex: 1
11257
+ },
11258
+ content: {
11259
+ position: "absolute",
11260
+ top: 0,
11261
+ bottom: 0,
11262
+ zIndex: 2,
11263
+ elevation: 4
11264
+ },
11265
+ scrollContent: { flex: 1 },
11266
+ scrollContentContainer: {
11267
+ flexGrow: 1,
11268
+ paddingBottom: 4
11269
+ },
11270
+ header: {},
11271
+ item: {},
11272
+ separator: { height: 1 },
11273
+ mainContent: {}
11274
+ });
11275
+ const Sidebar = {
11276
+ Root: SidebarRoot,
11277
+ Trigger: SidebarTrigger,
11278
+ Portal: SidebarPortal,
11279
+ Overlay: SidebarOverlay,
11280
+ Content: SidebarContent,
11281
+ Header: SidebarHeader,
11282
+ Item: SidebarItem,
11283
+ Separator: SidebarSeparator,
11284
+ Main: SidebarMain,
11285
+ Backdrop: SidebarBackdrop,
11286
+ Container: SidebarContainer
11287
+ };
11288
+
11289
+ //#endregion
11290
+ //#region src/components/data-display/Avatar.tsx
11291
+ const Avatar = react.default.forwardRef(({ src, alt = "Avatar", color, variant = "solid", highContrast, radius, size = 2, fallback, fallbackBehavior = "character", style, accessibilityLabel, children }, ref) => {
11292
+ const theme = useTheme$1();
11293
+ const mode = useThemeMode$1();
11294
+ const isDark = mode === "dark";
11295
+ const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
11296
+ const grayAlpha = getGrayAlpha(theme);
11297
+ const activeColor = color || theme.accentColor;
11298
+ const radii = theme.radii[radius] ?? theme.radii.medium;
11299
+ const selectedRadius = radius || theme.radius;
11300
+ const [imageError, setImageError] = (0, react.useState)(false);
11301
+ const variantColors = (0, react.useMemo)(() => getVariantColors(theme, activeColor, mode, variant, highContrast), [
11302
+ getVariantColors,
11303
+ color,
11304
+ variant,
11305
+ highContrast,
11306
+ isDark,
11307
+ theme
11308
+ ]);
11309
+ const getSizeValues = () => {
11310
+ switch (size) {
11311
+ case 1: return {
11312
+ size: 24,
11313
+ fontSize: 10,
11314
+ borderWidth: 0,
11315
+ borderRadius: selectedRadius === "full" ? 9999 : radii
11316
+ };
11317
+ case 2: return {
11318
+ size: 32,
11319
+ fontSize: 12,
11320
+ borderWidth: 0,
11321
+ borderRadius: selectedRadius === "full" ? 9999 : radii
11322
+ };
11323
+ case 3: return {
11324
+ size: 48,
11325
+ fontSize: 18,
11326
+ borderWidth: 0,
11327
+ borderRadius: selectedRadius === "full" ? 9999 : radii
11328
+ };
11329
+ case 4: return {
11330
+ size: 64,
11331
+ fontSize: 24,
11332
+ borderWidth: 0,
11333
+ borderRadius: selectedRadius === "full" ? 9999 : radii
11334
+ };
10602
11335
  case 5: return {
10603
11336
  size: 80,
10604
11337
  fontSize: 32,
@@ -10648,10 +11381,10 @@ const Avatar = react.default.forwardRef(({ src, alt = "Avatar", color, variant =
10648
11381
  if (!trimmed) return null;
10649
11382
  return trimmed.split(/\s+/).map((word) => word[0]).join("").slice(0, 2).toUpperCase() || null;
10650
11383
  })();
10651
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(View_default, {
11384
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
10652
11385
  ref,
10653
11386
  style: [
10654
- styles$12.avatar,
11387
+ styles$13.avatar,
10655
11388
  {
10656
11389
  width: sizeValues.size,
10657
11390
  height: sizeValues.size,
@@ -10676,8 +11409,8 @@ const Avatar = react.default.forwardRef(({ src, alt = "Avatar", color, variant =
10676
11409
  onError: () => setImageError(true),
10677
11410
  accessibilityLabel: alt,
10678
11411
  testID: "avatar-image"
10679
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(View_default, {
10680
- style: [styles$12.fallback, {
11412
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11413
+ style: [styles$13.fallback, {
10681
11414
  backgroundColor: variantColors.backgroundColor,
10682
11415
  flex: 1,
10683
11416
  width: "100%",
@@ -10701,7 +11434,7 @@ const AvatarFallback = ({ children }) => {
10701
11434
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
10702
11435
  };
10703
11436
  Avatar.Fallback = AvatarFallback;
10704
- const styles$12 = react_native.StyleSheet.create({
11437
+ const styles$13 = react_native.StyleSheet.create({
10705
11438
  avatar: {
10706
11439
  alignItems: "center",
10707
11440
  justifyContent: "center"
@@ -10769,7 +11502,7 @@ const Badge = react.default.forwardRef(({ children, variant = "soft", color, rad
10769
11502
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
10770
11503
  ref,
10771
11504
  style: [
10772
- styles$11.badge,
11505
+ styles$12.badge,
10773
11506
  badgeStyle,
10774
11507
  style
10775
11508
  ],
@@ -10777,13 +11510,13 @@ const Badge = react.default.forwardRef(({ children, variant = "soft", color, rad
10777
11510
  accessibilityRole: "none",
10778
11511
  ...rest,
10779
11512
  children: typeof children === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
10780
- style: [styles$11.text, textStyle],
11513
+ style: [styles$12.text, textStyle],
10781
11514
  children
10782
11515
  }) : children
10783
11516
  });
10784
11517
  });
10785
11518
  Badge.displayName = "Badge";
10786
- const styles$11 = react_native.StyleSheet.create({
11519
+ const styles$12 = react_native.StyleSheet.create({
10787
11520
  badge: {
10788
11521
  flexDirection: "row",
10789
11522
  alignItems: "center"
@@ -11019,14 +11752,14 @@ const Card = react.default.forwardRef(({ asChild = false, children, color, radiu
11019
11752
  style,
11020
11753
  ...rest,
11021
11754
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11022
- style: [styles$10.card, cardStyle],
11755
+ style: [styles$11.card, cardStyle],
11023
11756
  children
11024
11757
  })
11025
11758
  });
11026
11759
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11027
11760
  ref,
11028
11761
  style: [
11029
- styles$10.card,
11762
+ styles$11.card,
11030
11763
  cardStyle,
11031
11764
  style
11032
11765
  ],
@@ -11040,7 +11773,7 @@ const CardFooter = ({ children, separate = true }) => {
11040
11773
  useThemeMode$1();
11041
11774
  const grayAlpha = getGrayAlpha(theme);
11042
11775
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11043
- style: [styles$10.footer, separate && {
11776
+ style: [styles$11.footer, separate && {
11044
11777
  borderTopWidth: 1,
11045
11778
  borderTopColor: grayAlpha["6"],
11046
11779
  marginTop: theme.space[4],
@@ -11050,7 +11783,7 @@ const CardFooter = ({ children, separate = true }) => {
11050
11783
  });
11051
11784
  };
11052
11785
  Card.Footer = CardFooter;
11053
- const styles$10 = react_native.StyleSheet.create({
11786
+ const styles$11 = react_native.StyleSheet.create({
11054
11787
  card: { overflow: "hidden" },
11055
11788
  footer: {
11056
11789
  flexDirection: "row",
@@ -11097,7 +11830,7 @@ const DataListRoot = ({ children, orientation = "horizontal", size = 2, trim = "
11097
11830
  },
11098
11831
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
11099
11832
  style: [
11100
- styles$9.root,
11833
+ styles$10.root,
11101
11834
  rootStyle,
11102
11835
  trimStyles,
11103
11836
  style
@@ -11121,7 +11854,7 @@ const DataListItem = ({ children, align = "baseline", style }) => {
11121
11854
  };
11122
11855
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
11123
11856
  style: [
11124
- styles$9.item,
11857
+ styles$10.item,
11125
11858
  itemStyle,
11126
11859
  style
11127
11860
  ],
@@ -11191,7 +11924,7 @@ const DataListValue = ({ children, style }) => {
11191
11924
  });
11192
11925
  };
11193
11926
  DataListValue.displayName = "DataList.Value";
11194
- const styles$9 = react_native.StyleSheet.create({
11927
+ const styles$10 = react_native.StyleSheet.create({
11195
11928
  root: { width: "100%" },
11196
11929
  item: { width: "100%" }
11197
11930
  });
@@ -11223,7 +11956,7 @@ const FancyList = ({ data, renderItem, keyExtractor, style, showDividers = true,
11223
11956
  borderBottomColor: dividerColor
11224
11957
  };
11225
11958
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11226
- style: [styles$8.item, itemStyle],
11959
+ style: [styles$9.item, itemStyle],
11227
11960
  children: renderItem({
11228
11961
  item: info.item,
11229
11962
  index: info.index,
@@ -11238,14 +11971,14 @@ const FancyList = ({ data, renderItem, keyExtractor, style, showDividers = true,
11238
11971
  };
11239
11972
  if (!scrollable) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
11240
11973
  style: [
11241
- styles$8.container,
11974
+ styles$9.container,
11242
11975
  listContainerStyle,
11243
11976
  style
11244
11977
  ],
11245
11978
  children: [
11246
11979
  ListHeaderComponent,
11247
11980
  data.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11248
- style: styles$8.nonScrollableItem,
11981
+ style: styles$9.nonScrollableItem,
11249
11982
  children: renderItem({
11250
11983
  item,
11251
11984
  index,
@@ -11256,28 +11989,28 @@ const FancyList = ({ data, renderItem, keyExtractor, style, showDividers = true,
11256
11989
  ]
11257
11990
  });
11258
11991
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11259
- style: [styles$8.container, style],
11992
+ style: [styles$9.container, style],
11260
11993
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnFlatList, {
11261
11994
  data,
11262
11995
  renderItem: renderListItem,
11263
11996
  keyExtractor: defaultKeyExtractor,
11264
- style: [styles$8.flatList, listContainerStyle],
11265
- contentContainerStyle: styles$8.contentContainer,
11997
+ style: [styles$9.flatList, listContainerStyle],
11998
+ contentContainerStyle: styles$9.contentContainer,
11266
11999
  showsVerticalScrollIndicator: true,
11267
12000
  ListEmptyComponent,
11268
12001
  ListHeaderComponent,
11269
12002
  ListFooterComponent,
11270
- ItemSeparatorComponent: () => showDividers ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$8.divider, {
12003
+ ItemSeparatorComponent: () => showDividers ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, { style: [styles$9.divider, {
11271
12004
  backgroundColor: dividerColor,
11272
12005
  marginHorizontal: theme.space[4]
11273
12006
  }] }) : null,
11274
- ListHeaderComponentStyle: styles$8.listHeaderFooter,
11275
- ListFooterComponentStyle: styles$8.listHeaderFooter
12007
+ ListHeaderComponentStyle: styles$9.listHeaderFooter,
12008
+ ListFooterComponentStyle: styles$9.listHeaderFooter
11276
12009
  })
11277
12010
  });
11278
12011
  };
11279
12012
  FancyList.displayName = "FancyList";
11280
- const styles$8 = react_native.StyleSheet.create({
12013
+ const styles$9 = react_native.StyleSheet.create({
11281
12014
  container: { width: "100%" },
11282
12015
  flatList: { flex: 1 },
11283
12016
  contentContainer: { flexGrow: 1 },
@@ -11381,7 +12114,7 @@ const Progress = (0, react.forwardRef)(({ value, max = 100, size = 2, variant =
11381
12114
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11382
12115
  ref,
11383
12116
  style: [
11384
- styles$7.track,
12117
+ styles$8.track,
11385
12118
  {
11386
12119
  backgroundColor: trackBackgroundColor,
11387
12120
  borderColor: trackBorder.borderColor,
@@ -11400,7 +12133,7 @@ const Progress = (0, react.forwardRef)(({ value, max = 100, size = 2, variant =
11400
12133
  },
11401
12134
  accessibilityRole: "progressbar",
11402
12135
  testID,
11403
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: [styles$7.indicator, {
12136
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, { style: [styles$8.indicator, {
11404
12137
  width: animatedWidth,
11405
12138
  backgroundColor: indicatorColor,
11406
12139
  borderRadius: selectedRadius
@@ -11408,7 +12141,7 @@ const Progress = (0, react.forwardRef)(({ value, max = 100, size = 2, variant =
11408
12141
  });
11409
12142
  });
11410
12143
  Progress.displayName = "Progress";
11411
- const styles$7 = react_native.StyleSheet.create({
12144
+ const styles$8 = react_native.StyleSheet.create({
11412
12145
  track: {
11413
12146
  width: "100%",
11414
12147
  overflow: "hidden"
@@ -11441,7 +12174,7 @@ const Spinner = react.default.forwardRef(({ size = "medium", color, highContrast
11441
12174
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11442
12175
  ref,
11443
12176
  style: [
11444
- styles$6.container,
12177
+ styles$7.container,
11445
12178
  {
11446
12179
  width: sizeConfig.dimension,
11447
12180
  height: sizeConfig.dimension
@@ -11458,148 +12191,312 @@ const Spinner = react.default.forwardRef(({ size = "medium", color, highContrast
11458
12191
  });
11459
12192
  });
11460
12193
  Spinner.displayName = "Spinner";
11461
- const styles$6 = react_native.StyleSheet.create({ container: {
12194
+ const styles$7 = react_native.StyleSheet.create({ container: {
11462
12195
  justifyContent: "center",
11463
12196
  alignItems: "center"
11464
12197
  } });
11465
12198
 
12199
+ //#endregion
12200
+ //#region src/components/data-display/Skeleton.tsx
12201
+ const PULSE_ANIMATION = {
12202
+ duration: 1e3,
12203
+ useNativeDriver: true
12204
+ };
12205
+ const SKELEON_COLORS = {
12206
+ light: "#E5E7EB",
12207
+ dark: "#D1D5DB"
12208
+ };
12209
+ const Skeleton = react.default.forwardRef(({ children, loading = true, style, textStyle, width, height, accessibilityLabel = "Loading", testID }, ref) => {
12210
+ const pulseAnim = (0, react.useRef)(new react_native.Animated.Value(0)).current;
12211
+ (0, react.useEffect)(() => {
12212
+ const animation = react_native.Animated.loop(react_native.Animated.sequence([react_native.Animated.timing(pulseAnim, {
12213
+ toValue: 1,
12214
+ ...PULSE_ANIMATION
12215
+ }), react_native.Animated.timing(pulseAnim, {
12216
+ toValue: 0,
12217
+ ...PULSE_ANIMATION
12218
+ })]));
12219
+ animation.start();
12220
+ return () => {
12221
+ animation.stop();
12222
+ };
12223
+ }, [pulseAnim]);
12224
+ const pulseStyle = { backgroundColor: pulseAnim.interpolate({
12225
+ inputRange: [0, 1],
12226
+ outputRange: [SKELEON_COLORS.light, SKELEON_COLORS.dark]
12227
+ }) };
12228
+ if (!loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
12229
+ if (!react.default.isValidElement(children) && typeof children === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.Text, {
12230
+ ref,
12231
+ style: [
12232
+ textStyle,
12233
+ pulseStyle,
12234
+ width !== void 0 ? { width } : void 0,
12235
+ height !== void 0 ? { height } : void 0
12236
+ ],
12237
+ accessibilityLabel,
12238
+ accessibilityRole: "progressbar",
12239
+ testID,
12240
+ children
12241
+ });
12242
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Animated.View, {
12243
+ ref,
12244
+ style: [
12245
+ styles$6.blockContainer,
12246
+ pulseStyle,
12247
+ width !== void 0 ? { width } : void 0,
12248
+ height !== void 0 ? { height } : void 0,
12249
+ style
12250
+ ],
12251
+ accessibilityLabel,
12252
+ accessibilityRole: "progressbar",
12253
+ testID,
12254
+ children: children && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12255
+ style: styles$6.hiddenChildren,
12256
+ pointerEvents: "none",
12257
+ children
12258
+ })
12259
+ });
12260
+ });
12261
+ Skeleton.displayName = "Skeleton";
12262
+ const styles$6 = react_native.StyleSheet.create({
12263
+ inlineText: {
12264
+ color: "transparent",
12265
+ fontSize: 14,
12266
+ lineHeight: 20,
12267
+ overflow: "hidden"
12268
+ },
12269
+ blockContainer: {
12270
+ minHeight: 20,
12271
+ overflow: "hidden"
12272
+ },
12273
+ hiddenChildren: { opacity: 0 }
12274
+ });
12275
+
11466
12276
  //#endregion
11467
12277
  //#region src/components/data-display/Table.tsx
11468
- const Table = ({ columns, data, style, scrollable = true }) => {
12278
+ const TableContext = (0, react.createContext)(null);
12279
+ const useTableContext = () => {
12280
+ const context = (0, react.useContext)(TableContext);
12281
+ if (!context) throw new Error("Table sub-components must be used within Table.Root");
12282
+ return context;
12283
+ };
12284
+ const TableRoot = react.default.forwardRef(({ children, size = "2", scrollable = true, style }, ref) => {
11469
12285
  const theme = useTheme$1();
11470
- useThemeMode$1() === "dark" ? theme.colors.gray.dark : theme.colors.gray;
11471
- getGrayAlpha(theme);
12286
+ const mode = useThemeMode$1();
12287
+ const isDark = mode === "dark";
12288
+ const grayAlpha = getGrayAlpha(theme, mode);
11472
12289
  const tableStyle = {
11473
12290
  borderRadius: theme.radii.medium,
11474
- overflow: "hidden"
12291
+ overflow: "hidden",
12292
+ backgroundColor: isDark ? grayAlpha["2"] : grayAlpha["1"]
12293
+ };
12294
+ const contextValue = {
12295
+ size,
12296
+ isRoot: true
11475
12297
  };
11476
- const TableContent = () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RnView, {
11477
- style: [styles$5.table, tableStyle],
11478
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Thead, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tr, {
11479
- isHeader: true,
11480
- children: columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Th, {
11481
- width: column.width,
11482
- align: column.align,
11483
- children: column.title
11484
- }, column.key))
11485
- }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tbody, { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tr, { children: columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Td, {
11486
- align: column.align,
11487
- children: column.render ? column.render(row, rowIndex) : String(row[column.key] ?? "")
11488
- }, column.key)) }, rowIndex)) })]
11489
- });
11490
- if (scrollable) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnScrollView, {
12298
+ const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableContext.Provider, {
12299
+ value: contextValue,
12300
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12301
+ ref,
12302
+ style: [
12303
+ styles$5.root,
12304
+ tableStyle,
12305
+ style
12306
+ ],
12307
+ children
12308
+ })
12309
+ });
12310
+ if (scrollable) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
11491
12311
  horizontal: true,
11492
- style: [styles$5.scrollContainer, style],
11493
12312
  showsHorizontalScrollIndicator: false,
11494
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableContent, {})
11495
- });
11496
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11497
- style: [styles$5.container, style],
11498
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableContent, {})
12313
+ contentContainerStyle: styles$5.scrollContent,
12314
+ children: content
11499
12315
  });
11500
- };
11501
- Table.displayName = "Table";
11502
- const Thead = ({ children }) => {
11503
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11504
- style: styles$5.thead,
12316
+ return content;
12317
+ });
12318
+ TableRoot.displayName = "Table.Root";
12319
+ const TableHeader = react.default.forwardRef(({ children, style }, ref) => {
12320
+ const theme = useTheme$1();
12321
+ const mode = useThemeMode$1();
12322
+ const isDark = mode === "dark";
12323
+ const grayAlpha = getGrayAlpha(theme, mode);
12324
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12325
+ ref,
12326
+ style: [
12327
+ styles$5.header,
12328
+ {
12329
+ backgroundColor: isDark ? grayAlpha["3"] : grayAlpha["2"],
12330
+ borderBottomWidth: 0,
12331
+ borderBottomColor: isDark ? grayAlpha["6"] : grayAlpha["5"]
12332
+ },
12333
+ style
12334
+ ],
11505
12335
  children
11506
12336
  });
11507
- };
11508
- const Tbody = ({ children }) => {
11509
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11510
- style: styles$5.tbody,
12337
+ });
12338
+ TableHeader.displayName = "Table.Header";
12339
+ const TableBody = react.default.forwardRef(({ children, style }, ref) => {
12340
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12341
+ ref,
12342
+ style: [styles$5.body, style],
11511
12343
  children
11512
12344
  });
11513
- };
11514
- const Tr = ({ children, isHeader = false }) => {
12345
+ });
12346
+ TableBody.displayName = "Table.Body";
12347
+ const TableRow = react.default.forwardRef(({ children, style }, ref) => {
11515
12348
  const theme = useTheme$1();
11516
- const isDark = useThemeMode$1() === "dark";
11517
- isDark ? theme.colors.gray.dark : theme.colors.gray;
11518
- const grayAlpha = getGrayAlpha(theme);
11519
- const headerBackground = isDark ? grayAlpha["3"] : grayAlpha["2"];
11520
- const borderColor = isDark ? grayAlpha["6"] : grayAlpha["5"];
11521
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
12349
+ const mode = useThemeMode$1();
12350
+ const isDark = mode === "dark";
12351
+ const grayAlpha = getGrayAlpha(theme, mode);
12352
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12353
+ ref,
11522
12354
  style: [
11523
- styles$5.tr,
11524
- isHeader && {
11525
- backgroundColor: headerBackground,
12355
+ styles$5.row,
12356
+ {
12357
+ flex: 1,
11526
12358
  borderBottomWidth: 1,
11527
- borderBottomColor: borderColor
12359
+ borderBottomColor: isDark ? grayAlpha["6"] : grayAlpha["5"]
11528
12360
  },
11529
- !isHeader && {
11530
- borderBottomWidth: 1,
11531
- borderBottomColor: borderColor
11532
- }
12361
+ style
11533
12362
  ],
11534
12363
  children
11535
12364
  });
11536
- };
11537
- const Th = ({ children, width, align = "left" }) => {
12365
+ });
12366
+ TableRow.displayName = "Table.Row";
12367
+ const TableColumnHeaderCell = react.default.forwardRef(({ children, width, align = "left", style }, ref) => {
12368
+ const context = useTableContext();
11538
12369
  const theme = useTheme$1();
11539
12370
  const grayScale = useThemeMode$1() === "dark" ? theme.colors.gray.dark : theme.colors.gray;
11540
- const thStyle = { width };
11541
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
12371
+ const getSizePadding = () => {
12372
+ switch (context.size) {
12373
+ case "1": return {
12374
+ paddingVertical: theme.space[2],
12375
+ paddingHorizontal: theme.space[3]
12376
+ };
12377
+ case "3": return {
12378
+ paddingVertical: theme.space[4],
12379
+ paddingHorizontal: theme.space[5]
12380
+ };
12381
+ default: return {
12382
+ paddingVertical: theme.space[3],
12383
+ paddingHorizontal: theme.space[4]
12384
+ };
12385
+ }
12386
+ };
12387
+ const getSizeFont = () => {
12388
+ switch (context.size) {
12389
+ case "1": return { fontSize: theme.typography.fontSizes[1].fontSize };
12390
+ case "3": return { fontSize: theme.typography.fontSizes[3].fontSize };
12391
+ default: return { fontSize: theme.typography.fontSizes[2].fontSize };
12392
+ }
12393
+ };
12394
+ const padding = getSizePadding();
12395
+ const fontSize = getSizeFont();
12396
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12397
+ ref,
11542
12398
  style: [
11543
- styles$5.th,
11544
- thStyle,
11545
- justifyContentMap[align]
12399
+ styles$5.cell,
12400
+ {
12401
+ width,
12402
+ alignItems: {
12403
+ left: "flex-start",
12404
+ center: "center",
12405
+ right: "flex-end"
12406
+ }[align],
12407
+ ...padding
12408
+ },
12409
+ style
11546
12410
  ],
11547
12411
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
11548
12412
  style: {
11549
12413
  color: grayScale[12],
11550
12414
  fontWeight: "600",
11551
- fontSize: theme.typography.fontSizes[1].fontSize
12415
+ ...fontSize
11552
12416
  },
11553
12417
  children
11554
12418
  })
11555
12419
  });
11556
- };
11557
- const Td = ({ children, align = "left" }) => {
12420
+ });
12421
+ TableColumnHeaderCell.displayName = "Table.ColumnHeaderCell";
12422
+ const TableCell = react.default.forwardRef(({ children, align = "left", style }, ref) => {
12423
+ const context = useTableContext();
11558
12424
  const theme = useTheme$1();
11559
12425
  const grayScale = useThemeMode$1() === "dark" ? theme.colors.gray.dark : theme.colors.gray;
11560
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RnView, {
11561
- style: [styles$5.td, justifyContentMap[align]],
12426
+ const getSizePadding = () => {
12427
+ switch (context.size) {
12428
+ case "1": return {
12429
+ paddingVertical: theme.space[2],
12430
+ paddingHorizontal: theme.space[3]
12431
+ };
12432
+ case "3": return {
12433
+ paddingVertical: theme.space[4],
12434
+ paddingHorizontal: theme.space[5]
12435
+ };
12436
+ default: return {
12437
+ paddingVertical: theme.space[3],
12438
+ paddingHorizontal: theme.space[4]
12439
+ };
12440
+ }
12441
+ };
12442
+ const getSizeFont = () => {
12443
+ switch (context.size) {
12444
+ case "1": return { fontSize: theme.typography.fontSizes[1].fontSize };
12445
+ case "3": return { fontSize: theme.typography.fontSizes[3].fontSize };
12446
+ default: return { fontSize: theme.typography.fontSizes[2].fontSize };
12447
+ }
12448
+ };
12449
+ const padding = getSizePadding();
12450
+ const fontSize = getSizeFont();
12451
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
12452
+ ref,
12453
+ style: [
12454
+ styles$5.cell,
12455
+ {
12456
+ alignItems: {
12457
+ left: "flex-start",
12458
+ center: "center",
12459
+ right: "flex-end"
12460
+ }[align],
12461
+ ...padding
12462
+ },
12463
+ style
12464
+ ],
11562
12465
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
11563
12466
  style: {
11564
12467
  color: grayScale[11],
11565
- fontSize: theme.typography.fontSizes[1].fontSize
12468
+ ...fontSize
11566
12469
  },
11567
12470
  children
11568
12471
  })
11569
12472
  });
11570
- };
11571
- const justifyContentMap = {
11572
- left: { justifyContent: "flex-start" },
11573
- center: { justifyContent: "center" },
11574
- right: { justifyContent: "flex-end" }
11575
- };
11576
- Table.Thead = Thead;
11577
- Table.Tbody = Tbody;
11578
- Table.Tr = Tr;
11579
- Table.Th = Th;
11580
- Table.Td = Td;
12473
+ });
12474
+ TableCell.displayName = "Table.Cell";
11581
12475
  const styles$5 = react_native.StyleSheet.create({
11582
- container: { width: "100%" },
11583
- scrollContainer: { flex: 1 },
11584
- table: { minWidth: "100%" },
11585
- thead: { flexDirection: "row" },
11586
- tbody: { flexDirection: "column" },
11587
- tr: {
12476
+ scrollContent: { flexGrow: 1 },
12477
+ root: { minWidth: "100%" },
12478
+ header: {
11588
12479
  flexDirection: "row",
11589
- minHeight: 44,
11590
- alignItems: "center",
11591
- borderBottomWidth: 1,
11592
- borderBottomColor: "transparent"
11593
- },
11594
- th: {
11595
- padding: 12,
11596
12480
  minHeight: 44
11597
12481
  },
11598
- td: {
11599
- padding: 12,
12482
+ body: { flexDirection: "column" },
12483
+ row: {
12484
+ flexDirection: "row",
11600
12485
  minHeight: 44
12486
+ },
12487
+ cell: {
12488
+ flex: 1,
12489
+ minWidth: 80
11601
12490
  }
11602
12491
  });
12492
+ const Table = {
12493
+ Root: TableRoot,
12494
+ Header: TableHeader,
12495
+ Body: TableBody,
12496
+ Row: TableRow,
12497
+ ColumnHeaderCell: TableColumnHeaderCell,
12498
+ Cell: TableCell
12499
+ };
11603
12500
 
11604
12501
  //#endregion
11605
12502
  //#region src/components/navigation/SegmentedControl.tsx
@@ -11609,19 +12506,57 @@ function useSegmentedControlContext() {
11609
12506
  if (!context) throw new Error("SegmentedControl.Item must be used within SegmentedControl.Root");
11610
12507
  return context;
11611
12508
  }
12509
+ const SegmentedControlValue = ({ children }) => {
12510
+ const { value: selectedValue, color, isDark, grayScale, activeColor, solidVariantColors, softVariantColors, sizeValues, theme, itemValue, isItemSelected, itemDisabled } = useSegmentedControlContext();
12511
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
12512
+ style: {
12513
+ color: itemDisabled ? grayScale["9"] : color ? isItemSelected ? solidVariantColors.textColor : softVariantColors.textColor : isItemSelected ? grayScale[12] : grayScale[10],
12514
+ fontWeight: isItemSelected ? theme.typography.fontWeights.semibold : theme.typography.fontWeights.regular,
12515
+ fontSize: sizeValues.fontSize
12516
+ },
12517
+ children
12518
+ });
12519
+ };
12520
+ SegmentedControlValue.displayName = "SegmentedControlValue";
12521
+ const SegmentedControlIcon = ({ children }) => {
12522
+ const { color, isDark, grayScale, activeColor, solidVariantColors, softVariantColors, sizeValues, itemValue, isItemSelected, itemDisabled } = useSegmentedControlContext();
12523
+ const iconColor = itemDisabled ? grayScale["9"] : color ? isItemSelected ? solidVariantColors.textColor : softVariantColors.textColor : isItemSelected ? grayScale[12] : grayScale[10];
12524
+ const iconSize = sizeValues.fontSize;
12525
+ return react.default.cloneElement(children, {
12526
+ ...children.props,
12527
+ color: iconColor,
12528
+ size: children.props.size ?? iconSize
12529
+ });
12530
+ };
12531
+ SegmentedControlIcon.displayName = "SegmentedControlIcon";
12532
+ const SegmentedControlItemContext = (0, react.createContext)(null);
11612
12533
  const SegmentedControlItem = ({ value, disabled: itemDisabled, children }) => {
11613
- const { value: selectedValue, onValueChange, disabled, sizeValues, isDark, grayScale, grayAlpha, activeColor, radii, selectedRadius, softVariantColors, solidVariantColors, color, onItemLayout, theme, pillBackgroundColor, hapticFeedback } = useSegmentedControlContext();
12534
+ const { value: selectedValue, onValueChange, disabled, sizeValues, isDark, grayScale, grayAlpha, activeColor, radii, selectedRadius, softVariantColors, solidVariantColors, color, onItemLayout, theme, pillBackgroundColor, hapticFeedback, globalHaptics } = useSegmentedControlContext();
11614
12535
  const isSelected = value === selectedValue;
11615
12536
  const isDisabled = disabled || itemDisabled;
12537
+ const hasValueChild = (0, react.isValidElement)(children) && children.type?.displayName === "SegmentedControlValue";
12538
+ const hasIconChild = (0, react.isValidElement)(children) && children.type?.displayName === "SegmentedControlIcon";
12539
+ const itemContextValue = {
12540
+ itemValue: value,
12541
+ isSelected,
12542
+ isDisabled
12543
+ };
12544
+ const mergedContext = {
12545
+ ...useSegmentedControlContext(),
12546
+ itemValue: value,
12547
+ isItemSelected: isSelected,
12548
+ itemDisabled: isDisabled
12549
+ };
11616
12550
  const handlePress = (0, react.useCallback)(() => {
11617
12551
  if (!isDisabled) {
11618
12552
  onValueChange(value);
11619
- if (hapticFeedback) react_native.Vibration.vibrate(10);
12553
+ if (globalHaptics && hapticFeedback) triggerHaptic("press");
11620
12554
  }
11621
12555
  }, [
11622
12556
  isDisabled,
11623
12557
  onValueChange,
11624
12558
  value,
12559
+ globalHaptics,
11625
12560
  hapticFeedback
11626
12561
  ]);
11627
12562
  const handleLayout = (0, react.useCallback)((event) => {
@@ -11641,23 +12576,29 @@ const SegmentedControlItem = ({ value, disabled: itemDisabled, children }) => {
11641
12576
  fontWeight: isSelected ? theme.typography.fontWeights.semibold : theme.typography.fontWeights.regular,
11642
12577
  fontSize: sizeValues.fontSize
11643
12578
  };
11644
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable_default, {
11645
- style: optionStyle,
11646
- onPress: handlePress,
11647
- onLayout: handleLayout,
11648
- disabled: isDisabled,
11649
- accessibilityRole: "radio",
11650
- accessibilityState: {
11651
- checked: isSelected,
11652
- disabled: isDisabled
11653
- },
11654
- pressedScale: .975,
11655
- pressedOpacity: .9,
11656
- animationDuration: 100,
11657
- hapticFeedback: false,
11658
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
11659
- style: textStyle,
11660
- children
12579
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SegmentedControlItemContext.Provider, {
12580
+ value: itemContextValue,
12581
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SegmentedControlContext.Provider, {
12582
+ value: mergedContext,
12583
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnimatedPressable, {
12584
+ style: optionStyle,
12585
+ onPress: handlePress,
12586
+ onLayout: handleLayout,
12587
+ disabled: isDisabled,
12588
+ accessibilityRole: "radio",
12589
+ accessibilityState: {
12590
+ checked: isSelected,
12591
+ disabled: isDisabled
12592
+ },
12593
+ pressedScale: .975,
12594
+ pressedOpacity: .9,
12595
+ animationDuration: 100,
12596
+ hapticFeedback: false,
12597
+ children: hasValueChild || hasIconChild ? children : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextComponent, {
12598
+ style: textStyle,
12599
+ children
12600
+ })
12601
+ })
11661
12602
  })
11662
12603
  });
11663
12604
  };
@@ -11665,6 +12606,7 @@ SegmentedControlItem.displayName = "SegmentedControlItem";
11665
12606
  const SegmentedControlRoot = ({ defaultValue, value: controlledValue, onValueChange, disabled = false, color, radius, size = 3, style, highContrast = false, children, hapticFeedback = true }) => {
11666
12607
  const theme = useTheme$1();
11667
12608
  const mode = useThemeMode$1();
12609
+ const globalHaptics = useHaptics$1();
11668
12610
  const isDark = mode === "dark";
11669
12611
  const grayScale = isDark ? theme.colors.gray.dark : theme.colors.gray;
11670
12612
  const grayAlpha = getGrayAlpha(theme);
@@ -11761,7 +12703,11 @@ const SegmentedControlRoot = ({ defaultValue, value: controlledValue, onValueCha
11761
12703
  onItemLayout: handleItemLayout,
11762
12704
  theme,
11763
12705
  pillBackgroundColor,
11764
- hapticFeedback
12706
+ hapticFeedback,
12707
+ globalHaptics,
12708
+ itemValue: null,
12709
+ isItemSelected: false,
12710
+ itemDisabled: false
11765
12711
  };
11766
12712
  const pillWidth = itemLayouts[currentValue]?.width || 0;
11767
12713
  const pillInnerRadius = selectedRadius === "full" ? 9999 : radii;
@@ -11790,7 +12736,9 @@ const SegmentedControlRoot = ({ defaultValue, value: controlledValue, onValueCha
11790
12736
  SegmentedControlRoot.displayName = "SegmentedControlRoot";
11791
12737
  const SegmentedControl = {
11792
12738
  Item: SegmentedControlItem,
11793
- Root: SegmentedControlRoot
12739
+ Root: SegmentedControlRoot,
12740
+ Value: SegmentedControlValue,
12741
+ Icon: SegmentedControlIcon
11794
12742
  };
11795
12743
  const styles$4 = react_native.StyleSheet.create({
11796
12744
  container: {
@@ -12149,6 +13097,7 @@ const AccordionTrigger = react.default.forwardRef(({ children, style, icon, hapt
12149
13097
  const itemContext = useAccordionItemContext();
12150
13098
  const theme = useTheme$1();
12151
13099
  const mode = useThemeMode$1();
13100
+ const globalHaptics = useHaptics$1();
12152
13101
  const { value, open, disabled } = itemContext;
12153
13102
  const { size, dir, collapsible, type, onValueChange } = accordionContext;
12154
13103
  const grayAlpha = getGrayAlpha(theme, mode);
@@ -12196,7 +13145,7 @@ const AccordionTrigger = react.default.forwardRef(({ children, style, icon, hapt
12196
13145
  if (open) onValueChange(currentValue.filter((v) => v !== value));
12197
13146
  else onValueChange([...currentValue, value]);
12198
13147
  }
12199
- if (hapticFeedback) react_native.Vibration.vibrate(10);
13148
+ if (globalHaptics && hapticFeedback) triggerHaptic("selection");
12200
13149
  };
12201
13150
  const rtlRotationInterpolate = rotationAnim.interpolate({
12202
13151
  inputRange: [0, 1],
@@ -12216,7 +13165,7 @@ const AccordionTrigger = react.default.forwardRef(({ children, style, icon, hapt
12216
13165
  const getIconColor = () => {
12217
13166
  return grayAlpha["11"];
12218
13167
  };
12219
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable_default, {
13168
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AnimatedPressable, {
12220
13169
  ref,
12221
13170
  style: [triggerStyle, style],
12222
13171
  onPress: handlePress,
@@ -12254,7 +13203,7 @@ const AccordionTrigger = react.default.forwardRef(({ children, style, icon, hapt
12254
13203
  transform: [{ rotate: rtlRotationInterpolate }],
12255
13204
  marginLeft: theme.space[2]
12256
13205
  },
12257
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon$1, {
13206
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, {
12258
13207
  width: sizeStyles.iconSize,
12259
13208
  height: sizeStyles.iconSize,
12260
13209
  color: getIconColor()
@@ -12486,6 +13435,8 @@ exports.SelectSeparator = SelectSeparator;
12486
13435
  exports.SelectTrigger = SelectTrigger;
12487
13436
  exports.SelectValue = SelectValue;
12488
13437
  exports.Separator = Separator;
13438
+ exports.Sidebar = Sidebar;
13439
+ exports.Skeleton = Skeleton;
12489
13440
  exports.Slider = Slider;
12490
13441
  exports.Slot = Slot;
12491
13442
  exports.Spacer = Spacer;
@@ -12612,6 +13563,7 @@ exports.tomatoAlpha = tomatoAlpha;
12612
13563
  exports.typography = typography;
12613
13564
  exports.useAnchorPosition = useAnchorPosition;
12614
13565
  exports.useDeviceColorScheme = useDeviceColorScheme;
13566
+ exports.useHaptics = useHaptics;
12615
13567
  exports.usePortal = usePortal;
12616
13568
  exports.useResponsive = useResponsive;
12617
13569
  exports.useTheme = useTheme;