@retray-dev/ui-kit 10.1.0 → 12.1.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.
Files changed (192) hide show
  1. package/COMPONENTS.md +419 -38
  2. package/README.md +14 -5
  3. package/dist/Accordion.js +1 -1
  4. package/dist/Accordion.mjs +3 -3
  5. package/dist/AlertBanner.js +1 -1
  6. package/dist/AlertBanner.mjs +3 -3
  7. package/dist/AppHeader.js +1 -1
  8. package/dist/AppHeader.mjs +4 -4
  9. package/dist/Avatar.mjs +2 -2
  10. package/dist/Badge.js +1 -1
  11. package/dist/Badge.mjs +3 -3
  12. package/dist/Button.js +1 -1
  13. package/dist/Button.mjs +3 -3
  14. package/dist/Card.mjs +2 -2
  15. package/dist/CategoryStrip.js +1 -1
  16. package/dist/CategoryStrip.mjs +3 -3
  17. package/dist/Checkbox.mjs +2 -2
  18. package/dist/Chip.js +1 -1
  19. package/dist/Chip.mjs +3 -3
  20. package/dist/ConfirmDialog.d.mts +1 -6
  21. package/dist/ConfirmDialog.d.ts +1 -6
  22. package/dist/ConfirmDialog.js +30 -24
  23. package/dist/ConfirmDialog.mjs +4 -4
  24. package/dist/CurrencyDisplay.mjs +2 -2
  25. package/dist/CurrencyInput.d.mts +3 -8
  26. package/dist/CurrencyInput.d.ts +3 -8
  27. package/dist/CurrencyInput.js +4 -2
  28. package/dist/CurrencyInput.mjs +4 -4
  29. package/dist/DetailRow.d.mts +1 -1
  30. package/dist/DetailRow.d.ts +1 -1
  31. package/dist/DetailRow.js +1 -1
  32. package/dist/DetailRow.mjs +3 -3
  33. package/dist/EmptyState.js +1 -1
  34. package/dist/EmptyState.mjs +4 -4
  35. package/dist/ErrorBoundary.js +1 -1
  36. package/dist/ErrorBoundary.mjs +3 -3
  37. package/dist/Form.mjs +2 -2
  38. package/dist/IconButton.js +1 -1
  39. package/dist/IconButton.mjs +3 -3
  40. package/dist/IconPicker.d.mts +17 -0
  41. package/dist/IconPicker.d.ts +17 -0
  42. package/dist/IconPicker.js +1424 -0
  43. package/dist/IconPicker.mjs +8 -0
  44. package/dist/ImageUpload.d.mts +3 -1
  45. package/dist/ImageUpload.d.ts +3 -1
  46. package/dist/ImageUpload.js +28 -10
  47. package/dist/ImageUpload.mjs +3 -3
  48. package/dist/ImageViewer.js +1 -1
  49. package/dist/ImageViewer.mjs +5 -5
  50. package/dist/Input.js +1 -1
  51. package/dist/Input.mjs +3 -3
  52. package/dist/LabelValue.js +1 -1
  53. package/dist/LabelValue.mjs +3 -3
  54. package/dist/ListGroup.mjs +2 -2
  55. package/dist/ListItem.d.mts +7 -7
  56. package/dist/ListItem.d.ts +7 -7
  57. package/dist/ListItem.js +13 -8
  58. package/dist/ListItem.mjs +3 -3
  59. package/dist/MediaCard.js +1 -1
  60. package/dist/MediaCard.mjs +3 -3
  61. package/dist/MenuGroup.mjs +2 -2
  62. package/dist/MenuItem.js +1 -1
  63. package/dist/MenuItem.mjs +3 -3
  64. package/dist/MonthPicker.mjs +2 -2
  65. package/dist/NumberStepper.d.mts +19 -0
  66. package/dist/NumberStepper.d.ts +19 -0
  67. package/dist/NumberStepper.js +410 -0
  68. package/dist/NumberStepper.mjs +9 -0
  69. package/dist/PagerDots.js +1 -1
  70. package/dist/PagerDots.mjs +3 -3
  71. package/dist/Pressable.d.mts +15 -7
  72. package/dist/Pressable.d.ts +15 -7
  73. package/dist/Pressable.js +7 -3
  74. package/dist/Pressable.mjs +1 -1
  75. package/dist/PricingCard.js +1 -1
  76. package/dist/PricingCard.mjs +5 -5
  77. package/dist/Progress.mjs +2 -2
  78. package/dist/RadioGroup.mjs +2 -2
  79. package/dist/RetrayProvider.mjs +3 -3
  80. package/dist/Select.mjs +2 -2
  81. package/dist/SelectableGrid.js +1 -1
  82. package/dist/SelectableGrid.mjs +3 -3
  83. package/dist/Separator.mjs +2 -2
  84. package/dist/Sheet.d.mts +4 -46
  85. package/dist/Sheet.d.ts +4 -46
  86. package/dist/Sheet.js +46 -114
  87. package/dist/Sheet.mjs +2 -3
  88. package/dist/SheetSelect.js +1 -1
  89. package/dist/SheetSelect.mjs +3 -3
  90. package/dist/Skeleton.mjs +2 -2
  91. package/dist/Slider.mjs +2 -2
  92. package/dist/Spinner.mjs +2 -2
  93. package/dist/Stats.d.mts +30 -0
  94. package/dist/Stats.d.ts +30 -0
  95. package/dist/Stats.js +429 -0
  96. package/dist/Stats.mjs +9 -0
  97. package/dist/Switch.mjs +2 -2
  98. package/dist/TabBar.js +1 -1
  99. package/dist/TabBar.mjs +3 -3
  100. package/dist/Tabs.mjs +2 -2
  101. package/dist/Text.d.mts +3 -1
  102. package/dist/Text.d.ts +3 -1
  103. package/dist/Text.js +3 -3
  104. package/dist/Text.mjs +2 -2
  105. package/dist/Textarea.js +1 -1
  106. package/dist/Textarea.mjs +3 -3
  107. package/dist/Toast.mjs +2 -2
  108. package/dist/Toggle.js +1 -1
  109. package/dist/Toggle.mjs +3 -3
  110. package/dist/{chunk-DJ7RN37L.mjs → chunk-265G6A46.mjs} +2 -2
  111. package/dist/{chunk-WOEYDUJZ.mjs → chunk-2A2LEFZG.mjs} +2 -2
  112. package/dist/{chunk-ID72TK46.mjs → chunk-2CBQKU7H.mjs} +1 -1
  113. package/dist/{chunk-OB4JUQ3O.mjs → chunk-2I2AYECM.mjs} +1 -1
  114. package/dist/{chunk-WJLKJMKR.mjs → chunk-357YO24D.mjs} +4 -4
  115. package/dist/{chunk-GQYFLP3D.mjs → chunk-3GEYJ7I5.mjs} +1 -1
  116. package/dist/{chunk-AV4EMIRH.mjs → chunk-3N2M3WZL.mjs} +1 -1
  117. package/dist/{chunk-TERDKCLE.mjs → chunk-3UYAZ7I4.mjs} +2 -2
  118. package/dist/{chunk-JMOZEC77.mjs → chunk-4WFMPFZB.mjs} +1 -1
  119. package/dist/chunk-5OLNXP3S.mjs +144 -0
  120. package/dist/{chunk-6OAZJ577.mjs → chunk-7HSILTC4.mjs} +3 -3
  121. package/dist/{chunk-IRRY3CRZ.mjs → chunk-AKM4EPOT.mjs} +1 -1
  122. package/dist/{chunk-VGTDN7SW.mjs → chunk-AQEVCEXV.mjs} +2 -2
  123. package/dist/{chunk-WBOOUHSS.mjs → chunk-BCWEHE34.mjs} +1 -1
  124. package/dist/{chunk-AJ7ZDNBT.mjs → chunk-BOVUP27T.mjs} +1 -1
  125. package/dist/{chunk-BRKYVJVV.mjs → chunk-BQZE3HAW.mjs} +1 -1
  126. package/dist/{chunk-MLF3EZFW.mjs → chunk-D3Y2T42P.mjs} +2 -2
  127. package/dist/{chunk-3U4SSNWP.mjs → chunk-DF6DU42P.mjs} +2 -2
  128. package/dist/{chunk-ZJKGQMYH.mjs → chunk-DI7CBDL6.mjs} +2 -2
  129. package/dist/{chunk-2TFTAWVJ.mjs → chunk-DOGIPOF5.mjs} +2 -2
  130. package/dist/{chunk-MBMXYJJV.mjs → chunk-E7NEHHXV.mjs} +7 -3
  131. package/dist/{chunk-MX6HRKMI.mjs → chunk-EFLFRAHD.mjs} +1 -1
  132. package/dist/{chunk-SOYNZDVY.mjs → chunk-EMUWGDWC.mjs} +6 -1
  133. package/dist/{chunk-4I7D47FH.mjs → chunk-F4V6XLP4.mjs} +4 -4
  134. package/dist/{chunk-UREA2GYY.mjs → chunk-FA2KMTH5.mjs} +2 -2
  135. package/dist/{chunk-Y2NS74WS.mjs → chunk-FFTYLPSB.mjs} +46 -98
  136. package/dist/{chunk-OHBNABL5.mjs → chunk-FUVYSVGR.mjs} +14 -9
  137. package/dist/{chunk-KIHCWCWL.mjs → chunk-FVTVCJAH.mjs} +2 -2
  138. package/dist/{chunk-Y4GL2MHX.mjs → chunk-GK4VRMNE.mjs} +30 -12
  139. package/dist/{chunk-6Q64UFIA.mjs → chunk-HJ46DTJE.mjs} +1 -1
  140. package/dist/{chunk-WF2XDFRK.mjs → chunk-HLMPMUK2.mjs} +1 -1
  141. package/dist/{chunk-GD6KXMG5.mjs → chunk-I4V5XZPS.mjs} +1 -1
  142. package/dist/{chunk-AZJF2BLK.mjs → chunk-ISY26JQJ.mjs} +2 -2
  143. package/dist/{chunk-X4G6APW6.mjs → chunk-J6Q2YJEV.mjs} +1 -1
  144. package/dist/{chunk-KZL5VTYK.mjs → chunk-JCZQOY4O.mjs} +31 -24
  145. package/dist/{chunk-CZCQZHG6.mjs → chunk-JNVAIDLK.mjs} +2 -2
  146. package/dist/{chunk-SOA2Z4RB.mjs → chunk-JULSIZDM.mjs} +1 -1
  147. package/dist/{chunk-T7XZ7H7Y.mjs → chunk-KA7LTET3.mjs} +17 -3
  148. package/dist/chunk-KHYX4IOM.mjs +1114 -0
  149. package/dist/{chunk-LXJIIOYQ.mjs → chunk-LRM4AVYY.mjs} +2 -2
  150. package/dist/{chunk-VQ57HWPL.mjs → chunk-MYZ2EDYU.mjs} +2 -2
  151. package/dist/chunk-N4ZPVCJH.mjs +126 -0
  152. package/dist/{chunk-NA7PARID.mjs → chunk-NXI4YDZ2.mjs} +2 -2
  153. package/dist/{chunk-4K625MVM.mjs → chunk-OULVKTWL.mjs} +2 -2
  154. package/dist/{chunk-A4MDAP7G.mjs → chunk-P64WHW4A.mjs} +2 -2
  155. package/dist/{chunk-URI2WBIV.mjs → chunk-P73V2EKS.mjs} +2 -2
  156. package/dist/{chunk-ZUR7AU5R.mjs → chunk-PGERH3P7.mjs} +2 -2
  157. package/dist/{chunk-2UYENBLV.mjs → chunk-QSFV2P7O.mjs} +1 -1
  158. package/dist/{chunk-JT7HKXRB.mjs → chunk-S3KJCPEJ.mjs} +1 -1
  159. package/dist/{chunk-6MKGPAR2.mjs → chunk-V6NFJXKO.mjs} +2 -2
  160. package/dist/{chunk-A3A6KNQN.mjs → chunk-WOEWGSTU.mjs} +1 -1
  161. package/dist/{chunk-JUXSWN54.mjs → chunk-X26S5EVZ.mjs} +4 -2
  162. package/dist/{chunk-YFZ3ELX5.mjs → chunk-XBAGGKLW.mjs} +2 -2
  163. package/dist/{chunk-JB67UOB5.mjs → chunk-ZHMSAYLT.mjs} +2 -2
  164. package/dist/fonts.d.mts +1 -7
  165. package/dist/fonts.d.ts +1 -7
  166. package/dist/fonts.js +0 -2
  167. package/dist/fonts.mjs +1 -2
  168. package/dist/index.d.mts +7 -1
  169. package/dist/index.d.ts +7 -1
  170. package/dist/index.js +1831 -475
  171. package/dist/index.mjs +54 -51
  172. package/package.json +3 -3
  173. package/src/components/ConfirmDialog/ConfirmDialog.tsx +39 -30
  174. package/src/components/CurrencyInput/CurrencyInput.tsx +4 -7
  175. package/src/components/DetailRow/DetailRow.tsx +1 -1
  176. package/src/components/IconPicker/IconPicker.tsx +395 -0
  177. package/src/components/IconPicker/index.ts +1 -0
  178. package/src/components/ImageUpload/ImageUpload.tsx +34 -12
  179. package/src/components/ListItem/ListItem.tsx +43 -28
  180. package/src/components/NumberStepper/NumberStepper.tsx +147 -0
  181. package/src/components/NumberStepper/index.ts +1 -0
  182. package/src/components/Pressable/Pressable.tsx +20 -8
  183. package/src/components/Sheet/Sheet.tsx +64 -172
  184. package/src/components/Stats/Stats.tsx +226 -0
  185. package/src/components/Stats/index.ts +2 -0
  186. package/src/components/Text/Text.tsx +4 -2
  187. package/src/fonts.ts +0 -7
  188. package/src/index.ts +7 -1
  189. package/src/theme/colorUtils.ts +9 -0
  190. package/src/utils/curatedIcons.ts +849 -0
  191. package/src/utils/fontGuard.ts +2 -1
  192. package/src/utils/icons.ts +20 -2
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React25 = require('react');
3
+ var React54 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var reactNativeSizeMatters = require('react-native-size-matters');
6
6
  var AntDesign = require('@expo/vector-icons/AntDesign');
@@ -12,7 +12,7 @@ var Ionicons = require('@expo/vector-icons/Ionicons');
12
12
  var pressto = require('pressto');
13
13
  var Animated12 = require('react-native-reanimated');
14
14
  var expoFont = require('expo-font');
15
- var BottomSheet = require('@gorhom/bottom-sheet');
15
+ var bottomSheet = require('@gorhom/bottom-sheet');
16
16
  var reactNativeEase = require('react-native-ease');
17
17
  var vectorIcons = require('@expo/vector-icons');
18
18
  var expoLinearGradient = require('expo-linear-gradient');
@@ -24,7 +24,7 @@ var reactNativeGestureHandler = require('react-native-gesture-handler');
24
24
 
25
25
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
26
26
 
27
- var React25__default = /*#__PURE__*/_interopDefault(React25);
27
+ var React54__default = /*#__PURE__*/_interopDefault(React54);
28
28
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
29
29
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
30
30
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
@@ -32,7 +32,6 @@ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
32
32
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
33
33
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
34
34
  var Animated12__default = /*#__PURE__*/_interopDefault(Animated12);
35
- var BottomSheet__default = /*#__PURE__*/_interopDefault(BottomSheet);
36
35
  var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
37
36
 
38
37
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -93,6 +92,11 @@ function darken(hex, amount) {
93
92
  if (!rgb) return hex;
94
93
  return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
95
94
  }
95
+ function withAlpha(hex, alpha) {
96
+ const rgb = hexToRgb(hex);
97
+ if (!rgb) return hex;
98
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
99
+ }
96
100
 
97
101
  // src/theme/colors.ts
98
102
  var defaultLight = {
@@ -168,23 +172,23 @@ function deriveColors(t, scheme) {
168
172
  }
169
173
 
170
174
  // src/theme/ThemeProvider.tsx
171
- var ThemeContext = React25.createContext({
175
+ var ThemeContext = React54.createContext({
172
176
  colors: deriveColors(defaultLight, "light"),
173
177
  colorScheme: "light"
174
178
  });
175
179
  function ThemeProvider({ children, theme, colorScheme = "system" }) {
176
180
  const systemScheme = reactNative.useColorScheme() ?? "light";
177
181
  const resolvedScheme = colorScheme === "system" ? systemScheme : colorScheme;
178
- const colors = React25.useMemo(() => {
182
+ const colors = React54.useMemo(() => {
179
183
  const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
180
184
  const override = resolvedScheme === "dark" ? theme?.dark : theme?.light;
181
185
  const merged = override ? { ...base, ...override } : base;
182
186
  return deriveColors(merged, resolvedScheme);
183
187
  }, [resolvedScheme, theme]);
184
- return /* @__PURE__ */ React25__default.default.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
188
+ return /* @__PURE__ */ React54__default.default.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
185
189
  }
186
190
  function useTheme() {
187
- const context = React25.useContext(ThemeContext);
191
+ const context = React54.useContext(ThemeContext);
188
192
  if (!context) {
189
193
  throw new Error("useTheme must be used within a ThemeProvider");
190
194
  }
@@ -369,9 +373,9 @@ function configureIconFamilies(families) {
369
373
  activeFamilies = order.length > 0 ? order : ALL_FAMILIES;
370
374
  resolvedCache = null;
371
375
  }
372
- function buildCache() {
376
+ function buildCache(families) {
373
377
  const cache = /* @__PURE__ */ new Map();
374
- for (const family of activeFamilies) {
378
+ for (const family of families ?? activeFamilies) {
375
379
  const glyphMap = family.getGlyphMap();
376
380
  for (const iconName of Object.keys(glyphMap)) {
377
381
  cache.set(iconName, family);
@@ -385,6 +389,20 @@ function resolveFamily(name) {
385
389
  }
386
390
  return resolvedCache.get(name) ?? null;
387
391
  }
392
+ var cachedIconNames = null;
393
+ function getValidIconNames(families) {
394
+ if (families && families.length > 0) {
395
+ const tempFamilies = families.map((n) => ALL_FAMILIES.find((f) => f.name === n)).filter((f) => f !== void 0);
396
+ if (tempFamilies.length === 0) return [];
397
+ const cache = buildCache(tempFamilies);
398
+ return Array.from(cache.keys());
399
+ }
400
+ if (!cachedIconNames) {
401
+ const cache = buildCache();
402
+ cachedIconNames = Array.from(cache.keys());
403
+ }
404
+ return cachedIconNames;
405
+ }
388
406
  function Icon({ name, size, color, family }) {
389
407
  let resolved = null;
390
408
  if (family) {
@@ -394,10 +412,10 @@ function Icon({ name, size, color, family }) {
394
412
  }
395
413
  if (!resolved) return null;
396
414
  const Component = resolved.component;
397
- return React25__default.default.createElement(Component, { name, size, color });
415
+ return React54__default.default.createElement(Component, { name, size, color });
398
416
  }
399
417
  function renderIcon(name, size, color) {
400
- return React25__default.default.createElement(Icon, { name, size, color });
418
+ return React54__default.default.createElement(Icon, { name, size, color });
401
419
  }
402
420
 
403
421
  // src/tokens.ts
@@ -722,7 +740,7 @@ function ButtonBase({
722
740
  const styleArray = Array.isArray(style) ? style : style ? [style] : [];
723
741
  const flatStyle = reactNative.StyleSheet.flatten(styleArray);
724
742
  const { flex, ...restStyle } = flatStyle || {};
725
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }] }, /* @__PURE__ */ React25__default.default.createElement(
743
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }] }, /* @__PURE__ */ React54__default.default.createElement(
726
744
  PressableButton,
727
745
  {
728
746
  style: [
@@ -743,7 +761,7 @@ function ButtonBase({
743
761
  accessibilityHint,
744
762
  accessibilityState: { disabled: isDisabled, busy: loading }
745
763
  },
746
- loading ? /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React25__default.default.createElement(
764
+ loading ? /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, /* @__PURE__ */ React54__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React54__default.default.createElement(
747
765
  reactNative.Text,
748
766
  {
749
767
  style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
@@ -751,7 +769,7 @@ function ButtonBase({
751
769
  numberOfLines: 1
752
770
  },
753
771
  label
754
- )) : /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(
772
+ )) : /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React54__default.default.createElement(
755
773
  reactNative.Text,
756
774
  {
757
775
  style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
@@ -759,10 +777,10 @@ function ButtonBase({
759
777
  numberOfLines: 1
760
778
  },
761
779
  label
762
- ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon))
780
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, effectiveIcon))
763
781
  ));
764
782
  }
765
- var Button = React25__default.default.memo(ButtonBase);
783
+ var Button = React54__default.default.memo(ButtonBase);
766
784
  var styles = reactNative.StyleSheet.create({
767
785
  base: {
768
786
  borderRadius: RADIUS.md,
@@ -788,7 +806,7 @@ var styles = reactNative.StyleSheet.create({
788
806
  }
789
807
  });
790
808
  function ButtonGroup({ children, gap = 12, vertical = false, style }) {
791
- return /* @__PURE__ */ React25__default.default.createElement(
809
+ return /* @__PURE__ */ React54__default.default.createElement(
792
810
  reactNative.View,
793
811
  {
794
812
  style: [
@@ -798,8 +816,8 @@ function ButtonGroup({ children, gap = 12, vertical = false, style }) {
798
816
  style
799
817
  ]
800
818
  },
801
- React25__default.default.Children.map(children, (child) => {
802
- if (!React25__default.default.isValidElement(child)) return child;
819
+ React54__default.default.Children.map(children, (child) => {
820
+ if (!React54__default.default.isValidElement(child)) return child;
803
821
  const childProps = child.props;
804
822
  const extraProps = {
805
823
  style: [child.props.style, { flex: 1 }]
@@ -807,7 +825,7 @@ function ButtonGroup({ children, gap = 12, vertical = false, style }) {
807
825
  if (!vertical && "label" in childProps && childProps["size"] === void 0) {
808
826
  extraProps["size"] = "sm";
809
827
  }
810
- return React25__default.default.cloneElement(child, extraProps);
828
+ return React54__default.default.cloneElement(child, extraProps);
811
829
  })
812
830
  );
813
831
  }
@@ -868,7 +886,7 @@ function IconButtonBase({
868
886
  const showBadge = badge !== void 0 && badge !== false && badge !== 0;
869
887
  const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
870
888
  const showCount = typeof badge === "number" && badge > 0;
871
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles3.wrapper }, /* @__PURE__ */ React25__default.default.createElement(
889
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles3.wrapper }, /* @__PURE__ */ React54__default.default.createElement(
872
890
  PressableButton,
873
891
  {
874
892
  style: [
@@ -888,14 +906,14 @@ function IconButtonBase({
888
906
  accessibilityHint,
889
907
  accessibilityState: { disabled: isDisabled, busy: loading }
890
908
  },
891
- loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
892
- ), showBadge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
909
+ loading ? /* @__PURE__ */ React54__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
910
+ ), showBadge && /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [
893
911
  styles3.badge,
894
912
  { backgroundColor: colors.primary },
895
913
  showCount ? styles3.badgeCount : styles3.badgeDot
896
- ] }, showCount && /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
914
+ ] }, showCount && /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
897
915
  }
898
- var IconButton = React25__default.default.memo(IconButtonBase);
916
+ var IconButton = React54__default.default.memo(IconButtonBase);
899
917
  var styles3 = reactNative.StyleSheet.create({
900
918
  wrapper: {
901
919
  alignSelf: "flex-start"
@@ -940,7 +958,7 @@ function warnIfFontsMissing() {
940
958
  try {
941
959
  if (!expoFont.isLoaded("Sohne-Regular")) {
942
960
  console.warn(
943
- "[retray-ui-kit] Sohne fonts are not loaded \u2014 text will fall back to the system font. Load them at your app root before rendering any UI kit component:\n\n import { useFonts } from 'expo-font'\n import { SohneFonts } from '@retray-dev/ui-kit/fonts'\n\n const [fontsLoaded] = useFonts(SohneFonts)\n if (!fontsLoaded) return null\n"
961
+ "[retray-ui-kit] Sohne fonts are not loaded \u2014 text will fall back to the system font. Load them at your app root before rendering any UI kit component:\n\n import { useFonts } from 'expo-font'\n import { SohneFontNames } from '@retray-dev/ui-kit/fonts'\n // Copy the SohneFonts boilerplate from CONSUMER.md into your App.tsx\n\n const [fontsLoaded] = useFonts(SohneFonts)\n if (!fontsLoaded) return null\n"
944
962
  );
945
963
  }
946
964
  } catch {
@@ -985,32 +1003,32 @@ var defaultColorVariant = {
985
1003
  "button-lg": "foreground",
986
1004
  "button-sm": "foreground"
987
1005
  };
988
- function TextBase({ variant = "body-md", color, style, children, ...props }) {
1006
+ function TextBase({ variant = "body-md", color, style, uppercase, children, ...props }) {
989
1007
  warnIfFontsMissing();
990
1008
  const { colors } = useTheme();
991
1009
  const colorKey = defaultColorVariant[variant] ?? "foreground";
992
1010
  const resolvedColor = color ?? colors[colorKey];
993
- return /* @__PURE__ */ React25__default.default.createElement(
1011
+ return /* @__PURE__ */ React54__default.default.createElement(
994
1012
  reactNative.Text,
995
1013
  {
996
- style: [variantStyles[variant], { color: resolvedColor }, style],
1014
+ style: [variantStyles[variant], { color: resolvedColor }, uppercase && { textTransform: "uppercase" }, style],
997
1015
  allowFontScaling: true,
998
1016
  ...props
999
1017
  },
1000
1018
  children
1001
1019
  );
1002
1020
  }
1003
- var Text3 = React25__default.default.memo(TextBase);
1021
+ var Text3 = React54__default.default.memo(TextBase);
1004
1022
  var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
1005
1023
  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 }) {
1006
1024
  const { colors } = useTheme();
1007
- const [focused, setFocused] = React25.useState(false);
1008
- const [showPassword, setShowPassword] = React25.useState(false);
1025
+ const [focused, setFocused] = React54.useState(false);
1026
+ const [showPassword, setShowPassword] = React54.useState(false);
1009
1027
  const isDisabled = disabled || editable === false;
1010
1028
  const isPassword = type === "password";
1011
1029
  const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
1012
1030
  const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
1013
- const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25__default.default.createElement(
1031
+ const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React54__default.default.createElement(
1014
1032
  reactNative.TouchableOpacity,
1015
1033
  {
1016
1034
  onPress: () => setShowPassword(!showPassword),
@@ -1019,10 +1037,10 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1019
1037
  accessibilityRole: "button",
1020
1038
  accessibilityLabel: showPassword ? "Hide password" : "Show password"
1021
1039
  },
1022
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
1040
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
1023
1041
  ) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
1024
1042
  const borderColor = error ? colors.destructive : focused ? colors.primary : colors.border;
1025
- 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(
1043
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React54__default.default.createElement(
1026
1044
  reactNativeEase.EaseView,
1027
1045
  {
1028
1046
  style: [
@@ -1034,9 +1052,9 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1034
1052
  animate: { borderColor },
1035
1053
  transition: COLOR_TRANSITION
1036
1054
  },
1037
- 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,
1038
- sheetMode ? /* @__PURE__ */ React25__default.default.createElement(
1039
- BottomSheet.BottomSheetTextInput,
1055
+ effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles4.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles4.prefixContainer }, effectivePrefix) : null,
1056
+ sheetMode ? /* @__PURE__ */ React54__default.default.createElement(
1057
+ bottomSheet.BottomSheetTextInput,
1040
1058
  {
1041
1059
  style: [
1042
1060
  styles4.input,
@@ -1059,7 +1077,7 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1059
1077
  accessibilityLabel: accessibilityLabel ?? label,
1060
1078
  ...props
1061
1079
  }
1062
- ) : /* @__PURE__ */ React25__default.default.createElement(
1080
+ ) : /* @__PURE__ */ React54__default.default.createElement(
1063
1081
  reactNative.TextInput,
1064
1082
  {
1065
1083
  style: [
@@ -1084,8 +1102,8 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1084
1102
  ...props
1085
1103
  }
1086
1104
  ),
1087
- effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles4.suffixContainer }, effectiveSuffix) : null
1088
- ), error ? /* @__PURE__ */ React25__default.default.createElement(
1105
+ effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles4.suffixContainer }, effectiveSuffix) : null
1106
+ ), error ? /* @__PURE__ */ React54__default.default.createElement(
1089
1107
  reactNative.Text,
1090
1108
  {
1091
1109
  style: [styles4.helperText, { color: colors.destructive }],
@@ -1093,7 +1111,7 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
1093
1111
  accessibilityLiveRegion: "polite"
1094
1112
  },
1095
1113
  error
1096
- ) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1114
+ ) : null, !error && hint ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1097
1115
  }
1098
1116
  var styles4 = reactNative.StyleSheet.create({
1099
1117
  container: {
@@ -1195,7 +1213,7 @@ function BadgeBase({ label, children, variant = "default", size = "md", icon, ic
1195
1213
  const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
1196
1214
  const content = children ?? label;
1197
1215
  const a11yLabel = typeof content === "string" ? content : label;
1198
- return /* @__PURE__ */ React25__default.default.createElement(
1216
+ return /* @__PURE__ */ React54__default.default.createElement(
1199
1217
  reactNative.View,
1200
1218
  {
1201
1219
  style: [styles5.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style],
@@ -1203,10 +1221,10 @@ function BadgeBase({ label, children, variant = "default", size = "md", icon, ic
1203
1221
  accessibilityLabel: a11yLabel
1204
1222
  },
1205
1223
  effectiveIcon,
1206
- typeof content === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content
1224
+ typeof content === "string" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles5.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content
1207
1225
  );
1208
1226
  }
1209
- var Badge = React25__default.default.memo(BadgeBase);
1227
+ var Badge = React54__default.default.memo(BadgeBase);
1210
1228
  var styles5 = reactNative.StyleSheet.create({
1211
1229
  container: {
1212
1230
  borderRadius: 9999,
@@ -1251,9 +1269,9 @@ function Card({ children, variant = "elevated", onPress, style, accessibilityLab
1251
1269
  elevation: 0
1252
1270
  }
1253
1271
  }[variant];
1254
- const cardContent = /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles6.card, variantStyle, style] }, children);
1272
+ const cardContent = /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles6.card, variantStyle, style] }, children);
1255
1273
  if (onPress) {
1256
- return /* @__PURE__ */ React25__default.default.createElement(
1274
+ return /* @__PURE__ */ React54__default.default.createElement(
1257
1275
  PressableCard,
1258
1276
  {
1259
1277
  onPress: handlePress,
@@ -1269,21 +1287,21 @@ function Card({ children, variant = "elevated", onPress, style, accessibilityLab
1269
1287
  return cardContent;
1270
1288
  }
1271
1289
  function CardHeader({ children, style }) {
1272
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles6.header, style] }, children);
1290
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles6.header, style] }, children);
1273
1291
  }
1274
1292
  function CardTitle({ children, style }) {
1275
1293
  const { colors } = useTheme();
1276
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles6.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
1294
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles6.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
1277
1295
  }
1278
1296
  function CardDescription({ children, style }) {
1279
1297
  const { colors } = useTheme();
1280
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles6.description, { color: colors.foregroundSubtle }, style], allowFontScaling: true }, children);
1298
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles6.description, { color: colors.foregroundSubtle }, style], allowFontScaling: true }, children);
1281
1299
  }
1282
1300
  function CardContent({ children, style }) {
1283
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles6.content, style] }, children);
1301
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles6.content, style] }, children);
1284
1302
  }
1285
1303
  function CardFooter({ children, style }) {
1286
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles6.footer, style] }, children);
1304
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles6.footer, style] }, children);
1287
1305
  }
1288
1306
  var styles6 = reactNative.StyleSheet.create({
1289
1307
  card: {
@@ -1321,7 +1339,7 @@ var styles6 = reactNative.StyleSheet.create({
1321
1339
  });
1322
1340
  function Separator({ orientation = "horizontal", style }) {
1323
1341
  const { colors } = useTheme();
1324
- return /* @__PURE__ */ React25__default.default.createElement(
1342
+ return /* @__PURE__ */ React54__default.default.createElement(
1325
1343
  reactNative.View,
1326
1344
  {
1327
1345
  style: [
@@ -1356,7 +1374,7 @@ function Spinner({ size = "md", color, label, ...props }) {
1356
1374
  const { colors } = useTheme();
1357
1375
  const a11yLabel = label || "Loading";
1358
1376
  if (label) {
1359
- return /* @__PURE__ */ React25__default.default.createElement(
1377
+ return /* @__PURE__ */ React54__default.default.createElement(
1360
1378
  reactNative.View,
1361
1379
  {
1362
1380
  style: styles8.wrapper,
@@ -1364,8 +1382,8 @@ function Spinner({ size = "md", color, label, ...props }) {
1364
1382
  accessibilityLabel: a11yLabel,
1365
1383
  accessibilityState: { busy: true }
1366
1384
  },
1367
- /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }),
1368
- /* @__PURE__ */ React25__default.default.createElement(
1385
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }),
1386
+ /* @__PURE__ */ React54__default.default.createElement(
1369
1387
  reactNative.Text,
1370
1388
  {
1371
1389
  style: [styles8.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
@@ -1375,7 +1393,7 @@ function Spinner({ size = "md", color, label, ...props }) {
1375
1393
  )
1376
1394
  );
1377
1395
  }
1378
- return /* @__PURE__ */ React25__default.default.createElement(
1396
+ return /* @__PURE__ */ React54__default.default.createElement(
1379
1397
  reactNative.ActivityIndicator,
1380
1398
  {
1381
1399
  size: sizeMap2[size],
@@ -1407,9 +1425,9 @@ function Skeleton({
1407
1425
  }) {
1408
1426
  const { colors, colorScheme } = useTheme();
1409
1427
  const shimmer = Animated12.useSharedValue(0);
1410
- const [containerWidth, setContainerWidth] = React25.useState(300);
1428
+ const [containerWidth, setContainerWidth] = React54.useState(300);
1411
1429
  const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
1412
- React25.useEffect(() => {
1430
+ React54.useEffect(() => {
1413
1431
  shimmer.value = Animated12.withRepeat(
1414
1432
  Animated12.withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Animated12.Easing.linear }),
1415
1433
  -1,
@@ -1422,7 +1440,7 @@ function Skeleton({
1422
1440
  const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
1423
1441
  const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
1424
1442
  const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
1425
- return /* @__PURE__ */ React25__default.default.createElement(
1443
+ return /* @__PURE__ */ React54__default.default.createElement(
1426
1444
  reactNative.View,
1427
1445
  {
1428
1446
  style: [
@@ -1435,7 +1453,7 @@ function Skeleton({
1435
1453
  accessibilityLabel: "Loading",
1436
1454
  accessibilityState: { busy: true }
1437
1455
  },
1438
- /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React25__default.default.createElement(
1456
+ /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React54__default.default.createElement(
1439
1457
  expoLinearGradient.LinearGradient,
1440
1458
  {
1441
1459
  colors: ["transparent", shimmerHighlight, "transparent"],
@@ -1455,10 +1473,10 @@ var aspectRatioMap = {
1455
1473
  };
1456
1474
  function MediaCardSkeleton({ aspectRatio = "4:3", showSubtitle = true, style }) {
1457
1475
  const ratio = aspectRatioMap[aspectRatio];
1458
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, /* @__PURE__ */ React25__default.default.createElement(Skeleton, { width: "100%", height: void 0, style: skeletonStyles.fill, borderRadius: RADIUS.md }))), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: skeletonStyles.meta }, /* @__PURE__ */ React25__default.default.createElement(Skeleton, { width: "70%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React25__default.default.createElement(Skeleton, { width: "45%", height: vs(12), borderRadius: RADIUS.xs }) : null));
1476
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, /* @__PURE__ */ React54__default.default.createElement(Skeleton, { width: "100%", height: void 0, style: skeletonStyles.fill, borderRadius: RADIUS.md }))), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: skeletonStyles.meta }, /* @__PURE__ */ React54__default.default.createElement(Skeleton, { width: "70%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React54__default.default.createElement(Skeleton, { width: "45%", height: vs(12), borderRadius: RADIUS.xs }) : null));
1459
1477
  }
1460
1478
  function ListItemSkeleton({ showAvatar = true, showSubtitle = true, style }) {
1461
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [skeletonStyles.row, style] }, showAvatar ? /* @__PURE__ */ React25__default.default.createElement(Skeleton, { preset: "circle", diameter: 40 }) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: skeletonStyles.rowText }, /* @__PURE__ */ React25__default.default.createElement(Skeleton, { width: "60%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React25__default.default.createElement(Skeleton, { width: "40%", height: vs(12), borderRadius: RADIUS.xs }) : null));
1479
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [skeletonStyles.row, style] }, showAvatar ? /* @__PURE__ */ React54__default.default.createElement(Skeleton, { preset: "circle", diameter: 40 }) : null, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: skeletonStyles.rowText }, /* @__PURE__ */ React54__default.default.createElement(Skeleton, { width: "60%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React54__default.default.createElement(Skeleton, { width: "40%", height: vs(12), borderRadius: RADIUS.xs }) : null));
1462
1480
  }
1463
1481
  function ListSkeleton({
1464
1482
  count = 6,
@@ -1469,10 +1487,10 @@ function ListSkeleton({
1469
1487
  style
1470
1488
  }) {
1471
1489
  if (columns <= 1) {
1472
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [{ gap: vs(gap) }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React25__default.default.createElement(ListItemSkeleton, { key: i, showAvatar })));
1490
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [{ gap: vs(gap) }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React54__default.default.createElement(ListItemSkeleton, { key: i, showAvatar })));
1473
1491
  }
1474
1492
  const widthPct = `${100 / columns}%`;
1475
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [skeletonStyles.grid, { marginHorizontal: -s(gap) / 2 }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: i, style: { width: widthPct, paddingHorizontal: s(gap) / 2, marginBottom: vs(gap) } }, /* @__PURE__ */ React25__default.default.createElement(MediaCardSkeleton, { aspectRatio }))));
1493
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [skeletonStyles.grid, { marginHorizontal: -s(gap) / 2 }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { key: i, style: { width: widthPct, paddingHorizontal: s(gap) / 2, marginBottom: vs(gap) } }, /* @__PURE__ */ React54__default.default.createElement(MediaCardSkeleton, { aspectRatio }))));
1476
1494
  }
1477
1495
  Skeleton.MediaCard = MediaCardSkeleton;
1478
1496
  Skeleton.ListItem = ListItemSkeleton;
@@ -1535,7 +1553,7 @@ function getInitials(fallback, fallbackText) {
1535
1553
  }
1536
1554
  function AvatarBase({ src, fallback, fallbackText, size = "md", status, style }) {
1537
1555
  const { colors } = useTheme();
1538
- const [imageError, setImageError] = React25.useState(false);
1556
+ const [imageError, setImageError] = React54.useState(false);
1539
1557
  const dimension = typeof size === "number" ? size : sizeMap3[size];
1540
1558
  const fontSize = typeof size === "number" ? size * 0.38 : fontSizeMap[size];
1541
1559
  const showFallback = !src || imageError;
@@ -1554,21 +1572,21 @@ function AvatarBase({ src, fallback, fallbackText, size = "md", status, style })
1554
1572
  overflow: "hidden"
1555
1573
  };
1556
1574
  const a11yLabel = fallbackText || fallback || "Avatar";
1557
- return /* @__PURE__ */ React25__default.default.createElement(
1575
+ return /* @__PURE__ */ React54__default.default.createElement(
1558
1576
  reactNative.View,
1559
1577
  {
1560
1578
  style: [styles10.wrapper, style],
1561
1579
  accessibilityRole: "image",
1562
1580
  accessibilityLabel: a11yLabel
1563
1581
  },
1564
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles10.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25__default.default.createElement(
1582
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles10.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React54__default.default.createElement(
1565
1583
  reactNative.Image,
1566
1584
  {
1567
1585
  source: { uri: src },
1568
1586
  style: { width: dimension, height: dimension },
1569
1587
  onError: () => setImageError(true)
1570
1588
  }
1571
- ) : /* @__PURE__ */ React25__default.default.createElement(
1589
+ ) : /* @__PURE__ */ React54__default.default.createElement(
1572
1590
  reactNative.Text,
1573
1591
  {
1574
1592
  style: [styles10.fallback, { color: colors.foregroundMuted, fontSize }],
@@ -1576,7 +1594,7 @@ function AvatarBase({ src, fallback, fallbackText, size = "md", status, style })
1576
1594
  },
1577
1595
  getInitials(fallback, fallbackText)
1578
1596
  )),
1579
- status && /* @__PURE__ */ React25__default.default.createElement(
1597
+ status && /* @__PURE__ */ React54__default.default.createElement(
1580
1598
  reactNative.View,
1581
1599
  {
1582
1600
  style: [
@@ -1594,7 +1612,7 @@ function AvatarBase({ src, fallback, fallbackText, size = "md", status, style })
1594
1612
  )
1595
1613
  );
1596
1614
  }
1597
- var Avatar = React25__default.default.memo(AvatarBase);
1615
+ var Avatar = React54__default.default.memo(AvatarBase);
1598
1616
  var styles10 = reactNative.StyleSheet.create({
1599
1617
  wrapper: {
1600
1618
  alignSelf: "flex-start",
@@ -1619,15 +1637,15 @@ function AlertBanner({ title, description, variant = "default", icon, iconName,
1619
1637
  const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.foreground;
1620
1638
  const bgColor = variant === "destructive" ? isDark ? "rgba(239, 83, 80, 0.15)" : "rgba(199, 40, 40, 0.10)" : variant === "success" ? isDark ? "rgba(46, 125, 82, 0.15)" : "rgba(26, 122, 69, 0.10)" : variant === "warning" ? isDark ? "rgba(245, 166, 35, 0.15)" : "rgba(154, 82, 0, 0.10)" : colors.surface;
1621
1639
  const borderColor = variant === "destructive" ? isDark ? "rgba(239, 83, 80, 0.30)" : "rgba(199, 40, 40, 0.25)" : variant === "success" ? isDark ? "rgba(46, 125, 82, 0.30)" : "rgba(26, 122, 69, 0.25)" : variant === "warning" ? isDark ? "rgba(245, 166, 35, 0.30)" : "rgba(154, 82, 0, 0.25)" : colors.border;
1622
- const defaultIcon = variant === "success" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: ms(16), color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "error-outline", size: ms(17), color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: ms(17), color: accentColor }) : (
1640
+ const defaultIcon = variant === "success" ? /* @__PURE__ */ React54__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: ms(16), color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React54__default.default.createElement(vectorIcons.MaterialIcons, { name: "error-outline", size: ms(17), color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React54__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: ms(17), color: accentColor }) : (
1623
1641
  // AUDIT FIX: default variant previously used colors.primary (near-black)
1624
1642
  // as the info icon tint — ambiguous and heavy. accentResolved gives it
1625
1643
  // a meaningful chromatic signal when an accent is defined.
1626
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: ms(16), color: accentColor })
1644
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: ms(16), color: accentColor })
1627
1645
  );
1628
1646
  const effectiveIcon = iconName ? renderIcon(iconName, ms(16), iconColor ?? accentColor) : icon ?? defaultIcon;
1629
1647
  const a11yLabel = description ? `${title}. ${description}` : title;
1630
- return /* @__PURE__ */ React25__default.default.createElement(
1648
+ return /* @__PURE__ */ React54__default.default.createElement(
1631
1649
  reactNative.View,
1632
1650
  {
1633
1651
  style: [
@@ -1638,9 +1656,9 @@ function AlertBanner({ title, description, variant = "default", icon, iconName,
1638
1656
  accessibilityRole: "alert",
1639
1657
  accessibilityLabel: a11yLabel
1640
1658
  },
1641
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles11.iconSlot }, effectiveIcon),
1642
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles11.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.description, { color: colors.foreground, opacity: 0.85 }], allowFontScaling: true }, description) : null),
1643
- onDismiss ? /* @__PURE__ */ React25__default.default.createElement(
1659
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles11.iconSlot }, effectiveIcon),
1660
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles11.content }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles11.description, { color: colors.foreground, opacity: 0.85 }], allowFontScaling: true }, description) : null),
1661
+ onDismiss ? /* @__PURE__ */ React54__default.default.createElement(
1644
1662
  reactNative.TouchableOpacity,
1645
1663
  {
1646
1664
  onPress: onDismiss,
@@ -1649,7 +1667,7 @@ function AlertBanner({ title, description, variant = "default", icon, iconName,
1649
1667
  accessibilityRole: "button",
1650
1668
  accessibilityLabel: "Dismiss"
1651
1669
  },
1652
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ms(16), color: colors.foregroundMuted })
1670
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "x", size: ms(16), color: colors.foregroundMuted })
1653
1671
  ) : null
1654
1672
  );
1655
1673
  }
@@ -1686,9 +1704,9 @@ var styles11 = reactNative.StyleSheet.create({
1686
1704
  function Progress({ value = 0, max = 100, variant = "default", style, accessibilityLabel }) {
1687
1705
  const { colors } = useTheme();
1688
1706
  const percent = Math.min(Math.max(value / max * 100, 0), 100);
1689
- const [trackWidth, setTrackWidth] = React25.useState(0);
1707
+ const [trackWidth, setTrackWidth] = React54.useState(0);
1690
1708
  const animatedWidth = Animated12.useSharedValue(0);
1691
- React25.useEffect(() => {
1709
+ React54.useEffect(() => {
1692
1710
  if (trackWidth === 0) return;
1693
1711
  animatedWidth.value = Animated12.withSpring(percent / 100 * trackWidth, SPRINGS.glide);
1694
1712
  }, [percent, trackWidth, animatedWidth]);
@@ -1696,7 +1714,7 @@ function Progress({ value = 0, max = 100, variant = "default", style, accessibil
1696
1714
  width: animatedWidth.value
1697
1715
  }));
1698
1716
  const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
1699
- return /* @__PURE__ */ React25__default.default.createElement(
1717
+ return /* @__PURE__ */ React54__default.default.createElement(
1700
1718
  reactNative.View,
1701
1719
  {
1702
1720
  style: [styles12.track, { backgroundColor: colors.surface }, style],
@@ -1705,7 +1723,7 @@ function Progress({ value = 0, max = 100, variant = "default", style, accessibil
1705
1723
  accessibilityLabel,
1706
1724
  accessibilityValue: { min: 0, max: 100, now: Math.round(percent) }
1707
1725
  },
1708
- /* @__PURE__ */ React25__default.default.createElement(
1726
+ /* @__PURE__ */ React54__default.default.createElement(
1709
1727
  Animated12__default.default.View,
1710
1728
  {
1711
1729
  style: [styles12.indicator, { backgroundColor: indicatorColor }, indicatorAnimatedStyle]
@@ -1729,7 +1747,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, act
1729
1747
  const { colors } = useTheme();
1730
1748
  const isCompact = size === "compact";
1731
1749
  const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
1732
- return /* @__PURE__ */ React25__default.default.createElement(
1750
+ return /* @__PURE__ */ React54__default.default.createElement(
1733
1751
  reactNative.View,
1734
1752
  {
1735
1753
  style: [
@@ -1739,7 +1757,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, act
1739
1757
  style
1740
1758
  ]
1741
1759
  },
1742
- effectiveIcon ? /* @__PURE__ */ React25__default.default.createElement(
1760
+ effectiveIcon ? /* @__PURE__ */ React54__default.default.createElement(
1743
1761
  reactNative.View,
1744
1762
  {
1745
1763
  style: [
@@ -1750,15 +1768,15 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, act
1750
1768
  },
1751
1769
  effectiveIcon
1752
1770
  ) : null,
1753
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles13.textWrapper }, /* @__PURE__ */ React25__default.default.createElement(
1771
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles13.textWrapper }, /* @__PURE__ */ React54__default.default.createElement(
1754
1772
  reactNative.Text,
1755
1773
  {
1756
1774
  style: [styles13.title, isCompact && styles13.titleCompact, { color: colors.foreground }],
1757
1775
  allowFontScaling: true
1758
1776
  },
1759
1777
  title
1760
- ), description && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1761
- !isCompact && (action ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles13.action }, action) : actionLabel && onAction ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles13.action }, /* @__PURE__ */ React25__default.default.createElement(Button, { label: actionLabel, variant: "primary", onPress: onAction })) : null)
1778
+ ), description && !isCompact ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles13.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1779
+ !isCompact && (action ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles13.action }, action) : actionLabel && onAction ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles13.action }, /* @__PURE__ */ React54__default.default.createElement(Button, { label: actionLabel, variant: "primary", onPress: onAction })) : null)
1762
1780
  );
1763
1781
  }
1764
1782
  var styles13 = reactNative.StyleSheet.create({
@@ -1817,7 +1835,7 @@ var styles13 = reactNative.StyleSheet.create({
1817
1835
  function useColorTransition(active, options = {}) {
1818
1836
  const { duration = TIMINGS.state.duration } = options;
1819
1837
  const progress = Animated12.useSharedValue(active ? 1 : 0);
1820
- React25.useEffect(() => {
1838
+ React54.useEffect(() => {
1821
1839
  progress.value = Animated12.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
1822
1840
  }, [active, duration, progress]);
1823
1841
  return progress;
@@ -1841,7 +1859,7 @@ function Textarea({
1841
1859
  ...props
1842
1860
  }) {
1843
1861
  const { colors } = useTheme();
1844
- const [focused, setFocused] = React25.useState(false);
1862
+ const [focused, setFocused] = React54.useState(false);
1845
1863
  const focusProgress = useColorTransition(focused, {
1846
1864
  duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
1847
1865
  });
@@ -1850,7 +1868,7 @@ function Textarea({
1850
1868
  borderColor: error ? colors.destructive : Animated12.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
1851
1869
  borderWidth: error ? 2 : Animated12.interpolate(focusProgress.value, [0, 1], [1, 2])
1852
1870
  }));
1853
- 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(
1871
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React54__default.default.createElement(
1854
1872
  Animated12__default.default.View,
1855
1873
  {
1856
1874
  style: [
@@ -1858,9 +1876,9 @@ function Textarea({
1858
1876
  { backgroundColor: colors.background }
1859
1877
  ]
1860
1878
  },
1861
- /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles14.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
1862
- resolvedPrefixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
1863
- /* @__PURE__ */ React25__default.default.createElement(
1879
+ /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [styles14.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
1880
+ resolvedPrefixIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
1881
+ /* @__PURE__ */ React54__default.default.createElement(
1864
1882
  reactNative.TextInput,
1865
1883
  {
1866
1884
  multiline: true,
@@ -1889,7 +1907,7 @@ function Textarea({
1889
1907
  ...props
1890
1908
  }
1891
1909
  )
1892
- ), error ? /* @__PURE__ */ React25__default.default.createElement(
1910
+ ), error ? /* @__PURE__ */ React54__default.default.createElement(
1893
1911
  reactNative.Text,
1894
1912
  {
1895
1913
  style: [styles14.helperText, { color: colors.destructive }],
@@ -1897,7 +1915,7 @@ function Textarea({
1897
1915
  accessibilityLiveRegion: "polite"
1898
1916
  },
1899
1917
  error
1900
- ) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1918
+ ) : null, !error && hint ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1901
1919
  }
1902
1920
  var styles14 = reactNative.StyleSheet.create({
1903
1921
  container: {
@@ -1957,7 +1975,7 @@ function Checkbox({
1957
1975
  // AUDIT FIX: opacity was applied only to the box, leaving the label at full
1958
1976
  // opacity when disabled — a contradictory visual signal. Now the entire row
1959
1977
  // dims uniformly so label and control communicate the same disabled state.
1960
- /* @__PURE__ */ React25__default.default.createElement(
1978
+ /* @__PURE__ */ React54__default.default.createElement(
1961
1979
  PressableButton,
1962
1980
  {
1963
1981
  style: [styles15.row, disabled && styles15.rowDisabled, style],
@@ -1969,7 +1987,7 @@ function Checkbox({
1969
1987
  accessibilityLabel: accessibilityLabel ?? label,
1970
1988
  accessibilityState: { checked, disabled: !!disabled }
1971
1989
  },
1972
- /* @__PURE__ */ React25__default.default.createElement(
1990
+ /* @__PURE__ */ React54__default.default.createElement(
1973
1991
  reactNativeEase.EaseView,
1974
1992
  {
1975
1993
  style: styles15.box,
@@ -1979,9 +1997,9 @@ function Checkbox({
1979
1997
  },
1980
1998
  transition: COLOR_TRANSITION
1981
1999
  },
1982
- /* @__PURE__ */ React25__default.default.createElement(reactNativeEase.EaseView, { animate: { opacity: checked ? 1 : 0 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
2000
+ /* @__PURE__ */ React54__default.default.createElement(reactNativeEase.EaseView, { animate: { opacity: checked ? 1 : 0 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
1983
2001
  ),
1984
- label ? /* @__PURE__ */ React25__default.default.createElement(
2002
+ label ? /* @__PURE__ */ React54__default.default.createElement(
1985
2003
  reactNative.Text,
1986
2004
  {
1987
2005
  style: [styles15.label, { color: colors.foreground }],
@@ -2033,7 +2051,7 @@ var DISABLED_OPACITY = 0.45;
2033
2051
  function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
2034
2052
  const { colors } = useTheme();
2035
2053
  const isDisabled = !!disabled;
2036
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [{ alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React25__default.default.createElement(
2054
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [{ alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React54__default.default.createElement(
2037
2055
  reactNative.TouchableOpacity,
2038
2056
  {
2039
2057
  onPress: () => {
@@ -2048,14 +2066,14 @@ function Switch({ checked = false, onCheckedChange, disabled, style, accessibili
2048
2066
  accessibilityState: { checked, disabled: isDisabled },
2049
2067
  style: styles16.touchable
2050
2068
  },
2051
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles16.trackContainer }, /* @__PURE__ */ React25__default.default.createElement(
2069
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles16.trackContainer }, /* @__PURE__ */ React54__default.default.createElement(
2052
2070
  reactNativeEase.EaseView,
2053
2071
  {
2054
2072
  style: [styles16.track, isDisabled && styles16.disabledTrack],
2055
2073
  animate: { backgroundColor: checked ? colors.primary : colors.surfaceStrong },
2056
2074
  transition: COLOR_TRANSITION
2057
2075
  }
2058
- ), /* @__PURE__ */ React25__default.default.createElement(
2076
+ ), /* @__PURE__ */ React54__default.default.createElement(
2059
2077
  reactNativeEase.EaseView,
2060
2078
  {
2061
2079
  style: [styles16.trackBorder, { borderWidth: 1.5 }],
@@ -2063,30 +2081,30 @@ function Switch({ checked = false, onCheckedChange, disabled, style, accessibili
2063
2081
  animate: { borderColor: checked ? "transparent" : colors.border },
2064
2082
  transition: COLOR_TRANSITION
2065
2083
  }
2066
- ), /* @__PURE__ */ React25__default.default.createElement(
2084
+ ), /* @__PURE__ */ React54__default.default.createElement(
2067
2085
  reactNativeEase.EaseView,
2068
2086
  {
2069
2087
  style: [styles16.thumb, { backgroundColor: colors.primaryForeground }],
2070
2088
  animate: { translateX: checked ? THUMB_TRAVEL : 0 },
2071
2089
  transition: SPRING_ELASTIC
2072
2090
  },
2073
- /* @__PURE__ */ React25__default.default.createElement(
2091
+ /* @__PURE__ */ React54__default.default.createElement(
2074
2092
  reactNativeEase.EaseView,
2075
2093
  {
2076
2094
  style: styles16.iconWrapper,
2077
2095
  animate: { opacity: checked ? isDisabled ? DISABLED_OPACITY : 1 : 0 },
2078
2096
  transition: OPACITY_TRANSITION
2079
2097
  },
2080
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })
2098
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })
2081
2099
  ),
2082
- /* @__PURE__ */ React25__default.default.createElement(
2100
+ /* @__PURE__ */ React54__default.default.createElement(
2083
2101
  reactNativeEase.EaseView,
2084
2102
  {
2085
2103
  style: styles16.iconWrapper,
2086
2104
  animate: { opacity: checked ? 0 : isDisabled ? DISABLED_OPACITY : 1 },
2087
2105
  transition: OPACITY_TRANSITION
2088
2106
  },
2089
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted })
2107
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted })
2090
2108
  )
2091
2109
  ))
2092
2110
  ));
@@ -2139,15 +2157,15 @@ function ToggleIcon({ pressed, iconName, activeIconName, icon, activeIcon, iconC
2139
2157
  return prop;
2140
2158
  };
2141
2159
  if (pressed) {
2142
- if (activeIconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? primaryColor));
2160
+ if (activeIconName) return /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? primaryColor));
2143
2161
  const active = renderProp(activeIcon);
2144
- if (active) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, active);
2145
- return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: iconSize, color: primaryColor });
2162
+ if (active) return /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, active);
2163
+ return /* @__PURE__ */ React54__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: iconSize, color: primaryColor });
2146
2164
  }
2147
- if (iconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? mutedColor));
2165
+ if (iconName) return /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? mutedColor));
2148
2166
  const custom = renderProp(icon);
2149
- if (custom) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, custom);
2150
- return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: mutedColor });
2167
+ if (custom) return /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, custom);
2168
+ return /* @__PURE__ */ React54__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: mutedColor });
2151
2169
  }
2152
2170
  var sizeStyles = {
2153
2171
  sm: { paddingHorizontal: s(12), paddingVertical: vs(8), minWidth: s(40), minHeight: vs(40) },
@@ -2178,7 +2196,7 @@ function Toggle({
2178
2196
  selectionAsync();
2179
2197
  onPressedChange?.(!pressed);
2180
2198
  };
2181
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [disabled && styles17.disabled, style] }, /* @__PURE__ */ React25__default.default.createElement(
2199
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [disabled && styles17.disabled, style] }, /* @__PURE__ */ React54__default.default.createElement(
2182
2200
  PressableButton,
2183
2201
  {
2184
2202
  onPress: handlePress,
@@ -2190,7 +2208,7 @@ function Toggle({
2190
2208
  accessibilityLabel: accessibilityLabel ?? label,
2191
2209
  accessibilityState: { selected: pressed, disabled: !!disabled }
2192
2210
  },
2193
- /* @__PURE__ */ React25__default.default.createElement(
2211
+ /* @__PURE__ */ React54__default.default.createElement(
2194
2212
  reactNativeEase.EaseView,
2195
2213
  {
2196
2214
  style: [styles17.base, sizeStyles[size], { borderWidth: 2 }],
@@ -2200,7 +2218,7 @@ function Toggle({
2200
2218
  },
2201
2219
  transition: COLOR_TRANSITION
2202
2220
  },
2203
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles17.inner }, /* @__PURE__ */ React25__default.default.createElement(
2221
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles17.inner }, /* @__PURE__ */ React54__default.default.createElement(
2204
2222
  ToggleIcon,
2205
2223
  {
2206
2224
  pressed,
@@ -2214,7 +2232,7 @@ function Toggle({
2214
2232
  primaryColor: colors.primary,
2215
2233
  mutedColor: colors.foregroundMuted
2216
2234
  }
2217
- ), label ? /* @__PURE__ */ React25__default.default.createElement(
2235
+ ), label ? /* @__PURE__ */ React54__default.default.createElement(
2218
2236
  reactNative.Text,
2219
2237
  {
2220
2238
  style: [styles17.label, { color: pressed ? colors.primary : colors.foreground }],
@@ -2244,9 +2262,9 @@ var styles17 = reactNative.StyleSheet.create({
2244
2262
  }
2245
2263
  });
2246
2264
  function useHover() {
2247
- const [hovered, setHovered] = React25.useState(false);
2248
- const onMouseEnter = React25.useCallback(() => setHovered(true), []);
2249
- const onMouseLeave = React25.useCallback(() => setHovered(false), []);
2265
+ const [hovered, setHovered] = React54.useState(false);
2266
+ const onMouseEnter = React54.useCallback(() => setHovered(true), []);
2267
+ const onMouseLeave = React54.useCallback(() => setHovered(false), []);
2250
2268
  if (reactNative.Platform.OS !== "web") {
2251
2269
  return { hovered: false, hoverHandlers: {} };
2252
2270
  }
@@ -2263,11 +2281,11 @@ function usePressScale({
2263
2281
  } = {}) {
2264
2282
  const scale2 = Animated12.useSharedValue(1);
2265
2283
  const { hovered, hoverHandlers } = useHover();
2266
- const onPressIn = React25.useCallback(() => {
2284
+ const onPressIn = React54.useCallback(() => {
2267
2285
  if (disabled) return;
2268
2286
  scale2.value = Animated12.withSpring(pressScale, pressInSpring);
2269
2287
  }, [disabled, pressScale, pressInSpring, scale2]);
2270
- const onPressOut = React25.useCallback(() => {
2288
+ const onPressOut = React54.useCallback(() => {
2271
2289
  if (disabled) return;
2272
2290
  scale2.value = Animated12.withSpring(1, pressOutSpring);
2273
2291
  }, [disabled, pressOutSpring, scale2]);
@@ -2300,7 +2318,7 @@ function RadioItem({
2300
2318
  // AUDIT FIX: opacity was applied only to the radio circle, leaving the label
2301
2319
  // at full opacity when disabled. The whole row now dims uniformly so users
2302
2320
  // get a single, consistent disabled signal across the entire item.
2303
- /* @__PURE__ */ React25__default.default.createElement(
2321
+ /* @__PURE__ */ React54__default.default.createElement(
2304
2322
  reactNative.TouchableOpacity,
2305
2323
  {
2306
2324
  style: [styles18.row, option.disabled && styles18.rowDisabled],
@@ -2319,14 +2337,14 @@ function RadioItem({
2319
2337
  accessibilityLabel: option.label,
2320
2338
  accessibilityState: { checked: selected, disabled: !!option.disabled }
2321
2339
  },
2322
- /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React25__default.default.createElement(
2340
+ /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React54__default.default.createElement(
2323
2341
  reactNativeEase.EaseView,
2324
2342
  {
2325
2343
  style: styles18.radio,
2326
2344
  animate: { borderColor: selected ? colors.primary : colors.border },
2327
2345
  transition: COLOR_TRANSITION
2328
2346
  },
2329
- /* @__PURE__ */ React25__default.default.createElement(
2347
+ /* @__PURE__ */ React54__default.default.createElement(
2330
2348
  reactNativeEase.EaseView,
2331
2349
  {
2332
2350
  style: [styles18.dot, { backgroundColor: colors.primary }],
@@ -2335,7 +2353,7 @@ function RadioItem({
2335
2353
  }
2336
2354
  )
2337
2355
  )),
2338
- /* @__PURE__ */ React25__default.default.createElement(
2356
+ /* @__PURE__ */ React54__default.default.createElement(
2339
2357
  reactNative.Text,
2340
2358
  {
2341
2359
  style: [styles18.label, { color: colors.foreground }],
@@ -2354,14 +2372,14 @@ function RadioGroup({
2354
2372
  style,
2355
2373
  accessibilityLabel
2356
2374
  }) {
2357
- return /* @__PURE__ */ React25__default.default.createElement(
2375
+ return /* @__PURE__ */ React54__default.default.createElement(
2358
2376
  reactNative.View,
2359
2377
  {
2360
2378
  style: [styles18.container, orientation === "horizontal" && styles18.horizontal, style],
2361
2379
  accessibilityRole: "radiogroup",
2362
2380
  accessibilityLabel
2363
2381
  },
2364
- options.map((option) => /* @__PURE__ */ React25__default.default.createElement(
2382
+ options.map((option) => /* @__PURE__ */ React54__default.default.createElement(
2365
2383
  RadioItem,
2366
2384
  {
2367
2385
  key: option.value,
@@ -2417,7 +2435,7 @@ function TabTrigger({
2417
2435
  }) {
2418
2436
  const { colors } = useTheme();
2419
2437
  const isUnderline = variant === "underline";
2420
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { onLayout, style: styles19.triggerWrap }, /* @__PURE__ */ React25__default.default.createElement(
2438
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { onLayout, style: styles19.triggerWrap }, /* @__PURE__ */ React54__default.default.createElement(
2421
2439
  PressableTab,
2422
2440
  {
2423
2441
  style: [
@@ -2432,7 +2450,7 @@ function TabTrigger({
2432
2450
  accessibilityState: { selected: isActive },
2433
2451
  accessibilityLabel: tab.label
2434
2452
  },
2435
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React25__default.default.createElement(
2453
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React54__default.default.createElement(
2436
2454
  reactNative.Text,
2437
2455
  {
2438
2456
  style: [
@@ -2450,14 +2468,14 @@ function TabTrigger({
2450
2468
  ));
2451
2469
  }
2452
2470
  function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
2453
- const [internal, setInternal] = React25.useState(tabs[0]?.value ?? "");
2471
+ const [internal, setInternal] = React54.useState(tabs[0]?.value ?? "");
2454
2472
  const { colors } = useTheme();
2455
2473
  const active = value ?? internal;
2456
- const tabLayouts = React25.useRef({});
2474
+ const tabLayouts = React54.useRef({});
2457
2475
  const pillX = Animated12.useSharedValue(0);
2458
2476
  const pillWidth = Animated12.useSharedValue(0);
2459
- const initialised = React25.useRef(false);
2460
- const animatePill = React25.useCallback((tabValue, animate) => {
2477
+ const initialised = React54.useRef(false);
2478
+ const animatePill = React54.useCallback((tabValue, animate) => {
2461
2479
  const layout = tabLayouts.current[tabValue];
2462
2480
  if (!layout) return;
2463
2481
  if (animate) {
@@ -2468,7 +2486,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2468
2486
  pillWidth.value = layout.width;
2469
2487
  }
2470
2488
  }, [pillX, pillWidth]);
2471
- React25.useEffect(() => {
2489
+ React54.useEffect(() => {
2472
2490
  if (initialised.current) animatePill(active, true);
2473
2491
  }, [active, animatePill]);
2474
2492
  const handlePress = (v) => {
@@ -2480,7 +2498,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2480
2498
  transform: [{ translateX: pillX.value }],
2481
2499
  width: pillWidth.value
2482
2500
  }));
2483
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React25__default.default.createElement(
2501
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React54__default.default.createElement(
2484
2502
  reactNative.View,
2485
2503
  {
2486
2504
  style: [
@@ -2488,7 +2506,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2488
2506
  ],
2489
2507
  accessibilityRole: "tablist"
2490
2508
  },
2491
- variant === "pill" && /* @__PURE__ */ React25__default.default.createElement(
2509
+ variant === "pill" && /* @__PURE__ */ React54__default.default.createElement(
2492
2510
  Animated12__default.default.View,
2493
2511
  {
2494
2512
  style: [
@@ -2510,7 +2528,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2510
2528
  ]
2511
2529
  }
2512
2530
  ),
2513
- tabs.map((tab) => /* @__PURE__ */ React25__default.default.createElement(
2531
+ tabs.map((tab) => /* @__PURE__ */ React54__default.default.createElement(
2514
2532
  TabTrigger,
2515
2533
  {
2516
2534
  key: tab.value,
@@ -2532,7 +2550,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
2532
2550
  }
2533
2551
  function TabsContent({ value, activeValue, children, style }) {
2534
2552
  if (value !== activeValue) return null;
2535
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style, accessibilityRole: "none" }, children);
2553
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style, accessibilityRole: "none" }, children);
2536
2554
  }
2537
2555
  var styles19 = reactNative.StyleSheet.create({
2538
2556
  list: {
@@ -2593,7 +2611,7 @@ function AccordionItemComponent({
2593
2611
  const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
2594
2612
  const isExpanded = Animated12.useSharedValue(isOpen);
2595
2613
  const height = Animated12.useSharedValue(0);
2596
- React25__default.default.useEffect(() => {
2614
+ React54__default.default.useEffect(() => {
2597
2615
  isExpanded.value = isOpen;
2598
2616
  }, [isOpen, isExpanded]);
2599
2617
  const derivedHeight = Animated12.useDerivedValue(
@@ -2615,7 +2633,7 @@ function AccordionItemComponent({
2615
2633
  const rotationStyle = Animated12.useAnimatedStyle(() => ({
2616
2634
  transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
2617
2635
  }));
2618
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React25__default.default.createElement(
2636
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React54__default.default.createElement(
2619
2637
  reactNative.Pressable,
2620
2638
  {
2621
2639
  style: ({ pressed }) => [styles20.trigger, { opacity: pressed ? 0.6 : 1 }],
@@ -2627,9 +2645,9 @@ function AccordionItemComponent({
2627
2645
  accessibilityState: { expanded: isOpen },
2628
2646
  accessibilityLabel: typeof item.trigger === "string" ? item.trigger : void 0
2629
2647
  },
2630
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, typeof item.trigger === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger) : item.trigger),
2631
- /* @__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 }))
2632
- ), /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
2648
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, typeof item.trigger === "string" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger) : item.trigger),
2649
+ /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2650
+ ), /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React54__default.default.createElement(
2633
2651
  reactNative.View,
2634
2652
  {
2635
2653
  style: styles20.content,
@@ -2637,11 +2655,11 @@ function AccordionItemComponent({
2637
2655
  height.value = e.nativeEvent.layout.height;
2638
2656
  }
2639
2657
  },
2640
- typeof item.content === "string" || typeof item.content === "number" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.contentText, { color: colors.foregroundMuted }], allowFontScaling: true }, item.content) : item.content
2658
+ typeof item.content === "string" || typeof item.content === "number" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles20.contentText, { color: colors.foregroundMuted }], allowFontScaling: true }, item.content) : item.content
2641
2659
  )));
2642
2660
  }
2643
2661
  function Accordion({ items, type = "single", defaultValue, style }) {
2644
- const [openValues, setOpenValues] = React25.useState(() => {
2662
+ const [openValues, setOpenValues] = React54.useState(() => {
2645
2663
  if (!defaultValue) return [];
2646
2664
  return Array.isArray(defaultValue) ? defaultValue : [defaultValue];
2647
2665
  });
@@ -2654,7 +2672,7 @@ function Accordion({ items, type = "single", defaultValue, style }) {
2654
2672
  );
2655
2673
  }
2656
2674
  };
2657
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.list, style] }, items.map((item) => /* @__PURE__ */ React25__default.default.createElement(
2675
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles20.list, style] }, items.map((item) => /* @__PURE__ */ React54__default.default.createElement(
2658
2676
  AccordionItemComponent,
2659
2677
  {
2660
2678
  key: item.value,
@@ -2726,7 +2744,7 @@ function Slider({
2726
2744
  style
2727
2745
  }) {
2728
2746
  const { colors } = useTheme();
2729
- const lastSteppedValue = React25.useRef(value);
2747
+ const lastSteppedValue = React54.useRef(value);
2730
2748
  const handleValueChange = (v) => {
2731
2749
  if (step && v !== lastSteppedValue.current) {
2732
2750
  lastSteppedValue.current = v;
@@ -2734,7 +2752,7 @@ function Slider({
2734
2752
  }
2735
2753
  onValueChange?.(v);
2736
2754
  };
2737
- return /* @__PURE__ */ React25__default.default.createElement(
2755
+ return /* @__PURE__ */ React54__default.default.createElement(
2738
2756
  reactNative.View,
2739
2757
  {
2740
2758
  style: [styles21.wrapper, style],
@@ -2747,8 +2765,8 @@ function Slider({
2747
2765
  text: formatValue2(value)
2748
2766
  }
2749
2767
  },
2750
- label || showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles21.header }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null,
2751
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React25__default.default.createElement(
2768
+ label || showValue ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles21.header }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null,
2769
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React54__default.default.createElement(
2752
2770
  RNSlider__default.default,
2753
2771
  {
2754
2772
  value,
@@ -2792,73 +2810,69 @@ var styles21 = reactNative.StyleSheet.create({
2792
2810
  opacity: 0.45
2793
2811
  }
2794
2812
  });
2795
- var SCREEN_HEIGHT = reactNative.Dimensions.get("window").height;
2796
- var DEFAULT_MAX_HEIGHT = SCREEN_HEIGHT * 0.85;
2797
- var isAndroid = reactNative.Platform.OS === "android";
2798
2813
  function SheetHeader({ children, style }) {
2799
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.header, style] }, children);
2814
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles22.header, style] }, children);
2800
2815
  }
2801
2816
  function SheetContent({ children, style }) {
2802
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.sheetContent, style] }, children);
2817
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles22.sheetContent, style] }, children);
2803
2818
  }
2804
2819
  function SheetFooter({ children, style }) {
2805
2820
  const { colors } = useTheme();
2806
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.sheetFooter, { backgroundColor: colors.card, borderTopColor: colors.border }, style] }, children);
2821
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles22.sheetFooter, { backgroundColor: colors.card, borderTopColor: colors.border }, style] }, children);
2807
2822
  }
2808
2823
  function Sheet({
2809
2824
  open,
2810
2825
  onClose,
2811
2826
  title,
2812
2827
  subtitle,
2813
- description,
2814
2828
  showCloseButton = false,
2815
2829
  children,
2816
2830
  style,
2817
2831
  contentStyle,
2818
- scrollable,
2832
+ scrollable = false,
2819
2833
  maxHeight,
2820
- keyboardBehavior,
2834
+ keyboardBehavior = "interactive",
2821
2835
  keyboardBlurBehavior = "restore",
2822
2836
  enableBlurKeyboardOnGesture = true,
2823
2837
  android_keyboardInputMode = "adjustPan",
2824
2838
  footer,
2825
- snapPoints,
2826
- responsive = false,
2827
- dialogMaxWidth = 480
2839
+ snapPoints
2828
2840
  }) {
2829
2841
  const { colors } = useTheme();
2830
2842
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
2831
- const { width: windowWidth } = reactNative.useWindowDimensions();
2832
- const ref = React25.useRef(null);
2833
- const asDialog = responsive && windowWidth >= BREAKPOINTS.wide;
2834
- const effectiveKeyboardBehavior = keyboardBehavior ?? "interactive";
2835
- React25.useEffect(() => {
2843
+ const ref = React54.useRef(null);
2844
+ const wasOpened = React54.useRef(false);
2845
+ const name = React54.useId();
2846
+ React54.useEffect(() => {
2836
2847
  if (open) {
2837
2848
  impactMedium();
2838
- ref.current?.snapToIndex(0);
2839
- } else {
2840
- ref.current?.close();
2849
+ ref.current?.present();
2850
+ wasOpened.current = true;
2851
+ } else if (wasOpened.current) {
2852
+ ref.current?.dismiss();
2841
2853
  }
2842
2854
  }, [open]);
2843
- const renderBackdrop = React25.useCallback((props) => /* @__PURE__ */ React25__default.default.createElement(
2844
- BottomSheet.BottomSheetBackdrop,
2845
- {
2846
- ...props,
2847
- disappearsOnIndex: -1,
2848
- appearsOnIndex: 0,
2849
- pressBehavior: "close"
2850
- }
2851
- ), []);
2852
- const childArray = React25__default.default.Children.toArray(children);
2853
- const customHeader = childArray.find((child) => React25__default.default.isValidElement(child) && child.type === SheetHeader);
2854
- const customContent = childArray.find((child) => React25__default.default.isValidElement(child) && child.type === SheetContent);
2855
- const customFooter = childArray.find((child) => React25__default.default.isValidElement(child) && child.type === SheetFooter);
2855
+ const renderBackdrop = React54.useCallback(
2856
+ (props) => /* @__PURE__ */ React54__default.default.createElement(
2857
+ bottomSheet.BottomSheetBackdrop,
2858
+ {
2859
+ ...props,
2860
+ disappearsOnIndex: -1,
2861
+ appearsOnIndex: 0,
2862
+ pressBehavior: "close"
2863
+ }
2864
+ ),
2865
+ []
2866
+ );
2867
+ const childArray = React54__default.default.Children.toArray(children);
2868
+ const customHeader = childArray.find((child) => React54__default.default.isValidElement(child) && child.type === SheetHeader);
2869
+ const customContent = childArray.find((child) => React54__default.default.isValidElement(child) && child.type === SheetContent);
2870
+ const customFooter = childArray.find((child) => React54__default.default.isValidElement(child) && child.type === SheetFooter);
2856
2871
  const filteredChildren = customHeader || customContent || customFooter ? childArray.filter(
2857
- (child) => !React25__default.default.isValidElement(child) || child.type !== SheetHeader && child.type !== SheetContent && child.type !== SheetFooter
2872
+ (child) => !React54__default.default.isValidElement(child) || child.type !== SheetHeader && child.type !== SheetContent && child.type !== SheetFooter
2858
2873
  ) : children;
2859
- const effectiveSubtitle = subtitle ?? description;
2860
- const showHeader = !!(title || effectiveSubtitle || showCloseButton) && !customHeader;
2861
- const headerNode = customHeader ? customHeader : showHeader ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.header, { backgroundColor: colors.card }], accessibilityRole: "header" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React25__default.default.createElement(
2874
+ const showHeader = !!(title || subtitle || showCloseButton) && !customHeader;
2875
+ const headerNode = customHeader ? customHeader : showHeader ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles22.header, { backgroundColor: colors.card }], accessibilityRole: "header" }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React54__default.default.createElement(
2862
2876
  reactNative.TouchableOpacity,
2863
2877
  {
2864
2878
  onPress: onClose,
@@ -2869,78 +2883,50 @@ function Sheet({
2869
2883
  accessibilityLabel: "Close",
2870
2884
  hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }
2871
2885
  },
2872
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: "close", size: ms(18), color: colors.foregroundMuted })
2873
- ) : null), effectiveSubtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null) : null;
2886
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.AntDesign, { name: "close", size: ms(18), color: colors.foregroundMuted })
2887
+ ) : null), subtitle ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, subtitle) : null) : null;
2874
2888
  const contentNode = customContent ? customContent : filteredChildren;
2875
2889
  const effectiveFooter = customFooter ? customFooter : footer;
2876
- const renderFooter = React25.useCallback((props) => {
2877
- if (!effectiveFooter) return null;
2878
- return /* @__PURE__ */ React25__default.default.createElement(BottomSheet.BottomSheetFooter, { ...props }, effectiveFooter);
2879
- }, [effectiveFooter]);
2880
- if (asDialog) {
2881
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Modal, { visible: open, transparent: true, animationType: "fade", onRequestClose: onClose }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Pressable, { style: styles22.dialogBackdrop, onPress: onClose, accessibilityRole: "button", accessibilityLabel: "Close" }, /* @__PURE__ */ React25__default.default.createElement(
2882
- reactNative.Pressable,
2883
- {
2884
- style: [
2885
- styles22.dialogCard,
2886
- { backgroundColor: colors.card, maxWidth: dialogMaxWidth, maxHeight: SCREEN_HEIGHT * 0.85 }
2887
- ],
2888
- onPress: () => {
2889
- }
2890
- },
2891
- headerNode,
2892
- /* @__PURE__ */ React25__default.default.createElement(
2893
- reactNative.ScrollView,
2894
- {
2895
- contentContainerStyle: [styles22.dialogContent, style],
2896
- style: contentStyle,
2897
- showsVerticalScrollIndicator: true,
2898
- bounces: false
2899
- },
2900
- contentNode
2901
- ),
2902
- effectiveFooter
2903
- )));
2904
- }
2905
- const useScroll = scrollable || !!maxHeight;
2906
- const effectiveMaxHeight = maxHeight ?? DEFAULT_MAX_HEIGHT;
2890
+ const renderFooter = React54.useCallback(
2891
+ (props) => {
2892
+ if (!effectiveFooter) return null;
2893
+ return /* @__PURE__ */ React54__default.default.createElement(bottomSheet.BottomSheetFooter, { ...props }, effectiveFooter);
2894
+ },
2895
+ [effectiveFooter]
2896
+ );
2907
2897
  const useDynamicSizing = !snapPoints;
2908
- return /* @__PURE__ */ React25__default.default.createElement(
2909
- BottomSheet__default.default,
2898
+ return /* @__PURE__ */ React54__default.default.createElement(
2899
+ bottomSheet.BottomSheetModal,
2910
2900
  {
2911
2901
  ref,
2912
- index: -1,
2913
- onClose,
2902
+ name,
2903
+ onDismiss: onClose,
2914
2904
  enableDynamicSizing: useDynamicSizing,
2915
2905
  snapPoints,
2916
- maxDynamicContentSize: useDynamicSizing ? effectiveMaxHeight : void 0,
2906
+ maxDynamicContentSize: useDynamicSizing && maxHeight ? maxHeight : void 0,
2917
2907
  backdropComponent: renderBackdrop,
2918
2908
  footerComponent: effectiveFooter ? renderFooter : void 0,
2919
- backgroundStyle: [styles22.background, { backgroundColor: colors.card }],
2920
- handleIndicatorStyle: [styles22.handle, { backgroundColor: colors.border }],
2909
+ backgroundStyle: { ...styles22.background, backgroundColor: colors.card },
2910
+ handleIndicatorStyle: { ...styles22.handle, backgroundColor: colors.border },
2921
2911
  enablePanDownToClose: true,
2922
2912
  topInset: insets.top,
2923
- keyboardBehavior: effectiveKeyboardBehavior,
2913
+ keyboardBehavior,
2924
2914
  keyboardBlurBehavior,
2925
2915
  android_keyboardInputMode,
2926
2916
  enableBlurKeyboardOnGesture
2927
2917
  },
2928
- useScroll ? /* @__PURE__ */ React25__default.default.createElement(
2929
- BottomSheet.BottomSheetScrollView,
2918
+ scrollable ? /* @__PURE__ */ React54__default.default.createElement(
2919
+ bottomSheet.BottomSheetScrollView,
2930
2920
  {
2931
- contentContainerStyle: [
2932
- styles22.scrollContent,
2933
- style
2934
- ],
2921
+ contentContainerStyle: [styles22.scrollContent, style],
2935
2922
  style: contentStyle,
2936
2923
  showsVerticalScrollIndicator: true,
2937
- indicatorStyle: "black",
2938
- persistentScrollbar: isAndroid,
2924
+ bounces: false,
2939
2925
  stickyHeaderIndices: headerNode ? [0] : void 0
2940
2926
  },
2941
2927
  headerNode,
2942
2928
  contentNode
2943
- ) : /* @__PURE__ */ React25__default.default.createElement(BottomSheet.BottomSheetView, { style: [styles22.content, contentStyle, style] }, headerNode, contentNode)
2929
+ ) : /* @__PURE__ */ React54__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles22.content, contentStyle, style] }, headerNode, contentNode)
2944
2930
  );
2945
2931
  }
2946
2932
  Sheet.Header = SheetHeader;
@@ -2987,8 +2973,7 @@ var styles22 = reactNative.StyleSheet.create({
2987
2973
  },
2988
2974
  scrollContent: {
2989
2975
  paddingHorizontal: s(16),
2990
- paddingBottom: vs(32),
2991
- paddingRight: s(16)
2976
+ paddingBottom: vs(32)
2992
2977
  },
2993
2978
  sheetContent: {
2994
2979
  gap: vs(16)
@@ -2999,28 +2984,10 @@ var styles22 = reactNative.StyleSheet.create({
2999
2984
  borderTopWidth: 1,
3000
2985
  flexDirection: "row",
3001
2986
  gap: s(12)
3002
- },
3003
- dialogBackdrop: {
3004
- flex: 1,
3005
- backgroundColor: "rgba(0,0,0,0.5)",
3006
- alignItems: "center",
3007
- justifyContent: "center",
3008
- padding: s(24)
3009
- },
3010
- dialogCard: {
3011
- width: "100%",
3012
- borderRadius: RADIUS.lg,
3013
- paddingTop: vs(16),
3014
- overflow: "hidden",
3015
- ...SHADOWS.xl
3016
- },
3017
- dialogContent: {
3018
- paddingHorizontal: s(16),
3019
- paddingBottom: vs(16)
3020
2987
  }
3021
2988
  });
3022
2989
  var isIOS = reactNative.Platform.OS === "ios";
3023
- var isAndroid2 = reactNative.Platform.OS === "android";
2990
+ var isAndroid = reactNative.Platform.OS === "android";
3024
2991
  var isWeb2 = reactNative.Platform.OS === "web";
3025
2992
  function Select({
3026
2993
  options,
@@ -3038,9 +3005,9 @@ function Select({
3038
3005
  pressScale: PRESS_SCALE.button,
3039
3006
  disabled
3040
3007
  });
3041
- const [pickerVisible, setPickerVisible] = React25.useState(false);
3042
- const [pendingValue, setPendingValue] = React25.useState(value);
3043
- const pickerRef = React25.useRef(null);
3008
+ const [pickerVisible, setPickerVisible] = React54.useState(false);
3009
+ const [pendingValue, setPendingValue] = React54.useState(value);
3010
+ const pickerRef = React54.useRef(null);
3044
3011
  const selected = options.find((o) => o.value === value);
3045
3012
  const handleOpen = () => {
3046
3013
  if (disabled) return;
@@ -3048,7 +3015,7 @@ function Select({
3048
3015
  if (isIOS) {
3049
3016
  setPendingValue(value);
3050
3017
  setPickerVisible(true);
3051
- } else if (isAndroid2) {
3018
+ } else if (isAndroid) {
3052
3019
  pickerRef.current?.focus?.();
3053
3020
  }
3054
3021
  };
@@ -3062,7 +3029,7 @@ function Select({
3062
3029
  }
3063
3030
  setPickerVisible(false);
3064
3031
  };
3065
- 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(
3032
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React54__default.default.createElement(
3066
3033
  reactNative.TouchableOpacity,
3067
3034
  {
3068
3035
  style: [
@@ -3082,7 +3049,7 @@ function Select({
3082
3049
  accessibilityValue: { text: selected?.label ?? placeholder },
3083
3050
  accessibilityState: { disabled: !!disabled, expanded: pickerVisible }
3084
3051
  },
3085
- /* @__PURE__ */ React25__default.default.createElement(
3052
+ /* @__PURE__ */ React54__default.default.createElement(
3086
3053
  reactNative.Text,
3087
3054
  {
3088
3055
  style: [
@@ -3094,8 +3061,8 @@ function Select({
3094
3061
  },
3095
3062
  selected?.label ?? placeholder
3096
3063
  ),
3097
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 20, color: colors.foregroundMuted })
3098
- )) : null, isIOS ? /* @__PURE__ */ React25__default.default.createElement(
3064
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 20, color: colors.foregroundMuted })
3065
+ )) : null, isIOS ? /* @__PURE__ */ React54__default.default.createElement(
3099
3066
  reactNative.Modal,
3100
3067
  {
3101
3068
  visible: pickerVisible,
@@ -3103,16 +3070,16 @@ function Select({
3103
3070
  animationType: "slide",
3104
3071
  onRequestClose: handleDismiss
3105
3072
  },
3106
- /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { style: styles23.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
3107
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, null), /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: handleConfirm, style: styles23.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React25__default.default.createElement(
3073
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.TouchableOpacity, { style: styles23.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
3074
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles23.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles23.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles23.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, null), /* @__PURE__ */ React54__default.default.createElement(reactNative.TouchableOpacity, { onPress: handleConfirm, style: styles23.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles23.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React54__default.default.createElement(
3108
3075
  picker.Picker,
3109
3076
  {
3110
3077
  selectedValue: pendingValue ?? "",
3111
3078
  onValueChange: (val) => setPendingValue(val),
3112
3079
  itemStyle: { color: colors.foreground }
3113
3080
  },
3114
- !value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
3115
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
3081
+ !value ? /* @__PURE__ */ React54__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
3082
+ options.map((o) => /* @__PURE__ */ React54__default.default.createElement(
3116
3083
  picker.Picker.Item,
3117
3084
  {
3118
3085
  key: o.value,
@@ -3123,7 +3090,7 @@ function Select({
3123
3090
  }
3124
3091
  ))
3125
3092
  ))
3126
- ) : null, isAndroid2 ? /* @__PURE__ */ React25__default.default.createElement(
3093
+ ) : null, isAndroid ? /* @__PURE__ */ React54__default.default.createElement(
3127
3094
  picker.Picker,
3128
3095
  {
3129
3096
  ref: pickerRef,
@@ -3139,8 +3106,8 @@ function Select({
3139
3106
  prompt: label,
3140
3107
  style: styles23.androidHiddenPicker
3141
3108
  },
3142
- !value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
3143
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
3109
+ !value ? /* @__PURE__ */ React54__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
3110
+ options.map((o) => /* @__PURE__ */ React54__default.default.createElement(
3144
3111
  picker.Picker.Item,
3145
3112
  {
3146
3113
  key: o.value,
@@ -3149,7 +3116,7 @@ function Select({
3149
3116
  enabled: !o.disabled
3150
3117
  }
3151
3118
  ))
3152
- ) : null, isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(
3119
+ ) : null, isWeb2 ? /* @__PURE__ */ React54__default.default.createElement(
3153
3120
  picker.Picker,
3154
3121
  {
3155
3122
  selectedValue: value ?? "",
@@ -3169,8 +3136,8 @@ function Select({
3169
3136
  }
3170
3137
  ]
3171
3138
  },
3172
- /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }),
3173
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
3139
+ /* @__PURE__ */ React54__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }),
3140
+ options.map((o) => /* @__PURE__ */ React54__default.default.createElement(
3174
3141
  picker.Picker.Item,
3175
3142
  {
3176
3143
  key: o.value,
@@ -3179,7 +3146,7 @@ function Select({
3179
3146
  enabled: !o.disabled
3180
3147
  }
3181
3148
  ))
3182
- ) : null, error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
3149
+ ) : null, error ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles23.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
3183
3150
  }
3184
3151
  var styles23 = reactNative.StyleSheet.create({
3185
3152
  container: {
@@ -3260,7 +3227,7 @@ function useToast() {
3260
3227
  function ToastProvider({ children }) {
3261
3228
  const { colorScheme } = useTheme();
3262
3229
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
3263
- return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, children, /* @__PURE__ */ React25__default.default.createElement(
3230
+ return /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, children, /* @__PURE__ */ React54__default.default.createElement(
3264
3231
  sonnerNative.Toaster,
3265
3232
  {
3266
3233
  theme: colorScheme,
@@ -3310,7 +3277,8 @@ function CurrencyInput({
3310
3277
  editable,
3311
3278
  containerStyle,
3312
3279
  style,
3313
- sheetMode
3280
+ sheetMode,
3281
+ ...props
3314
3282
  }) {
3315
3283
  const handleChange = (text) => {
3316
3284
  const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text;
@@ -3328,9 +3296,10 @@ function CurrencyInput({
3328
3296
  fontSize: isLarge ? ms(32) : ms(17)
3329
3297
  };
3330
3298
  const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
3331
- return /* @__PURE__ */ React25__default.default.createElement(
3299
+ return /* @__PURE__ */ React54__default.default.createElement(
3332
3300
  Input,
3333
3301
  {
3302
+ ...props,
3334
3303
  value: displayValue,
3335
3304
  onChangeText: handleChange,
3336
3305
  keyboardType: "numeric",
@@ -3378,7 +3347,7 @@ function CurrencyDisplayBase({ value, prefix = "$", showDecimals = false, textCo
3378
3347
  const baseFontSize = variant ? variantFontSize[variant] : ms(56);
3379
3348
  const fontSize = maxFontSize ?? baseFontSize;
3380
3349
  const letterSpacing = variant ? variantLetterSpacing[variant] : -2;
3381
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles24.container, style] }, /* @__PURE__ */ React25__default.default.createElement(
3350
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles24.container, style] }, /* @__PURE__ */ React54__default.default.createElement(
3382
3351
  reactNative.Text,
3383
3352
  {
3384
3353
  style: [styles24.amount, { color: textColor ?? colors.foreground, fontSize, letterSpacing }],
@@ -3390,7 +3359,7 @@ function CurrencyDisplayBase({ value, prefix = "$", showDecimals = false, textCo
3390
3359
  formatted
3391
3360
  ));
3392
3361
  }
3393
- var CurrencyDisplay = React25__default.default.memo(CurrencyDisplayBase);
3362
+ var CurrencyDisplay = React54__default.default.memo(CurrencyDisplayBase);
3394
3363
  var styles24 = reactNative.StyleSheet.create({
3395
3364
  container: {
3396
3365
  alignSelf: "flex-start"
@@ -3405,8 +3374,7 @@ function ListItemBase({
3405
3374
  imageSource,
3406
3375
  leftRender,
3407
3376
  rightRender,
3408
- trailing,
3409
- icon,
3377
+ rightActions,
3410
3378
  leftIcon,
3411
3379
  rightIcon,
3412
3380
  leftIconColor,
@@ -3431,8 +3399,8 @@ function ListItemBase({
3431
3399
  selectionAsync();
3432
3400
  onPress?.();
3433
3401
  };
3434
- const effectiveLeft = imageSource ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Image, { source: imageSource, style: styles25.image }) : leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
3435
- const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
3402
+ const effectiveLeft = imageSource ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Image, { source: imageSource, style: styles25.image }) : leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender;
3403
+ const hasRightContent = !!(rightIcon || rightActions && rightActions.length > 0 || rightRender !== void 0 || showChevron);
3436
3404
  const cardStyle = variant === "card" ? {
3437
3405
  backgroundColor: colors.card,
3438
3406
  borderRadius: RADIUS.md,
@@ -3445,7 +3413,7 @@ function ListItemBase({
3445
3413
  elevation: 2
3446
3414
  } : {};
3447
3415
  const a11yLabel = accessibilityLabel ?? [title, subtitle, caption].filter(Boolean).join(". ");
3448
- const content = /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveLeft ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.leftContainer }, effectiveLeft) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.content }, /* @__PURE__ */ React25__default.default.createElement(
3416
+ const content = /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, effectiveLeft ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles25.leftContainer }, effectiveLeft) : null, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles25.content }, /* @__PURE__ */ React54__default.default.createElement(
3449
3417
  reactNative.Text,
3450
3418
  {
3451
3419
  style: [styles25.title, { color: colors.foreground }, titleStyle],
@@ -3453,7 +3421,7 @@ function ListItemBase({
3453
3421
  allowFontScaling: true
3454
3422
  },
3455
3423
  title
3456
- ), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
3424
+ ), subtitle ? /* @__PURE__ */ React54__default.default.createElement(
3457
3425
  reactNative.Text,
3458
3426
  {
3459
3427
  style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
@@ -3461,7 +3429,7 @@ function ListItemBase({
3461
3429
  allowFontScaling: true
3462
3430
  },
3463
3431
  subtitle
3464
- ) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(
3432
+ ) : null, caption ? /* @__PURE__ */ React54__default.default.createElement(
3465
3433
  reactNative.Text,
3466
3434
  {
3467
3435
  style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
@@ -3469,16 +3437,16 @@ function ListItemBase({
3469
3437
  allowFontScaling: true
3470
3438
  },
3471
3439
  caption
3472
- ) : null), effectiveRight !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25__default.default.createElement(
3440
+ ) : null), hasRightContent ? rightIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted)) : rightActions && rightActions.length > 0 ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles25.rightActionsContainer }, rightActions.map((action, i) => /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, { key: i }, action))) : rightRender !== void 0 ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof rightRender === "string" ? /* @__PURE__ */ React54__default.default.createElement(
3473
3441
  reactNative.Text,
3474
3442
  {
3475
3443
  style: [styles25.rightText, { color: colors.foregroundMuted }],
3476
3444
  allowFontScaling: true
3477
3445
  },
3478
- effectiveRight
3479
- ) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null);
3446
+ rightRender
3447
+ ) : rightRender) : showChevron ? /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null : null);
3480
3448
  if (onPress) {
3481
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: disabled && styles25.disabled }, /* @__PURE__ */ React25__default.default.createElement(
3449
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: disabled && styles25.disabled }, /* @__PURE__ */ React54__default.default.createElement(
3482
3450
  PressableRow,
3483
3451
  {
3484
3452
  style: [styles25.container, cardStyle, style],
@@ -3492,11 +3460,11 @@ function ListItemBase({
3492
3460
  accessibilityState: { disabled: !!disabled }
3493
3461
  },
3494
3462
  content
3495
- ), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles25.separator, { backgroundColor: colors.separator }] }) : null);
3463
+ ), showSeparator ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles25.separator, { backgroundColor: colors.separator }] }) : null);
3496
3464
  }
3497
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [disabled && styles25.disabled] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles25.container, cardStyle, style] }, content), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles25.separator, { backgroundColor: colors.separator }] }) : null);
3465
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [disabled && styles25.disabled] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles25.container, cardStyle, style] }, content), showSeparator ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles25.separator, { backgroundColor: colors.separator }] }) : null);
3498
3466
  }
3499
- var ListItem = React25__default.default.memo(ListItemBase);
3467
+ var ListItem = React54__default.default.memo(ListItemBase);
3500
3468
  var styles25 = reactNative.StyleSheet.create({
3501
3469
  container: {
3502
3470
  flexDirection: "row",
@@ -3543,6 +3511,12 @@ var styles25 = reactNative.StyleSheet.create({
3543
3511
  flexShrink: 0,
3544
3512
  maxWidth: s(160)
3545
3513
  },
3514
+ rightActionsContainer: {
3515
+ flexDirection: "row",
3516
+ alignItems: "center",
3517
+ gap: s(8),
3518
+ flexShrink: 0
3519
+ },
3546
3520
  rightText: {
3547
3521
  fontFamily: "Sohne-Regular",
3548
3522
  fontSize: ms(14)
@@ -3557,17 +3531,17 @@ var styles25 = reactNative.StyleSheet.create({
3557
3531
  });
3558
3532
  function ListGroup({ children, variant = "plain", style }) {
3559
3533
  const { colors } = useTheme();
3560
- const processedChildren = React25__default.default.Children.map(children, (child, index) => {
3561
- if (!React25__default.default.isValidElement(child)) return child;
3534
+ const processedChildren = React54__default.default.Children.map(children, (child, index) => {
3535
+ if (!React54__default.default.isValidElement(child)) return child;
3562
3536
  if (child.type === ListGroupHeader || child.type === ListGroupFooter) {
3563
3537
  return child;
3564
3538
  }
3565
3539
  const childProps = child.props;
3566
3540
  const isListItem = "title" in childProps;
3567
3541
  if (!isListItem) return child;
3568
- const isLast = index === React25__default.default.Children.count(children) - 1;
3542
+ const isLast = index === React54__default.default.Children.count(children) - 1;
3569
3543
  if (childProps["showSeparator"] === void 0 && !isLast) {
3570
- return React25__default.default.cloneElement(child, {
3544
+ return React54__default.default.cloneElement(child, {
3571
3545
  showSeparator: true
3572
3546
  });
3573
3547
  }
@@ -3585,21 +3559,21 @@ function ListGroup({ children, variant = "plain", style }) {
3585
3559
  elevation: 2,
3586
3560
  paddingVertical: vs(4)
3587
3561
  } : {};
3588
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.container, cardStyle, style] }, processedChildren);
3562
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles26.container, cardStyle, style] }, processedChildren);
3589
3563
  }
3590
3564
  function ListGroupHeader({ children, style }) {
3591
3565
  const { colors } = useTheme();
3592
3566
  if (typeof children === "string") {
3593
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.header, { borderBottomColor: colors.separator }, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles26.headerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3567
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles26.header, { borderBottomColor: colors.separator }, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles26.headerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3594
3568
  }
3595
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.header, { borderBottomColor: colors.separator }, style] }, children);
3569
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles26.header, { borderBottomColor: colors.separator }, style] }, children);
3596
3570
  }
3597
3571
  function ListGroupFooter({ children, style }) {
3598
3572
  const { colors } = useTheme();
3599
3573
  if (typeof children === "string") {
3600
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.footer, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles26.footerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3574
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles26.footer, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles26.footerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3601
3575
  }
3602
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.footer, style] }, children);
3576
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles26.footer, style] }, children);
3603
3577
  }
3604
3578
  ListGroup.Header = ListGroupHeader;
3605
3579
  ListGroup.Footer = ListGroupFooter;
@@ -3663,7 +3637,7 @@ function MenuItemBase({
3663
3637
  elevation: 2
3664
3638
  } : {};
3665
3639
  const a11yLabel = accessibilityLabel ?? (subtitle ? `${label}. ${subtitle}` : label);
3666
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: disabled && styles27.disabled }, /* @__PURE__ */ React25__default.default.createElement(
3640
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: disabled && styles27.disabled }, /* @__PURE__ */ React54__default.default.createElement(
3667
3641
  PressableRow,
3668
3642
  {
3669
3643
  style: [styles27.container, cardStyle, style],
@@ -3676,8 +3650,8 @@ function MenuItemBase({
3676
3650
  accessibilityLabel: a11yLabel,
3677
3651
  accessibilityState: { disabled }
3678
3652
  },
3679
- resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles27.iconContainer }, resolvedIcon) : null,
3680
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles27.labelContainer }, /* @__PURE__ */ React25__default.default.createElement(
3653
+ resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles27.iconContainer }, resolvedIcon) : null,
3654
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles27.labelContainer }, /* @__PURE__ */ React54__default.default.createElement(
3681
3655
  reactNative.Text,
3682
3656
  {
3683
3657
  style: [styles27.label, { color: colors.foreground }, labelStyle],
@@ -3685,7 +3659,7 @@ function MenuItemBase({
3685
3659
  allowFontScaling: true
3686
3660
  },
3687
3661
  label
3688
- ), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
3662
+ ), subtitle ? /* @__PURE__ */ React54__default.default.createElement(
3689
3663
  reactNative.Text,
3690
3664
  {
3691
3665
  style: [styles27.subtitle, { color: colors.foregroundMuted }],
@@ -3694,7 +3668,7 @@ function MenuItemBase({
3694
3668
  },
3695
3669
  subtitle
3696
3670
  ) : null),
3697
- rightRender !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(
3671
+ rightRender !== void 0 ? /* @__PURE__ */ React54__default.default.createElement(
3698
3672
  reactNative.View,
3699
3673
  {
3700
3674
  style: styles27.rightContainer,
@@ -3703,10 +3677,10 @@ function MenuItemBase({
3703
3677
  }
3704
3678
  },
3705
3679
  rightRender
3706
- ) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 18, color: colors.foregroundMuted }) : null
3707
- ), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles27.separator, { backgroundColor: colors.separator }] }) : null);
3680
+ ) : showChevron ? /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 18, color: colors.foregroundMuted }) : null
3681
+ ), showSeparator ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles27.separator, { backgroundColor: colors.separator }] }) : null);
3708
3682
  }
3709
- var MenuItem = React25__default.default.memo(MenuItemBase);
3683
+ var MenuItem = React54__default.default.memo(MenuItemBase);
3710
3684
  var styles27 = reactNative.StyleSheet.create({
3711
3685
  container: {
3712
3686
  flexDirection: "row",
@@ -3750,17 +3724,17 @@ var styles27 = reactNative.StyleSheet.create({
3750
3724
  });
3751
3725
  function MenuGroup({ children, variant = "plain", style }) {
3752
3726
  const { colors } = useTheme();
3753
- const processedChildren = React25__default.default.Children.map(children, (child, index) => {
3754
- if (!React25__default.default.isValidElement(child)) return child;
3727
+ const processedChildren = React54__default.default.Children.map(children, (child, index) => {
3728
+ if (!React54__default.default.isValidElement(child)) return child;
3755
3729
  if (child.type === MenuGroupHeader || child.type === MenuGroupFooter) {
3756
3730
  return child;
3757
3731
  }
3758
3732
  const childProps = child.props;
3759
3733
  const isMenuItem = "onPress" in childProps;
3760
3734
  if (!isMenuItem) return child;
3761
- const isLast = index === React25__default.default.Children.count(children) - 1;
3735
+ const isLast = index === React54__default.default.Children.count(children) - 1;
3762
3736
  if (childProps["showSeparator"] === void 0 && !isLast) {
3763
- return React25__default.default.cloneElement(child, {
3737
+ return React54__default.default.cloneElement(child, {
3764
3738
  showSeparator: true
3765
3739
  });
3766
3740
  }
@@ -3778,21 +3752,21 @@ function MenuGroup({ children, variant = "plain", style }) {
3778
3752
  elevation: 2,
3779
3753
  paddingVertical: vs(4)
3780
3754
  } : {};
3781
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, cardStyle, style] }, processedChildren);
3755
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles28.container, cardStyle, style] }, processedChildren);
3782
3756
  }
3783
3757
  function MenuGroupHeader({ children, style }) {
3784
3758
  const { colors } = useTheme();
3785
3759
  if (typeof children === "string") {
3786
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.header, { borderBottomColor: colors.separator }, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.headerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3760
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles28.header, { borderBottomColor: colors.separator }, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles28.headerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3787
3761
  }
3788
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.header, { borderBottomColor: colors.separator }, style] }, children);
3762
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles28.header, { borderBottomColor: colors.separator }, style] }, children);
3789
3763
  }
3790
3764
  function MenuGroupFooter({ children, style }) {
3791
3765
  const { colors } = useTheme();
3792
3766
  if (typeof children === "string") {
3793
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.footer, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.footerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3767
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles28.footer, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles28.footerText, { color: colors.foregroundMuted }], allowFontScaling: true }, children));
3794
3768
  }
3795
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.footer, style] }, children);
3769
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles28.footer, style] }, children);
3796
3770
  }
3797
3771
  MenuGroup.Header = MenuGroupHeader;
3798
3772
  MenuGroup.Footer = MenuGroupFooter;
@@ -3829,7 +3803,7 @@ function ChipBase({ label, selected = false, onPress, icon, iconName, style, acc
3829
3803
  onPress?.();
3830
3804
  };
3831
3805
  const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
3832
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles29.wrapper, style] }, /* @__PURE__ */ React25__default.default.createElement(
3806
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles29.wrapper, style] }, /* @__PURE__ */ React54__default.default.createElement(
3833
3807
  PressableChip,
3834
3808
  {
3835
3809
  onPress: handlePress,
@@ -3839,7 +3813,7 @@ function ChipBase({ label, selected = false, onPress, icon, iconName, style, acc
3839
3813
  accessibilityLabel: accessibilityLabel ?? label,
3840
3814
  accessibilityState: { selected }
3841
3815
  },
3842
- /* @__PURE__ */ React25__default.default.createElement(
3816
+ /* @__PURE__ */ React54__default.default.createElement(
3843
3817
  reactNativeEase.EaseView,
3844
3818
  {
3845
3819
  style: styles29.chip,
@@ -3849,8 +3823,8 @@ function ChipBase({ label, selected = false, onPress, icon, iconName, style, acc
3849
3823
  },
3850
3824
  transition: COLOR_TRANSITION
3851
3825
  },
3852
- resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles29.chipIcon }, resolvedIcon) : null,
3853
- /* @__PURE__ */ React25__default.default.createElement(
3826
+ resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles29.chipIcon }, resolvedIcon) : null,
3827
+ /* @__PURE__ */ React54__default.default.createElement(
3854
3828
  reactNative.Text,
3855
3829
  {
3856
3830
  style: [styles29.label, { color: selected ? colors.primaryForeground : colors.foreground }],
@@ -3861,7 +3835,7 @@ function ChipBase({ label, selected = false, onPress, icon, iconName, style, acc
3861
3835
  )
3862
3836
  ));
3863
3837
  }
3864
- var Chip = React25__default.default.memo(ChipBase);
3838
+ var Chip = React54__default.default.memo(ChipBase);
3865
3839
  function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
3866
3840
  const handlePress = (optionValue) => {
3867
3841
  if (!multiSelect) {
@@ -3877,7 +3851,7 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
3877
3851
  if (Array.isArray(value)) return value.includes(optionValue);
3878
3852
  return optionValue === value;
3879
3853
  };
3880
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles29.group, style] }, options.map((opt) => /* @__PURE__ */ React25__default.default.createElement(
3854
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles29.group, style] }, options.map((opt) => /* @__PURE__ */ React54__default.default.createElement(
3881
3855
  Chip,
3882
3856
  {
3883
3857
  key: opt.value,
@@ -3927,7 +3901,6 @@ function ConfirmDialog({
3927
3901
  visible,
3928
3902
  title,
3929
3903
  subtitle,
3930
- description,
3931
3904
  confirmLabel = "Confirm",
3932
3905
  cancelLabel = "Cancel",
3933
3906
  confirmVariant = "primary",
@@ -3937,38 +3910,45 @@ function ConfirmDialog({
3937
3910
  onCancel
3938
3911
  }) {
3939
3912
  const { colors } = useTheme();
3940
- const ref = React25.useRef(null);
3941
- const effectiveSubtitle = subtitle ?? description;
3942
- React25.useEffect(() => {
3913
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
3914
+ const ref = React54.useRef(null);
3915
+ const wasOpened = React54.useRef(false);
3916
+ const name = React54.useId();
3917
+ React54.useEffect(() => {
3943
3918
  if (visible) {
3944
3919
  impactMedium();
3945
- ref.current?.snapToIndex(0);
3946
- } else {
3947
- ref.current?.close();
3920
+ ref.current?.present();
3921
+ wasOpened.current = true;
3922
+ } else if (wasOpened.current) {
3923
+ ref.current?.dismiss();
3948
3924
  }
3949
3925
  }, [visible]);
3950
- const renderBackdrop = (props) => /* @__PURE__ */ React25__default.default.createElement(
3951
- BottomSheet.BottomSheetBackdrop,
3952
- {
3953
- ...props,
3954
- disappearsOnIndex: -1,
3955
- appearsOnIndex: 0,
3956
- pressBehavior: "close"
3957
- }
3926
+ const renderBackdrop = React54.useCallback(
3927
+ (props) => /* @__PURE__ */ React54__default.default.createElement(
3928
+ bottomSheet.BottomSheetBackdrop,
3929
+ {
3930
+ ...props,
3931
+ disappearsOnIndex: -1,
3932
+ appearsOnIndex: 0,
3933
+ pressBehavior: "close"
3934
+ }
3935
+ ),
3936
+ []
3958
3937
  );
3959
- return /* @__PURE__ */ React25__default.default.createElement(
3960
- BottomSheet__default.default,
3938
+ return /* @__PURE__ */ React54__default.default.createElement(
3939
+ bottomSheet.BottomSheetModal,
3961
3940
  {
3962
3941
  ref,
3963
- index: -1,
3964
- onClose: onCancel,
3942
+ name,
3943
+ onDismiss: onCancel,
3965
3944
  enableDynamicSizing: true,
3966
3945
  backdropComponent: renderBackdrop,
3967
- backgroundStyle: [styles30.background, { backgroundColor: colors.card }],
3968
- handleIndicatorStyle: [styles30.handle, { backgroundColor: colors.border }],
3969
- enablePanDownToClose: true
3946
+ backgroundStyle: { ...styles30.background, backgroundColor: colors.card },
3947
+ handleIndicatorStyle: { ...styles30.handle, backgroundColor: colors.border },
3948
+ enablePanDownToClose: true,
3949
+ topInset: insets.top
3970
3950
  },
3971
- /* @__PURE__ */ React25__default.default.createElement(BottomSheet.BottomSheetView, { style: styles30.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.header, accessibilityRole: "header" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.headerRow }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.title, { color: colors.foreground }], allowFontScaling: true }, title), showCloseButton ? /* @__PURE__ */ React25__default.default.createElement(
3951
+ /* @__PURE__ */ React54__default.default.createElement(bottomSheet.BottomSheetView, { style: styles30.content }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles30.header, accessibilityRole: "header" }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles30.headerRow }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles30.title, { color: colors.foreground }], allowFontScaling: true }, title), showCloseButton ? /* @__PURE__ */ React54__default.default.createElement(
3972
3952
  reactNative.TouchableOpacity,
3973
3953
  {
3974
3954
  onPress: onCancel,
@@ -3979,8 +3959,8 @@ function ConfirmDialog({
3979
3959
  accessibilityLabel: "Close",
3980
3960
  hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }
3981
3961
  },
3982
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ms(18), color: colors.foregroundMuted })
3983
- ) : null), effectiveSubtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.actions }, /* @__PURE__ */ React25__default.default.createElement(
3962
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "x", size: ms(18), color: colors.foregroundMuted })
3963
+ ) : null), subtitle ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles30.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, subtitle) : null), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles30.actions }, /* @__PURE__ */ React54__default.default.createElement(
3984
3964
  Button,
3985
3965
  {
3986
3966
  label: confirmLabel,
@@ -3992,7 +3972,7 @@ function ConfirmDialog({
3992
3972
  notificationSuccess();
3993
3973
  onConfirm();
3994
3974
  },
3995
- icon: /* @__PURE__ */ React25__default.default.createElement(
3975
+ icon: /* @__PURE__ */ React54__default.default.createElement(
3996
3976
  vectorIcons.Feather,
3997
3977
  {
3998
3978
  name: confirmVariant === "destructive" ? "trash-2" : "check",
@@ -4001,7 +3981,7 @@ function ConfirmDialog({
4001
3981
  }
4002
3982
  )
4003
3983
  }
4004
- ), /* @__PURE__ */ React25__default.default.createElement(
3984
+ ), /* @__PURE__ */ React54__default.default.createElement(
4005
3985
  Button,
4006
3986
  {
4007
3987
  label: cancelLabel,
@@ -4011,7 +3991,7 @@ function ConfirmDialog({
4011
3991
  selectionAsync();
4012
3992
  onCancel();
4013
3993
  },
4014
- icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
3994
+ icon: /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
4015
3995
  }
4016
3996
  )))
4017
3997
  );
@@ -4062,9 +4042,9 @@ var styles30 = reactNative.StyleSheet.create({
4062
4042
  function LabelValueBase({ label, value, iconName, iconColor, style }) {
4063
4043
  const { colors } = useTheme();
4064
4044
  const resolvedIcon = iconName ? renderIcon(iconName, ms(14), iconColor ?? colors.foregroundMuted) : null;
4065
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles31.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles31.labelSide }, resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles31.icon }, resolvedIcon) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label)), typeof value === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
4045
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles31.container, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles31.labelSide }, resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles31.icon }, resolvedIcon) : null, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles31.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label)), typeof value === "string" ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles31.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
4066
4046
  }
4067
- var LabelValue = React25__default.default.memo(LabelValueBase);
4047
+ var LabelValue = React54__default.default.memo(LabelValueBase);
4068
4048
  var styles31 = reactNative.StyleSheet.create({
4069
4049
  container: {
4070
4050
  flexDirection: "row",
@@ -4129,7 +4109,7 @@ function MonthPicker({ value, onChange, minValue, maxValue, locale = "en", forma
4129
4109
  selectionAsync();
4130
4110
  onChange(fromIndex(index + 1));
4131
4111
  };
4132
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles32.container, style], accessibilityRole: "adjustable", accessibilityLabel: getLabel() }, /* @__PURE__ */ React25__default.default.createElement(
4112
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles32.container, style], accessibilityRole: "adjustable", accessibilityLabel: getLabel() }, /* @__PURE__ */ React54__default.default.createElement(
4133
4113
  reactNative.TouchableOpacity,
4134
4114
  {
4135
4115
  style: [styles32.arrow, prevDisabled && styles32.arrowDisabled],
@@ -4142,8 +4122,8 @@ function MonthPicker({ value, onChange, minValue, maxValue, locale = "en", forma
4142
4122
  accessibilityState: { disabled: prevDisabled },
4143
4123
  hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
4144
4124
  },
4145
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
4146
- ), /* @__PURE__ */ React25__default.default.createElement(
4125
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
4126
+ ), /* @__PURE__ */ React54__default.default.createElement(
4147
4127
  reactNative.Text,
4148
4128
  {
4149
4129
  style: [styles32.label, { color: colors.foreground }],
@@ -4151,7 +4131,7 @@ function MonthPicker({ value, onChange, minValue, maxValue, locale = "en", forma
4151
4131
  accessibilityLiveRegion: "polite"
4152
4132
  },
4153
4133
  getLabel()
4154
- ), /* @__PURE__ */ React25__default.default.createElement(
4134
+ ), /* @__PURE__ */ React54__default.default.createElement(
4155
4135
  reactNative.TouchableOpacity,
4156
4136
  {
4157
4137
  style: [styles32.arrow, nextDisabled && styles32.arrowDisabled],
@@ -4164,7 +4144,7 @@ function MonthPicker({ value, onChange, minValue, maxValue, locale = "en", forma
4164
4144
  accessibilityState: { disabled: nextDisabled },
4165
4145
  hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
4166
4146
  },
4167
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
4147
+ /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
4168
4148
  ));
4169
4149
  }
4170
4150
  var styles32 = reactNative.StyleSheet.create({
@@ -4230,7 +4210,7 @@ function MediaCardBase({
4230
4210
  const ratio = aspectRatioMap2[aspectRatio];
4231
4211
  const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
4232
4212
  const a11yLabel = accessibilityLabel ?? [title, subtitle].filter(Boolean).join(". ");
4233
- const cardContent = /* @__PURE__ */ React25__default.default.createElement(
4213
+ const cardContent = /* @__PURE__ */ React54__default.default.createElement(
4234
4214
  reactNative.View,
4235
4215
  {
4236
4216
  style: [
@@ -4240,14 +4220,14 @@ function MediaCardBase({
4240
4220
  ],
4241
4221
  ...reactNative.Platform.OS === "web" ? hoverHandlers : {}
4242
4222
  },
4243
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles33.imageContainer, imageStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React25__default.default.createElement(
4223
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles33.imageContainer, imageStyle] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React54__default.default.createElement(
4244
4224
  reactNative.Image,
4245
4225
  {
4246
4226
  source: imageSource,
4247
4227
  style: styles33.image,
4248
4228
  resizeMode: "cover"
4249
4229
  }
4250
- ) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles33.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles33.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React25__default.default.createElement(
4230
+ ) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles33.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles33.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React54__default.default.createElement(
4251
4231
  reactNative.TouchableOpacity,
4252
4232
  {
4253
4233
  style: [styles33.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
@@ -4264,10 +4244,10 @@ function MediaCardBase({
4264
4244
  },
4265
4245
  resolvedActionIcon
4266
4246
  )),
4267
- (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)
4247
+ (title || subtitle || caption || footer) && /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles33.meta }, title ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles33.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles33.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles33.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
4268
4248
  );
4269
4249
  if (onPress) {
4270
- return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React25__default.default.createElement(
4250
+ return /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React54__default.default.createElement(
4271
4251
  reactNative.TouchableOpacity,
4272
4252
  {
4273
4253
  onPress: handlePress,
@@ -4283,7 +4263,7 @@ function MediaCardBase({
4283
4263
  }
4284
4264
  return cardContent;
4285
4265
  }
4286
- var MediaCard = React25__default.default.memo(MediaCardBase);
4266
+ var MediaCard = React54__default.default.memo(MediaCardBase);
4287
4267
  var styles33 = reactNative.StyleSheet.create({
4288
4268
  card: {
4289
4269
  borderRadius: RADIUS.md,
@@ -4341,7 +4321,7 @@ var styles33 = reactNative.StyleSheet.create({
4341
4321
  lineHeight: mvs(16)
4342
4322
  }
4343
4323
  });
4344
- var CategoryChip = React25__default.default.memo(function CategoryChip2({
4324
+ var CategoryChip = React54__default.default.memo(function CategoryChip2({
4345
4325
  item,
4346
4326
  selected,
4347
4327
  onSelect
@@ -4352,7 +4332,7 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
4352
4332
  });
4353
4333
  const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
4354
4334
  const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, iconColor) : item.icon ?? null;
4355
- return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React25__default.default.createElement(
4335
+ return /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React54__default.default.createElement(
4356
4336
  reactNative.TouchableOpacity,
4357
4337
  {
4358
4338
  onPress: () => onSelect(item.value),
@@ -4364,7 +4344,7 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
4364
4344
  accessibilityLabel: item.label,
4365
4345
  accessibilityState: { selected }
4366
4346
  },
4367
- /* @__PURE__ */ React25__default.default.createElement(
4347
+ /* @__PURE__ */ React54__default.default.createElement(
4368
4348
  reactNativeEase.EaseView,
4369
4349
  {
4370
4350
  style: styles34.chip,
@@ -4374,8 +4354,8 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
4374
4354
  },
4375
4355
  transition: COLOR_TRANSITION
4376
4356
  },
4377
- resolvedIcon && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles34.chipIcon }, resolvedIcon),
4378
- /* @__PURE__ */ React25__default.default.createElement(
4357
+ resolvedIcon && /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles34.chipIcon }, resolvedIcon),
4358
+ /* @__PURE__ */ React54__default.default.createElement(
4379
4359
  reactNative.Text,
4380
4360
  {
4381
4361
  style: [styles34.chipLabel, { color: selected ? colors.primaryForeground : colors.foregroundSubtle }],
@@ -4383,7 +4363,7 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
4383
4363
  },
4384
4364
  item.label
4385
4365
  ),
4386
- item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles34.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles34.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
4366
+ item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles34.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles34.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
4387
4367
  )
4388
4368
  ));
4389
4369
  });
@@ -4397,7 +4377,7 @@ function CategoryStrip({
4397
4377
  accessibilityLabel
4398
4378
  }) {
4399
4379
  const selected = Array.isArray(value) ? value : value ? [value] : [];
4400
- const handlePress = React25.useCallback(
4380
+ const handlePress = React54.useCallback(
4401
4381
  (v) => {
4402
4382
  selectionAsync();
4403
4383
  if (multiSelect) {
@@ -4410,7 +4390,7 @@ function CategoryStrip({
4410
4390
  },
4411
4391
  [multiSelect, value, onValueChange]
4412
4392
  );
4413
- return /* @__PURE__ */ React25__default.default.createElement(
4393
+ return /* @__PURE__ */ React54__default.default.createElement(
4414
4394
  reactNative.ScrollView,
4415
4395
  {
4416
4396
  horizontal: true,
@@ -4420,7 +4400,7 @@ function CategoryStrip({
4420
4400
  accessibilityRole: multiSelect ? void 0 : "radiogroup",
4421
4401
  accessibilityLabel
4422
4402
  },
4423
- categories.map((cat) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25__default.default.createElement(
4403
+ categories.map((cat) => /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React54__default.default.createElement(
4424
4404
  CategoryChip,
4425
4405
  {
4426
4406
  item: cat,
@@ -4471,21 +4451,24 @@ var styles34 = reactNative.StyleSheet.create({
4471
4451
  lineHeight: 14
4472
4452
  }
4473
4453
  });
4474
- function Pressable3({
4454
+ function Pressable2({
4475
4455
  children,
4476
4456
  onPress,
4477
4457
  pressScale: _pressScale = PRESS_SCALE.card,
4478
4458
  haptics = true,
4479
4459
  style,
4480
4460
  disabled,
4481
- hoverScale: _hoverScale = 1.02
4461
+ hoverScale: _hoverScale = 1.02,
4462
+ accessibilityRole,
4463
+ accessibilityState,
4464
+ accessibilityLabel
4482
4465
  }) {
4483
4466
  const handlePress = () => {
4484
4467
  if (disabled || !onPress) return;
4485
4468
  if (haptics) impactLight();
4486
4469
  onPress();
4487
4470
  };
4488
- return /* @__PURE__ */ React25__default.default.createElement(
4471
+ return /* @__PURE__ */ React54__default.default.createElement(
4489
4472
  PressableCard,
4490
4473
  {
4491
4474
  style,
@@ -4494,8 +4477,9 @@ function Pressable3({
4494
4477
  rippleColor: "transparent",
4495
4478
  touchSoundDisabled: true,
4496
4479
  activateOnHover: true,
4497
- accessibilityRole: "button",
4498
- accessibilityState: { disabled: !!disabled }
4480
+ accessibilityRole: accessibilityRole ?? "button",
4481
+ accessibilityState: accessibilityState ?? { disabled: !!disabled },
4482
+ accessibilityLabel
4499
4483
  },
4500
4484
  children
4501
4485
  );
@@ -4532,23 +4516,23 @@ function DetailRowBase({
4532
4516
  borderColor: "rgba(128,128,128,0.3)",
4533
4517
  marginHorizontal: s(4)
4534
4518
  };
4535
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles35.row, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles35.labelSide }, resolvedLeftIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles35.icon }, resolvedLeftIcon) : null, typeof label === "string" ? /* @__PURE__ */ React25__default.default.createElement(
4519
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles35.row, style] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles35.labelSide }, resolvedLeftIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles35.icon }, resolvedLeftIcon) : null, typeof label === "string" ? /* @__PURE__ */ React54__default.default.createElement(
4536
4520
  reactNative.Text,
4537
4521
  {
4538
4522
  style: [styles35.labelText, { color: colors.foregroundMuted, fontFamily: weightMap[labelWeight] }, labelStyle],
4539
4523
  allowFontScaling: true
4540
4524
  },
4541
4525
  label
4542
- ) : label), separatorStyle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: separatorStyle }) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles35.spacer }), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles35.valueSide }, typeof value === "string" ? /* @__PURE__ */ React25__default.default.createElement(
4526
+ ) : label), separatorStyle ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: separatorStyle }) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles35.spacer }), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles35.valueSide }, typeof value === "string" ? /* @__PURE__ */ React54__default.default.createElement(
4543
4527
  reactNative.Text,
4544
4528
  {
4545
4529
  style: [styles35.valueText, { color: valueColor ?? colors.foreground }, valueStyle],
4546
4530
  allowFontScaling: true
4547
4531
  },
4548
4532
  value
4549
- ) : value, resolvedRightIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles35.icon }, resolvedRightIcon) : null));
4533
+ ) : value, resolvedRightIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles35.icon }, resolvedRightIcon) : null));
4550
4534
  }
4551
- var DetailRow = React25__default.default.memo(DetailRowBase);
4535
+ var DetailRow = React54__default.default.memo(DetailRowBase);
4552
4536
  var styles35 = reactNative.StyleSheet.create({
4553
4537
  row: {
4554
4538
  flexDirection: "row",
@@ -4585,7 +4569,7 @@ var styles35 = reactNative.StyleSheet.create({
4585
4569
  }
4586
4570
  });
4587
4571
  function Form({ children, style }) {
4588
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles36.form, style] }, children);
4572
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles36.form, style] }, children);
4589
4573
  }
4590
4574
  function FormField({
4591
4575
  children,
@@ -4597,14 +4581,14 @@ function FormField({
4597
4581
  errorStyle
4598
4582
  }) {
4599
4583
  const { colors } = useTheme();
4600
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles36.field, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles36.label, { color: colors.foreground }, labelStyle], allowFontScaling: true }, label, required ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: { color: colors.destructive } }, " *") : null) : null, children, error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles36.error, { color: colors.destructive }, errorStyle], allowFontScaling: true }, error) : null);
4584
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles36.field, style] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles36.label, { color: colors.foreground }, labelStyle], allowFontScaling: true }, label, required ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: { color: colors.destructive } }, " *") : null) : null, children, error ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles36.error, { color: colors.destructive }, errorStyle], allowFontScaling: true }, error) : null);
4601
4585
  }
4602
4586
  function FormSection({ children, title, description, style }) {
4603
4587
  const { colors } = useTheme();
4604
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles36.section, style] }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles36.sectionHeader }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles36.sectionTitle, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles36.sectionDescription, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null, children);
4588
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles36.section, style] }, title ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles36.sectionHeader }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles36.sectionTitle, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles36.sectionDescription, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null, children);
4605
4589
  }
4606
4590
  function FormFooter({ children, style }) {
4607
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles36.footer, style] }, children);
4591
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles36.footer, style] }, children);
4608
4592
  }
4609
4593
  Form.Field = FormField;
4610
4594
  Form.Section = FormSection;
@@ -4653,7 +4637,7 @@ var defaultKeyExtractor = (item, index) => {
4653
4637
  return id !== void 0 ? String(id) : String(index);
4654
4638
  };
4655
4639
  function VirtualListInner({ itemHeight, keyExtractor, renderItem, ...props }, ref) {
4656
- const getItemLayout = React25.useCallback(
4640
+ const getItemLayout = React54.useCallback(
4657
4641
  (_data, index) => ({
4658
4642
  length: itemHeight ?? 0,
4659
4643
  offset: (itemHeight ?? 0) * index,
@@ -4661,7 +4645,7 @@ function VirtualListInner({ itemHeight, keyExtractor, renderItem, ...props }, re
4661
4645
  }),
4662
4646
  [itemHeight]
4663
4647
  );
4664
- return /* @__PURE__ */ React25__default.default.createElement(
4648
+ return /* @__PURE__ */ React54__default.default.createElement(
4665
4649
  reactNative.FlatList,
4666
4650
  {
4667
4651
  ref,
@@ -4673,9 +4657,9 @@ function VirtualListInner({ itemHeight, keyExtractor, renderItem, ...props }, re
4673
4657
  }
4674
4658
  );
4675
4659
  }
4676
- var VirtualList = React25__default.default.forwardRef(VirtualListInner);
4660
+ var VirtualList = React54__default.default.forwardRef(VirtualListInner);
4677
4661
  function RetrayProvider({ children, theme, colorScheme = "system" }) {
4678
- return /* @__PURE__ */ React25__default.default.createElement(reactNativeSafeAreaContext.SafeAreaProvider, { initialMetrics: reactNativeSafeAreaContext.initialWindowMetrics }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles37.root }, /* @__PURE__ */ React25__default.default.createElement(ThemeProvider, { theme, colorScheme }, /* @__PURE__ */ React25__default.default.createElement(BottomSheet.BottomSheetModalProvider, null, /* @__PURE__ */ React25__default.default.createElement(ToastProvider, null, children)))));
4662
+ return /* @__PURE__ */ React54__default.default.createElement(reactNativeSafeAreaContext.SafeAreaProvider, { initialMetrics: reactNativeSafeAreaContext.initialWindowMetrics }, /* @__PURE__ */ React54__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles37.root }, /* @__PURE__ */ React54__default.default.createElement(ThemeProvider, { theme, colorScheme }, /* @__PURE__ */ React54__default.default.createElement(bottomSheet.BottomSheetModalProvider, null, /* @__PURE__ */ React54__default.default.createElement(ToastProvider, null, children)))));
4679
4663
  }
4680
4664
  var styles37 = reactNative.StyleSheet.create({
4681
4665
  root: { flex: 1 }
@@ -4687,7 +4671,7 @@ function DefaultErrorFallback({
4687
4671
  message
4688
4672
  }) {
4689
4673
  const { colors } = useTheme();
4690
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles38.container, { backgroundColor: colors.background }], accessibilityRole: "alert" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles38.iconCircle, { backgroundColor: colors.destructiveTint }] }, renderIcon("alert-triangle", ms(28), colors.destructive)), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles38.title, { color: colors.foreground }], allowFontScaling: true }, title), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles38.message, { color: colors.foregroundMuted }], allowFontScaling: true }, message ?? error.message ?? "An unexpected error occurred."), /* @__PURE__ */ React25__default.default.createElement(
4674
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles38.container, { backgroundColor: colors.background }], accessibilityRole: "alert" }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles38.iconCircle, { backgroundColor: colors.destructiveTint }] }, renderIcon("alert-triangle", ms(28), colors.destructive)), /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles38.title, { color: colors.foreground }], allowFontScaling: true }, title), /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles38.message, { color: colors.foregroundMuted }], allowFontScaling: true }, message ?? error.message ?? "An unexpected error occurred."), /* @__PURE__ */ React54__default.default.createElement(
4691
4675
  reactNative.TouchableOpacity,
4692
4676
  {
4693
4677
  style: [styles38.button, { backgroundColor: colors.primary }],
@@ -4700,10 +4684,10 @@ function DefaultErrorFallback({
4700
4684
  accessibilityRole: "button",
4701
4685
  accessibilityLabel: "Try again"
4702
4686
  },
4703
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles38.buttonLabel, { color: colors.primaryForeground }], allowFontScaling: true }, "Try again")
4687
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles38.buttonLabel, { color: colors.primaryForeground }], allowFontScaling: true }, "Try again")
4704
4688
  ));
4705
4689
  }
4706
- var ErrorBoundary = class extends React25__default.default.Component {
4690
+ var ErrorBoundary = class extends React54__default.default.Component {
4707
4691
  constructor() {
4708
4692
  super(...arguments);
4709
4693
  this.state = { error: null };
@@ -4727,7 +4711,7 @@ var ErrorBoundary = class extends React25__default.default.Component {
4727
4711
  if (fallback !== void 0) {
4728
4712
  return fallback;
4729
4713
  }
4730
- return /* @__PURE__ */ React25__default.default.createElement(DefaultErrorFallback, { error, reset: this.reset, title, message });
4714
+ return /* @__PURE__ */ React54__default.default.createElement(DefaultErrorFallback, { error, reset: this.reset, title, message });
4731
4715
  }
4732
4716
  return this.props.children;
4733
4717
  }
@@ -4776,20 +4760,20 @@ var styles38 = reactNative.StyleSheet.create({
4776
4760
  });
4777
4761
  function Dot({ active, size, activeColor, inactiveColor, onPress, index, total }) {
4778
4762
  const progress = Animated12.useSharedValue(active ? 1 : 0);
4779
- React25.useEffect(() => {
4763
+ React54.useEffect(() => {
4780
4764
  progress.value = Animated12.withSpring(active ? 1 : 0, SPRINGS.glide);
4781
4765
  }, [active, progress]);
4782
4766
  const animatedStyle = Animated12.useAnimatedStyle(() => ({
4783
4767
  width: size + progress.value * size * 1.5,
4784
4768
  backgroundColor: Animated12.interpolateColor(progress.value, [0, 1], [inactiveColor, activeColor])
4785
4769
  }));
4786
- const dot = /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ height: size, borderRadius: size / 2 }, animatedStyle] });
4770
+ const dot = /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [{ height: size, borderRadius: size / 2 }, animatedStyle] });
4787
4771
  if (!onPress) return dot;
4788
4772
  const handlePress = () => {
4789
4773
  selectionAsync();
4790
4774
  onPress();
4791
4775
  };
4792
- return /* @__PURE__ */ React25__default.default.createElement(
4776
+ return /* @__PURE__ */ React54__default.default.createElement(
4793
4777
  reactNative.TouchableOpacity,
4794
4778
  {
4795
4779
  onPress: handlePress,
@@ -4838,14 +4822,14 @@ function PagerDots({
4838
4822
  onDotPress(activeIndex + 1);
4839
4823
  }
4840
4824
  };
4841
- return /* @__PURE__ */ React25__default.default.createElement(
4825
+ return /* @__PURE__ */ React54__default.default.createElement(
4842
4826
  reactNative.View,
4843
4827
  {
4844
4828
  style: [styles39.container, { gap: s(spacing) }, style],
4845
4829
  accessibilityRole: "adjustable",
4846
4830
  accessibilityLabel: `Page ${activeIndex + 1} of ${count}`
4847
4831
  },
4848
- hasControls && /* @__PURE__ */ React25__default.default.createElement(
4832
+ hasControls && /* @__PURE__ */ React54__default.default.createElement(
4849
4833
  reactNative.TouchableOpacity,
4850
4834
  {
4851
4835
  onPress: handlePrevious,
@@ -4859,7 +4843,7 @@ function PagerDots({
4859
4843
  },
4860
4844
  renderIcon("chevron-left", s(18), canGoPrev ? colors.foreground : colors.foregroundMuted)
4861
4845
  ),
4862
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles39.dotsRow, { gap: s(spacing) }] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React25__default.default.createElement(
4846
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles39.dotsRow, { gap: s(spacing) }] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React54__default.default.createElement(
4863
4847
  Dot,
4864
4848
  {
4865
4849
  key: i,
@@ -4872,7 +4856,7 @@ function PagerDots({
4872
4856
  onPress: onDotPress ? () => onDotPress(i) : void 0
4873
4857
  }
4874
4858
  ))),
4875
- hasControls && /* @__PURE__ */ React25__default.default.createElement(
4859
+ hasControls && /* @__PURE__ */ React54__default.default.createElement(
4876
4860
  reactNative.TouchableOpacity,
4877
4861
  {
4878
4862
  onPress: handleNext,
@@ -4923,7 +4907,7 @@ function AppHeader({
4923
4907
  const { width } = reactNative.useWindowDimensions();
4924
4908
  const isWide = width >= BREAKPOINTS.wide;
4925
4909
  const centered = titleAlign === "center" || titleAlign === "auto" && isWide;
4926
- const leftNode = left ?? (onBack ? /* @__PURE__ */ React25__default.default.createElement(
4910
+ const leftNode = left ?? (onBack ? /* @__PURE__ */ React54__default.default.createElement(
4927
4911
  IconButton,
4928
4912
  {
4929
4913
  iconName: backIconName,
@@ -4933,7 +4917,7 @@ function AppHeader({
4933
4917
  accessibilityLabel: "Go back"
4934
4918
  }
4935
4919
  ) : null);
4936
- const titleBlock = /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles40.titleBlock, centered && styles40.titleBlockCentered], pointerEvents: "none" }, title ? /* @__PURE__ */ React25__default.default.createElement(
4920
+ const titleBlock = /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles40.titleBlock, centered && styles40.titleBlockCentered], pointerEvents: "none" }, title ? /* @__PURE__ */ React54__default.default.createElement(
4937
4921
  reactNative.Text,
4938
4922
  {
4939
4923
  style: [styles40.title, { color: colors.foreground }, centered && styles40.textCentered],
@@ -4942,7 +4926,7 @@ function AppHeader({
4942
4926
  accessibilityRole: "header"
4943
4927
  },
4944
4928
  title
4945
- ) : null, subtitle ? /* @__PURE__ */ React25__default.default.createElement(
4929
+ ) : null, subtitle ? /* @__PURE__ */ React54__default.default.createElement(
4946
4930
  reactNative.Text,
4947
4931
  {
4948
4932
  style: [styles40.subtitle, { color: colors.foregroundMuted }, centered && styles40.textCentered],
@@ -4951,7 +4935,7 @@ function AppHeader({
4951
4935
  },
4952
4936
  subtitle
4953
4937
  ) : null);
4954
- return /* @__PURE__ */ React25__default.default.createElement(
4938
+ return /* @__PURE__ */ React54__default.default.createElement(
4955
4939
  reactNative.View,
4956
4940
  {
4957
4941
  style: [
@@ -4965,7 +4949,7 @@ function AppHeader({
4965
4949
  style
4966
4950
  ]
4967
4951
  },
4968
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles40.bar }, centered ? /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, titleBlock), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles40.side }, leftNode), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles40.side, styles40.sideRight] }, right)) : /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles40.side }, leftNode), titleBlock, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles40.side, styles40.sideRight] }, right)))
4952
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles40.bar }, centered ? /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, titleBlock), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles40.side }, leftNode), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles40.side, styles40.sideRight] }, right)) : /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles40.side }, leftNode), titleBlock, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles40.side, styles40.sideRight] }, right)))
4969
4953
  );
4970
4954
  }
4971
4955
  var styles40 = reactNative.StyleSheet.create({
@@ -5022,7 +5006,7 @@ function Cell({ item, selected, width, onPress }) {
5022
5006
  });
5023
5007
  const iconColor = selected ? colors.primary : colors.foregroundSubtle;
5024
5008
  const iconNode = item.icon ?? (item.iconName ? renderIcon(item.iconName, ms(24), iconColor) : null);
5025
- return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(
5009
+ return /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [{ width }, animatedStyle] }, /* @__PURE__ */ React54__default.default.createElement(
5026
5010
  reactNative.TouchableOpacity,
5027
5011
  {
5028
5012
  onPress,
@@ -5045,7 +5029,7 @@ function Cell({ item, selected, width, onPress }) {
5045
5029
  ]
5046
5030
  },
5047
5031
  iconNode,
5048
- item.label ? /* @__PURE__ */ React25__default.default.createElement(
5032
+ item.label ? /* @__PURE__ */ React54__default.default.createElement(
5049
5033
  reactNative.Text,
5050
5034
  {
5051
5035
  style: [styles41.label, { color: selected ? colors.primary : colors.foreground }],
@@ -5066,7 +5050,7 @@ function SelectableGrid({
5066
5050
  orientation = "grid",
5067
5051
  style
5068
5052
  }) {
5069
- const [containerWidth, setContainerWidth] = React25.useState(0);
5053
+ const [containerWidth, setContainerWidth] = React54.useState(0);
5070
5054
  const gapPx = s(gap);
5071
5055
  const cellWidth = containerWidth > 0 ? (containerWidth - gapPx * (numColumns - 1)) / numColumns - 0.5 : 0;
5072
5056
  const horizCellWidth = s(72);
@@ -5076,7 +5060,7 @@ function SelectableGrid({
5076
5060
  onChange(item.value);
5077
5061
  };
5078
5062
  if (orientation === "horizontal") {
5079
- return /* @__PURE__ */ React25__default.default.createElement(
5063
+ return /* @__PURE__ */ React54__default.default.createElement(
5080
5064
  reactNative.ScrollView,
5081
5065
  {
5082
5066
  horizontal: true,
@@ -5084,7 +5068,7 @@ function SelectableGrid({
5084
5068
  contentContainerStyle: [styles41.horizontal, { gap: gapPx }, style],
5085
5069
  accessibilityRole: multiple ? void 0 : "radiogroup"
5086
5070
  },
5087
- items.map((item) => /* @__PURE__ */ React25__default.default.createElement(
5071
+ items.map((item) => /* @__PURE__ */ React54__default.default.createElement(
5088
5072
  Cell,
5089
5073
  {
5090
5074
  key: String(item.value),
@@ -5096,14 +5080,14 @@ function SelectableGrid({
5096
5080
  ))
5097
5081
  );
5098
5082
  }
5099
- return /* @__PURE__ */ React25__default.default.createElement(
5083
+ return /* @__PURE__ */ React54__default.default.createElement(
5100
5084
  reactNative.View,
5101
5085
  {
5102
5086
  style: [styles41.grid, { gap: gapPx }, style],
5103
5087
  onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width),
5104
5088
  accessibilityRole: multiple ? void 0 : "radiogroup"
5105
5089
  },
5106
- cellWidth > 0 ? items.map((item) => /* @__PURE__ */ React25__default.default.createElement(
5090
+ cellWidth > 0 ? items.map((item) => /* @__PURE__ */ React54__default.default.createElement(
5107
5091
  Cell,
5108
5092
  {
5109
5093
  key: String(item.value),
@@ -5159,7 +5143,7 @@ function PricingCard({
5159
5143
  style
5160
5144
  }) {
5161
5145
  const { colors } = useTheme();
5162
- return /* @__PURE__ */ React25__default.default.createElement(
5146
+ return /* @__PURE__ */ React54__default.default.createElement(
5163
5147
  reactNative.View,
5164
5148
  {
5165
5149
  style: [
@@ -5174,14 +5158,14 @@ function PricingCard({
5174
5158
  ],
5175
5159
  accessibilityRole: "summary"
5176
5160
  },
5177
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles42.header }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles42.name, { color: colors.foreground }], allowFontScaling: true }, name), badge ? /* @__PURE__ */ React25__default.default.createElement(Badge, { label: badge, variant: highlighted ? "default" : "secondary", size: "sm" }) : null),
5178
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles42.priceRow }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles42.price, { color: colors.foreground }], allowFontScaling: true }, price), period ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles42.period, { color: colors.foregroundMuted }], allowFontScaling: true }, period) : null),
5179
- description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles42.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null,
5180
- features.length > 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles42.features }, features.map(normalize).map((f, i) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: i, style: styles42.featureRow }, renderIcon(
5161
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles42.header }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles42.name, { color: colors.foreground }], allowFontScaling: true }, name), badge ? /* @__PURE__ */ React54__default.default.createElement(Badge, { label: badge, variant: highlighted ? "default" : "secondary", size: "sm" }) : null),
5162
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles42.priceRow }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles42.price, { color: colors.foreground }], allowFontScaling: true }, price), period ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles42.period, { color: colors.foregroundMuted }], allowFontScaling: true }, period) : null),
5163
+ description ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles42.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null,
5164
+ features.length > 0 ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles42.features }, features.map(normalize).map((f, i) => /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { key: i, style: styles42.featureRow }, renderIcon(
5181
5165
  f.included ? "check" : "minus",
5182
5166
  ms(16),
5183
5167
  f.included ? colors.success : colors.foregroundMuted
5184
- ), /* @__PURE__ */ React25__default.default.createElement(
5168
+ ), /* @__PURE__ */ React54__default.default.createElement(
5185
5169
  reactNative.Text,
5186
5170
  {
5187
5171
  style: [
@@ -5193,7 +5177,7 @@ function PricingCard({
5193
5177
  },
5194
5178
  f.label
5195
5179
  )))) : null,
5196
- ctaLabel ? /* @__PURE__ */ React25__default.default.createElement(
5180
+ ctaLabel ? /* @__PURE__ */ React54__default.default.createElement(
5197
5181
  Button,
5198
5182
  {
5199
5183
  label: ctaLabel,
@@ -5203,7 +5187,7 @@ function PricingCard({
5203
5187
  style: styles42.cta
5204
5188
  }
5205
5189
  ) : null,
5206
- footnote ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles42.footnote, { color: colors.foregroundMuted }], allowFontScaling: true }, footnote) : null
5190
+ footnote ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles42.footnote, { color: colors.foregroundMuted }], allowFontScaling: true }, footnote) : null
5207
5191
  );
5208
5192
  }
5209
5193
  var styles42 = reactNative.StyleSheet.create({
@@ -5285,7 +5269,7 @@ function TabBar({
5285
5269
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
5286
5270
  const resolvedActive = activeColor ?? colors.primary;
5287
5271
  const resolvedInactive = inactiveColor ?? colors.foregroundMuted;
5288
- return /* @__PURE__ */ React25__default.default.createElement(
5272
+ return /* @__PURE__ */ React54__default.default.createElement(
5289
5273
  reactNative.View,
5290
5274
  {
5291
5275
  style: [
@@ -5305,7 +5289,7 @@ function TabBar({
5305
5289
  const iconNode = item.icon ?? (item.iconName ? renderIcon(item.iconName, ms(24), tint) : null);
5306
5290
  const showBadge = item.badge !== void 0 && item.badge !== false;
5307
5291
  const badgeCount = typeof item.badge === "number" ? item.badge : void 0;
5308
- return /* @__PURE__ */ React25__default.default.createElement(
5292
+ return /* @__PURE__ */ React54__default.default.createElement(
5309
5293
  reactNative.TouchableOpacity,
5310
5294
  {
5311
5295
  key: item.key,
@@ -5320,7 +5304,7 @@ function TabBar({
5320
5304
  accessibilityState: { selected: active },
5321
5305
  accessibilityLabel: item.label ?? item.key
5322
5306
  },
5323
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, null, iconNode, showBadge ? /* @__PURE__ */ React25__default.default.createElement(
5307
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, null, iconNode, showBadge ? /* @__PURE__ */ React54__default.default.createElement(
5324
5308
  reactNative.View,
5325
5309
  {
5326
5310
  style: [
@@ -5329,9 +5313,9 @@ function TabBar({
5329
5313
  badgeCount === void 0 && styles43.badgeDot
5330
5314
  ]
5331
5315
  },
5332
- badgeCount !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles43.badgeText, { color: colors.destructiveForeground }], allowFontScaling: false }, badgeCount > 99 ? "99+" : badgeCount) : null
5316
+ badgeCount !== void 0 ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles43.badgeText, { color: colors.destructiveForeground }], allowFontScaling: false }, badgeCount > 99 ? "99+" : badgeCount) : null
5333
5317
  ) : null),
5334
- item.label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles43.label, { color: tint }], numberOfLines: 1, allowFontScaling: true }, item.label) : null
5318
+ item.label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles43.label, { color: tint }], numberOfLines: 1, allowFontScaling: true }, item.label) : null
5335
5319
  );
5336
5320
  })
5337
5321
  );
@@ -5390,7 +5374,7 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
5390
5374
  const translateY = Animated12.useSharedValue(0);
5391
5375
  const savedX = Animated12.useSharedValue(0);
5392
5376
  const savedY = Animated12.useSharedValue(0);
5393
- const reportZoom = React25.useCallback((zoomed) => onZoomChange(zoomed), [onZoomChange]);
5377
+ const reportZoom = React54.useCallback((zoomed) => onZoomChange(zoomed), [onZoomChange]);
5394
5378
  const reset = () => {
5395
5379
  "worklet";
5396
5380
  scale2.value = Animated12.withTiming(1);
@@ -5436,17 +5420,17 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
5436
5420
  { scale: scale2.value }
5437
5421
  ]
5438
5422
  }));
5439
- return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [{ width, height }, styles44.imageWrap], collapsable: false }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width, height }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Image, { source, style: { width, height }, resizeMode: "contain" }))));
5423
+ return /* @__PURE__ */ React54__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [{ width, height }, styles44.imageWrap], collapsable: false }, /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [{ width, height }, animatedStyle] }, /* @__PURE__ */ React54__default.default.createElement(reactNative.Image, { source, style: { width, height }, resizeMode: "contain" }))));
5440
5424
  }
5441
5425
  function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5442
5426
  const window = reactNative.useWindowDimensions();
5443
5427
  const width = window.width > 0 ? window.width : reactNative.Dimensions.get("window").width;
5444
5428
  const height = window.height > 0 ? window.height : reactNative.Dimensions.get("window").height;
5445
5429
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
5446
- const [index, setIndex] = React25.useState(initialIndex);
5447
- const [pagingEnabled, setPagingEnabled] = React25.useState(true);
5448
- const scrollRef = React25__default.default.useRef(null);
5449
- React25__default.default.useEffect(() => {
5430
+ const [index, setIndex] = React54.useState(initialIndex);
5431
+ const [pagingEnabled, setPagingEnabled] = React54.useState(true);
5432
+ const scrollRef = React54__default.default.useRef(null);
5433
+ React54__default.default.useEffect(() => {
5450
5434
  if (!visible) return;
5451
5435
  const handle = requestAnimationFrame(() => {
5452
5436
  setIndex(initialIndex);
@@ -5457,7 +5441,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5457
5441
  }, [visible, initialIndex, width]);
5458
5442
  const dragY = Animated12.useSharedValue(0);
5459
5443
  const DISMISS_THRESHOLD = height * 0.18;
5460
- const closeViewer = React25.useCallback(() => onClose(), [onClose]);
5444
+ const closeViewer = React54.useCallback(() => onClose(), [onClose]);
5461
5445
  const swipeDown = reactNativeGestureHandler.Gesture.Pan().enabled(pagingEnabled).activeOffsetY(12).failOffsetX([-16, 16]).onUpdate((e) => {
5462
5446
  dragY.value = Math.max(0, e.translationY);
5463
5447
  }).onEnd((e) => {
@@ -5467,7 +5451,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5467
5451
  dragY.value = Animated12.withTiming(0);
5468
5452
  }
5469
5453
  });
5470
- React25__default.default.useEffect(() => {
5454
+ React54__default.default.useEffect(() => {
5471
5455
  if (visible) dragY.value = 0;
5472
5456
  }, [visible, dragY]);
5473
5457
  const dismissStyle = Animated12.useAnimatedStyle(() => ({
@@ -5484,7 +5468,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5484
5468
  scrollRef.current?.scrollTo({ x: page * width, animated: true });
5485
5469
  setIndex(page);
5486
5470
  };
5487
- 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(reactNative.View, { style: styles44.root, collapsable: false }, /* @__PURE__ */ React25__default.default.createElement(
5471
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React54__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles44.root }, /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [styles44.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React54__default.default.createElement(Animated12__default.default.View, { style: [styles44.container, dismissStyle] }, /* @__PURE__ */ React54__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles44.root, collapsable: false }, /* @__PURE__ */ React54__default.default.createElement(
5488
5472
  reactNative.ScrollView,
5489
5473
  {
5490
5474
  ref: scrollRef,
@@ -5495,7 +5479,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5495
5479
  onMomentumScrollEnd: onMomentumEnd,
5496
5480
  bounces: false
5497
5481
  },
5498
- images.map((source, i) => /* @__PURE__ */ React25__default.default.createElement(
5482
+ images.map((source, i) => /* @__PURE__ */ React54__default.default.createElement(
5499
5483
  ZoomableImage,
5500
5484
  {
5501
5485
  key: i,
@@ -5505,7 +5489,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5505
5489
  onZoomChange: (zoomed) => setPagingEnabled(!zoomed)
5506
5490
  }
5507
5491
  ))
5508
- ))), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles44.closeButtonWrapper, { top: insets.top + vs(8) }] }, /* @__PURE__ */ React25__default.default.createElement(
5492
+ ))), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles44.closeButtonWrapper, { top: insets.top + vs(8) }] }, /* @__PURE__ */ React54__default.default.createElement(
5509
5493
  IconButton,
5510
5494
  {
5511
5495
  iconName: "x",
@@ -5516,7 +5500,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
5516
5500
  onPress: onClose,
5517
5501
  accessibilityLabel: "Close"
5518
5502
  }
5519
- )), images.length > 1 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles44.dots, { bottom: insets.bottom + vs(16) }], pointerEvents: "box-none" }, /* @__PURE__ */ React25__default.default.createElement(
5503
+ )), images.length > 1 ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles44.dots, { bottom: insets.bottom + vs(16) }], pointerEvents: "box-none" }, /* @__PURE__ */ React54__default.default.createElement(
5520
5504
  PagerDots,
5521
5505
  {
5522
5506
  count: images.length,
@@ -5566,7 +5550,7 @@ function SheetSelectChip({
5566
5550
  };
5567
5551
  const iconColor = selected ? colors.primaryForeground : colors.foreground;
5568
5552
  const resolvedIcon = option.iconName ? renderIcon(option.iconName, ms(13), iconColor) : null;
5569
- return /* @__PURE__ */ React25__default.default.createElement(
5553
+ return /* @__PURE__ */ React54__default.default.createElement(
5570
5554
  PressableChip,
5571
5555
  {
5572
5556
  onPress: option.disabled ? void 0 : handlePress,
@@ -5576,7 +5560,7 @@ function SheetSelectChip({
5576
5560
  accessibilityLabel: option.disabled ? `${option.label}, unavailable` : option.label,
5577
5561
  accessibilityState: { selected, disabled: option.disabled }
5578
5562
  },
5579
- /* @__PURE__ */ React25__default.default.createElement(
5563
+ /* @__PURE__ */ React54__default.default.createElement(
5580
5564
  reactNativeEase.EaseView,
5581
5565
  {
5582
5566
  style: [styles45.chip, option.disabled && styles45.chipDisabled],
@@ -5586,8 +5570,8 @@ function SheetSelectChip({
5586
5570
  },
5587
5571
  transition: COLOR_TRANSITION
5588
5572
  },
5589
- resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles45.chipIcon }, resolvedIcon) : null,
5590
- /* @__PURE__ */ React25__default.default.createElement(
5573
+ resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles45.chipIcon }, resolvedIcon) : null,
5574
+ /* @__PURE__ */ React54__default.default.createElement(
5591
5575
  reactNative.Text,
5592
5576
  {
5593
5577
  style: [styles45.chipLabel, { color: selected ? colors.primaryForeground : colors.foreground }],
@@ -5624,7 +5608,7 @@ function SheetSelect({
5624
5608
  const newArray = alreadySelected ? currentArray.filter((v) => v !== optionValue) : [...currentArray, optionValue];
5625
5609
  onValueChange?.(newArray);
5626
5610
  };
5627
- const chips = options.map((opt) => /* @__PURE__ */ React25__default.default.createElement(
5611
+ const chips = options.map((opt) => /* @__PURE__ */ React54__default.default.createElement(
5628
5612
  SheetSelectChip,
5629
5613
  {
5630
5614
  key: opt.value,
@@ -5633,7 +5617,7 @@ function SheetSelect({
5633
5617
  onPress: () => handlePress(opt.value)
5634
5618
  }
5635
5619
  ));
5636
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles45.container, style], accessibilityLabel }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles45.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, wrap ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles45.wrapContainer }, chips) : /* @__PURE__ */ React25__default.default.createElement(
5620
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles45.container, style], accessibilityLabel }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles45.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, wrap ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles45.wrapContainer }, chips) : /* @__PURE__ */ React54__default.default.createElement(
5637
5621
  reactNative.ScrollView,
5638
5622
  {
5639
5623
  horizontal: true,
@@ -5641,7 +5625,7 @@ function SheetSelect({
5641
5625
  contentContainerStyle: styles45.scrollContent
5642
5626
  },
5643
5627
  chips
5644
- ), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles45.error, { color: colors.destructive }], allowFontScaling: true, accessibilityLiveRegion: "polite" }, error) : null);
5628
+ ), error ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles45.error, { color: colors.destructive }], allowFontScaling: true, accessibilityLiveRegion: "polite" }, error) : null);
5645
5629
  }
5646
5630
  var styles45 = reactNative.StyleSheet.create({
5647
5631
  container: {
@@ -5693,6 +5677,7 @@ function ImageUpload({
5693
5677
  onChange,
5694
5678
  loading = false,
5695
5679
  placeholder = "Tap to add image",
5680
+ showPlaceholderText = true,
5696
5681
  width,
5697
5682
  height = 200,
5698
5683
  borderRadius = RADIUS.lg,
@@ -5705,23 +5690,31 @@ function ImageUpload({
5705
5690
  const handlePress = async () => {
5706
5691
  if (disabled || loading) return;
5707
5692
  impactLight();
5708
- let ImagePicker;
5693
+ let picker;
5709
5694
  try {
5710
- ImagePicker = await import('expo-image-picker');
5695
+ const mod = await import('expo-image-picker/build/ExponentImagePicker');
5696
+ picker = mod.default;
5711
5697
  } catch {
5712
- if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed. Add it as a dependency.");
5713
- return;
5698
+ try {
5699
+ picker = await import('expo-image-picker');
5700
+ } catch {
5701
+ if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed.");
5702
+ return;
5703
+ }
5714
5704
  }
5715
5705
  if (reactNative.Platform.OS !== "web") {
5716
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
5717
- if (status !== "granted") return;
5706
+ try {
5707
+ const { status } = await picker.requestMediaLibraryPermissionsAsync();
5708
+ if (status !== "granted") return;
5709
+ } catch {
5710
+ }
5718
5711
  }
5719
- const result = await ImagePicker.launchImageLibraryAsync({
5712
+ const result = await picker.launchImageLibraryAsync({
5720
5713
  mediaTypes: ["images"],
5721
5714
  allowsEditing: true,
5722
5715
  quality: 0.8
5723
5716
  });
5724
- if (!result.canceled && result.assets[0]) {
5717
+ if (!result.canceled && result.assets?.[0]) {
5725
5718
  onChange?.(result.assets[0].uri);
5726
5719
  }
5727
5720
  };
@@ -5735,7 +5728,7 @@ function ImageUpload({
5735
5728
  backgroundColor: value ? "transparent" : colors.surface,
5736
5729
  overflow: "hidden"
5737
5730
  };
5738
- return /* @__PURE__ */ React25__default.default.createElement(
5731
+ return /* @__PURE__ */ React54__default.default.createElement(
5739
5732
  PressableCard,
5740
5733
  {
5741
5734
  onPress: handlePress,
@@ -5747,16 +5740,24 @@ function ImageUpload({
5747
5740
  accessibilityState: { disabled: disabled || loading },
5748
5741
  style: [containerStyle, style]
5749
5742
  },
5750
- value ? /* @__PURE__ */ React25__default.default.createElement(
5743
+ value ? /* @__PURE__ */ React54__default.default.createElement(
5751
5744
  reactNative.Image,
5752
5745
  {
5753
5746
  source: { uri: value },
5754
5747
  style: [reactNative.StyleSheet.absoluteFillObject, { borderRadius }],
5755
5748
  resizeMode
5756
5749
  }
5757
- ) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.placeholder }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles46.placeholderText, { color: colors.foregroundMuted }], allowFontScaling: true }, placeholder)),
5758
- loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(Spinner, { size: "md" })) : null,
5759
- value && !loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
5750
+ ) : /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles46.placeholder }, /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), showPlaceholderText ? /* @__PURE__ */ React54__default.default.createElement(
5751
+ reactNative.Text,
5752
+ {
5753
+ style: [styles46.placeholderText, { color: colors.foregroundMuted }],
5754
+ numberOfLines: 1,
5755
+ allowFontScaling: true
5756
+ },
5757
+ placeholder
5758
+ ) : null),
5759
+ loading ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles46.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React54__default.default.createElement(Spinner, { size: "md" })) : null,
5760
+ value && !loading ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles46.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles46.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React54__default.default.createElement(vectorIcons.Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
5760
5761
  );
5761
5762
  }
5762
5763
  var styles46 = reactNative.StyleSheet.create({
@@ -5768,7 +5769,8 @@ var styles46 = reactNative.StyleSheet.create({
5768
5769
  },
5769
5770
  placeholderText: {
5770
5771
  fontFamily: "Sohne-Regular",
5771
- fontSize: ms(13)
5772
+ fontSize: ms(13),
5773
+ textAlign: "center"
5772
5774
  },
5773
5775
  loadingOverlay: {
5774
5776
  ...reactNative.StyleSheet.absoluteFillObject,
@@ -5789,6 +5791,1355 @@ var styles46 = reactNative.StyleSheet.create({
5789
5791
  }
5790
5792
  });
5791
5793
 
5794
+ // src/utils/curatedIcons.ts
5795
+ var CURATED_ICONS = [
5796
+ // ─── Food ────────────────────────────────────────────────────────────────────
5797
+ {
5798
+ name: "food",
5799
+ label: "Food",
5800
+ labelEs: "Comida",
5801
+ categoryIcon: "coffee",
5802
+ icons: [
5803
+ // Bebidas
5804
+ "beer-outline",
5805
+ "wine-outline",
5806
+ "cafe-outline",
5807
+ "water-outline",
5808
+ "coffee",
5809
+ // Comida
5810
+ "pizza-outline",
5811
+ "fast-food-outline",
5812
+ "fish-outline",
5813
+ "ice-cream-outline",
5814
+ "egg-outline",
5815
+ "nutrition-outline",
5816
+ // Servicio y operación
5817
+ "restaurant-outline",
5818
+ "server-outline",
5819
+ "menu-outline",
5820
+ "basket-outline",
5821
+ "receipt-outline",
5822
+ "pricetag-outline",
5823
+ "pricetags-outline",
5824
+ "reorder-four-outline",
5825
+ "reorder-three-outline",
5826
+ "cart-outline",
5827
+ "cash-outline",
5828
+ "wallet-outline",
5829
+ "storefront-outline",
5830
+ // Delivery / pedidos
5831
+ "truck",
5832
+ "package",
5833
+ "shopping-bag",
5834
+ "shopping-cart",
5835
+ // Ubicación y reserva
5836
+ "map-pin",
5837
+ "home",
5838
+ "calendar",
5839
+ "clock",
5840
+ // Experiencia
5841
+ "star",
5842
+ "heart",
5843
+ "bookmark",
5844
+ "thumbs-up",
5845
+ "check",
5846
+ "gift"
5847
+ ]
5848
+ },
5849
+ // ─── Sports ──────────────────────────────────────────────────────────────────
5850
+ {
5851
+ name: "sports",
5852
+ label: "Sports",
5853
+ labelEs: "Deportes",
5854
+ categoryIcon: "trophy-outline",
5855
+ icons: [
5856
+ // Deportes
5857
+ "american-football-outline",
5858
+ "baseball-outline",
5859
+ "basketball-outline",
5860
+ "bicycle-outline",
5861
+ "football-outline",
5862
+ "tennisball-outline",
5863
+ "golf-outline",
5864
+ "fitness-outline",
5865
+ "car-sport-outline",
5866
+ "game-controller-outline",
5867
+ // Competición y logros
5868
+ "trophy-outline",
5869
+ "medal-outline",
5870
+ "award",
5871
+ "target",
5872
+ "flag",
5873
+ "crosshair",
5874
+ // Outdoor
5875
+ "compass-outline",
5876
+ "map-outline",
5877
+ "trail-sign-outline",
5878
+ "bonfire-outline",
5879
+ "snow-outline",
5880
+ "flame-outline",
5881
+ "sun",
5882
+ "droplet",
5883
+ "wind",
5884
+ "map",
5885
+ "map-pin",
5886
+ "navigation",
5887
+ "navigation-2",
5888
+ // Rendimiento y métricas
5889
+ "stats-chart-outline",
5890
+ "trending-up-outline",
5891
+ "trending-down-outline",
5892
+ "bar-chart-outline",
5893
+ "pie-chart-outline",
5894
+ "analytics-outline",
5895
+ "activity",
5896
+ "zap",
5897
+ "watch",
5898
+ "trending-up",
5899
+ "trending-down",
5900
+ "bar-chart-2",
5901
+ "clock",
5902
+ "calendar"
5903
+ ]
5904
+ },
5905
+ // ─── Business ────────────────────────────────────────────────────────────────
5906
+ {
5907
+ name: "business",
5908
+ label: "Business",
5909
+ labelEs: "Negocios",
5910
+ categoryIcon: "briefcase",
5911
+ icons: [
5912
+ // Empresa
5913
+ "briefcase",
5914
+ "users",
5915
+ "user",
5916
+ "user-plus",
5917
+ "user-check",
5918
+ "user-x",
5919
+ "briefcase-outline",
5920
+ "business-outline",
5921
+ "id-card-outline",
5922
+ // Comercio y operación
5923
+ "shopping-cart",
5924
+ "shopping-bag",
5925
+ "credit-card",
5926
+ "dollar-sign",
5927
+ "percent",
5928
+ "tag",
5929
+ "gift",
5930
+ "cart-outline",
5931
+ "cash-outline",
5932
+ "wallet-outline",
5933
+ "storefront-outline",
5934
+ "pricetag-outline",
5935
+ "pricetags-outline",
5936
+ "receipt-outline",
5937
+ "card-outline",
5938
+ // Logística
5939
+ "truck",
5940
+ "package",
5941
+ // Documentos
5942
+ "file",
5943
+ "file-text",
5944
+ "file-plus",
5945
+ "folder",
5946
+ "paperclip",
5947
+ "document-outline",
5948
+ "document-text-outline",
5949
+ "documents-outline",
5950
+ "folder-outline",
5951
+ // Comunicación de negocio
5952
+ "mail",
5953
+ "phone",
5954
+ "phone-call",
5955
+ "send",
5956
+ "message-square",
5957
+ "mail-outline",
5958
+ // Análisis
5959
+ "bar-chart",
5960
+ "bar-chart-2",
5961
+ "pie-chart",
5962
+ "trending-up",
5963
+ "trending-down",
5964
+ "activity",
5965
+ "globe"
5966
+ ]
5967
+ },
5968
+ // ─── Objects ─────────────────────────────────────────────────────────────────
5969
+ {
5970
+ name: "objects",
5971
+ label: "Objects",
5972
+ labelEs: "Objetos",
5973
+ categoryIcon: "package",
5974
+ icons: [
5975
+ // Archivos y carpetas
5976
+ "file",
5977
+ "file-text",
5978
+ "file-plus",
5979
+ "file-minus",
5980
+ "folder",
5981
+ "folder-plus",
5982
+ "folder-minus",
5983
+ "archive",
5984
+ "save",
5985
+ "paperclip",
5986
+ "document-outline",
5987
+ "document-text-outline",
5988
+ "documents-outline",
5989
+ "folder-outline",
5990
+ "folder-open-outline",
5991
+ "file-tray-outline",
5992
+ "file-tray-full-outline",
5993
+ "file-tray-stacked-outline",
5994
+ "archive-outline",
5995
+ "save-outline",
5996
+ // Seguridad
5997
+ "lock",
5998
+ "unlock",
5999
+ "key",
6000
+ "shield",
6001
+ "shield-off",
6002
+ "lock-closed-outline",
6003
+ "lock-open-outline",
6004
+ "key-outline",
6005
+ "shield-outline",
6006
+ "shield-checkmark-outline",
6007
+ // Dispositivos
6008
+ "monitor",
6009
+ "tablet",
6010
+ "smartphone",
6011
+ "tv",
6012
+ "server",
6013
+ "database",
6014
+ "hard-drive",
6015
+ "cpu",
6016
+ "radio",
6017
+ "laptop-outline",
6018
+ "phone-portrait-outline",
6019
+ "phone-landscape-outline",
6020
+ "tablet-landscape-outline",
6021
+ "tablet-portrait-outline",
6022
+ "tv-outline",
6023
+ "server-outline",
6024
+ "hardware-chip-outline",
6025
+ "watch-outline"
6026
+ ]
6027
+ },
6028
+ // ─── Status ──────────────────────────────────────────────────────────────────
6029
+ {
6030
+ name: "status",
6031
+ label: "Status",
6032
+ labelEs: "Estado",
6033
+ categoryIcon: "alert-circle",
6034
+ icons: [
6035
+ // Alertas
6036
+ "alert-circle",
6037
+ "alert-triangle",
6038
+ "alert-octagon",
6039
+ "info",
6040
+ "help-circle",
6041
+ "alert-circle-outline",
6042
+ "alert-outline",
6043
+ "information-circle-outline",
6044
+ "help-circle-outline",
6045
+ // Notificaciones
6046
+ "bell",
6047
+ "bell-off",
6048
+ "notifications-outline",
6049
+ "notifications-off-outline",
6050
+ "notifications-circle-outline",
6051
+ // Visibilidad
6052
+ "eye",
6053
+ "eye-off",
6054
+ "eye-outline",
6055
+ "eye-off-outline",
6056
+ // Indicadores
6057
+ "flag",
6058
+ "zap",
6059
+ "zap-off",
6060
+ "loader",
6061
+ "activity",
6062
+ "flash-outline",
6063
+ "bulb-outline",
6064
+ // Éxito / error / advertencia
6065
+ "check",
6066
+ "check-circle",
6067
+ "x",
6068
+ "x-circle",
6069
+ "x-octagon",
6070
+ "slash",
6071
+ "plus-circle",
6072
+ "minus-circle",
6073
+ "checkmark-circle-outline",
6074
+ "checkmark-done-circle-outline",
6075
+ "close-circle-outline",
6076
+ "add-circle-outline",
6077
+ "remove-circle-outline",
6078
+ // Estados de proceso
6079
+ "play-circle",
6080
+ "pause-circle",
6081
+ "stop-circle",
6082
+ "play-circle-outline",
6083
+ "pause-circle-outline",
6084
+ "stop-circle-outline"
6085
+ ]
6086
+ },
6087
+ // ─── Actions ─────────────────────────────────────────────────────────────────
6088
+ {
6089
+ name: "actions",
6090
+ label: "Actions",
6091
+ labelEs: "Acciones",
6092
+ categoryIcon: "edit-3",
6093
+ icons: [
6094
+ // Crear / añadir
6095
+ "plus",
6096
+ "plus-circle",
6097
+ "plus-square",
6098
+ "add-outline",
6099
+ "add-circle-outline",
6100
+ // Eliminar / quitar
6101
+ "minus",
6102
+ "minus-circle",
6103
+ "minus-square",
6104
+ "trash",
6105
+ "trash-2",
6106
+ "x",
6107
+ "x-circle",
6108
+ "x-square",
6109
+ "x-octagon",
6110
+ "slash",
6111
+ "trash-outline",
6112
+ "trash-bin-outline",
6113
+ "remove-outline",
6114
+ "remove-circle-outline",
6115
+ "close-circle-outline",
6116
+ "backspace-outline",
6117
+ "cut-outline",
6118
+ // Confirmar
6119
+ "check",
6120
+ "check-circle",
6121
+ "check-square",
6122
+ "checkmark-circle-outline",
6123
+ // Editar
6124
+ "edit",
6125
+ "edit-2",
6126
+ "edit-3",
6127
+ "copy",
6128
+ "clipboard",
6129
+ "scissors",
6130
+ "create-outline",
6131
+ "pencil-outline",
6132
+ "duplicate-outline",
6133
+ "copy-outline",
6134
+ "clipboard-outline",
6135
+ // Mover datos
6136
+ "download",
6137
+ "download-cloud",
6138
+ "upload",
6139
+ "upload-cloud",
6140
+ "download-outline",
6141
+ "cloud-download-outline",
6142
+ "cloud-upload-outline"
6143
+ ]
6144
+ },
6145
+ // ─── Communication ───────────────────────────────────────────────────────────
6146
+ {
6147
+ name: "communication",
6148
+ label: "Communication",
6149
+ labelEs: "Comunicaci\xF3n",
6150
+ categoryIcon: "message-circle",
6151
+ icons: [
6152
+ // Mensajería
6153
+ "message-circle",
6154
+ "message-square",
6155
+ "send",
6156
+ "mail",
6157
+ "inbox",
6158
+ "at-sign",
6159
+ "mail-outline",
6160
+ "mail-open-outline",
6161
+ "mail-unread-outline",
6162
+ "chatbubble-outline",
6163
+ "chatbubble-ellipses-outline",
6164
+ "chatbubbles-outline",
6165
+ "send-outline",
6166
+ "attach-outline",
6167
+ "at-outline",
6168
+ "at-circle-outline",
6169
+ // Llamadas
6170
+ "phone",
6171
+ "phone-call",
6172
+ "phone-incoming",
6173
+ "phone-outgoing",
6174
+ "phone-missed",
6175
+ "phone-off",
6176
+ "phone-forwarded",
6177
+ "voicemail",
6178
+ "call-outline",
6179
+ "phone-portrait-outline",
6180
+ "phone-landscape-outline",
6181
+ // Personas
6182
+ "user",
6183
+ "user-plus",
6184
+ "user-minus",
6185
+ "user-check",
6186
+ "user-x",
6187
+ "users",
6188
+ "person-outline",
6189
+ "person-circle-outline",
6190
+ "person-add-outline",
6191
+ "person-remove-outline",
6192
+ "people-outline",
6193
+ "people-circle-outline",
6194
+ // Reacciones
6195
+ "smile",
6196
+ "frown",
6197
+ "meh",
6198
+ "heart",
6199
+ "thumbs-up",
6200
+ "thumbs-down",
6201
+ "happy-outline",
6202
+ "sad-outline",
6203
+ "heart-outline",
6204
+ "thumbs-up-outline",
6205
+ "thumbs-down-outline"
6206
+ ]
6207
+ },
6208
+ // ─── Navigation ──────────────────────────────────────────────────────────────
6209
+ {
6210
+ name: "navigation",
6211
+ label: "Navigation",
6212
+ labelEs: "Navegaci\xF3n",
6213
+ categoryIcon: "compass",
6214
+ icons: [
6215
+ // Flechas cardinales
6216
+ "arrow-up",
6217
+ "arrow-down",
6218
+ "arrow-left",
6219
+ "arrow-right",
6220
+ "arrow-up-left",
6221
+ "arrow-up-right",
6222
+ "arrow-down-left",
6223
+ "arrow-down-right",
6224
+ "arrow-up-outline",
6225
+ "arrow-down-outline",
6226
+ "arrow-back-outline",
6227
+ "arrow-forward-outline",
6228
+ "arrow-undo-outline",
6229
+ "arrow-redo-outline",
6230
+ // Chevrones
6231
+ "chevron-up",
6232
+ "chevron-down",
6233
+ "chevron-left",
6234
+ "chevron-right",
6235
+ "chevrons-up",
6236
+ "chevrons-down",
6237
+ "chevrons-left",
6238
+ "chevrons-right",
6239
+ "chevron-up-outline",
6240
+ "chevron-down-outline",
6241
+ "chevron-back-outline",
6242
+ "chevron-forward-outline",
6243
+ "chevron-collapse-outline",
6244
+ "chevron-expand-outline",
6245
+ // Esquinas
6246
+ "corner-up-left",
6247
+ "corner-up-right",
6248
+ "corner-down-left",
6249
+ "corner-down-right",
6250
+ "corner-left-up",
6251
+ "corner-left-down",
6252
+ "corner-right-up",
6253
+ "corner-right-down",
6254
+ // Giro / refrescar
6255
+ "refresh-cw",
6256
+ "refresh-ccw",
6257
+ "rotate-cw",
6258
+ "rotate-ccw",
6259
+ "refresh-outline",
6260
+ "reload-outline",
6261
+ // Orientación y mapa
6262
+ "navigation",
6263
+ "navigation-2",
6264
+ "compass",
6265
+ "map",
6266
+ "map-pin",
6267
+ "target",
6268
+ "crosshair",
6269
+ "home",
6270
+ "anchor",
6271
+ "compass-outline",
6272
+ "map-outline",
6273
+ "location-outline",
6274
+ "navigate-outline",
6275
+ "pin-outline",
6276
+ "home-outline"
6277
+ ]
6278
+ },
6279
+ // ─── Media ───────────────────────────────────────────────────────────────────
6280
+ {
6281
+ name: "media",
6282
+ label: "Media",
6283
+ labelEs: "Medios",
6284
+ categoryIcon: "image",
6285
+ icons: [
6286
+ // Visual
6287
+ "image",
6288
+ "film",
6289
+ "video",
6290
+ "video-off",
6291
+ "camera",
6292
+ "camera-off",
6293
+ "image-outline",
6294
+ "images-outline",
6295
+ "film-outline",
6296
+ "videocam-outline",
6297
+ "videocam-off-outline",
6298
+ "camera-outline",
6299
+ "camera-reverse-outline",
6300
+ // Reproducción
6301
+ "play",
6302
+ "play-circle",
6303
+ "pause",
6304
+ "pause-circle",
6305
+ "square",
6306
+ "stop-circle",
6307
+ "fast-forward",
6308
+ "rewind",
6309
+ "skip-forward",
6310
+ "skip-back",
6311
+ "repeat",
6312
+ "shuffle",
6313
+ "play-outline",
6314
+ "pause-outline",
6315
+ "play-circle-outline",
6316
+ "pause-circle-outline",
6317
+ "stop-circle-outline",
6318
+ "play-back-outline",
6319
+ "play-forward-outline",
6320
+ "play-skip-back-outline",
6321
+ "play-skip-forward-outline",
6322
+ "repeat-outline",
6323
+ "shuffle-outline",
6324
+ // Audio
6325
+ "music",
6326
+ "headphones",
6327
+ "speaker",
6328
+ "volume",
6329
+ "volume-1",
6330
+ "volume-2",
6331
+ "volume-x",
6332
+ "mic",
6333
+ "mic-off",
6334
+ "mic-outline",
6335
+ "mic-off-outline",
6336
+ "mic-circle-outline",
6337
+ "musical-note-outline",
6338
+ "musical-notes-outline",
6339
+ "volume-high-outline",
6340
+ "volume-low-outline",
6341
+ "volume-medium-outline",
6342
+ "volume-mute-outline",
6343
+ "volume-off-outline"
6344
+ ]
6345
+ },
6346
+ // ─── Layout ──────────────────────────────────────────────────────────────────
6347
+ {
6348
+ name: "layout",
6349
+ label: "Layout",
6350
+ labelEs: "Dise\xF1o",
6351
+ categoryIcon: "grid",
6352
+ icons: [
6353
+ // Estructura
6354
+ "grid",
6355
+ "columns",
6356
+ "sidebar",
6357
+ "layout",
6358
+ "list",
6359
+ "menu",
6360
+ "table",
6361
+ "trello",
6362
+ "grid-outline",
6363
+ "list-outline",
6364
+ "menu-outline",
6365
+ "layers-outline",
6366
+ // Alineación
6367
+ "align-left",
6368
+ "align-center",
6369
+ "align-right",
6370
+ "align-justify",
6371
+ // Tipografía
6372
+ "bold",
6373
+ "italic",
6374
+ "underline",
6375
+ "type",
6376
+ "hash",
6377
+ // Formas
6378
+ "circle",
6379
+ "square",
6380
+ "triangle",
6381
+ "hexagon",
6382
+ "octagon",
6383
+ "square-outline",
6384
+ "triangle-outline",
6385
+ "diamond-outline",
6386
+ "shapes-outline",
6387
+ // Herramientas de diseño
6388
+ "pen-tool",
6389
+ "crop",
6390
+ "layers",
6391
+ "filter",
6392
+ "sliders",
6393
+ "aperture",
6394
+ "crop-outline",
6395
+ "filter-outline",
6396
+ "color-fill-outline",
6397
+ "color-filter-outline",
6398
+ "color-palette-outline",
6399
+ "color-wand-outline",
6400
+ "brush-outline",
6401
+ // Edición
6402
+ "edit",
6403
+ "edit-2",
6404
+ "edit-3",
6405
+ "copy",
6406
+ "trash",
6407
+ "move",
6408
+ "create-outline",
6409
+ "pencil-outline",
6410
+ "move-outline",
6411
+ "resize-outline",
6412
+ "duplicate-outline",
6413
+ // Navegación UI
6414
+ "more-horizontal",
6415
+ "more-vertical",
6416
+ "maximize",
6417
+ "minimize",
6418
+ "zoom-in",
6419
+ "zoom-out",
6420
+ "eye",
6421
+ "eye-off",
6422
+ "eye-outline",
6423
+ "eye-off-outline",
6424
+ "ellipsis-horizontal-circle-outline",
6425
+ "ellipsis-vertical-circle-outline"
6426
+ ]
6427
+ },
6428
+ // ─── Nature ──────────────────────────────────────────────────────────────────
6429
+ {
6430
+ name: "nature",
6431
+ label: "Nature",
6432
+ labelEs: "Naturaleza",
6433
+ categoryIcon: "sunny-outline",
6434
+ icons: [
6435
+ // Sol, luna y estrellas
6436
+ "sunny-outline",
6437
+ "moon-outline",
6438
+ "star-outline",
6439
+ "star-half-outline",
6440
+ "partly-sunny-outline",
6441
+ "sun",
6442
+ "moon",
6443
+ "sunrise",
6444
+ "sunset",
6445
+ // Clima
6446
+ "rainy-outline",
6447
+ "thunderstorm-outline",
6448
+ "snow-outline",
6449
+ "cloudy-outline",
6450
+ "cloudy-night-outline",
6451
+ "cloud-outline",
6452
+ "cloud-done-outline",
6453
+ "cloud-download-outline",
6454
+ "cloud-upload-outline",
6455
+ "cloud-offline-outline",
6456
+ "cloud-circle-outline",
6457
+ "cloud",
6458
+ "cloud-drizzle",
6459
+ "cloud-lightning",
6460
+ "cloud-rain",
6461
+ "cloud-snow",
6462
+ "cloud-off",
6463
+ "umbrella-outline",
6464
+ "thermometer-outline",
6465
+ "droplet",
6466
+ "wind",
6467
+ // Agua y fuego
6468
+ "water-outline",
6469
+ "flame-outline",
6470
+ "bonfire-outline",
6471
+ "eyedrop-outline",
6472
+ // Flora y fauna
6473
+ "leaf-outline",
6474
+ "flower-outline",
6475
+ "bug-outline",
6476
+ "fish-outline",
6477
+ "paw-outline",
6478
+ // Outdoor
6479
+ "binoculars-outline",
6480
+ "telescope-outline",
6481
+ "compass-outline",
6482
+ "map-outline",
6483
+ "location-outline",
6484
+ "flag-outline",
6485
+ "trail-sign-outline",
6486
+ "earth-outline",
6487
+ "globe-outline",
6488
+ "planet-outline",
6489
+ "compass",
6490
+ "map",
6491
+ "map-pin",
6492
+ "flag",
6493
+ "navigation",
6494
+ "navigation-2",
6495
+ "target",
6496
+ "crosshair",
6497
+ "life-buoy"
6498
+ ]
6499
+ },
6500
+ // ─── Brands ──────────────────────────────────────────────────────────────────
6501
+ {
6502
+ name: "brands",
6503
+ label: "Brands",
6504
+ labelEs: "Marcas",
6505
+ categoryIcon: "globe",
6506
+ icons: [
6507
+ // Feather brand icons — outlined, consistent with the rest of the library
6508
+ "github",
6509
+ "gitlab",
6510
+ "codepen",
6511
+ "codesandbox",
6512
+ "twitter",
6513
+ "facebook",
6514
+ "instagram",
6515
+ "linkedin",
6516
+ "youtube",
6517
+ "dribbble",
6518
+ "twitch",
6519
+ "slack",
6520
+ "figma",
6521
+ "framer",
6522
+ "chrome",
6523
+ "rss",
6524
+ // Filled / flat brand logos (FA5 brands) — kept in a second
6525
+ // visual tier. Rendered as the brand's official silhouette.
6526
+ // Visually consistent (all flat single-color) but heavier than the
6527
+ // Feather outlined set above. Use these only when an outlined Feather
6528
+ // version of the brand doesn't exist.
6529
+ "reddit",
6530
+ "tiktok",
6531
+ "pinterest",
6532
+ "whatsapp",
6533
+ "discord",
6534
+ "snapchat",
6535
+ "telegram",
6536
+ "viber",
6537
+ "line",
6538
+ "vimeo",
6539
+ "tumblr",
6540
+ "behance",
6541
+ "medium",
6542
+ "soundcloud",
6543
+ "google",
6544
+ "apple",
6545
+ "android",
6546
+ "windows",
6547
+ "linux",
6548
+ "amazon",
6549
+ "paypal",
6550
+ "stripe",
6551
+ "shopify",
6552
+ "dropbox",
6553
+ "spotify",
6554
+ "steam",
6555
+ "atlassian",
6556
+ "jira",
6557
+ "confluence",
6558
+ "bitbucket",
6559
+ "jenkins",
6560
+ "docker",
6561
+ "aws",
6562
+ "node",
6563
+ "react",
6564
+ "angular",
6565
+ "wordpress",
6566
+ "drupal",
6567
+ "joomla",
6568
+ "squarespace",
6569
+ "wix",
6570
+ "magento",
6571
+ "terminal",
6572
+ "pen-tool"
6573
+ ]
6574
+ }
6575
+ ];
6576
+ var ALL_CURATED_ICONS = [
6577
+ ...new Set(CURATED_ICONS.flatMap((c) => c.icons))
6578
+ ];
6579
+
6580
+ // src/components/IconPicker/IconPicker.tsx
6581
+ var NUM_COLUMNS = 6;
6582
+ var GAP = 6;
6583
+ var TRIGGER_SIZE = s(56);
6584
+ var SCREEN_HEIGHT = reactNative.Dimensions.get("window").height;
6585
+ function IconCell({ name, selected, size, onPress }) {
6586
+ const { colors } = useTheme();
6587
+ const handlePress = () => {
6588
+ selectionAsync();
6589
+ onPress();
6590
+ };
6591
+ const iconColor = selected ? colors.primaryForeground : colors.foreground;
6592
+ const bg = selected ? colors.primary : "transparent";
6593
+ return /* @__PURE__ */ React54__default.default.createElement(
6594
+ reactNative.TouchableOpacity,
6595
+ {
6596
+ onPress: handlePress,
6597
+ activeOpacity: 0.6,
6598
+ touchSoundDisabled: true,
6599
+ accessibilityRole: "button",
6600
+ accessibilityState: { selected },
6601
+ accessibilityLabel: name,
6602
+ style: [styles47.cell, { width: size, height: size, backgroundColor: bg }]
6603
+ },
6604
+ renderIcon(name, ms(20), iconColor)
6605
+ );
6606
+ }
6607
+ var IconCellMemo = React54__default.default.memo(IconCell);
6608
+ function IconPicker({
6609
+ value,
6610
+ onChange,
6611
+ label,
6612
+ error,
6613
+ hint,
6614
+ disabled = false,
6615
+ numColumns = NUM_COLUMNS,
6616
+ gap = GAP,
6617
+ style
6618
+ }) {
6619
+ const { colors } = useTheme();
6620
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
6621
+ const sheetRef = React54.useRef(null);
6622
+ const catScrollRef = React54.useRef(null);
6623
+ const [activeCategory, setActiveCategory] = React54.useState(null);
6624
+ const [containerWidth, setContainerWidth] = React54.useState(() => reactNative.Dimensions.get("window").width - s(16) * 2);
6625
+ const [ready, setReady] = React54.useState(false);
6626
+ const sheetName = React54.useId();
6627
+ const activeIcons = React54.useMemo(() => {
6628
+ if (activeCategory) {
6629
+ return CURATED_ICONS.find((c) => c.name === activeCategory)?.icons ?? ALL_CURATED_ICONS;
6630
+ }
6631
+ return ALL_CURATED_ICONS;
6632
+ }, [activeCategory]);
6633
+ const gapPx = s(gap);
6634
+ const cellSize = containerWidth > 0 ? Math.floor((containerWidth - gapPx * (numColumns - 1)) / numColumns) : 0;
6635
+ const rows = React54.useMemo(() => {
6636
+ const result = [];
6637
+ for (let i = 0; i < activeIcons.length; i += numColumns) {
6638
+ result.push(activeIcons.slice(i, i + numColumns));
6639
+ }
6640
+ return result;
6641
+ }, [activeIcons, numColumns]);
6642
+ const handleDismiss = React54.useCallback(() => {
6643
+ setActiveCategory(null);
6644
+ setReady(false);
6645
+ }, []);
6646
+ const handleSelect = React54.useCallback(
6647
+ (iconName) => {
6648
+ onChange(iconName);
6649
+ },
6650
+ [onChange]
6651
+ );
6652
+ const handleOpen = React54.useCallback(() => {
6653
+ if (disabled) return;
6654
+ impactMedium();
6655
+ setActiveCategory(null);
6656
+ setReady(false);
6657
+ sheetRef.current?.present();
6658
+ }, [disabled]);
6659
+ const renderBackdrop = React54.useCallback(
6660
+ (props) => /* @__PURE__ */ React54__default.default.createElement(bottomSheet.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, pressBehavior: "close" }),
6661
+ []
6662
+ );
6663
+ const selectedIcon = value ? renderIcon(value, ms(28), colors.foreground) : null;
6664
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles47.triggerContainer, style] }, label ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles47.triggerLabel, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React54__default.default.createElement(
6665
+ reactNative.TouchableOpacity,
6666
+ {
6667
+ onPress: handleOpen,
6668
+ disabled,
6669
+ activeOpacity: 0.7,
6670
+ touchSoundDisabled: true,
6671
+ accessibilityRole: "button",
6672
+ accessibilityLabel: label ?? "Seleccionar icono",
6673
+ accessibilityState: { disabled },
6674
+ style: [
6675
+ styles47.trigger,
6676
+ {
6677
+ backgroundColor: disabled ? colors.surface : colors.background,
6678
+ width: TRIGGER_SIZE,
6679
+ height: TRIGGER_SIZE,
6680
+ borderColor: error ? colors.destructive : value ? colors.primary : colors.border
6681
+ },
6682
+ disabled && styles47.triggerDisabled
6683
+ ]
6684
+ },
6685
+ selectedIcon ?? renderIcon("plus", ms(24), colors.foregroundMuted)
6686
+ ), error ? /* @__PURE__ */ React54__default.default.createElement(
6687
+ reactNative.Text,
6688
+ {
6689
+ style: [styles47.helperText, { color: colors.destructive }],
6690
+ allowFontScaling: true,
6691
+ accessibilityLiveRegion: "polite"
6692
+ },
6693
+ error
6694
+ ) : null, !error && hint ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles47.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null, /* @__PURE__ */ React54__default.default.createElement(
6695
+ bottomSheet.BottomSheetModal,
6696
+ {
6697
+ ref: sheetRef,
6698
+ name: sheetName,
6699
+ onDismiss: handleDismiss,
6700
+ enableDynamicSizing: true,
6701
+ maxDynamicContentSize: SCREEN_HEIGHT * 0.7,
6702
+ backdropComponent: renderBackdrop,
6703
+ backgroundStyle: { ...styles47.sheetBackground, backgroundColor: colors.card },
6704
+ handleIndicatorStyle: { ...styles47.handle, backgroundColor: colors.border },
6705
+ enablePanDownToClose: true,
6706
+ topInset: insets.top,
6707
+ android_keyboardInputMode: "adjustPan"
6708
+ },
6709
+ /* @__PURE__ */ React54__default.default.createElement(
6710
+ bottomSheet.BottomSheetScrollView,
6711
+ {
6712
+ contentContainerStyle: styles47.sheetContent,
6713
+ showsVerticalScrollIndicator: true
6714
+ },
6715
+ /* @__PURE__ */ React54__default.default.createElement(
6716
+ reactNative.View,
6717
+ {
6718
+ style: styles47.gridContainer,
6719
+ onLayout: (e) => {
6720
+ setContainerWidth(e.nativeEvent.layout.width);
6721
+ setReady(true);
6722
+ }
6723
+ },
6724
+ !ready ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles47.loader }, /* @__PURE__ */ React54__default.default.createElement(Spinner, { size: "md", color: colors.primary, label: "Cargando iconos..." })) : /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles47.sectionLabel, { color: colors.foregroundSubtle }], allowFontScaling: true }, "Categor\xEDas"), /* @__PURE__ */ React54__default.default.createElement(
6725
+ reactNativeGestureHandler.ScrollView,
6726
+ {
6727
+ ref: catScrollRef,
6728
+ horizontal: true,
6729
+ showsHorizontalScrollIndicator: false,
6730
+ contentContainerStyle: styles47.categoryStrip,
6731
+ style: styles47.categoryScroll
6732
+ },
6733
+ /* @__PURE__ */ React54__default.default.createElement(
6734
+ reactNative.TouchableOpacity,
6735
+ {
6736
+ onPress: () => setActiveCategory(null),
6737
+ activeOpacity: 0.7,
6738
+ touchSoundDisabled: true,
6739
+ accessibilityRole: "button",
6740
+ accessibilityLabel: "Todos",
6741
+ accessibilityState: { selected: activeCategory === null },
6742
+ style: [
6743
+ styles47.categoryChip,
6744
+ {
6745
+ backgroundColor: activeCategory === null ? colors.primary : colors.surface,
6746
+ borderColor: activeCategory === null ? colors.primary : colors.border
6747
+ }
6748
+ ]
6749
+ },
6750
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles47.categoryChipInner }, renderIcon("grid", ms(14), activeCategory === null ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React54__default.default.createElement(
6751
+ reactNative.Text,
6752
+ {
6753
+ style: [
6754
+ styles47.categoryChipText,
6755
+ { color: activeCategory === null ? colors.primaryForeground : colors.foreground }
6756
+ ],
6757
+ allowFontScaling: true,
6758
+ numberOfLines: 1
6759
+ },
6760
+ "Todos"
6761
+ ))
6762
+ ),
6763
+ CURATED_ICONS.map((cat) => /* @__PURE__ */ React54__default.default.createElement(
6764
+ reactNative.TouchableOpacity,
6765
+ {
6766
+ key: cat.name,
6767
+ onPress: () => setActiveCategory(cat.name),
6768
+ activeOpacity: 0.7,
6769
+ touchSoundDisabled: true,
6770
+ accessibilityRole: "button",
6771
+ accessibilityLabel: cat.labelEs,
6772
+ accessibilityState: { selected: activeCategory === cat.name },
6773
+ style: [
6774
+ styles47.categoryChip,
6775
+ {
6776
+ backgroundColor: activeCategory === cat.name ? colors.primary : colors.surface,
6777
+ borderColor: activeCategory === cat.name ? colors.primary : colors.border
6778
+ }
6779
+ ]
6780
+ },
6781
+ /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles47.categoryChipInner }, renderIcon(cat.categoryIcon, ms(14), activeCategory === cat.name ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React54__default.default.createElement(
6782
+ reactNative.Text,
6783
+ {
6784
+ style: [
6785
+ styles47.categoryChipText,
6786
+ { color: activeCategory === cat.name ? colors.primaryForeground : colors.foreground }
6787
+ ],
6788
+ allowFontScaling: true,
6789
+ numberOfLines: 1
6790
+ },
6791
+ cat.labelEs
6792
+ ))
6793
+ ))
6794
+ ), /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles47.separator, { backgroundColor: colors.border }] }), cellSize > 0 ? rows.map((row, i) => /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { key: row[0] ?? `row-${i}`, style: [styles47.row, { marginBottom: gapPx }] }, row.map((name) => /* @__PURE__ */ React54__default.default.createElement(
6795
+ IconCellMemo,
6796
+ {
6797
+ key: name,
6798
+ name,
6799
+ selected: value === name,
6800
+ size: cellSize,
6801
+ onPress: () => {
6802
+ handleSelect(name);
6803
+ sheetRef.current?.dismiss();
6804
+ }
6805
+ }
6806
+ )), Array.from({ length: numColumns - row.length }).map((_, j) => /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { key: `spacer-${j}`, style: { width: cellSize, height: cellSize } })))) : null)
6807
+ )
6808
+ )
6809
+ ));
6810
+ }
6811
+ var styles47 = reactNative.StyleSheet.create({
6812
+ triggerContainer: {
6813
+ gap: vs(8)
6814
+ },
6815
+ triggerLabel: {
6816
+ fontFamily: "Sohne-Medium",
6817
+ fontSize: ms(14)
6818
+ },
6819
+ trigger: {
6820
+ borderRadius: RADIUS.md,
6821
+ borderWidth: 1,
6822
+ alignItems: "center",
6823
+ justifyContent: "center"
6824
+ },
6825
+ triggerDisabled: {
6826
+ opacity: 0.6
6827
+ },
6828
+ helperText: {
6829
+ fontFamily: "Sohne-Regular",
6830
+ fontSize: ms(13)
6831
+ },
6832
+ sheetBackground: {
6833
+ borderTopLeftRadius: ms(16),
6834
+ borderTopRightRadius: ms(16)
6835
+ },
6836
+ handle: {
6837
+ width: s(36),
6838
+ height: vs(4),
6839
+ borderRadius: ms(2)
6840
+ },
6841
+ sheetContent: {
6842
+ paddingHorizontal: s(16),
6843
+ paddingBottom: vs(24)
6844
+ },
6845
+ sectionLabel: {
6846
+ fontFamily: "Sohne-Medium",
6847
+ fontSize: ms(12),
6848
+ marginBottom: vs(8),
6849
+ textTransform: "uppercase",
6850
+ letterSpacing: 0.5
6851
+ },
6852
+ categoryScroll: {
6853
+ flexGrow: 0,
6854
+ flexShrink: 0
6855
+ },
6856
+ categoryStrip: {
6857
+ gap: s(8)
6858
+ },
6859
+ categoryChip: {
6860
+ borderRadius: RADIUS.full,
6861
+ borderWidth: 1,
6862
+ paddingVertical: vs(6),
6863
+ paddingHorizontal: s(12)
6864
+ },
6865
+ categoryChipInner: {
6866
+ flexDirection: "row",
6867
+ alignItems: "center",
6868
+ gap: s(6)
6869
+ },
6870
+ categoryChipText: {
6871
+ fontFamily: "Sohne-Medium",
6872
+ fontSize: ms(12)
6873
+ },
6874
+ separator: {
6875
+ height: reactNative.StyleSheet.hairlineWidth,
6876
+ marginVertical: vs(12)
6877
+ },
6878
+ gridContainer: {},
6879
+ row: {
6880
+ flexDirection: "row",
6881
+ gap: GAP
6882
+ },
6883
+ cell: {
6884
+ borderRadius: RADIUS.md,
6885
+ alignItems: "center",
6886
+ justifyContent: "center"
6887
+ },
6888
+ loader: {
6889
+ minHeight: vs(200),
6890
+ alignItems: "center",
6891
+ justifyContent: "center"
6892
+ }
6893
+ });
6894
+ var sizeConfig = {
6895
+ sm: { button: s(40), icon: 16, valueFontSize: ms(18), valueLineHeight: mvs(24), valueMinWidth: s(32) },
6896
+ md: { button: s(44), icon: 18, valueFontSize: ms(22), valueLineHeight: mvs(28), valueMinWidth: s(36) },
6897
+ lg: { button: s(52), icon: 22, valueFontSize: ms(26), valueLineHeight: mvs(32), valueMinWidth: s(40) }
6898
+ };
6899
+ function NumberStepperBase({
6900
+ value,
6901
+ onValueChange,
6902
+ min = 1,
6903
+ max = 99,
6904
+ step = 1,
6905
+ size = "md",
6906
+ disabled = false,
6907
+ style,
6908
+ accessibilityLabel
6909
+ }) {
6910
+ const { colors } = useTheme();
6911
+ const canDecrement = value > min && !disabled;
6912
+ const canIncrement = value < max && !disabled;
6913
+ const handleDecrement = () => {
6914
+ if (!canDecrement) return;
6915
+ impactLight();
6916
+ onValueChange(Math.max(min, value - step));
6917
+ };
6918
+ const handleIncrement = () => {
6919
+ if (!canIncrement) return;
6920
+ impactLight();
6921
+ onValueChange(Math.min(max, value + step));
6922
+ };
6923
+ const { button: buttonSize, icon: iconSize, valueFontSize, valueLineHeight, valueMinWidth } = sizeConfig[size];
6924
+ const displayValue = String(value);
6925
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles48.container, style] }, /* @__PURE__ */ React54__default.default.createElement(
6926
+ PressableButton,
6927
+ {
6928
+ style: [
6929
+ styles48.button,
6930
+ {
6931
+ width: buttonSize,
6932
+ height: buttonSize,
6933
+ backgroundColor: colors.surface,
6934
+ borderColor: colors.border
6935
+ },
6936
+ !canDecrement && styles48.buttonDisabled
6937
+ ],
6938
+ enabled: canDecrement,
6939
+ onPress: handleDecrement,
6940
+ rippleColor: "transparent",
6941
+ touchSoundDisabled: true,
6942
+ accessibilityRole: "button",
6943
+ accessibilityLabel: `Decrease, current value ${displayValue}`,
6944
+ accessibilityState: { disabled: !canDecrement }
6945
+ },
6946
+ renderIcon("minus", iconSize, canDecrement ? colors.foreground : colors.foregroundMuted)
6947
+ ), /* @__PURE__ */ React54__default.default.createElement(
6948
+ reactNative.Text,
6949
+ {
6950
+ style: [
6951
+ styles48.value,
6952
+ {
6953
+ color: colors.foreground,
6954
+ fontSize: valueFontSize,
6955
+ lineHeight: valueLineHeight,
6956
+ minWidth: valueMinWidth
6957
+ }
6958
+ ],
6959
+ allowFontScaling: true,
6960
+ accessibilityLabel: accessibilityLabel ?? `Quantity: ${displayValue}`,
6961
+ accessibilityRole: "text"
6962
+ },
6963
+ displayValue
6964
+ ), /* @__PURE__ */ React54__default.default.createElement(
6965
+ PressableButton,
6966
+ {
6967
+ style: [
6968
+ styles48.button,
6969
+ {
6970
+ width: buttonSize,
6971
+ height: buttonSize,
6972
+ backgroundColor: colors.surface,
6973
+ borderColor: colors.border
6974
+ },
6975
+ !canIncrement && styles48.buttonDisabled
6976
+ ],
6977
+ enabled: canIncrement,
6978
+ onPress: handleIncrement,
6979
+ rippleColor: "transparent",
6980
+ touchSoundDisabled: true,
6981
+ accessibilityRole: "button",
6982
+ accessibilityLabel: `Increase, current value ${displayValue}`,
6983
+ accessibilityState: { disabled: !canIncrement }
6984
+ },
6985
+ renderIcon("plus", iconSize, canIncrement ? colors.foreground : colors.foregroundMuted)
6986
+ ));
6987
+ }
6988
+ var NumberStepper = React54__default.default.memo(NumberStepperBase);
6989
+ var styles48 = reactNative.StyleSheet.create({
6990
+ container: {
6991
+ flexDirection: "row",
6992
+ alignItems: "center",
6993
+ gap: s(12)
6994
+ },
6995
+ button: {
6996
+ borderRadius: RADIUS.md,
6997
+ alignItems: "center",
6998
+ justifyContent: "center",
6999
+ borderWidth: 1.5
7000
+ },
7001
+ buttonDisabled: {
7002
+ opacity: 0.35
7003
+ },
7004
+ value: {
7005
+ fontFamily: "Sohne-Medium",
7006
+ textAlign: "center"
7007
+ }
7008
+ });
7009
+ var COMPACT_THRESHOLD = s(150);
7010
+ function StatsComponent({
7011
+ value,
7012
+ label,
7013
+ description,
7014
+ icon,
7015
+ iconName,
7016
+ iconColor,
7017
+ variant = "elevated",
7018
+ onPress,
7019
+ style,
7020
+ accessibilityLabel
7021
+ }) {
7022
+ const { colors } = useTheme();
7023
+ const [containerWidth, setContainerWidth] = React54.useState(0);
7024
+ const handleLayout = React54.useCallback((e) => {
7025
+ const w = e.nativeEvent.layout.width;
7026
+ if (w > 0 && w !== containerWidth) {
7027
+ setContainerWidth(w);
7028
+ }
7029
+ }, [containerWidth]);
7030
+ const handlePress = () => {
7031
+ if (!onPress) return;
7032
+ impactLight();
7033
+ onPress();
7034
+ };
7035
+ const isCompact = containerWidth > 0 && containerWidth < COMPACT_THRESHOLD && !!(icon ?? iconName);
7036
+ const variantStyle = {
7037
+ elevated: {
7038
+ backgroundColor: colors.card,
7039
+ borderWidth: 0,
7040
+ shadowColor: "#000",
7041
+ shadowOffset: { width: 0, height: 4 },
7042
+ shadowOpacity: 0.09,
7043
+ shadowRadius: 14,
7044
+ elevation: 4
7045
+ },
7046
+ outlined: {
7047
+ backgroundColor: colors.card,
7048
+ borderColor: colors.border,
7049
+ shadowOpacity: 0,
7050
+ elevation: 0
7051
+ },
7052
+ filled: {
7053
+ backgroundColor: colors.surfaceStrong,
7054
+ borderColor: colors.border,
7055
+ shadowOpacity: 0,
7056
+ elevation: 0
7057
+ }
7058
+ }[variant];
7059
+ const iconColorResolved = iconColor ?? colors.primary;
7060
+ const resolvedIcon = iconName ? renderIcon(iconName, ms(22), iconColorResolved) : icon;
7061
+ const iconElement = resolvedIcon ? /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles49.iconWrapper }, resolvedIcon) : null;
7062
+ const valueElement = /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles49.value, { color: colors.foreground }], allowFontScaling: true }, value);
7063
+ const cardContent = /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles49.card, variantStyle, style], onLayout: handleLayout }, isCompact ? /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, iconElement, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles49.compactValue }, valueElement), /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles49.label, { color: colors.foregroundSubtle }], allowFontScaling: true }, label), description ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles49.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : /* @__PURE__ */ React54__default.default.createElement(React54__default.default.Fragment, null, /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles49.valueRow }, iconElement, valueElement), /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles49.label, { color: colors.foregroundSubtle }], allowFontScaling: true }, label), description ? /* @__PURE__ */ React54__default.default.createElement(reactNative.Text, { style: [styles49.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null));
7064
+ if (onPress) {
7065
+ return /* @__PURE__ */ React54__default.default.createElement(
7066
+ PressableCard,
7067
+ {
7068
+ onPress: handlePress,
7069
+ rippleColor: "transparent",
7070
+ touchSoundDisabled: true,
7071
+ activateOnHover: true,
7072
+ accessibilityRole: "button",
7073
+ accessibilityLabel
7074
+ },
7075
+ cardContent
7076
+ );
7077
+ }
7078
+ return cardContent;
7079
+ }
7080
+ function StatsGroup({ children, gap = s(12), style }) {
7081
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: [styles49.group, { gap }, style] }, React54__default.default.Children.map(children, (child) => {
7082
+ if (!React54__default.default.isValidElement(child)) return child;
7083
+ const childStyle = child.props.style;
7084
+ const mergedStyle = childStyle ? [childStyle, { alignSelf: "stretch" }] : [{ alignSelf: "stretch" }];
7085
+ return /* @__PURE__ */ React54__default.default.createElement(reactNative.View, { style: styles49.groupItem }, React54__default.default.cloneElement(
7086
+ child,
7087
+ { style: mergedStyle }
7088
+ ));
7089
+ }));
7090
+ }
7091
+ var Stats = Object.assign(React54__default.default.memo(StatsComponent), { Group: StatsGroup });
7092
+ var styles49 = reactNative.StyleSheet.create({
7093
+ card: {
7094
+ borderRadius: RADIUS.md,
7095
+ borderWidth: 1,
7096
+ padding: s(16),
7097
+ alignSelf: "flex-start",
7098
+ alignItems: "center",
7099
+ justifyContent: "center"
7100
+ },
7101
+ valueRow: {
7102
+ flexDirection: "row",
7103
+ alignItems: "center",
7104
+ justifyContent: "center",
7105
+ gap: s(8)
7106
+ },
7107
+ iconWrapper: {
7108
+ alignItems: "center",
7109
+ justifyContent: "center"
7110
+ },
7111
+ compactValue: {
7112
+ marginTop: vs(8)
7113
+ },
7114
+ value: {
7115
+ fontFamily: "Sohne-Bold",
7116
+ fontSize: ms(28),
7117
+ lineHeight: mvs(32),
7118
+ textAlign: "center"
7119
+ },
7120
+ label: {
7121
+ fontFamily: "Sohne-Regular",
7122
+ fontSize: ms(13),
7123
+ lineHeight: mvs(18),
7124
+ marginTop: vs(8),
7125
+ textAlign: "center"
7126
+ },
7127
+ description: {
7128
+ fontFamily: "Sohne-Regular",
7129
+ fontSize: ms(12),
7130
+ lineHeight: mvs(16),
7131
+ marginTop: vs(4),
7132
+ textAlign: "center"
7133
+ },
7134
+ group: {
7135
+ flexDirection: "row",
7136
+ width: "100%"
7137
+ },
7138
+ groupItem: {
7139
+ flex: 1
7140
+ }
7141
+ });
7142
+
5792
7143
  // src/utils/typography.ts
5793
7144
  function getResponsiveFontSize(text, maxSize, steps = [
5794
7145
  { maxLen: 10, subtract: 0 },
@@ -5803,14 +7154,14 @@ function getResponsiveFontSize(text, maxSize, steps = [
5803
7154
  return maxSize - 8;
5804
7155
  }
5805
7156
  function useConfirmDialog(options) {
5806
- const [visible, setVisible] = React25.useState(false);
5807
- const [target, setTarget] = React25.useState(null);
5808
- const [loading, setLoading] = React25.useState(false);
5809
- const open = React25.useCallback((t) => {
7157
+ const [visible, setVisible] = React54.useState(false);
7158
+ const [target, setTarget] = React54.useState(null);
7159
+ const [loading, setLoading] = React54.useState(false);
7160
+ const open = React54.useCallback((t) => {
5810
7161
  setTarget(t ?? null);
5811
7162
  setVisible(true);
5812
7163
  }, []);
5813
- const handleConfirm = React25.useCallback(async () => {
7164
+ const handleConfirm = React54.useCallback(async () => {
5814
7165
  setLoading(true);
5815
7166
  try {
5816
7167
  await options.onConfirm();
@@ -5820,7 +7171,7 @@ function useConfirmDialog(options) {
5820
7171
  setTarget(null);
5821
7172
  }
5822
7173
  }, [options]);
5823
- const handleCancel = React25.useCallback(() => {
7174
+ const handleCancel = React54.useCallback(() => {
5824
7175
  setVisible(false);
5825
7176
  setTarget(null);
5826
7177
  options.onCancel?.();
@@ -5841,11 +7192,11 @@ function useConfirmDialog(options) {
5841
7192
 
5842
7193
  Object.defineProperty(exports, "BottomSheetModalProvider", {
5843
7194
  enumerable: true,
5844
- get: function () { return BottomSheet.BottomSheetModalProvider; }
7195
+ get: function () { return bottomSheet.BottomSheetModalProvider; }
5845
7196
  });
5846
7197
  Object.defineProperty(exports, "SheetTextInput", {
5847
7198
  enumerable: true,
5848
- get: function () { return BottomSheet.BottomSheetTextInput; }
7199
+ get: function () { return bottomSheet.BottomSheetTextInput; }
5849
7200
  });
5850
7201
  Object.defineProperty(exports, "toast", {
5851
7202
  enumerable: true,
@@ -5882,6 +7233,7 @@ exports.FormSection = FormSection;
5882
7233
  exports.ICON_SIZES = ICON_SIZES;
5883
7234
  exports.Icon = Icon;
5884
7235
  exports.IconButton = IconButton;
7236
+ exports.IconPicker = IconPicker;
5885
7237
  exports.ImageUpload = ImageUpload;
5886
7238
  exports.ImageViewer = ImageViewer;
5887
7239
  exports.Input = Input;
@@ -5896,8 +7248,9 @@ exports.MenuGroupFooter = MenuGroupFooter;
5896
7248
  exports.MenuGroupHeader = MenuGroupHeader;
5897
7249
  exports.MenuItem = MenuItem;
5898
7250
  exports.MonthPicker = MonthPicker;
7251
+ exports.NumberStepper = NumberStepper;
5899
7252
  exports.PagerDots = PagerDots;
5900
- exports.Pressable = Pressable3;
7253
+ exports.Pressable = Pressable2;
5901
7254
  exports.PricingCard = PricingCard;
5902
7255
  exports.Progress = Progress;
5903
7256
  exports.RADIUS = RADIUS;
@@ -5913,6 +7266,7 @@ exports.SheetSelect = SheetSelect;
5913
7266
  exports.Skeleton = Skeleton;
5914
7267
  exports.Slider = Slider;
5915
7268
  exports.Spinner = Spinner;
7269
+ exports.Stats = Stats;
5916
7270
  exports.Switch = Switch;
5917
7271
  exports.TYPOGRAPHY = TYPOGRAPHY;
5918
7272
  exports.TabBar = TabBar;
@@ -5930,6 +7284,7 @@ exports.defaultDark = defaultDark;
5930
7284
  exports.defaultLight = defaultLight;
5931
7285
  exports.deriveColors = deriveColors;
5932
7286
  exports.getResponsiveFontSize = getResponsiveFontSize;
7287
+ exports.getValidIconNames = getValidIconNames;
5933
7288
  exports.impactHeavy = impactHeavy;
5934
7289
  exports.impactLight = impactLight;
5935
7290
  exports.impactMedium = impactMedium;
@@ -5943,3 +7298,4 @@ exports.selectionAsync = selectionAsync;
5943
7298
  exports.useConfirmDialog = useConfirmDialog;
5944
7299
  exports.useTheme = useTheme;
5945
7300
  exports.useToast = useToast;
7301
+ exports.withAlpha = withAlpha;