@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
@@ -4,10 +4,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
4
4
  import { useTheme } from '../../theme'
5
5
  import { s, vs, ms } from '../../utils/scaling'
6
6
 
7
- // Direct function API — no hook required
8
7
  export { sonnerToast as toast }
9
8
 
10
- // useToast — backward-compat wrapper
11
9
  export function useToast() {
12
10
  return {
13
11
  toast: sonnerToast,
@@ -15,7 +13,6 @@ export function useToast() {
15
13
  }
16
14
  }
17
15
 
18
- // ToastProvider — wraps children + renders the Toaster
19
16
  export function ToastProvider({ children }: { children: React.ReactNode }) {
20
17
  const { colorScheme } = useTheme()
21
18
  const insets = useSafeAreaInsets()
@@ -26,7 +23,10 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
26
23
  <Toaster
27
24
  theme={colorScheme}
28
25
  position="top-center"
29
- richColors={false}
26
+ // AUDIT FIX: was richColors={false} — all semantic variants (error, success,
27
+ // warning) were visually identical. richColors={true} restores correct
28
+ // semantic coloring so users immediately recognise severity from colour alone.
29
+ richColors={true}
30
30
  gap={vs(8)}
31
31
  offset={insets.top + vs(8)}
32
32
  visibleToasts={3}
@@ -40,11 +40,11 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
40
40
  paddingVertical: vs(10),
41
41
  },
42
42
  titleStyle: {
43
- fontFamily: 'Poppins-Medium',
43
+ fontFamily: 'Sohne-Medium',
44
44
  fontSize: ms(13),
45
45
  },
46
46
  descriptionStyle: {
47
- fontFamily: 'Poppins-Regular',
47
+ fontFamily: 'Sohne-Regular',
48
48
  fontSize: ms(12),
49
49
  opacity: 0.85,
50
50
  },
@@ -1,22 +1,52 @@
1
1
  import React from 'react'
2
- import { TouchableOpacity, StyleSheet, TouchableOpacityProps, ViewStyle, View } from 'react-native'
3
- import Animated, {
4
- useAnimatedStyle,
5
- interpolateColor,
6
- } from 'react-native-reanimated'
2
+ import { StyleSheet, ViewStyle, View, Text } from 'react-native'
3
+ import { EaseView } from 'react-native-ease'
7
4
  import { FontAwesome5 } from '@expo/vector-icons'
8
5
  import { selectionAsync as hapticSelection } from '../../utils/haptics'
9
6
  import { useTheme } from '../../theme'
10
7
  import { s, vs, ms } from '../../utils/scaling'
11
8
  import { renderIcon } from '../../utils/icons'
12
- import { usePressScale } from '../../utils/usePressScale'
13
- import { useColorTransition } from '../../utils/useColorTransition'
14
- import { PRESS_SCALE } from '../../utils/animations'
9
+ import { COLOR_TRANSITION } from '../../utils/animations'
10
+ import { PressableButton } from '../../utils/pressable'
11
+
12
+ interface ToggleIconProps {
13
+ pressed: boolean
14
+ iconName?: string
15
+ activeIconName?: string
16
+ icon?: React.ReactNode | ((pressed: boolean) => React.ReactNode)
17
+ activeIcon?: React.ReactNode | ((pressed: boolean) => React.ReactNode)
18
+ iconColor?: string
19
+ activeIconColor?: string
20
+ iconSize: number
21
+ primaryColor: string
22
+ mutedColor: string
23
+ }
24
+
25
+ function ToggleIcon({ pressed, iconName, activeIconName, icon, activeIcon, iconColor, activeIconColor, iconSize, primaryColor, mutedColor }: ToggleIconProps) {
26
+ const renderProp = (prop?: React.ReactNode | ((p: boolean) => React.ReactNode)) => {
27
+ if (!prop) return null
28
+ if (typeof prop === 'function') return (prop as (p: boolean) => React.ReactNode)(pressed)
29
+ return prop
30
+ }
31
+
32
+ if (pressed) {
33
+ if (activeIconName) return <>{renderIcon(activeIconName, iconSize, activeIconColor ?? primaryColor)}</>
34
+ const active = renderProp(activeIcon)
35
+ if (active) return <>{active}</>
36
+ return <FontAwesome5 name="check-circle" size={iconSize} color={primaryColor} />
37
+ }
38
+
39
+ if (iconName) return <>{renderIcon(iconName, iconSize, iconColor ?? mutedColor)}</>
40
+ const custom = renderProp(icon)
41
+ if (custom) return <>{custom}</>
42
+
43
+ return <FontAwesome5 name="circle" size={iconSize} color={mutedColor} />
44
+ }
15
45
 
16
46
  export type ToggleVariant = 'default' | 'outline'
17
47
  export type ToggleSize = 'sm' | 'md' | 'lg'
18
48
 
19
- export interface ToggleProps extends TouchableOpacityProps {
49
+ export interface ToggleProps {
20
50
  pressed?: boolean
21
51
  onPressedChange?: (pressed: boolean) => void
22
52
  variant?: ToggleVariant
@@ -40,6 +70,9 @@ export interface ToggleProps extends TouchableOpacityProps {
40
70
  iconColor?: string
41
71
  /** Override the resolved active icon color. Defaults to `primary`. */
42
72
  activeIconColor?: string
73
+ disabled?: boolean
74
+ style?: ViewStyle
75
+ accessibilityLabel?: string
43
76
  }
44
77
 
45
78
  const sizeStyles: Record<ToggleSize, ViewStyle> = {
@@ -65,88 +98,63 @@ export function Toggle({
65
98
  disabled,
66
99
  style,
67
100
  accessibilityLabel,
68
- ...props
69
101
  }: ToggleProps) {
70
102
  const { colors } = useTheme()
71
- const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
72
- pressScale: PRESS_SCALE.button,
73
- disabled,
74
- })
75
- const progress = useColorTransition(pressed)
76
103
 
77
104
  const inactiveBorder = variant === 'outline' ? colors.border : 'transparent'
78
105
 
79
- const surfaceStyle = useAnimatedStyle(() => ({
80
- borderColor: interpolateColor(progress.value, [0, 1], [inactiveBorder, colors.primary]),
81
- backgroundColor: interpolateColor(progress.value, [0, 1], ['transparent', colors.surfaceStrong]),
82
- }))
83
-
84
- const textStyle = useAnimatedStyle(() => ({
85
- color: interpolateColor(progress.value, [0, 1], [colors.foreground, colors.primary]),
86
- }))
87
-
88
106
  const iconSize = iconSizeMap[size]
89
107
 
90
- const LeftIcon = () => {
91
- const renderProp = (prop?: any) => {
92
- if (!prop) return null
93
- if (typeof prop === 'function') return prop(pressed)
94
- return prop
95
- }
96
-
97
- if (pressed) {
98
- if (activeIconName) return <>{renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary)}</>
99
- const active = renderProp(activeIcon)
100
- if (active) return <>{active}</>
101
- return <FontAwesome5 name="check-circle" size={iconSize} color={colors.primary} />
102
- }
103
-
104
- if (iconName) return <>{renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted)}</>
105
- const custom = renderProp(icon)
106
- if (custom) return <>{custom}</>
107
-
108
- return <FontAwesome5 name="circle" size={iconSize} color={colors.foregroundMuted} />
108
+ const handlePress = () => {
109
+ hapticSelection()
110
+ onPressedChange?.(!pressed)
109
111
  }
110
112
 
111
113
  return (
112
- <Animated.View
113
- style={[scaleStyle, disabled && styles.disabled, style]}
114
- {...hoverHandlers}
115
- >
116
- <TouchableOpacity
117
- onPress={() => {
118
- hapticSelection()
119
- onPressedChange?.(!pressed)
120
- }}
121
- onPressIn={onPressIn}
122
- onPressOut={onPressOut}
123
- disabled={disabled}
124
- activeOpacity={1}
125
- touchSoundDisabled={true}
114
+ <View style={[disabled && styles.disabled, style]}>
115
+ <PressableButton
116
+ onPress={handlePress}
117
+ enabled={!disabled}
118
+ rippleColor="transparent"
119
+ touchSoundDisabled
120
+ activateOnHover
126
121
  accessibilityRole="button"
127
122
  accessibilityLabel={accessibilityLabel ?? label}
128
123
  accessibilityState={{ selected: pressed, disabled: !!disabled }}
129
- {...props}
130
124
  >
131
- <Animated.View
132
- style={[
133
- styles.base,
134
- sizeStyles[size],
135
- { borderWidth: 2 },
136
- surfaceStyle,
137
- ]}
125
+ <EaseView
126
+ style={[styles.base, sizeStyles[size], { borderWidth: 2 }]}
127
+ animate={{
128
+ borderColor: pressed ? colors.primary : inactiveBorder,
129
+ backgroundColor: pressed ? colors.surfaceStrong : 'transparent',
130
+ }}
131
+ transition={COLOR_TRANSITION}
138
132
  >
139
133
  <View style={styles.inner}>
140
- <LeftIcon />
134
+ <ToggleIcon
135
+ pressed={pressed}
136
+ iconName={iconName}
137
+ activeIconName={activeIconName}
138
+ icon={icon}
139
+ activeIcon={activeIcon}
140
+ iconColor={iconColor}
141
+ activeIconColor={activeIconColor}
142
+ iconSize={iconSize}
143
+ primaryColor={colors.primary}
144
+ mutedColor={colors.foregroundMuted}
145
+ />
141
146
  {label ? (
142
- <Animated.Text style={[styles.label, textStyle]} allowFontScaling={true}>
147
+ <Text
148
+ style={[styles.label, { color: pressed ? colors.primary : colors.foreground }]}
149
+ allowFontScaling={true}
150
+ >
143
151
  {label}
144
- </Animated.Text>
152
+ </Text>
145
153
  ) : null}
146
154
  </View>
147
- </Animated.View>
148
- </TouchableOpacity>
149
- </Animated.View>
155
+ </EaseView>
156
+ </PressableButton>
157
+ </View>
150
158
  )
151
159
  }
152
160
 
@@ -164,7 +172,7 @@ const styles = StyleSheet.create({
164
172
  opacity: 0.45,
165
173
  },
166
174
  label: {
167
- fontFamily: 'Poppins-Medium',
175
+ fontFamily: 'Sohne-Medium',
168
176
  fontSize: ms(14),
169
177
  },
170
178
  })
@@ -0,0 +1,60 @@
1
+ import React, { useCallback } from 'react'
2
+ import { FlatList, FlatListProps, ListRenderItem } from 'react-native'
3
+
4
+ export interface VirtualListItem {
5
+ id?: string | number
6
+ }
7
+
8
+ export interface VirtualListProps<T> extends Omit<FlatListProps<T>, 'getItemLayout'> {
9
+ /**
10
+ * Fixed row height in px. When provided, enables `getItemLayout` so the list
11
+ * skips async measurement — large datasets scroll and `scrollToIndex` jump
12
+ * without layout passes. Omit only for variable-height rows.
13
+ */
14
+ itemHeight?: number
15
+ }
16
+
17
+ const defaultKeyExtractor = <T,>(item: T, index: number): string => {
18
+ const id = (item as VirtualListItem | null)?.id
19
+ return id !== undefined ? String(id) : String(index)
20
+ }
21
+
22
+ /**
23
+ * Virtualized list primitive. Thin wrapper over `FlatList` with sane defaults
24
+ * for the common case: stable keys + optional fixed-height fast path.
25
+ *
26
+ * For 10k+ rows, pass `itemHeight` and a `React.memo`-wrapped `renderItem` so
27
+ * only on-screen rows mount and re-render.
28
+ *
29
+ * @example
30
+ * const renderItem = useCallback(({ item }) => <ListItem title={item.title} onPress={...} />, [])
31
+ * <VirtualList data={rows} renderItem={renderItem} itemHeight={64} />
32
+ */
33
+ function VirtualListInner<T>(
34
+ { itemHeight, keyExtractor, renderItem, ...props }: VirtualListProps<T>,
35
+ ref: React.Ref<FlatList<T>>,
36
+ ) {
37
+ const getItemLayout = useCallback(
38
+ (_data: ArrayLike<T> | null | undefined, index: number) => ({
39
+ length: itemHeight ?? 0,
40
+ offset: (itemHeight ?? 0) * index,
41
+ index,
42
+ }),
43
+ [itemHeight],
44
+ )
45
+
46
+ return (
47
+ <FlatList<T>
48
+ ref={ref}
49
+ keyExtractor={keyExtractor ?? defaultKeyExtractor}
50
+ renderItem={renderItem as ListRenderItem<T>}
51
+ getItemLayout={itemHeight !== undefined ? getItemLayout : undefined}
52
+ removeClippedSubviews
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ export const VirtualList = React.forwardRef(VirtualListInner) as <T>(
59
+ props: VirtualListProps<T> & { ref?: React.Ref<FlatList<T>> },
60
+ ) => React.ReactElement
@@ -0,0 +1 @@
1
+ export * from './VirtualList'
package/src/fonts.ts CHANGED
@@ -1,30 +1,51 @@
1
1
  /**
2
- * Poppins font family required by @retray-dev/ui-kit components.
3
- *
2
+ * Sohne font family required by @retray-dev/ui-kit components.
3
+ *
4
4
  * Consumer apps must load these fonts at app root using expo-font:
5
- *
5
+ *
6
6
  * @example
7
7
  * import { useFonts } from 'expo-font'
8
- * import { PoppinsFonts } from '@retray-dev/ui-kit'
9
- *
8
+ * import { SohneFonts } from '@retray-dev/ui-kit/fonts'
9
+ *
10
10
  * function App() {
11
- * const [fontsLoaded] = useFonts(PoppinsFonts)
11
+ * const [fontsLoaded] = useFonts(SohneFonts)
12
12
  * if (!fontsLoaded) return null
13
13
  * // render app
14
14
  * }
15
15
  */
16
- export const PoppinsFonts = {
17
- 'Poppins-Thin': require('./assets/fonts/Poppins-Thin.ttf'),
18
- 'Poppins-ExtraLight': require('./assets/fonts/Poppins-ExtraLight.ttf'),
19
- 'Poppins-Light': require('./assets/fonts/Poppins-Light.ttf'),
20
- 'Poppins-Regular': require('./assets/fonts/Poppins-Regular.ttf'),
21
- 'Poppins-Medium': require('./assets/fonts/Poppins-Medium.ttf'),
22
- 'Poppins-SemiBold': require('./assets/fonts/Poppins-SemiBold.ttf'),
23
- 'Poppins-Bold': require('./assets/fonts/Poppins-Bold.ttf'),
24
- 'Poppins-ExtraBold': require('./assets/fonts/Poppins-ExtraBold.ttf'),
25
- 'Poppins-Black': require('./assets/fonts/Poppins-Black.ttf'),
26
- 'Poppins-Italic': require('./assets/fonts/Poppins-Italic.ttf'),
27
- 'Poppins-MediumItalic': require('./assets/fonts/Poppins-MediumItalic.ttf'),
28
- 'Poppins-SemiBoldItalic': require('./assets/fonts/Poppins-SemiBoldItalic.ttf'),
29
- 'Poppins-BoldItalic': require('./assets/fonts/Poppins-BoldItalic.ttf'),
16
+ // `.otf` assets resolve to a Metro asset module id (number) via require() at the
17
+ // consumer's build time. Declared locally so the dts build does not depend on @types/node.
18
+ declare const require: (path: string) => number
19
+
20
+ export const SohneFonts = {
21
+ // Sohne base
22
+ 'Sohne-ExtraLight': require('./assets/fonts/Sohne-ExtraLight.otf'),
23
+ 'Sohne-ExtraLightItalic': require('./assets/fonts/Sohne-ExtraLightItalic.otf'),
24
+ 'Sohne-Light': require('./assets/fonts/Sohne-Light.otf'),
25
+ 'Sohne-LightItalic': require('./assets/fonts/Sohne-LightItalic.otf'),
26
+ 'Sohne-Regular': require('./assets/fonts/Sohne-Regular.otf'),
27
+ 'Sohne-Italic': require('./assets/fonts/Sohne-Italic.otf'),
28
+ 'Sohne-Medium': require('./assets/fonts/Sohne-Medium.otf'),
29
+ 'Sohne-MediumItalic': require('./assets/fonts/Sohne-MediumItalic.otf'),
30
+ 'Sohne-SemiBold': require('./assets/fonts/Sohne-SemiBold.otf'),
31
+ 'Sohne-SemiBoldItalic': require('./assets/fonts/Sohne-SemiBoldItalic.otf'),
32
+ 'Sohne-Bold': require('./assets/fonts/Sohne-Bold.otf'),
33
+ 'Sohne-BoldItalic': require('./assets/fonts/Sohne-BoldItalic.otf'),
34
+ 'Sohne-ExtraBold': require('./assets/fonts/Sohne-ExtraBold.otf'),
35
+ 'Sohne-ExtraBoldItalic': require('./assets/fonts/Sohne-ExtraBoldItalic.otf'),
36
+ // SohneMono
37
+ 'SohneMono-ExtraLight': require('./assets/fonts/SohneMono-ExtraLight.otf'),
38
+ 'SohneMono-ExtraLightItalic': require('./assets/fonts/SohneMono-ExtraLightItalic.otf'),
39
+ 'SohneMono-Light': require('./assets/fonts/SohneMono-Light.otf'),
40
+ 'SohneMono-LightItalic': require('./assets/fonts/SohneMono-LightItalic.otf'),
41
+ 'SohneMono-Regular': require('./assets/fonts/SohneMono-Regular.otf'),
42
+ 'SohneMono-Italic': require('./assets/fonts/SohneMono-Italic.otf'),
43
+ 'SohneMono-Medium': require('./assets/fonts/SohneMono-Medium.otf'),
44
+ 'SohneMono-MediumItalic': require('./assets/fonts/SohneMono-MediumItalic.otf'),
45
+ 'SohneMono-SemiBold': require('./assets/fonts/SohneMono-SemiBold.otf'),
46
+ 'SohneMono-SemiBoldItalic': require('./assets/fonts/SohneMono-SemiBoldItalic.otf'),
47
+ 'SohneMono-Bold': require('./assets/fonts/SohneMono-Bold.otf'),
48
+ 'SohneMono-BoldItalic': require('./assets/fonts/SohneMono-BoldItalic.otf'),
49
+ 'SohneMono-ExtraBold': require('./assets/fonts/SohneMono-ExtraBold.otf'),
50
+ 'SohneMono-ExtraBoldItalic': require('./assets/fonts/SohneMono-ExtraBoldItalic.otf'),
30
51
  } as const
package/src/index.ts CHANGED
@@ -31,10 +31,10 @@ export * from './components/Select'
31
31
  export * from './components/Toast'
32
32
  export * from './components/CurrencyInput'
33
33
  export * from './components/CurrencyDisplay'
34
- // CurrencyInputLarge is deprecated — use <CurrencyInput size="large" /> instead
35
- export { CurrencyInput as CurrencyInputLarge } from './components/CurrencyInput'
36
34
  export * from './components/ListItem'
35
+ export * from './components/ListGroup'
37
36
  export * from './components/MenuItem'
37
+ export * from './components/MenuGroup'
38
38
  export * from './components/Chip'
39
39
  export * from './components/ConfirmDialog'
40
40
  export * from './components/LabelValue'
@@ -43,14 +43,39 @@ export * from './components/MediaCard'
43
43
  export * from './components/CategoryStrip'
44
44
  export * from './components/Pressable'
45
45
  export * from './components/DetailRow'
46
+ export * from './components/Form'
47
+ export * from './components/VirtualList'
48
+ export * from './components/RetrayProvider'
49
+ export * from './components/ErrorBoundary'
50
+ export * from './components/PagerDots'
51
+ export * from './components/AppHeader'
52
+ export * from './components/SelectableGrid'
53
+ export * from './components/PricingCard'
54
+ export * from './components/TabBar'
55
+ export * from './components/ImageViewer'
56
+ // HolographicCard is intentionally NOT re-exported here — it depends on the
57
+ // optional peer @shopify/react-native-skia, so it must stay out of the main
58
+ // barrel's module graph. Deep-import it: '@retray-dev/ui-kit/HolographicCard'.
46
59
 
47
60
  // Icon utility
48
- export { Icon, renderIcon } from './utils/icons'
61
+ export { Icon, renderIcon, configureIconFamilies } from './utils/icons'
49
62
 
50
63
  // Typography utilities
51
64
  export { getResponsiveFontSize } from './utils/typography'
52
65
  export type { IconProps, IconFamily } from './utils/icons'
53
66
 
67
+ // Haptic feedback utilities
68
+ export {
69
+ selectionAsync,
70
+ impactLight,
71
+ impactMedium,
72
+ impactHeavy,
73
+ notificationSuccess,
74
+ notificationError,
75
+ notificationWarning,
76
+ richHaptics,
77
+ } from './utils/haptics'
78
+
54
79
  // Design tokens
55
80
  export {
56
81
  SPACING,
@@ -1,61 +1,74 @@
1
1
  import { ThemeColors, ResolvedColors } from './types'
2
- import { mixWithBackground, withAlphaOnWhite, withAlphaOnDark, lighten, darken, isDark } from './colorUtils'
2
+ import { mixWithBackground, withAlphaOnWhite, withAlphaOnDark, lighten, darken } from './colorUtils'
3
3
 
4
- // ─── Default palettes (12 tokens each) ───────────────────────────────────────
5
- // These are the only values consumers need to override.
6
- // Designed to look great out of the box with no customization.
4
+ // ─── Default palettes ─────────────────────────────────────────────────────────
5
+ // AUDIT FIXES applied:
6
+ // · accent + accentForeground added system was fully achromatic
7
+ // · warning darkened: #e67e00 → #9a5200 (white text: 2.86:1 → 5.86:1 ✓ AA)
8
+ // · destructive darkened: #e53935 → #c72828 (white text: 4.22:1 → 5.59:1 ✓ AA)
9
+ // · foreground tweaked #222222 → #1a1a1a (matches primary, 16.1:1 on white ✓)
7
10
 
8
11
  export const defaultLight: ThemeColors = {
9
- background: '#ffffff',
10
- foreground: '#222222', // Airbnb ink — deep near-black, never pure black
11
- card: '#ffffff',
12
- primary: '#1a1a1a', // Near-black primary — clean, premium default
13
- primaryForeground: '#ffffff',
14
- border: '#dddddd', // Airbnb hairline light, airy
15
- destructive: '#e53935',
12
+ background: '#ffffff',
13
+ foreground: '#1a1a1a',
14
+ card: '#ffffff',
15
+ primary: '#1a1a1a',
16
+ primaryForeground: '#ffffff',
17
+ // AUDIT FIX: brand accentwas undefined; falls back to primary when omitted
18
+ accent: '#d4561d',
19
+ accentForeground: '#ffffff',
20
+ border: '#dddddd',
21
+ // AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
22
+ destructive: '#c72828',
16
23
  destructiveForeground: '#ffffff',
17
- success: '#1a7a45',
18
- successForeground: '#ffffff',
19
- warning: '#e67e00',
20
- warningForeground: '#ffffff',
24
+ success: '#1a7a45',
25
+ successForeground: '#ffffff',
26
+ // AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
27
+ warning: '#9a5200',
28
+ warningForeground: '#ffffff',
21
29
  }
22
30
 
23
31
  export const defaultDark: ThemeColors = {
24
- background: '#0f0f0f',
25
- foreground: '#fafafa',
26
- card: '#1c1c1c',
27
- primary: '#fafafa',
28
- primaryForeground: '#0f0f0f',
29
- border: '#303030',
30
- destructive: '#ef5350',
32
+ background: '#0f0f0f',
33
+ foreground: '#fafafa',
34
+ card: '#1c1c1c',
35
+ primary: '#fafafa',
36
+ primaryForeground: '#0f0f0f',
37
+ // AUDIT FIX: lighter accent for dark surfaces (warm amber-orange)
38
+ accent: '#e87645',
39
+ accentForeground: '#ffffff',
40
+ border: '#303030',
41
+ destructive: '#ef5350',
31
42
  destructiveForeground: '#ffffff',
32
- success: '#2e7d52',
33
- successForeground: '#ffffff',
34
- warning: '#f57c00',
35
- warningForeground: '#ffffff',
43
+ success: '#2e7d52',
44
+ successForeground: '#ffffff',
45
+ // AUDIT FIX: brighter amber for dark-bg visibility; dark text for contrast
46
+ // #f5a623 on #0f0f0f = 8.6:1 ✓ as indicator; #0f0f0f text on #f5a623 = 8.6:1 ✓
47
+ warning: '#f5a623',
48
+ warningForeground: '#0f0f0f',
36
49
  }
37
50
 
38
51
  // ─── Color derivation ─────────────────────────────────────────────────────────
39
- // Takes 12 public tokens → produces full ResolvedColors for component consumption.
40
- // Dark mode uses bg-blended tints instead of white-blended to stay on-palette.
41
-
42
52
  export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): ResolvedColors {
43
53
  const dark = scheme === 'dark'
44
54
  const bg = t.background
45
55
 
46
- // Text hierarchy: foreground mixed with background at different opacities
47
- const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.55)
48
- const foregroundMuted = mixWithBackground(t.foreground, bg, 0.38)
56
+ // AUDIT FIX: Text hierarchy opacities raised to pass WCAG AA.
57
+ // foregroundSubtle was 0.55 → ~#858585 (3.5:1 fail on white)
58
+ // foregroundMuted was 0.38 → ~#ababab (2.2:1 critical fail on white)
59
+ // New values on light (#1a1a1a on #ffffff):
60
+ // foregroundSubtle 0.70 → ~#646464 (5.9:1 ✓ AA)
61
+ // foregroundMuted 0.62 → ~#767676 (4.5:1 ✓ AA minimum)
62
+ const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.70)
63
+ const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62)
49
64
 
50
- // Surface fills: slight offset from background
51
65
  const surface = dark
52
- ? lighten(bg, -0.06) // slightly lighter than dark bg
53
- : darken(bg, 0.04) // slightly darker than white → #f7f7f7 equivalent
66
+ ? lighten(bg, -0.06)
67
+ : darken(bg, 0.04)
54
68
  const surfaceStrong = dark
55
69
  ? lighten(bg, -0.12)
56
- : darken(bg, 0.08) // #ebebeb equivalent
70
+ : darken(bg, 0.08)
57
71
 
58
- // Semantic tints: color blended toward background
59
72
  const destructiveTint = dark
60
73
  ? withAlphaOnDark(t.destructive, 0.15, bg)
61
74
  : withAlphaOnWhite(t.destructive, 0.08)
@@ -92,7 +105,8 @@ export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): Resolved
92
105
  overlay: t.overlay ?? 'rgba(0,0,0,0.45)',
93
106
  accentResolved: t.accent ?? t.primary,
94
107
  accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
95
- ring: t.primary, // focus ring always = primary
96
- input: t.border, // input border always = border
108
+ ring: t.accent ?? t.primary,
109
+ input: t.border,
110
+ separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16),
97
111
  }
98
112
  }
@@ -49,6 +49,9 @@ export type ResolvedColors = ThemeColors & {
49
49
  // Aliases (ring + input always equal primary + border for coherence)
50
50
  ring: string // = primary
51
51
  input: string // = border
52
+
53
+ // Divider/separator line — deliberately darker than border for visibility
54
+ separator: string
52
55
  }
53
56
 
54
57
  export type Theme = {