@retray-dev/ui-kit 13.0.0 → 13.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/CHANGELOG.md +680 -0
  2. package/CONSUMER.md +26 -9
  3. package/README.md +11 -12
  4. package/{COMPONENTS.md → SKILL.md} +515 -815
  5. package/dist/Accordion.d.mts +8 -6
  6. package/dist/Accordion.d.ts +8 -6
  7. package/dist/Accordion.js +40 -40
  8. package/dist/Accordion.mjs +4 -5
  9. package/dist/AlertBanner.d.mts +3 -3
  10. package/dist/AlertBanner.d.ts +3 -3
  11. package/dist/AlertBanner.js +7 -13
  12. package/dist/AlertBanner.mjs +4 -5
  13. package/dist/AppHeader.d.mts +8 -5
  14. package/dist/AppHeader.d.ts +8 -5
  15. package/dist/AppHeader.js +44 -31
  16. package/dist/AppHeader.mjs +6 -7
  17. package/dist/Avatar.d.mts +4 -4
  18. package/dist/Avatar.d.ts +4 -4
  19. package/dist/Avatar.mjs +2 -3
  20. package/dist/Badge.d.mts +5 -5
  21. package/dist/Badge.d.ts +5 -5
  22. package/dist/Badge.js +7 -13
  23. package/dist/Badge.mjs +3 -4
  24. package/dist/Button.d.mts +5 -5
  25. package/dist/Button.d.ts +5 -5
  26. package/dist/Button.js +31 -29
  27. package/dist/Button.mjs +5 -6
  28. package/dist/ButtonGroup.d.mts +3 -3
  29. package/dist/ButtonGroup.d.ts +3 -3
  30. package/dist/ButtonGroup.mjs +0 -1
  31. package/dist/Card.d.mts +13 -13
  32. package/dist/Card.d.ts +13 -13
  33. package/dist/Card.js +23 -14
  34. package/dist/Card.mjs +4 -5
  35. package/dist/CategoryStrip.d.mts +3 -3
  36. package/dist/CategoryStrip.d.ts +3 -3
  37. package/dist/CategoryStrip.js +30 -27
  38. package/dist/CategoryStrip.mjs +5 -6
  39. package/dist/Checkbox.d.mts +3 -2
  40. package/dist/Checkbox.d.ts +3 -2
  41. package/dist/Checkbox.js +26 -15
  42. package/dist/Checkbox.mjs +3 -4
  43. package/dist/Chip.d.mts +5 -5
  44. package/dist/Chip.d.ts +5 -5
  45. package/dist/Chip.js +30 -27
  46. package/dist/Chip.mjs +5 -6
  47. package/dist/ConfirmDialog.d.mts +3 -2
  48. package/dist/ConfirmDialog.d.ts +3 -2
  49. package/dist/ConfirmDialog.js +67 -49
  50. package/dist/ConfirmDialog.mjs +7 -7
  51. package/dist/CurrencyDisplay.d.mts +3 -3
  52. package/dist/CurrencyDisplay.d.ts +3 -3
  53. package/dist/CurrencyDisplay.mjs +2 -3
  54. package/dist/CurrencyInput.d.mts +2 -2
  55. package/dist/CurrencyInput.d.ts +2 -2
  56. package/dist/CurrencyInput.js +7 -13
  57. package/dist/CurrencyInput.mjs +4 -5
  58. package/dist/DetailRow.d.mts +6 -6
  59. package/dist/DetailRow.d.ts +6 -6
  60. package/dist/DetailRow.js +7 -13
  61. package/dist/DetailRow.mjs +3 -4
  62. package/dist/EmptyState.d.mts +4 -4
  63. package/dist/EmptyState.d.ts +4 -4
  64. package/dist/EmptyState.js +31 -29
  65. package/dist/EmptyState.mjs +6 -7
  66. package/dist/ErrorBoundary.d.mts +9 -7
  67. package/dist/ErrorBoundary.d.ts +9 -7
  68. package/dist/ErrorBoundary.js +33 -29
  69. package/dist/ErrorBoundary.mjs +5 -6
  70. package/dist/Form.d.mts +9 -9
  71. package/dist/Form.d.ts +9 -9
  72. package/dist/Form.mjs +2 -3
  73. package/dist/HolographicCard.d.mts +2 -2
  74. package/dist/HolographicCard.d.ts +2 -2
  75. package/dist/HolographicCard.js +23 -14
  76. package/dist/HolographicCard.mjs +2 -3
  77. package/dist/IconButton.d.mts +4 -4
  78. package/dist/IconButton.d.ts +4 -4
  79. package/dist/IconButton.js +30 -27
  80. package/dist/IconButton.mjs +4 -5
  81. package/dist/IconPicker.d.mts +2 -2
  82. package/dist/IconPicker.d.ts +2 -2
  83. package/dist/IconPicker.js +40 -45
  84. package/dist/IconPicker.mjs +6 -7
  85. package/dist/Image.d.mts +18 -0
  86. package/dist/Image.d.ts +18 -0
  87. package/dist/Image.js +53 -0
  88. package/dist/Image.mjs +2 -0
  89. package/dist/ImageUpload.d.mts +2 -4
  90. package/dist/ImageUpload.d.ts +2 -4
  91. package/dist/ImageUpload.js +50 -40
  92. package/dist/ImageUpload.mjs +5 -6
  93. package/dist/ImageViewer.d.mts +2 -2
  94. package/dist/ImageViewer.d.ts +2 -2
  95. package/dist/ImageViewer.js +31 -28
  96. package/dist/ImageViewer.mjs +6 -7
  97. package/dist/Input.d.mts +4 -4
  98. package/dist/Input.d.ts +4 -4
  99. package/dist/Input.js +7 -13
  100. package/dist/Input.mjs +3 -4
  101. package/dist/ItemGroup.d.mts +23 -0
  102. package/dist/ItemGroup.d.ts +23 -0
  103. package/dist/{ListGroup.js → ItemGroup.js} +11 -13
  104. package/dist/ItemGroup.mjs +4 -0
  105. package/dist/LabelValue.d.mts +4 -4
  106. package/dist/LabelValue.d.ts +4 -4
  107. package/dist/LabelValue.js +7 -13
  108. package/dist/LabelValue.mjs +3 -4
  109. package/dist/ListItem.d.mts +7 -6
  110. package/dist/ListItem.d.ts +7 -6
  111. package/dist/ListItem.js +33 -28
  112. package/dist/ListItem.mjs +5 -6
  113. package/dist/MediaCard.d.mts +6 -6
  114. package/dist/MediaCard.d.ts +6 -6
  115. package/dist/MediaCard.js +30 -27
  116. package/dist/MediaCard.mjs +5 -6
  117. package/dist/MenuItem.d.mts +6 -5
  118. package/dist/MenuItem.d.ts +6 -5
  119. package/dist/MenuItem.js +33 -28
  120. package/dist/MenuItem.mjs +5 -6
  121. package/dist/MonthPicker.d.mts +2 -2
  122. package/dist/MonthPicker.d.ts +2 -2
  123. package/dist/MonthPicker.js +23 -14
  124. package/dist/MonthPicker.mjs +3 -4
  125. package/dist/NumberStepper.d.mts +4 -3
  126. package/dist/NumberStepper.d.ts +4 -3
  127. package/dist/NumberStepper.js +34 -28
  128. package/dist/NumberStepper.mjs +5 -6
  129. package/dist/PagerDots.d.mts +2 -2
  130. package/dist/PagerDots.d.ts +2 -2
  131. package/dist/PagerDots.js +30 -27
  132. package/dist/PagerDots.mjs +4 -5
  133. package/dist/Pressable.d.mts +3 -27
  134. package/dist/Pressable.d.ts +3 -27
  135. package/dist/Pressable.js +23 -14
  136. package/dist/Pressable.mjs +2 -3
  137. package/dist/PricingCard.d.mts +2 -2
  138. package/dist/PricingCard.d.ts +2 -2
  139. package/dist/PricingCard.js +31 -29
  140. package/dist/PricingCard.mjs +7 -8
  141. package/dist/Progress.d.mts +2 -2
  142. package/dist/Progress.d.ts +2 -2
  143. package/dist/Progress.mjs +2 -3
  144. package/dist/RadioGroup.d.mts +2 -2
  145. package/dist/RadioGroup.d.ts +2 -2
  146. package/dist/RadioGroup.js +23 -14
  147. package/dist/RadioGroup.mjs +3 -4
  148. package/dist/RetrayProvider.d.mts +1 -1
  149. package/dist/RetrayProvider.d.ts +1 -1
  150. package/dist/RetrayProvider.js +14 -34
  151. package/dist/RetrayProvider.mjs +3 -4
  152. package/dist/ScreenContainer.d.mts +24 -0
  153. package/dist/ScreenContainer.d.ts +24 -0
  154. package/dist/ScreenContainer.js +85 -0
  155. package/dist/ScreenContainer.mjs +3 -0
  156. package/dist/Select.d.mts +3 -2
  157. package/dist/Select.d.ts +3 -2
  158. package/dist/Select.js +41 -46
  159. package/dist/Select.mjs +3 -4
  160. package/dist/SelectableCard.d.mts +5 -5
  161. package/dist/SelectableCard.d.ts +5 -5
  162. package/dist/SelectableCard.js +30 -27
  163. package/dist/SelectableCard.mjs +5 -6
  164. package/dist/SelectableGrid.d.mts +5 -4
  165. package/dist/SelectableGrid.d.ts +5 -4
  166. package/dist/SelectableGrid.js +80 -45
  167. package/dist/SelectableGrid.mjs +5 -6
  168. package/dist/Separator.d.mts +4 -2
  169. package/dist/Separator.d.ts +4 -2
  170. package/dist/Separator.js +29 -1
  171. package/dist/Separator.mjs +3 -3
  172. package/dist/Sheet.d.mts +11 -11
  173. package/dist/Sheet.d.ts +11 -11
  174. package/dist/Sheet.js +62 -34
  175. package/dist/Sheet.mjs +4 -4
  176. package/dist/SheetSelect.d.mts +2 -2
  177. package/dist/SheetSelect.d.ts +2 -2
  178. package/dist/SheetSelect.js +30 -27
  179. package/dist/SheetSelect.mjs +5 -6
  180. package/dist/Skeleton.d.mts +5 -5
  181. package/dist/Skeleton.d.ts +5 -5
  182. package/dist/Skeleton.mjs +3 -4
  183. package/dist/Slider.d.mts +3 -2
  184. package/dist/Slider.d.ts +3 -2
  185. package/dist/Slider.js +25 -14
  186. package/dist/Slider.mjs +3 -4
  187. package/dist/Spinner.d.mts +2 -2
  188. package/dist/Spinner.d.ts +2 -2
  189. package/dist/Spinner.mjs +2 -3
  190. package/dist/Stats.d.mts +6 -6
  191. package/dist/Stats.d.ts +6 -6
  192. package/dist/Stats.js +30 -27
  193. package/dist/Stats.mjs +5 -6
  194. package/dist/Switch.d.mts +3 -2
  195. package/dist/Switch.d.ts +3 -2
  196. package/dist/Switch.js +25 -15
  197. package/dist/Switch.mjs +3 -4
  198. package/dist/TabBar.d.mts +3 -3
  199. package/dist/TabBar.d.ts +3 -3
  200. package/dist/TabBar.js +30 -27
  201. package/dist/TabBar.mjs +4 -5
  202. package/dist/Tabs.d.mts +13 -13
  203. package/dist/Tabs.d.ts +13 -13
  204. package/dist/Tabs.js +23 -14
  205. package/dist/Tabs.mjs +3 -4
  206. package/dist/Text.d.mts +4 -4
  207. package/dist/Text.d.ts +4 -4
  208. package/dist/Text.js +20 -2
  209. package/dist/Text.mjs +3 -4
  210. package/dist/Textarea.d.mts +3 -3
  211. package/dist/Textarea.d.ts +3 -3
  212. package/dist/Textarea.js +7 -13
  213. package/dist/Textarea.mjs +3 -4
  214. package/dist/Toast.d.mts +15 -13
  215. package/dist/Toast.d.ts +15 -13
  216. package/dist/Toast.mjs +2 -3
  217. package/dist/Toggle.d.mts +4 -4
  218. package/dist/Toggle.d.ts +4 -4
  219. package/dist/Toggle.js +30 -27
  220. package/dist/Toggle.mjs +4 -5
  221. package/dist/VirtualizedList.d.mts +28 -0
  222. package/dist/VirtualizedList.d.ts +28 -0
  223. package/dist/VirtualizedList.js +130 -0
  224. package/dist/VirtualizedList.mjs +3 -0
  225. package/dist/{chunk-MZ6WRTD2.mjs → chunk-24JTXQ2M.mjs} +7 -13
  226. package/dist/{chunk-OBV72JD4.mjs → chunk-2DDJ53DK.mjs} +9 -11
  227. package/dist/{chunk-6CR4S6W2.mjs → chunk-2J5OZOMX.mjs} +19 -8
  228. package/dist/{chunk-4NQFTHN3.mjs → chunk-3GE4UFV5.mjs} +2 -2
  229. package/dist/{chunk-KAGADD2O.mjs → chunk-3RIZCKRM.mjs} +2 -2
  230. package/dist/{chunk-DE25XTVQ.mjs → chunk-3VHFOSZR.mjs} +2 -2
  231. package/dist/{chunk-UOKFSFNJ.mjs → chunk-4PF4LKNT.mjs} +4 -2
  232. package/dist/{chunk-5MYNAAFE.mjs → chunk-5J7VKFSZ.mjs} +4 -4
  233. package/dist/{chunk-BTUW5LSG.mjs → chunk-5TNQ573V.mjs} +4 -3
  234. package/dist/{chunk-6QLBHUEG.mjs → chunk-6T2DVIQT.mjs} +7 -5
  235. package/dist/{chunk-L3YKPTJQ.mjs → chunk-7CE6PDCQ.mjs} +2 -2
  236. package/dist/{chunk-Y6YS33GM.mjs → chunk-AHFEAY6M.mjs} +4 -4
  237. package/dist/{chunk-4ZO5PTKF.mjs → chunk-AZRATPNP.mjs} +5 -3
  238. package/dist/{chunk-V2ZB2XNS.mjs → chunk-BGXOEFDM.mjs} +9 -22
  239. package/dist/{chunk-KC5QDYGZ.mjs → chunk-BMAAAJWN.mjs} +2 -2
  240. package/dist/{chunk-IJCMPVW5.mjs → chunk-BQMJQMWY.mjs} +2 -2
  241. package/dist/{chunk-E4EQSCKR.mjs → chunk-BTPCY4C7.mjs} +7 -5
  242. package/dist/chunk-BVJAYPAD.mjs +55 -0
  243. package/dist/{chunk-RA6SAAFE.mjs → chunk-BWLVX2SQ.mjs} +4 -4
  244. package/dist/{chunk-EROPDCB5.mjs → chunk-CCEM3HIJ.mjs} +30 -25
  245. package/dist/chunk-CTUFFKGS.mjs +30 -0
  246. package/dist/{chunk-EHGBHFMH.mjs → chunk-CYGYC7XT.mjs} +8 -4
  247. package/dist/{chunk-ESQDPO5E.mjs → chunk-DLAOTHHS.mjs} +7 -6
  248. package/dist/{chunk-QY3X2UYR.mjs → chunk-DYYPDQA2.mjs} +21 -7
  249. package/dist/{chunk-S44XWTTC.mjs → chunk-E4BJ5WXG.mjs} +3 -3
  250. package/dist/{chunk-HUSSF6TF.mjs → chunk-EQNCMDZC.mjs} +1 -1
  251. package/dist/{chunk-PI6RULJX.mjs → chunk-EQYTDFDD.mjs} +1 -1
  252. package/dist/{chunk-BULKGOIZ.mjs → chunk-FE26TPCI.mjs} +4 -4
  253. package/dist/{chunk-DBHSUUKU.mjs → chunk-FOUSI6JD.mjs} +1 -1
  254. package/dist/{chunk-KPTY7UYQ.mjs → chunk-GR7PKEKD.mjs} +1 -1
  255. package/dist/{chunk-RRKM4MKB.mjs → chunk-HLWGFBIF.mjs} +3 -3
  256. package/dist/chunk-HMKJGVXA.mjs +35 -0
  257. package/dist/{chunk-U6DEBYU5.mjs → chunk-IFGZUJFH.mjs} +3 -3
  258. package/dist/{chunk-2VIDP72N.mjs → chunk-K3V6OTVB.mjs} +1 -1
  259. package/dist/{chunk-K7TKID3V.mjs → chunk-K4YFTUMC.mjs} +3 -3
  260. package/dist/{chunk-NGEN2EES.mjs → chunk-MQAK2W6L.mjs} +14 -22
  261. package/dist/{chunk-CM2DG4MR.mjs → chunk-MSS3CD6F.mjs} +4 -4
  262. package/dist/{chunk-TETMEKZE.mjs → chunk-NQYS6RPX.mjs} +8 -5
  263. package/dist/{chunk-62BBSSUF.mjs → chunk-P5KC3RTG.mjs} +1 -1
  264. package/dist/{chunk-K3QX2M26.mjs → chunk-PPKCGCZ3.mjs} +5 -5
  265. package/dist/{chunk-ITG4JQM3.mjs → chunk-QEE3EQ3N.mjs} +2 -2
  266. package/dist/{chunk-URIH43IJ.mjs → chunk-RLPPRIJ7.mjs} +20 -34
  267. package/dist/{chunk-XCIG6HT2.mjs → chunk-S433IOQE.mjs} +2 -2
  268. package/dist/{chunk-IGU223UM.mjs → chunk-SWUZKVYO.mjs} +1 -1
  269. package/dist/{chunk-MP7GLMIR.mjs → chunk-T4KMKHTI.mjs} +55 -23
  270. package/dist/{chunk-2QOHHBJC.mjs → chunk-UBTP4NPP.mjs} +5 -21
  271. package/dist/{chunk-TMH263OK.mjs → chunk-UEA2VYGW.mjs} +3 -3
  272. package/dist/chunk-VISIOH33.mjs +37 -0
  273. package/dist/{chunk-SZEKQAOY.mjs → chunk-VSKBODEY.mjs} +1 -1
  274. package/dist/{chunk-FTTI6T5Q.mjs → chunk-W422TEH2.mjs} +3 -3
  275. package/dist/{chunk-WIPEDNSD.mjs → chunk-WD5LBXPR.mjs} +4 -4
  276. package/dist/chunk-WFNGSYS4.mjs +111 -0
  277. package/dist/chunk-WR6DCNAE.mjs +65 -0
  278. package/dist/{chunk-ERWJPVX7.mjs → chunk-XKBB2UZU.mjs} +2 -2
  279. package/dist/{chunk-CBIZLRYH.mjs → chunk-Y5TPAKOS.mjs} +14 -17
  280. package/dist/{chunk-AZV7KNJI.mjs → chunk-YKWIMVGU.mjs} +2 -2
  281. package/dist/{chunk-ZKDKKQCE.mjs → chunk-YOXSXHDE.mjs} +4 -4
  282. package/dist/{chunk-PGQ6FMXS.mjs → chunk-ZO5BRTCW.mjs} +2 -2
  283. package/dist/{chunk-KSSVIFYR.mjs → chunk-ZQGCQ7SA.mjs} +14 -34
  284. package/dist/{chunk-ZTPYUU5C.mjs → chunk-ZRUUUVOO.mjs} +3 -3
  285. package/dist/fonts.mjs +0 -2
  286. package/dist/{index-CY34hxPN.d.ts → index-CinAt5Uo.d.mts} +3 -3
  287. package/dist/{index-CY34hxPN.d.mts → index-CinAt5Uo.d.ts} +3 -3
  288. package/dist/index.d.mts +69 -19
  289. package/dist/index.d.ts +69 -19
  290. package/dist/index.js +1023 -839
  291. package/dist/index.mjs +76 -70
  292. package/package.json +15 -12
  293. package/src/components/Accordion/Accordion.tsx +12 -18
  294. package/src/components/AppHeader/AppHeader.tsx +33 -10
  295. package/src/components/Checkbox/Checkbox.tsx +3 -0
  296. package/src/components/ConfirmDialog/ConfirmDialog.tsx +7 -21
  297. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -2
  298. package/src/components/Image/Image.tsx +50 -0
  299. package/src/components/Image/index.ts +2 -0
  300. package/src/components/ImageUpload/ImageUpload.tsx +34 -26
  301. package/src/components/{ListGroup/ListGroup.tsx → ItemGroup/ItemGroup.tsx} +15 -29
  302. package/src/components/ItemGroup/index.ts +2 -0
  303. package/src/components/ListGroup/index.tsx +20 -0
  304. package/src/components/ListItem/ListItem.tsx +3 -0
  305. package/src/components/MenuGroup/index.tsx +20 -0
  306. package/src/components/MenuItem/MenuItem.tsx +3 -0
  307. package/src/components/NumberStepper/NumberStepper.tsx +4 -0
  308. package/src/components/Pressable/Pressable.tsx +0 -24
  309. package/src/components/ScreenContainer/ScreenContainer.tsx +94 -0
  310. package/src/components/ScreenContainer/index.ts +2 -0
  311. package/src/components/Select/Select.tsx +25 -30
  312. package/src/components/SelectableGrid/SelectableGrid.tsx +51 -20
  313. package/src/components/Separator/Separator.tsx +35 -2
  314. package/src/components/Sheet/Sheet.tsx +3 -21
  315. package/src/components/Sheet/index.ts +2 -2
  316. package/src/components/Slider/Slider.tsx +3 -0
  317. package/src/components/Switch/Switch.tsx +3 -1
  318. package/src/components/Tabs/Tabs.tsx +9 -9
  319. package/src/components/Tabs/index.ts +1 -1
  320. package/src/components/Text/Text.tsx +7 -0
  321. package/src/components/VirtualizedList/VirtualizedList.tsx +154 -0
  322. package/src/components/VirtualizedList/index.ts +2 -0
  323. package/src/hooks/useConfirmDialog.ts +2 -11
  324. package/src/hooks/useSheetModal.ts +40 -0
  325. package/src/index.ts +5 -1
  326. package/src/theme/colors.ts +19 -57
  327. package/src/tokens.ts +21 -7
  328. package/src/utils/curatedIcons.ts +9 -18
  329. package/src/utils/haptics.ts +10 -21
  330. package/src/utils/icons.ts +7 -14
  331. package/dist/ListGroup.d.mts +0 -34
  332. package/dist/ListGroup.d.ts +0 -34
  333. package/dist/ListGroup.mjs +0 -5
  334. package/dist/MenuGroup.d.mts +0 -34
  335. package/dist/MenuGroup.d.ts +0 -34
  336. package/dist/MenuGroup.js +0 -106
  337. package/dist/MenuGroup.mjs +0 -5
  338. package/dist/chunk-ARONDO7M.mjs +0 -40
  339. package/dist/chunk-EW2FIDSM.mjs +0 -29
  340. package/dist/chunk-S2VGME7X.mjs +0 -82
  341. package/dist/chunk-Y6FXYEAI.mjs +0 -8
  342. package/src/components/ListGroup/index.ts +0 -1
  343. package/src/components/MenuGroup/MenuGroup.tsx +0 -145
  344. package/src/components/MenuGroup/index.ts +0 -1
@@ -1,15 +1,33 @@
1
1
  import React from 'react'
2
- import { View, StyleSheet, ViewStyle } from 'react-native'
2
+ import { View, Text, StyleSheet, ViewStyle } from 'react-native'
3
3
  import { useTheme } from '../../theme'
4
+ import { s } from '../../utils/scaling'
4
5
 
5
6
  export interface SeparatorProps {
6
7
  orientation?: 'horizontal' | 'vertical'
8
+ /** Label shown in the center of a horizontal separator — renders as "── label ──". */
9
+ label?: string
7
10
  style?: ViewStyle
8
11
  }
9
12
 
10
- export function Separator({ orientation = 'horizontal', style }: SeparatorProps) {
13
+ export function Separator({ orientation = 'horizontal', label, style }: SeparatorProps) {
11
14
  const { colors } = useTheme()
12
15
 
16
+ if (label && orientation !== 'vertical') {
17
+ return (
18
+ <View style={[styles.row, style]} accessibilityRole="none">
19
+ <View style={[styles.line, { backgroundColor: colors.separator }]} />
20
+ <Text
21
+ style={[styles.label, { color: colors.foregroundMuted }]}
22
+ allowFontScaling={true}
23
+ >
24
+ {label}
25
+ </Text>
26
+ <View style={[styles.line, { backgroundColor: colors.separator }]} />
27
+ </View>
28
+ )
29
+ }
30
+
13
31
  return (
14
32
  <View
15
33
  style={[
@@ -30,4 +48,19 @@ const styles = StyleSheet.create({
30
48
  width: 1,
31
49
  height: '100%',
32
50
  },
51
+ row: {
52
+ flexDirection: 'row',
53
+ alignItems: 'center',
54
+ gap: s(12),
55
+ },
56
+ line: {
57
+ flex: 1,
58
+ height: 1,
59
+ },
60
+ label: {
61
+ fontFamily: 'Sohne-Medium',
62
+ fontSize: 13,
63
+ letterSpacing: 0.32,
64
+ textTransform: 'uppercase',
65
+ },
33
66
  })
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useRef, useId } from 'react'
1
+ import React, { useCallback, useId } from 'react'
2
2
  import { View, Text, TouchableOpacity, StyleSheet, ViewStyle } from 'react-native'
3
3
  import {
4
4
  BottomSheetModal,
@@ -13,8 +13,8 @@ import {
13
13
  } from '@gorhom/bottom-sheet'
14
14
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
15
15
  import { AntDesign } from '@expo/vector-icons'
16
- import { impactMedium } from '../../utils/haptics'
17
16
  import { useTheme } from '../../theme'
17
+ import { useSheetModal } from '../../hooks/useSheetModal'
18
18
  import { s, vs, ms, mvs } from '../../utils/scaling'
19
19
 
20
20
  export { BottomSheetModalProvider }
@@ -97,27 +97,9 @@ export function Sheet({
97
97
  }: SheetProps) {
98
98
  const { colors } = useTheme()
99
99
  const insets = useSafeAreaInsets()
100
- const ref = useRef<BottomSheetModal>(null)
101
- const wasOpened = useRef(false)
102
- const isPresentedRef = useRef(false)
100
+ const { ref, handleDismiss } = useSheetModal(open, onClose)
103
101
  const name = useId()
104
102
 
105
- const handleDismiss = useCallback(() => {
106
- isPresentedRef.current = false
107
- onClose?.()
108
- }, [onClose])
109
-
110
- useEffect(() => {
111
- if (open && !isPresentedRef.current) {
112
- impactMedium()
113
- ref.current?.present()
114
- wasOpened.current = true
115
- isPresentedRef.current = true
116
- } else if (!open && wasOpened.current && isPresentedRef.current) {
117
- ref.current?.dismiss()
118
- }
119
- }, [open])
120
-
121
103
  const renderBackdrop = useCallback(
122
104
  (props: BottomSheetBackdropProps) => (
123
105
  <BottomSheetBackdrop
@@ -1,2 +1,2 @@
1
- export { Sheet, BottomSheetModalProvider, SheetTextInput } from './Sheet'
2
- export type { SheetProps } from './Sheet'
1
+ export { Sheet, SheetHeader, SheetContent, SheetFooter, BottomSheetModalProvider, SheetTextInput } from './Sheet'
2
+ export type { SheetProps, SheetHeaderProps, SheetContentProps, SheetFooterProps } from './Sheet'
@@ -16,6 +16,7 @@ export interface SliderProps {
16
16
  showValue?: boolean
17
17
  formatValue?: (value: number) => string
18
18
  accessibilityLabel?: string
19
+ accessibilityHint?: string
19
20
  disabled?: boolean
20
21
  style?: ViewStyle
21
22
  }
@@ -31,6 +32,7 @@ export function Slider({
31
32
  showValue = false,
32
33
  formatValue = (v: number) => v.toFixed(2),
33
34
  accessibilityLabel,
35
+ accessibilityHint,
34
36
  disabled,
35
37
  style,
36
38
  }: SliderProps) {
@@ -50,6 +52,7 @@ export function Slider({
50
52
  style={[styles.wrapper, style]}
51
53
  accessibilityRole="adjustable"
52
54
  accessibilityLabel={accessibilityLabel ?? label}
55
+ accessibilityHint={accessibilityHint}
53
56
  accessibilityValue={{
54
57
  min: minimumValue,
55
58
  max: maximumValue,
@@ -23,9 +23,10 @@ export interface SwitchProps {
23
23
  disabled?: boolean
24
24
  style?: ViewStyle
25
25
  accessibilityLabel?: string
26
+ accessibilityHint?: string
26
27
  }
27
28
 
28
- export function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }: SwitchProps) {
29
+ export function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel, accessibilityHint }: SwitchProps) {
29
30
  const { colors } = useTheme()
30
31
  const isDisabled = !!disabled
31
32
 
@@ -41,6 +42,7 @@ export function Switch({ checked = false, onCheckedChange, disabled, style, acce
41
42
  touchSoundDisabled
42
43
  accessibilityRole="switch"
43
44
  accessibilityLabel={accessibilityLabel}
45
+ accessibilityHint={accessibilityHint}
44
46
  accessibilityState={{ checked, disabled: isDisabled }}
45
47
  style={styles.touchable}
46
48
  >
@@ -11,19 +11,19 @@ import { s, vs, ms } from '../../utils/scaling'
11
11
  import { SPRINGS } from '../../utils/animations'
12
12
  import { PressableTab } from '../../utils/pressable'
13
13
 
14
- export interface TabItem {
14
+ export interface TabItem<T extends string = string> {
15
15
  label: string
16
- value: string
16
+ value: T
17
17
  icon?: React.ReactNode | ((active: boolean) => React.ReactNode)
18
18
  }
19
19
 
20
20
  export type TabsVariant = 'pill' | 'underline'
21
21
 
22
- export interface TabsProps {
23
- tabs: TabItem[]
22
+ export interface TabsProps<T extends string = string> {
23
+ tabs: TabItem<T>[]
24
24
  variant?: TabsVariant
25
- value?: string
26
- onValueChange?: (value: string) => void
25
+ value?: T
26
+ onValueChange?: (value: T) => void
27
27
  children?: React.ReactNode
28
28
  style?: ViewStyle
29
29
  }
@@ -89,8 +89,8 @@ function TabTrigger({
89
89
  )
90
90
  }
91
91
 
92
- export function Tabs({ tabs, variant = 'pill', value, onValueChange, children, style }: TabsProps) {
93
- const [internal, setInternal] = useState(tabs[0]?.value ?? '')
92
+ export function Tabs<T extends string = string>({ tabs, variant = 'pill', value, onValueChange, children, style }: TabsProps<T>) {
93
+ const [internal, setInternal] = useState<T>((tabs[0]?.value ?? '') as T)
94
94
  const { colors } = useTheme()
95
95
  const active = value ?? internal
96
96
 
@@ -117,7 +117,7 @@ export function Tabs({ tabs, variant = 'pill', value, onValueChange, children, s
117
117
  if (initialised.current) animatePill(active, true)
118
118
  }, [active, animatePill])
119
119
 
120
- const handlePress = (v: string) => {
120
+ const handlePress = (v: T) => {
121
121
  hapticSelection()
122
122
  if (!value) setInternal(v)
123
123
  onValueChange?.(v)
@@ -1,2 +1,2 @@
1
1
  export { Tabs, TabsContent } from './Tabs'
2
- export type { TabsProps, TabsContentProps, TabItem } from './Tabs'
2
+ export type { TabsProps, TabsContentProps, TabItem, TabsVariant } from './Tabs'
@@ -24,6 +24,8 @@ export type TextVariant =
24
24
  | 'uppercase-tag'
25
25
  | 'button-lg'
26
26
  | 'button-sm'
27
+ | 'code-sm'
28
+ | 'code-md'
27
29
 
28
30
  export interface TextProps extends RNTextProps {
29
31
  variant?: TextVariant
@@ -50,6 +52,8 @@ const variantStyles: Record<TextVariant, TextStyle> = {
50
52
  'uppercase-tag':{ ...TYPOGRAPHY['uppercase-tag'],fontSize: ms(TYPOGRAPHY['uppercase-tag'].fontSize),lineHeight: mvs(TYPOGRAPHY['uppercase-tag'].lineHeight) },
51
53
  'button-lg': { ...TYPOGRAPHY['button-lg'], fontSize: ms(TYPOGRAPHY['button-lg'].fontSize), lineHeight: mvs(TYPOGRAPHY['button-lg'].lineHeight) },
52
54
  'button-sm': { ...TYPOGRAPHY['button-sm'], fontSize: ms(TYPOGRAPHY['button-sm'].fontSize), lineHeight: mvs(TYPOGRAPHY['button-sm'].lineHeight) },
55
+ 'code-sm': { ...TYPOGRAPHY['code-sm'], fontSize: ms(TYPOGRAPHY['code-sm'].fontSize), lineHeight: mvs(TYPOGRAPHY['code-sm'].lineHeight) },
56
+ 'code-md': { ...TYPOGRAPHY['code-md'], fontSize: ms(TYPOGRAPHY['code-md'].fontSize), lineHeight: mvs(TYPOGRAPHY['code-md'].lineHeight) },
53
57
  }
54
58
 
55
59
  // Default color by variant — hierarchy matches Airbnb ink/body/muted pattern
@@ -70,6 +74,8 @@ const defaultColorVariant: Partial<Record<TextVariant, 'foreground' | 'foregroun
70
74
  'uppercase-tag':'foregroundMuted',
71
75
  'button-lg': 'foreground',
72
76
  'button-sm': 'foreground',
77
+ 'code-sm': 'foreground',
78
+ 'code-md': 'foreground',
73
79
  }
74
80
 
75
81
  let fontWarned = false
@@ -77,6 +83,7 @@ function warnIfFontsMissing(): void {
77
83
  if (fontWarned || typeof __DEV__ === 'undefined' || !__DEV__) return
78
84
  fontWarned = true
79
85
  if (!expoFontIsLoaded('Sohne-Regular')) {
86
+ // eslint-disable-next-line no-console
80
87
  console.warn('[retray-ui-kit] Sohne fonts not loaded — text falls back to system font.')
81
88
  }
82
89
  }
@@ -0,0 +1,154 @@
1
+ import React, { useCallback } from 'react'
2
+ import {
3
+ SectionList,
4
+ type SectionListProps,
5
+ type SectionListRenderItemInfo,
6
+ RefreshControl,
7
+ View,
8
+ Text,
9
+ StyleSheet,
10
+ type ViewStyle,
11
+ } from 'react-native'
12
+ import { useTheme } from '../../theme'
13
+ import { s, vs } from '../../utils/scaling'
14
+
15
+ export interface VirtualizedListSection<T> {
16
+ title?: string
17
+ data: readonly T[]
18
+ }
19
+
20
+ export interface VirtualizedListProps<T>
21
+ extends Omit<SectionListProps<T>, 'sections' | 'renderItem' | 'ListEmptyComponent'> {
22
+ sections: VirtualizedListSection<T>[]
23
+ renderItem: (info: SectionListRenderItemInfo<T>) => React.ReactElement | null
24
+ /** Empty state shown when no data. */
25
+ emptyTitle?: string
26
+ /** Empty state description. */
27
+ emptyDescription?: string
28
+ /** Custom empty state component. Overrides emptyTitle/emptyDescription. */
29
+ emptyComponent?: React.ReactNode
30
+ /** Enable pull-to-refresh. */
31
+ refreshing?: boolean
32
+ onRefresh?: () => void
33
+ /** Sticky section headers. Default true. */
34
+ stickyHeaders?: boolean
35
+ /** Override section header color. Defaults to foregroundMuted. */
36
+ headerColor?: string
37
+ style?: ViewStyle
38
+ }
39
+
40
+ export function VirtualizedList<T>({
41
+ sections,
42
+ renderItem,
43
+ emptyTitle = 'Sin contenido',
44
+ emptyDescription,
45
+ emptyComponent,
46
+ refreshing = false,
47
+ onRefresh,
48
+ stickyHeaders = true,
49
+ headerColor,
50
+ style,
51
+ ...props
52
+ }: VirtualizedListProps<T>) {
53
+ const { colors } = useTheme()
54
+
55
+ const renderSectionHeader = useCallback(
56
+ ({ section }: { section: VirtualizedListSection<T> }) => {
57
+ if (!section.title) return null
58
+ return (
59
+ <View style={[styles.sectionHeader, { backgroundColor: colors.background }]}>
60
+ <Text
61
+ style={[styles.sectionHeaderText, { color: headerColor ?? colors.foregroundMuted }]}
62
+ allowFontScaling={true}
63
+ >
64
+ {section.title}
65
+ </Text>
66
+ </View>
67
+ )
68
+ },
69
+ [colors.background, colors.foregroundMuted, headerColor],
70
+ )
71
+
72
+ const keyExtractor = useCallback(
73
+ (_item: T, index: number) => String(index),
74
+ [],
75
+ )
76
+
77
+ const flatSections = sections.filter((s) => s.data.length > 0)
78
+ const hasData = flatSections.length > 0
79
+
80
+ if (!hasData) {
81
+ if (emptyComponent) return <View style={style}>{emptyComponent}</View>
82
+ return (
83
+ <View style={[styles.empty, style]}>
84
+ <Text
85
+ style={[styles.emptyTitle, { color: colors.foregroundMuted }]}
86
+ allowFontScaling={true}
87
+ >
88
+ {emptyTitle}
89
+ </Text>
90
+ {emptyDescription ? (
91
+ <Text
92
+ style={[styles.emptyDescription, { color: colors.foregroundMuted }]}
93
+ allowFontScaling={true}
94
+ >
95
+ {emptyDescription}
96
+ </Text>
97
+ ) : null}
98
+ </View>
99
+ )
100
+ }
101
+
102
+ return (
103
+ <SectionList
104
+ sections={flatSections}
105
+ renderItem={renderItem}
106
+ renderSectionHeader={renderSectionHeader}
107
+ keyExtractor={keyExtractor}
108
+ stickySectionHeadersEnabled={stickyHeaders}
109
+ refreshControl={
110
+ onRefresh ? (
111
+ <RefreshControl
112
+ refreshing={refreshing}
113
+ onRefresh={onRefresh}
114
+ tintColor={colors.primary}
115
+ />
116
+ ) : undefined
117
+ }
118
+ style={style}
119
+ showsVerticalScrollIndicator={false}
120
+ {...props}
121
+ />
122
+ )
123
+ }
124
+
125
+ const styles = StyleSheet.create({
126
+ sectionHeader: {
127
+ paddingHorizontal: s(16),
128
+ paddingTop: vs(16),
129
+ paddingBottom: vs(6),
130
+ },
131
+ sectionHeaderText: {
132
+ fontFamily: 'Sohne-SemiBold',
133
+ fontSize: 13,
134
+ letterSpacing: 0.32,
135
+ textTransform: 'uppercase',
136
+ },
137
+ empty: {
138
+ flex: 1,
139
+ alignItems: 'center',
140
+ justifyContent: 'center',
141
+ paddingHorizontal: s(32),
142
+ gap: vs(8),
143
+ },
144
+ emptyTitle: {
145
+ fontFamily: 'Sohne-Medium',
146
+ fontSize: 16,
147
+ textAlign: 'center',
148
+ },
149
+ emptyDescription: {
150
+ fontFamily: 'Sohne-Regular',
151
+ fontSize: 14,
152
+ textAlign: 'center',
153
+ },
154
+ })
@@ -0,0 +1,2 @@
1
+ export { VirtualizedList } from './VirtualizedList'
2
+ export type { VirtualizedListProps, VirtualizedListSection } from './VirtualizedList'
@@ -16,7 +16,6 @@ export interface UseConfirmDialogResult {
16
16
  export function useConfirmDialog(options: UseConfirmDialogOptions): UseConfirmDialogResult {
17
17
  const [visible, setVisible] = useState(false)
18
18
  const [loading, setLoading] = useState(false)
19
- const mountedRef = useRef(true)
20
19
  const onConfirmRef = useRef(options.onConfirm)
21
20
  const onCancelRef = useRef(options.onCancel)
22
21
 
@@ -25,12 +24,6 @@ export function useConfirmDialog(options: UseConfirmDialogOptions): UseConfirmDi
25
24
  onCancelRef.current = options.onCancel
26
25
  })
27
26
 
28
- useEffect(() => {
29
- return () => {
30
- mountedRef.current = false
31
- }
32
- }, [])
33
-
34
27
  const open = useCallback(() => setVisible(true), [])
35
28
 
36
29
  const handleConfirm = useCallback(async () => {
@@ -40,10 +33,8 @@ export function useConfirmDialog(options: UseConfirmDialogOptions): UseConfirmDi
40
33
  } catch {
41
34
  /* consumer handles error in onConfirm */
42
35
  } finally {
43
- if (mountedRef.current) {
44
- setLoading(false)
45
- setVisible(false)
46
- }
36
+ setLoading(false)
37
+ setVisible(false)
47
38
  }
48
39
  }, [])
49
40
 
@@ -0,0 +1,40 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+ import { BottomSheetModal } from '@gorhom/bottom-sheet'
3
+ import { impactMedium } from '../utils/haptics'
4
+
5
+ type SheetState = 'idle' | 'presenting' | 'presented' | 'dismissing'
6
+
7
+ export function useSheetModal(visible: boolean, onDismiss?: () => void) {
8
+ const ref = useRef<BottomSheetModal>(null)
9
+ const state = useRef<SheetState>('idle')
10
+ const onDismissRef = useRef(onDismiss)
11
+ const [tick, setTick] = useState(0)
12
+
13
+ useEffect(() => {
14
+ onDismissRef.current = onDismiss
15
+ })
16
+
17
+ useEffect(() => {
18
+ if (visible) {
19
+ if (state.current === 'idle') {
20
+ state.current = 'presenting'
21
+ impactMedium()
22
+ ref.current?.present()
23
+ state.current = 'presented'
24
+ }
25
+ } else {
26
+ if (state.current === 'presented' || state.current === 'presenting') {
27
+ state.current = 'dismissing'
28
+ ref.current?.dismiss()
29
+ }
30
+ }
31
+ }, [visible, tick])
32
+
33
+ const handleDismiss = useCallback(() => {
34
+ state.current = 'idle'
35
+ onDismissRef.current?.()
36
+ setTick((t) => t + 1)
37
+ }, [])
38
+
39
+ return { ref, handleDismiss }
40
+ }
package/src/index.ts CHANGED
@@ -39,9 +39,9 @@ export * from './components/Chip'
39
39
  export * from './components/ConfirmDialog'
40
40
  export * from './components/LabelValue'
41
41
  export * from './components/MonthPicker'
42
+ export * from './components/Pressable'
42
43
  export * from './components/MediaCard'
43
44
  export * from './components/CategoryStrip'
44
- export * from './components/Pressable'
45
45
  export * from './components/DetailRow'
46
46
  export * from './components/Form'
47
47
  export * from './components/RetrayProvider'
@@ -58,6 +58,9 @@ export * from './components/ImageUpload'
58
58
  export * from './components/IconPicker'
59
59
  export * from './components/NumberStepper'
60
60
  export * from './components/Stats'
61
+ export * from './components/Image'
62
+ export * from './components/ScreenContainer'
63
+ export * from './components/VirtualizedList'
61
64
  // HolographicCard is intentionally NOT re-exported here — it depends on the
62
65
  // optional peer @shopify/react-native-skia, so it must stay out of the main
63
66
  // barrel's module graph. Deep-import it: '@retray-dev/ui-kit/HolographicCard'.
@@ -86,6 +89,7 @@ export {
86
89
  // Hooks
87
90
  export { useConfirmDialog } from './hooks/useConfirmDialog'
88
91
  export type { UseConfirmDialogOptions, UseConfirmDialogResult } from './hooks/useConfirmDialog'
92
+ export { useSheetModal } from './hooks/useSheetModal'
89
93
 
90
94
 
91
95
  // Design tokens
@@ -9,20 +9,6 @@ function rgbToHex(r: number, g: number, b: number): string {
9
9
  return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`
10
10
  }
11
11
 
12
- function withAlphaOnWhite(hex: string, alpha: number): string {
13
- const rgb = hexToRgb(hex)
14
- if (!rgb) return hex
15
- const r = rgb.r * alpha + 255 * (1 - alpha); const g = rgb.g * alpha + 255 * (1 - alpha); const b = rgb.b * alpha + 255 * (1 - alpha)
16
- return rgbToHex(r, g, b)
17
- }
18
-
19
- function withAlphaOnDark(hex: string, alpha: number, bgHex = '#0f0f0f'): string {
20
- const rgb = hexToRgb(hex); const bg = hexToRgb(bgHex)
21
- if (!rgb || !bg) return hex
22
- const r = rgb.r * alpha + bg.r * (1 - alpha); const g = rgb.g * alpha + bg.g * (1 - alpha); const b = rgb.b * alpha + bg.b * (1 - alpha)
23
- return rgbToHex(r, g, b)
24
- }
25
-
26
12
  function mixWithBackground(fgHex: string, bgHex: string, opacity: number): string {
27
13
  const fg = hexToRgb(fgHex); const bg = hexToRgb(bgHex)
28
14
  if (!fg || !bg) return fgHex
@@ -30,14 +16,11 @@ function mixWithBackground(fgHex: string, bgHex: string, opacity: number): strin
30
16
  return rgbToHex(r, g, b)
31
17
  }
32
18
 
33
- function lighten(hex: string, amount: number): string {
34
- return withAlphaOnWhite(hex, 1 - amount)
35
- }
36
-
37
- function darken(hex: string, amount: number): string {
38
- const rgb = hexToRgb(hex)
39
- if (!rgb) return hex
40
- return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount))
19
+ function createColorPair(fg: string, bg: string, dark: boolean): { tint: string; border: string } {
20
+ return {
21
+ tint: mixWithBackground(fg, dark ? bg : '#ffffff', dark ? 0.15 : 0.08),
22
+ border: mixWithBackground(fg, dark ? bg : '#ffffff', dark ? 0.45 : 0.30),
23
+ }
41
24
  }
42
25
 
43
26
  // ─── Default palettes ─────────────────────────────────────────────────────────
@@ -91,49 +74,26 @@ export const defaultDark: ThemeColors = {
91
74
  export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): ResolvedColors {
92
75
  const dark = scheme === 'dark'
93
76
  const bg = t.background
77
+ const WHITE = '#ffffff'
78
+ const BLACK = '#000000'
94
79
 
95
- // AUDIT FIX: Text hierarchy opacities raised to pass WCAG AA.
96
- // foregroundSubtle was 0.55 → ~#858585 (3.5:1 fail on white)
97
- // foregroundMuted was 0.38 → ~#ababab (2.2:1 critical fail on white)
98
- // New values on light (#1a1a1a on #ffffff):
99
- // foregroundSubtle 0.70 → ~#646464 (5.9:1 ✓ AA)
100
- // foregroundMuted 0.62 → ~#767676 (4.5:1 ✓ AA minimum)
101
80
  const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.70)
102
81
  const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62)
103
82
 
104
83
  const surface = dark
105
- ? lighten(bg, -0.06)
106
- : darken(bg, 0.04)
84
+ ? mixWithBackground(bg, BLACK, 0.94)
85
+ : mixWithBackground(bg, BLACK, 0.96)
107
86
  const surfaceStrong = dark
108
- ? lighten(bg, -0.12)
109
- : darken(bg, 0.08)
87
+ ? mixWithBackground(bg, BLACK, 0.88)
88
+ : mixWithBackground(bg, BLACK, 0.92)
110
89
 
111
- // Skeleton needs higher contrast than surface to be visible.
112
- // Light: 10% darken (was 4% via surface — invisible). Dark: 10% lighten.
113
90
  const skeleton = dark
114
- ? lighten(bg, -0.10)
115
- : darken(bg, 0.10)
116
-
117
- const destructiveTint = dark
118
- ? withAlphaOnDark(t.destructive, 0.15, bg)
119
- : withAlphaOnWhite(t.destructive, 0.08)
120
- const destructiveBorder = dark
121
- ? withAlphaOnDark(t.destructive, 0.45, bg)
122
- : withAlphaOnWhite(t.destructive, 0.30)
123
-
124
- const successTint = dark
125
- ? withAlphaOnDark(t.success, 0.15, bg)
126
- : withAlphaOnWhite(t.success, 0.08)
127
- const successBorder = dark
128
- ? withAlphaOnDark(t.success, 0.45, bg)
129
- : withAlphaOnWhite(t.success, 0.30)
91
+ ? mixWithBackground(bg, BLACK, 0.90)
92
+ : mixWithBackground(bg, BLACK, 0.90)
130
93
 
131
- const warningTint = dark
132
- ? withAlphaOnDark(t.warning, 0.15, bg)
133
- : withAlphaOnWhite(t.warning, 0.08)
134
- const warningBorder = dark
135
- ? withAlphaOnDark(t.warning, 0.45, bg)
136
- : withAlphaOnWhite(t.warning, 0.30)
94
+ const { tint: destructiveTint, border: destructiveBorder } = createColorPair(t.destructive, bg, dark)
95
+ const { tint: successTint, border: successBorder } = createColorPair(t.success, bg, dark)
96
+ const { tint: warningTint, border: warningBorder } = createColorPair(t.warning, bg, dark)
137
97
 
138
98
  return {
139
99
  ...t,
@@ -153,6 +113,8 @@ export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): Resolved
153
113
  accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
154
114
  ring: t.accent ?? t.primary,
155
115
  input: t.border,
156
- separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16),
116
+ separator: dark
117
+ ? mixWithBackground(t.border, WHITE, 0.78)
118
+ : mixWithBackground(t.border, BLACK, 0.84),
157
119
  }
158
120
  }
package/src/tokens.ts CHANGED
@@ -49,17 +49,17 @@ export const SHADOWS = {
49
49
  },
50
50
  lg: {
51
51
  shadowColor: '#000',
52
- shadowOffset: { width: 0, height: 6 },
53
- shadowOpacity: 0.16,
54
- shadowRadius: 16,
55
- elevation: 10,
52
+ shadowOffset: { width: 0, height: 4 },
53
+ shadowOpacity: 0.12,
54
+ shadowRadius: 12,
55
+ elevation: 8,
56
56
  },
57
57
  xl: {
58
58
  shadowColor: '#000',
59
- shadowOffset: { width: 0, height: 12 },
60
- shadowOpacity: 0.24,
59
+ shadowOffset: { width: 0, height: 8 },
60
+ shadowOpacity: 0.18,
61
61
  shadowRadius: 24,
62
- elevation: 18,
62
+ elevation: 16,
63
63
  },
64
64
  } as const
65
65
 
@@ -200,6 +200,20 @@ export const TYPOGRAPHY = {
200
200
  lineHeight: 18,
201
201
  letterSpacing: 0,
202
202
  },
203
+ 'code-sm': {
204
+ fontFamily: 'SohneMono-Regular',
205
+ fontSize: 13,
206
+ fontWeight: '400' as const,
207
+ lineHeight: 18,
208
+ letterSpacing: 0,
209
+ },
210
+ 'code-md': {
211
+ fontFamily: 'SohneMono-Regular',
212
+ fontSize: 15,
213
+ fontWeight: '400' as const,
214
+ lineHeight: 22,
215
+ letterSpacing: 0,
216
+ },
203
217
  } as const
204
218
 
205
219
  // ─── Types ────────────────────────────────────────────────────────────────────