@retray-dev/ui-kit 13.2.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 (334) hide show
  1. package/CHANGELOG.md +680 -0
  2. package/CONSUMER.md +2 -0
  3. package/README.md +4 -4
  4. package/SKILL.md +276 -12
  5. package/dist/Accordion.d.mts +6 -6
  6. package/dist/Accordion.d.ts +6 -6
  7. package/dist/Accordion.js +39 -40
  8. package/dist/Accordion.mjs +4 -4
  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 -4
  13. package/dist/AppHeader.d.mts +4 -4
  14. package/dist/AppHeader.d.ts +4 -4
  15. package/dist/AppHeader.js +37 -28
  16. package/dist/AppHeader.mjs +6 -6
  17. package/dist/Avatar.d.mts +4 -4
  18. package/dist/Avatar.d.ts +4 -4
  19. package/dist/Avatar.mjs +2 -2
  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 -3
  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 -5
  28. package/dist/ButtonGroup.d.mts +3 -3
  29. package/dist/ButtonGroup.d.ts +3 -3
  30. package/dist/Card.d.mts +13 -13
  31. package/dist/Card.d.ts +13 -13
  32. package/dist/Card.js +23 -14
  33. package/dist/Card.mjs +4 -4
  34. package/dist/CategoryStrip.d.mts +3 -3
  35. package/dist/CategoryStrip.d.ts +3 -3
  36. package/dist/CategoryStrip.js +30 -27
  37. package/dist/CategoryStrip.mjs +5 -5
  38. package/dist/Checkbox.d.mts +2 -2
  39. package/dist/Checkbox.d.ts +2 -2
  40. package/dist/Checkbox.js +23 -14
  41. package/dist/Checkbox.mjs +3 -3
  42. package/dist/Chip.d.mts +5 -5
  43. package/dist/Chip.d.ts +5 -5
  44. package/dist/Chip.js +30 -27
  45. package/dist/Chip.mjs +5 -5
  46. package/dist/ConfirmDialog.d.mts +2 -2
  47. package/dist/ConfirmDialog.d.ts +2 -2
  48. package/dist/ConfirmDialog.js +64 -58
  49. package/dist/ConfirmDialog.mjs +7 -6
  50. package/dist/CurrencyDisplay.d.mts +3 -3
  51. package/dist/CurrencyDisplay.d.ts +3 -3
  52. package/dist/CurrencyDisplay.mjs +2 -2
  53. package/dist/CurrencyInput.d.mts +2 -2
  54. package/dist/CurrencyInput.d.ts +2 -2
  55. package/dist/CurrencyInput.js +7 -13
  56. package/dist/CurrencyInput.mjs +4 -4
  57. package/dist/DetailRow.d.mts +6 -6
  58. package/dist/DetailRow.d.ts +6 -6
  59. package/dist/DetailRow.js +7 -13
  60. package/dist/DetailRow.mjs +3 -3
  61. package/dist/EmptyState.d.mts +4 -4
  62. package/dist/EmptyState.d.ts +4 -4
  63. package/dist/EmptyState.js +31 -29
  64. package/dist/EmptyState.mjs +6 -6
  65. package/dist/ErrorBoundary.d.mts +9 -7
  66. package/dist/ErrorBoundary.d.ts +9 -7
  67. package/dist/ErrorBoundary.js +33 -29
  68. package/dist/ErrorBoundary.mjs +5 -5
  69. package/dist/Form.d.mts +9 -9
  70. package/dist/Form.d.ts +9 -9
  71. package/dist/Form.mjs +2 -2
  72. package/dist/HolographicCard.d.mts +2 -2
  73. package/dist/HolographicCard.d.ts +2 -2
  74. package/dist/HolographicCard.js +23 -14
  75. package/dist/HolographicCard.mjs +2 -2
  76. package/dist/IconButton.d.mts +4 -4
  77. package/dist/IconButton.d.ts +4 -4
  78. package/dist/IconButton.js +30 -27
  79. package/dist/IconButton.mjs +4 -4
  80. package/dist/IconPicker.d.mts +2 -2
  81. package/dist/IconPicker.d.ts +2 -2
  82. package/dist/IconPicker.js +40 -45
  83. package/dist/IconPicker.mjs +6 -6
  84. package/dist/Image.d.mts +18 -0
  85. package/dist/Image.d.ts +18 -0
  86. package/dist/Image.js +53 -0
  87. package/dist/Image.mjs +2 -0
  88. package/dist/ImageUpload.d.mts +2 -2
  89. package/dist/ImageUpload.d.ts +2 -2
  90. package/dist/ImageUpload.js +24 -15
  91. package/dist/ImageUpload.mjs +5 -5
  92. package/dist/ImageViewer.d.mts +2 -2
  93. package/dist/ImageViewer.d.ts +2 -2
  94. package/dist/ImageViewer.js +31 -28
  95. package/dist/ImageViewer.mjs +6 -6
  96. package/dist/Input.d.mts +4 -4
  97. package/dist/Input.d.ts +4 -4
  98. package/dist/Input.js +7 -13
  99. package/dist/Input.mjs +3 -3
  100. package/dist/ItemGroup.d.mts +23 -0
  101. package/dist/ItemGroup.d.ts +23 -0
  102. package/dist/{ListGroup.js → ItemGroup.js} +11 -13
  103. package/dist/ItemGroup.mjs +4 -0
  104. package/dist/LabelValue.d.mts +4 -4
  105. package/dist/LabelValue.d.ts +4 -4
  106. package/dist/LabelValue.js +7 -13
  107. package/dist/LabelValue.mjs +3 -3
  108. package/dist/ListItem.d.mts +6 -6
  109. package/dist/ListItem.d.ts +6 -6
  110. package/dist/ListItem.js +30 -27
  111. package/dist/ListItem.mjs +5 -5
  112. package/dist/MediaCard.d.mts +6 -6
  113. package/dist/MediaCard.d.ts +6 -6
  114. package/dist/MediaCard.js +30 -27
  115. package/dist/MediaCard.mjs +5 -5
  116. package/dist/MenuItem.d.mts +5 -5
  117. package/dist/MenuItem.d.ts +5 -5
  118. package/dist/MenuItem.js +30 -27
  119. package/dist/MenuItem.mjs +5 -5
  120. package/dist/MonthPicker.d.mts +2 -2
  121. package/dist/MonthPicker.d.ts +2 -2
  122. package/dist/MonthPicker.js +23 -14
  123. package/dist/MonthPicker.mjs +3 -3
  124. package/dist/NumberStepper.d.mts +3 -3
  125. package/dist/NumberStepper.d.ts +3 -3
  126. package/dist/NumberStepper.js +30 -27
  127. package/dist/NumberStepper.mjs +5 -5
  128. package/dist/PagerDots.d.mts +2 -2
  129. package/dist/PagerDots.d.ts +2 -2
  130. package/dist/PagerDots.js +30 -27
  131. package/dist/PagerDots.mjs +4 -4
  132. package/dist/Pressable.d.mts +3 -27
  133. package/dist/Pressable.d.ts +3 -27
  134. package/dist/Pressable.js +23 -14
  135. package/dist/Pressable.mjs +2 -2
  136. package/dist/PricingCard.d.mts +2 -2
  137. package/dist/PricingCard.d.ts +2 -2
  138. package/dist/PricingCard.js +31 -29
  139. package/dist/PricingCard.mjs +7 -7
  140. package/dist/Progress.d.mts +2 -2
  141. package/dist/Progress.d.ts +2 -2
  142. package/dist/Progress.mjs +2 -2
  143. package/dist/RadioGroup.d.mts +2 -2
  144. package/dist/RadioGroup.d.ts +2 -2
  145. package/dist/RadioGroup.js +23 -14
  146. package/dist/RadioGroup.mjs +3 -3
  147. package/dist/RetrayProvider.d.mts +1 -1
  148. package/dist/RetrayProvider.d.ts +1 -1
  149. package/dist/RetrayProvider.js +14 -34
  150. package/dist/RetrayProvider.mjs +3 -3
  151. package/dist/ScreenContainer.d.mts +24 -0
  152. package/dist/ScreenContainer.d.ts +24 -0
  153. package/dist/ScreenContainer.js +85 -0
  154. package/dist/ScreenContainer.mjs +3 -0
  155. package/dist/Select.d.mts +2 -2
  156. package/dist/Select.d.ts +2 -2
  157. package/dist/Select.js +38 -45
  158. package/dist/Select.mjs +3 -3
  159. package/dist/SelectableCard.d.mts +5 -5
  160. package/dist/SelectableCard.d.ts +5 -5
  161. package/dist/SelectableCard.js +30 -27
  162. package/dist/SelectableCard.mjs +5 -5
  163. package/dist/SelectableGrid.d.mts +5 -4
  164. package/dist/SelectableGrid.d.ts +5 -4
  165. package/dist/SelectableGrid.js +80 -44
  166. package/dist/SelectableGrid.mjs +5 -5
  167. package/dist/Separator.d.mts +4 -2
  168. package/dist/Separator.d.ts +4 -2
  169. package/dist/Separator.js +29 -1
  170. package/dist/Separator.mjs +3 -2
  171. package/dist/Sheet.d.mts +10 -10
  172. package/dist/Sheet.d.ts +10 -10
  173. package/dist/Sheet.js +59 -44
  174. package/dist/Sheet.mjs +4 -3
  175. package/dist/SheetSelect.d.mts +2 -2
  176. package/dist/SheetSelect.d.ts +2 -2
  177. package/dist/SheetSelect.js +30 -27
  178. package/dist/SheetSelect.mjs +5 -5
  179. package/dist/Skeleton.d.mts +5 -5
  180. package/dist/Skeleton.d.ts +5 -5
  181. package/dist/Skeleton.mjs +3 -3
  182. package/dist/Slider.d.mts +2 -2
  183. package/dist/Slider.d.ts +2 -2
  184. package/dist/Slider.js +23 -14
  185. package/dist/Slider.mjs +3 -3
  186. package/dist/Spinner.d.mts +2 -2
  187. package/dist/Spinner.d.ts +2 -2
  188. package/dist/Spinner.mjs +2 -2
  189. package/dist/Stats.d.mts +6 -6
  190. package/dist/Stats.d.ts +6 -6
  191. package/dist/Stats.js +30 -27
  192. package/dist/Stats.mjs +5 -5
  193. package/dist/Switch.d.mts +2 -2
  194. package/dist/Switch.d.ts +2 -2
  195. package/dist/Switch.js +23 -14
  196. package/dist/Switch.mjs +3 -3
  197. package/dist/TabBar.d.mts +3 -3
  198. package/dist/TabBar.d.ts +3 -3
  199. package/dist/TabBar.js +30 -27
  200. package/dist/TabBar.mjs +4 -4
  201. package/dist/Tabs.d.mts +13 -13
  202. package/dist/Tabs.d.ts +13 -13
  203. package/dist/Tabs.js +23 -14
  204. package/dist/Tabs.mjs +3 -3
  205. package/dist/Text.d.mts +4 -4
  206. package/dist/Text.d.ts +4 -4
  207. package/dist/Text.js +20 -2
  208. package/dist/Text.mjs +3 -3
  209. package/dist/Textarea.d.mts +3 -3
  210. package/dist/Textarea.d.ts +3 -3
  211. package/dist/Textarea.js +7 -13
  212. package/dist/Textarea.mjs +3 -3
  213. package/dist/Toast.d.mts +4 -4
  214. package/dist/Toast.d.ts +4 -4
  215. package/dist/Toast.mjs +2 -2
  216. package/dist/Toggle.d.mts +4 -4
  217. package/dist/Toggle.d.ts +4 -4
  218. package/dist/Toggle.js +30 -27
  219. package/dist/Toggle.mjs +4 -4
  220. package/dist/VirtualizedList.d.mts +28 -0
  221. package/dist/VirtualizedList.d.ts +28 -0
  222. package/dist/VirtualizedList.js +130 -0
  223. package/dist/VirtualizedList.mjs +3 -0
  224. package/dist/{chunk-MZ6WRTD2.mjs → chunk-24JTXQ2M.mjs} +7 -13
  225. package/dist/{chunk-OBV72JD4.mjs → chunk-2DDJ53DK.mjs} +9 -11
  226. package/dist/{chunk-H6MQL7PS.mjs → chunk-2J5OZOMX.mjs} +12 -6
  227. package/dist/{chunk-4NQFTHN3.mjs → chunk-3GE4UFV5.mjs} +2 -2
  228. package/dist/{chunk-KAGADD2O.mjs → chunk-3RIZCKRM.mjs} +2 -2
  229. package/dist/{chunk-DE25XTVQ.mjs → chunk-3VHFOSZR.mjs} +2 -2
  230. package/dist/{chunk-C5ZRMR2E.mjs → chunk-4PF4LKNT.mjs} +2 -2
  231. package/dist/{chunk-5MYNAAFE.mjs → chunk-5J7VKFSZ.mjs} +4 -4
  232. package/dist/{chunk-E2PONRJG.mjs → chunk-5TNQ573V.mjs} +2 -2
  233. package/dist/{chunk-CZN6L2QU.mjs → chunk-6T2DVIQT.mjs} +4 -4
  234. package/dist/{chunk-L3YKPTJQ.mjs → chunk-7CE6PDCQ.mjs} +2 -2
  235. package/dist/{chunk-Y6YS33GM.mjs → chunk-AHFEAY6M.mjs} +4 -4
  236. package/dist/{chunk-77UOVFIS.mjs → chunk-AZRATPNP.mjs} +2 -2
  237. package/dist/{chunk-UMZTPUB3.mjs → chunk-BGXOEFDM.mjs} +6 -31
  238. package/dist/{chunk-KC5QDYGZ.mjs → chunk-BMAAAJWN.mjs} +2 -2
  239. package/dist/{chunk-IJCMPVW5.mjs → chunk-BQMJQMWY.mjs} +2 -2
  240. package/dist/{chunk-COA2YZOX.mjs → chunk-BTPCY4C7.mjs} +4 -4
  241. package/dist/chunk-BVJAYPAD.mjs +55 -0
  242. package/dist/{chunk-RA6SAAFE.mjs → chunk-BWLVX2SQ.mjs} +4 -4
  243. package/dist/{chunk-HHOOFDBA.mjs → chunk-CCEM3HIJ.mjs} +5 -5
  244. package/dist/chunk-CTUFFKGS.mjs +30 -0
  245. package/dist/{chunk-EHGBHFMH.mjs → chunk-CYGYC7XT.mjs} +8 -4
  246. package/dist/{chunk-ESQDPO5E.mjs → chunk-DLAOTHHS.mjs} +7 -6
  247. package/dist/{chunk-QY3X2UYR.mjs → chunk-DYYPDQA2.mjs} +21 -7
  248. package/dist/{chunk-S44XWTTC.mjs → chunk-E4BJ5WXG.mjs} +3 -3
  249. package/dist/{chunk-HUSSF6TF.mjs → chunk-EQNCMDZC.mjs} +1 -1
  250. package/dist/{chunk-PI6RULJX.mjs → chunk-EQYTDFDD.mjs} +1 -1
  251. package/dist/{chunk-BULKGOIZ.mjs → chunk-FE26TPCI.mjs} +4 -4
  252. package/dist/{chunk-DBHSUUKU.mjs → chunk-FOUSI6JD.mjs} +1 -1
  253. package/dist/{chunk-KPTY7UYQ.mjs → chunk-GR7PKEKD.mjs} +1 -1
  254. package/dist/{chunk-RRKM4MKB.mjs → chunk-HLWGFBIF.mjs} +3 -3
  255. package/dist/chunk-HMKJGVXA.mjs +35 -0
  256. package/dist/{chunk-U6DEBYU5.mjs → chunk-IFGZUJFH.mjs} +3 -3
  257. package/dist/{chunk-2VIDP72N.mjs → chunk-K3V6OTVB.mjs} +1 -1
  258. package/dist/{chunk-K7TKID3V.mjs → chunk-K4YFTUMC.mjs} +3 -3
  259. package/dist/{chunk-NGEN2EES.mjs → chunk-MQAK2W6L.mjs} +14 -22
  260. package/dist/{chunk-CM2DG4MR.mjs → chunk-MSS3CD6F.mjs} +4 -4
  261. package/dist/{chunk-2QXJDRVU.mjs → chunk-NQYS6RPX.mjs} +4 -4
  262. package/dist/{chunk-62BBSSUF.mjs → chunk-P5KC3RTG.mjs} +1 -1
  263. package/dist/{chunk-K3QX2M26.mjs → chunk-PPKCGCZ3.mjs} +5 -5
  264. package/dist/{chunk-ITG4JQM3.mjs → chunk-QEE3EQ3N.mjs} +2 -2
  265. package/dist/{chunk-IDVUZIVY.mjs → chunk-RLPPRIJ7.mjs} +17 -33
  266. package/dist/{chunk-XCIG6HT2.mjs → chunk-S433IOQE.mjs} +2 -2
  267. package/dist/{chunk-IGU223UM.mjs → chunk-SWUZKVYO.mjs} +1 -1
  268. package/dist/{chunk-NPCBNGNE.mjs → chunk-T4KMKHTI.mjs} +55 -22
  269. package/dist/{chunk-7BZJRB77.mjs → chunk-UBTP4NPP.mjs} +4 -30
  270. package/dist/{chunk-TMH263OK.mjs → chunk-UEA2VYGW.mjs} +3 -3
  271. package/dist/chunk-VISIOH33.mjs +37 -0
  272. package/dist/{chunk-SZEKQAOY.mjs → chunk-VSKBODEY.mjs} +1 -1
  273. package/dist/{chunk-FTTI6T5Q.mjs → chunk-W422TEH2.mjs} +3 -3
  274. package/dist/{chunk-WIPEDNSD.mjs → chunk-WD5LBXPR.mjs} +4 -4
  275. package/dist/chunk-WFNGSYS4.mjs +111 -0
  276. package/dist/chunk-WR6DCNAE.mjs +65 -0
  277. package/dist/{chunk-ERWJPVX7.mjs → chunk-XKBB2UZU.mjs} +2 -2
  278. package/dist/{chunk-422IVD3H.mjs → chunk-Y5TPAKOS.mjs} +13 -17
  279. package/dist/{chunk-AZV7KNJI.mjs → chunk-YKWIMVGU.mjs} +2 -2
  280. package/dist/{chunk-ZKDKKQCE.mjs → chunk-YOXSXHDE.mjs} +4 -4
  281. package/dist/{chunk-PGQ6FMXS.mjs → chunk-ZO5BRTCW.mjs} +2 -2
  282. package/dist/{chunk-KSSVIFYR.mjs → chunk-ZQGCQ7SA.mjs} +14 -34
  283. package/dist/{chunk-ZTPYUU5C.mjs → chunk-ZRUUUVOO.mjs} +3 -3
  284. package/dist/{index-CY34hxPN.d.mts → index-CinAt5Uo.d.mts} +3 -3
  285. package/dist/{index-CY34hxPN.d.ts → index-CinAt5Uo.d.ts} +3 -3
  286. package/dist/index.d.mts +68 -18
  287. package/dist/index.d.ts +68 -18
  288. package/dist/index.js +965 -825
  289. package/dist/index.mjs +76 -69
  290. package/package.json +3 -2
  291. package/src/components/Accordion/Accordion.tsx +9 -18
  292. package/src/components/AppHeader/AppHeader.tsx +9 -1
  293. package/src/components/ConfirmDialog/ConfirmDialog.tsx +4 -34
  294. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -2
  295. package/src/components/Image/Image.tsx +50 -0
  296. package/src/components/Image/index.ts +2 -0
  297. package/src/components/ImageUpload/ImageUpload.tsx +1 -1
  298. package/src/components/{ListGroup/ListGroup.tsx → ItemGroup/ItemGroup.tsx} +15 -29
  299. package/src/components/ItemGroup/index.ts +2 -0
  300. package/src/components/ListGroup/index.tsx +20 -0
  301. package/src/components/MenuGroup/index.tsx +20 -0
  302. package/src/components/Pressable/Pressable.tsx +0 -24
  303. package/src/components/ScreenContainer/ScreenContainer.tsx +94 -0
  304. package/src/components/ScreenContainer/index.ts +2 -0
  305. package/src/components/Select/Select.tsx +22 -30
  306. package/src/components/SelectableGrid/SelectableGrid.tsx +51 -19
  307. package/src/components/Separator/Separator.tsx +35 -2
  308. package/src/components/Sheet/Sheet.tsx +3 -34
  309. package/src/components/Tabs/Tabs.tsx +9 -9
  310. package/src/components/Tabs/index.ts +1 -1
  311. package/src/components/Text/Text.tsx +6 -0
  312. package/src/components/VirtualizedList/VirtualizedList.tsx +154 -0
  313. package/src/components/VirtualizedList/index.ts +2 -0
  314. package/src/hooks/useConfirmDialog.ts +2 -11
  315. package/src/hooks/useSheetModal.ts +40 -0
  316. package/src/index.ts +5 -1
  317. package/src/theme/colors.ts +19 -57
  318. package/src/tokens.ts +21 -7
  319. package/src/utils/curatedIcons.ts +9 -18
  320. package/src/utils/haptics.ts +10 -21
  321. package/src/utils/icons.ts +7 -14
  322. package/dist/ListGroup.d.mts +0 -34
  323. package/dist/ListGroup.d.ts +0 -34
  324. package/dist/ListGroup.mjs +0 -4
  325. package/dist/MenuGroup.d.mts +0 -34
  326. package/dist/MenuGroup.d.ts +0 -34
  327. package/dist/MenuGroup.js +0 -106
  328. package/dist/MenuGroup.mjs +0 -4
  329. package/dist/chunk-ARONDO7M.mjs +0 -40
  330. package/dist/chunk-EW2FIDSM.mjs +0 -29
  331. package/dist/chunk-S2VGME7X.mjs +0 -82
  332. package/src/components/ListGroup/index.ts +0 -1
  333. package/src/components/MenuGroup/MenuGroup.tsx +0 -145
  334. package/src/components/MenuGroup/index.ts +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A personal React Native / Expo UI component library with a built-in design system, dark mode support, haptic feedback, and smooth animations.
4
4
 
5
- - 55 components across 9 categories (plus the deep-import `HolographicCard`)
5
+ - 57 components across 9 categories (plus the deep-import `HolographicCard`)
6
6
  - Light/dark theme with 12 public tokens (26 resolved) and full customization
7
7
  - Apple HIG–compliant touch targets and haptic feedback
8
8
  - Animated interactions: spring press, sliding tabs, accordion easing, animated progress
@@ -188,15 +188,15 @@ import { SPACING, ICON_SIZES, RADIUS, SHADOWS, BREAKPOINTS, TYPOGRAPHY } from '@
188
188
 
189
189
  | Category | Components |
190
190
  | ----------- | ----------------------------------------------------------------------------------------------- |
191
- | Display | `Text`, `Badge`, `Avatar`, `AvatarGroup`, `Separator`, `Spinner`, `Skeleton`, `Progress`, `CurrencyDisplay`, `Stats` |
191
+ | Display | `Text`, `Badge`, `Avatar`, `AvatarGroup`, `Separator`, `Spinner`, `Skeleton`, `Progress`, `CurrencyDisplay`, `Stats`, `Image` |
192
192
  | Surfaces | `Card`, `AlertBanner`, `EmptyState`, `MediaCard`, `PricingCard` |
193
193
  | Form | `Form` (+ `Form.Field` / `Form.Section` / `Form.Footer`), `Button`, `ButtonGroup`, `IconButton`, `Input`, `CurrencyInput`, `Textarea`, `Checkbox`, `Switch`, `Toggle`, `RadioGroup`, `Select`, `Slider`, `SelectableGrid`, `SelectableCard` (+ `SelectableCardGroup`), `SheetSelect`, `ImageUpload`, `IconPicker`, `NumberStepper` |
194
194
  | Composition | `Tabs`, `Accordion` |
195
195
  | Navigation | `AppHeader`, `TabBar`, `PagerDots` |
196
196
  | Overlays | `Sheet`, `ConfirmDialog`, `ImageViewer` |
197
197
  | Feedback | `Toast` / `ToastProvider` / `useToast` |
198
- | Data | `ListItem`, `ListGroup` (+ `.Header` / `.Footer`), `MenuItem`, `MenuGroup` (+ `.Header` / `.Footer`), `Chip` / `ChipGroup`, `LabelValue`, `MonthPicker`, `CategoryStrip`, `DetailRow` |
199
- | Utilities | `Pressable`, `Icon`, `RetrayProvider`, `ErrorBoundary` |
198
+ | Data | `ListItem`, `ListGroup` (+ `.Header` / `.Footer`), `MenuItem`, `MenuGroup` (+ `.Header` / `.Footer`), `Chip` / `ChipGroup`, `LabelValue`, `MonthPicker`, `CategoryStrip`, `DetailRow`, `VirtualizedList` |
199
+ | Utilities | `Pressable`, `Icon`, `RetrayProvider`, `ErrorBoundary`, `ScreenContainer` |
200
200
 
201
201
  Deep-import only: `HolographicCard` — `import { HolographicCard } from '@retray-dev/ui-kit/HolographicCard'`.
202
202
 
package/SKILL.md CHANGED
@@ -2,7 +2,7 @@
2
2
  name: retray-ui-kit
3
3
  description: >
4
4
  Complete guide for @retray-dev/ui-kit — a React Native / Expo component
5
- library (~55 components). Airbnb-inspired design, Sohne typography,
5
+ library (~57 components). Airbnb-inspired design, Sohne typography,
6
6
  haptic-rich interactions, animated with pressto + react-native-ease.
7
7
  Theme system, BottomSheet patterns, icon resolution, and conventions.
8
8
  ---
@@ -165,8 +165,8 @@ import { SPACING, ICON_SIZES, RADIUS, SHADOWS, BREAKPOINTS, TYPOGRAPHY } from '@
165
165
  |-----|---------|--------|-----------|-----|
166
166
  | `sm` | 0.06 | 4 | 2 | Default card |
167
167
  | `md` | 0.10 | 8 | 5 | Hover float |
168
- | `lg` | 0.16 | 16 | 10 | Modals |
169
- | `xl` | 0.24 | 24 | 18 | High-elevation |
168
+ | `lg` | 0.12 | 12 | 8 | Modals |
169
+ | `xl` | 0.18 | 24 | 16 | High-elevation |
170
170
 
171
171
  **BREAKPOINTS**
172
172
 
@@ -234,7 +234,7 @@ Feather > AntDesign > Entypo > FontAwesome5 > MaterialIcons > Ionicons
234
234
 
235
235
  ### Rules
236
236
  - Prefer Feather (outlined) over FA5 solid (filled). FA5 `defaultStyle='regular'` but some names only exist in `solid` — avoid those.
237
- - Icon lookup uses lazy singleton cache from `glyphMap` introspection.
237
+ - Icon lookup introspects `glyphMap` per call no caching between renders.
238
238
 
239
239
  ### `getResponsiveFontSize` utility
240
240
  ```tsx
@@ -295,7 +295,7 @@ Use `<Input sheetMode />` — transparently swaps to `BottomSheetTextInput`. For
295
295
 
296
296
  ## Haptics (expo-haptics)
297
297
 
298
- Web-safe via `Platform.OS !== 'web'` guard + dynamic `import()`.
298
+ Web-safe via static `import * as Haptics` with `Platform.OS === 'web'` guard at call sites.
299
299
 
300
300
  | Function | Usage |
301
301
  |---|---|
@@ -417,9 +417,137 @@ import { HolographicCard } from '@retray-dev/ui-kit/HolographicCard'
417
417
 
418
418
  ---
419
419
 
420
+ ### Image
421
+
422
+ **Import:** `import { Image } from '@retray-dev/ui-kit'`
423
+
424
+ **When to use:** Image display with automatic fallback when source is null or fails to load. Wraps `expo-image` for performant caching and cross-fade transitions. Supports aspect ratio containers.
425
+
426
+ | Prop | Type | Default | Notes |
427
+ |------|------|---------|-------|
428
+ | src | `string \| null` | — | Image URI. `null` or load failure shows fallback/skeleton |
429
+ | fallback | `ReactNode` | — | Custom fallback when src is null or image fails |
430
+ | aspectRatio | `number` | — | Width/height ratio — sets container proportionally (e.g. `16/9`, `4/3`) |
431
+ | borderRadius | `number` | `0` | Corner radius on the image |
432
+ | style | `ImageStyle` | — | — |
433
+
434
+ All remaining `expo-image` props (`contentFit`, `transition`, `placeholder`, etc.) pipe through.
435
+
436
+ **Fallback behavior:** When `src` is null/falsy or the image errors on load:
437
+ - If `fallback` is provided: renders fallback node inside a container
438
+ - Otherwise: renders a `skeleton`-colored placeholder matching the image dimensions
439
+
440
+ **Examples:**
441
+ ```tsx
442
+ <Image src="https://example.com/photo.jpg" aspectRatio={4/3} borderRadius={12} />
443
+ <Image src={null} fallback={<Icon name="image" size={32} color={colors.foregroundMuted} />} />
444
+ <Image src={avatar} borderRadius={40} style={{ width: 80, height: 80 }} />
445
+ <Image src={banner} aspectRatio={16/9} contentFit="cover" transition={500} />
446
+ ```
447
+
448
+ ---
449
+
450
+ ### ScreenContainer
451
+
452
+ **Import:** `import { ScreenContainer } from '@retray-dev/ui-kit'`
453
+
454
+ **When to use:** Consistent screen-level layout wrapper. Sets background color, safe area padding, optional scroll, keyboard avoidance, and centers content with a max-width constraint for wide screens.
455
+
456
+ | Prop | Type | Default | Notes |
457
+ |------|------|---------|-------|
458
+ | children | `ReactNode` | required | Screen content |
459
+ | maxWidth | `number` | `700` (BREAKPOINTS.wide) | Max content width. Set to `0` to disable centering |
460
+ | scroll | `boolean` | `false` | Wrap content in ScrollView |
461
+ | backgroundColor | `string` | Theme `background` | Override background color |
462
+ | paddingTop | `number` | Safe area top | Override top padding |
463
+ | paddingBottom | `number` | Safe area bottom | Override bottom padding |
464
+ | paddingHorizontal | `number` | `0` | Horizontal padding |
465
+ | keyboard | `boolean` | `false` | Enable KeyboardAvoidingView (iOS: padding behavior) |
466
+ | style | `ViewStyle` | — | Additional container styles |
467
+
468
+ **Behavior:** Wraps children in a centered View (maxWidth with `alignSelf: 'center'`). When `keyboard={true}`, wraps in `KeyboardAvoidingView`. When `scroll={true}`, wraps in `ScrollView` with `keyboardShouldPersistTaps="handled"`.
469
+
470
+ **Examples:**
471
+ ```tsx
472
+ // Basic screen
473
+ <ScreenContainer>
474
+ <Text variant="display-xl">Home</Text>
475
+ {/* screen content */}
476
+ </ScreenContainer>
477
+
478
+ // Scrollable with keyboard avoidance
479
+ <ScreenContainer scroll keyboard paddingHorizontal={16}>
480
+ <Input label="Name" />
481
+ <Input label="Email" />
482
+ <Button label="Submit" fullWidth />
483
+ </ScreenContainer>
484
+
485
+ // Wide desktop constraint
486
+ <ScreenContainer maxWidth={700} paddingHorizontal={16}>
487
+ <Text variant="display-lg">Dashboard</Text>
488
+ </ScreenContainer>
489
+ ```
490
+
491
+ ---
492
+
493
+ ### VirtualizedList
494
+
495
+ **Import:** `import { VirtualizedList } from '@retray-dev/ui-kit'`
496
+
497
+ **When to use:** Performant sectioned lists with sticky headers, pull-to-refresh, and empty state. Built on React Native `SectionList` for memory-efficient rendering of large datasets.
498
+
499
+ | Prop | Type | Default | Notes |
500
+ |------|------|---------|-------|
501
+ | sections | `VirtualizedListSection<T>[]` | required | `{ title?: string, data: T[] }` — sections with optional headers |
502
+ | renderItem | `(info: SectionListRenderItemInfo<T>) => ReactElement` | required | Row renderer for each item |
503
+ | emptyTitle | `string` | `'Sin contenido'` | Title shown when no data |
504
+ | emptyDescription | `string` | — | Description below empty title |
505
+ | emptyComponent | `ReactNode` | — | Custom empty state (overrides emptyTitle/emptyDescription) |
506
+ | refreshing | `boolean` | `false` | Pull-to-refresh loading state |
507
+ | onRefresh | `() => void` | — | Pull-to-refresh handler |
508
+ | stickyHeaders | `boolean` | `true` | Section headers stick to top while scrolling |
509
+ | headerColor | `string` | `foregroundMuted` | Section header text color override |
510
+ | style | `ViewStyle` | — | List container style |
511
+
512
+ Also accepts all `SectionListProps` (e.g. `ListHeaderComponent`, `ListFooterComponent`, `ItemSeparatorComponent`).
513
+
514
+ **Section headers:** Uppercase 13pt SemiBold text. Sections with empty `data` arrays are filtered out automatically.
515
+
516
+ **Empty state:** When all sections have empty data, shows centered emptyTitle/emptyDescription or custom emptyComponent.
517
+
518
+ **Examples:**
519
+ ```tsx
520
+ // Simple sectioned list
521
+ <VirtualizedList
522
+ sections={[
523
+ { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
524
+ { title: 'Vegetables', data: ['Carrot', 'Broccoli'] },
525
+ ]}
526
+ renderItem={({ item }) => <ListItem title={item} showSeparator />}
527
+ />
528
+
529
+ // With pull-to-refresh
530
+ <VirtualizedList
531
+ sections={data}
532
+ renderItem={renderRow}
533
+ refreshing={loading}
534
+ onRefresh={handleRefresh}
535
+ />
536
+
537
+ // Custom empty state
538
+ <VirtualizedList
539
+ sections={[]}
540
+ renderItem={() => null}
541
+ emptyTitle="No items found"
542
+ emptyDescription="Try adjusting your filters"
543
+ />
544
+ ```
545
+
546
+ ---
547
+
420
548
  ## Version
421
549
 
422
- **Current: 13.1.0.** Requires Expo SDK 54+, React Native 0.81+, React 19.
550
+ **Current: 13.4.0.** Requires Expo SDK 54+, React Native 0.81+, React 19.
423
551
 
424
552
  For full setup guide, see `CONSUMER.md`. For usage examples, see `EXAMPLES.md`.
425
553
 
@@ -1431,9 +1559,10 @@ const [guests, setGuests] = useState(2)
1431
1559
  | Prop | Type | Default | Notes |
1432
1560
  |------|------|---------|-------|
1433
1561
  | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Direction of the line |
1562
+ | label | `string` | — | Label shown in center of horizontal separator — renders as `── label ──` |
1434
1563
  | style | `ViewStyle` | — | — |
1435
1564
 
1436
- **Styling:** 1px thickness, `border` token color.
1565
+ **Styling:** 1px thickness, `border` token color. When `label` is provided, uses uppercase medium text with letter-spacing.
1437
1566
 
1438
1567
  **Examples:**
1439
1568
  ```tsx
@@ -1447,6 +1576,9 @@ const [guests, setGuests] = useState(2)
1447
1576
  <Text>Right</Text>
1448
1577
  </View>
1449
1578
 
1579
+ // With label
1580
+ <Separator label="o" />
1581
+
1450
1582
  // With custom spacing
1451
1583
  <Separator style={{ marginVertical: SPACING.lg }} />
1452
1584
  ```
@@ -2097,15 +2229,21 @@ const [accepted, setAccepted] = useState(false)
2097
2229
  | tabs | `TabItem[]` | required | Tab definitions |
2098
2230
  | variant | `'pill' \| 'underline'` | `'pill'` | Visual style |
2099
2231
  | value | `string` | — | Controlled active tab |
2100
- | onValueChange | `(value: string) => void` | — | — |
2232
+ | onValueChange | `(value: T) => void` | — | Generic infers from `value` prop type |
2101
2233
  | children | `ReactNode` | — | `TabsContent` components |
2102
2234
  | style | `ViewStyle` | — | — |
2103
2235
 
2104
2236
  **TabItem type:**
2105
2237
  ```ts
2106
- { label: string; value: string; icon?: ReactNode | ((isActive: boolean) => ReactNode) }
2238
+ interface TabItem<T extends string = string> {
2239
+ label: string
2240
+ value: T
2241
+ icon?: ReactNode | ((isActive: boolean) => ReactNode)
2242
+ }
2107
2243
  ```
2108
2244
 
2245
+ The generic `T` propagates from `TabItem<T>` through `onValueChange(value: T)`, so callbacks receive the correct union type without manual casting.
2246
+
2109
2247
  **Variants:**
2110
2248
  - `pill` — Animated background pill slides to active tab. Full-width distributed tabs. Active: filled `primary` + `primaryForeground` text. Default for top-of-screen navigation.
2111
2249
  - `underline` — 2px bottom border on active tab, no background. Tabs don't stretch — natural width. Airbnb-style filter tabs.
@@ -3739,17 +3877,23 @@ export default function TabLayout() {
3739
3877
  | title | `string` | `'Something went wrong'` | Default fallback title |
3740
3878
  | message | `string` | `error.message` | Default fallback body |
3741
3879
  | onError | `(error, info) => void` | — | Wire your crash reporter here |
3880
+ | onCatch | `(error, componentStack) => void` | — | Simplified callback — just error + stack string |
3742
3881
 
3743
3882
  **Default fallback:** centered themed card with a destructive icon, title, message, and a "Try again" button that calls `reset()`.
3744
3883
 
3745
- **Example:**
3884
+ **Examples:**
3746
3885
  ```tsx
3747
3886
  <ErrorBoundary onError={reportCrash}>
3748
3887
  <DocumentViewer />
3749
3888
  </ErrorBoundary>
3750
3889
 
3751
- // Custom fallback
3752
- <ErrorBoundary fallback={({ error, reset }) => <MyFallback error={error} onRetry={reset} />}>
3890
+ // Use componentStack in custom fallback
3891
+ <ErrorBoundary fallback={({ error, componentStack, reset }) => <MyFallback error={error} stack={componentStack} onRetry={reset} />}>
3892
+ <RiskyScreen />
3893
+ </ErrorBoundary>
3894
+
3895
+ // Simplified crash reporter
3896
+ <ErrorBoundary onCatch={(error, stack) => logCrash(error, stack)}>
3753
3897
  <RiskyScreen />
3754
3898
  </ErrorBoundary>
3755
3899
  ```
@@ -4069,3 +4213,123 @@ const { visible, loading, open, onConfirm, onCancel } = useConfirmDialog({
4069
4213
 
4070
4214
  ---
4071
4215
 
4216
+ ### Image
4217
+
4218
+ **Import:** `import { Image } from '@retray-dev/ui-kit'`
4219
+
4220
+ **When to use:** Display images with automatic fallback on load failure. Wraps `expo-image` for performant loading and caching.
4221
+
4222
+ | Prop | Type | Default | Notes |
4223
+ |------|------|---------|-------|
4224
+ | src | `string \| null` | — | Image URI. `null` or failed load shows fallback |
4225
+ | fallback | `ReactNode` | — | Custom fallback content when image fails to load |
4226
+ | aspectRatio | `number` | — | Width/height ratio — e.g. `16/9`, `4/3`. Sets container height proportionally |
4227
+ | borderRadius | `number` | `0` | Border radius override |
4228
+
4229
+ **All other `expo-image` props pass through** (except `source` — use `src` instead).
4230
+
4231
+ **Behavior:** On load error or `null` src: if `fallback` node provided, renders it inside container; otherwise renders a skeleton-colored placeholder with `accessibilityLabel="Imagen no disponible"`.
4232
+
4233
+ **Examples:**
4234
+ ```tsx
4235
+ // Basic
4236
+ <Image src="https://example.com/photo.jpg" aspectRatio={16/9} />
4237
+
4238
+ // With fallback
4239
+ <Image src={user.avatar} fallback={<Avatar fallbackText={user.name} />} />
4240
+
4241
+ // Rounded
4242
+ <Image src={photo.uri} borderRadius={12} aspectRatio={4/3} />
4243
+ ```
4244
+
4245
+ ---
4246
+
4247
+ ### ScreenContainer
4248
+
4249
+ **Import:** `import { ScreenContainer } from '@retray-dev/ui-kit'`
4250
+
4251
+ **When to use:** Consistent screen layout with safe area insets, optional scroll, keyboard avoidance, and responsive max-width centering.
4252
+
4253
+ | Prop | Type | Default | Notes |
4254
+ |------|------|---------|-------|
4255
+ | children | `ReactNode` | required | Screen content |
4256
+ | maxWidth | `number` | `700` | Max content width (points). `0` disables |
4257
+ | scroll | `boolean` | `false` | Enable scroll view |
4258
+ | backgroundColor | `string` | theme `background` | — |
4259
+ | paddingTop | `number` | safe area top | Override top padding |
4260
+ | paddingBottom | `number` | safe area bottom | Override bottom padding |
4261
+ | paddingHorizontal | `number` | `0` | Horizontal padding |
4262
+ | keyboard | `boolean` | `false` | Enable `KeyboardAvoidingView` (iOS `padding` behavior) |
4263
+ | style | `ViewStyle` | — | Additional wrapper style |
4264
+
4265
+ **Behavior:** Applies top/bottom safe area insets, centers content horizontally when screen exceeds `maxWidth`. When `keyboard` is enabled, wraps content in `KeyboardAvoidingView` with iOS `padding` behavior.
4266
+
4267
+ **Examples:**
4268
+ ```tsx
4269
+ // Basic scroll screen
4270
+ <ScreenContainer scroll paddingHorizontal={16}>
4271
+ <Text variant="title-md">Welcome</Text>
4272
+ </ScreenContainer>
4273
+
4274
+ // With keyboard avoidance for forms
4275
+ <ScreenContainer keyboard paddingHorizontal={16}>
4276
+ <Input label="Name" />
4277
+ <Input label="Email" />
4278
+ <Button label="Submit" />
4279
+ </ScreenContainer>
4280
+
4281
+ // Non-scroll, max width disabled
4282
+ <ScreenContainer maxWidth={0}>
4283
+ <FullWidthContent />
4284
+ </ScreenContainer>
4285
+ ```
4286
+
4287
+ ---
4288
+
4289
+ ### VirtualizedList
4290
+
4291
+ **Import:** `import { VirtualizedList } from '@retray-dev/ui-kit'`
4292
+
4293
+ **When to use:** Sectioned lists with sticky headers, empty state, and pull-to-refresh. Wraps React Native `SectionList` with Spanish defaults.
4294
+
4295
+ | Prop | Type | Default | Notes |
4296
+ |------|------|---------|-------|
4297
+ | sections | `VirtualizedListSection<T>[]` | required | `{ title?: string; data: T[] }` — only non-empty sections render |
4298
+ | renderItem | `(info) => ReactElement` | required | Standard `SectionList` render function |
4299
+ | emptyTitle | `string` | `'Sin contenido'` | Title shown when no data |
4300
+ | emptyDescription | `string` | — | Description below title |
4301
+ | emptyComponent | `ReactNode` | — | Custom empty state (overrides titles) |
4302
+ | refreshing | `boolean` | `false` | Pull-to-refresh state |
4303
+ | onRefresh | `() => void` | — | Refresh handler |
4304
+ | stickyHeaders | `boolean` | `true` | Enable sticky section headers |
4305
+ | headerColor | `string` | `foregroundMuted` | Section header text color |
4306
+
4307
+ **All other `SectionList` props pass through** (except `sections`, `renderItem`, `ListEmptyComponent`).
4308
+
4309
+ **Behavior:** Sections with empty `data` arrays are filtered out. When no sections have data, renders the empty state (custom component or default title). Sticky headers render section titles in uppercase with `Sohne-SemiBold`.
4310
+
4311
+ **Examples:**
4312
+ ```tsx
4313
+ const sections = [
4314
+ { title: 'Hoy', data: todayItems },
4315
+ { title: 'Ayer', data: yesterdayItems },
4316
+ ]
4317
+
4318
+ <VirtualizedList
4319
+ sections={sections}
4320
+ renderItem={({ item }) => <ListItem title={item.name} />}
4321
+ refreshing={refreshing}
4322
+ onRefresh={handleRefresh}
4323
+ />
4324
+
4325
+ // With custom empty state
4326
+ <VirtualizedList
4327
+ sections={[]}
4328
+ renderItem={() => null}
4329
+ emptyTitle="No hay transacciones"
4330
+ emptyDescription="Tus transacciones aparecerán aquí"
4331
+ />
4332
+ ```
4333
+
4334
+ ---
4335
+
@@ -1,14 +1,14 @@
1
- import React from 'react';
1
+ import React__default from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
3
 
4
4
  interface AccordionItem {
5
5
  value: string;
6
- trigger: string | React.ReactNode;
7
- content: React.ReactNode;
6
+ trigger: string | React__default.ReactNode;
7
+ content: React__default.ReactNode;
8
8
  /** Icon name from @expo/vector-icons rendered left of trigger. */
9
9
  iconName?: string;
10
10
  /** Custom icon node rendered left of trigger. */
11
- icon?: React.ReactNode;
11
+ icon?: React__default.ReactNode;
12
12
  /** Override icon color. Defaults to foregroundMuted. */
13
13
  iconColor?: string;
14
14
  /**
@@ -17,7 +17,7 @@ interface AccordionItem {
17
17
  * Automatically touch-isolated — taps on actions won't toggle the accordion.
18
18
  * Use this instead of embedding interactive elements inside `trigger`.
19
19
  */
20
- triggerActions?: React.ReactNode;
20
+ triggerActions?: React__default.ReactNode;
21
21
  accessibilityHint?: string;
22
22
  }
23
23
  interface AccordionProps {
@@ -31,6 +31,6 @@ interface AccordionProps {
31
31
  defaultValue?: string | string[];
32
32
  style?: ViewStyle;
33
33
  }
34
- declare function Accordion({ items, type, defaultValue, style }: AccordionProps): React.JSX.Element;
34
+ declare function Accordion({ items, type, defaultValue, style }: AccordionProps): React__default.JSX.Element;
35
35
 
36
36
  export { Accordion, type AccordionItem, type AccordionProps };
@@ -1,14 +1,14 @@
1
- import React from 'react';
1
+ import React__default from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
3
 
4
4
  interface AccordionItem {
5
5
  value: string;
6
- trigger: string | React.ReactNode;
7
- content: React.ReactNode;
6
+ trigger: string | React__default.ReactNode;
7
+ content: React__default.ReactNode;
8
8
  /** Icon name from @expo/vector-icons rendered left of trigger. */
9
9
  iconName?: string;
10
10
  /** Custom icon node rendered left of trigger. */
11
- icon?: React.ReactNode;
11
+ icon?: React__default.ReactNode;
12
12
  /** Override icon color. Defaults to foregroundMuted. */
13
13
  iconColor?: string;
14
14
  /**
@@ -17,7 +17,7 @@ interface AccordionItem {
17
17
  * Automatically touch-isolated — taps on actions won't toggle the accordion.
18
18
  * Use this instead of embedding interactive elements inside `trigger`.
19
19
  */
20
- triggerActions?: React.ReactNode;
20
+ triggerActions?: React__default.ReactNode;
21
21
  accessibilityHint?: string;
22
22
  }
23
23
  interface AccordionProps {
@@ -31,6 +31,6 @@ interface AccordionProps {
31
31
  defaultValue?: string | string[];
32
32
  style?: ViewStyle;
33
33
  }
34
- declare function Accordion({ items, type, defaultValue, style }: AccordionProps): React.JSX.Element;
34
+ declare function Accordion({ items, type, defaultValue, style }: AccordionProps): React__default.JSX.Element;
35
35
 
36
36
  export { Accordion, type AccordionItem, type AccordionProps };
package/dist/Accordion.js CHANGED
@@ -4,6 +4,7 @@ var React3 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var Animated = require('react-native-reanimated');
6
6
  var vectorIcons = require('@expo/vector-icons');
7
+ var Haptics = require('expo-haptics');
7
8
  var reactNativeSizeMatters = require('react-native-size-matters');
8
9
  var AntDesign = require('@expo/vector-icons/AntDesign');
9
10
  var Entypo = require('@expo/vector-icons/Entypo');
@@ -15,8 +16,27 @@ var pressto = require('pressto');
15
16
 
16
17
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
18
 
19
+ function _interopNamespace(e) {
20
+ if (e && e.__esModule) return e;
21
+ var n = Object.create(null);
22
+ if (e) {
23
+ Object.keys(e).forEach(function (k) {
24
+ if (k !== 'default') {
25
+ var d = Object.getOwnPropertyDescriptor(e, k);
26
+ Object.defineProperty(n, k, d.get ? d : {
27
+ enumerable: true,
28
+ get: function () { return e[k]; }
29
+ });
30
+ }
31
+ });
32
+ }
33
+ n.default = e;
34
+ return Object.freeze(n);
35
+ }
36
+
18
37
  var React3__default = /*#__PURE__*/_interopDefault(React3);
19
38
  var Animated__default = /*#__PURE__*/_interopDefault(Animated);
39
+ var Haptics__namespace = /*#__PURE__*/_interopNamespace(Haptics);
20
40
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
21
41
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
22
42
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
@@ -25,22 +45,11 @@ var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
25
45
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
26
46
 
27
47
  // src/components/Accordion/Accordion.tsx
28
- var _haptics = null;
29
- var _loaded = false;
30
- async function getHaptics() {
31
- if (reactNative.Platform.OS === "web") return null;
32
- if (!_loaded) {
33
- _loaded = true;
34
- try {
35
- _haptics = await import('expo-haptics');
36
- } catch {
37
- _haptics = null;
38
- }
39
- }
40
- return _haptics;
48
+ function maybeHaptics() {
49
+ return reactNative.Platform.OS === "web" ? null : Haptics__namespace;
41
50
  }
42
51
  function selectionAsync() {
43
- getHaptics().then((h) => h?.selectionAsync());
52
+ maybeHaptics()?.selectionAsync();
44
53
  }
45
54
  var ThemeContext = React3.createContext(void 0);
46
55
  function useTheme() {
@@ -62,23 +71,17 @@ var ALL_FAMILIES = [
62
71
  { name: "MaterialIcons", component: MaterialIcons__default.default },
63
72
  { name: "Ionicons", component: Ionicons__default.default }
64
73
  ];
65
- var glyphCacheInitialized = false;
66
- function ensureGlyphCache() {
67
- if (glyphCacheInitialized) return;
68
- glyphCacheInitialized = true;
69
- for (const entry of ALL_FAMILIES) {
70
- try {
71
- entry.glyphMap = entry.component.glyphMap;
72
- } catch {
73
- entry.glyphMap = {};
74
- }
74
+ function getGlyphMap(component) {
75
+ try {
76
+ return component.glyphMap ?? {};
77
+ } catch {
78
+ return {};
75
79
  }
76
80
  }
77
81
  function Icon({ name, size, color, family }) {
78
- ensureGlyphCache();
79
82
  const entry = family ? ALL_FAMILIES.find((f) => f.name === family) : ALL_FAMILIES.find((f) => {
80
- const glyphMap = f.glyphMap;
81
- return glyphMap ? name in glyphMap : false;
83
+ const glyphMap = getGlyphMap(f.component);
84
+ return name in glyphMap;
82
85
  });
83
86
  if (!entry) return null;
84
87
  return React3__default.default.createElement(entry.component, { name, size, color });
@@ -111,24 +114,20 @@ function AccordionItemComponent({
111
114
  React3__default.default.useEffect(() => {
112
115
  isExpanded.value = isOpen;
113
116
  }, [isOpen, isExpanded]);
114
- const derivedHeight = Animated.useDerivedValue(
115
- () => Animated.withTiming(height.value * Number(isExpanded.value), {
116
- duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
117
- easing: isExpanded.value ? Animated.Easing.bezier(0.23, 1, 0.32, 1) : Animated.Easing.in(Animated.Easing.ease)
118
- })
119
- );
120
- const derivedRotation = Animated.useDerivedValue(
121
- () => Animated.withTiming(isExpanded.value ? 1 : 0, {
117
+ const bodyStyle = Animated.useAnimatedStyle(() => ({
118
+ height: Animated.withTiming(height.value * Number(isExpanded.value), {
122
119
  duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
123
120
  easing: isExpanded.value ? Animated.Easing.bezier(0.23, 1, 0.32, 1) : Animated.Easing.in(Animated.Easing.ease)
124
- })
125
- );
126
- const bodyStyle = Animated.useAnimatedStyle(() => ({
127
- height: derivedHeight.value,
121
+ }),
128
122
  overflow: "hidden"
129
123
  }));
130
124
  const rotationStyle = Animated.useAnimatedStyle(() => ({
131
- transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
125
+ transform: [{
126
+ rotate: `${Animated.withTiming(isExpanded.value ? 1 : 0, {
127
+ duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
128
+ easing: isExpanded.value ? Animated.Easing.bezier(0.23, 1, 0.32, 1) : Animated.Easing.in(Animated.Easing.ease)
129
+ }) * 180}deg`
130
+ }]
132
131
  }));
133
132
  return /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [styles.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React3__default.default.createElement(
134
133
  PressableRow,
@@ -1,7 +1,7 @@
1
- export { Accordion } from './chunk-422IVD3H.mjs';
1
+ export { Accordion } from './chunk-Y5TPAKOS.mjs';
2
2
  import './chunk-M53LC4Q7.mjs';
3
3
  import './chunk-IFYMBOEN.mjs';
4
- import './chunk-ARONDO7M.mjs';
5
- import './chunk-MZ6WRTD2.mjs';
6
- import './chunk-KSSVIFYR.mjs';
4
+ import './chunk-CTUFFKGS.mjs';
5
+ import './chunk-24JTXQ2M.mjs';
6
+ import './chunk-ZQGCQ7SA.mjs';
7
7
  import './chunk-2CE3TQVY.mjs';
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React__default from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
3
 
4
4
  type AlertBannerVariant = 'default' | 'destructive' | 'success' | 'warning';
@@ -6,13 +6,13 @@ interface AlertBannerProps {
6
6
  title: string;
7
7
  description?: string;
8
8
  variant?: AlertBannerVariant;
9
- icon?: React.ReactNode;
9
+ icon?: React__default.ReactNode;
10
10
  iconName?: string;
11
11
  iconColor?: string;
12
12
  /** Called when the user taps the dismiss (×) button. If omitted, no button is shown. */
13
13
  onDismiss?: () => void;
14
14
  style?: ViewStyle;
15
15
  }
16
- declare function AlertBanner({ title, description, variant, icon, iconName, iconColor, onDismiss, style }: AlertBannerProps): React.JSX.Element;
16
+ declare function AlertBanner({ title, description, variant, icon, iconName, iconColor, onDismiss, style }: AlertBannerProps): React__default.JSX.Element;
17
17
 
18
18
  export { AlertBanner, type AlertBannerProps, type AlertBannerVariant };
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React__default from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
3
 
4
4
  type AlertBannerVariant = 'default' | 'destructive' | 'success' | 'warning';
@@ -6,13 +6,13 @@ interface AlertBannerProps {
6
6
  title: string;
7
7
  description?: string;
8
8
  variant?: AlertBannerVariant;
9
- icon?: React.ReactNode;
9
+ icon?: React__default.ReactNode;
10
10
  iconName?: string;
11
11
  iconColor?: string;
12
12
  /** Called when the user taps the dismiss (×) button. If omitted, no button is shown. */
13
13
  onDismiss?: () => void;
14
14
  style?: ViewStyle;
15
15
  }
16
- declare function AlertBanner({ title, description, variant, icon, iconName, iconColor, onDismiss, style }: AlertBannerProps): React.JSX.Element;
16
+ declare function AlertBanner({ title, description, variant, icon, iconName, iconColor, onDismiss, style }: AlertBannerProps): React__default.JSX.Element;
17
17
 
18
18
  export { AlertBanner, type AlertBannerProps, type AlertBannerVariant };