@retray-dev/ui-kit 1.0.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,8 +2,11 @@
2
2
 
3
3
  var React23 = require('react');
4
4
  var reactNative = require('react-native');
5
- var Haptics10 = require('expo-haptics');
5
+ var Haptics11 = require('expo-haptics');
6
+ var expoLinearGradient = require('expo-linear-gradient');
7
+ var ReanimatedAnimated = require('react-native-reanimated');
6
8
  var bottomSheet = require('@gorhom/bottom-sheet');
9
+ var reactNativeGestureHandler = require('react-native-gesture-handler');
7
10
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
8
11
 
9
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -27,7 +30,8 @@ function _interopNamespace(e) {
27
30
  }
28
31
 
29
32
  var React23__default = /*#__PURE__*/_interopDefault(React23);
30
- var Haptics10__namespace = /*#__PURE__*/_interopNamespace(Haptics10);
33
+ var Haptics11__namespace = /*#__PURE__*/_interopNamespace(Haptics11);
34
+ var ReanimatedAnimated__default = /*#__PURE__*/_interopDefault(ReanimatedAnimated);
31
35
 
32
36
  // src/theme/ThemeProvider.tsx
33
37
 
@@ -49,7 +53,9 @@ var defaultLight = {
49
53
  destructiveForeground: "#fafafa",
50
54
  border: "#e5e5e5",
51
55
  input: "#e5e5e5",
52
- ring: "#a3a3a3"
56
+ ring: "#a3a3a3",
57
+ success: "#16a34a",
58
+ successForeground: "#ffffff"
53
59
  };
54
60
  var defaultDark = {
55
61
  background: "#171717",
@@ -68,7 +74,9 @@ var defaultDark = {
68
74
  destructiveForeground: "#fafafa",
69
75
  border: "#2a2a2a",
70
76
  input: "#2a2a2a",
71
- ring: "#d4d4d4"
77
+ ring: "#d4d4d4",
78
+ success: "#22c55e",
79
+ successForeground: "#ffffff"
72
80
  };
73
81
 
74
82
  // src/theme/ThemeProvider.tsx
@@ -105,6 +113,8 @@ function Button({
105
113
  size = "md",
106
114
  loading = false,
107
115
  fullWidth = false,
116
+ icon,
117
+ iconPosition = "left",
108
118
  disabled,
109
119
  style,
110
120
  onPress,
@@ -115,13 +125,18 @@ function Button({
115
125
  const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
116
126
  const handlePressIn = () => {
117
127
  if (isDisabled) return;
118
- reactNative.Animated.spring(scale, { toValue: 0.97, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
128
+ reactNative.Animated.spring(scale, {
129
+ toValue: 0.95,
130
+ useNativeDriver: true,
131
+ speed: 40,
132
+ bounciness: 0
133
+ }).start();
119
134
  };
120
135
  const handlePressOut = () => {
121
- reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 2 }).start();
136
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
122
137
  };
123
138
  const handlePress = (e) => {
124
- Haptics10__namespace.impactAsync(Haptics10__namespace.ImpactFeedbackStyle.Light);
139
+ Haptics11__namespace.impactAsync(Haptics11__namespace.ImpactFeedbackStyle.Light);
125
140
  onPress?.(e);
126
141
  };
127
142
  const containerVariantStyle = {
@@ -150,12 +165,13 @@ function Button({
150
165
  ],
151
166
  disabled: isDisabled,
152
167
  activeOpacity: 1,
168
+ touchSoundDisabled: true,
153
169
  onPress: handlePress,
154
170
  onPressIn: handlePressIn,
155
171
  onPressOut: handlePressOut,
156
172
  ...props
157
173
  },
158
- loading ? /* @__PURE__ */ React23__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size]] }, label)
174
+ loading ? /* @__PURE__ */ React23__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React23__default.default.createElement(React23__default.default.Fragment, null, icon && iconPosition === "left" && /* @__PURE__ */ React23__default.default.createElement(React23__default.default.Fragment, null, icon), /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size], icon ? styles.labelWithIcon : void 0] }, label), icon && iconPosition === "right" && /* @__PURE__ */ React23__default.default.createElement(React23__default.default.Fragment, null, icon))
159
175
  ));
160
176
  }
161
177
  var styles = reactNative.StyleSheet.create({
@@ -173,6 +189,9 @@ var styles = reactNative.StyleSheet.create({
173
189
  },
174
190
  label: {
175
191
  fontWeight: "600"
192
+ },
193
+ labelWithIcon: {
194
+ marginHorizontal: 6
176
195
  }
177
196
  });
178
197
  var variantStyles = {
@@ -196,10 +215,10 @@ function Text2({ variant = "body", color, style, children, ...props }) {
196
215
  children
197
216
  );
198
217
  }
199
- function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
218
+ function Input({ label, error, hint, containerStyle, style, onFocus, onBlur, ...props }) {
200
219
  const { colors } = useTheme();
201
220
  const [focused, setFocused] = React23.useState(false);
202
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles2.container }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23__default.default.createElement(
221
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles2.container, containerStyle] }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23__default.default.createElement(
203
222
  reactNative.TextInput,
204
223
  {
205
224
  style: [
@@ -223,7 +242,7 @@ function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
223
242
  allowFontScaling: true,
224
243
  ...props
225
244
  }
226
- ), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.helperText, { color: colors.destructive }] }, error) : null, !error && hint ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.helperText, { color: colors.mutedForeground }] }, hint) : null);
245
+ ), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles2.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
227
246
  }
228
247
  var styles2 = reactNative.StyleSheet.create({
229
248
  container: {
@@ -259,7 +278,7 @@ function Badge({ label, variant = "default", style }) {
259
278
  destructive: colors.destructiveForeground,
260
279
  outline: colors.foreground
261
280
  }[variant];
262
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles3.container, containerStyle, style] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles3.label, { color: textColor }] }, label));
281
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles3.container, containerStyle, style] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles3.label, { color: textColor }], allowFontScaling: true }, label));
263
282
  }
264
283
  var styles3 = reactNative.StyleSheet.create({
265
284
  container: {
@@ -278,11 +297,7 @@ function Card({ children, style }) {
278
297
  return /* @__PURE__ */ React23__default.default.createElement(
279
298
  reactNative.View,
280
299
  {
281
- style: [
282
- styles4.card,
283
- { backgroundColor: colors.card, borderColor: colors.border },
284
- style
285
- ]
300
+ style: [styles4.card, { backgroundColor: colors.card, borderColor: colors.border }, style]
286
301
  },
287
302
  children
288
303
  );
@@ -368,41 +383,53 @@ var sizeMap = {
368
383
  };
369
384
  function Spinner({ size = "md", color, ...props }) {
370
385
  const { colors } = useTheme();
371
- return /* @__PURE__ */ React23__default.default.createElement(
372
- reactNative.ActivityIndicator,
373
- {
374
- size: sizeMap[size],
375
- color: color ?? colors.primary,
376
- ...props
377
- }
378
- );
386
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props });
379
387
  }
380
388
  function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
381
- const { colors } = useTheme();
382
- const opacity = React23.useRef(new reactNative.Animated.Value(1)).current;
389
+ const { colors, colorScheme } = useTheme();
390
+ const shimmerAnim = React23.useRef(new reactNative.Animated.Value(0)).current;
391
+ const [containerWidth, setContainerWidth] = React23.useState(300);
392
+ const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
383
393
  React23.useEffect(() => {
384
394
  const animation = reactNative.Animated.loop(
385
- reactNative.Animated.sequence([
386
- reactNative.Animated.timing(opacity, { toValue: 0.4, duration: 800, useNativeDriver: true }),
387
- reactNative.Animated.timing(opacity, { toValue: 1, duration: 800, useNativeDriver: true })
388
- ])
395
+ reactNative.Animated.timing(shimmerAnim, {
396
+ toValue: 1,
397
+ duration: 1200,
398
+ useNativeDriver: true
399
+ })
389
400
  );
390
401
  animation.start();
391
402
  return () => animation.stop();
392
- }, [opacity]);
403
+ }, [shimmerAnim]);
404
+ const translateX = shimmerAnim.interpolate({
405
+ inputRange: [0, 1],
406
+ outputRange: [-containerWidth, containerWidth]
407
+ });
393
408
  return /* @__PURE__ */ React23__default.default.createElement(
394
- reactNative.Animated.View,
409
+ reactNative.View,
395
410
  {
396
411
  style: [
397
412
  styles6.base,
398
- { width, height, borderRadius, backgroundColor: colors.muted, opacity },
413
+ { width, height, borderRadius, backgroundColor: colors.muted },
399
414
  style
400
- ]
401
- }
415
+ ],
416
+ onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
417
+ },
418
+ /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: [reactNative.StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React23__default.default.createElement(
419
+ expoLinearGradient.LinearGradient,
420
+ {
421
+ colors: ["transparent", shimmerHighlight, "transparent"],
422
+ start: { x: 0, y: 0 },
423
+ end: { x: 1, y: 0 },
424
+ style: reactNative.StyleSheet.absoluteFill
425
+ }
426
+ ))
402
427
  );
403
428
  }
404
429
  var styles6 = reactNative.StyleSheet.create({
405
- base: {}
430
+ base: {
431
+ overflow: "hidden"
432
+ }
406
433
  });
407
434
  var sizeMap2 = {
408
435
  sm: 24,
@@ -435,7 +462,13 @@ function Avatar({ src, fallback, size = "md", style }) {
435
462
  style: { width: dimension, height: dimension },
436
463
  onError: () => setImageError(true)
437
464
  }
438
- ) : /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles7.fallback, { color: colors.mutedForeground, fontSize: fontSizeMap[size] }] }, fallback?.slice(0, 2).toUpperCase() ?? "?"));
465
+ ) : /* @__PURE__ */ React23__default.default.createElement(
466
+ reactNative.Text,
467
+ {
468
+ style: [styles7.fallback, { color: colors.mutedForeground, fontSize: fontSizeMap[size] }]
469
+ },
470
+ fallback?.slice(0, 2).toUpperCase() ?? "?"
471
+ ));
439
472
  }
440
473
  var styles7 = reactNative.StyleSheet.create({
441
474
  base: {
@@ -501,10 +534,7 @@ function Progress({ value = 0, max = 100, style }) {
501
534
  /* @__PURE__ */ React23__default.default.createElement(
502
535
  reactNative.Animated.View,
503
536
  {
504
- style: [
505
- styles9.indicator,
506
- { width: animatedWidth, backgroundColor: colors.primary }
507
- ]
537
+ style: [styles9.indicator, { width: animatedWidth, backgroundColor: colors.primary }]
508
538
  }
509
539
  )
510
540
  );
@@ -561,10 +591,20 @@ var styles10 = reactNative.StyleSheet.create({
561
591
  marginTop: 8
562
592
  }
563
593
  });
564
- function Textarea({ label, error, hint, rows = 4, style, onFocus, onBlur, ...props }) {
594
+ function Textarea({
595
+ label,
596
+ error,
597
+ hint,
598
+ rows = 4,
599
+ containerStyle,
600
+ style,
601
+ onFocus,
602
+ onBlur,
603
+ ...props
604
+ }) {
565
605
  const { colors } = useTheme();
566
606
  const [focused, setFocused] = React23.useState(false);
567
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles11.container }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23__default.default.createElement(
607
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles11.container, containerStyle] }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23__default.default.createElement(
568
608
  reactNative.TextInput,
569
609
  {
570
610
  multiline: true,
@@ -592,7 +632,7 @@ function Textarea({ label, error, hint, rows = 4, style, onFocus, onBlur, ...pro
592
632
  allowFontScaling: true,
593
633
  ...props
594
634
  }
595
- ), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.helperText, { color: colors.destructive }] }, error) : null, !error && hint ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.helperText, { color: colors.mutedForeground }] }, hint) : null);
635
+ ), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles11.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
596
636
  }
597
637
  var styles11 = reactNative.StyleSheet.create({
598
638
  container: {
@@ -614,18 +654,35 @@ var styles11 = reactNative.StyleSheet.create({
614
654
  fontSize: 12
615
655
  }
616
656
  });
617
- function Checkbox({ checked = false, onCheckedChange, label, disabled, style }) {
657
+ function Checkbox({
658
+ checked = false,
659
+ onCheckedChange,
660
+ label,
661
+ disabled,
662
+ style
663
+ }) {
618
664
  const { colors } = useTheme();
619
- return /* @__PURE__ */ React23__default.default.createElement(
665
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
666
+ const handlePressIn = () => {
667
+ if (disabled) return;
668
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
669
+ };
670
+ const handlePressOut = () => {
671
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
672
+ };
673
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
620
674
  reactNative.TouchableOpacity,
621
675
  {
622
676
  style: [styles12.row, style],
623
677
  onPress: () => {
624
- Haptics10__namespace.selectionAsync();
678
+ Haptics11__namespace.selectionAsync();
625
679
  onCheckedChange?.(!checked);
626
680
  },
681
+ onPressIn: handlePressIn,
682
+ onPressOut: handlePressOut,
627
683
  disabled,
628
- activeOpacity: 0.7
684
+ activeOpacity: 1,
685
+ touchSoundDisabled: true
629
686
  },
630
687
  /* @__PURE__ */ React23__default.default.createElement(
631
688
  reactNative.View,
@@ -641,8 +698,14 @@ function Checkbox({ checked = false, onCheckedChange, label, disabled, style })
641
698
  },
642
699
  checked ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles12.checkmark, { borderColor: colors.primaryForeground }] }) : null
643
700
  ),
644
- label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles12.label, { color: disabled ? colors.mutedForeground : colors.foreground }] }, label) : null
645
- );
701
+ label ? /* @__PURE__ */ React23__default.default.createElement(
702
+ reactNative.Text,
703
+ {
704
+ style: [styles12.label, { color: disabled ? colors.mutedForeground : colors.foreground }]
705
+ },
706
+ label
707
+ ) : null
708
+ ));
646
709
  }
647
710
  var styles12 = reactNative.StyleSheet.create({
648
711
  row: {
@@ -701,11 +764,12 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
701
764
  reactNative.TouchableOpacity,
702
765
  {
703
766
  onPress: () => {
704
- Haptics10__namespace.selectionAsync();
767
+ Haptics11__namespace.selectionAsync();
705
768
  onCheckedChange?.(!checked);
706
769
  },
707
770
  disabled,
708
771
  activeOpacity: 0.8,
772
+ touchSoundDisabled: true,
709
773
  style: [styles13.wrapper, { opacity: disabled ? 0.45 : 1 }, style]
710
774
  },
711
775
  /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: [styles13.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React23__default.default.createElement(
@@ -756,29 +820,34 @@ function Toggle({
756
820
  ...props
757
821
  }) {
758
822
  const { colors } = useTheme();
823
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
824
+ const handlePressIn = () => {
825
+ if (disabled) return;
826
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
827
+ };
828
+ const handlePressOut = () => {
829
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
830
+ };
759
831
  const containerStyle = pressed ? { backgroundColor: colors.accent } : variant === "outline" ? { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border } : { backgroundColor: "transparent" };
760
832
  const textColor = pressed ? colors.accentForeground : colors.foreground;
761
- return /* @__PURE__ */ React23__default.default.createElement(
833
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
762
834
  reactNative.TouchableOpacity,
763
835
  {
764
- style: [
765
- styles14.base,
766
- containerStyle,
767
- sizeStyles[size],
768
- disabled && styles14.disabled,
769
- style
770
- ],
836
+ style: [styles14.base, containerStyle, sizeStyles[size], disabled && styles14.disabled, style],
771
837
  onPress: () => {
772
- Haptics10__namespace.selectionAsync();
838
+ Haptics11__namespace.selectionAsync();
773
839
  onPressedChange?.(!pressed);
774
840
  },
841
+ onPressIn: handlePressIn,
842
+ onPressOut: handlePressOut,
775
843
  disabled,
776
- activeOpacity: 0.7,
844
+ activeOpacity: 1,
845
+ touchSoundDisabled: true,
777
846
  ...props
778
847
  },
779
848
  icon,
780
849
  label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: textColor }] }, label) : null
781
- );
850
+ ));
782
851
  }
783
852
  var styles14 = reactNative.StyleSheet.create({
784
853
  base: {
@@ -796,6 +865,61 @@ var styles14 = reactNative.StyleSheet.create({
796
865
  fontWeight: "500"
797
866
  }
798
867
  });
868
+ function RadioItem({
869
+ option,
870
+ selected,
871
+ onSelect
872
+ }) {
873
+ const { colors } = useTheme();
874
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
875
+ const handlePressIn = () => {
876
+ if (option.disabled) return;
877
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
878
+ };
879
+ const handlePressOut = () => {
880
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
881
+ };
882
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
883
+ reactNative.TouchableOpacity,
884
+ {
885
+ style: styles15.row,
886
+ onPress: () => {
887
+ if (!option.disabled) {
888
+ Haptics11__namespace.selectionAsync();
889
+ onSelect();
890
+ }
891
+ },
892
+ onPressIn: handlePressIn,
893
+ onPressOut: handlePressOut,
894
+ activeOpacity: 1,
895
+ touchSoundDisabled: true,
896
+ disabled: option.disabled
897
+ },
898
+ /* @__PURE__ */ React23__default.default.createElement(
899
+ reactNative.View,
900
+ {
901
+ style: [
902
+ styles15.radio,
903
+ {
904
+ borderColor: selected ? colors.primary : colors.border,
905
+ opacity: option.disabled ? 0.45 : 1
906
+ }
907
+ ]
908
+ },
909
+ selected ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles15.dot, { backgroundColor: colors.primary }] }) : null
910
+ ),
911
+ /* @__PURE__ */ React23__default.default.createElement(
912
+ reactNative.Text,
913
+ {
914
+ style: [
915
+ styles15.label,
916
+ { color: option.disabled ? colors.mutedForeground : colors.foreground }
917
+ ]
918
+ },
919
+ option.label
920
+ )
921
+ ));
922
+ }
799
923
  function RadioGroup({
800
924
  options,
801
925
  value,
@@ -803,58 +927,15 @@ function RadioGroup({
803
927
  orientation = "vertical",
804
928
  style
805
929
  }) {
806
- const { colors } = useTheme();
807
- return /* @__PURE__ */ React23__default.default.createElement(
808
- reactNative.View,
930
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles15.container, orientation === "horizontal" && styles15.horizontal, style] }, options.map((option) => /* @__PURE__ */ React23__default.default.createElement(
931
+ RadioItem,
809
932
  {
810
- style: [
811
- styles15.container,
812
- orientation === "horizontal" && styles15.horizontal,
813
- style
814
- ]
815
- },
816
- options.map((option) => {
817
- const selected = option.value === value;
818
- return /* @__PURE__ */ React23__default.default.createElement(
819
- reactNative.TouchableOpacity,
820
- {
821
- key: option.value,
822
- style: styles15.row,
823
- onPress: () => {
824
- if (!option.disabled) {
825
- Haptics10__namespace.selectionAsync();
826
- onValueChange?.(option.value);
827
- }
828
- },
829
- activeOpacity: 0.7,
830
- disabled: option.disabled
831
- },
832
- /* @__PURE__ */ React23__default.default.createElement(
833
- reactNative.View,
834
- {
835
- style: [
836
- styles15.radio,
837
- {
838
- borderColor: selected ? colors.primary : colors.border,
839
- opacity: option.disabled ? 0.45 : 1
840
- }
841
- ]
842
- },
843
- selected ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles15.dot, { backgroundColor: colors.primary }] }) : null
844
- ),
845
- /* @__PURE__ */ React23__default.default.createElement(
846
- reactNative.Text,
847
- {
848
- style: [
849
- styles15.label,
850
- { color: option.disabled ? colors.mutedForeground : colors.foreground }
851
- ]
852
- },
853
- option.label
854
- )
855
- );
856
- })
857
- );
933
+ key: option.value,
934
+ option,
935
+ selected: option.value === value,
936
+ onSelect: () => onValueChange?.(option.value)
937
+ }
938
+ )));
858
939
  }
859
940
  var styles15 = reactNative.StyleSheet.create({
860
941
  container: {
@@ -887,6 +968,44 @@ var styles15 = reactNative.StyleSheet.create({
887
968
  lineHeight: 20
888
969
  }
889
970
  });
971
+ function TabTrigger({
972
+ tab,
973
+ isActive,
974
+ onPress,
975
+ onLayout
976
+ }) {
977
+ const { colors } = useTheme();
978
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
979
+ const handlePressIn = () => {
980
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
981
+ };
982
+ const handlePressOut = () => {
983
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
984
+ };
985
+ return /* @__PURE__ */ React23__default.default.createElement(
986
+ reactNative.TouchableOpacity,
987
+ {
988
+ style: styles16.trigger,
989
+ onPress,
990
+ onPressIn: handlePressIn,
991
+ onPressOut: handlePressOut,
992
+ onLayout,
993
+ activeOpacity: 1,
994
+ touchSoundDisabled: true
995
+ },
996
+ /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
997
+ reactNative.Text,
998
+ {
999
+ style: [
1000
+ styles16.triggerLabel,
1001
+ { color: isActive ? colors.foreground : colors.mutedForeground },
1002
+ isActive && styles16.activeTriggerLabel
1003
+ ]
1004
+ },
1005
+ tab.label
1006
+ ))
1007
+ );
1008
+ }
890
1009
  function Tabs({ tabs, value, onValueChange, children, style }) {
891
1010
  const [internal, setInternal] = React23.useState(tabs[0]?.value ?? "");
892
1011
  const { colors } = useTheme();
@@ -900,8 +1019,18 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
900
1019
  if (!layout) return;
901
1020
  if (animate) {
902
1021
  reactNative.Animated.parallel([
903
- reactNative.Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, speed: 20, bounciness: 0 }),
904
- reactNative.Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, speed: 20, bounciness: 0 })
1022
+ reactNative.Animated.spring(pillX, {
1023
+ toValue: layout.x,
1024
+ useNativeDriver: false,
1025
+ speed: 20,
1026
+ bounciness: 0
1027
+ }),
1028
+ reactNative.Animated.spring(pillWidth, {
1029
+ toValue: layout.width,
1030
+ useNativeDriver: false,
1031
+ speed: 20,
1032
+ bounciness: 0
1033
+ })
905
1034
  ]).start();
906
1035
  } else {
907
1036
  pillX.setValue(layout.x);
@@ -914,6 +1043,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
914
1043
  }
915
1044
  }, [active]);
916
1045
  const handlePress = (v) => {
1046
+ Haptics11__namespace.selectionAsync();
917
1047
  if (!value) setInternal(v);
918
1048
  onValueChange?.(v);
919
1049
  };
@@ -938,37 +1068,23 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
938
1068
  }
939
1069
  ]
940
1070
  }
941
- ), tabs.map((tab) => {
942
- const isActive = tab.value === active;
943
- return /* @__PURE__ */ React23__default.default.createElement(
944
- reactNative.TouchableOpacity,
945
- {
946
- key: tab.value,
947
- style: styles16.trigger,
948
- onPress: () => handlePress(tab.value),
949
- activeOpacity: 0.7,
950
- onLayout: (e) => {
951
- const { x, width } = e.nativeEvent.layout;
952
- tabLayouts.current[tab.value] = { x, width };
953
- if (tab.value === active) {
954
- animatePill(tab.value, false);
955
- initialised.current = true;
956
- }
1071
+ ), tabs.map((tab) => /* @__PURE__ */ React23__default.default.createElement(
1072
+ TabTrigger,
1073
+ {
1074
+ key: tab.value,
1075
+ tab,
1076
+ isActive: tab.value === active,
1077
+ onPress: () => handlePress(tab.value),
1078
+ onLayout: (e) => {
1079
+ const { x, width } = e.nativeEvent.layout;
1080
+ tabLayouts.current[tab.value] = { x, width };
1081
+ if (tab.value === active) {
1082
+ animatePill(tab.value, false);
1083
+ initialised.current = true;
957
1084
  }
958
- },
959
- /* @__PURE__ */ React23__default.default.createElement(
960
- reactNative.Text,
961
- {
962
- style: [
963
- styles16.triggerLabel,
964
- { color: isActive ? colors.foreground : colors.mutedForeground },
965
- isActive && styles16.activeTriggerLabel
966
- ]
967
- },
968
- tab.label
969
- )
970
- );
971
- })), children);
1085
+ }
1086
+ }
1087
+ ))), children);
972
1088
  }
973
1089
  function TabsContent({ value, activeValue, children, style }) {
974
1090
  if (value !== activeValue) return null;
@@ -988,6 +1104,7 @@ var styles16 = reactNative.StyleSheet.create({
988
1104
  paddingHorizontal: 12,
989
1105
  borderRadius: 6,
990
1106
  alignItems: "center",
1107
+ justifyContent: "center",
991
1108
  zIndex: 1
992
1109
  },
993
1110
  triggerLabel: {
@@ -1004,24 +1121,14 @@ function AccordionItemComponent({
1004
1121
  onToggle
1005
1122
  }) {
1006
1123
  const { colors } = useTheme();
1007
- const animatedHeight = React23.useRef(new reactNative.Animated.Value(0)).current;
1008
- const animatedRotation = React23.useRef(new reactNative.Animated.Value(0)).current;
1124
+ const animatedHeight = ReanimatedAnimated.useSharedValue(0);
1125
+ const animatedRotation = ReanimatedAnimated.useSharedValue(0);
1009
1126
  const contentHeight = React23.useRef(0);
1127
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
1010
1128
  const toggle = (open) => {
1011
- reactNative.Animated.parallel([
1012
- reactNative.Animated.timing(animatedHeight, {
1013
- toValue: open ? contentHeight.current : 0,
1014
- duration: 220,
1015
- easing: open ? reactNative.Easing.out(reactNative.Easing.ease) : reactNative.Easing.in(reactNative.Easing.ease),
1016
- useNativeDriver: false
1017
- }),
1018
- reactNative.Animated.timing(animatedRotation, {
1019
- toValue: open ? 1 : 0,
1020
- duration: 220,
1021
- easing: open ? reactNative.Easing.out(reactNative.Easing.ease) : reactNative.Easing.in(reactNative.Easing.ease),
1022
- useNativeDriver: true
1023
- })
1024
- ]).start();
1129
+ const easing = open ? ReanimatedAnimated.Easing.out(ReanimatedAnimated.Easing.ease) : ReanimatedAnimated.Easing.in(ReanimatedAnimated.Easing.ease);
1130
+ animatedHeight.value = ReanimatedAnimated.withTiming(open ? contentHeight.current : 0, { duration: 220, easing });
1131
+ animatedRotation.value = ReanimatedAnimated.withTiming(open ? 1 : 0, { duration: 220, easing });
1025
1132
  };
1026
1133
  React23__default.default.useEffect(() => {
1027
1134
  toggle(isOpen);
@@ -1029,32 +1136,44 @@ function AccordionItemComponent({
1029
1136
  const onLayout = (e) => {
1030
1137
  if (contentHeight.current === 0) {
1031
1138
  contentHeight.current = e.nativeEvent.layout.height;
1032
- if (isOpen) animatedHeight.setValue(contentHeight.current);
1139
+ if (isOpen) animatedHeight.value = contentHeight.current;
1033
1140
  }
1034
1141
  };
1035
- const rotate = animatedRotation.interpolate({
1036
- inputRange: [0, 1],
1037
- outputRange: ["0deg", "180deg"]
1038
- });
1039
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles17.item, { borderBottomColor: colors.border }] }, /* @__PURE__ */ React23__default.default.createElement(
1142
+ const heightStyle = ReanimatedAnimated.useAnimatedStyle(() => ({
1143
+ height: animatedHeight.value,
1144
+ overflow: "hidden"
1145
+ }));
1146
+ const rotationStyle = ReanimatedAnimated.useAnimatedStyle(() => ({
1147
+ transform: [{ rotate: `${animatedRotation.value * 180}deg` }]
1148
+ }));
1149
+ const handlePressIn = () => {
1150
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
1151
+ };
1152
+ const handlePressOut = () => {
1153
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
1154
+ };
1155
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles17.item, { borderBottomColor: colors.border }] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
1040
1156
  reactNative.TouchableOpacity,
1041
1157
  {
1042
1158
  style: styles17.trigger,
1043
1159
  onPress: () => {
1044
- Haptics10__namespace.selectionAsync();
1160
+ Haptics11__namespace.selectionAsync();
1045
1161
  onToggle();
1046
1162
  },
1047
- activeOpacity: 0.7
1163
+ onPressIn: handlePressIn,
1164
+ onPressOut: handlePressOut,
1165
+ activeOpacity: 1,
1166
+ touchSoundDisabled: true
1048
1167
  },
1049
1168
  /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles17.triggerText, { color: colors.foreground }] }, item.trigger),
1050
1169
  /* @__PURE__ */ React23__default.default.createElement(
1051
- reactNative.Animated.Text,
1170
+ ReanimatedAnimated__default.default.Text,
1052
1171
  {
1053
- style: [styles17.chevron, { color: colors.foreground, transform: [{ rotate }] }]
1172
+ style: [styles17.chevron, { color: colors.foreground }, rotationStyle]
1054
1173
  },
1055
1174
  "\u25BE"
1056
1175
  )
1057
- ), /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: [styles17.contentWrapper, { height: animatedHeight, overflow: "hidden" }] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles17.content, onLayout }, item.content)));
1176
+ )), /* @__PURE__ */ React23__default.default.createElement(ReanimatedAnimated__default.default.View, { style: heightStyle }, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles17.content, onLayout }, item.content)));
1058
1177
  }
1059
1178
  function Accordion({ items, type = "single", defaultValue, style }) {
1060
1179
  const [openValues, setOpenValues] = React23.useState(() => {
@@ -1099,7 +1218,6 @@ var styles17 = reactNative.StyleSheet.create({
1099
1218
  fontSize: 16,
1100
1219
  marginLeft: 8
1101
1220
  },
1102
- contentWrapper: {},
1103
1221
  content: {
1104
1222
  paddingBottom: 16,
1105
1223
  position: "absolute",
@@ -1146,7 +1264,7 @@ function Slider({
1146
1264
  const newValue = xToValue(x);
1147
1265
  if (newValue !== lastSteppedValue.current) {
1148
1266
  lastSteppedValue.current = newValue;
1149
- Haptics10__namespace.selectionAsync();
1267
+ Haptics11__namespace.selectionAsync();
1150
1268
  }
1151
1269
  setInternalValue(newValue);
1152
1270
  onValueChange?.(newValue);
@@ -1173,10 +1291,7 @@ function Slider({
1173
1291
  /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles18.track, { backgroundColor: colors.muted }] }, /* @__PURE__ */ React23__default.default.createElement(
1174
1292
  reactNative.View,
1175
1293
  {
1176
- style: [
1177
- styles18.range,
1178
- { width: `${percent}%`, backgroundColor: colors.primary }
1179
- ]
1294
+ style: [styles18.range, { width: `${percent}%`, backgroundColor: colors.primary }]
1180
1295
  }
1181
1296
  )),
1182
1297
  /* @__PURE__ */ React23__default.default.createElement(
@@ -1241,7 +1356,7 @@ function Sheet({
1241
1356
  const ref = React23.useRef(null);
1242
1357
  React23.useEffect(() => {
1243
1358
  if (open) {
1244
- Haptics10__namespace.impactAsync(Haptics10__namespace.ImpactFeedbackStyle.Light);
1359
+ Haptics11__namespace.impactAsync(Haptics11__namespace.ImpactFeedbackStyle.Light);
1245
1360
  ref.current?.present();
1246
1361
  } else {
1247
1362
  ref.current?.dismiss();
@@ -1308,26 +1423,49 @@ function Select({
1308
1423
  style
1309
1424
  }) {
1310
1425
  const { colors } = useTheme();
1311
- const [open, setOpen] = React23.useState(false);
1426
+ const bottomSheetRef = React23.useRef(null);
1427
+ const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
1312
1428
  const selected = options.find((o) => o.value === value);
1313
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles20.container, style] }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23__default.default.createElement(
1429
+ const handlePressIn = () => {
1430
+ if (disabled) return;
1431
+ reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
1432
+ };
1433
+ const handlePressOut = () => {
1434
+ reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
1435
+ };
1436
+ const handleOpen = () => {
1437
+ if (!disabled) {
1438
+ Haptics11__namespace.selectionAsync();
1439
+ bottomSheetRef.current?.present();
1440
+ }
1441
+ };
1442
+ const renderBackdrop = React23.useCallback(
1443
+ (props) => /* @__PURE__ */ React23__default.default.createElement(
1444
+ bottomSheet.BottomSheetBackdrop,
1445
+ {
1446
+ ...props,
1447
+ disappearsOnIndex: -1,
1448
+ appearsOnIndex: 0,
1449
+ pressBehavior: "close"
1450
+ }
1451
+ ),
1452
+ []
1453
+ );
1454
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles20.container, style] }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React23__default.default.createElement(
1314
1455
  reactNative.TouchableOpacity,
1315
1456
  {
1316
1457
  style: [
1317
1458
  styles20.trigger,
1318
1459
  {
1319
1460
  borderColor: error ? colors.destructive : colors.border,
1320
- backgroundColor: colors.background,
1321
- opacity: disabled ? 0.45 : 1
1461
+ backgroundColor: colors.background
1322
1462
  }
1323
1463
  ],
1324
- onPress: () => {
1325
- if (!disabled) {
1326
- Haptics10__namespace.selectionAsync();
1327
- setOpen(true);
1328
- }
1329
- },
1330
- activeOpacity: 0.7
1464
+ onPress: handleOpen,
1465
+ onPressIn: handlePressIn,
1466
+ onPressOut: handlePressOut,
1467
+ activeOpacity: 1,
1468
+ touchSoundDisabled: true
1331
1469
  },
1332
1470
  /* @__PURE__ */ React23__default.default.createElement(
1333
1471
  reactNative.Text,
@@ -1341,46 +1479,52 @@ function Select({
1341
1479
  selected?.label ?? placeholder
1342
1480
  ),
1343
1481
  /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.chevron, { color: colors.mutedForeground }] }, "\u25BE")
1344
- ), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.helperText, { color: colors.destructive }] }, error) : null, /* @__PURE__ */ React23__default.default.createElement(reactNative.Modal, { transparent: true, visible: open, onRequestClose: () => setOpen(false), animationType: "fade" }, /* @__PURE__ */ React23__default.default.createElement(reactNative.TouchableOpacity, { style: styles20.overlay, onPress: () => setOpen(false), activeOpacity: 1 }, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles20.list, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React23__default.default.createElement(
1345
- reactNative.FlatList,
1482
+ )), error ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.helperText, { color: colors.destructive }] }, error) : null, /* @__PURE__ */ React23__default.default.createElement(
1483
+ bottomSheet.BottomSheetModal,
1346
1484
  {
1347
- data: options,
1348
- keyExtractor: (item) => item.value,
1349
- renderItem: ({ item }) => {
1350
- const isSelected = item.value === value;
1351
- return /* @__PURE__ */ React23__default.default.createElement(
1352
- reactNative.TouchableOpacity,
1485
+ ref: bottomSheetRef,
1486
+ enableDynamicSizing: true,
1487
+ enablePanDownToClose: true,
1488
+ backdropComponent: renderBackdrop,
1489
+ backgroundStyle: [styles20.sheetBackground, { backgroundColor: colors.card }],
1490
+ handleIndicatorStyle: [styles20.sheetHandle, { backgroundColor: colors.border }]
1491
+ },
1492
+ /* @__PURE__ */ React23__default.default.createElement(bottomSheet.BottomSheetView, { style: styles20.sheetContent }, label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.sheetTitle, { color: colors.foreground }] }, label) : null, options.map((item) => {
1493
+ const isSelected = item.value === value;
1494
+ return /* @__PURE__ */ React23__default.default.createElement(
1495
+ reactNative.TouchableOpacity,
1496
+ {
1497
+ key: item.value,
1498
+ style: [
1499
+ styles20.option,
1500
+ isSelected && { backgroundColor: colors.accent },
1501
+ item.disabled && styles20.disabledOption
1502
+ ],
1503
+ onPress: () => {
1504
+ if (!item.disabled) {
1505
+ Haptics11__namespace.selectionAsync();
1506
+ onValueChange?.(item.value);
1507
+ bottomSheetRef.current?.dismiss();
1508
+ }
1509
+ },
1510
+ activeOpacity: 0.7,
1511
+ touchSoundDisabled: true
1512
+ },
1513
+ /* @__PURE__ */ React23__default.default.createElement(
1514
+ reactNative.Text,
1353
1515
  {
1354
1516
  style: [
1355
- styles20.option,
1356
- isSelected && { backgroundColor: colors.accent },
1357
- item.disabled && styles20.disabledOption
1358
- ],
1359
- onPress: () => {
1360
- if (!item.disabled) {
1361
- Haptics10__namespace.selectionAsync();
1362
- onValueChange?.(item.value);
1363
- setOpen(false);
1364
- }
1365
- },
1366
- activeOpacity: 0.7
1517
+ styles20.optionText,
1518
+ { color: item.disabled ? colors.mutedForeground : colors.foreground },
1519
+ isSelected && { fontWeight: "500" }
1520
+ ]
1367
1521
  },
1368
- /* @__PURE__ */ React23__default.default.createElement(
1369
- reactNative.Text,
1370
- {
1371
- style: [
1372
- styles20.optionText,
1373
- { color: item.disabled ? colors.mutedForeground : colors.foreground },
1374
- isSelected && { fontWeight: "500" }
1375
- ]
1376
- },
1377
- item.label
1378
- ),
1379
- isSelected ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.checkmark, { color: colors.primary }] }, "\u2713") : null
1380
- );
1381
- }
1382
- }
1383
- )))));
1522
+ item.label
1523
+ ),
1524
+ isSelected ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles20.checkmark, { color: colors.primary }] }, "\u2713") : null
1525
+ );
1526
+ }))
1527
+ ));
1384
1528
  }
1385
1529
  var styles20 = reactNative.StyleSheet.create({
1386
1530
  container: {
@@ -1411,34 +1555,44 @@ var styles20 = reactNative.StyleSheet.create({
1411
1555
  helperText: {
1412
1556
  fontSize: 12
1413
1557
  },
1414
- overlay: {
1415
- flex: 1,
1416
- backgroundColor: "rgba(0,0,0,0.3)",
1417
- justifyContent: "center",
1418
- padding: 24
1558
+ sheetBackground: {
1559
+ borderTopLeftRadius: 16,
1560
+ borderTopRightRadius: 16
1419
1561
  },
1420
- list: {
1421
- borderRadius: 12,
1422
- borderWidth: 1,
1423
- maxHeight: 300,
1424
- overflow: "hidden"
1562
+ sheetHandle: {
1563
+ width: 36,
1564
+ height: 4,
1565
+ borderRadius: 2
1566
+ },
1567
+ sheetContent: {
1568
+ paddingHorizontal: 16,
1569
+ paddingBottom: 32
1570
+ },
1571
+ sheetTitle: {
1572
+ fontSize: 16,
1573
+ fontWeight: "600",
1574
+ paddingVertical: 12,
1575
+ paddingHorizontal: 4
1425
1576
  },
1426
1577
  option: {
1427
1578
  flexDirection: "row",
1428
1579
  alignItems: "center",
1429
1580
  justifyContent: "space-between",
1430
1581
  paddingHorizontal: 12,
1431
- paddingVertical: 10
1582
+ paddingVertical: 14,
1583
+ borderRadius: 8
1432
1584
  },
1433
1585
  optionText: {
1434
- fontSize: 15
1586
+ fontSize: 15,
1587
+ flex: 1
1435
1588
  },
1436
1589
  disabledOption: {
1437
1590
  opacity: 0.45
1438
1591
  },
1439
1592
  checkmark: {
1440
1593
  fontSize: 14,
1441
- fontWeight: "600"
1594
+ fontWeight: "600",
1595
+ marginLeft: 8
1442
1596
  }
1443
1597
  });
1444
1598
  var ToastContext = React23.createContext({
@@ -1450,41 +1604,53 @@ var ToastContext = React23.createContext({
1450
1604
  function useToast() {
1451
1605
  return React23.useContext(ToastContext);
1452
1606
  }
1607
+ var SWIPE_THRESHOLD = 80;
1608
+ var VELOCITY_THRESHOLD = 800;
1453
1609
  function ToastNotification({ item, onDismiss }) {
1454
1610
  const { colors } = useTheme();
1455
- const translateY = React23.useRef(new reactNative.Animated.Value(-80)).current;
1456
- const opacity = React23.useRef(new reactNative.Animated.Value(0)).current;
1611
+ const translateY = ReanimatedAnimated.useSharedValue(-80);
1612
+ const translateX = ReanimatedAnimated.useSharedValue(0);
1613
+ const opacity = ReanimatedAnimated.useSharedValue(0);
1457
1614
  React23.useEffect(() => {
1458
- reactNative.Animated.parallel([
1459
- reactNative.Animated.spring(translateY, { toValue: 0, useNativeDriver: true, bounciness: 2 }),
1460
- reactNative.Animated.timing(opacity, { toValue: 1, duration: 200, useNativeDriver: true })
1461
- ]).start();
1615
+ translateY.value = ReanimatedAnimated.withTiming(0, { duration: 120, easing: ReanimatedAnimated.Easing.out(ReanimatedAnimated.Easing.exp) });
1616
+ opacity.value = ReanimatedAnimated.withTiming(1, { duration: 100 });
1462
1617
  const timer = setTimeout(() => {
1463
- reactNative.Animated.parallel([
1464
- reactNative.Animated.timing(translateY, { toValue: -80, duration: 200, useNativeDriver: true }),
1465
- reactNative.Animated.timing(opacity, { toValue: 0, duration: 200, useNativeDriver: true })
1466
- ]).start(onDismiss);
1618
+ translateY.value = ReanimatedAnimated.withTiming(-80, { duration: 200 });
1619
+ opacity.value = ReanimatedAnimated.withTiming(0, { duration: 200 }, (done) => {
1620
+ if (done) ReanimatedAnimated.runOnJS(onDismiss)();
1621
+ });
1467
1622
  }, item.duration ?? 3e3);
1468
1623
  return () => clearTimeout(timer);
1469
1624
  }, []);
1625
+ const panGesture = reactNativeGestureHandler.Gesture.Pan().onUpdate((e) => {
1626
+ translateX.value = e.translationX;
1627
+ }).onEnd((e) => {
1628
+ const shouldDismiss = Math.abs(translateX.value) > SWIPE_THRESHOLD || Math.abs(e.velocityX) > VELOCITY_THRESHOLD;
1629
+ if (shouldDismiss) {
1630
+ const direction = translateX.value > 0 ? 1 : -1;
1631
+ translateX.value = ReanimatedAnimated.withTiming(direction * 500, { duration: 200 }, (done) => {
1632
+ if (done) ReanimatedAnimated.runOnJS(onDismiss)();
1633
+ });
1634
+ opacity.value = ReanimatedAnimated.withTiming(0, { duration: 150 });
1635
+ } else {
1636
+ translateX.value = ReanimatedAnimated.withSpring(0, { damping: 20, stiffness: 300 });
1637
+ }
1638
+ });
1639
+ const animatedStyle = ReanimatedAnimated.useAnimatedStyle(() => ({
1640
+ opacity: opacity.value,
1641
+ transform: [{ translateY: translateY.value }, { translateX: translateX.value }]
1642
+ }));
1470
1643
  const bgColor = {
1471
1644
  default: colors.foreground,
1472
1645
  destructive: colors.destructive,
1473
- success: "#16a34a"
1646
+ success: colors.success
1474
1647
  }[item.variant ?? "default"];
1475
1648
  const textColor = {
1476
1649
  default: colors.background,
1477
1650
  destructive: colors.destructiveForeground,
1478
- success: "#ffffff"
1651
+ success: colors.successForeground
1479
1652
  }[item.variant ?? "default"];
1480
- return /* @__PURE__ */ React23__default.default.createElement(
1481
- reactNative.Animated.View,
1482
- {
1483
- style: [styles21.toast, { backgroundColor: bgColor, opacity, transform: [{ translateY }] }]
1484
- },
1485
- /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles21.toastContent }, item.title ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.toastTitle, { color: textColor }] }, item.title) : null, item.description ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.toastDescription, { color: textColor, opacity: 0.85 }] }, item.description) : null),
1486
- /* @__PURE__ */ React23__default.default.createElement(reactNative.TouchableOpacity, { onPress: onDismiss, style: styles21.dismissButton }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.dismissIcon, { color: textColor }] }, "\u2715"))
1487
- );
1653
+ return /* @__PURE__ */ React23__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React23__default.default.createElement(ReanimatedAnimated__default.default.View, { style: [styles21.toast, { backgroundColor: bgColor }, animatedStyle] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles21.toastContent }, item.title ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.toastTitle, { color: textColor }] }, item.title) : null, item.description ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.toastDescription, { color: textColor, opacity: 0.85 }] }, item.description) : null), /* @__PURE__ */ React23__default.default.createElement(reactNative.TouchableOpacity, { onPress: onDismiss, style: styles21.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.dismissIcon, { color: textColor }] }, "\u2715"))));
1488
1654
  }
1489
1655
  function ToastProvider({ children }) {
1490
1656
  const [toasts, setToasts] = React23.useState([]);
@@ -1492,11 +1658,11 @@ function ToastProvider({ children }) {
1492
1658
  const toast = React23.useCallback((item) => {
1493
1659
  const id = Math.random().toString(36).slice(2);
1494
1660
  if (item.variant === "success") {
1495
- Haptics10__namespace.notificationAsync(Haptics10__namespace.NotificationFeedbackType.Success);
1661
+ Haptics11__namespace.notificationAsync(Haptics11__namespace.NotificationFeedbackType.Success);
1496
1662
  } else if (item.variant === "destructive") {
1497
- Haptics10__namespace.notificationAsync(Haptics10__namespace.NotificationFeedbackType.Error);
1663
+ Haptics11__namespace.notificationAsync(Haptics11__namespace.NotificationFeedbackType.Error);
1498
1664
  } else {
1499
- Haptics10__namespace.impactAsync(Haptics10__namespace.ImpactFeedbackStyle.Light);
1665
+ Haptics11__namespace.impactAsync(Haptics11__namespace.ImpactFeedbackStyle.Light);
1500
1666
  }
1501
1667
  setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3));
1502
1668
  }, []);
@@ -1537,8 +1703,8 @@ var styles21 = reactNative.StyleSheet.create({
1537
1703
  fontSize: 13
1538
1704
  },
1539
1705
  dismissButton: {
1540
- padding: 4,
1541
- marginLeft: 8
1706
+ padding: 12,
1707
+ marginLeft: 4
1542
1708
  },
1543
1709
  dismissIcon: {
1544
1710
  fontSize: 12