@retray-dev/ui-kit 1.5.0 → 1.7.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
@@ -6,6 +6,7 @@ var Haptics11 = require('expo-haptics');
6
6
  var expoLinearGradient = require('expo-linear-gradient');
7
7
  var ReanimatedAnimated = require('react-native-reanimated');
8
8
  var bottomSheet = require('@gorhom/bottom-sheet');
9
+ var reactNativeWorklets = require('react-native-worklets');
9
10
  var reactNativeGestureHandler = require('react-native-gesture-handler');
10
11
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
11
12
 
@@ -98,13 +99,13 @@ function useTheme() {
98
99
  return React23.useContext(ThemeContext);
99
100
  }
100
101
  var containerSizeStyles = {
101
- sm: { paddingHorizontal: 16, paddingVertical: 10 },
102
- md: { paddingHorizontal: 20, paddingVertical: 14 },
103
- lg: { paddingHorizontal: 28, paddingVertical: 18 }
102
+ sm: { paddingHorizontal: 20, paddingVertical: 12 },
103
+ md: { paddingHorizontal: 24, paddingVertical: 16 },
104
+ lg: { paddingHorizontal: 32, paddingVertical: 20 }
104
105
  };
105
106
  var labelSizeStyles = {
106
- sm: { fontSize: 14 },
107
- md: { fontSize: 16 },
107
+ sm: { fontSize: 15 },
108
+ md: { fontSize: 17 },
108
109
  lg: { fontSize: 18 }
109
110
  };
110
111
  function Button({
@@ -171,12 +172,12 @@ function Button({
171
172
  onPressOut: handlePressOut,
172
173
  ...props
173
174
  },
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))
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, typeof icon === "function" ? icon({ label, size, variant }) : 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, typeof icon === "function" ? icon({ label, size, variant }) : icon))
175
176
  ));
176
177
  }
177
178
  var styles = reactNative.StyleSheet.create({
178
179
  base: {
179
- borderRadius: 8,
180
+ borderRadius: 999,
180
181
  alignItems: "center",
181
182
  justifyContent: "center",
182
183
  flexDirection: "row"
@@ -195,12 +196,12 @@ var styles = reactNative.StyleSheet.create({
195
196
  }
196
197
  });
197
198
  var variantStyles = {
198
- h1: { fontSize: 32, fontWeight: "700", lineHeight: 44 },
199
- h2: { fontSize: 24, fontWeight: "700", lineHeight: 32 },
200
- h3: { fontSize: 20, fontWeight: "600", lineHeight: 28 },
201
- body: { fontSize: 16, fontWeight: "400", lineHeight: 24 },
202
- caption: { fontSize: 12, fontWeight: "400", lineHeight: 18 },
203
- label: { fontSize: 14, fontWeight: "500", lineHeight: 20 }
199
+ h1: { fontSize: 40, fontWeight: "700", lineHeight: 52 },
200
+ h2: { fontSize: 28, fontWeight: "700", lineHeight: 36 },
201
+ h3: { fontSize: 22, fontWeight: "600", lineHeight: 30 },
202
+ body: { fontSize: 17, fontWeight: "400", lineHeight: 26 },
203
+ caption: { fontSize: 13, fontWeight: "400", lineHeight: 20 },
204
+ label: { fontSize: 15, fontWeight: "500", lineHeight: 22 }
204
205
  };
205
206
  function Text2({ variant = "body", color, style, children, ...props }) {
206
207
  const { colors } = useTheme();
@@ -246,22 +247,22 @@ function Input({ label, error, hint, containerStyle, style, onFocus, onBlur, ...
246
247
  }
247
248
  var styles2 = reactNative.StyleSheet.create({
248
249
  container: {
249
- gap: 4
250
+ gap: 6
250
251
  },
251
252
  label: {
252
- fontSize: 14,
253
+ fontSize: 15,
253
254
  fontWeight: "500",
254
- marginBottom: 4
255
+ marginBottom: 6
255
256
  },
256
257
  input: {
257
258
  borderWidth: 1.5,
258
- borderRadius: 8,
259
- paddingHorizontal: 16,
260
- paddingVertical: 14,
261
- fontSize: 16
259
+ borderRadius: 14,
260
+ paddingHorizontal: 20,
261
+ paddingVertical: 16,
262
+ fontSize: 17
262
263
  },
263
264
  helperText: {
264
- fontSize: 12
265
+ fontSize: 13
265
266
  }
266
267
  });
267
268
  function Badge({ label, variant = "default", style }) {
@@ -282,13 +283,13 @@ function Badge({ label, variant = "default", style }) {
282
283
  }
283
284
  var styles3 = reactNative.StyleSheet.create({
284
285
  container: {
285
- borderRadius: 6,
286
- paddingHorizontal: 8,
287
- paddingVertical: 2,
286
+ borderRadius: 8,
287
+ paddingHorizontal: 10,
288
+ paddingVertical: 4,
288
289
  alignSelf: "flex-start"
289
290
  },
290
291
  label: {
291
- fontSize: 12,
292
+ fontSize: 13,
292
293
  fontWeight: "500"
293
294
  }
294
295
  });
@@ -321,7 +322,7 @@ function CardFooter({ children, style }) {
321
322
  }
322
323
  var styles4 = reactNative.StyleSheet.create({
323
324
  card: {
324
- borderRadius: 12,
325
+ borderRadius: 20,
325
326
  borderWidth: 1,
326
327
  shadowColor: "#000",
327
328
  shadowOffset: { width: 0, height: 1 },
@@ -330,24 +331,24 @@ var styles4 = reactNative.StyleSheet.create({
330
331
  elevation: 1
331
332
  },
332
333
  header: {
333
- padding: 24,
334
+ padding: 28,
334
335
  paddingBottom: 0,
335
- gap: 6
336
+ gap: 8
336
337
  },
337
338
  title: {
338
- fontSize: 18,
339
+ fontSize: 20,
339
340
  fontWeight: "600",
340
- lineHeight: 24
341
+ lineHeight: 28
341
342
  },
342
343
  description: {
343
- fontSize: 14,
344
- lineHeight: 20
344
+ fontSize: 15,
345
+ lineHeight: 22
345
346
  },
346
347
  content: {
347
- padding: 24
348
+ padding: 28
348
349
  },
349
350
  footer: {
350
- padding: 24,
351
+ padding: 28,
351
352
  paddingTop: 0,
352
353
  flexDirection: "row",
353
354
  alignItems: "center"
@@ -432,16 +433,16 @@ var styles6 = reactNative.StyleSheet.create({
432
433
  }
433
434
  });
434
435
  var sizeMap2 = {
435
- sm: 24,
436
- md: 32,
437
- lg: 48,
438
- xl: 64
436
+ sm: 28,
437
+ md: 40,
438
+ lg: 56,
439
+ xl: 72
439
440
  };
440
441
  var fontSizeMap = {
441
- sm: 10,
442
- md: 13,
443
- lg: 18,
444
- xl: 24
442
+ sm: 12,
443
+ md: 16,
444
+ lg: 22,
445
+ xl: 28
445
446
  };
446
447
  function Avatar({ src, fallback, size = "md", style }) {
447
448
  const { colors } = useTheme();
@@ -484,7 +485,7 @@ function Alert({ title, description, variant = "default", icon, style }) {
484
485
  const borderColor = variant === "destructive" ? colors.destructive : colors.border;
485
486
  const titleColor = variant === "destructive" ? colors.destructive : colors.foreground;
486
487
  const descColor = variant === "destructive" ? colors.destructive : colors.mutedForeground;
487
- return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles8.container, { backgroundColor: colors.card, borderColor }, style] }, icon ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles8.icon }, icon) : null, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles8.content }, title ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles8.title, { color: titleColor }] }, title) : null, description ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles8.description, { color: descColor }] }, description) : null));
488
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles8.container, { backgroundColor: colors.card, borderColor }, style] }, icon ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles8.icon }, icon) : /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles8.icon }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles8.defaultIcon, { color: titleColor }] }, variant === "destructive" ? "\u26A0" : "\u2139")), /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles8.content }, title ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles8.title, { color: titleColor }] }, title) : null, description ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles8.description, { color: descColor }] }, description) : null));
488
489
  }
489
490
  var styles8 = reactNative.StyleSheet.create({
490
491
  container: {
@@ -509,6 +510,10 @@ var styles8 = reactNative.StyleSheet.create({
509
510
  description: {
510
511
  fontSize: 14,
511
512
  lineHeight: 20
513
+ },
514
+ defaultIcon: {
515
+ fontSize: 18,
516
+ fontWeight: "700"
512
517
  }
513
518
  });
514
519
  function Progress({ value = 0, max = 100, style }) {
@@ -616,7 +621,7 @@ function Textarea({
616
621
  borderColor: error ? colors.destructive : focused ? colors.ring : colors.border,
617
622
  color: colors.foreground,
618
623
  backgroundColor: colors.background,
619
- minHeight: rows * 28
624
+ minHeight: rows * 30
620
625
  },
621
626
  style
622
627
  ],
@@ -636,22 +641,22 @@ function Textarea({
636
641
  }
637
642
  var styles11 = reactNative.StyleSheet.create({
638
643
  container: {
639
- gap: 4
644
+ gap: 6
640
645
  },
641
646
  label: {
642
- fontSize: 14,
647
+ fontSize: 15,
643
648
  fontWeight: "500",
644
- marginBottom: 4
649
+ marginBottom: 6
645
650
  },
646
651
  input: {
647
652
  borderWidth: 1.5,
648
- borderRadius: 8,
649
- paddingHorizontal: 16,
650
- paddingVertical: 14,
651
- fontSize: 16
653
+ borderRadius: 14,
654
+ paddingHorizontal: 20,
655
+ paddingVertical: 16,
656
+ fontSize: 17
652
657
  },
653
658
  helperText: {
654
- fontSize: 12
659
+ fontSize: 13
655
660
  }
656
661
  });
657
662
  function Checkbox({
@@ -711,31 +716,31 @@ var styles12 = reactNative.StyleSheet.create({
711
716
  row: {
712
717
  flexDirection: "row",
713
718
  alignItems: "center",
714
- gap: 10
719
+ gap: 12
715
720
  },
716
721
  box: {
717
- width: 24,
718
- height: 24,
719
- borderRadius: 6,
722
+ width: 28,
723
+ height: 28,
724
+ borderRadius: 8,
720
725
  borderWidth: 1.5,
721
726
  alignItems: "center",
722
727
  justifyContent: "center"
723
728
  },
724
729
  checkmark: {
725
- width: 13,
726
- height: 8,
730
+ width: 15,
731
+ height: 9,
727
732
  borderLeftWidth: 2,
728
733
  borderBottomWidth: 2,
729
734
  transform: [{ rotate: "-45deg" }, { translateY: -1 }]
730
735
  },
731
736
  label: {
732
- fontSize: 14,
733
- lineHeight: 20
737
+ fontSize: 15,
738
+ lineHeight: 22
734
739
  }
735
740
  });
736
- var TRACK_WIDTH = 56;
737
- var TRACK_HEIGHT = 32;
738
- var THUMB_SIZE = 24;
741
+ var TRACK_WIDTH = 60;
742
+ var TRACK_HEIGHT = 36;
743
+ var THUMB_SIZE = 28;
739
744
  var THUMB_OFFSET = 4;
740
745
  var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
741
746
  function Switch({ checked = false, onCheckedChange, disabled, style }) {
@@ -788,11 +793,14 @@ var styles13 = reactNative.StyleSheet.create({
788
793
  track: {
789
794
  width: TRACK_WIDTH,
790
795
  height: TRACK_HEIGHT,
791
- borderRadius: TRACK_HEIGHT / 2,
792
- justifyContent: "center",
793
- paddingHorizontal: THUMB_OFFSET
796
+ borderRadius: TRACK_HEIGHT / 2
797
+ // No justifyContent/alignItems — thumb uses absolute positioning
798
+ // so the track's flex layout doesn't interfere with translateX animation
794
799
  },
795
800
  thumb: {
801
+ position: "absolute",
802
+ top: THUMB_OFFSET,
803
+ left: THUMB_OFFSET,
796
804
  width: THUMB_SIZE,
797
805
  height: THUMB_SIZE,
798
806
  borderRadius: THUMB_SIZE / 2,
@@ -815,12 +823,22 @@ function Toggle({
815
823
  size = "md",
816
824
  label,
817
825
  icon,
826
+ activeIcon,
818
827
  disabled,
819
828
  style,
820
829
  ...props
821
830
  }) {
822
831
  const { colors } = useTheme();
823
832
  const scale = React23.useRef(new reactNative.Animated.Value(1)).current;
833
+ const pressAnim = React23.useRef(new reactNative.Animated.Value(pressed ? 1 : 0)).current;
834
+ React23.useEffect(() => {
835
+ reactNative.Animated.timing(pressAnim, {
836
+ toValue: pressed ? 1 : 0,
837
+ duration: 150,
838
+ easing: reactNative.Easing.out(reactNative.Easing.ease),
839
+ useNativeDriver: false
840
+ }).start();
841
+ }, [pressed, pressAnim]);
824
842
  const handlePressIn = () => {
825
843
  if (disabled) return;
826
844
  reactNative.Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
@@ -828,34 +846,71 @@ function Toggle({
828
846
  const handlePressOut = () => {
829
847
  reactNative.Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
830
848
  };
831
- const containerStyle = pressed ? { backgroundColor: colors.accent } : variant === "outline" ? { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border } : { backgroundColor: "transparent" };
832
- const textColor = pressed ? colors.accentForeground : colors.foreground;
849
+ const borderColor = pressAnim.interpolate({
850
+ inputRange: [0, 1],
851
+ outputRange: [variant === "outline" ? colors.border : "transparent", colors.primary]
852
+ });
853
+ const backgroundColor = pressAnim.interpolate({
854
+ inputRange: [0, 1],
855
+ outputRange: ["transparent", colors.accent]
856
+ });
857
+ const textColor = pressAnim.interpolate({
858
+ inputRange: [0, 1],
859
+ outputRange: [colors.foreground, colors.primary]
860
+ });
861
+ const LeftIcon = () => {
862
+ const renderProp = (prop) => {
863
+ if (!prop) return null;
864
+ if (typeof prop === "function") return prop(pressed);
865
+ return prop;
866
+ };
867
+ if (!pressed) return renderProp(icon);
868
+ const active = renderProp(activeIcon);
869
+ if (active) return /* @__PURE__ */ React23__default.default.createElement(React23__default.default.Fragment, null, active);
870
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles14.checkContainer, { borderColor: colors.primary }] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles14.checkMark, { color: colors.primary }] }, "\u2713"));
871
+ };
833
872
  return /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
834
- reactNative.TouchableOpacity,
873
+ reactNative.Animated.View,
835
874
  {
836
- style: [styles14.base, containerStyle, sizeStyles[size], disabled && styles14.disabled, style],
837
- onPress: () => {
838
- Haptics11__namespace.selectionAsync();
839
- onPressedChange?.(!pressed);
840
- },
841
- onPressIn: handlePressIn,
842
- onPressOut: handlePressOut,
843
- disabled,
844
- activeOpacity: 1,
845
- touchSoundDisabled: true,
846
- ...props
875
+ style: [
876
+ styles14.base,
877
+ sizeStyles[size],
878
+ { borderColor, backgroundColor, borderWidth: 2 },
879
+ disabled && styles14.disabled,
880
+ style
881
+ ]
847
882
  },
848
- icon,
849
- label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: textColor }] }, label) : null
883
+ /* @__PURE__ */ React23__default.default.createElement(
884
+ reactNative.TouchableOpacity,
885
+ {
886
+ style: styles14.touchable,
887
+ onPress: () => {
888
+ Haptics11__namespace.selectionAsync();
889
+ onPressedChange?.(!pressed);
890
+ },
891
+ onPressIn: handlePressIn,
892
+ onPressOut: handlePressOut,
893
+ disabled,
894
+ activeOpacity: 1,
895
+ touchSoundDisabled: true,
896
+ ...props
897
+ },
898
+ /* @__PURE__ */ React23__default.default.createElement(LeftIcon, null),
899
+ label ? /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.Text, { style: [styles14.label, { color: textColor }] }, label) : null
900
+ )
850
901
  ));
851
902
  }
852
903
  var styles14 = reactNative.StyleSheet.create({
853
904
  base: {
854
905
  borderRadius: 8,
906
+ overflow: "hidden"
907
+ },
908
+ touchable: {
855
909
  flexDirection: "row",
856
910
  alignItems: "center",
857
911
  justifyContent: "center",
858
- gap: 8
912
+ gap: 8,
913
+ flex: 1
859
914
  },
860
915
  disabled: {
861
916
  opacity: 0.45
@@ -863,6 +918,18 @@ var styles14 = reactNative.StyleSheet.create({
863
918
  label: {
864
919
  fontSize: 14,
865
920
  fontWeight: "500"
921
+ },
922
+ checkContainer: {
923
+ width: 24,
924
+ height: 24,
925
+ borderRadius: 12,
926
+ borderWidth: 2,
927
+ alignItems: "center",
928
+ justifyContent: "center"
929
+ },
930
+ checkMark: {
931
+ fontSize: 14,
932
+ fontWeight: "700"
866
933
  }
867
934
  });
868
935
  function RadioItem({
@@ -993,7 +1060,7 @@ function TabTrigger({
993
1060
  activeOpacity: 1,
994
1061
  touchSoundDisabled: true
995
1062
  },
996
- /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(
1063
+ /* @__PURE__ */ React23__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles16.triggerInner }, tab.icon ? /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: styles16.triggerIcon }, typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon) : null, /* @__PURE__ */ React23__default.default.createElement(
997
1064
  reactNative.Text,
998
1065
  {
999
1066
  style: [
@@ -1003,7 +1070,7 @@ function TabTrigger({
1003
1070
  ]
1004
1071
  },
1005
1072
  tab.label
1006
- ))
1073
+ )))
1007
1074
  );
1008
1075
  }
1009
1076
  function Tabs({ tabs, value, onValueChange, children, style }) {
@@ -1059,7 +1126,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
1059
1126
  bottom: 4,
1060
1127
  left: pillX,
1061
1128
  width: pillWidth,
1062
- borderRadius: 6,
1129
+ borderRadius: 8,
1063
1130
  shadowColor: "#000",
1064
1131
  shadowOffset: { width: 0, height: 1 },
1065
1132
  shadowOpacity: 0.1,
@@ -1093,22 +1160,33 @@ function TabsContent({ value, activeValue, children, style }) {
1093
1160
  var styles16 = reactNative.StyleSheet.create({
1094
1161
  list: {
1095
1162
  flexDirection: "row",
1096
- borderRadius: 8,
1163
+ borderRadius: 12,
1097
1164
  padding: 4,
1098
1165
  gap: 4
1099
1166
  },
1100
1167
  pill: {},
1101
1168
  trigger: {
1102
1169
  flex: 1,
1103
- paddingVertical: 8,
1104
- paddingHorizontal: 12,
1105
- borderRadius: 6,
1170
+ paddingVertical: 12,
1171
+ paddingHorizontal: 16,
1172
+ borderRadius: 8,
1106
1173
  alignItems: "center",
1107
1174
  justifyContent: "center",
1108
1175
  zIndex: 1
1109
1176
  },
1177
+ triggerInner: {
1178
+ flexDirection: "row",
1179
+ alignItems: "center",
1180
+ justifyContent: "center",
1181
+ gap: 8
1182
+ },
1183
+ triggerIcon: {
1184
+ marginRight: 6,
1185
+ alignItems: "center",
1186
+ justifyContent: "center"
1187
+ },
1110
1188
  triggerLabel: {
1111
- fontSize: 14,
1189
+ fontSize: 15,
1112
1190
  fontWeight: "400"
1113
1191
  },
1114
1192
  activeTriggerLabel: {
@@ -1207,19 +1285,19 @@ var styles17 = reactNative.StyleSheet.create({
1207
1285
  flexDirection: "row",
1208
1286
  justifyContent: "space-between",
1209
1287
  alignItems: "center",
1210
- paddingVertical: 16
1288
+ paddingVertical: 20
1211
1289
  },
1212
1290
  triggerText: {
1213
- fontSize: 15,
1291
+ fontSize: 17,
1214
1292
  fontWeight: "500",
1215
1293
  flex: 1
1216
1294
  },
1217
1295
  chevron: {
1218
- fontSize: 16,
1296
+ fontSize: 18,
1219
1297
  marginLeft: 8
1220
1298
  },
1221
1299
  content: {
1222
- paddingBottom: 16,
1300
+ paddingBottom: 20,
1223
1301
  position: "absolute",
1224
1302
  width: "100%"
1225
1303
  }
@@ -1528,10 +1606,10 @@ function Select({
1528
1606
  }
1529
1607
  var styles20 = reactNative.StyleSheet.create({
1530
1608
  container: {
1531
- gap: 4
1609
+ gap: 6
1532
1610
  },
1533
1611
  label: {
1534
- fontSize: 14,
1612
+ fontSize: 15,
1535
1613
  fontWeight: "500",
1536
1614
  marginBottom: 2
1537
1615
  },
@@ -1540,24 +1618,24 @@ var styles20 = reactNative.StyleSheet.create({
1540
1618
  alignItems: "center",
1541
1619
  justifyContent: "space-between",
1542
1620
  borderWidth: 1.5,
1543
- borderRadius: 8,
1544
- paddingHorizontal: 16,
1545
- paddingVertical: 14
1621
+ borderRadius: 14,
1622
+ paddingHorizontal: 20,
1623
+ paddingVertical: 16
1546
1624
  },
1547
1625
  triggerText: {
1548
- fontSize: 16,
1626
+ fontSize: 17,
1549
1627
  flex: 1
1550
1628
  },
1551
1629
  chevron: {
1552
- fontSize: 14,
1630
+ fontSize: 16,
1553
1631
  marginLeft: 8
1554
1632
  },
1555
1633
  helperText: {
1556
- fontSize: 12
1634
+ fontSize: 13
1557
1635
  },
1558
1636
  sheetBackground: {
1559
- borderTopLeftRadius: 16,
1560
- borderTopRightRadius: 16
1637
+ borderTopLeftRadius: 24,
1638
+ borderTopRightRadius: 24
1561
1639
  },
1562
1640
  sheetHandle: {
1563
1641
  width: 36,
@@ -1565,32 +1643,32 @@ var styles20 = reactNative.StyleSheet.create({
1565
1643
  borderRadius: 2
1566
1644
  },
1567
1645
  sheetContent: {
1568
- paddingHorizontal: 16,
1569
- paddingBottom: 32
1646
+ paddingHorizontal: 20,
1647
+ paddingBottom: 36
1570
1648
  },
1571
1649
  sheetTitle: {
1572
- fontSize: 16,
1650
+ fontSize: 17,
1573
1651
  fontWeight: "600",
1574
- paddingVertical: 12,
1652
+ paddingVertical: 16,
1575
1653
  paddingHorizontal: 4
1576
1654
  },
1577
1655
  option: {
1578
1656
  flexDirection: "row",
1579
1657
  alignItems: "center",
1580
1658
  justifyContent: "space-between",
1581
- paddingHorizontal: 12,
1582
- paddingVertical: 14,
1583
- borderRadius: 8
1659
+ paddingHorizontal: 16,
1660
+ paddingVertical: 16,
1661
+ borderRadius: 12
1584
1662
  },
1585
1663
  optionText: {
1586
- fontSize: 15,
1664
+ fontSize: 17,
1587
1665
  flex: 1
1588
1666
  },
1589
1667
  disabledOption: {
1590
1668
  opacity: 0.45
1591
1669
  },
1592
1670
  checkmark: {
1593
- fontSize: 14,
1671
+ fontSize: 16,
1594
1672
  fontWeight: "600",
1595
1673
  marginLeft: 8
1596
1674
  }
@@ -1617,7 +1695,7 @@ function ToastNotification({ item, onDismiss }) {
1617
1695
  const timer = setTimeout(() => {
1618
1696
  translateY.value = ReanimatedAnimated.withTiming(-80, { duration: 200 });
1619
1697
  opacity.value = ReanimatedAnimated.withTiming(0, { duration: 200 }, (done) => {
1620
- if (done) ReanimatedAnimated.runOnJS(onDismiss)();
1698
+ if (done) reactNativeWorklets.scheduleOnRN(onDismiss);
1621
1699
  });
1622
1700
  }, item.duration ?? 3e3);
1623
1701
  return () => clearTimeout(timer);
@@ -1629,7 +1707,7 @@ function ToastNotification({ item, onDismiss }) {
1629
1707
  if (shouldDismiss) {
1630
1708
  const direction = translateX.value > 0 ? 1 : -1;
1631
1709
  translateX.value = ReanimatedAnimated.withTiming(direction * 500, { duration: 200 }, (done) => {
1632
- if (done) ReanimatedAnimated.runOnJS(onDismiss)();
1710
+ if (done) reactNativeWorklets.scheduleOnRN(onDismiss);
1633
1711
  });
1634
1712
  opacity.value = ReanimatedAnimated.withTiming(0, { duration: 150 });
1635
1713
  } else {
@@ -1650,7 +1728,8 @@ function ToastNotification({ item, onDismiss }) {
1650
1728
  destructive: colors.destructiveForeground,
1651
1729
  success: colors.successForeground
1652
1730
  }[item.variant ?? "default"];
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"))));
1731
+ const leftIcon = item.icon ?? /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles21.defaultIcon, { color: textColor }] }, item.variant === "success" ? "\u2713" : item.variant === "destructive" ? "\u2716" : "\u2139");
1732
+ 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.leftIconContainer }, leftIcon), /* @__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"))));
1654
1733
  }
1655
1734
  function ToastProvider({ children }) {
1656
1735
  const [toasts, setToasts] = React23.useState([]);
@@ -1682,9 +1761,9 @@ var styles21 = reactNative.StyleSheet.create({
1682
1761
  toast: {
1683
1762
  flexDirection: "row",
1684
1763
  alignItems: "center",
1685
- borderRadius: 12,
1686
- paddingHorizontal: 16,
1687
- paddingVertical: 12,
1764
+ borderRadius: 16,
1765
+ paddingHorizontal: 20,
1766
+ paddingVertical: 14,
1688
1767
  shadowColor: "#000",
1689
1768
  shadowOffset: { width: 0, height: 4 },
1690
1769
  shadowOpacity: 0.15,
@@ -1695,21 +1774,140 @@ var styles21 = reactNative.StyleSheet.create({
1695
1774
  flex: 1,
1696
1775
  gap: 4
1697
1776
  },
1777
+ leftIconContainer: {
1778
+ width: 36,
1779
+ alignItems: "center",
1780
+ justifyContent: "center",
1781
+ marginRight: 8
1782
+ },
1783
+ defaultIcon: {
1784
+ fontSize: 22,
1785
+ fontWeight: "700"
1786
+ },
1698
1787
  toastTitle: {
1699
- fontSize: 14,
1788
+ fontSize: 15,
1700
1789
  fontWeight: "600"
1701
1790
  },
1702
1791
  toastDescription: {
1703
- fontSize: 13
1792
+ fontSize: 14
1704
1793
  },
1705
1794
  dismissButton: {
1706
1795
  padding: 12,
1707
1796
  marginLeft: 4
1708
1797
  },
1709
1798
  dismissIcon: {
1710
- fontSize: 12
1799
+ fontSize: 14
1800
+ }
1801
+ });
1802
+ function formatCurrency(raw, separator) {
1803
+ const digits = raw.replace(/\D/g, "");
1804
+ if (!digits) return "";
1805
+ return digits.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
1806
+ }
1807
+ function CurrencyInput({
1808
+ value,
1809
+ onChangeText,
1810
+ onChangeValue,
1811
+ prefix = "$",
1812
+ thousandsSeparator = ".",
1813
+ label,
1814
+ error,
1815
+ hint,
1816
+ placeholder,
1817
+ editable,
1818
+ containerStyle
1819
+ }) {
1820
+ const handleChange = (text) => {
1821
+ const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text;
1822
+ const formatted = formatCurrency(withoutPrefix, thousandsSeparator);
1823
+ const display = formatted ? `${prefix}${formatted}` : "";
1824
+ onChangeText?.(display);
1825
+ const separatorRegex = new RegExp(`\\${thousandsSeparator}`, "g");
1826
+ const raw = parseFloat(formatted.replace(separatorRegex, "") || "0");
1827
+ onChangeValue?.(isNaN(raw) ? 0 : raw);
1828
+ };
1829
+ return /* @__PURE__ */ React23__default.default.createElement(
1830
+ Input,
1831
+ {
1832
+ value,
1833
+ onChangeText: handleChange,
1834
+ keyboardType: "numeric",
1835
+ label,
1836
+ error,
1837
+ hint,
1838
+ placeholder: placeholder ?? `${prefix}0`,
1839
+ editable,
1840
+ containerStyle
1841
+ }
1842
+ );
1843
+ }
1844
+ function formatValue(value, prefix, showDecimals) {
1845
+ const num = typeof value === "string" ? parseFloat(value.replace(/[^0-9.-]/g, "")) : value;
1846
+ if (isNaN(num)) return `${prefix}0`;
1847
+ const abs = Math.abs(num);
1848
+ const sign = num < 0 ? "-" : "";
1849
+ const intPart = Math.floor(abs).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
1850
+ if (showDecimals) {
1851
+ const decStr = (abs % 1).toFixed(2).slice(2);
1852
+ return `${sign}${prefix}${intPart},${decStr}`;
1853
+ }
1854
+ return `${sign}${prefix}${intPart}`;
1855
+ }
1856
+ function CurrencyDisplay({ value, prefix = "$", showDecimals = false, style }) {
1857
+ const { colors } = useTheme();
1858
+ const formatted = formatValue(value, prefix, showDecimals);
1859
+ return /* @__PURE__ */ React23__default.default.createElement(reactNative.View, { style: [styles22.container, style] }, /* @__PURE__ */ React23__default.default.createElement(reactNative.Text, { style: [styles22.amount, { color: colors.foreground }], allowFontScaling: true }, formatted));
1860
+ }
1861
+ var styles22 = reactNative.StyleSheet.create({
1862
+ container: {},
1863
+ amount: {
1864
+ fontSize: 56,
1865
+ fontWeight: "700"
1711
1866
  }
1712
1867
  });
1868
+ function formatCurrency2(raw, separator) {
1869
+ const digits = raw.replace(/\D/g, "");
1870
+ if (!digits) return "";
1871
+ return digits.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
1872
+ }
1873
+ function CurrencyInputLarge({
1874
+ value,
1875
+ onChangeText,
1876
+ onChangeValue,
1877
+ prefix = "$",
1878
+ thousandsSeparator = ".",
1879
+ label,
1880
+ error,
1881
+ hint,
1882
+ placeholder,
1883
+ editable,
1884
+ containerStyle
1885
+ }) {
1886
+ const handleChange = (text) => {
1887
+ const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text;
1888
+ const formatted = formatCurrency2(withoutPrefix, thousandsSeparator);
1889
+ const display = formatted ? `${prefix}${formatted}` : "";
1890
+ onChangeText?.(display);
1891
+ const separatorRegex = new RegExp(`\\${thousandsSeparator}`, "g");
1892
+ const raw = parseFloat(formatted.replace(separatorRegex, "") || "0");
1893
+ onChangeValue?.(isNaN(raw) ? 0 : raw);
1894
+ };
1895
+ return /* @__PURE__ */ React23__default.default.createElement(
1896
+ Input,
1897
+ {
1898
+ value,
1899
+ onChangeText: handleChange,
1900
+ keyboardType: "numeric",
1901
+ label,
1902
+ error,
1903
+ hint,
1904
+ placeholder: placeholder ?? `${prefix}0`,
1905
+ editable,
1906
+ containerStyle,
1907
+ style: { fontSize: 36 }
1908
+ }
1909
+ );
1910
+ }
1713
1911
 
1714
1912
  Object.defineProperty(exports, "BottomSheetModalProvider", {
1715
1913
  enumerable: true,
@@ -1727,6 +1925,9 @@ exports.CardFooter = CardFooter;
1727
1925
  exports.CardHeader = CardHeader;
1728
1926
  exports.CardTitle = CardTitle;
1729
1927
  exports.Checkbox = Checkbox;
1928
+ exports.CurrencyDisplay = CurrencyDisplay;
1929
+ exports.CurrencyInput = CurrencyInput;
1930
+ exports.CurrencyInputLarge = CurrencyInputLarge;
1730
1931
  exports.EmptyState = EmptyState;
1731
1932
  exports.Input = Input;
1732
1933
  exports.Progress = Progress;