@retray-dev/ui-kit 9.2.0 → 9.3.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/fonts.mjs ADDED
@@ -0,0 +1,37 @@
1
+ import { __require } from './chunk-Y6FXYEAI.mjs';
2
+
3
+ // src/fonts.ts
4
+ var SohneFonts = {
5
+ // Sohne base
6
+ "Sohne-ExtraLight": __require("../src/assets/fonts/Sohne-ExtraLight.otf"),
7
+ "Sohne-ExtraLightItalic": __require("../src/assets/fonts/Sohne-ExtraLightItalic.otf"),
8
+ "Sohne-Light": __require("../src/assets/fonts/Sohne-Light.otf"),
9
+ "Sohne-LightItalic": __require("../src/assets/fonts/Sohne-LightItalic.otf"),
10
+ "Sohne-Regular": __require("../src/assets/fonts/Sohne-Regular.otf"),
11
+ "Sohne-Italic": __require("../src/assets/fonts/Sohne-Italic.otf"),
12
+ "Sohne-Medium": __require("../src/assets/fonts/Sohne-Medium.otf"),
13
+ "Sohne-MediumItalic": __require("../src/assets/fonts/Sohne-MediumItalic.otf"),
14
+ "Sohne-SemiBold": __require("../src/assets/fonts/Sohne-SemiBold.otf"),
15
+ "Sohne-SemiBoldItalic": __require("../src/assets/fonts/Sohne-SemiBoldItalic.otf"),
16
+ "Sohne-Bold": __require("../src/assets/fonts/Sohne-Bold.otf"),
17
+ "Sohne-BoldItalic": __require("../src/assets/fonts/Sohne-BoldItalic.otf"),
18
+ "Sohne-ExtraBold": __require("../src/assets/fonts/Sohne-ExtraBold.otf"),
19
+ "Sohne-ExtraBoldItalic": __require("../src/assets/fonts/Sohne-ExtraBoldItalic.otf"),
20
+ // SohneMono
21
+ "SohneMono-ExtraLight": __require("../src/assets/fonts/SohneMono-ExtraLight.otf"),
22
+ "SohneMono-ExtraLightItalic": __require("../src/assets/fonts/SohneMono-ExtraLightItalic.otf"),
23
+ "SohneMono-Light": __require("../src/assets/fonts/SohneMono-Light.otf"),
24
+ "SohneMono-LightItalic": __require("../src/assets/fonts/SohneMono-LightItalic.otf"),
25
+ "SohneMono-Regular": __require("../src/assets/fonts/SohneMono-Regular.otf"),
26
+ "SohneMono-Italic": __require("../src/assets/fonts/SohneMono-Italic.otf"),
27
+ "SohneMono-Medium": __require("../src/assets/fonts/SohneMono-Medium.otf"),
28
+ "SohneMono-MediumItalic": __require("../src/assets/fonts/SohneMono-MediumItalic.otf"),
29
+ "SohneMono-SemiBold": __require("../src/assets/fonts/SohneMono-SemiBold.otf"),
30
+ "SohneMono-SemiBoldItalic": __require("../src/assets/fonts/SohneMono-SemiBoldItalic.otf"),
31
+ "SohneMono-Bold": __require("../src/assets/fonts/SohneMono-Bold.otf"),
32
+ "SohneMono-BoldItalic": __require("../src/assets/fonts/SohneMono-BoldItalic.otf"),
33
+ "SohneMono-ExtraBold": __require("../src/assets/fonts/SohneMono-ExtraBold.otf"),
34
+ "SohneMono-ExtraBoldItalic": __require("../src/assets/fonts/SohneMono-ExtraBoldItalic.otf")
35
+ };
36
+
37
+ export { SohneFonts };
package/dist/index.js CHANGED
@@ -10,12 +10,12 @@ var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
10
10
  var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
11
11
  var Ionicons = require('@expo/vector-icons/Ionicons');
12
12
  var pressto = require('pressto');
13
- var Animated13 = require('react-native-reanimated');
13
+ var Animated12 = require('react-native-reanimated');
14
14
  var expoFont = require('expo-font');
15
15
  var bottomSheet = require('@gorhom/bottom-sheet');
16
+ var reactNativeEase = require('react-native-ease');
16
17
  var vectorIcons = require('@expo/vector-icons');
17
18
  var expoLinearGradient = require('expo-linear-gradient');
18
- var reactNativeEase = require('react-native-ease');
19
19
  var RNSlider = require('@react-native-community/slider');
20
20
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
21
21
  var picker = require('@react-native-picker/picker');
@@ -31,7 +31,7 @@ var Feather__default = /*#__PURE__*/_interopDefault(Feather);
31
31
  var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
32
32
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
33
33
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
34
- var Animated13__default = /*#__PURE__*/_interopDefault(Animated13);
34
+ var Animated12__default = /*#__PURE__*/_interopDefault(Animated12);
35
35
  var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
36
36
 
37
37
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -611,11 +611,11 @@ var TIMINGS = {
611
611
  };
612
612
  var EASINGS = {
613
613
  /** Material-style ease-out — natural deceleration for state changes. */
614
- standard: Animated13.Easing.bezier(0.2, 0, 0, 1),
614
+ standard: Animated12.Easing.bezier(0.2, 0, 0, 1),
615
615
  /** Strong ease-out for expanding surfaces (Accordion open). */
616
- expand: Animated13.Easing.bezier(0.23, 1, 0.32, 1),
616
+ expand: Animated12.Easing.bezier(0.23, 1, 0.32, 1),
617
617
  /** Quick ease-in for collapsing. */
618
- collapse: Animated13.Easing.in(Animated13.Easing.ease)
618
+ collapse: Animated12.Easing.in(Animated12.Easing.ease)
619
619
  };
620
620
  var COLOR_TRANSITION = {
621
621
  type: "timing",
@@ -1000,24 +1000,11 @@ function TextBase({ variant = "body-md", color, style, children, ...props }) {
1000
1000
  );
1001
1001
  }
1002
1002
  var Text3 = React25__default.default.memo(TextBase);
1003
- function useColorTransition(active, options = {}) {
1004
- const { duration = TIMINGS.state.duration } = options;
1005
- const progress = Animated13.useSharedValue(active ? 1 : 0);
1006
- React25.useEffect(() => {
1007
- progress.value = Animated13.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
1008
- }, [active, duration, progress]);
1009
- return progress;
1010
- }
1011
-
1012
- // src/components/Input/Input.tsx
1013
1003
  var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
1014
1004
  function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, sheetMode = false, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }) {
1015
1005
  const { colors } = useTheme();
1016
1006
  const [focused, setFocused] = React25.useState(false);
1017
1007
  const [showPassword, setShowPassword] = React25.useState(false);
1018
- const focusProgress = useColorTransition(focused, {
1019
- duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
1020
- });
1021
1008
  const isDisabled = disabled || editable === false;
1022
1009
  const isPassword = type === "password";
1023
1010
  const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
@@ -1033,20 +1020,19 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1033
1020
  },
1034
1021
  /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
1035
1022
  ) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
1036
- const borderAnimStyle = Animated13.useAnimatedStyle(() => ({
1037
- borderColor: error ? colors.destructive : Animated13.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
1038
- borderWidth: error ? 2 : Animated13.interpolate(focusProgress.value, [0, 1], [1, 2])
1039
- }));
1023
+ const borderColor = error ? colors.destructive : focused ? colors.primary : colors.border;
1040
1024
  return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
1041
- Animated13__default.default.View,
1025
+ reactNativeEase.EaseView,
1042
1026
  {
1043
1027
  style: [
1044
1028
  styles4.inputWrapper,
1045
1029
  { backgroundColor: isDisabled ? colors.surface : colors.background },
1030
+ error && styles4.inputWrapperError,
1046
1031
  inputWrapperStyle
1047
- ]
1032
+ ],
1033
+ animate: { borderColor },
1034
+ transition: COLOR_TRANSITION
1048
1035
  },
1049
- /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles4.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
1050
1036
  effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles4.prefixContainer }, effectivePrefix) : null,
1051
1037
  sheetMode ? /* @__PURE__ */ React25__default.default.createElement(
1052
1038
  bottomSheet.BottomSheetTextInput,
@@ -1122,16 +1108,14 @@ var styles4 = reactNative.StyleSheet.create({
1122
1108
  inputWrapper: {
1123
1109
  flexDirection: "row",
1124
1110
  alignItems: "center",
1125
- // Border lives on borderOverlay (absolute) so its 1px→2px focus change
1126
- // never resizes this box. Wrapper itself carries no border.
1127
1111
  borderRadius: 8,
1112
+ borderWidth: 1,
1128
1113
  paddingHorizontal: s(14),
1129
1114
  paddingVertical: vs(11),
1130
1115
  minHeight: 48
1131
1116
  },
1132
- borderOverlay: {
1133
- ...reactNative.StyleSheet.absoluteFillObject,
1134
- borderRadius: 8
1117
+ inputWrapperError: {
1118
+ borderWidth: 2
1135
1119
  },
1136
1120
  input: {
1137
1121
  fontFamily: "Sohne-Regular",
@@ -1421,17 +1405,17 @@ function Skeleton({
1421
1405
  style
1422
1406
  }) {
1423
1407
  const { colors, colorScheme } = useTheme();
1424
- const shimmer = Animated13.useSharedValue(0);
1408
+ const shimmer = Animated12.useSharedValue(0);
1425
1409
  const [containerWidth, setContainerWidth] = React25.useState(300);
1426
1410
  const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
1427
1411
  React25.useEffect(() => {
1428
- shimmer.value = Animated13.withRepeat(
1429
- Animated13.withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Animated13.Easing.linear }),
1412
+ shimmer.value = Animated12.withRepeat(
1413
+ Animated12.withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Animated12.Easing.linear }),
1430
1414
  -1,
1431
1415
  false
1432
1416
  );
1433
1417
  }, [shimmer]);
1434
- const shimmerStyle = Animated13.useAnimatedStyle(() => ({
1418
+ const shimmerStyle = Animated12.useAnimatedStyle(() => ({
1435
1419
  transform: [{ translateX: -containerWidth + shimmer.value * (containerWidth * 2) }]
1436
1420
  }));
1437
1421
  const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
@@ -1450,7 +1434,7 @@ function Skeleton({
1450
1434
  accessibilityLabel: "Loading",
1451
1435
  accessibilityState: { busy: true }
1452
1436
  },
1453
- /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React25__default.default.createElement(
1437
+ /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React25__default.default.createElement(
1454
1438
  expoLinearGradient.LinearGradient,
1455
1439
  {
1456
1440
  colors: ["transparent", shimmerHighlight, "transparent"],
@@ -1702,12 +1686,12 @@ function Progress({ value = 0, max = 100, variant = "default", style, accessibil
1702
1686
  const { colors } = useTheme();
1703
1687
  const percent = Math.min(Math.max(value / max * 100, 0), 100);
1704
1688
  const [trackWidth, setTrackWidth] = React25.useState(0);
1705
- const animatedWidth = Animated13.useSharedValue(0);
1689
+ const animatedWidth = Animated12.useSharedValue(0);
1706
1690
  React25.useEffect(() => {
1707
1691
  if (trackWidth === 0) return;
1708
- animatedWidth.value = Animated13.withSpring(percent / 100 * trackWidth, SPRINGS.glide);
1692
+ animatedWidth.value = Animated12.withSpring(percent / 100 * trackWidth, SPRINGS.glide);
1709
1693
  }, [percent, trackWidth, animatedWidth]);
1710
- const indicatorAnimatedStyle = Animated13.useAnimatedStyle(() => ({
1694
+ const indicatorAnimatedStyle = Animated12.useAnimatedStyle(() => ({
1711
1695
  width: animatedWidth.value
1712
1696
  }));
1713
1697
  const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
@@ -1721,7 +1705,7 @@ function Progress({ value = 0, max = 100, variant = "default", style, accessibil
1721
1705
  accessibilityValue: { min: 0, max: 100, now: Math.round(percent) }
1722
1706
  },
1723
1707
  /* @__PURE__ */ React25__default.default.createElement(
1724
- Animated13__default.default.View,
1708
+ Animated12__default.default.View,
1725
1709
  {
1726
1710
  style: [styles12.indicator, { backgroundColor: indicatorColor }, indicatorAnimatedStyle]
1727
1711
  }
@@ -1829,6 +1813,16 @@ var styles13 = reactNative.StyleSheet.create({
1829
1813
  paddingHorizontal: s(32)
1830
1814
  }
1831
1815
  });
1816
+ function useColorTransition(active, options = {}) {
1817
+ const { duration = TIMINGS.state.duration } = options;
1818
+ const progress = Animated12.useSharedValue(active ? 1 : 0);
1819
+ React25.useEffect(() => {
1820
+ progress.value = Animated12.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
1821
+ }, [active, duration, progress]);
1822
+ return progress;
1823
+ }
1824
+
1825
+ // src/components/Textarea/Textarea.tsx
1832
1826
  var webInputResetStyle2 = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
1833
1827
  function Textarea({
1834
1828
  label,
@@ -1851,19 +1845,19 @@ function Textarea({
1851
1845
  duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
1852
1846
  });
1853
1847
  const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
1854
- const borderAnimStyle = Animated13.useAnimatedStyle(() => ({
1855
- borderColor: error ? colors.destructive : Animated13.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
1856
- borderWidth: error ? 2 : Animated13.interpolate(focusProgress.value, [0, 1], [1, 2])
1848
+ const borderAnimStyle = Animated12.useAnimatedStyle(() => ({
1849
+ borderColor: error ? colors.destructive : Animated12.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
1850
+ borderWidth: error ? 2 : Animated12.interpolate(focusProgress.value, [0, 1], [1, 2])
1857
1851
  }));
1858
1852
  return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
1859
- Animated13__default.default.View,
1853
+ Animated12__default.default.View,
1860
1854
  {
1861
1855
  style: [
1862
1856
  styles14.inputWrapper,
1863
1857
  { backgroundColor: colors.background }
1864
1858
  ]
1865
1859
  },
1866
- /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles14.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
1860
+ /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles14.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
1867
1861
  resolvedPrefixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
1868
1862
  /* @__PURE__ */ React25__default.default.createElement(
1869
1863
  reactNative.TextInput,
@@ -2243,18 +2237,18 @@ function usePressScale({
2243
2237
  pressOutSpring = SPRINGS.pressOut,
2244
2238
  disabled = false
2245
2239
  } = {}) {
2246
- const scale2 = Animated13.useSharedValue(1);
2240
+ const scale2 = Animated12.useSharedValue(1);
2247
2241
  const { hovered, hoverHandlers } = useHover();
2248
2242
  const onPressIn = React25.useCallback(() => {
2249
2243
  if (disabled) return;
2250
- scale2.value = Animated13.withSpring(pressScale, pressInSpring);
2244
+ scale2.value = Animated12.withSpring(pressScale, pressInSpring);
2251
2245
  }, [disabled, pressScale, pressInSpring, scale2]);
2252
2246
  const onPressOut = React25.useCallback(() => {
2253
2247
  if (disabled) return;
2254
- scale2.value = Animated13.withSpring(1, pressOutSpring);
2248
+ scale2.value = Animated12.withSpring(1, pressOutSpring);
2255
2249
  }, [disabled, pressOutSpring, scale2]);
2256
2250
  const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
2257
- const animatedStyle = Animated13.useAnimatedStyle(() => ({
2251
+ const animatedStyle = Animated12.useAnimatedStyle(() => ({
2258
2252
  transform: [
2259
2253
  { scale: scale2.value * (hoverActive ? hoverScale : 1) }
2260
2254
  ]
@@ -2301,7 +2295,7 @@ function RadioItem({
2301
2295
  accessibilityLabel: option.label,
2302
2296
  accessibilityState: { checked: selected, disabled: !!option.disabled }
2303
2297
  },
2304
- /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React25__default.default.createElement(
2298
+ /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React25__default.default.createElement(
2305
2299
  reactNativeEase.EaseView,
2306
2300
  {
2307
2301
  style: styles18.radio,
@@ -2436,15 +2430,15 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2436
2430
  const { colors } = useTheme();
2437
2431
  const active = value ?? internal;
2438
2432
  const tabLayouts = React25.useRef({});
2439
- const pillX = Animated13.useSharedValue(0);
2440
- const pillWidth = Animated13.useSharedValue(0);
2433
+ const pillX = Animated12.useSharedValue(0);
2434
+ const pillWidth = Animated12.useSharedValue(0);
2441
2435
  const initialised = React25.useRef(false);
2442
2436
  const animatePill = React25.useCallback((tabValue, animate) => {
2443
2437
  const layout = tabLayouts.current[tabValue];
2444
2438
  if (!layout) return;
2445
2439
  if (animate) {
2446
- pillX.value = Animated13.withSpring(layout.x, SPRINGS.glide);
2447
- pillWidth.value = Animated13.withSpring(layout.width, SPRINGS.glide);
2440
+ pillX.value = Animated12.withSpring(layout.x, SPRINGS.glide);
2441
+ pillWidth.value = Animated12.withSpring(layout.width, SPRINGS.glide);
2448
2442
  } else {
2449
2443
  pillX.value = layout.x;
2450
2444
  pillWidth.value = layout.width;
@@ -2458,7 +2452,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2458
2452
  if (!value) setInternal(v);
2459
2453
  onValueChange?.(v);
2460
2454
  };
2461
- const pillAnimatedStyle = Animated13.useAnimatedStyle(() => ({
2455
+ const pillAnimatedStyle = Animated12.useAnimatedStyle(() => ({
2462
2456
  transform: [{ translateX: pillX.value }],
2463
2457
  width: pillWidth.value
2464
2458
  }));
@@ -2471,7 +2465,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2471
2465
  accessibilityRole: "tablist"
2472
2466
  },
2473
2467
  variant === "pill" && /* @__PURE__ */ React25__default.default.createElement(
2474
- Animated13__default.default.View,
2468
+ Animated12__default.default.View,
2475
2469
  {
2476
2470
  style: [
2477
2471
  styles19.pill,
@@ -2573,28 +2567,28 @@ function AccordionItemComponent({
2573
2567
  }) {
2574
2568
  const { colors } = useTheme();
2575
2569
  const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
2576
- const isExpanded = Animated13.useSharedValue(isOpen);
2577
- const height = Animated13.useSharedValue(0);
2570
+ const isExpanded = Animated12.useSharedValue(isOpen);
2571
+ const height = Animated12.useSharedValue(0);
2578
2572
  React25__default.default.useEffect(() => {
2579
2573
  isExpanded.value = isOpen;
2580
2574
  }, [isOpen, isExpanded]);
2581
- const derivedHeight = Animated13.useDerivedValue(
2582
- () => Animated13.withTiming(height.value * Number(isExpanded.value), {
2575
+ const derivedHeight = Animated12.useDerivedValue(
2576
+ () => Animated12.withTiming(height.value * Number(isExpanded.value), {
2583
2577
  duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
2584
2578
  easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
2585
2579
  })
2586
2580
  );
2587
- const derivedRotation = Animated13.useDerivedValue(
2588
- () => Animated13.withTiming(isExpanded.value ? 1 : 0, {
2581
+ const derivedRotation = Animated12.useDerivedValue(
2582
+ () => Animated12.withTiming(isExpanded.value ? 1 : 0, {
2589
2583
  duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
2590
2584
  easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
2591
2585
  })
2592
2586
  );
2593
- const bodyStyle = Animated13.useAnimatedStyle(() => ({
2587
+ const bodyStyle = Animated12.useAnimatedStyle(() => ({
2594
2588
  height: derivedHeight.value,
2595
2589
  overflow: "hidden"
2596
2590
  }));
2597
- const rotationStyle = Animated13.useAnimatedStyle(() => ({
2591
+ const rotationStyle = Animated12.useAnimatedStyle(() => ({
2598
2592
  transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
2599
2593
  }));
2600
2594
  return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React25__default.default.createElement(
@@ -2610,8 +2604,8 @@ function AccordionItemComponent({
2610
2604
  accessibilityLabel: item.trigger
2611
2605
  },
2612
2606
  /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
2613
- /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2614
- ), /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
2607
+ /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2608
+ ), /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
2615
2609
  reactNative.View,
2616
2610
  {
2617
2611
  style: styles20.content,
@@ -3042,7 +3036,7 @@ function Select({
3042
3036
  }
3043
3037
  setPickerVisible(false);
3044
3038
  };
3045
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React25__default.default.createElement(
3039
+ return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React25__default.default.createElement(
3046
3040
  reactNative.TouchableOpacity,
3047
3041
  {
3048
3042
  style: [
@@ -3382,6 +3376,7 @@ var styles24 = reactNative.StyleSheet.create({
3382
3376
  }
3383
3377
  });
3384
3378
  function ListItemBase({
3379
+ imageSource,
3385
3380
  leftRender,
3386
3381
  rightRender,
3387
3382
  trailing,
@@ -3410,7 +3405,7 @@ function ListItemBase({
3410
3405
  selectionAsync();
3411
3406
  onPress?.();
3412
3407
  };
3413
- const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
3408
+ const effectiveLeft = imageSource ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Image, { source: imageSource, style: styles25.image }) : leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
3414
3409
  const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
3415
3410
  const cardStyle = variant === "card" ? {
3416
3411
  backgroundColor: colors.card,
@@ -3491,6 +3486,11 @@ var styles25 = reactNative.StyleSheet.create({
3491
3486
  justifyContent: "center",
3492
3487
  flexShrink: 0
3493
3488
  },
3489
+ image: {
3490
+ width: s(40),
3491
+ height: s(40),
3492
+ borderRadius: 8
3493
+ },
3494
3494
  content: {
3495
3495
  flex: 1,
3496
3496
  gap: vs(4)
@@ -4212,7 +4212,7 @@ function MediaCardBase({
4212
4212
  (title || subtitle || caption || footer) && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles33.meta }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
4213
4213
  );
4214
4214
  if (onPress) {
4215
- return /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React25__default.default.createElement(
4215
+ return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React25__default.default.createElement(
4216
4216
  reactNative.TouchableOpacity,
4217
4217
  {
4218
4218
  onPress: handlePress,
@@ -4297,7 +4297,7 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
4297
4297
  });
4298
4298
  const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
4299
4299
  const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, iconColor) : item.icon ?? null;
4300
- return /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React25__default.default.createElement(
4300
+ return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React25__default.default.createElement(
4301
4301
  reactNative.TouchableOpacity,
4302
4302
  {
4303
4303
  onPress: () => onSelect(item.value),
@@ -4720,15 +4720,15 @@ var styles38 = reactNative.StyleSheet.create({
4720
4720
  }
4721
4721
  });
4722
4722
  function Dot({ active, size, activeColor, inactiveColor, onPress, index, total }) {
4723
- const progress = Animated13.useSharedValue(active ? 1 : 0);
4723
+ const progress = Animated12.useSharedValue(active ? 1 : 0);
4724
4724
  React25.useEffect(() => {
4725
- progress.value = Animated13.withSpring(active ? 1 : 0, SPRINGS.glide);
4725
+ progress.value = Animated12.withSpring(active ? 1 : 0, SPRINGS.glide);
4726
4726
  }, [active, progress]);
4727
- const animatedStyle = Animated13.useAnimatedStyle(() => ({
4727
+ const animatedStyle = Animated12.useAnimatedStyle(() => ({
4728
4728
  width: size + progress.value * size * 1.5,
4729
- backgroundColor: Animated13.interpolateColor(progress.value, [0, 1], [inactiveColor, activeColor])
4729
+ backgroundColor: Animated12.interpolateColor(progress.value, [0, 1], [inactiveColor, activeColor])
4730
4730
  }));
4731
- const dot = /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [{ height: size, borderRadius: size / 2 }, animatedStyle] });
4731
+ const dot = /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ height: size, borderRadius: size / 2 }, animatedStyle] });
4732
4732
  if (!onPress) return dot;
4733
4733
  const handlePress = () => {
4734
4734
  selectionAsync();
@@ -4967,7 +4967,7 @@ function Cell({ item, selected, width, onPress }) {
4967
4967
  });
4968
4968
  const iconColor = selected ? colors.primary : colors.foregroundSubtle;
4969
4969
  const iconNode = item.icon ?? (item.iconName ? renderIcon(item.iconName, ms(24), iconColor) : null);
4970
- return /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [{ width }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(
4970
+ return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(
4971
4971
  reactNative.TouchableOpacity,
4972
4972
  {
4973
4973
  onPress,
@@ -5329,22 +5329,22 @@ var styles43 = reactNative.StyleSheet.create({
5329
5329
  var MAX_SCALE = 3;
5330
5330
  var DOUBLE_TAP_SCALE = 2.5;
5331
5331
  function ZoomableImage({ source, width, height, onZoomChange }) {
5332
- const scale2 = Animated13.useSharedValue(1);
5333
- const savedScale = Animated13.useSharedValue(1);
5334
- const translateX = Animated13.useSharedValue(0);
5335
- const translateY = Animated13.useSharedValue(0);
5336
- const savedX = Animated13.useSharedValue(0);
5337
- const savedY = Animated13.useSharedValue(0);
5332
+ const scale2 = Animated12.useSharedValue(1);
5333
+ const savedScale = Animated12.useSharedValue(1);
5334
+ const translateX = Animated12.useSharedValue(0);
5335
+ const translateY = Animated12.useSharedValue(0);
5336
+ const savedX = Animated12.useSharedValue(0);
5337
+ const savedY = Animated12.useSharedValue(0);
5338
5338
  const reportZoom = React25.useCallback((zoomed) => onZoomChange(zoomed), [onZoomChange]);
5339
5339
  const reset = () => {
5340
5340
  "worklet";
5341
- scale2.value = Animated13.withTiming(1);
5341
+ scale2.value = Animated12.withTiming(1);
5342
5342
  savedScale.value = 1;
5343
- translateX.value = Animated13.withTiming(0);
5344
- translateY.value = Animated13.withTiming(0);
5343
+ translateX.value = Animated12.withTiming(0);
5344
+ translateY.value = Animated12.withTiming(0);
5345
5345
  savedX.value = 0;
5346
5346
  savedY.value = 0;
5347
- Animated13.runOnJS(reportZoom)(false);
5347
+ Animated12.runOnJS(reportZoom)(false);
5348
5348
  };
5349
5349
  const pinch = reactNativeGestureHandler.Gesture.Pinch().onUpdate((e) => {
5350
5350
  scale2.value = Math.max(1, Math.min(savedScale.value * e.scale, MAX_SCALE));
@@ -5353,7 +5353,7 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
5353
5353
  if (scale2.value <= 1) {
5354
5354
  reset();
5355
5355
  } else {
5356
- Animated13.runOnJS(reportZoom)(true);
5356
+ Animated12.runOnJS(reportZoom)(true);
5357
5357
  }
5358
5358
  });
5359
5359
  const pan = reactNativeGestureHandler.Gesture.Pan().onUpdate((e) => {
@@ -5368,21 +5368,21 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
5368
5368
  if (scale2.value > 1) {
5369
5369
  reset();
5370
5370
  } else {
5371
- scale2.value = Animated13.withTiming(DOUBLE_TAP_SCALE);
5371
+ scale2.value = Animated12.withTiming(DOUBLE_TAP_SCALE);
5372
5372
  savedScale.value = DOUBLE_TAP_SCALE;
5373
- Animated13.runOnJS(reportZoom)(true);
5373
+ Animated12.runOnJS(reportZoom)(true);
5374
5374
  }
5375
5375
  });
5376
5376
  const composed = reactNativeGestureHandler.Gesture.Exclusive(doubleTap, reactNativeGestureHandler.Gesture.Simultaneous(pinch, pan));
5377
- const animatedStyle = Animated13.useAnimatedStyle(() => ({
5377
+ const animatedStyle = Animated12.useAnimatedStyle(() => ({
5378
5378
  transform: [
5379
5379
  { translateX: translateX.value },
5380
5380
  { translateY: translateY.value },
5381
5381
  { scale: scale2.value }
5382
5382
  ]
5383
5383
  }));
5384
- return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [{ width, height }, styles44.imageWrap] }, /* @__PURE__ */ React25__default.default.createElement(
5385
- Animated13__default.default.Image,
5384
+ return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width, height }, styles44.imageWrap] }, /* @__PURE__ */ React25__default.default.createElement(
5385
+ Animated12__default.default.Image,
5386
5386
  {
5387
5387
  source,
5388
5388
  style: [{ width, height }, animatedStyle],
@@ -5405,25 +5405,25 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5405
5405
  });
5406
5406
  return () => cancelAnimationFrame(handle);
5407
5407
  }, [visible, initialIndex, width]);
5408
- const dragY = Animated13.useSharedValue(0);
5408
+ const dragY = Animated12.useSharedValue(0);
5409
5409
  const DISMISS_THRESHOLD = height * 0.18;
5410
5410
  const closeViewer = React25.useCallback(() => onClose(), [onClose]);
5411
5411
  const swipeDown = reactNativeGestureHandler.Gesture.Pan().enabled(pagingEnabled).activeOffsetY(12).failOffsetX([-16, 16]).onUpdate((e) => {
5412
5412
  dragY.value = Math.max(0, e.translationY);
5413
5413
  }).onEnd((e) => {
5414
5414
  if (e.translationY > DISMISS_THRESHOLD || e.velocityY > 800) {
5415
- Animated13.runOnJS(closeViewer)();
5415
+ Animated12.runOnJS(closeViewer)();
5416
5416
  } else {
5417
- dragY.value = Animated13.withTiming(0);
5417
+ dragY.value = Animated12.withTiming(0);
5418
5418
  }
5419
5419
  });
5420
5420
  React25__default.default.useEffect(() => {
5421
5421
  if (visible) dragY.value = 0;
5422
5422
  }, [visible, dragY]);
5423
- const dismissStyle = Animated13.useAnimatedStyle(() => ({
5423
+ const dismissStyle = Animated12.useAnimatedStyle(() => ({
5424
5424
  transform: [{ translateY: dragY.value }]
5425
5425
  }));
5426
- const backdropStyle = Animated13.useAnimatedStyle(() => ({
5426
+ const backdropStyle = Animated12.useAnimatedStyle(() => ({
5427
5427
  opacity: 1 - Math.min(dragY.value / (height * 0.5), 0.85)
5428
5428
  }));
5429
5429
  const onMomentumEnd = (e) => {
@@ -5434,7 +5434,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5434
5434
  scrollRef.current?.scrollTo({ x: page * width, animated: true });
5435
5435
  setIndex(page);
5436
5436
  };
5437
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles44.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles44.container, dismissStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(
5437
+ return /* @__PURE__ */ React25__default.default.createElement(reactNative.Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles44.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles44.container, dismissStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(
5438
5438
  reactNative.ScrollView,
5439
5439
  {
5440
5440
  ref: scrollRef,
package/dist/index.mjs CHANGED
@@ -1,14 +1,15 @@
1
+ export { Tabs, TabsContent } from './chunk-GQYFLP3D.mjs';
1
2
  export { Text } from './chunk-WJLKJMKR.mjs';
2
- export { Textarea } from './chunk-EH745HE5.mjs';
3
+ export { Textarea } from './chunk-CZCQZHG6.mjs';
3
4
  export { Toggle } from './chunk-KIHCWCWL.mjs';
4
5
  export { VirtualList } from './chunk-NC5ZTR2Y.mjs';
6
+ export { Separator } from './chunk-MX6HRKMI.mjs';
5
7
  export { BottomSheetModalProvider, Sheet, BottomSheetTextInput as SheetTextInput } from './chunk-PFZTM6D5.mjs';
6
8
  export { SheetSelect } from './chunk-URI2WBIV.mjs';
7
9
  export { Skeleton } from './chunk-AJ7ZDNBT.mjs';
8
10
  export { Slider } from './chunk-JMOZEC77.mjs';
9
11
  export { Switch } from './chunk-QKH5ZOD5.mjs';
10
12
  export { TabBar } from './chunk-MLF3EZFW.mjs';
11
- export { Tabs, TabsContent } from './chunk-GQYFLP3D.mjs';
12
13
  export { Pressable } from './chunk-MBMXYJJV.mjs';
13
14
  export { PricingCard } from './chunk-4I7D47FH.mjs';
14
15
  export { Progress } from './chunk-OB4JUQ3O.mjs';
@@ -17,14 +18,14 @@ export { RetrayProvider } from './chunk-YFZ3ELX5.mjs';
17
18
  export { ToastProvider, sonnerToast as toast, useToast } from './chunk-2UYENBLV.mjs';
18
19
  export { Select } from './chunk-A3A6KNQN.mjs';
19
20
  export { SelectableGrid } from './chunk-NA7PARID.mjs';
20
- export { Separator } from './chunk-MX6HRKMI.mjs';
21
21
  export { LabelValue } from './chunk-A4MDAP7G.mjs';
22
22
  export { ListGroup, ListGroupFooter, ListGroupHeader } from './chunk-SOA2Z4RB.mjs';
23
- export { ListItem } from './chunk-T4I5WVHA.mjs';
23
+ export { ListItem } from './chunk-OHBNABL5.mjs';
24
24
  export { MediaCard } from './chunk-VGTDN7SW.mjs';
25
25
  export { MenuGroup, MenuGroupFooter, MenuGroupHeader } from './chunk-IRRY3CRZ.mjs';
26
26
  export { MenuItem } from './chunk-ZJKGQMYH.mjs';
27
27
  export { MonthPicker, dateToMonthPickerValue, monthPickerValueToDate } from './chunk-GD6KXMG5.mjs';
28
+ export { DetailRow } from './chunk-JB67UOB5.mjs';
28
29
  export { EmptyState } from './chunk-6OAZJ577.mjs';
29
30
  export { ErrorBoundary } from './chunk-LXJIIOYQ.mjs';
30
31
  export { Form, FormField, FormFooter, FormSection } from './chunk-6Q64UFIA.mjs';
@@ -32,6 +33,7 @@ export { ImageUpload } from './chunk-Y4GL2MHX.mjs';
32
33
  export { Spinner } from './chunk-WBOOUHSS.mjs';
33
34
  export { ImageViewer } from './chunk-Z4BVUWW6.mjs';
34
35
  export { PagerDots } from './chunk-4K625MVM.mjs';
36
+ export { ButtonGroup } from './chunk-3BBOZ3OQ.mjs';
35
37
  export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-ID72TK46.mjs';
36
38
  export { CategoryStrip } from './chunk-VQ57HWPL.mjs';
37
39
  import './chunk-YNROWHQJ.mjs';
@@ -39,10 +41,8 @@ export { Checkbox } from './chunk-AV4EMIRH.mjs';
39
41
  export { Chip, ChipGroup } from './chunk-UREA2GYY.mjs';
40
42
  export { ConfirmDialog } from './chunk-FZZLPJ6B.mjs';
41
43
  export { CurrencyDisplay } from './chunk-BRKYVJVV.mjs';
42
- export { CurrencyInput } from './chunk-KNSENOV4.mjs';
43
- export { Input } from './chunk-LVYEU5ZK.mjs';
44
- import './chunk-26BCI223.mjs';
45
- export { DetailRow } from './chunk-JB67UOB5.mjs';
44
+ export { CurrencyInput } from './chunk-JUXSWN54.mjs';
45
+ export { Input } from './chunk-ZUR7AU5R.mjs';
46
46
  export { Accordion } from './chunk-O3HA6TYM.mjs';
47
47
  export { AlertBanner } from './chunk-6MKGPAR2.mjs';
48
48
  export { AppHeader } from './chunk-AZJF2BLK.mjs';
@@ -56,7 +56,6 @@ import './chunk-DVK4G2GT.mjs';
56
56
  export { BREAKPOINTS, ICON_SIZES, RADIUS, SHADOWS, SPACING, TYPOGRAPHY } from './chunk-QY3X2UYR.mjs';
57
57
  export { Icon, configureIconFamilies, renderIcon } from './chunk-T7XZ7H7Y.mjs';
58
58
  export { ThemeProvider, defaultDark, defaultLight, deriveColors, useTheme } from './chunk-SOYNZDVY.mjs';
59
- export { ButtonGroup } from './chunk-3BBOZ3OQ.mjs';
60
59
  import './chunk-2CE3TQVY.mjs';
61
60
  import './chunk-Y6FXYEAI.mjs';
62
61
  import { useState, useCallback } from 'react';