@retray-dev/ui-kit 13.0.0 → 13.4.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 (344) hide show
  1. package/CHANGELOG.md +680 -0
  2. package/CONSUMER.md +26 -9
  3. package/README.md +11 -12
  4. package/{COMPONENTS.md → SKILL.md} +515 -815
  5. package/dist/Accordion.d.mts +8 -6
  6. package/dist/Accordion.d.ts +8 -6
  7. package/dist/Accordion.js +40 -40
  8. package/dist/Accordion.mjs +4 -5
  9. package/dist/AlertBanner.d.mts +3 -3
  10. package/dist/AlertBanner.d.ts +3 -3
  11. package/dist/AlertBanner.js +7 -13
  12. package/dist/AlertBanner.mjs +4 -5
  13. package/dist/AppHeader.d.mts +8 -5
  14. package/dist/AppHeader.d.ts +8 -5
  15. package/dist/AppHeader.js +44 -31
  16. package/dist/AppHeader.mjs +6 -7
  17. package/dist/Avatar.d.mts +4 -4
  18. package/dist/Avatar.d.ts +4 -4
  19. package/dist/Avatar.mjs +2 -3
  20. package/dist/Badge.d.mts +5 -5
  21. package/dist/Badge.d.ts +5 -5
  22. package/dist/Badge.js +7 -13
  23. package/dist/Badge.mjs +3 -4
  24. package/dist/Button.d.mts +5 -5
  25. package/dist/Button.d.ts +5 -5
  26. package/dist/Button.js +31 -29
  27. package/dist/Button.mjs +5 -6
  28. package/dist/ButtonGroup.d.mts +3 -3
  29. package/dist/ButtonGroup.d.ts +3 -3
  30. package/dist/ButtonGroup.mjs +0 -1
  31. package/dist/Card.d.mts +13 -13
  32. package/dist/Card.d.ts +13 -13
  33. package/dist/Card.js +23 -14
  34. package/dist/Card.mjs +4 -5
  35. package/dist/CategoryStrip.d.mts +3 -3
  36. package/dist/CategoryStrip.d.ts +3 -3
  37. package/dist/CategoryStrip.js +30 -27
  38. package/dist/CategoryStrip.mjs +5 -6
  39. package/dist/Checkbox.d.mts +3 -2
  40. package/dist/Checkbox.d.ts +3 -2
  41. package/dist/Checkbox.js +26 -15
  42. package/dist/Checkbox.mjs +3 -4
  43. package/dist/Chip.d.mts +5 -5
  44. package/dist/Chip.d.ts +5 -5
  45. package/dist/Chip.js +30 -27
  46. package/dist/Chip.mjs +5 -6
  47. package/dist/ConfirmDialog.d.mts +3 -2
  48. package/dist/ConfirmDialog.d.ts +3 -2
  49. package/dist/ConfirmDialog.js +67 -49
  50. package/dist/ConfirmDialog.mjs +7 -7
  51. package/dist/CurrencyDisplay.d.mts +3 -3
  52. package/dist/CurrencyDisplay.d.ts +3 -3
  53. package/dist/CurrencyDisplay.mjs +2 -3
  54. package/dist/CurrencyInput.d.mts +2 -2
  55. package/dist/CurrencyInput.d.ts +2 -2
  56. package/dist/CurrencyInput.js +7 -13
  57. package/dist/CurrencyInput.mjs +4 -5
  58. package/dist/DetailRow.d.mts +6 -6
  59. package/dist/DetailRow.d.ts +6 -6
  60. package/dist/DetailRow.js +7 -13
  61. package/dist/DetailRow.mjs +3 -4
  62. package/dist/EmptyState.d.mts +4 -4
  63. package/dist/EmptyState.d.ts +4 -4
  64. package/dist/EmptyState.js +31 -29
  65. package/dist/EmptyState.mjs +6 -7
  66. package/dist/ErrorBoundary.d.mts +9 -7
  67. package/dist/ErrorBoundary.d.ts +9 -7
  68. package/dist/ErrorBoundary.js +33 -29
  69. package/dist/ErrorBoundary.mjs +5 -6
  70. package/dist/Form.d.mts +9 -9
  71. package/dist/Form.d.ts +9 -9
  72. package/dist/Form.mjs +2 -3
  73. package/dist/HolographicCard.d.mts +2 -2
  74. package/dist/HolographicCard.d.ts +2 -2
  75. package/dist/HolographicCard.js +23 -14
  76. package/dist/HolographicCard.mjs +2 -3
  77. package/dist/IconButton.d.mts +4 -4
  78. package/dist/IconButton.d.ts +4 -4
  79. package/dist/IconButton.js +30 -27
  80. package/dist/IconButton.mjs +4 -5
  81. package/dist/IconPicker.d.mts +2 -2
  82. package/dist/IconPicker.d.ts +2 -2
  83. package/dist/IconPicker.js +40 -45
  84. package/dist/IconPicker.mjs +6 -7
  85. package/dist/Image.d.mts +18 -0
  86. package/dist/Image.d.ts +18 -0
  87. package/dist/Image.js +53 -0
  88. package/dist/Image.mjs +2 -0
  89. package/dist/ImageUpload.d.mts +2 -4
  90. package/dist/ImageUpload.d.ts +2 -4
  91. package/dist/ImageUpload.js +50 -40
  92. package/dist/ImageUpload.mjs +5 -6
  93. package/dist/ImageViewer.d.mts +2 -2
  94. package/dist/ImageViewer.d.ts +2 -2
  95. package/dist/ImageViewer.js +31 -28
  96. package/dist/ImageViewer.mjs +6 -7
  97. package/dist/Input.d.mts +4 -4
  98. package/dist/Input.d.ts +4 -4
  99. package/dist/Input.js +7 -13
  100. package/dist/Input.mjs +3 -4
  101. package/dist/ItemGroup.d.mts +23 -0
  102. package/dist/ItemGroup.d.ts +23 -0
  103. package/dist/{ListGroup.js → ItemGroup.js} +11 -13
  104. package/dist/ItemGroup.mjs +4 -0
  105. package/dist/LabelValue.d.mts +4 -4
  106. package/dist/LabelValue.d.ts +4 -4
  107. package/dist/LabelValue.js +7 -13
  108. package/dist/LabelValue.mjs +3 -4
  109. package/dist/ListItem.d.mts +7 -6
  110. package/dist/ListItem.d.ts +7 -6
  111. package/dist/ListItem.js +33 -28
  112. package/dist/ListItem.mjs +5 -6
  113. package/dist/MediaCard.d.mts +6 -6
  114. package/dist/MediaCard.d.ts +6 -6
  115. package/dist/MediaCard.js +30 -27
  116. package/dist/MediaCard.mjs +5 -6
  117. package/dist/MenuItem.d.mts +6 -5
  118. package/dist/MenuItem.d.ts +6 -5
  119. package/dist/MenuItem.js +33 -28
  120. package/dist/MenuItem.mjs +5 -6
  121. package/dist/MonthPicker.d.mts +2 -2
  122. package/dist/MonthPicker.d.ts +2 -2
  123. package/dist/MonthPicker.js +23 -14
  124. package/dist/MonthPicker.mjs +3 -4
  125. package/dist/NumberStepper.d.mts +4 -3
  126. package/dist/NumberStepper.d.ts +4 -3
  127. package/dist/NumberStepper.js +34 -28
  128. package/dist/NumberStepper.mjs +5 -6
  129. package/dist/PagerDots.d.mts +2 -2
  130. package/dist/PagerDots.d.ts +2 -2
  131. package/dist/PagerDots.js +30 -27
  132. package/dist/PagerDots.mjs +4 -5
  133. package/dist/Pressable.d.mts +3 -27
  134. package/dist/Pressable.d.ts +3 -27
  135. package/dist/Pressable.js +23 -14
  136. package/dist/Pressable.mjs +2 -3
  137. package/dist/PricingCard.d.mts +2 -2
  138. package/dist/PricingCard.d.ts +2 -2
  139. package/dist/PricingCard.js +31 -29
  140. package/dist/PricingCard.mjs +7 -8
  141. package/dist/Progress.d.mts +2 -2
  142. package/dist/Progress.d.ts +2 -2
  143. package/dist/Progress.mjs +2 -3
  144. package/dist/RadioGroup.d.mts +2 -2
  145. package/dist/RadioGroup.d.ts +2 -2
  146. package/dist/RadioGroup.js +23 -14
  147. package/dist/RadioGroup.mjs +3 -4
  148. package/dist/RetrayProvider.d.mts +1 -1
  149. package/dist/RetrayProvider.d.ts +1 -1
  150. package/dist/RetrayProvider.js +14 -34
  151. package/dist/RetrayProvider.mjs +3 -4
  152. package/dist/ScreenContainer.d.mts +24 -0
  153. package/dist/ScreenContainer.d.ts +24 -0
  154. package/dist/ScreenContainer.js +85 -0
  155. package/dist/ScreenContainer.mjs +3 -0
  156. package/dist/Select.d.mts +3 -2
  157. package/dist/Select.d.ts +3 -2
  158. package/dist/Select.js +41 -46
  159. package/dist/Select.mjs +3 -4
  160. package/dist/SelectableCard.d.mts +5 -5
  161. package/dist/SelectableCard.d.ts +5 -5
  162. package/dist/SelectableCard.js +30 -27
  163. package/dist/SelectableCard.mjs +5 -6
  164. package/dist/SelectableGrid.d.mts +5 -4
  165. package/dist/SelectableGrid.d.ts +5 -4
  166. package/dist/SelectableGrid.js +80 -45
  167. package/dist/SelectableGrid.mjs +5 -6
  168. package/dist/Separator.d.mts +4 -2
  169. package/dist/Separator.d.ts +4 -2
  170. package/dist/Separator.js +29 -1
  171. package/dist/Separator.mjs +3 -3
  172. package/dist/Sheet.d.mts +11 -11
  173. package/dist/Sheet.d.ts +11 -11
  174. package/dist/Sheet.js +62 -34
  175. package/dist/Sheet.mjs +4 -4
  176. package/dist/SheetSelect.d.mts +2 -2
  177. package/dist/SheetSelect.d.ts +2 -2
  178. package/dist/SheetSelect.js +30 -27
  179. package/dist/SheetSelect.mjs +5 -6
  180. package/dist/Skeleton.d.mts +5 -5
  181. package/dist/Skeleton.d.ts +5 -5
  182. package/dist/Skeleton.mjs +3 -4
  183. package/dist/Slider.d.mts +3 -2
  184. package/dist/Slider.d.ts +3 -2
  185. package/dist/Slider.js +25 -14
  186. package/dist/Slider.mjs +3 -4
  187. package/dist/Spinner.d.mts +2 -2
  188. package/dist/Spinner.d.ts +2 -2
  189. package/dist/Spinner.mjs +2 -3
  190. package/dist/Stats.d.mts +6 -6
  191. package/dist/Stats.d.ts +6 -6
  192. package/dist/Stats.js +30 -27
  193. package/dist/Stats.mjs +5 -6
  194. package/dist/Switch.d.mts +3 -2
  195. package/dist/Switch.d.ts +3 -2
  196. package/dist/Switch.js +25 -15
  197. package/dist/Switch.mjs +3 -4
  198. package/dist/TabBar.d.mts +3 -3
  199. package/dist/TabBar.d.ts +3 -3
  200. package/dist/TabBar.js +30 -27
  201. package/dist/TabBar.mjs +4 -5
  202. package/dist/Tabs.d.mts +13 -13
  203. package/dist/Tabs.d.ts +13 -13
  204. package/dist/Tabs.js +23 -14
  205. package/dist/Tabs.mjs +3 -4
  206. package/dist/Text.d.mts +4 -4
  207. package/dist/Text.d.ts +4 -4
  208. package/dist/Text.js +20 -2
  209. package/dist/Text.mjs +3 -4
  210. package/dist/Textarea.d.mts +3 -3
  211. package/dist/Textarea.d.ts +3 -3
  212. package/dist/Textarea.js +7 -13
  213. package/dist/Textarea.mjs +3 -4
  214. package/dist/Toast.d.mts +15 -13
  215. package/dist/Toast.d.ts +15 -13
  216. package/dist/Toast.mjs +2 -3
  217. package/dist/Toggle.d.mts +4 -4
  218. package/dist/Toggle.d.ts +4 -4
  219. package/dist/Toggle.js +30 -27
  220. package/dist/Toggle.mjs +4 -5
  221. package/dist/VirtualizedList.d.mts +28 -0
  222. package/dist/VirtualizedList.d.ts +28 -0
  223. package/dist/VirtualizedList.js +130 -0
  224. package/dist/VirtualizedList.mjs +3 -0
  225. package/dist/{chunk-MZ6WRTD2.mjs → chunk-24JTXQ2M.mjs} +7 -13
  226. package/dist/{chunk-OBV72JD4.mjs → chunk-2DDJ53DK.mjs} +9 -11
  227. package/dist/{chunk-6CR4S6W2.mjs → chunk-2J5OZOMX.mjs} +19 -8
  228. package/dist/{chunk-4NQFTHN3.mjs → chunk-3GE4UFV5.mjs} +2 -2
  229. package/dist/{chunk-KAGADD2O.mjs → chunk-3RIZCKRM.mjs} +2 -2
  230. package/dist/{chunk-DE25XTVQ.mjs → chunk-3VHFOSZR.mjs} +2 -2
  231. package/dist/{chunk-UOKFSFNJ.mjs → chunk-4PF4LKNT.mjs} +4 -2
  232. package/dist/{chunk-5MYNAAFE.mjs → chunk-5J7VKFSZ.mjs} +4 -4
  233. package/dist/{chunk-BTUW5LSG.mjs → chunk-5TNQ573V.mjs} +4 -3
  234. package/dist/{chunk-6QLBHUEG.mjs → chunk-6T2DVIQT.mjs} +7 -5
  235. package/dist/{chunk-L3YKPTJQ.mjs → chunk-7CE6PDCQ.mjs} +2 -2
  236. package/dist/{chunk-Y6YS33GM.mjs → chunk-AHFEAY6M.mjs} +4 -4
  237. package/dist/{chunk-4ZO5PTKF.mjs → chunk-AZRATPNP.mjs} +5 -3
  238. package/dist/{chunk-V2ZB2XNS.mjs → chunk-BGXOEFDM.mjs} +9 -22
  239. package/dist/{chunk-KC5QDYGZ.mjs → chunk-BMAAAJWN.mjs} +2 -2
  240. package/dist/{chunk-IJCMPVW5.mjs → chunk-BQMJQMWY.mjs} +2 -2
  241. package/dist/{chunk-E4EQSCKR.mjs → chunk-BTPCY4C7.mjs} +7 -5
  242. package/dist/chunk-BVJAYPAD.mjs +55 -0
  243. package/dist/{chunk-RA6SAAFE.mjs → chunk-BWLVX2SQ.mjs} +4 -4
  244. package/dist/{chunk-EROPDCB5.mjs → chunk-CCEM3HIJ.mjs} +30 -25
  245. package/dist/chunk-CTUFFKGS.mjs +30 -0
  246. package/dist/{chunk-EHGBHFMH.mjs → chunk-CYGYC7XT.mjs} +8 -4
  247. package/dist/{chunk-ESQDPO5E.mjs → chunk-DLAOTHHS.mjs} +7 -6
  248. package/dist/{chunk-QY3X2UYR.mjs → chunk-DYYPDQA2.mjs} +21 -7
  249. package/dist/{chunk-S44XWTTC.mjs → chunk-E4BJ5WXG.mjs} +3 -3
  250. package/dist/{chunk-HUSSF6TF.mjs → chunk-EQNCMDZC.mjs} +1 -1
  251. package/dist/{chunk-PI6RULJX.mjs → chunk-EQYTDFDD.mjs} +1 -1
  252. package/dist/{chunk-BULKGOIZ.mjs → chunk-FE26TPCI.mjs} +4 -4
  253. package/dist/{chunk-DBHSUUKU.mjs → chunk-FOUSI6JD.mjs} +1 -1
  254. package/dist/{chunk-KPTY7UYQ.mjs → chunk-GR7PKEKD.mjs} +1 -1
  255. package/dist/{chunk-RRKM4MKB.mjs → chunk-HLWGFBIF.mjs} +3 -3
  256. package/dist/chunk-HMKJGVXA.mjs +35 -0
  257. package/dist/{chunk-U6DEBYU5.mjs → chunk-IFGZUJFH.mjs} +3 -3
  258. package/dist/{chunk-2VIDP72N.mjs → chunk-K3V6OTVB.mjs} +1 -1
  259. package/dist/{chunk-K7TKID3V.mjs → chunk-K4YFTUMC.mjs} +3 -3
  260. package/dist/{chunk-NGEN2EES.mjs → chunk-MQAK2W6L.mjs} +14 -22
  261. package/dist/{chunk-CM2DG4MR.mjs → chunk-MSS3CD6F.mjs} +4 -4
  262. package/dist/{chunk-TETMEKZE.mjs → chunk-NQYS6RPX.mjs} +8 -5
  263. package/dist/{chunk-62BBSSUF.mjs → chunk-P5KC3RTG.mjs} +1 -1
  264. package/dist/{chunk-K3QX2M26.mjs → chunk-PPKCGCZ3.mjs} +5 -5
  265. package/dist/{chunk-ITG4JQM3.mjs → chunk-QEE3EQ3N.mjs} +2 -2
  266. package/dist/{chunk-URIH43IJ.mjs → chunk-RLPPRIJ7.mjs} +20 -34
  267. package/dist/{chunk-XCIG6HT2.mjs → chunk-S433IOQE.mjs} +2 -2
  268. package/dist/{chunk-IGU223UM.mjs → chunk-SWUZKVYO.mjs} +1 -1
  269. package/dist/{chunk-MP7GLMIR.mjs → chunk-T4KMKHTI.mjs} +55 -23
  270. package/dist/{chunk-2QOHHBJC.mjs → chunk-UBTP4NPP.mjs} +5 -21
  271. package/dist/{chunk-TMH263OK.mjs → chunk-UEA2VYGW.mjs} +3 -3
  272. package/dist/chunk-VISIOH33.mjs +37 -0
  273. package/dist/{chunk-SZEKQAOY.mjs → chunk-VSKBODEY.mjs} +1 -1
  274. package/dist/{chunk-FTTI6T5Q.mjs → chunk-W422TEH2.mjs} +3 -3
  275. package/dist/{chunk-WIPEDNSD.mjs → chunk-WD5LBXPR.mjs} +4 -4
  276. package/dist/chunk-WFNGSYS4.mjs +111 -0
  277. package/dist/chunk-WR6DCNAE.mjs +65 -0
  278. package/dist/{chunk-ERWJPVX7.mjs → chunk-XKBB2UZU.mjs} +2 -2
  279. package/dist/{chunk-CBIZLRYH.mjs → chunk-Y5TPAKOS.mjs} +14 -17
  280. package/dist/{chunk-AZV7KNJI.mjs → chunk-YKWIMVGU.mjs} +2 -2
  281. package/dist/{chunk-ZKDKKQCE.mjs → chunk-YOXSXHDE.mjs} +4 -4
  282. package/dist/{chunk-PGQ6FMXS.mjs → chunk-ZO5BRTCW.mjs} +2 -2
  283. package/dist/{chunk-KSSVIFYR.mjs → chunk-ZQGCQ7SA.mjs} +14 -34
  284. package/dist/{chunk-ZTPYUU5C.mjs → chunk-ZRUUUVOO.mjs} +3 -3
  285. package/dist/fonts.mjs +0 -2
  286. package/dist/{index-CY34hxPN.d.ts → index-CinAt5Uo.d.mts} +3 -3
  287. package/dist/{index-CY34hxPN.d.mts → index-CinAt5Uo.d.ts} +3 -3
  288. package/dist/index.d.mts +69 -19
  289. package/dist/index.d.ts +69 -19
  290. package/dist/index.js +1023 -839
  291. package/dist/index.mjs +76 -70
  292. package/package.json +15 -12
  293. package/src/components/Accordion/Accordion.tsx +12 -18
  294. package/src/components/AppHeader/AppHeader.tsx +33 -10
  295. package/src/components/Checkbox/Checkbox.tsx +3 -0
  296. package/src/components/ConfirmDialog/ConfirmDialog.tsx +7 -21
  297. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -2
  298. package/src/components/Image/Image.tsx +50 -0
  299. package/src/components/Image/index.ts +2 -0
  300. package/src/components/ImageUpload/ImageUpload.tsx +34 -26
  301. package/src/components/{ListGroup/ListGroup.tsx → ItemGroup/ItemGroup.tsx} +15 -29
  302. package/src/components/ItemGroup/index.ts +2 -0
  303. package/src/components/ListGroup/index.tsx +20 -0
  304. package/src/components/ListItem/ListItem.tsx +3 -0
  305. package/src/components/MenuGroup/index.tsx +20 -0
  306. package/src/components/MenuItem/MenuItem.tsx +3 -0
  307. package/src/components/NumberStepper/NumberStepper.tsx +4 -0
  308. package/src/components/Pressable/Pressable.tsx +0 -24
  309. package/src/components/ScreenContainer/ScreenContainer.tsx +94 -0
  310. package/src/components/ScreenContainer/index.ts +2 -0
  311. package/src/components/Select/Select.tsx +25 -30
  312. package/src/components/SelectableGrid/SelectableGrid.tsx +51 -20
  313. package/src/components/Separator/Separator.tsx +35 -2
  314. package/src/components/Sheet/Sheet.tsx +3 -21
  315. package/src/components/Sheet/index.ts +2 -2
  316. package/src/components/Slider/Slider.tsx +3 -0
  317. package/src/components/Switch/Switch.tsx +3 -1
  318. package/src/components/Tabs/Tabs.tsx +9 -9
  319. package/src/components/Tabs/index.ts +1 -1
  320. package/src/components/Text/Text.tsx +7 -0
  321. package/src/components/VirtualizedList/VirtualizedList.tsx +154 -0
  322. package/src/components/VirtualizedList/index.ts +2 -0
  323. package/src/hooks/useConfirmDialog.ts +2 -11
  324. package/src/hooks/useSheetModal.ts +40 -0
  325. package/src/index.ts +5 -1
  326. package/src/theme/colors.ts +19 -57
  327. package/src/tokens.ts +21 -7
  328. package/src/utils/curatedIcons.ts +9 -18
  329. package/src/utils/haptics.ts +10 -21
  330. package/src/utils/icons.ts +7 -14
  331. package/dist/ListGroup.d.mts +0 -34
  332. package/dist/ListGroup.d.ts +0 -34
  333. package/dist/ListGroup.mjs +0 -5
  334. package/dist/MenuGroup.d.mts +0 -34
  335. package/dist/MenuGroup.d.ts +0 -34
  336. package/dist/MenuGroup.js +0 -106
  337. package/dist/MenuGroup.mjs +0 -5
  338. package/dist/chunk-ARONDO7M.mjs +0 -40
  339. package/dist/chunk-EW2FIDSM.mjs +0 -29
  340. package/dist/chunk-S2VGME7X.mjs +0 -82
  341. package/dist/chunk-Y6FXYEAI.mjs +0 -8
  342. package/src/components/ListGroup/index.ts +0 -1
  343. package/src/components/MenuGroup/MenuGroup.tsx +0 -145
  344. package/src/components/MenuGroup/index.ts +0 -1
package/dist/index.mjs CHANGED
@@ -1,66 +1,80 @@
1
- export { Toggle } from './chunk-RRKM4MKB.mjs';
2
- export { Stats } from './chunk-ZKDKKQCE.mjs';
3
- export { Switch } from './chunk-BTUW5LSG.mjs';
4
- export { TabBar } from './chunk-U6DEBYU5.mjs';
5
- export { Tabs, TabsContent } from './chunk-KC5QDYGZ.mjs';
6
- export { Text } from './chunk-EHGBHFMH.mjs';
7
- export { Textarea } from './chunk-L3YKPTJQ.mjs';
8
- export { Select } from './chunk-URIH43IJ.mjs';
9
- export { SelectableCard, SelectableCardGroup } from './chunk-BULKGOIZ.mjs';
10
- export { SelectableGrid } from './chunk-MP7GLMIR.mjs';
11
- export { Separator } from './chunk-EW2FIDSM.mjs';
12
- export { BottomSheetModalProvider, Sheet, BottomSheetTextInput as SheetTextInput } from './chunk-2QOHHBJC.mjs';
13
- export { SheetSelect } from './chunk-WIPEDNSD.mjs';
14
- export { Skeleton } from './chunk-XCIG6HT2.mjs';
15
- export { Slider } from './chunk-UOKFSFNJ.mjs';
16
- export { MonthPicker, dateToMonthPickerValue, monthPickerValueToDate } from './chunk-ITG4JQM3.mjs';
17
- export { NumberStepper } from './chunk-TETMEKZE.mjs';
18
- export { Pressable } from './chunk-62BBSSUF.mjs';
19
- export { PricingCard } from './chunk-K3QX2M26.mjs';
20
- export { Progress } from './chunk-DBHSUUKU.mjs';
21
- export { RadioGroup } from './chunk-IJCMPVW5.mjs';
22
- export { RetrayProvider } from './chunk-ERWJPVX7.mjs';
23
- export { ToastProvider, sonnerToast as toast, useToast } from './chunk-SZEKQAOY.mjs';
24
- export { ImageViewer } from './chunk-PGQ6FMXS.mjs';
25
- export { PagerDots } from './chunk-S44XWTTC.mjs';
26
- export { LabelValue } from './chunk-DE25XTVQ.mjs';
27
- export { ListGroup, ListGroupFooter, ListGroupHeader } from './chunk-OBV72JD4.mjs';
28
- export { ListItem } from './chunk-6QLBHUEG.mjs';
29
- export { MediaCard } from './chunk-CM2DG4MR.mjs';
30
- export { MenuGroup, MenuGroupFooter, MenuGroupHeader } from './chunk-S2VGME7X.mjs';
31
- export { MenuItem } from './chunk-E4EQSCKR.mjs';
32
- export { DetailRow } from './chunk-KAGADD2O.mjs';
33
- export { EmptyState } from './chunk-FTTI6T5Q.mjs';
34
- export { ErrorBoundary } from './chunk-ESQDPO5E.mjs';
35
- export { Form, FormField, FormFooter, FormSection } from './chunk-KPTY7UYQ.mjs';
36
- export { IconPicker } from './chunk-NGEN2EES.mjs';
37
- export { ImageUpload } from './chunk-EROPDCB5.mjs';
38
- export { Spinner } from './chunk-2VIDP72N.mjs';
1
+ export { Toggle } from './chunk-HLWGFBIF.mjs';
2
+ export { VirtualizedList } from './chunk-WFNGSYS4.mjs';
3
+ export { Slider } from './chunk-4PF4LKNT.mjs';
4
+ export { Stats } from './chunk-YOXSXHDE.mjs';
5
+ export { Switch } from './chunk-5TNQ573V.mjs';
6
+ export { TabBar } from './chunk-IFGZUJFH.mjs';
7
+ export { Tabs, TabsContent } from './chunk-BMAAAJWN.mjs';
8
+ export { Text } from './chunk-CYGYC7XT.mjs';
9
+ export { Textarea } from './chunk-7CE6PDCQ.mjs';
10
+ export { ScreenContainer } from './chunk-WR6DCNAE.mjs';
11
+ export { Select } from './chunk-RLPPRIJ7.mjs';
12
+ export { SelectableCard, SelectableCardGroup } from './chunk-FE26TPCI.mjs';
13
+ export { SelectableGrid } from './chunk-T4KMKHTI.mjs';
14
+ export { Separator } from './chunk-BVJAYPAD.mjs';
15
+ export { BottomSheetModalProvider, Sheet, SheetContent, SheetFooter, SheetHeader, BottomSheetTextInput as SheetTextInput } from './chunk-UBTP4NPP.mjs';
16
+ export { SheetSelect } from './chunk-WD5LBXPR.mjs';
17
+ export { Skeleton } from './chunk-S433IOQE.mjs';
18
+ export { MonthPicker, dateToMonthPickerValue, monthPickerValueToDate } from './chunk-QEE3EQ3N.mjs';
19
+ export { NumberStepper } from './chunk-NQYS6RPX.mjs';
20
+ export { Pressable } from './chunk-P5KC3RTG.mjs';
21
+ export { PricingCard } from './chunk-PPKCGCZ3.mjs';
22
+ export { Progress } from './chunk-FOUSI6JD.mjs';
23
+ export { RadioGroup } from './chunk-BQMJQMWY.mjs';
24
+ export { RetrayProvider } from './chunk-XKBB2UZU.mjs';
25
+ export { ToastProvider, sonnerToast as toast, useToast } from './chunk-VSKBODEY.mjs';
26
+ export { ImageUpload } from './chunk-CCEM3HIJ.mjs';
27
+ export { ImageViewer } from './chunk-ZO5BRTCW.mjs';
28
+ export { PagerDots } from './chunk-E4BJ5WXG.mjs';
29
+ import { ItemGroup, ItemGroupHeader, ItemGroupFooter } from './chunk-2DDJ53DK.mjs';
30
+ export { ItemGroupFooter as ListGroupFooter, ItemGroupHeader as ListGroupHeader, ItemGroupFooter as MenuGroupFooter, ItemGroupHeader as MenuGroupHeader } from './chunk-2DDJ53DK.mjs';
31
+ export { LabelValue } from './chunk-3VHFOSZR.mjs';
32
+ export { ListItem } from './chunk-6T2DVIQT.mjs';
33
+ export { MediaCard } from './chunk-MSS3CD6F.mjs';
34
+ export { MenuItem } from './chunk-BTPCY4C7.mjs';
35
+ export { DetailRow } from './chunk-3RIZCKRM.mjs';
36
+ export { EmptyState } from './chunk-W422TEH2.mjs';
37
+ export { ErrorBoundary } from './chunk-DLAOTHHS.mjs';
38
+ export { Form, FormField, FormFooter, FormSection } from './chunk-GR7PKEKD.mjs';
39
+ export { IconPicker } from './chunk-MQAK2W6L.mjs';
40
+ export { Spinner } from './chunk-K3V6OTVB.mjs';
41
+ export { Image } from './chunk-VISIOH33.mjs';
39
42
  export { ButtonGroup } from './chunk-3BBOZ3OQ.mjs';
40
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-TMH263OK.mjs';
41
- export { CategoryStrip } from './chunk-5MYNAAFE.mjs';
42
- export { Checkbox } from './chunk-4ZO5PTKF.mjs';
43
- export { Chip, ChipGroup } from './chunk-RA6SAAFE.mjs';
44
- export { ConfirmDialog } from './chunk-V2ZB2XNS.mjs';
45
- export { CurrencyDisplay } from './chunk-PI6RULJX.mjs';
46
- export { CurrencyInput } from './chunk-HUSSF6TF.mjs';
47
- export { Input } from './chunk-4NQFTHN3.mjs';
48
- export { Accordion } from './chunk-CBIZLRYH.mjs';
49
- export { AlertBanner } from './chunk-K7TKID3V.mjs';
50
- export { AppHeader } from './chunk-6CR4S6W2.mjs';
51
- export { IconButton } from './chunk-ZTPYUU5C.mjs';
52
- export { Avatar, AvatarGroup } from './chunk-IGU223UM.mjs';
53
- export { Badge } from './chunk-AZV7KNJI.mjs';
54
- export { Button } from './chunk-Y6YS33GM.mjs';
43
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-UEA2VYGW.mjs';
44
+ export { CategoryStrip } from './chunk-5J7VKFSZ.mjs';
45
+ export { Checkbox } from './chunk-AZRATPNP.mjs';
46
+ export { Chip, ChipGroup } from './chunk-BWLVX2SQ.mjs';
47
+ export { ConfirmDialog } from './chunk-BGXOEFDM.mjs';
48
+ export { useSheetModal } from './chunk-HMKJGVXA.mjs';
49
+ export { CurrencyDisplay } from './chunk-EQYTDFDD.mjs';
50
+ export { CurrencyInput } from './chunk-EQNCMDZC.mjs';
51
+ export { Input } from './chunk-3GE4UFV5.mjs';
52
+ export { Accordion } from './chunk-Y5TPAKOS.mjs';
53
+ export { AlertBanner } from './chunk-K4YFTUMC.mjs';
54
+ export { AppHeader } from './chunk-2J5OZOMX.mjs';
55
+ export { IconButton } from './chunk-ZRUUUVOO.mjs';
56
+ export { Avatar, AvatarGroup } from './chunk-SWUZKVYO.mjs';
57
+ export { Badge } from './chunk-YKWIMVGU.mjs';
58
+ export { Button } from './chunk-AHFEAY6M.mjs';
55
59
  import './chunk-M53LC4Q7.mjs';
56
60
  import './chunk-IFYMBOEN.mjs';
57
- export { impactHeavy, impactLight, impactMedium, notificationError, notificationSuccess, notificationWarning, selectionAsync } from './chunk-ARONDO7M.mjs';
58
- export { BREAKPOINTS, ICON_SIZES, RADIUS, SHADOWS, SPACING, TYPOGRAPHY } from './chunk-QY3X2UYR.mjs';
59
- export { Icon } from './chunk-MZ6WRTD2.mjs';
60
- export { ThemeProvider, defaultDark, defaultLight, deriveColors, hexToRgb, useTheme, withAlpha } from './chunk-KSSVIFYR.mjs';
61
+ export { impactHeavy, impactLight, impactMedium, notificationError, notificationSuccess, notificationWarning, selectionAsync } from './chunk-CTUFFKGS.mjs';
62
+ export { BREAKPOINTS, ICON_SIZES, RADIUS, SHADOWS, SPACING, TYPOGRAPHY } from './chunk-DYYPDQA2.mjs';
63
+ export { Icon } from './chunk-24JTXQ2M.mjs';
64
+ export { ThemeProvider, defaultDark, defaultLight, deriveColors, hexToRgb, useTheme, withAlpha } from './chunk-ZQGCQ7SA.mjs';
61
65
  import './chunk-2CE3TQVY.mjs';
62
- import './chunk-Y6FXYEAI.mjs';
63
- import { useState, useRef, useEffect, useCallback } from 'react';
66
+ import React, { useState, useRef, useEffect, useCallback } from 'react';
67
+
68
+ function ListGroup(props) {
69
+ return /* @__PURE__ */ React.createElement(ItemGroup, { childPropKey: "title", ...props });
70
+ }
71
+ ListGroup.Header = ItemGroupHeader;
72
+ ListGroup.Footer = ItemGroupFooter;
73
+ function MenuGroup(props) {
74
+ return /* @__PURE__ */ React.createElement(ItemGroup, { childPropKey: "onPress", ...props });
75
+ }
76
+ MenuGroup.Header = ItemGroupHeader;
77
+ MenuGroup.Footer = ItemGroupFooter;
64
78
 
65
79
  // src/utils/typography.ts
66
80
  function getResponsiveFontSize(text, maxSize, steps = [
@@ -78,18 +92,12 @@ function getResponsiveFontSize(text, maxSize, steps = [
78
92
  function useConfirmDialog(options) {
79
93
  const [visible, setVisible] = useState(false);
80
94
  const [loading, setLoading] = useState(false);
81
- const mountedRef = useRef(true);
82
95
  const onConfirmRef = useRef(options.onConfirm);
83
96
  const onCancelRef = useRef(options.onCancel);
84
97
  useEffect(() => {
85
98
  onConfirmRef.current = options.onConfirm;
86
99
  onCancelRef.current = options.onCancel;
87
100
  });
88
- useEffect(() => {
89
- return () => {
90
- mountedRef.current = false;
91
- };
92
- }, []);
93
101
  const open = useCallback(() => setVisible(true), []);
94
102
  const handleConfirm = useCallback(async () => {
95
103
  setLoading(true);
@@ -97,10 +105,8 @@ function useConfirmDialog(options) {
97
105
  await onConfirmRef.current();
98
106
  } catch {
99
107
  } finally {
100
- if (mountedRef.current) {
101
- setLoading(false);
102
- setVisible(false);
103
- }
108
+ setLoading(false);
109
+ setVisible(false);
104
110
  }
105
111
  }, []);
106
112
  const handleCancel = useCallback(() => {
@@ -110,4 +116,4 @@ function useConfirmDialog(options) {
110
116
  return { visible, loading, open, onConfirm: handleConfirm, onCancel: handleCancel };
111
117
  }
112
118
 
113
- export { getResponsiveFontSize, useConfirmDialog };
119
+ export { ListGroup, MenuGroup, getResponsiveFontSize, useConfirmDialog };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retray-dev/ui-kit",
3
- "version": "13.0.0",
3
+ "version": "13.4.0",
4
4
  "description": "Personal UI Kit for React Native / Expo",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -26,11 +26,12 @@
26
26
  "dist",
27
27
  "src",
28
28
  "scripts",
29
- "COMPONENTS.md",
30
29
  "CONSUMER.md",
31
30
  "EXAMPLES.md",
32
31
  "FONTS.md",
33
- "DESIGN.md"
32
+ "DESIGN.md",
33
+ "SKILL.md",
34
+ "CHANGELOG.md"
34
35
  ],
35
36
  "scripts": {
36
37
  "postinstall": "node scripts/copy-fonts.js",
@@ -66,8 +67,9 @@
66
67
  "expo-font": ">=14.0.0",
67
68
  "expo-haptics": ">=14.0.0",
68
69
  "expo-image": ">=3.0.0",
69
- "expo-image-picker": ">=15.0.0",
70
+ "react-native-image-picker": ">=7.0.0",
70
71
  "expo-linear-gradient": ">=13.0.0",
72
+ "expo-modules-core": ">=3.0.0",
71
73
  "expo-sensors": ">=13.0.0",
72
74
  "pressto": ">=0.6.0",
73
75
  "react": ">=17",
@@ -89,14 +91,15 @@
89
91
  "expo-sensors": {
90
92
  "optional": true
91
93
  },
92
- "expo-image-picker": {
93
- "optional": true
94
- },
94
+
95
95
  "react-native-ease": {
96
96
  "optional": false
97
97
  },
98
98
  "pressto": {
99
99
  "optional": false
100
+ },
101
+ "react-native-image-picker": {
102
+ "optional": true
100
103
  }
101
104
  },
102
105
  "pnpm": {
@@ -133,21 +136,21 @@
133
136
  "expo-haptics": "~15.0.8",
134
137
  "expo-image": "~3.0.11",
135
138
  "expo-linear-gradient": "~15.0.8",
136
- "expo-sensors": "~15.0.7",
139
+ "expo-sensors": "~15.0.8",
137
140
  "jest-expo": "~54.0.17",
138
- "pressto": "^0.6.1",
141
+ "pressto": "^0.7.0",
139
142
  "prettier": "^3.8.3",
140
143
  "react": "19.1.0",
141
144
  "react-native": "0.81.5",
142
- "react-native-ease": "^0.7.2",
145
+ "react-native-ease": "^0.7.3",
143
146
  "react-native-gesture-handler": "~2.28.0",
144
147
  "react-native-reanimated": "~4.1.1",
145
148
  "react-native-safe-area-context": "5.6.2",
146
149
  "react-native-screens": "4.16.0",
147
150
  "react-native-size-matters": "^0.4.2",
148
- "react-native-svg": "15.12.1",
151
+ "react-native-svg": "15.15.5",
149
152
  "react-native-worklets": "~0.5.1",
150
- "sonner-native": "0.23.1",
153
+ "sonner-native": "0.26.3",
151
154
  "test-renderer": "^1.2.0",
152
155
  "tsup": "^8.0.0",
153
156
  "typescript": "^5.4.0",
@@ -8,7 +8,6 @@ import {
8
8
  import Animated, {
9
9
  Easing,
10
10
  useSharedValue,
11
- useDerivedValue,
12
11
  useAnimatedStyle,
13
12
  withTiming,
14
13
  } from 'react-native-reanimated'
@@ -30,12 +29,14 @@ export interface AccordionItem {
30
29
  icon?: React.ReactNode
31
30
  /** Override icon color. Defaults to foregroundMuted. */
32
31
  iconColor?: string
32
+ /**
33
33
  /**
34
34
  * Action buttons rendered after the trigger content but before the chevron.
35
35
  * Automatically touch-isolated — taps on actions won't toggle the accordion.
36
36
  * Use this instead of embedding interactive elements inside `trigger`.
37
37
  */
38
38
  triggerActions?: React.ReactNode
39
+ accessibilityHint?: string
39
40
  }
40
41
 
41
42
  export interface AccordionProps {
@@ -74,29 +75,21 @@ function AccordionItemComponent({
74
75
  isExpanded.value = isOpen
75
76
  }, [isOpen, isExpanded])
76
77
 
77
- // Derived animated height — height * Number(isExpanded) gives 0 when closed and
78
- // the measured height when open. `withTiming` wraps it so every change animates.
79
- const derivedHeight = useDerivedValue(() =>
80
- withTiming(height.value * Number(isExpanded.value), {
81
- duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
82
- easing: isExpanded.value ? Easing.bezier(0.23, 1, 0.32, 1) : Easing.in(Easing.ease),
83
- })
84
- )
85
-
86
- const derivedRotation = useDerivedValue(() =>
87
- withTiming(isExpanded.value ? 1 : 0, {
78
+ const bodyStyle = useAnimatedStyle(() => ({
79
+ height: withTiming(height.value * Number(isExpanded.value), {
88
80
  duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
89
81
  easing: isExpanded.value ? Easing.bezier(0.23, 1, 0.32, 1) : Easing.in(Easing.ease),
90
- })
91
- )
92
-
93
- const bodyStyle = useAnimatedStyle(() => ({
94
- height: derivedHeight.value,
82
+ }),
95
83
  overflow: 'hidden',
96
84
  }))
97
85
 
98
86
  const rotationStyle = useAnimatedStyle(() => ({
99
- transform: [{ rotate: `${derivedRotation.value * 180}deg` }],
87
+ transform: [{
88
+ rotate: `${withTiming(isExpanded.value ? 1 : 0, {
89
+ duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
90
+ easing: isExpanded.value ? Easing.bezier(0.23, 1, 0.32, 1) : Easing.in(Easing.ease),
91
+ }) * 180}deg`,
92
+ }],
100
93
  }))
101
94
 
102
95
  return (
@@ -111,6 +104,7 @@ function AccordionItemComponent({
111
104
  accessibilityRole="button"
112
105
  accessibilityState={{ expanded: isOpen }}
113
106
  accessibilityLabel={typeof item.trigger === 'string' ? item.trigger : undefined}
107
+ accessibilityHint={item.accessibilityHint}
114
108
  style={styles.trigger}
115
109
  >
116
110
  <View style={styles.triggerContent}>
@@ -3,6 +3,7 @@ import { View, Text, StyleSheet, ViewStyle, useWindowDimensions } from 'react-na
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
4
4
  import { useTheme } from '../../theme'
5
5
  import { IconButton } from '../IconButton'
6
+ import { Icon } from '../../utils/icons'
6
7
  import { s, vs, ms, mvs } from '../../utils/scaling'
7
8
  import { BREAKPOINTS } from '../../tokens'
8
9
 
@@ -15,7 +16,9 @@ export interface AppHeaderProps {
15
16
  onBack?: () => void
16
17
  /** Icon name for the back button. Defaults to `'chevron-left'`. */
17
18
  backIconName?: string
18
- /** Custom left content overrides the back button. */
19
+ /** Icon name for a decorative icon shown left of the title, after the back button. Ignored when `left` is provided. */
20
+ iconName?: string
21
+ /** Custom left content — overrides the back button and `iconName`. */
19
22
  left?: React.ReactNode
20
23
  /** Custom right content (actions). */
21
24
  right?: React.ReactNode
@@ -40,12 +43,14 @@ export interface AppHeaderProps {
40
43
  *
41
44
  * @example
42
45
  * <AppHeader title="Settings" onBack={navigation.goBack} right={<IconButton iconName="more-horizontal" variant="text" />} />
46
+ * <AppHeader title="Perfil" iconName="user" onBack={navigation.goBack} />
43
47
  */
44
48
  export function AppHeader({
45
49
  title,
46
50
  subtitle,
47
51
  onBack,
48
52
  backIconName = 'chevron-left',
53
+ iconName,
49
54
  left,
50
55
  right,
51
56
  titleAlign = 'auto',
@@ -61,15 +66,24 @@ export function AppHeader({
61
66
  const isWide = width >= BREAKPOINTS.wide
62
67
  const centered = titleAlign === 'center' || (titleAlign === 'auto' && isWide)
63
68
 
64
- const leftNode = left ?? (onBack ? (
65
- <IconButton
66
- iconName={backIconName}
67
- variant="text"
68
- size="md"
69
- onPress={onBack}
70
- accessibilityLabel="Atrás"
71
- />
72
- ) : null)
69
+ const leftNode = left ?? (
70
+ <>
71
+ {onBack ? (
72
+ <IconButton
73
+ iconName={backIconName}
74
+ variant="text"
75
+ size="md"
76
+ onPress={onBack}
77
+ accessibilityLabel="Atrás"
78
+ />
79
+ ) : null}
80
+ {iconName && !left ? (
81
+ <View style={styles.iconSlot}>
82
+ <Icon name={iconName} size={20} color={colors.foreground} />
83
+ </View>
84
+ ) : null}
85
+ </>
86
+ )
73
87
 
74
88
  const titleBlock = (
75
89
  <View style={[styles.titleBlock, centered && styles.titleBlockCentered]} pointerEvents="none">
@@ -143,9 +157,12 @@ const styles = StyleSheet.create({
143
157
  flexDirection: 'row',
144
158
  alignItems: 'center',
145
159
  justifyContent: 'flex-start',
160
+ paddingLeft: s(8),
161
+ gap: s(4),
146
162
  },
147
163
  sideRight: {
148
164
  justifyContent: 'flex-end',
165
+ paddingRight: s(8),
149
166
  },
150
167
  titleBlock: {
151
168
  flex: 1,
@@ -166,6 +183,12 @@ const styles = StyleSheet.create({
166
183
  fontSize: ms(13),
167
184
  lineHeight: mvs(16),
168
185
  },
186
+ iconSlot: {
187
+ width: s(44),
188
+ height: s(44),
189
+ alignItems: 'center',
190
+ justifyContent: 'center',
191
+ },
169
192
  textCentered: {
170
193
  textAlign: 'center',
171
194
  },
@@ -14,6 +14,7 @@ export interface CheckboxProps {
14
14
  disabled?: boolean
15
15
  style?: ViewStyle
16
16
  accessibilityLabel?: string
17
+ accessibilityHint?: string
17
18
  }
18
19
 
19
20
  export function Checkbox({
@@ -23,6 +24,7 @@ export function Checkbox({
23
24
  disabled,
24
25
  style,
25
26
  accessibilityLabel,
27
+ accessibilityHint,
26
28
  }: CheckboxProps) {
27
29
  const { colors } = useTheme()
28
30
 
@@ -43,6 +45,7 @@ export function Checkbox({
43
45
  touchSoundDisabled
44
46
  accessibilityRole="checkbox"
45
47
  accessibilityLabel={accessibilityLabel ?? label}
48
+ accessibilityHint={accessibilityHint}
46
49
  accessibilityState={{ checked, disabled: !!disabled }}
47
50
  >
48
51
  <EaseView
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useRef, useId } from 'react'
1
+ import React, { useCallback, useId } from 'react'
2
2
  import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
3
3
  import {
4
4
  BottomSheetModal,
@@ -8,8 +8,9 @@ import {
8
8
  } from '@gorhom/bottom-sheet'
9
9
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
10
10
  import { Feather } from '@expo/vector-icons'
11
- import { impactMedium, notificationSuccess, selectionAsync as hapticSelection } from '../../utils/haptics'
11
+ import { notificationSuccess, selectionAsync as hapticSelection } from '../../utils/haptics'
12
12
  import { useTheme } from '../../theme'
13
+ import { useSheetModal } from '../../hooks/useSheetModal'
13
14
  import { Button } from '../Button'
14
15
  import { s, vs, ms, mvs } from '../../utils/scaling'
15
16
 
@@ -24,6 +25,7 @@ export interface ConfirmDialogProps {
24
25
  showCloseButton?: boolean
25
26
  onConfirm: () => void
26
27
  onCancel: () => void
28
+ accessibilityHint?: string
27
29
  }
28
30
 
29
31
  export function ConfirmDialog({
@@ -37,30 +39,13 @@ export function ConfirmDialog({
37
39
  showCloseButton = false,
38
40
  onConfirm,
39
41
  onCancel,
42
+ accessibilityHint,
40
43
  }: ConfirmDialogProps) {
41
44
  const { colors } = useTheme()
42
45
  const insets = useSafeAreaInsets()
43
- const ref = useRef<BottomSheetModal>(null)
44
- const wasOpened = useRef(false)
45
- const isPresentedRef = useRef(false)
46
+ const { ref, handleDismiss } = useSheetModal(visible, onCancel)
46
47
  const name = useId()
47
48
 
48
- const handleDismiss = useCallback(() => {
49
- isPresentedRef.current = false
50
- onCancel()
51
- }, [onCancel])
52
-
53
- useEffect(() => {
54
- if (visible && !isPresentedRef.current) {
55
- impactMedium()
56
- ref.current?.present()
57
- wasOpened.current = true
58
- isPresentedRef.current = true
59
- } else if (!visible && wasOpened.current && isPresentedRef.current) {
60
- ref.current?.dismiss()
61
- }
62
- }, [visible])
63
-
64
49
  const renderBackdrop = useCallback(
65
50
  (props: BottomSheetBackdropProps) => (
66
51
  <BottomSheetBackdrop
@@ -122,6 +107,7 @@ export function ConfirmDialog({
122
107
  notificationSuccess()
123
108
  onConfirm()
124
109
  }}
110
+ accessibilityHint={accessibilityHint}
125
111
  icon={
126
112
  <Feather
127
113
  name={confirmVariant === 'destructive' ? 'trash-2' : 'check'}
@@ -8,6 +8,8 @@ import { impactLight } from '../../utils/haptics'
8
8
 
9
9
  export interface ErrorFallbackProps {
10
10
  error: Error
11
+ /** Stack trace from the error boundary. */
12
+ componentStack: string
11
13
  /** Reset the boundary and attempt to re-render children. */
12
14
  reset: () => void
13
15
  }
@@ -97,13 +99,14 @@ export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoun
97
99
  const { error } = this.state
98
100
  if (error) {
99
101
  const { fallback, title, message } = this.props
102
+ const componentStack = error.stack ?? ''
100
103
  if (typeof fallback === 'function') {
101
- return fallback({ error, reset: this.reset })
104
+ return fallback({ error, componentStack, reset: this.reset })
102
105
  }
103
106
  if (fallback !== undefined) {
104
107
  return fallback
105
108
  }
106
- return <DefaultErrorFallback error={error} reset={this.reset} title={title} message={message} />
109
+ return <DefaultErrorFallback error={error} componentStack={componentStack} reset={this.reset} title={title} message={message} />
107
110
  }
108
111
  return this.props.children
109
112
  }
@@ -0,0 +1,50 @@
1
+ import React, { useState } from 'react'
2
+ import { View, type ImageStyle } from 'react-native'
3
+ import { Image as ExpoImage, type ImageProps as ExpoImageProps } from 'expo-image'
4
+ import { useTheme } from '../../theme'
5
+
6
+ export interface ImageProps extends Omit<ExpoImageProps, 'source' | 'style'> {
7
+ /** Image source URI. */
8
+ src?: string | null
9
+ /** Custom fallback shown when image fails to load or src is null. */
10
+ fallback?: React.ReactNode
11
+ /** Aspect ratio width/height — e.g. 16/9, 4/3. Sets container height proportionally. */
12
+ aspectRatio?: number
13
+ /** Border radius override. Defaults to 0. */
14
+ borderRadius?: number
15
+ style?: ImageStyle
16
+ }
17
+
18
+ export function Image({ src, fallback, aspectRatio, borderRadius = 0, style, ...props }: ImageProps) {
19
+ const { colors } = useTheme()
20
+ const [failed, setFailed] = useState(false)
21
+
22
+ if (!src || failed) {
23
+ return fallback ? (
24
+ <View style={[style, { overflow: 'hidden' }]}>{fallback}</View>
25
+ ) : (
26
+ <View
27
+ style={[
28
+ { backgroundColor: colors.skeleton, overflow: 'hidden' },
29
+ borderRadius ? { borderRadius } : undefined,
30
+ aspectRatio ? { aspectRatio } : undefined,
31
+ style,
32
+ ]}
33
+ />
34
+ )
35
+ }
36
+
37
+ const imageStyle: ImageStyle = {
38
+ ...(aspectRatio ? { aspectRatio, width: '100%' as const } : {}),
39
+ ...(borderRadius ? { borderRadius } : {}),
40
+ }
41
+
42
+ return (
43
+ <ExpoImage
44
+ source={{ uri: src }}
45
+ style={[imageStyle, style]}
46
+ onError={() => setFailed(true)}
47
+ {...props}
48
+ />
49
+ )
50
+ }
@@ -0,0 +1,2 @@
1
+ export { Image } from './Image'
2
+ export type { ImageProps } from './Image'