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