@retray-dev/ui-kit 6.2.0 → 9.0.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 (389) hide show
  1. package/COMPONENTS.md +997 -20
  2. package/EXAMPLES.md +250 -2
  3. package/README.md +21 -14
  4. package/dist/Accordion.d.mts +28 -0
  5. package/dist/Accordion.d.ts +28 -0
  6. package/dist/Accordion.js +392 -0
  7. package/dist/Accordion.mjs +7 -0
  8. package/dist/AlertBanner.d.mts +16 -0
  9. package/dist/AlertBanner.d.ts +16 -0
  10. package/dist/AlertBanner.js +250 -0
  11. package/dist/AlertBanner.mjs +6 -0
  12. package/dist/AppHeader.d.mts +40 -0
  13. package/dist/AppHeader.d.ts +40 -0
  14. package/dist/AppHeader.js +515 -0
  15. package/dist/AppHeader.mjs +10 -0
  16. package/dist/Avatar.d.mts +20 -0
  17. package/dist/Avatar.d.ts +20 -0
  18. package/dist/Avatar.js +244 -0
  19. package/dist/Avatar.mjs +4 -0
  20. package/dist/Badge.d.mts +26 -0
  21. package/dist/Badge.d.ts +26 -0
  22. package/dist/Badge.js +257 -0
  23. package/dist/Badge.mjs +5 -0
  24. package/dist/Button.d.mts +30 -0
  25. package/dist/Button.d.ts +30 -0
  26. package/dist/Button.js +432 -0
  27. package/dist/Button.mjs +9 -0
  28. package/dist/ButtonGroup.d.mts +26 -0
  29. package/dist/ButtonGroup.d.ts +26 -0
  30. package/dist/ButtonGroup.js +52 -0
  31. package/dist/ButtonGroup.mjs +3 -0
  32. package/dist/Card.d.mts +39 -0
  33. package/dist/Card.d.ts +39 -0
  34. package/dist/Card.js +349 -0
  35. package/dist/Card.mjs +8 -0
  36. package/dist/CategoryStrip.d.mts +26 -0
  37. package/dist/CategoryStrip.d.ts +26 -0
  38. package/dist/CategoryStrip.js +453 -0
  39. package/dist/CategoryStrip.mjs +9 -0
  40. package/dist/Checkbox.d.mts +14 -0
  41. package/dist/Checkbox.d.ts +14 -0
  42. package/dist/Checkbox.js +336 -0
  43. package/dist/Checkbox.mjs +7 -0
  44. package/dist/Chip.d.mts +31 -0
  45. package/dist/Chip.d.ts +31 -0
  46. package/dist/Chip.js +403 -0
  47. package/dist/Chip.mjs +8 -0
  48. package/dist/ConfirmDialog.d.mts +15 -0
  49. package/dist/ConfirmDialog.d.ts +15 -0
  50. package/dist/ConfirmDialog.js +560 -0
  51. package/dist/ConfirmDialog.mjs +10 -0
  52. package/dist/CurrencyDisplay.d.mts +24 -0
  53. package/dist/CurrencyDisplay.d.ts +24 -0
  54. package/dist/CurrencyDisplay.js +189 -0
  55. package/dist/CurrencyDisplay.mjs +4 -0
  56. package/dist/CurrencyInput.d.mts +26 -0
  57. package/dist/CurrencyInput.d.ts +26 -0
  58. package/dist/CurrencyInput.js +408 -0
  59. package/dist/CurrencyInput.mjs +8 -0
  60. package/dist/DetailRow.d.mts +32 -0
  61. package/dist/DetailRow.d.ts +32 -0
  62. package/dist/DetailRow.js +275 -0
  63. package/dist/DetailRow.mjs +5 -0
  64. package/dist/EmptyState.d.mts +27 -0
  65. package/dist/EmptyState.d.ts +27 -0
  66. package/dist/EmptyState.js +523 -0
  67. package/dist/EmptyState.mjs +10 -0
  68. package/dist/ErrorBoundary.d.mts +42 -0
  69. package/dist/ErrorBoundary.d.ts +42 -0
  70. package/dist/ErrorBoundary.js +351 -0
  71. package/dist/ErrorBoundary.mjs +7 -0
  72. package/dist/Form.d.mts +52 -0
  73. package/dist/Form.d.ts +52 -0
  74. package/dist/Form.js +204 -0
  75. package/dist/Form.mjs +4 -0
  76. package/dist/HolographicCard.d.mts +55 -0
  77. package/dist/HolographicCard.d.ts +55 -0
  78. package/dist/HolographicCard.js +316 -0
  79. package/dist/HolographicCard.mjs +191 -0
  80. package/dist/IconButton.d.mts +27 -0
  81. package/dist/IconButton.d.ts +27 -0
  82. package/dist/IconButton.js +400 -0
  83. package/dist/IconButton.mjs +8 -0
  84. package/dist/ImageViewer.d.mts +23 -0
  85. package/dist/ImageViewer.d.ts +23 -0
  86. package/dist/ImageViewer.js +582 -0
  87. package/dist/ImageViewer.mjs +8 -0
  88. package/dist/Input.d.mts +23 -0
  89. package/dist/Input.d.ts +23 -0
  90. package/dist/Input.js +351 -0
  91. package/dist/Input.mjs +7 -0
  92. package/dist/LabelValue.d.mts +16 -0
  93. package/dist/LabelValue.d.ts +16 -0
  94. package/dist/LabelValue.js +225 -0
  95. package/dist/LabelValue.mjs +5 -0
  96. package/dist/ListGroup.d.mts +34 -0
  97. package/dist/ListGroup.d.ts +34 -0
  98. package/dist/ListGroup.js +217 -0
  99. package/dist/ListGroup.mjs +5 -0
  100. package/dist/ListItem.d.mts +64 -0
  101. package/dist/ListItem.d.ts +64 -0
  102. package/dist/ListItem.js +444 -0
  103. package/dist/ListItem.mjs +9 -0
  104. package/dist/MediaCard.d.mts +39 -0
  105. package/dist/MediaCard.d.ts +39 -0
  106. package/dist/MediaCard.js +475 -0
  107. package/dist/MediaCard.mjs +9 -0
  108. package/dist/MenuGroup.d.mts +34 -0
  109. package/dist/MenuGroup.d.ts +34 -0
  110. package/dist/MenuGroup.js +217 -0
  111. package/dist/MenuGroup.mjs +5 -0
  112. package/dist/MenuItem.d.mts +48 -0
  113. package/dist/MenuItem.d.ts +48 -0
  114. package/dist/MenuItem.js +415 -0
  115. package/dist/MenuItem.mjs +9 -0
  116. package/dist/MonthPicker.d.mts +28 -0
  117. package/dist/MonthPicker.d.ts +28 -0
  118. package/dist/MonthPicker.js +297 -0
  119. package/dist/MonthPicker.mjs +5 -0
  120. package/dist/PagerDots.d.mts +35 -0
  121. package/dist/PagerDots.d.ts +35 -0
  122. package/dist/PagerDots.js +392 -0
  123. package/dist/PagerDots.mjs +7 -0
  124. package/dist/Pressable.d.mts +34 -0
  125. package/dist/Pressable.d.ts +34 -0
  126. package/dist/Pressable.js +143 -0
  127. package/dist/Pressable.mjs +5 -0
  128. package/dist/PricingCard.d.mts +50 -0
  129. package/dist/PricingCard.d.ts +50 -0
  130. package/dist/PricingCard.js +636 -0
  131. package/dist/PricingCard.mjs +11 -0
  132. package/dist/Progress.d.mts +14 -0
  133. package/dist/Progress.d.ts +14 -0
  134. package/dist/Progress.js +191 -0
  135. package/dist/Progress.mjs +5 -0
  136. package/dist/RadioGroup.d.mts +19 -0
  137. package/dist/RadioGroup.d.ts +19 -0
  138. package/dist/RadioGroup.js +392 -0
  139. package/dist/RadioGroup.mjs +7 -0
  140. package/dist/RetrayProvider.d.mts +2 -0
  141. package/dist/RetrayProvider.d.ts +2 -0
  142. package/dist/RetrayProvider.js +214 -0
  143. package/dist/RetrayProvider.mjs +5 -0
  144. package/dist/Select.d.mts +22 -0
  145. package/dist/Select.d.ts +22 -0
  146. package/dist/Select.js +488 -0
  147. package/dist/Select.mjs +7 -0
  148. package/dist/SelectableGrid.d.mts +44 -0
  149. package/dist/SelectableGrid.d.ts +44 -0
  150. package/dist/SelectableGrid.js +448 -0
  151. package/dist/SelectableGrid.mjs +9 -0
  152. package/dist/Separator.d.mts +10 -0
  153. package/dist/Separator.d.ts +10 -0
  154. package/dist/Separator.js +156 -0
  155. package/dist/Separator.mjs +3 -0
  156. package/dist/Sheet.d.mts +93 -0
  157. package/dist/Sheet.d.ts +93 -0
  158. package/dist/Sheet.js +450 -0
  159. package/dist/Sheet.mjs +6 -0
  160. package/dist/Skeleton.d.mts +67 -0
  161. package/dist/Skeleton.d.ts +67 -0
  162. package/dist/Skeleton.js +266 -0
  163. package/dist/Skeleton.mjs +6 -0
  164. package/dist/Slider.d.mts +20 -0
  165. package/dist/Slider.d.ts +20 -0
  166. package/dist/Slider.js +279 -0
  167. package/dist/Slider.mjs +5 -0
  168. package/dist/Spinner.d.mts +12 -0
  169. package/dist/Spinner.d.ts +12 -0
  170. package/dist/Spinner.js +193 -0
  171. package/dist/Spinner.mjs +4 -0
  172. package/dist/Switch.d.mts +13 -0
  173. package/dist/Switch.d.ts +13 -0
  174. package/dist/Switch.js +311 -0
  175. package/dist/Switch.mjs +6 -0
  176. package/dist/TabBar.d.mts +42 -0
  177. package/dist/TabBar.d.ts +42 -0
  178. package/dist/TabBar.js +361 -0
  179. package/dist/TabBar.mjs +6 -0
  180. package/dist/Tabs.d.mts +27 -0
  181. package/dist/Tabs.d.ts +27 -0
  182. package/dist/Tabs.js +419 -0
  183. package/dist/Tabs.mjs +7 -0
  184. package/dist/Text.d.mts +12 -0
  185. package/dist/Text.d.ts +12 -0
  186. package/dist/Text.js +327 -0
  187. package/dist/Text.mjs +5 -0
  188. package/dist/Textarea.d.mts +16 -0
  189. package/dist/Textarea.d.ts +16 -0
  190. package/dist/Textarea.js +333 -0
  191. package/dist/Textarea.mjs +7 -0
  192. package/dist/Toast.d.mts +47 -0
  193. package/dist/Toast.d.ts +47 -0
  194. package/dist/Toast.js +185 -0
  195. package/dist/Toast.mjs +4 -0
  196. package/dist/Toggle.d.mts +36 -0
  197. package/dist/Toggle.d.ts +36 -0
  198. package/dist/Toggle.js +412 -0
  199. package/dist/Toggle.mjs +8 -0
  200. package/dist/VirtualList.d.mts +19 -0
  201. package/dist/VirtualList.d.ts +19 -0
  202. package/dist/VirtualList.js +38 -0
  203. package/dist/VirtualList.mjs +2 -0
  204. package/dist/chunk-26BCI223.mjs +14 -0
  205. package/dist/chunk-2CE3TQVY.mjs +11 -0
  206. package/dist/chunk-2TFTAWVJ.mjs +131 -0
  207. package/dist/chunk-2UYENBLV.mjs +49 -0
  208. package/dist/chunk-3BBOZ3OQ.mjs +41 -0
  209. package/dist/chunk-3DKJ2GIC.mjs +30 -0
  210. package/dist/chunk-3U4SSNWP.mjs +120 -0
  211. package/dist/chunk-4I7D47FH.mjs +139 -0
  212. package/dist/chunk-4K625MVM.mjs +142 -0
  213. package/dist/chunk-6OAZJ577.mjs +98 -0
  214. package/dist/chunk-6Q64UFIA.mjs +71 -0
  215. package/dist/chunk-756RAKE4.mjs +145 -0
  216. package/dist/chunk-7QHVVCB3.mjs +115 -0
  217. package/dist/chunk-A3A6KNQN.mjs +245 -0
  218. package/dist/chunk-A4MDAP7G.mjs +42 -0
  219. package/dist/chunk-AJ7ZDNBT.mjs +120 -0
  220. package/dist/chunk-AV4EMIRH.mjs +94 -0
  221. package/dist/chunk-AZJF2BLK.mjs +115 -0
  222. package/dist/chunk-BNP626TY.mjs +159 -0
  223. package/dist/chunk-BRKYVJVV.mjs +60 -0
  224. package/dist/chunk-DVK4G2GT.mjs +59 -0
  225. package/dist/chunk-EH745HE5.mjs +127 -0
  226. package/dist/chunk-EJ7ZPXOH.mjs +163 -0
  227. package/dist/chunk-GD6KXMG5.mjs +106 -0
  228. package/dist/chunk-GQYFLP3D.mjs +187 -0
  229. package/dist/chunk-ID72TK46.mjs +111 -0
  230. package/dist/chunk-IRRY3CRZ.mjs +82 -0
  231. package/dist/chunk-JB67UOB5.mjs +92 -0
  232. package/dist/chunk-JMOZEC77.mjs +90 -0
  233. package/dist/chunk-JT7HKXRB.mjs +114 -0
  234. package/dist/chunk-KIHCWCWL.mjs +124 -0
  235. package/dist/chunk-LXJIIOYQ.mjs +104 -0
  236. package/dist/chunk-M6ZXVBTK.mjs +64 -0
  237. package/dist/chunk-MAC465BB.mjs +61 -0
  238. package/dist/chunk-MBMXYJJV.mjs +36 -0
  239. package/dist/chunk-MLF3EZFW.mjs +119 -0
  240. package/dist/chunk-MX6HRKMI.mjs +29 -0
  241. package/dist/chunk-NA7PARID.mjs +147 -0
  242. package/dist/chunk-NC5ZTR2Y.mjs +32 -0
  243. package/dist/chunk-O3HA6TYM.mjs +139 -0
  244. package/dist/chunk-OB4JUQ3O.mjs +51 -0
  245. package/dist/chunk-PFZTM6D5.mjs +238 -0
  246. package/dist/chunk-QKH5ZOD5.mjs +97 -0
  247. package/dist/chunk-QY3X2UYR.mjs +191 -0
  248. package/dist/chunk-SOA2Z4RB.mjs +82 -0
  249. package/dist/chunk-SOYNZDVY.mjs +151 -0
  250. package/dist/chunk-T7XZ7H7Y.mjs +57 -0
  251. package/dist/chunk-TERDKCLE.mjs +74 -0
  252. package/dist/chunk-UREA2GYY.mjs +113 -0
  253. package/dist/chunk-VGTDN7SW.mjs +164 -0
  254. package/dist/chunk-VQ57HWPL.mjs +144 -0
  255. package/dist/chunk-WBOOUHSS.mjs +62 -0
  256. package/dist/chunk-WJLKJMKR.mjs +78 -0
  257. package/dist/chunk-X4G6APW6.mjs +134 -0
  258. package/dist/chunk-Y6FXYEAI.mjs +8 -0
  259. package/dist/chunk-YFZ3ELX5.mjs +16 -0
  260. package/dist/chunk-YNROWHQJ.mjs +46 -0
  261. package/dist/chunk-Z4BVUWW6.mjs +196 -0
  262. package/dist/chunk-ZJKGQMYH.mjs +131 -0
  263. package/dist/index-wt-orHUi.d.mts +85 -0
  264. package/dist/index-wt-orHUi.d.ts +85 -0
  265. package/dist/index.d.mts +149 -920
  266. package/dist/index.d.ts +149 -920
  267. package/dist/index.js +2560 -970
  268. package/dist/index.mjs +60 -3895
  269. package/package.json +55 -16
  270. package/src/assets/fonts/Sohne-Bold.otf +0 -0
  271. package/src/assets/fonts/Sohne-BoldItalic.otf +0 -0
  272. package/src/assets/fonts/Sohne-ExtraBold.otf +0 -0
  273. package/src/assets/fonts/Sohne-ExtraBoldItalic.otf +0 -0
  274. package/src/assets/fonts/Sohne-ExtraLight.otf +0 -0
  275. package/src/assets/fonts/Sohne-ExtraLightItalic.otf +0 -0
  276. package/src/assets/fonts/Sohne-Italic.otf +0 -0
  277. package/src/assets/fonts/Sohne-Light.otf +0 -0
  278. package/src/assets/fonts/Sohne-LightItalic.otf +0 -0
  279. package/src/assets/fonts/Sohne-Medium.otf +0 -0
  280. package/src/assets/fonts/Sohne-MediumItalic.otf +0 -0
  281. package/src/assets/fonts/Sohne-Regular.otf +0 -0
  282. package/src/assets/fonts/Sohne-SemiBold.otf +0 -0
  283. package/src/assets/fonts/Sohne-SemiBoldItalic.otf +0 -0
  284. package/src/assets/fonts/SohneMono-Bold.otf +0 -0
  285. package/src/assets/fonts/SohneMono-BoldItalic.otf +0 -0
  286. package/src/assets/fonts/SohneMono-ExtraBold.otf +0 -0
  287. package/src/assets/fonts/SohneMono-ExtraBoldItalic.otf +0 -0
  288. package/src/assets/fonts/SohneMono-ExtraLight.otf +0 -0
  289. package/src/assets/fonts/SohneMono-ExtraLightItalic.otf +0 -0
  290. package/src/assets/fonts/SohneMono-Italic.otf +0 -0
  291. package/src/assets/fonts/SohneMono-Light.otf +0 -0
  292. package/src/assets/fonts/SohneMono-LightItalic.otf +0 -0
  293. package/src/assets/fonts/SohneMono-Medium.otf +0 -0
  294. package/src/assets/fonts/SohneMono-MediumItalic.otf +0 -0
  295. package/src/assets/fonts/SohneMono-Regular.otf +0 -0
  296. package/src/assets/fonts/SohneMono-SemiBold.otf +0 -0
  297. package/src/assets/fonts/SohneMono-SemiBoldItalic.otf +0 -0
  298. package/src/components/Accordion/Accordion.tsx +15 -4
  299. package/src/components/AlertBanner/AlertBanner.tsx +38 -12
  300. package/src/components/AppHeader/AppHeader.tsx +172 -0
  301. package/src/components/AppHeader/index.ts +1 -0
  302. package/src/components/Avatar/Avatar.tsx +14 -4
  303. package/src/components/Badge/Badge.tsx +12 -3
  304. package/src/components/Button/Button.tsx +30 -38
  305. package/src/components/ButtonGroup/ButtonGroup.tsx +13 -10
  306. package/src/components/Card/Card.tsx +29 -57
  307. package/src/components/CategoryStrip/CategoryStrip.tsx +41 -42
  308. package/src/components/Checkbox/Checkbox.tsx +36 -45
  309. package/src/components/Chip/Chip.tsx +41 -48
  310. package/src/components/ConfirmDialog/ConfirmDialog.tsx +2 -2
  311. package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +4 -2
  312. package/src/components/CurrencyInput/CurrencyInput.tsx +12 -10
  313. package/src/components/DetailRow/DetailRow.tsx +9 -7
  314. package/src/components/EmptyState/EmptyState.tsx +4 -3
  315. package/src/components/ErrorBoundary/ErrorBoundary.tsx +153 -0
  316. package/src/components/ErrorBoundary/index.ts +1 -0
  317. package/src/components/Form/Form.tsx +149 -0
  318. package/src/components/Form/index.ts +1 -0
  319. package/src/components/HolographicCard/HolographicCard.tsx +315 -0
  320. package/src/components/HolographicCard/index.ts +1 -0
  321. package/src/components/IconButton/IconButton.tsx +23 -29
  322. package/src/components/ImageViewer/ImageViewer.tsx +290 -0
  323. package/src/components/ImageViewer/index.ts +1 -0
  324. package/src/components/Input/Input.tsx +27 -31
  325. package/src/components/LabelValue/LabelValue.tsx +6 -4
  326. package/src/components/ListGroup/ListGroup.tsx +145 -0
  327. package/src/components/ListGroup/index.ts +1 -0
  328. package/src/components/ListItem/ListItem.tsx +78 -76
  329. package/src/components/MediaCard/MediaCard.tsx +15 -7
  330. package/src/components/MenuGroup/MenuGroup.tsx +145 -0
  331. package/src/components/MenuGroup/index.ts +1 -0
  332. package/src/components/MenuItem/MenuItem.tsx +16 -33
  333. package/src/components/MonthPicker/MonthPicker.tsx +41 -15
  334. package/src/components/MonthPicker/index.ts +1 -1
  335. package/src/components/PagerDots/PagerDots.tsx +200 -0
  336. package/src/components/PagerDots/index.ts +1 -0
  337. package/src/components/Pressable/Pressable.tsx +19 -35
  338. package/src/components/PricingCard/PricingCard.tsx +220 -0
  339. package/src/components/PricingCard/index.ts +1 -0
  340. package/src/components/RadioGroup/RadioGroup.tsx +23 -39
  341. package/src/components/RetrayProvider/RetrayProvider.tsx +59 -0
  342. package/src/components/RetrayProvider/index.ts +1 -0
  343. package/src/components/Select/Select.tsx +6 -6
  344. package/src/components/SelectableGrid/SelectableGrid.tsx +205 -0
  345. package/src/components/SelectableGrid/index.ts +1 -0
  346. package/src/components/Separator/Separator.tsx +1 -3
  347. package/src/components/Sheet/Sheet.tsx +146 -18
  348. package/src/components/Skeleton/Skeleton.tsx +143 -2
  349. package/src/components/Slider/Slider.tsx +2 -2
  350. package/src/components/Spinner/Spinner.tsx +18 -3
  351. package/src/components/Switch/Switch.tsx +44 -49
  352. package/src/components/TabBar/TabBar.tsx +169 -0
  353. package/src/components/TabBar/index.ts +1 -0
  354. package/src/components/Tabs/Tabs.tsx +45 -44
  355. package/src/components/Text/Text.tsx +5 -1
  356. package/src/components/Textarea/Textarea.tsx +18 -14
  357. package/src/components/Toast/Toast.tsx +6 -6
  358. package/src/components/Toggle/Toggle.tsx +80 -72
  359. package/src/components/VirtualList/VirtualList.tsx +60 -0
  360. package/src/components/VirtualList/index.ts +1 -0
  361. package/src/fonts.ts +41 -20
  362. package/src/index.ts +28 -3
  363. package/src/theme/colors.ts +53 -39
  364. package/src/theme/types.ts +3 -0
  365. package/src/tokens.ts +49 -39
  366. package/src/utils/animations.ts +29 -1
  367. package/src/utils/fontGuard.ts +34 -0
  368. package/src/utils/haptics.ts +211 -9
  369. package/src/utils/icons.ts +47 -20
  370. package/src/utils/pressable.ts +66 -0
  371. package/src/utils/usePressScale.ts +2 -0
  372. package/src/assets/fonts/Poppins-Black.ttf +0 -0
  373. package/src/assets/fonts/Poppins-BlackItalic.ttf +0 -0
  374. package/src/assets/fonts/Poppins-Bold.ttf +0 -0
  375. package/src/assets/fonts/Poppins-BoldItalic.ttf +0 -0
  376. package/src/assets/fonts/Poppins-ExtraBold.ttf +0 -0
  377. package/src/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
  378. package/src/assets/fonts/Poppins-ExtraLight.ttf +0 -0
  379. package/src/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
  380. package/src/assets/fonts/Poppins-Italic.ttf +0 -0
  381. package/src/assets/fonts/Poppins-Light.ttf +0 -0
  382. package/src/assets/fonts/Poppins-LightItalic.ttf +0 -0
  383. package/src/assets/fonts/Poppins-Medium.ttf +0 -0
  384. package/src/assets/fonts/Poppins-MediumItalic.ttf +0 -0
  385. package/src/assets/fonts/Poppins-Regular.ttf +0 -0
  386. package/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
  387. package/src/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
  388. package/src/assets/fonts/Poppins-Thin.ttf +0 -0
  389. package/src/assets/fonts/Poppins-ThinItalic.ttf +0 -0
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ import { useImage } from '@shopify/react-native-skia';
4
+
5
+ /** Available foil color preset names */
6
+ type FoilPreset = 'rainbow' | 'gold' | 'silver' | 'cosmic' | 'emerald' | 'rose' | 'ocean' | 'fire' | 'aurora' | 'neon';
7
+ /** Foil color presets — each is an array of RGBA colors for the gradient */
8
+ declare const FOIL_PRESETS: Record<FoilPreset, string[]>;
9
+ interface HolographicCardProps {
10
+ /** Card art — `require()` asset or `{ uri }`. Omitted = gradient-only foil surface. */
11
+ source?: Parameters<typeof useImage>[0];
12
+ /** Card width (dp). Defaults to 300. */
13
+ width?: number;
14
+ /** Card height (dp). Defaults to `width * 1.4` (trading-card ratio). */
15
+ height?: number;
16
+ /** Corner radius (dp). Defaults to `RADIUS.md`. */
17
+ borderRadius?: number;
18
+ /** React to device motion (gyroscope) for parallax tilt + sheen. Defaults to true. */
19
+ enableTilt?: boolean;
20
+ /** Strength of the foil sheen, 0–1. Defaults to 1. */
21
+ intensity?: number;
22
+ /** Called when the card is pressed. */
23
+ onPress?: () => void;
24
+ style?: ViewStyle;
25
+ /** Foil color preset. Defaults to 'rainbow'. Ignored if `foilColors` is provided. */
26
+ foilPreset?: FoilPreset;
27
+ /** Custom foil gradient colors (array of RGBA strings). Overrides `foilPreset`. */
28
+ foilColors?: string[];
29
+ /** Maximum tilt angle in degrees (0–45). Defaults to 10. */
30
+ maxTiltDegrees?: number;
31
+ /** Sensitivity of tilt to device motion (0.1–2). Higher = more responsive. Defaults to 1. */
32
+ tiltSensitivity?: number;
33
+ /** How far the sheen moves relative to tilt (0–1). Defaults to 0.6. */
34
+ sheenSpread?: number;
35
+ /** Animation duration for tilt smoothing in ms. Defaults to 80. */
36
+ tiltAnimationDuration?: number;
37
+ /** Perspective depth for 3D effect (200–2000). Defaults to 800. */
38
+ perspective?: number;
39
+ /** Blend mode for the foil overlay. Defaults to 'plus'. */
40
+ blendMode?: 'plus' | 'screen' | 'overlay' | 'softLight' | 'hardLight';
41
+ }
42
+ /**
43
+ * Holographic / foil trading-card surface (Pokémon-TCG style). Renders the art
44
+ * on a Skia canvas with an animated rainbow sheen, and tilts in 3D toward device
45
+ * motion. The sheen position tracks the tilt so the foil "catches the light".
46
+ *
47
+ * Deep-import only — keeps Skia out of the main bundle:
48
+ * `import { HolographicCard } from '@retray-dev/ui-kit/HolographicCard'`
49
+ *
50
+ * Requires the optional peers `@shopify/react-native-skia` and (for tilt)
51
+ * `expo-sensors`. Without `expo-sensors` the card renders with a static sheen.
52
+ */
53
+ declare function HolographicCard({ source, width, height, borderRadius, enableTilt, intensity, onPress, style, foilPreset, foilColors, maxTiltDegrees, tiltSensitivity, sheenSpread, tiltAnimationDuration, perspective, blendMode, }: HolographicCardProps): React.JSX.Element;
54
+
55
+ export { FOIL_PRESETS, type FoilPreset, HolographicCard, type HolographicCardProps };
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ import { useImage } from '@shopify/react-native-skia';
4
+
5
+ /** Available foil color preset names */
6
+ type FoilPreset = 'rainbow' | 'gold' | 'silver' | 'cosmic' | 'emerald' | 'rose' | 'ocean' | 'fire' | 'aurora' | 'neon';
7
+ /** Foil color presets — each is an array of RGBA colors for the gradient */
8
+ declare const FOIL_PRESETS: Record<FoilPreset, string[]>;
9
+ interface HolographicCardProps {
10
+ /** Card art — `require()` asset or `{ uri }`. Omitted = gradient-only foil surface. */
11
+ source?: Parameters<typeof useImage>[0];
12
+ /** Card width (dp). Defaults to 300. */
13
+ width?: number;
14
+ /** Card height (dp). Defaults to `width * 1.4` (trading-card ratio). */
15
+ height?: number;
16
+ /** Corner radius (dp). Defaults to `RADIUS.md`. */
17
+ borderRadius?: number;
18
+ /** React to device motion (gyroscope) for parallax tilt + sheen. Defaults to true. */
19
+ enableTilt?: boolean;
20
+ /** Strength of the foil sheen, 0–1. Defaults to 1. */
21
+ intensity?: number;
22
+ /** Called when the card is pressed. */
23
+ onPress?: () => void;
24
+ style?: ViewStyle;
25
+ /** Foil color preset. Defaults to 'rainbow'. Ignored if `foilColors` is provided. */
26
+ foilPreset?: FoilPreset;
27
+ /** Custom foil gradient colors (array of RGBA strings). Overrides `foilPreset`. */
28
+ foilColors?: string[];
29
+ /** Maximum tilt angle in degrees (0–45). Defaults to 10. */
30
+ maxTiltDegrees?: number;
31
+ /** Sensitivity of tilt to device motion (0.1–2). Higher = more responsive. Defaults to 1. */
32
+ tiltSensitivity?: number;
33
+ /** How far the sheen moves relative to tilt (0–1). Defaults to 0.6. */
34
+ sheenSpread?: number;
35
+ /** Animation duration for tilt smoothing in ms. Defaults to 80. */
36
+ tiltAnimationDuration?: number;
37
+ /** Perspective depth for 3D effect (200–2000). Defaults to 800. */
38
+ perspective?: number;
39
+ /** Blend mode for the foil overlay. Defaults to 'plus'. */
40
+ blendMode?: 'plus' | 'screen' | 'overlay' | 'softLight' | 'hardLight';
41
+ }
42
+ /**
43
+ * Holographic / foil trading-card surface (Pokémon-TCG style). Renders the art
44
+ * on a Skia canvas with an animated rainbow sheen, and tilts in 3D toward device
45
+ * motion. The sheen position tracks the tilt so the foil "catches the light".
46
+ *
47
+ * Deep-import only — keeps Skia out of the main bundle:
48
+ * `import { HolographicCard } from '@retray-dev/ui-kit/HolographicCard'`
49
+ *
50
+ * Requires the optional peers `@shopify/react-native-skia` and (for tilt)
51
+ * `expo-sensors`. Without `expo-sensors` the card renders with a static sheen.
52
+ */
53
+ declare function HolographicCard({ source, width, height, borderRadius, enableTilt, intensity, onPress, style, foilPreset, foilColors, maxTiltDegrees, tiltSensitivity, sheenSpread, tiltAnimationDuration, perspective, blendMode, }: HolographicCardProps): React.JSX.Element;
54
+
55
+ export { FOIL_PRESETS, type FoilPreset, HolographicCard, type HolographicCardProps };
@@ -0,0 +1,316 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var reactNative = require('react-native');
5
+ var reactNativeSkia = require('@shopify/react-native-skia');
6
+ var Animated = require('react-native-reanimated');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var React__default = /*#__PURE__*/_interopDefault(React);
11
+ var Animated__default = /*#__PURE__*/_interopDefault(Animated);
12
+
13
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
+ }) : x)(function(x) {
16
+ if (typeof require !== "undefined") return require.apply(this, arguments);
17
+ throw Error('Dynamic require of "' + x + '" is not supported');
18
+ });
19
+ var SPRINGS = {
20
+ /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
21
+ pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
22
+ pressOut: { stiffness: 280, damping: 22, mass: 0.8 }};
23
+ ({
24
+ /** Material-style ease-out — natural deceleration for state changes. */
25
+ standard: Animated.Easing.bezier(0.2, 0, 0, 1),
26
+ /** Strong ease-out for expanding surfaces (Accordion open). */
27
+ expand: Animated.Easing.bezier(0.23, 1, 0.32, 1),
28
+ /** Quick ease-in for collapsing. */
29
+ collapse: Animated.Easing.in(Animated.Easing.ease)
30
+ });
31
+ var PRESS_SCALE = {
32
+ button: 0.95,
33
+ card: 0.98};
34
+ function useHover() {
35
+ const [hovered, setHovered] = React.useState(false);
36
+ const onMouseEnter = React.useCallback(() => setHovered(true), []);
37
+ const onMouseLeave = React.useCallback(() => setHovered(false), []);
38
+ if (reactNative.Platform.OS !== "web") {
39
+ return { hovered: false, hoverHandlers: {} };
40
+ }
41
+ return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
42
+ }
43
+
44
+ // src/utils/usePressScale.ts
45
+ function usePressScale({
46
+ pressScale = PRESS_SCALE.button,
47
+ hoverScale = 1.02,
48
+ pressInSpring = SPRINGS.pressIn,
49
+ pressOutSpring = SPRINGS.pressOut,
50
+ disabled = false
51
+ } = {}) {
52
+ const scale = Animated.useSharedValue(1);
53
+ const { hovered, hoverHandlers } = useHover();
54
+ const onPressIn = React.useCallback(() => {
55
+ if (disabled) return;
56
+ scale.value = Animated.withSpring(pressScale, pressInSpring);
57
+ }, [disabled, pressScale, pressInSpring, scale]);
58
+ const onPressOut = React.useCallback(() => {
59
+ if (disabled) return;
60
+ scale.value = Animated.withSpring(1, pressOutSpring);
61
+ }, [disabled, pressOutSpring, scale]);
62
+ const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
63
+ const animatedStyle = Animated.useAnimatedStyle(() => ({
64
+ transform: [
65
+ { scale: scale.value * (hoverActive ? hoverScale : 1) }
66
+ ]
67
+ }));
68
+ return {
69
+ animatedStyle,
70
+ onPressIn,
71
+ onPressOut,
72
+ hoverHandlers
73
+ };
74
+ }
75
+ var _haptics = null;
76
+ var _hapticsLoaded = false;
77
+ async function getHaptics() {
78
+ if (reactNative.Platform.OS === "web") return null;
79
+ if (!_hapticsLoaded) {
80
+ _hapticsLoaded = true;
81
+ try {
82
+ _haptics = await import('expo-haptics');
83
+ } catch {
84
+ _haptics = null;
85
+ }
86
+ }
87
+ return _haptics;
88
+ }
89
+ var _pulsar = null;
90
+ var _pulsarChecked = false;
91
+ var _pulsarAvailable = false;
92
+ function isPulsarNativeRegistered() {
93
+ try {
94
+ const g = globalThis;
95
+ if (typeof g.__turboModuleProxy === "function") {
96
+ return g.__turboModuleProxy("RNPulsar") != null;
97
+ }
98
+ return reactNative.NativeModules?.RNPulsar != null;
99
+ } catch {
100
+ return false;
101
+ }
102
+ }
103
+ function getPulsar() {
104
+ if (reactNative.Platform.OS === "web") return null;
105
+ if (!_pulsarChecked) {
106
+ _pulsarChecked = true;
107
+ try {
108
+ if (isPulsarNativeRegistered()) {
109
+ _pulsar = __require("react-native-pulsar");
110
+ _pulsarAvailable = true;
111
+ }
112
+ } catch {
113
+ _pulsar = null;
114
+ _pulsarAvailable = false;
115
+ }
116
+ }
117
+ return _pulsarAvailable ? _pulsar : null;
118
+ }
119
+ function impactLight() {
120
+ if (reactNative.Platform.OS === "web") return;
121
+ getHaptics().then((h) => {
122
+ if (h) {
123
+ h.impactAsync(h.ImpactFeedbackStyle.Light);
124
+ } else {
125
+ getPulsar()?.Presets.System.impactLight();
126
+ }
127
+ });
128
+ }
129
+
130
+ // src/tokens.ts
131
+ var RADIUS = {
132
+ md: 14};
133
+
134
+ // src/components/HolographicCard/HolographicCard.tsx
135
+ var FOIL_PRESETS = {
136
+ // Classic holographic rainbow
137
+ rainbow: [
138
+ "rgba(255, 0, 128, 0.45)",
139
+ "rgba(255, 200, 0, 0.40)",
140
+ "rgba(0, 255, 170, 0.40)",
141
+ "rgba(0, 170, 255, 0.45)",
142
+ "rgba(180, 0, 255, 0.45)"
143
+ ],
144
+ // Premium gold foil
145
+ gold: [
146
+ "rgba(255, 215, 0, 0.50)",
147
+ "rgba(255, 180, 0, 0.45)",
148
+ "rgba(218, 165, 32, 0.40)",
149
+ "rgba(255, 223, 128, 0.50)",
150
+ "rgba(184, 134, 11, 0.45)"
151
+ ],
152
+ // Chrome silver foil
153
+ silver: [
154
+ "rgba(192, 192, 192, 0.50)",
155
+ "rgba(220, 220, 220, 0.45)",
156
+ "rgba(169, 169, 169, 0.40)",
157
+ "rgba(240, 240, 240, 0.50)",
158
+ "rgba(128, 128, 128, 0.45)"
159
+ ],
160
+ // Deep space cosmic
161
+ cosmic: [
162
+ "rgba(75, 0, 130, 0.50)",
163
+ "rgba(138, 43, 226, 0.45)",
164
+ "rgba(255, 20, 147, 0.40)",
165
+ "rgba(0, 191, 255, 0.45)",
166
+ "rgba(148, 0, 211, 0.50)"
167
+ ],
168
+ // Emerald green luxury
169
+ emerald: [
170
+ "rgba(0, 201, 87, 0.50)",
171
+ "rgba(46, 139, 87, 0.45)",
172
+ "rgba(0, 255, 127, 0.40)",
173
+ "rgba(60, 179, 113, 0.45)",
174
+ "rgba(0, 128, 0, 0.50)"
175
+ ],
176
+ // Rose gold / pink
177
+ rose: [
178
+ "rgba(255, 105, 180, 0.50)",
179
+ "rgba(255, 182, 193, 0.45)",
180
+ "rgba(219, 112, 147, 0.40)",
181
+ "rgba(255, 20, 147, 0.45)",
182
+ "rgba(199, 21, 133, 0.50)"
183
+ ],
184
+ // Deep ocean blue
185
+ ocean: [
186
+ "rgba(0, 119, 190, 0.50)",
187
+ "rgba(0, 180, 216, 0.45)",
188
+ "rgba(72, 202, 228, 0.40)",
189
+ "rgba(144, 224, 239, 0.45)",
190
+ "rgba(0, 150, 199, 0.50)"
191
+ ],
192
+ // Hot fire gradient
193
+ fire: [
194
+ "rgba(255, 69, 0, 0.50)",
195
+ "rgba(255, 140, 0, 0.45)",
196
+ "rgba(255, 215, 0, 0.40)",
197
+ "rgba(255, 99, 71, 0.45)",
198
+ "rgba(220, 20, 60, 0.50)"
199
+ ],
200
+ // Aurora borealis
201
+ aurora: [
202
+ "rgba(0, 255, 127, 0.45)",
203
+ "rgba(127, 255, 212, 0.40)",
204
+ "rgba(0, 206, 209, 0.45)",
205
+ "rgba(138, 43, 226, 0.40)",
206
+ "rgba(255, 20, 147, 0.45)"
207
+ ],
208
+ // Neon cyberpunk
209
+ neon: [
210
+ "rgba(255, 0, 255, 0.55)",
211
+ "rgba(0, 255, 255, 0.50)",
212
+ "rgba(255, 255, 0, 0.45)",
213
+ "rgba(0, 255, 0, 0.50)",
214
+ "rgba(255, 0, 128, 0.55)"
215
+ ]
216
+ };
217
+ var DEFAULT_FOIL_COLORS = FOIL_PRESETS.rainbow;
218
+ var DEFAULT_TILT_DEG = 10;
219
+ var DEFAULT_NORM_FACTOR = Math.PI / 6;
220
+ function HolographicCard({
221
+ source,
222
+ width = 300,
223
+ height,
224
+ borderRadius = RADIUS.md,
225
+ enableTilt = true,
226
+ intensity = 1,
227
+ onPress,
228
+ style,
229
+ // New customization props
230
+ foilPreset = "rainbow",
231
+ foilColors,
232
+ maxTiltDegrees = DEFAULT_TILT_DEG,
233
+ tiltSensitivity = 1,
234
+ sheenSpread = 0.6,
235
+ tiltAnimationDuration = 80,
236
+ perspective = 800,
237
+ blendMode = "plus"
238
+ }) {
239
+ const h = height ?? width * 1.4;
240
+ const image = reactNativeSkia.useImage(source ?? null);
241
+ const clampedTilt = Math.max(0, Math.min(45, maxTiltDegrees));
242
+ const clampedSensitivity = Math.max(0.1, Math.min(2, tiltSensitivity));
243
+ const clampedSpread = Math.max(0, Math.min(1, sheenSpread));
244
+ const clampedPerspective = Math.max(200, Math.min(2e3, perspective));
245
+ const resolvedFoilColors = React.useMemo(() => {
246
+ if (foilColors && foilColors.length >= 2) return foilColors;
247
+ return FOIL_PRESETS[foilPreset] ?? DEFAULT_FOIL_COLORS;
248
+ }, [foilColors, foilPreset]);
249
+ const normFactor = DEFAULT_NORM_FACTOR / clampedSensitivity;
250
+ const tiltX = Animated.useSharedValue(0);
251
+ const tiltY = Animated.useSharedValue(0);
252
+ React.useEffect(() => {
253
+ if (!enableTilt || reactNative.Platform.OS === "web") return;
254
+ let remove;
255
+ let cancelled = false;
256
+ import('expo-sensors').then(({ DeviceMotion }) => {
257
+ if (cancelled) return;
258
+ DeviceMotion.setUpdateInterval(16);
259
+ const sub = DeviceMotion.addListener(({ rotation }) => {
260
+ if (!rotation) return;
261
+ const nx = Math.max(-1, Math.min(rotation.gamma / normFactor, 1));
262
+ const ny = Math.max(-1, Math.min(rotation.beta / normFactor, 1));
263
+ tiltX.value = Animated.withTiming(nx, { duration: tiltAnimationDuration });
264
+ tiltY.value = Animated.withTiming(ny, { duration: tiltAnimationDuration });
265
+ });
266
+ remove = () => sub.remove();
267
+ }).catch(() => {
268
+ });
269
+ return () => {
270
+ cancelled = true;
271
+ remove?.();
272
+ };
273
+ }, [enableTilt, tiltX, tiltY, normFactor, tiltAnimationDuration]);
274
+ const { animatedStyle: pressStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
275
+ pressScale: PRESS_SCALE.card,
276
+ disabled: !onPress
277
+ });
278
+ const tiltStyle = Animated.useAnimatedStyle(() => ({
279
+ transform: [
280
+ { perspective: clampedPerspective },
281
+ { rotateX: `${-tiltY.value * clampedTilt}deg` },
282
+ { rotateY: `${tiltX.value * clampedTilt}deg` }
283
+ ]
284
+ }));
285
+ const start = Animated.useDerivedValue(() => reactNativeSkia.vec(width * (0.5 - tiltX.value * clampedSpread), h * (0.5 - tiltY.value * clampedSpread)));
286
+ const end = Animated.useDerivedValue(() => reactNativeSkia.vec(width * (0.5 + tiltX.value * clampedSpread), h * (0.5 + tiltY.value * clampedSpread)));
287
+ const rrct = { x: 0, y: 0, width, height: h };
288
+ const canvas = /* @__PURE__ */ React__default.default.createElement(reactNativeSkia.Canvas, { style: { width, height: h } }, image ? /* @__PURE__ */ React__default.default.createElement(reactNativeSkia.Group, { clip: { rect: rrct, rx: borderRadius, ry: borderRadius } }, /* @__PURE__ */ React__default.default.createElement(reactNativeSkia.Image, { image, x: 0, y: 0, width, height: h, fit: "cover" })) : null, /* @__PURE__ */ React__default.default.createElement(reactNativeSkia.RoundedRect, { x: 0, y: 0, width, height: h, r: borderRadius, opacity: intensity, blendMode }, /* @__PURE__ */ React__default.default.createElement(reactNativeSkia.LinearGradient, { start, end, colors: resolvedFoilColors })));
289
+ const card = /* @__PURE__ */ React__default.default.createElement(Animated__default.default.View, { style: [{ width, height: h }, tiltStyle, style] }, canvas);
290
+ if (!onPress) return card;
291
+ return /* @__PURE__ */ React__default.default.createElement(Animated__default.default.View, { style: pressStyle }, /* @__PURE__ */ React__default.default.createElement(
292
+ reactNative.TouchableOpacity,
293
+ {
294
+ onPress: () => {
295
+ impactLight();
296
+ onPress();
297
+ },
298
+ onPressIn,
299
+ onPressOut,
300
+ activeOpacity: 1,
301
+ touchSoundDisabled: true,
302
+ accessibilityRole: "imagebutton",
303
+ ...hoverHandlers,
304
+ style: styles.touch
305
+ },
306
+ card
307
+ ));
308
+ }
309
+ var styles = reactNative.StyleSheet.create({
310
+ touch: {
311
+ alignSelf: "flex-start"
312
+ }
313
+ });
314
+
315
+ exports.FOIL_PRESETS = FOIL_PRESETS;
316
+ exports.HolographicCard = HolographicCard;
@@ -0,0 +1,191 @@
1
+ import { usePressScale } from './chunk-YNROWHQJ.mjs';
2
+ import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
+ import { PRESS_SCALE } from './chunk-DVK4G2GT.mjs';
4
+ import { RADIUS } from './chunk-QY3X2UYR.mjs';
5
+ import './chunk-Y6FXYEAI.mjs';
6
+ import React, { useMemo, useEffect } from 'react';
7
+ import { StyleSheet, Platform, TouchableOpacity } from 'react-native';
8
+ import { useImage, vec, Canvas, Group, Image, RoundedRect, LinearGradient } from '@shopify/react-native-skia';
9
+ import Animated, { useSharedValue, withTiming, useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
10
+
11
+ var FOIL_PRESETS = {
12
+ // Classic holographic rainbow
13
+ rainbow: [
14
+ "rgba(255, 0, 128, 0.45)",
15
+ "rgba(255, 200, 0, 0.40)",
16
+ "rgba(0, 255, 170, 0.40)",
17
+ "rgba(0, 170, 255, 0.45)",
18
+ "rgba(180, 0, 255, 0.45)"
19
+ ],
20
+ // Premium gold foil
21
+ gold: [
22
+ "rgba(255, 215, 0, 0.50)",
23
+ "rgba(255, 180, 0, 0.45)",
24
+ "rgba(218, 165, 32, 0.40)",
25
+ "rgba(255, 223, 128, 0.50)",
26
+ "rgba(184, 134, 11, 0.45)"
27
+ ],
28
+ // Chrome silver foil
29
+ silver: [
30
+ "rgba(192, 192, 192, 0.50)",
31
+ "rgba(220, 220, 220, 0.45)",
32
+ "rgba(169, 169, 169, 0.40)",
33
+ "rgba(240, 240, 240, 0.50)",
34
+ "rgba(128, 128, 128, 0.45)"
35
+ ],
36
+ // Deep space cosmic
37
+ cosmic: [
38
+ "rgba(75, 0, 130, 0.50)",
39
+ "rgba(138, 43, 226, 0.45)",
40
+ "rgba(255, 20, 147, 0.40)",
41
+ "rgba(0, 191, 255, 0.45)",
42
+ "rgba(148, 0, 211, 0.50)"
43
+ ],
44
+ // Emerald green luxury
45
+ emerald: [
46
+ "rgba(0, 201, 87, 0.50)",
47
+ "rgba(46, 139, 87, 0.45)",
48
+ "rgba(0, 255, 127, 0.40)",
49
+ "rgba(60, 179, 113, 0.45)",
50
+ "rgba(0, 128, 0, 0.50)"
51
+ ],
52
+ // Rose gold / pink
53
+ rose: [
54
+ "rgba(255, 105, 180, 0.50)",
55
+ "rgba(255, 182, 193, 0.45)",
56
+ "rgba(219, 112, 147, 0.40)",
57
+ "rgba(255, 20, 147, 0.45)",
58
+ "rgba(199, 21, 133, 0.50)"
59
+ ],
60
+ // Deep ocean blue
61
+ ocean: [
62
+ "rgba(0, 119, 190, 0.50)",
63
+ "rgba(0, 180, 216, 0.45)",
64
+ "rgba(72, 202, 228, 0.40)",
65
+ "rgba(144, 224, 239, 0.45)",
66
+ "rgba(0, 150, 199, 0.50)"
67
+ ],
68
+ // Hot fire gradient
69
+ fire: [
70
+ "rgba(255, 69, 0, 0.50)",
71
+ "rgba(255, 140, 0, 0.45)",
72
+ "rgba(255, 215, 0, 0.40)",
73
+ "rgba(255, 99, 71, 0.45)",
74
+ "rgba(220, 20, 60, 0.50)"
75
+ ],
76
+ // Aurora borealis
77
+ aurora: [
78
+ "rgba(0, 255, 127, 0.45)",
79
+ "rgba(127, 255, 212, 0.40)",
80
+ "rgba(0, 206, 209, 0.45)",
81
+ "rgba(138, 43, 226, 0.40)",
82
+ "rgba(255, 20, 147, 0.45)"
83
+ ],
84
+ // Neon cyberpunk
85
+ neon: [
86
+ "rgba(255, 0, 255, 0.55)",
87
+ "rgba(0, 255, 255, 0.50)",
88
+ "rgba(255, 255, 0, 0.45)",
89
+ "rgba(0, 255, 0, 0.50)",
90
+ "rgba(255, 0, 128, 0.55)"
91
+ ]
92
+ };
93
+ var DEFAULT_FOIL_COLORS = FOIL_PRESETS.rainbow;
94
+ var DEFAULT_TILT_DEG = 10;
95
+ var DEFAULT_NORM_FACTOR = Math.PI / 6;
96
+ function HolographicCard({
97
+ source,
98
+ width = 300,
99
+ height,
100
+ borderRadius = RADIUS.md,
101
+ enableTilt = true,
102
+ intensity = 1,
103
+ onPress,
104
+ style,
105
+ // New customization props
106
+ foilPreset = "rainbow",
107
+ foilColors,
108
+ maxTiltDegrees = DEFAULT_TILT_DEG,
109
+ tiltSensitivity = 1,
110
+ sheenSpread = 0.6,
111
+ tiltAnimationDuration = 80,
112
+ perspective = 800,
113
+ blendMode = "plus"
114
+ }) {
115
+ const h = height ?? width * 1.4;
116
+ const image = useImage(source ?? null);
117
+ const clampedTilt = Math.max(0, Math.min(45, maxTiltDegrees));
118
+ const clampedSensitivity = Math.max(0.1, Math.min(2, tiltSensitivity));
119
+ const clampedSpread = Math.max(0, Math.min(1, sheenSpread));
120
+ const clampedPerspective = Math.max(200, Math.min(2e3, perspective));
121
+ const resolvedFoilColors = useMemo(() => {
122
+ if (foilColors && foilColors.length >= 2) return foilColors;
123
+ return FOIL_PRESETS[foilPreset] ?? DEFAULT_FOIL_COLORS;
124
+ }, [foilColors, foilPreset]);
125
+ const normFactor = DEFAULT_NORM_FACTOR / clampedSensitivity;
126
+ const tiltX = useSharedValue(0);
127
+ const tiltY = useSharedValue(0);
128
+ useEffect(() => {
129
+ if (!enableTilt || Platform.OS === "web") return;
130
+ let remove;
131
+ let cancelled = false;
132
+ import('expo-sensors').then(({ DeviceMotion }) => {
133
+ if (cancelled) return;
134
+ DeviceMotion.setUpdateInterval(16);
135
+ const sub = DeviceMotion.addListener(({ rotation }) => {
136
+ if (!rotation) return;
137
+ const nx = Math.max(-1, Math.min(rotation.gamma / normFactor, 1));
138
+ const ny = Math.max(-1, Math.min(rotation.beta / normFactor, 1));
139
+ tiltX.value = withTiming(nx, { duration: tiltAnimationDuration });
140
+ tiltY.value = withTiming(ny, { duration: tiltAnimationDuration });
141
+ });
142
+ remove = () => sub.remove();
143
+ }).catch(() => {
144
+ });
145
+ return () => {
146
+ cancelled = true;
147
+ remove?.();
148
+ };
149
+ }, [enableTilt, tiltX, tiltY, normFactor, tiltAnimationDuration]);
150
+ const { animatedStyle: pressStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
151
+ pressScale: PRESS_SCALE.card,
152
+ disabled: !onPress
153
+ });
154
+ const tiltStyle = useAnimatedStyle(() => ({
155
+ transform: [
156
+ { perspective: clampedPerspective },
157
+ { rotateX: `${-tiltY.value * clampedTilt}deg` },
158
+ { rotateY: `${tiltX.value * clampedTilt}deg` }
159
+ ]
160
+ }));
161
+ const start = useDerivedValue(() => vec(width * (0.5 - tiltX.value * clampedSpread), h * (0.5 - tiltY.value * clampedSpread)));
162
+ const end = useDerivedValue(() => vec(width * (0.5 + tiltX.value * clampedSpread), h * (0.5 + tiltY.value * clampedSpread)));
163
+ const rrct = { x: 0, y: 0, width, height: h };
164
+ const canvas = /* @__PURE__ */ React.createElement(Canvas, { style: { width, height: h } }, image ? /* @__PURE__ */ React.createElement(Group, { clip: { rect: rrct, rx: borderRadius, ry: borderRadius } }, /* @__PURE__ */ React.createElement(Image, { image, x: 0, y: 0, width, height: h, fit: "cover" })) : null, /* @__PURE__ */ React.createElement(RoundedRect, { x: 0, y: 0, width, height: h, r: borderRadius, opacity: intensity, blendMode }, /* @__PURE__ */ React.createElement(LinearGradient, { start, end, colors: resolvedFoilColors })));
165
+ const card = /* @__PURE__ */ React.createElement(Animated.View, { style: [{ width, height: h }, tiltStyle, style] }, canvas);
166
+ if (!onPress) return card;
167
+ return /* @__PURE__ */ React.createElement(Animated.View, { style: pressStyle }, /* @__PURE__ */ React.createElement(
168
+ TouchableOpacity,
169
+ {
170
+ onPress: () => {
171
+ impactLight();
172
+ onPress();
173
+ },
174
+ onPressIn,
175
+ onPressOut,
176
+ activeOpacity: 1,
177
+ touchSoundDisabled: true,
178
+ accessibilityRole: "imagebutton",
179
+ ...hoverHandlers,
180
+ style: styles.touch
181
+ },
182
+ card
183
+ ));
184
+ }
185
+ var styles = StyleSheet.create({
186
+ touch: {
187
+ alignSelf: "flex-start"
188
+ }
189
+ });
190
+
191
+ export { FOIL_PRESETS, HolographicCard };
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+
4
+ type IconButtonVariant = 'primary' | 'secondary' | 'outline' | 'text' | 'destructive';
5
+ type IconButtonSize = 'sm' | 'md' | 'lg';
6
+ interface IconButtonProps {
7
+ iconName?: string;
8
+ icon?: React.ReactNode;
9
+ iconColor?: string;
10
+ variant?: IconButtonVariant;
11
+ size?: IconButtonSize;
12
+ loading?: boolean;
13
+ /**
14
+ * Badge overlay. `true` shows a dot. A number shows a count (capped at 99).
15
+ * The dot/count appears top-right of the button.
16
+ */
17
+ badge?: boolean | number;
18
+ disabled?: boolean;
19
+ style?: ViewStyle;
20
+ onPress?: () => void;
21
+ accessibilityLabel?: string;
22
+ accessibilityHint?: string;
23
+ }
24
+ declare function IconButtonBase({ iconName, icon, iconColor, variant, size, loading, badge, disabled, style, onPress, accessibilityLabel, accessibilityHint, }: IconButtonProps): React.JSX.Element;
25
+ declare const IconButton: React.MemoExoticComponent<typeof IconButtonBase>;
26
+
27
+ export { IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant };
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+
4
+ type IconButtonVariant = 'primary' | 'secondary' | 'outline' | 'text' | 'destructive';
5
+ type IconButtonSize = 'sm' | 'md' | 'lg';
6
+ interface IconButtonProps {
7
+ iconName?: string;
8
+ icon?: React.ReactNode;
9
+ iconColor?: string;
10
+ variant?: IconButtonVariant;
11
+ size?: IconButtonSize;
12
+ loading?: boolean;
13
+ /**
14
+ * Badge overlay. `true` shows a dot. A number shows a count (capped at 99).
15
+ * The dot/count appears top-right of the button.
16
+ */
17
+ badge?: boolean | number;
18
+ disabled?: boolean;
19
+ style?: ViewStyle;
20
+ onPress?: () => void;
21
+ accessibilityLabel?: string;
22
+ accessibilityHint?: string;
23
+ }
24
+ declare function IconButtonBase({ iconName, icon, iconColor, variant, size, loading, badge, disabled, style, onPress, accessibilityLabel, accessibilityHint, }: IconButtonProps): React.JSX.Element;
25
+ declare const IconButton: React.MemoExoticComponent<typeof IconButtonBase>;
26
+
27
+ export { IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant };