@retray-dev/ui-kit 6.1.0 → 7.0.1

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 (321) hide show
  1. package/COMPONENTS.md +447 -13
  2. package/EXAMPLES.md +248 -0
  3. package/README.md +11 -10
  4. package/dist/Accordion.d.mts +28 -0
  5. package/dist/Accordion.d.ts +28 -0
  6. package/dist/Accordion.js +340 -0
  7. package/dist/Accordion.mjs +6 -0
  8. package/dist/AlertBanner.d.mts +16 -0
  9. package/dist/AlertBanner.d.ts +16 -0
  10. package/dist/AlertBanner.js +247 -0
  11. package/dist/AlertBanner.mjs +5 -0
  12. package/dist/Avatar.d.mts +20 -0
  13. package/dist/Avatar.d.ts +20 -0
  14. package/dist/Avatar.js +234 -0
  15. package/dist/Avatar.mjs +3 -0
  16. package/dist/Badge.d.mts +26 -0
  17. package/dist/Badge.d.ts +26 -0
  18. package/dist/Badge.js +247 -0
  19. package/dist/Badge.mjs +4 -0
  20. package/dist/Button.d.mts +25 -0
  21. package/dist/Button.d.ts +25 -0
  22. package/dist/Button.js +414 -0
  23. package/dist/Button.mjs +8 -0
  24. package/dist/ButtonGroup.d.mts +26 -0
  25. package/dist/ButtonGroup.d.ts +26 -0
  26. package/dist/ButtonGroup.js +52 -0
  27. package/dist/ButtonGroup.mjs +2 -0
  28. package/dist/Card.d.mts +39 -0
  29. package/dist/Card.d.ts +39 -0
  30. package/dist/Card.js +329 -0
  31. package/dist/Card.mjs +7 -0
  32. package/dist/CategoryStrip.d.mts +26 -0
  33. package/dist/CategoryStrip.d.ts +26 -0
  34. package/dist/CategoryStrip.js +396 -0
  35. package/dist/CategoryStrip.mjs +9 -0
  36. package/dist/Checkbox.d.mts +14 -0
  37. package/dist/Checkbox.d.ts +14 -0
  38. package/dist/Checkbox.js +304 -0
  39. package/dist/Checkbox.mjs +7 -0
  40. package/dist/Chip.d.mts +31 -0
  41. package/dist/Chip.d.ts +31 -0
  42. package/dist/Chip.js +370 -0
  43. package/dist/Chip.mjs +8 -0
  44. package/dist/ConfirmDialog.d.mts +15 -0
  45. package/dist/ConfirmDialog.d.ts +15 -0
  46. package/dist/ConfirmDialog.js +530 -0
  47. package/dist/ConfirmDialog.mjs +9 -0
  48. package/dist/CurrencyDisplay.d.mts +24 -0
  49. package/dist/CurrencyDisplay.d.ts +24 -0
  50. package/dist/CurrencyDisplay.js +189 -0
  51. package/dist/CurrencyDisplay.mjs +3 -0
  52. package/dist/CurrencyInput.d.mts +26 -0
  53. package/dist/CurrencyInput.d.ts +26 -0
  54. package/dist/CurrencyInput.js +404 -0
  55. package/dist/CurrencyInput.mjs +7 -0
  56. package/dist/DetailRow.d.mts +32 -0
  57. package/dist/DetailRow.d.ts +32 -0
  58. package/dist/DetailRow.js +275 -0
  59. package/dist/DetailRow.mjs +4 -0
  60. package/dist/EmptyState.d.mts +27 -0
  61. package/dist/EmptyState.d.ts +27 -0
  62. package/dist/EmptyState.js +503 -0
  63. package/dist/EmptyState.mjs +9 -0
  64. package/dist/Form.d.mts +52 -0
  65. package/dist/Form.d.ts +52 -0
  66. package/dist/Form.js +204 -0
  67. package/dist/Form.mjs +3 -0
  68. package/dist/IconButton.d.mts +22 -0
  69. package/dist/IconButton.d.ts +22 -0
  70. package/dist/IconButton.js +383 -0
  71. package/dist/IconButton.mjs +7 -0
  72. package/dist/Input.d.mts +23 -0
  73. package/dist/Input.d.ts +23 -0
  74. package/dist/Input.js +351 -0
  75. package/dist/Input.mjs +6 -0
  76. package/dist/LabelValue.d.mts +16 -0
  77. package/dist/LabelValue.d.ts +16 -0
  78. package/dist/LabelValue.js +225 -0
  79. package/dist/LabelValue.mjs +4 -0
  80. package/dist/ListGroup.d.mts +34 -0
  81. package/dist/ListGroup.d.ts +34 -0
  82. package/dist/ListGroup.js +217 -0
  83. package/dist/ListGroup.mjs +4 -0
  84. package/dist/ListItem.d.mts +64 -0
  85. package/dist/ListItem.d.ts +64 -0
  86. package/dist/ListItem.js +430 -0
  87. package/dist/ListItem.mjs +8 -0
  88. package/dist/MediaCard.d.mts +39 -0
  89. package/dist/MediaCard.d.ts +39 -0
  90. package/dist/MediaCard.js +427 -0
  91. package/dist/MediaCard.mjs +8 -0
  92. package/dist/MenuGroup.d.mts +34 -0
  93. package/dist/MenuGroup.d.ts +34 -0
  94. package/dist/MenuGroup.js +217 -0
  95. package/dist/MenuGroup.mjs +4 -0
  96. package/dist/MenuItem.d.mts +48 -0
  97. package/dist/MenuItem.d.ts +48 -0
  98. package/dist/MenuItem.js +403 -0
  99. package/dist/MenuItem.mjs +8 -0
  100. package/dist/MonthPicker.d.mts +20 -0
  101. package/dist/MonthPicker.d.ts +20 -0
  102. package/dist/MonthPicker.js +234 -0
  103. package/dist/MonthPicker.mjs +4 -0
  104. package/dist/Pressable.d.mts +34 -0
  105. package/dist/Pressable.d.ts +34 -0
  106. package/dist/Pressable.js +132 -0
  107. package/dist/Pressable.mjs +4 -0
  108. package/dist/Progress.d.mts +14 -0
  109. package/dist/Progress.d.ts +14 -0
  110. package/dist/Progress.js +191 -0
  111. package/dist/Progress.mjs +4 -0
  112. package/dist/RadioGroup.d.mts +19 -0
  113. package/dist/RadioGroup.d.ts +19 -0
  114. package/dist/RadioGroup.js +341 -0
  115. package/dist/RadioGroup.mjs +7 -0
  116. package/dist/Select.d.mts +22 -0
  117. package/dist/Select.d.ts +22 -0
  118. package/dist/Select.js +441 -0
  119. package/dist/Select.mjs +6 -0
  120. package/dist/Separator.d.mts +10 -0
  121. package/dist/Separator.d.ts +10 -0
  122. package/dist/Separator.js +156 -0
  123. package/dist/Separator.mjs +2 -0
  124. package/dist/Sheet.d.mts +81 -0
  125. package/dist/Sheet.d.ts +81 -0
  126. package/dist/Sheet.js +340 -0
  127. package/dist/Sheet.mjs +4 -0
  128. package/dist/Skeleton.d.mts +17 -0
  129. package/dist/Skeleton.d.ts +17 -0
  130. package/dist/Skeleton.js +205 -0
  131. package/dist/Skeleton.mjs +4 -0
  132. package/dist/Slider.d.mts +20 -0
  133. package/dist/Slider.d.ts +20 -0
  134. package/dist/Slider.js +232 -0
  135. package/dist/Slider.mjs +4 -0
  136. package/dist/Spinner.d.mts +12 -0
  137. package/dist/Spinner.d.ts +12 -0
  138. package/dist/Spinner.js +172 -0
  139. package/dist/Spinner.mjs +3 -0
  140. package/dist/Switch.d.mts +13 -0
  141. package/dist/Switch.d.ts +13 -0
  142. package/dist/Switch.js +261 -0
  143. package/dist/Switch.mjs +5 -0
  144. package/dist/Tabs.d.mts +27 -0
  145. package/dist/Tabs.d.ts +27 -0
  146. package/dist/Tabs.js +389 -0
  147. package/dist/Tabs.mjs +6 -0
  148. package/dist/Text.d.mts +12 -0
  149. package/dist/Text.d.ts +12 -0
  150. package/dist/Text.js +311 -0
  151. package/dist/Text.mjs +4 -0
  152. package/dist/Textarea.d.mts +16 -0
  153. package/dist/Textarea.d.ts +16 -0
  154. package/dist/Textarea.js +333 -0
  155. package/dist/Textarea.mjs +6 -0
  156. package/dist/Toast.d.mts +47 -0
  157. package/dist/Toast.d.ts +47 -0
  158. package/dist/Toast.js +185 -0
  159. package/dist/Toast.mjs +3 -0
  160. package/dist/Toggle.d.mts +33 -0
  161. package/dist/Toggle.d.ts +33 -0
  162. package/dist/Toggle.js +397 -0
  163. package/dist/Toggle.mjs +8 -0
  164. package/dist/VirtualList.d.mts +19 -0
  165. package/dist/VirtualList.d.ts +19 -0
  166. package/dist/VirtualList.js +38 -0
  167. package/dist/VirtualList.mjs +1 -0
  168. package/dist/chunk-2CE3TQVY.mjs +11 -0
  169. package/dist/chunk-2UYENBLV.mjs +49 -0
  170. package/dist/chunk-3BBOZ3OQ.mjs +41 -0
  171. package/dist/chunk-5IKW3VNC.mjs +43 -0
  172. package/dist/chunk-63357L2X.mjs +51 -0
  173. package/dist/chunk-6LQYY7HC.mjs +127 -0
  174. package/dist/chunk-6Q64UFIA.mjs +71 -0
  175. package/dist/chunk-76PFOSM2.mjs +41 -0
  176. package/dist/chunk-7H2OR44A.mjs +14 -0
  177. package/dist/chunk-A4MDAP7G.mjs +42 -0
  178. package/dist/chunk-AU2VDY4P.mjs +190 -0
  179. package/dist/chunk-BRKYVJVV.mjs +60 -0
  180. package/dist/chunk-CRYBX2CM.mjs +146 -0
  181. package/dist/chunk-DITNP6PL.mjs +106 -0
  182. package/dist/chunk-FTLJOUOQ.mjs +97 -0
  183. package/dist/chunk-GCWOGZYL.mjs +104 -0
  184. package/dist/chunk-GNGLDL6Z.mjs +60 -0
  185. package/dist/chunk-GPOUINK5.mjs +148 -0
  186. package/dist/chunk-HSPSMN6U.mjs +115 -0
  187. package/dist/chunk-IRRY3CRZ.mjs +82 -0
  188. package/dist/chunk-JB67UOB5.mjs +92 -0
  189. package/dist/chunk-JBLL7U3U.mjs +64 -0
  190. package/dist/chunk-KWCPOM6W.mjs +136 -0
  191. package/dist/chunk-KZJRQOIU.mjs +64 -0
  192. package/dist/chunk-L7E7TVEZ.mjs +145 -0
  193. package/dist/chunk-LG4DO3DK.mjs +174 -0
  194. package/dist/chunk-LWG526VX.mjs +139 -0
  195. package/dist/chunk-MN7OG7IY.mjs +96 -0
  196. package/dist/chunk-MX6HRKMI.mjs +29 -0
  197. package/dist/chunk-NC5ZTR2Y.mjs +32 -0
  198. package/dist/chunk-NQGVLMWG.mjs +90 -0
  199. package/dist/chunk-QCNARS3X.mjs +46 -0
  200. package/dist/chunk-QXGYKWI7.mjs +134 -0
  201. package/dist/chunk-QY3X2UYR.mjs +191 -0
  202. package/dist/chunk-RKLHUDZS.mjs +92 -0
  203. package/dist/chunk-RMMK64W5.mjs +54 -0
  204. package/dist/chunk-RR2VQLKE.mjs +190 -0
  205. package/dist/chunk-RTC3CFXF.mjs +29 -0
  206. package/dist/chunk-SBZYEV4S.mjs +61 -0
  207. package/dist/chunk-SOA2Z4RB.mjs +82 -0
  208. package/dist/chunk-SOYNZDVY.mjs +151 -0
  209. package/dist/chunk-T7XZ7H7Y.mjs +57 -0
  210. package/dist/chunk-TAJ2PQ2O.mjs +163 -0
  211. package/dist/chunk-U4N7WF4Z.mjs +108 -0
  212. package/dist/chunk-URDE3EUU.mjs +132 -0
  213. package/dist/chunk-URLL5JBR.mjs +245 -0
  214. package/dist/chunk-XDMN67KV.mjs +59 -0
  215. package/dist/chunk-Y6MXOREN.mjs +120 -0
  216. package/dist/chunk-YZJAFS4P.mjs +131 -0
  217. package/dist/index.d.mts +94 -852
  218. package/dist/index.d.ts +94 -852
  219. package/dist/index.js +1387 -942
  220. package/dist/index.mjs +50 -3844
  221. package/package.json +23 -14
  222. package/src/assets/fonts/Sohne-Bold.otf +0 -0
  223. package/src/assets/fonts/Sohne-BoldItalic.otf +0 -0
  224. package/src/assets/fonts/Sohne-ExtraBold.otf +0 -0
  225. package/src/assets/fonts/Sohne-ExtraBoldItalic.otf +0 -0
  226. package/src/assets/fonts/Sohne-ExtraLight.otf +0 -0
  227. package/src/assets/fonts/Sohne-ExtraLightItalic.otf +0 -0
  228. package/src/assets/fonts/Sohne-Italic.otf +0 -0
  229. package/src/assets/fonts/Sohne-Light.otf +0 -0
  230. package/src/assets/fonts/Sohne-LightItalic.otf +0 -0
  231. package/src/assets/fonts/Sohne-Medium.otf +0 -0
  232. package/src/assets/fonts/Sohne-MediumItalic.otf +0 -0
  233. package/src/assets/fonts/Sohne-Regular.otf +0 -0
  234. package/src/assets/fonts/Sohne-SemiBold.otf +0 -0
  235. package/src/assets/fonts/Sohne-SemiBoldItalic.otf +0 -0
  236. package/src/assets/fonts/SohneMono-Bold.otf +0 -0
  237. package/src/assets/fonts/SohneMono-BoldItalic.otf +0 -0
  238. package/src/assets/fonts/SohneMono-ExtraBold.otf +0 -0
  239. package/src/assets/fonts/SohneMono-ExtraBoldItalic.otf +0 -0
  240. package/src/assets/fonts/SohneMono-ExtraLight.otf +0 -0
  241. package/src/assets/fonts/SohneMono-ExtraLightItalic.otf +0 -0
  242. package/src/assets/fonts/SohneMono-Italic.otf +0 -0
  243. package/src/assets/fonts/SohneMono-Light.otf +0 -0
  244. package/src/assets/fonts/SohneMono-LightItalic.otf +0 -0
  245. package/src/assets/fonts/SohneMono-Medium.otf +0 -0
  246. package/src/assets/fonts/SohneMono-MediumItalic.otf +0 -0
  247. package/src/assets/fonts/SohneMono-Regular.otf +0 -0
  248. package/src/assets/fonts/SohneMono-SemiBold.otf +0 -0
  249. package/src/assets/fonts/SohneMono-SemiBoldItalic.otf +0 -0
  250. package/src/components/Accordion/Accordion.tsx +13 -15
  251. package/src/components/AlertBanner/AlertBanner.tsx +33 -12
  252. package/src/components/Avatar/Avatar.tsx +4 -2
  253. package/src/components/Badge/Badge.tsx +4 -2
  254. package/src/components/Button/Button.tsx +30 -29
  255. package/src/components/ButtonGroup/ButtonGroup.tsx +13 -10
  256. package/src/components/Card/Card.tsx +36 -65
  257. package/src/components/CategoryStrip/CategoryStrip.tsx +68 -58
  258. package/src/components/Checkbox/Checkbox.tsx +41 -55
  259. package/src/components/Chip/Chip.tsx +49 -84
  260. package/src/components/ConfirmDialog/ConfirmDialog.tsx +2 -2
  261. package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +4 -2
  262. package/src/components/CurrencyInput/CurrencyInput.tsx +2 -2
  263. package/src/components/DetailRow/DetailRow.tsx +9 -7
  264. package/src/components/EmptyState/EmptyState.tsx +2 -2
  265. package/src/components/Form/Form.tsx +149 -0
  266. package/src/components/Form/index.ts +1 -0
  267. package/src/components/IconButton/IconButton.tsx +24 -20
  268. package/src/components/Input/Input.tsx +63 -50
  269. package/src/components/LabelValue/LabelValue.tsx +6 -4
  270. package/src/components/ListGroup/ListGroup.tsx +145 -0
  271. package/src/components/ListGroup/index.ts +1 -0
  272. package/src/components/ListItem/ListItem.tsx +30 -43
  273. package/src/components/MediaCard/MediaCard.tsx +31 -29
  274. package/src/components/MenuGroup/MenuGroup.tsx +145 -0
  275. package/src/components/MenuGroup/index.ts +1 -0
  276. package/src/components/MenuItem/MenuItem.tsx +29 -40
  277. package/src/components/MonthPicker/MonthPicker.tsx +14 -4
  278. package/src/components/Pressable/Pressable.tsx +27 -46
  279. package/src/components/Progress/Progress.tsx +21 -12
  280. package/src/components/RadioGroup/RadioGroup.tsx +55 -32
  281. package/src/components/Select/Select.tsx +23 -21
  282. package/src/components/Separator/Separator.tsx +1 -3
  283. package/src/components/Sheet/Sheet.tsx +85 -18
  284. package/src/components/Skeleton/Skeleton.tsx +25 -14
  285. package/src/components/Slider/Slider.tsx +13 -3
  286. package/src/components/Spinner/Spinner.tsx +1 -1
  287. package/src/components/Switch/Switch.tsx +70 -52
  288. package/src/components/Tabs/Tabs.tsx +59 -47
  289. package/src/components/Text/Text.tsx +3 -1
  290. package/src/components/Textarea/Textarea.tsx +44 -23
  291. package/src/components/Toast/Toast.tsx +6 -6
  292. package/src/components/Toggle/Toggle.tsx +86 -68
  293. package/src/components/VirtualList/VirtualList.tsx +60 -0
  294. package/src/components/VirtualList/index.ts +1 -0
  295. package/src/fonts.ts +38 -20
  296. package/src/index.ts +5 -1
  297. package/src/theme/colors.ts +53 -39
  298. package/src/theme/types.ts +3 -0
  299. package/src/tokens.ts +49 -39
  300. package/src/utils/animations.ts +58 -0
  301. package/src/utils/icons.ts +47 -20
  302. package/src/utils/useColorTransition.ts +40 -0
  303. package/src/utils/usePressScale.ts +75 -0
  304. package/src/assets/fonts/Poppins-Black.ttf +0 -0
  305. package/src/assets/fonts/Poppins-BlackItalic.ttf +0 -0
  306. package/src/assets/fonts/Poppins-Bold.ttf +0 -0
  307. package/src/assets/fonts/Poppins-BoldItalic.ttf +0 -0
  308. package/src/assets/fonts/Poppins-ExtraBold.ttf +0 -0
  309. package/src/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
  310. package/src/assets/fonts/Poppins-ExtraLight.ttf +0 -0
  311. package/src/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
  312. package/src/assets/fonts/Poppins-Italic.ttf +0 -0
  313. package/src/assets/fonts/Poppins-Light.ttf +0 -0
  314. package/src/assets/fonts/Poppins-LightItalic.ttf +0 -0
  315. package/src/assets/fonts/Poppins-Medium.ttf +0 -0
  316. package/src/assets/fonts/Poppins-MediumItalic.ttf +0 -0
  317. package/src/assets/fonts/Poppins-Regular.ttf +0 -0
  318. package/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
  319. package/src/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
  320. package/src/assets/fonts/Poppins-Thin.ttf +0 -0
  321. package/src/assets/fonts/Poppins-ThinItalic.ttf +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retray-dev/ui-kit",
3
- "version": "6.1.0",
3
+ "version": "7.0.1",
4
4
  "description": "Personal UI Kit for React Native / Expo",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -11,7 +11,12 @@
11
11
  "import": "./dist/index.mjs",
12
12
  "require": "./dist/index.js"
13
13
  },
14
- "./fonts": "./src/fonts.ts"
14
+ "./fonts": "./src/fonts.ts",
15
+ "./*": {
16
+ "types": "./dist/*.d.ts",
17
+ "import": "./dist/*.mjs",
18
+ "require": "./dist/*.js"
19
+ }
15
20
  },
16
21
  "files": [
17
22
  "dist",
@@ -29,6 +34,7 @@
29
34
  "format:check": "prettier --check src",
30
35
  "lint:all": "pnpm lint && pnpm --filter retray-ui-kit-example lint",
31
36
  "format:all": "pnpm format && pnpm --filter retray-ui-kit-example format",
37
+ "verify": "pnpm typecheck && pnpm lint && pnpm build",
32
38
  "deploy": "pnpm typecheck && pnpm build && npm publish --access public"
33
39
  },
34
40
  "keywords": [
@@ -51,17 +57,20 @@
51
57
  "react-native-gesture-handler": ">=2.0.0",
52
58
  "react-native-reanimated": ">=4.0.0",
53
59
  "react-native-safe-area-context": ">=4.0.0",
60
+ "react-native-screens": ">=3.0.0",
54
61
  "react-native-size-matters": ">=0.4.0",
55
- "react-native-worklets": ">=0.5.0",
56
62
  "react-native-svg": ">=15.0.0",
57
- "react-native-screens": ">=3.0.0"
63
+ "react-native-worklets": ">=0.5.0"
58
64
  },
59
65
  "pnpm": {
60
66
  "overrides": {
61
67
  "fast-xml-parser": "^5.5.7",
62
68
  "react": "19.1.0",
63
69
  "react-native": "0.81.5",
64
- "react-native-worklets": "0.5.1"
70
+ "react-native-worklets": "0.5.1",
71
+ "@types/react": "19.1.17",
72
+ "react-native-safe-area-context": "5.6.2",
73
+ "@gorhom/bottom-sheet": "5.2.8"
65
74
  },
66
75
  "onlyBuiltDependencies": [
67
76
  "esbuild"
@@ -69,32 +78,32 @@
69
78
  },
70
79
  "devDependencies": {
71
80
  "@eslint/js": "^9.0.0",
72
- "react-native-size-matters": "^0.4.2",
73
81
  "@expo/vector-icons": "^15.1.1",
74
- "@gorhom/bottom-sheet": "^5.0.0",
82
+ "@gorhom/bottom-sheet": "5.2.8",
75
83
  "@react-native-community/slider": "5.0.1",
76
84
  "@react-native-picker/picker": "2.11.1",
77
- "@types/react": "^19.1.0",
85
+ "@types/react": "19.1.17",
78
86
  "eslint": "^9.0.0",
79
87
  "eslint-config-prettier": "^10.0.0",
80
88
  "eslint-plugin-react": "^7.37.0",
81
- "eslint-plugin-react-hooks": "^5.0.0",
89
+ "eslint-plugin-react-hooks": "^7.1.1",
82
90
  "expo-font": "~14.0.11",
83
91
  "expo-haptics": "~15.0.8",
84
92
  "expo-linear-gradient": "~15.0.8",
85
- "prettier": "^3.0.0",
93
+ "prettier": "^3.8.3",
86
94
  "react": "19.1.0",
87
95
  "react-native": "0.81.5",
88
96
  "react-native-gesture-handler": "~2.28.0",
89
97
  "react-native-reanimated": "~4.1.1",
90
- "react-native-safe-area-context": "~5.6.2",
98
+ "react-native-safe-area-context": "5.6.2",
99
+ "react-native-screens": "4.16.0",
100
+ "react-native-size-matters": "^0.4.2",
101
+ "react-native-svg": "15.12.1",
91
102
  "react-native-worklets": "~0.5.1",
92
103
  "sonner-native": "0.23.1",
93
- "react-native-svg": "15.12.1",
94
- "react-native-screens": "4.16.0",
95
104
  "tsup": "^8.0.0",
96
105
  "typescript": "^5.4.0",
97
- "typescript-eslint": "^8.0.0"
106
+ "typescript-eslint": "^8.60.0"
98
107
  },
99
108
  "packageManager": "pnpm@11.0.8+sha512.4c4097e1dd2d42372c4e7fa5a791ff28fc75a484c7ac192e64b1df0fdef17594ba982f9b4fed9adfb3c757846f565b799b2763fb3733d1de1bcb82cf46684912"
100
109
  }
Binary file
Binary file
@@ -11,17 +11,13 @@ import Animated, {
11
11
  useDerivedValue,
12
12
  useAnimatedStyle,
13
13
  withTiming,
14
- Easing,
15
- type EasingFunction,
16
14
  } from 'react-native-reanimated'
17
-
18
- const easingExpand: EasingFunction = Easing.bezier(0.23, 1, 0.32, 1) as unknown as EasingFunction
19
- const easingCollapse: EasingFunction = Easing.in(Easing.ease)
20
15
  import { Entypo } from '@expo/vector-icons'
21
16
  import { selectionAsync as hapticSelection } from '../../utils/haptics'
22
17
  import { useTheme } from '../../theme'
23
18
  import { s, vs, ms } from '../../utils/scaling'
24
19
  import { renderIcon } from '../../utils/icons'
20
+ import { TIMINGS, EASINGS } from '../../utils/animations'
25
21
 
26
22
  export interface AccordionItem {
27
23
  value: string
@@ -69,22 +65,21 @@ function AccordionItemComponent({
69
65
  // Keep isExpanded in sync with the parent-driven isOpen prop
70
66
  React.useEffect(() => {
71
67
  isExpanded.value = isOpen
72
- }, [isOpen])
68
+ }, [isOpen, isExpanded])
73
69
 
74
- // Derived animated height — pattern from Reanimated docs:
75
- // height * Number(isExpanded) gives 0 when closed and the measured height when open.
76
- // withTiming wraps it so every change animates automatically.
70
+ // Derived animated height — height * Number(isExpanded) gives 0 when closed and
71
+ // the measured height when open. `withTiming` wraps it so every change animates.
77
72
  const derivedHeight = useDerivedValue(() =>
78
73
  withTiming(height.value * Number(isExpanded.value), {
79
- duration: 220,
80
- easing: isExpanded.value ? easingExpand : easingCollapse,
74
+ duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
75
+ easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse,
81
76
  })
82
77
  )
83
78
 
84
79
  const derivedRotation = useDerivedValue(() =>
85
80
  withTiming(isExpanded.value ? 1 : 0, {
86
- duration: 220,
87
- easing: isExpanded.value ? easingExpand : easingCollapse,
81
+ duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
82
+ easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse,
88
83
  })
89
84
  )
90
85
 
@@ -105,6 +100,9 @@ function AccordionItemComponent({
105
100
  hapticSelection()
106
101
  onToggle()
107
102
  }}
103
+ accessibilityRole="button"
104
+ accessibilityState={{ expanded: isOpen }}
105
+ accessibilityLabel={item.trigger}
108
106
  >
109
107
  <View style={styles.triggerContent}>
110
108
  {resolvedIcon ? <View style={styles.icon}>{resolvedIcon}</View> : null}
@@ -192,7 +190,7 @@ const styles = StyleSheet.create({
192
190
  justifyContent: 'center',
193
191
  },
194
192
  triggerText: {
195
- fontFamily: 'Poppins-Medium',
193
+ fontFamily: 'Sohne-Medium',
196
194
  fontSize: ms(14),
197
195
  },
198
196
  chevron: {
@@ -201,7 +199,7 @@ const styles = StyleSheet.create({
201
199
  // position:'absolute' is the key — the inner View escapes the animated wrapper's
202
200
  // clipped height so onLayout always reports the true content height.
203
201
  content: {
204
- paddingHorizontal: s(14),
202
+ paddingHorizontal: s(8),
205
203
  paddingBottom: vs(12),
206
204
  position: 'absolute',
207
205
  width: '100%',
@@ -19,13 +19,29 @@ export interface AlertBannerProps {
19
19
  }
20
20
 
21
21
  export function AlertBanner({ title, description, variant = 'default', icon, iconName, iconColor, style }: AlertBannerProps) {
22
- const { colors } = useTheme()
22
+ const { colors, colorScheme } = useTheme()
23
+
24
+ // Match Toast richColors appearance — saturated semantic colors
25
+ const isDark = colorScheme === 'dark'
23
26
 
24
27
  const accentColor =
25
28
  variant === 'destructive' ? colors.destructive
26
29
  : variant === 'success' ? colors.success
27
30
  : variant === 'warning' ? colors.warning
28
- : colors.primary
31
+ : colors.foreground
32
+
33
+ // Match sonner-native richColors backgrounds (more saturated than tint)
34
+ const bgColor =
35
+ variant === 'destructive' ? (isDark ? 'rgba(239, 83, 80, 0.15)' : 'rgba(199, 40, 40, 0.10)')
36
+ : variant === 'success' ? (isDark ? 'rgba(46, 125, 82, 0.15)' : 'rgba(26, 122, 69, 0.10)')
37
+ : variant === 'warning' ? (isDark ? 'rgba(245, 166, 35, 0.15)' : 'rgba(154, 82, 0, 0.10)')
38
+ : colors.surface
39
+
40
+ const borderColor =
41
+ variant === 'destructive' ? (isDark ? 'rgba(239, 83, 80, 0.30)' : 'rgba(199, 40, 40, 0.25)')
42
+ : variant === 'success' ? (isDark ? 'rgba(46, 125, 82, 0.30)' : 'rgba(26, 122, 69, 0.25)')
43
+ : variant === 'warning' ? (isDark ? 'rgba(245, 166, 35, 0.30)' : 'rgba(154, 82, 0, 0.25)')
44
+ : colors.border
29
45
 
30
46
  const defaultIcon =
31
47
  variant === 'success' ? (
@@ -35,6 +51,9 @@ export function AlertBanner({ title, description, variant = 'default', icon, ico
35
51
  ) : variant === 'warning' ? (
36
52
  <MaterialIcons name="warning-amber" size={ms(17)} color={accentColor} />
37
53
  ) : (
54
+ // AUDIT FIX: default variant previously used colors.primary (near-black)
55
+ // as the info icon tint — ambiguous and heavy. accentResolved gives it
56
+ // a meaningful chromatic signal when an accent is defined.
38
57
  <Entypo name="info-with-circle" size={ms(16)} color={accentColor} />
39
58
  )
40
59
 
@@ -43,14 +62,18 @@ export function AlertBanner({ title, description, variant = 'default', icon, ico
43
62
  : icon ?? defaultIcon
44
63
 
45
64
  return (
46
- <View style={[styles.container, { backgroundColor: colors.card }, style]}>
47
- {/* Icon */}
65
+ <View
66
+ style={[
67
+ styles.container,
68
+ { backgroundColor: bgColor, borderWidth: 1, borderColor },
69
+ style,
70
+ ]}
71
+ >
48
72
  <View style={styles.iconSlot}>{effectiveIcon}</View>
49
- {/* Text */}
50
73
  <View style={styles.content}>
51
74
  <Text style={[styles.title, { color: colors.foreground }]} allowFontScaling={true}>{title}</Text>
52
75
  {description ? (
53
- <Text style={[styles.description, { color: colors.foregroundMuted }]} allowFontScaling={true}>{description}</Text>
76
+ <Text style={[styles.description, { color: colors.foreground, opacity: 0.85 }]} allowFontScaling={true}>{description}</Text>
54
77
  ) : null}
55
78
  </View>
56
79
  </View>
@@ -63,8 +86,8 @@ const styles = StyleSheet.create({
63
86
  alignItems: 'flex-start',
64
87
  borderRadius: RADIUS.lg,
65
88
  gap: s(8),
66
- paddingVertical: vs(8),
67
- paddingHorizontal: s(10),
89
+ paddingVertical: vs(10),
90
+ paddingHorizontal: s(12),
68
91
  },
69
92
  iconSlot: {
70
93
  marginTop: vs(1),
@@ -74,13 +97,11 @@ const styles = StyleSheet.create({
74
97
  gap: vs(2),
75
98
  },
76
99
  title: {
77
- fontFamily: 'Poppins-Medium',
100
+ fontFamily: 'Sohne-Medium',
78
101
  fontSize: ms(13),
79
- lineHeight: ms(19),
80
102
  },
81
103
  description: {
82
- fontFamily: 'Poppins-Regular',
104
+ fontFamily: 'Sohne-Regular',
83
105
  fontSize: ms(12),
84
- lineHeight: ms(17),
85
106
  },
86
107
  })
@@ -50,7 +50,7 @@ function getInitials(fallback?: string, fallbackText?: string): string {
50
50
  return '?'
51
51
  }
52
52
 
53
- export function Avatar({ src, fallback, fallbackText, size = 'md', status, style }: AvatarProps) {
53
+ function AvatarBase({ src, fallback, fallbackText, size = 'md', status, style }: AvatarProps) {
54
54
  const { colors } = useTheme()
55
55
  const [imageError, setImageError] = useState(false)
56
56
  const dimension = typeof size === 'number' ? size : sizeMap[size as AvatarSize]
@@ -111,6 +111,8 @@ export function Avatar({ src, fallback, fallbackText, size = 'md', status, style
111
111
  )
112
112
  }
113
113
 
114
+ export const Avatar = React.memo(AvatarBase)
115
+
114
116
  const styles = StyleSheet.create({
115
117
  wrapper: {
116
118
  alignSelf: 'flex-start',
@@ -121,7 +123,7 @@ const styles = StyleSheet.create({
121
123
  justifyContent: 'center',
122
124
  },
123
125
  fallback: {
124
- fontFamily: 'Poppins-Medium',
126
+ fontFamily: 'Sohne-Medium',
125
127
  },
126
128
  statusDot: {
127
129
  position: 'absolute',
@@ -45,7 +45,7 @@ const sizeIconGap: Record<BadgeSize, number> = {
45
45
 
46
46
  const sizeIconSize: Record<BadgeSize, number> = { sm: 10, md: 12, lg: 14 }
47
47
 
48
- export function Badge({ label, children, variant = 'default', size = 'md', icon, iconName, iconColor, style }: BadgeProps) {
48
+ function BadgeBase({ label, children, variant = 'default', size = 'md', icon, iconName, iconColor, style }: BadgeProps) {
49
49
  const { colors } = useTheme()
50
50
 
51
51
  const containerStyle: ViewStyle = {
@@ -92,6 +92,8 @@ export function Badge({ label, children, variant = 'default', size = 'md', icon,
92
92
  )
93
93
  }
94
94
 
95
+ export const Badge = React.memo(BadgeBase)
96
+
95
97
  const styles = StyleSheet.create({
96
98
  container: {
97
99
  borderRadius: 9999,
@@ -100,6 +102,6 @@ const styles = StyleSheet.create({
100
102
  alignItems: 'center',
101
103
  },
102
104
  label: {
103
- fontFamily: 'Poppins-Medium',
105
+ fontFamily: 'Sohne-Medium',
104
106
  },
105
107
  })
@@ -1,27 +1,22 @@
1
- import React, { useRef } from 'react'
1
+ import React from 'react'
2
2
  import {
3
3
  TouchableOpacity,
4
4
  Text,
5
- Animated,
6
5
  ActivityIndicator,
7
6
  StyleSheet,
8
7
  TouchableOpacityProps,
9
8
  ViewStyle,
10
9
  TextStyle,
11
- Platform,
12
10
  } from 'react-native'
13
-
14
- const nativeDriver = Platform.OS !== 'web'
11
+ import Animated from 'react-native-reanimated'
15
12
  import { impactMedium } from '../../utils/haptics'
16
13
  import { useTheme } from '../../theme'
17
14
  import { s, vs, ms, mvs } from '../../utils/scaling'
18
15
  import { renderIcon } from '../../utils/icons'
19
16
  import { RADIUS, TYPOGRAPHY } from '../../tokens'
17
+ import { usePressScale } from '../../utils/usePressScale'
18
+ import { PRESS_SCALE } from '../../utils/animations'
20
19
 
21
- // primary: filled primary — main CTA (pill-shaped, Airbnb-style)
22
- // secondary: outlined primary border — alternative actions
23
- // text: fully transparent — low-emphasis, in-context actions
24
- // destructive: filled destructive — delete/danger actions
25
20
  export type ButtonVariant = 'primary' | 'secondary' | 'text' | 'destructive'
26
21
  export type ButtonSize = 'sm' | 'md' | 'lg'
27
22
 
@@ -37,7 +32,6 @@ export interface ButtonProps extends TouchableOpacityProps {
37
32
  iconPosition?: 'left' | 'right'
38
33
  }
39
34
 
40
- // Airbnb-spec sizing: md=48px height, padding 14px vertical 24px horizontal
41
35
  const containerSizeStyles: Record<ButtonSize, ViewStyle> = {
42
36
  sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
43
37
  md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
@@ -52,7 +46,7 @@ const labelSizeStyles: Record<ButtonSize, TextStyle> = {
52
46
 
53
47
  const iconSizeMap: Record<ButtonSize, number> = { sm: 16, md: 18, lg: 20 }
54
48
 
55
- export function Button({
49
+ function ButtonBase({
56
50
  label,
57
51
  variant = 'primary',
58
52
  size = 'md',
@@ -65,20 +59,16 @@ export function Button({
65
59
  disabled,
66
60
  style,
67
61
  onPress,
62
+ accessibilityLabel,
63
+ accessibilityHint,
68
64
  ...props
69
65
  }: ButtonProps) {
70
66
  const { colors } = useTheme()
71
67
  const isDisabled = disabled || loading
72
- const scale = useRef(new Animated.Value(1)).current
73
-
74
- const handlePressIn = () => {
75
- if (isDisabled) return
76
- Animated.spring(scale, { toValue: 0.95, useNativeDriver: nativeDriver, stiffness: 600, damping: 35, mass: 0.8 }).start()
77
- }
78
-
79
- const handlePressOut = () => {
80
- Animated.spring(scale, { toValue: 1, useNativeDriver: nativeDriver, stiffness: 280, damping: 22, mass: 0.8 }).start()
81
- }
68
+ const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
69
+ pressScale: PRESS_SCALE.button,
70
+ disabled: isDisabled,
71
+ })
82
72
 
83
73
  const handlePress: TouchableOpacityProps['onPress'] = (e) => {
84
74
  impactMedium()
@@ -95,7 +85,10 @@ export function Button({
95
85
  const labelVariantStyle: TextStyle = {
96
86
  primary: { color: colors.primaryForeground },
97
87
  secondary: { color: colors.primary },
98
- text: { color: colors.foreground },
88
+ // AUDIT FIX: was colors.foreground — visually indistinguishable from plain text,
89
+ // no affordance that it's a CTA. Now uses accentResolved so text-only buttons
90
+ // carry the brand voltage. Falls back to primary when no accent is defined.
91
+ text: { color: colors.accentResolved },
99
92
  destructive: { color: colors.destructiveForeground },
100
93
  }[variant]
101
94
 
@@ -108,15 +101,17 @@ export function Button({
108
101
  const spinnerColor =
109
102
  variant === 'destructive' ? colors.destructiveForeground
110
103
  : variant === 'primary' ? colors.primaryForeground
111
- : colors.foreground
104
+ : colors.accentResolved
112
105
 
113
- // Extract flex from style for wrapper — ButtonGroup sets flex: 1
114
106
  const styleArray = Array.isArray(style) ? style : style ? [style] : []
115
107
  const flatStyle = StyleSheet.flatten(styleArray)
116
108
  const { flex, ...restStyle } = flatStyle || {}
117
109
 
118
110
  return (
119
- <Animated.View style={[fullWidth && styles.fullWidth, flex !== undefined && { flex }, { transform: [{ scale }] }]}>
111
+ <Animated.View
112
+ style={[fullWidth && styles.fullWidth, flex !== undefined && { flex }, animatedStyle]}
113
+ {...hoverHandlers}
114
+ >
120
115
  <TouchableOpacity
121
116
  style={[
122
117
  styles.base,
@@ -130,8 +125,12 @@ export function Button({
130
125
  activeOpacity={1}
131
126
  touchSoundDisabled={true}
132
127
  onPress={handlePress}
133
- onPressIn={handlePressIn}
134
- onPressOut={handlePressOut}
128
+ onPressIn={onPressIn}
129
+ onPressOut={onPressOut}
130
+ accessibilityRole="button"
131
+ accessibilityLabel={accessibilityLabel ?? label}
132
+ accessibilityHint={accessibilityHint}
133
+ accessibilityState={{ disabled: isDisabled, busy: loading }}
135
134
  {...props}
136
135
  >
137
136
  {loading ? (
@@ -163,9 +162,11 @@ export function Button({
163
162
  )
164
163
  }
165
164
 
165
+ export const Button = React.memo(ButtonBase)
166
+
166
167
  const styles = StyleSheet.create({
167
168
  base: {
168
- borderRadius: RADIUS.md, // 14px — Airbnb-aligned rounded rect (not pill)
169
+ borderRadius: RADIUS.md,
169
170
  alignItems: 'center',
170
171
  justifyContent: 'center',
171
172
  flexDirection: 'row',
@@ -177,7 +178,7 @@ const styles = StyleSheet.create({
177
178
  opacity: 0.45,
178
179
  },
179
180
  label: {
180
- fontFamily: 'Poppins-Medium',
181
+ fontFamily: 'Sohne-Medium',
181
182
  flexShrink: 1,
182
183
  },
183
184
  labelWithIcon: {
@@ -33,16 +33,19 @@ export function ButtonGroup({ children, gap = 12, vertical = false, style }: But
33
33
  style,
34
34
  ]}
35
35
  >
36
- {React.Children.map(children, (child) =>
37
- React.isValidElement(child)
38
- ? React.cloneElement(child as React.ReactElement<any>, {
39
- style: [
40
- (child as React.ReactElement<any>).props.style,
41
- { flex: 1 },
42
- ],
43
- })
44
- : child,
45
- )}
36
+ {React.Children.map(children, (child) => {
37
+ if (!React.isValidElement(child)) return child
38
+ const childProps = child.props as Record<string, unknown>
39
+ const extraProps: Record<string, unknown> = {
40
+ style: [(child as React.ReactElement<{ style?: unknown }>).props.style, { flex: 1 }],
41
+ }
42
+ // Horizontal ButtonGroup: default Button children to sm size to prevent
43
+ // oversized layout. Only applies when consumer hasn't explicitly set size.
44
+ if (!vertical && 'label' in childProps && childProps['size'] === undefined) {
45
+ extraProps['size'] = 'sm'
46
+ }
47
+ return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, extraProps)
48
+ })}
46
49
  </View>
47
50
  )
48
51
  }