orn-ui 0.2.9 → 0.3.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 (552) hide show
  1. package/AGENTS.md +67 -52
  2. package/README.md +5 -9
  3. package/lib/commonjs/atoms/Avatar.js +77 -5
  4. package/lib/commonjs/atoms/Avatar.js.map +1 -1
  5. package/lib/commonjs/atoms/Badge.js +17 -8
  6. package/lib/commonjs/atoms/Badge.js.map +1 -1
  7. package/lib/commonjs/atoms/Button.js +108 -39
  8. package/lib/commonjs/atoms/Button.js.map +1 -1
  9. package/lib/commonjs/atoms/Card.js +24 -2
  10. package/lib/commonjs/atoms/Card.js.map +1 -1
  11. package/lib/commonjs/atoms/Checkbox.js +41 -10
  12. package/lib/commonjs/atoms/Checkbox.js.map +1 -1
  13. package/lib/commonjs/atoms/Divider.js +30 -5
  14. package/lib/commonjs/atoms/Divider.js.map +1 -1
  15. package/lib/commonjs/atoms/EmptyState.js +58 -20
  16. package/lib/commonjs/atoms/EmptyState.js.map +1 -1
  17. package/lib/commonjs/atoms/Fab.js +32 -12
  18. package/lib/commonjs/atoms/Fab.js.map +1 -1
  19. package/lib/commonjs/atoms/Gradient.js +102 -36
  20. package/lib/commonjs/atoms/Gradient.js.map +1 -1
  21. package/lib/commonjs/atoms/IconButton.js +25 -4
  22. package/lib/commonjs/atoms/IconButton.js.map +1 -1
  23. package/lib/commonjs/atoms/Image.js +61 -25
  24. package/lib/commonjs/atoms/Image.js.map +1 -1
  25. package/lib/commonjs/atoms/Input.js +105 -17
  26. package/lib/commonjs/atoms/Input.js.map +1 -1
  27. package/lib/commonjs/atoms/KeyValueRow.js +37 -9
  28. package/lib/commonjs/atoms/KeyValueRow.js.map +1 -1
  29. package/lib/commonjs/atoms/PressableScale.js +25 -5
  30. package/lib/commonjs/atoms/PressableScale.js.map +1 -1
  31. package/lib/commonjs/atoms/ShinyText.js +29 -29
  32. package/lib/commonjs/atoms/Skeleton.js +28 -13
  33. package/lib/commonjs/atoms/Skeleton.js.map +1 -1
  34. package/lib/commonjs/atoms/Spinner.js +81 -22
  35. package/lib/commonjs/atoms/Spinner.js.map +1 -1
  36. package/lib/commonjs/atoms/Text.js +56 -5
  37. package/lib/commonjs/atoms/Text.js.map +1 -1
  38. package/lib/commonjs/atoms/Transition.js +46 -43
  39. package/lib/commonjs/atoms/Transition.js.map +1 -1
  40. package/lib/commonjs/atoms/index.js +6 -0
  41. package/lib/commonjs/atoms/index.js.map +1 -1
  42. package/lib/commonjs/atoms/inputValidation.js +56 -0
  43. package/lib/commonjs/atoms/inputValidation.js.map +1 -0
  44. package/lib/commonjs/icons/Icon.js +4 -4
  45. package/lib/commonjs/icons/defaultIcons.js +576 -24
  46. package/lib/commonjs/icons/defaultIcons.js.map +1 -1
  47. package/lib/commonjs/icons/index.js +6 -0
  48. package/lib/commonjs/icons/index.js.map +1 -1
  49. package/lib/commonjs/molecules/AvatarHeader.js +47 -14
  50. package/lib/commonjs/molecules/AvatarHeader.js.map +1 -1
  51. package/lib/commonjs/molecules/FormActions.js +25 -9
  52. package/lib/commonjs/molecules/FormActions.js.map +1 -1
  53. package/lib/commonjs/molecules/InfoRow.js +30 -14
  54. package/lib/commonjs/molecules/InfoRow.js.map +1 -1
  55. package/lib/commonjs/molecules/OptionCard.js +37 -22
  56. package/lib/commonjs/molecules/OptionCard.js.map +1 -1
  57. package/lib/commonjs/molecules/SegmentedControl.js +103 -14
  58. package/lib/commonjs/molecules/SegmentedControl.js.map +1 -1
  59. package/lib/commonjs/molecules/Stepper.js +61 -16
  60. package/lib/commonjs/molecules/Stepper.js.map +1 -1
  61. package/lib/commonjs/molecules/Steps.js +105 -41
  62. package/lib/commonjs/molecules/Steps.js.map +1 -1
  63. package/lib/commonjs/molecules/SymmetricGrid.js +26 -18
  64. package/lib/commonjs/molecules/SymmetricGrid.js.map +1 -1
  65. package/lib/commonjs/organisms/Alert.js +49 -35
  66. package/lib/commonjs/organisms/Alert.js.map +1 -1
  67. package/lib/commonjs/organisms/AlertProvider.js +10 -10
  68. package/lib/commonjs/organisms/BottomSheet.js +137 -85
  69. package/lib/commonjs/organisms/BottomSheet.js.map +1 -1
  70. package/lib/commonjs/organisms/Chart.js +197 -156
  71. package/lib/commonjs/organisms/Chart.js.map +1 -1
  72. package/lib/commonjs/organisms/DateField.js +36 -20
  73. package/lib/commonjs/organisms/DateField.js.map +1 -1
  74. package/lib/commonjs/organisms/DatePicker.js +56 -33
  75. package/lib/commonjs/organisms/DatePicker.js.map +1 -1
  76. package/lib/commonjs/organisms/List.js +62 -34
  77. package/lib/commonjs/organisms/List.js.map +1 -1
  78. package/lib/commonjs/organisms/Modal.js +120 -82
  79. package/lib/commonjs/organisms/Modal.js.map +1 -1
  80. package/lib/commonjs/organisms/NavigationBar.js +63 -24
  81. package/lib/commonjs/organisms/NavigationBar.js.map +1 -1
  82. package/lib/commonjs/organisms/OptionWheel.js +64 -64
  83. package/lib/commonjs/organisms/OptionWheel.js.map +1 -1
  84. package/lib/commonjs/organisms/ReorderableList.js +48 -27
  85. package/lib/commonjs/organisms/ReorderableList.js.map +1 -1
  86. package/lib/commonjs/organisms/Screen.js +68 -35
  87. package/lib/commonjs/organisms/Screen.js.map +1 -1
  88. package/lib/commonjs/organisms/SearchList.js +56 -26
  89. package/lib/commonjs/organisms/SearchList.js.map +1 -1
  90. package/lib/commonjs/organisms/Select.js +45 -24
  91. package/lib/commonjs/organisms/Select.js.map +1 -1
  92. package/lib/commonjs/organisms/Slides.js +36 -23
  93. package/lib/commonjs/organisms/Slides.js.map +1 -1
  94. package/lib/commonjs/organisms/ThemeToggle.js +10 -9
  95. package/lib/commonjs/organisms/ThemeToggle.js.map +1 -1
  96. package/lib/commonjs/organisms/Timeline.js +73 -56
  97. package/lib/commonjs/organisms/Timeline.js.map +1 -1
  98. package/lib/commonjs/organisms/Toast.js +46 -15
  99. package/lib/commonjs/organisms/Toast.js.map +1 -1
  100. package/lib/commonjs/organisms/ToastProvider.js +14 -10
  101. package/lib/commonjs/organisms/ToastProvider.js.map +1 -1
  102. package/lib/commonjs/organisms/Wizard.js +40 -15
  103. package/lib/commonjs/organisms/Wizard.js.map +1 -1
  104. package/lib/commonjs/organisms/chart/frame.js +25 -25
  105. package/lib/commonjs/organisms/chart/frame.js.map +1 -1
  106. package/lib/commonjs/organisms/chart/marks.js +42 -42
  107. package/lib/commonjs/organisms/chart/math.js +84 -85
  108. package/lib/commonjs/organisms/chart/math.js.map +1 -1
  109. package/lib/commonjs/organisms/chart/palette.js +28 -28
  110. package/lib/commonjs/organisms/imperativeBridge.js +5 -5
  111. package/lib/commonjs/organisms/imperativeBridge.js.map +1 -1
  112. package/lib/commonjs/organisms/useSlides.js +53 -21
  113. package/lib/commonjs/organisms/useSlides.js.map +1 -1
  114. package/lib/commonjs/safe-area/SafeAreaUIProvider.js +9 -66
  115. package/lib/commonjs/safe-area/SafeAreaUIProvider.js.map +1 -1
  116. package/lib/commonjs/safe-area/index.js.map +1 -1
  117. package/lib/commonjs/theme/KeyboardAvoidance.js +206 -0
  118. package/lib/commonjs/theme/KeyboardAvoidance.js.map +1 -0
  119. package/lib/commonjs/theme/NativeOverlay.js +263 -0
  120. package/lib/commonjs/theme/NativeOverlay.js.map +1 -0
  121. package/lib/commonjs/theme/UIProvider.js +86 -33
  122. package/lib/commonjs/theme/UIProvider.js.map +1 -1
  123. package/lib/commonjs/theme/colors.js +17 -17
  124. package/lib/commonjs/theme/colors.js.map +1 -1
  125. package/lib/commonjs/theme/createStyles.js +19 -16
  126. package/lib/commonjs/theme/createStyles.js.map +1 -1
  127. package/lib/commonjs/theme/createTheme.js +6 -6
  128. package/lib/commonjs/theme/index.js +6 -0
  129. package/lib/commonjs/theme/index.js.map +1 -1
  130. package/lib/commonjs/theme/insets.js +1 -1
  131. package/lib/commonjs/theme/labels.js +29 -1
  132. package/lib/commonjs/theme/labels.js.map +1 -1
  133. package/lib/commonjs/theme/palettes.js +25 -23
  134. package/lib/commonjs/theme/palettes.js.map +1 -1
  135. package/lib/commonjs/theme/tokens.js +28 -14
  136. package/lib/commonjs/theme/tokens.js.map +1 -1
  137. package/lib/commonjs/theme/useKeyboardField.js +36 -0
  138. package/lib/commonjs/theme/useKeyboardField.js.map +1 -0
  139. package/lib/commonjs/theme/useReduceMotion.js +31 -0
  140. package/lib/commonjs/theme/useReduceMotion.js.map +1 -0
  141. package/lib/module/atoms/Avatar.js +79 -8
  142. package/lib/module/atoms/Avatar.js.map +1 -1
  143. package/lib/module/atoms/Badge.js +17 -8
  144. package/lib/module/atoms/Badge.js.map +1 -1
  145. package/lib/module/atoms/Button.js +110 -41
  146. package/lib/module/atoms/Button.js.map +1 -1
  147. package/lib/module/atoms/Card.js +24 -2
  148. package/lib/module/atoms/Card.js.map +1 -1
  149. package/lib/module/atoms/Checkbox.js +42 -11
  150. package/lib/module/atoms/Checkbox.js.map +1 -1
  151. package/lib/module/atoms/Divider.js +31 -6
  152. package/lib/module/atoms/Divider.js.map +1 -1
  153. package/lib/module/atoms/EmptyState.js +58 -20
  154. package/lib/module/atoms/EmptyState.js.map +1 -1
  155. package/lib/module/atoms/Fab.js +33 -13
  156. package/lib/module/atoms/Fab.js.map +1 -1
  157. package/lib/module/atoms/Gradient.js +103 -37
  158. package/lib/module/atoms/Gradient.js.map +1 -1
  159. package/lib/module/atoms/IconButton.js +25 -4
  160. package/lib/module/atoms/IconButton.js.map +1 -1
  161. package/lib/module/atoms/Image.js +61 -25
  162. package/lib/module/atoms/Image.js.map +1 -1
  163. package/lib/module/atoms/Input.js +108 -20
  164. package/lib/module/atoms/Input.js.map +1 -1
  165. package/lib/module/atoms/KeyValueRow.js +37 -9
  166. package/lib/module/atoms/KeyValueRow.js.map +1 -1
  167. package/lib/module/atoms/PressableScale.js +25 -5
  168. package/lib/module/atoms/PressableScale.js.map +1 -1
  169. package/lib/module/atoms/ShinyText.js +29 -29
  170. package/lib/module/atoms/Skeleton.js +30 -13
  171. package/lib/module/atoms/Skeleton.js.map +1 -1
  172. package/lib/module/atoms/Spinner.js +82 -23
  173. package/lib/module/atoms/Spinner.js.map +1 -1
  174. package/lib/module/atoms/Text.js +56 -5
  175. package/lib/module/atoms/Text.js.map +1 -1
  176. package/lib/module/atoms/Transition.js +41 -42
  177. package/lib/module/atoms/Transition.js.map +1 -1
  178. package/lib/module/atoms/index.js +1 -1
  179. package/lib/module/atoms/index.js.map +1 -1
  180. package/lib/module/atoms/inputValidation.js +52 -0
  181. package/lib/module/atoms/inputValidation.js.map +1 -0
  182. package/lib/module/icons/Icon.js +4 -4
  183. package/lib/module/icons/defaultIcons.js +574 -24
  184. package/lib/module/icons/defaultIcons.js.map +1 -1
  185. package/lib/module/icons/index.js +1 -1
  186. package/lib/module/icons/index.js.map +1 -1
  187. package/lib/module/molecules/AvatarHeader.js +47 -14
  188. package/lib/module/molecules/AvatarHeader.js.map +1 -1
  189. package/lib/module/molecules/FormActions.js +25 -9
  190. package/lib/module/molecules/FormActions.js.map +1 -1
  191. package/lib/module/molecules/InfoRow.js +30 -14
  192. package/lib/module/molecules/InfoRow.js.map +1 -1
  193. package/lib/module/molecules/OptionCard.js +37 -22
  194. package/lib/module/molecules/OptionCard.js.map +1 -1
  195. package/lib/module/molecules/SegmentedControl.js +107 -18
  196. package/lib/module/molecules/SegmentedControl.js.map +1 -1
  197. package/lib/module/molecules/Stepper.js +63 -18
  198. package/lib/module/molecules/Stepper.js.map +1 -1
  199. package/lib/module/molecules/Steps.js +107 -43
  200. package/lib/module/molecules/Steps.js.map +1 -1
  201. package/lib/module/molecules/SymmetricGrid.js +26 -18
  202. package/lib/module/molecules/SymmetricGrid.js.map +1 -1
  203. package/lib/module/organisms/Alert.js +51 -37
  204. package/lib/module/organisms/Alert.js.map +1 -1
  205. package/lib/module/organisms/AlertProvider.js +10 -10
  206. package/lib/module/organisms/BottomSheet.js +142 -88
  207. package/lib/module/organisms/BottomSheet.js.map +1 -1
  208. package/lib/module/organisms/Chart.js +199 -158
  209. package/lib/module/organisms/Chart.js.map +1 -1
  210. package/lib/module/organisms/DateField.js +36 -20
  211. package/lib/module/organisms/DateField.js.map +1 -1
  212. package/lib/module/organisms/DatePicker.js +56 -33
  213. package/lib/module/organisms/DatePicker.js.map +1 -1
  214. package/lib/module/organisms/List.js +62 -34
  215. package/lib/module/organisms/List.js.map +1 -1
  216. package/lib/module/organisms/Modal.js +122 -84
  217. package/lib/module/organisms/Modal.js.map +1 -1
  218. package/lib/module/organisms/NavigationBar.js +64 -25
  219. package/lib/module/organisms/NavigationBar.js.map +1 -1
  220. package/lib/module/organisms/OptionWheel.js +64 -64
  221. package/lib/module/organisms/OptionWheel.js.map +1 -1
  222. package/lib/module/organisms/ReorderableList.js +48 -27
  223. package/lib/module/organisms/ReorderableList.js.map +1 -1
  224. package/lib/module/organisms/Screen.js +70 -37
  225. package/lib/module/organisms/Screen.js.map +1 -1
  226. package/lib/module/organisms/SearchList.js +56 -26
  227. package/lib/module/organisms/SearchList.js.map +1 -1
  228. package/lib/module/organisms/Select.js +46 -25
  229. package/lib/module/organisms/Select.js.map +1 -1
  230. package/lib/module/organisms/Slides.js +37 -24
  231. package/lib/module/organisms/Slides.js.map +1 -1
  232. package/lib/module/organisms/ThemeToggle.js +11 -10
  233. package/lib/module/organisms/ThemeToggle.js.map +1 -1
  234. package/lib/module/organisms/Timeline.js +73 -56
  235. package/lib/module/organisms/Timeline.js.map +1 -1
  236. package/lib/module/organisms/Toast.js +47 -16
  237. package/lib/module/organisms/Toast.js.map +1 -1
  238. package/lib/module/organisms/ToastProvider.js +15 -11
  239. package/lib/module/organisms/ToastProvider.js.map +1 -1
  240. package/lib/module/organisms/Wizard.js +41 -16
  241. package/lib/module/organisms/Wizard.js.map +1 -1
  242. package/lib/module/organisms/chart/frame.js +25 -25
  243. package/lib/module/organisms/chart/frame.js.map +1 -1
  244. package/lib/module/organisms/chart/marks.js +42 -42
  245. package/lib/module/organisms/chart/math.js +84 -85
  246. package/lib/module/organisms/chart/math.js.map +1 -1
  247. package/lib/module/organisms/chart/palette.js +28 -28
  248. package/lib/module/organisms/imperativeBridge.js +5 -5
  249. package/lib/module/organisms/imperativeBridge.js.map +1 -1
  250. package/lib/module/organisms/useSlides.js +53 -21
  251. package/lib/module/organisms/useSlides.js.map +1 -1
  252. package/lib/module/safe-area/SafeAreaUIProvider.js +10 -65
  253. package/lib/module/safe-area/SafeAreaUIProvider.js.map +1 -1
  254. package/lib/module/safe-area/index.js +1 -0
  255. package/lib/module/safe-area/index.js.map +1 -1
  256. package/lib/module/theme/KeyboardAvoidance.js +198 -0
  257. package/lib/module/theme/KeyboardAvoidance.js.map +1 -0
  258. package/lib/module/theme/NativeOverlay.js +257 -0
  259. package/lib/module/theme/NativeOverlay.js.map +1 -0
  260. package/lib/module/theme/UIProvider.js +88 -35
  261. package/lib/module/theme/UIProvider.js.map +1 -1
  262. package/lib/module/theme/colors.js +17 -17
  263. package/lib/module/theme/colors.js.map +1 -1
  264. package/lib/module/theme/createStyles.js +20 -16
  265. package/lib/module/theme/createStyles.js.map +1 -1
  266. package/lib/module/theme/createTheme.js +6 -6
  267. package/lib/module/theme/index.js +1 -1
  268. package/lib/module/theme/index.js.map +1 -1
  269. package/lib/module/theme/insets.js +1 -1
  270. package/lib/module/theme/labels.js +29 -1
  271. package/lib/module/theme/labels.js.map +1 -1
  272. package/lib/module/theme/palettes.js +25 -23
  273. package/lib/module/theme/palettes.js.map +1 -1
  274. package/lib/module/theme/tokens.js +27 -13
  275. package/lib/module/theme/tokens.js.map +1 -1
  276. package/lib/module/theme/useKeyboardField.js +33 -0
  277. package/lib/module/theme/useKeyboardField.js.map +1 -0
  278. package/lib/module/theme/useReduceMotion.js +28 -0
  279. package/lib/module/theme/useReduceMotion.js.map +1 -0
  280. package/lib/typescript/atoms/Avatar.d.ts +35 -5
  281. package/lib/typescript/atoms/Avatar.d.ts.map +1 -1
  282. package/lib/typescript/atoms/Badge.d.ts +14 -3
  283. package/lib/typescript/atoms/Badge.d.ts.map +1 -1
  284. package/lib/typescript/atoms/Button.d.ts +34 -3
  285. package/lib/typescript/atoms/Button.d.ts.map +1 -1
  286. package/lib/typescript/atoms/Card.d.ts +13 -2
  287. package/lib/typescript/atoms/Card.d.ts.map +1 -1
  288. package/lib/typescript/atoms/Checkbox.d.ts +26 -1
  289. package/lib/typescript/atoms/Checkbox.d.ts.map +1 -1
  290. package/lib/typescript/atoms/Divider.d.ts +18 -1
  291. package/lib/typescript/atoms/Divider.d.ts.map +1 -1
  292. package/lib/typescript/atoms/EmptyState.d.ts +30 -3
  293. package/lib/typescript/atoms/EmptyState.d.ts.map +1 -1
  294. package/lib/typescript/atoms/Fab.d.ts +24 -4
  295. package/lib/typescript/atoms/Fab.d.ts.map +1 -1
  296. package/lib/typescript/atoms/Gradient.d.ts +21 -15
  297. package/lib/typescript/atoms/Gradient.d.ts.map +1 -1
  298. package/lib/typescript/atoms/IconButton.d.ts +18 -4
  299. package/lib/typescript/atoms/IconButton.d.ts.map +1 -1
  300. package/lib/typescript/atoms/Image.d.ts +39 -17
  301. package/lib/typescript/atoms/Image.d.ts.map +1 -1
  302. package/lib/typescript/atoms/Input.d.ts +57 -7
  303. package/lib/typescript/atoms/Input.d.ts.map +1 -1
  304. package/lib/typescript/atoms/KeyValueRow.d.ts +16 -4
  305. package/lib/typescript/atoms/KeyValueRow.d.ts.map +1 -1
  306. package/lib/typescript/atoms/PressableScale.d.ts +12 -5
  307. package/lib/typescript/atoms/PressableScale.d.ts.map +1 -1
  308. package/lib/typescript/atoms/ShinyText.d.ts +17 -17
  309. package/lib/typescript/atoms/ShinyText.d.ts.map +1 -1
  310. package/lib/typescript/atoms/Skeleton.d.ts +12 -7
  311. package/lib/typescript/atoms/Skeleton.d.ts.map +1 -1
  312. package/lib/typescript/atoms/Spinner.d.ts +29 -1
  313. package/lib/typescript/atoms/Spinner.d.ts.map +1 -1
  314. package/lib/typescript/atoms/Text.d.ts +46 -0
  315. package/lib/typescript/atoms/Text.d.ts.map +1 -1
  316. package/lib/typescript/atoms/Transition.d.ts +19 -15
  317. package/lib/typescript/atoms/Transition.d.ts.map +1 -1
  318. package/lib/typescript/atoms/index.d.ts +3 -3
  319. package/lib/typescript/atoms/index.d.ts.map +1 -1
  320. package/lib/typescript/atoms/inputValidation.d.ts +29 -0
  321. package/lib/typescript/atoms/inputValidation.d.ts.map +1 -0
  322. package/lib/typescript/icons/Icon.d.ts +4 -4
  323. package/lib/typescript/icons/defaultIcons.d.ts +19 -2
  324. package/lib/typescript/icons/defaultIcons.d.ts.map +1 -1
  325. package/lib/typescript/icons/index.d.ts +2 -2
  326. package/lib/typescript/icons/index.d.ts.map +1 -1
  327. package/lib/typescript/icons/types.d.ts +13 -3
  328. package/lib/typescript/icons/types.d.ts.map +1 -1
  329. package/lib/typescript/molecules/AvatarHeader.d.ts +23 -4
  330. package/lib/typescript/molecules/AvatarHeader.d.ts.map +1 -1
  331. package/lib/typescript/molecules/FormActions.d.ts +21 -4
  332. package/lib/typescript/molecules/FormActions.d.ts.map +1 -1
  333. package/lib/typescript/molecules/InfoRow.d.ts +17 -3
  334. package/lib/typescript/molecules/InfoRow.d.ts.map +1 -1
  335. package/lib/typescript/molecules/OptionCard.d.ts +20 -5
  336. package/lib/typescript/molecules/OptionCard.d.ts.map +1 -1
  337. package/lib/typescript/molecules/SegmentedControl.d.ts +18 -2
  338. package/lib/typescript/molecules/SegmentedControl.d.ts.map +1 -1
  339. package/lib/typescript/molecules/Stepper.d.ts +23 -7
  340. package/lib/typescript/molecules/Stepper.d.ts.map +1 -1
  341. package/lib/typescript/molecules/Steps.d.ts +18 -4
  342. package/lib/typescript/molecules/Steps.d.ts.map +1 -1
  343. package/lib/typescript/molecules/SymmetricGrid.d.ts +15 -5
  344. package/lib/typescript/molecules/SymmetricGrid.d.ts.map +1 -1
  345. package/lib/typescript/organisms/Alert.d.ts +28 -2
  346. package/lib/typescript/organisms/Alert.d.ts.map +1 -1
  347. package/lib/typescript/organisms/AlertProvider.d.ts +10 -10
  348. package/lib/typescript/organisms/AlertProvider.d.ts.map +1 -1
  349. package/lib/typescript/organisms/BottomSheet.d.ts +20 -5
  350. package/lib/typescript/organisms/BottomSheet.d.ts.map +1 -1
  351. package/lib/typescript/organisms/Chart.d.ts +86 -75
  352. package/lib/typescript/organisms/Chart.d.ts.map +1 -1
  353. package/lib/typescript/organisms/DateField.d.ts +17 -3
  354. package/lib/typescript/organisms/DateField.d.ts.map +1 -1
  355. package/lib/typescript/organisms/DatePicker.d.ts +7 -11
  356. package/lib/typescript/organisms/DatePicker.d.ts.map +1 -1
  357. package/lib/typescript/organisms/List.d.ts +30 -3
  358. package/lib/typescript/organisms/List.d.ts.map +1 -1
  359. package/lib/typescript/organisms/Modal.d.ts +30 -3
  360. package/lib/typescript/organisms/Modal.d.ts.map +1 -1
  361. package/lib/typescript/organisms/NavigationBar.d.ts +26 -7
  362. package/lib/typescript/organisms/NavigationBar.d.ts.map +1 -1
  363. package/lib/typescript/organisms/OptionWheel.d.ts +20 -16
  364. package/lib/typescript/organisms/OptionWheel.d.ts.map +1 -1
  365. package/lib/typescript/organisms/ReorderableList.d.ts +20 -11
  366. package/lib/typescript/organisms/ReorderableList.d.ts.map +1 -1
  367. package/lib/typescript/organisms/Screen.d.ts +27 -8
  368. package/lib/typescript/organisms/Screen.d.ts.map +1 -1
  369. package/lib/typescript/organisms/SearchList.d.ts +46 -3
  370. package/lib/typescript/organisms/SearchList.d.ts.map +1 -1
  371. package/lib/typescript/organisms/Select.d.ts +26 -6
  372. package/lib/typescript/organisms/Select.d.ts.map +1 -1
  373. package/lib/typescript/organisms/Slides.d.ts +44 -26
  374. package/lib/typescript/organisms/Slides.d.ts.map +1 -1
  375. package/lib/typescript/organisms/ThemeToggle.d.ts +6 -2
  376. package/lib/typescript/organisms/ThemeToggle.d.ts.map +1 -1
  377. package/lib/typescript/organisms/Timeline.d.ts +26 -9
  378. package/lib/typescript/organisms/Timeline.d.ts.map +1 -1
  379. package/lib/typescript/organisms/Toast.d.ts +19 -4
  380. package/lib/typescript/organisms/Toast.d.ts.map +1 -1
  381. package/lib/typescript/organisms/ToastProvider.d.ts +8 -8
  382. package/lib/typescript/organisms/ToastProvider.d.ts.map +1 -1
  383. package/lib/typescript/organisms/Wizard.d.ts +24 -6
  384. package/lib/typescript/organisms/Wizard.d.ts.map +1 -1
  385. package/lib/typescript/organisms/chart/frame.d.ts +21 -21
  386. package/lib/typescript/organisms/chart/frame.d.ts.map +1 -1
  387. package/lib/typescript/organisms/chart/marks.d.ts +28 -28
  388. package/lib/typescript/organisms/chart/marks.d.ts.map +1 -1
  389. package/lib/typescript/organisms/chart/math.d.ts +69 -70
  390. package/lib/typescript/organisms/chart/math.d.ts.map +1 -1
  391. package/lib/typescript/organisms/chart/palette.d.ts +2 -2
  392. package/lib/typescript/organisms/chart/palette.d.ts.map +1 -1
  393. package/lib/typescript/organisms/imperativeBridge.d.ts +4 -4
  394. package/lib/typescript/organisms/useSlides.d.ts +8 -16
  395. package/lib/typescript/organisms/useSlides.d.ts.map +1 -1
  396. package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts +9 -7
  397. package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts.map +1 -1
  398. package/lib/typescript/safe-area/index.d.ts.map +1 -1
  399. package/lib/typescript/theme/KeyboardAvoidance.d.ts +62 -0
  400. package/lib/typescript/theme/KeyboardAvoidance.d.ts.map +1 -0
  401. package/lib/typescript/theme/NativeOverlay.d.ts +43 -0
  402. package/lib/typescript/theme/NativeOverlay.d.ts.map +1 -0
  403. package/lib/typescript/theme/UIProvider.d.ts +38 -20
  404. package/lib/typescript/theme/UIProvider.d.ts.map +1 -1
  405. package/lib/typescript/theme/colors.d.ts +13 -13
  406. package/lib/typescript/theme/colors.d.ts.map +1 -1
  407. package/lib/typescript/theme/createStyles.d.ts +20 -14
  408. package/lib/typescript/theme/createStyles.d.ts.map +1 -1
  409. package/lib/typescript/theme/createTheme.d.ts +5 -5
  410. package/lib/typescript/theme/index.d.ts +1 -1
  411. package/lib/typescript/theme/index.d.ts.map +1 -1
  412. package/lib/typescript/theme/insets.d.ts +1 -1
  413. package/lib/typescript/theme/insets.d.ts.map +1 -1
  414. package/lib/typescript/theme/labels.d.ts +57 -2
  415. package/lib/typescript/theme/labels.d.ts.map +1 -1
  416. package/lib/typescript/theme/palettes.d.ts +25 -19
  417. package/lib/typescript/theme/palettes.d.ts.map +1 -1
  418. package/lib/typescript/theme/tokens.d.ts +15 -8
  419. package/lib/typescript/theme/tokens.d.ts.map +1 -1
  420. package/lib/typescript/theme/types.d.ts +7 -7
  421. package/lib/typescript/theme/types.d.ts.map +1 -1
  422. package/lib/typescript/theme/useKeyboardField.d.ts +17 -0
  423. package/lib/typescript/theme/useKeyboardField.d.ts.map +1 -0
  424. package/lib/typescript/theme/useReduceMotion.d.ts +7 -0
  425. package/lib/typescript/theme/useReduceMotion.d.ts.map +1 -0
  426. package/llms.txt +4 -4
  427. package/package.json +15 -14
  428. package/registry/alert-provider.json +4 -3
  429. package/registry/alert.json +3 -2
  430. package/registry/avatar-header.json +1 -1
  431. package/registry/avatar.json +3 -2
  432. package/registry/badge.json +1 -1
  433. package/registry/bottom-sheet.json +1 -1
  434. package/registry/button.json +3 -2
  435. package/registry/card.json +1 -1
  436. package/registry/chart.json +5 -5
  437. package/registry/checkbox.json +3 -2
  438. package/registry/core.json +31 -15
  439. package/registry/date-field.json +1 -1
  440. package/registry/date-picker.json +3 -2
  441. package/registry/divider.json +1 -1
  442. package/registry/empty-state.json +4 -2
  443. package/registry/fab.json +3 -2
  444. package/registry/form-actions.json +3 -2
  445. package/registry/gradient.json +1 -1
  446. package/registry/icon-button.json +3 -2
  447. package/registry/image.json +1 -1
  448. package/registry/index.json +79 -61
  449. package/registry/info-row.json +1 -1
  450. package/registry/input.json +5 -1
  451. package/registry/key-value-row.json +1 -1
  452. package/registry/list.json +3 -1
  453. package/registry/manifest.json +3 -1
  454. package/registry/modal.json +1 -1
  455. package/registry/navigation-bar.json +1 -1
  456. package/registry/option-card.json +3 -2
  457. package/registry/option-wheel.json +1 -1
  458. package/registry/pressable-scale.json +3 -2
  459. package/registry/reorderable-list.json +1 -1
  460. package/registry/screen.json +1 -1
  461. package/registry/search-list.json +7 -1
  462. package/registry/segmented-control.json +1 -1
  463. package/registry/select.json +1 -1
  464. package/registry/shiny-text.json +1 -1
  465. package/registry/skeleton.json +3 -2
  466. package/registry/slides.json +2 -2
  467. package/registry/spinner.json +1 -1
  468. package/registry/stepper.json +1 -1
  469. package/registry/steps.json +1 -1
  470. package/registry/symmetric-grid.json +1 -1
  471. package/registry/theme-toggle.json +1 -1
  472. package/registry/timeline.json +1 -1
  473. package/registry/title.json +1 -1
  474. package/registry/toast-provider.json +2 -2
  475. package/registry/toast.json +1 -1
  476. package/registry/transition.json +1 -1
  477. package/registry/wizard.json +1 -1
  478. package/src/atoms/Avatar.tsx +117 -26
  479. package/src/atoms/Badge.tsx +20 -9
  480. package/src/atoms/Button.tsx +102 -30
  481. package/src/atoms/Card.tsx +23 -3
  482. package/src/atoms/Checkbox.tsx +49 -12
  483. package/src/atoms/Divider.tsx +34 -4
  484. package/src/atoms/EmptyState.tsx +63 -16
  485. package/src/atoms/Fab.tsx +56 -9
  486. package/src/atoms/Gradient.tsx +92 -41
  487. package/src/atoms/IconButton.tsx +27 -4
  488. package/src/atoms/Image.tsx +74 -28
  489. package/src/atoms/Input.tsx +129 -19
  490. package/src/atoms/KeyValueRow.tsx +72 -28
  491. package/src/atoms/PressableScale.tsx +31 -7
  492. package/src/atoms/ShinyText.tsx +31 -31
  493. package/src/atoms/Skeleton.tsx +37 -17
  494. package/src/atoms/Spinner.tsx +87 -24
  495. package/src/atoms/Text.tsx +66 -6
  496. package/src/atoms/Transition.tsx +40 -44
  497. package/src/atoms/index.ts +3 -3
  498. package/src/atoms/inputValidation.ts +59 -0
  499. package/src/icons/Icon.tsx +4 -4
  500. package/src/icons/defaultIcons.tsx +445 -22
  501. package/src/icons/index.ts +2 -2
  502. package/src/icons/types.ts +26 -4
  503. package/src/molecules/AvatarHeader.tsx +88 -34
  504. package/src/molecules/FormActions.tsx +36 -6
  505. package/src/molecules/InfoRow.tsx +39 -12
  506. package/src/molecules/OptionCard.tsx +55 -20
  507. package/src/molecules/SegmentedControl.tsx +135 -15
  508. package/src/molecules/Stepper.tsx +73 -19
  509. package/src/molecules/Steps.tsx +121 -39
  510. package/src/molecules/SymmetricGrid.tsx +28 -12
  511. package/src/organisms/Alert.tsx +97 -26
  512. package/src/organisms/AlertProvider.tsx +13 -13
  513. package/src/organisms/BottomSheet.tsx +115 -43
  514. package/src/organisms/Chart.tsx +223 -165
  515. package/src/organisms/DateField.tsx +40 -15
  516. package/src/organisms/DatePicker.tsx +53 -32
  517. package/src/organisms/List.tsx +64 -15
  518. package/src/organisms/Modal.tsx +122 -63
  519. package/src/organisms/NavigationBar.tsx +73 -23
  520. package/src/organisms/OptionWheel.tsx +70 -66
  521. package/src/organisms/ReorderableList.tsx +49 -27
  522. package/src/organisms/Screen.tsx +79 -42
  523. package/src/organisms/SearchList.tsx +84 -20
  524. package/src/organisms/Select.tsx +63 -29
  525. package/src/organisms/Slides.tsx +63 -44
  526. package/src/organisms/ThemeToggle.tsx +15 -6
  527. package/src/organisms/Timeline.tsx +79 -62
  528. package/src/organisms/Toast.tsx +50 -15
  529. package/src/organisms/ToastProvider.tsx +17 -13
  530. package/src/organisms/Wizard.tsx +58 -21
  531. package/src/organisms/chart/frame.tsx +35 -35
  532. package/src/organisms/chart/marks.tsx +53 -53
  533. package/src/organisms/chart/math.ts +93 -94
  534. package/src/organisms/chart/palette.ts +28 -28
  535. package/src/organisms/imperativeBridge.ts +5 -5
  536. package/src/organisms/useSlides.ts +66 -31
  537. package/src/safe-area/SafeAreaUIProvider.tsx +9 -70
  538. package/src/safe-area/index.ts +1 -0
  539. package/src/theme/KeyboardAvoidance.tsx +216 -0
  540. package/src/theme/NativeOverlay.tsx +269 -0
  541. package/src/theme/UIProvider.tsx +109 -46
  542. package/src/theme/colors.ts +21 -21
  543. package/src/theme/createStyles.ts +23 -19
  544. package/src/theme/createTheme.ts +6 -6
  545. package/src/theme/index.ts +1 -1
  546. package/src/theme/insets.ts +1 -1
  547. package/src/theme/labels.ts +85 -2
  548. package/src/theme/palettes.ts +33 -25
  549. package/src/theme/tokens.ts +27 -13
  550. package/src/theme/types.ts +7 -7
  551. package/src/theme/useKeyboardField.ts +33 -0
  552. package/src/theme/useReduceMotion.ts +27 -0
@@ -1,4 +1,4 @@
1
- import React, { memo, useEffect, useRef } from 'react';
1
+ import React, { memo, useEffect, useRef, type ComponentProps } from 'react';
2
2
  import {
3
3
  Animated,
4
4
  Easing,
@@ -9,15 +9,19 @@ import {
9
9
  } from 'react-native';
10
10
  import { createStyles } from '../theme/createStyles';
11
11
  import { useTheme } from '../theme/UIProvider';
12
+ import { useReduceMotion } from './Transition';
13
+
14
+ /** Half a pulse cycle (opaque → faint). A loading loop, not a transition: it doesn't come from `duration`. */
15
+ const PULSE_HALF_MS = 700;
12
16
 
13
17
  export type SkeletonVariant = 'rect' | 'text' | 'circle';
14
18
 
15
19
  export interface SkeletonProps {
16
- /** @default '100%' ('circle' also uses this as the diameter) */
20
+ /** Width of the placeholder. @default '100%' ('circle' also uses this as the diameter) */
17
21
  width?: DimensionValue;
18
- /** @default 16 ('text' uses the line height; 'circle', the width) */
22
+ /** Height of the placeholder. @default 16 ('text' uses Body's line height; 'circle', the width) */
19
23
  height?: DimensionValue;
20
- /** @default 'rect' */
24
+ /** Shape: a block, a line of text or a circle. @default 'rect' */
21
25
  variant?: SkeletonVariant;
22
26
  /** Override of the theme's radius. */
23
27
  radius?: number;
@@ -25,7 +29,7 @@ export interface SkeletonProps {
25
29
  lines?: number;
26
30
  /** Width of the last line, so the paragraph doesn't end as a solid block. @default '60%' */
27
31
  lastLineWidth?: DimensionValue;
28
- /** @default true */
32
+ /** Pulses while waiting. Off when the system's Reduce Motion is on. @default true */
29
33
  animated?: boolean;
30
34
  style?: StyleProp<ViewStyle>;
31
35
  testID?: string;
@@ -33,14 +37,24 @@ export interface SkeletonProps {
33
37
 
34
38
  const useStyles = createStyles((theme) => ({
35
39
  block: { backgroundColor: theme.colors.skeleton },
36
- lines: { gap: theme.tokens.spacing.sm },
40
+ // Each line takes exactly `lineHeight.md` (Body's): a `fontSize.md` bar
41
+ // plus half the leading above and below. That way the fake paragraph
42
+ // measures the same as the real one and nothing jumps when the content arrives.
43
+ textLine: {
44
+ marginVertical: (theme.tokens.lineHeight.md - theme.tokens.fontSize.md) / 2,
45
+ },
37
46
  }));
38
47
 
39
48
  /**
40
49
  * Skeleton
41
- * Placeholder que late mientras llega el contenido real. Reserva el espacio
42
- * exacto de lo que reemplaza, así la pantalla no salta cuando aparecen los
43
- * datos — que es justamente lo que un Spinner centrado no puede hacer.
50
+ * Placeholder that pulses while the real content arrives. It reserves the
51
+ * exact space of what it replaces, so the screen doesn't jump when the data
52
+ * shows up — which is precisely what a centered Spinner can't do.
53
+ *
54
+ * Gestalt, similarity: the silhouette repeats the shape and size of the
55
+ * content (a circle for avatars, Body-height lines for text), so the eye
56
+ * already groups the screen before the data arrives. Respects Reduce Motion:
57
+ * no pulse, a static block.
44
58
  */
45
59
  export const Skeleton = memo(
46
60
  ({
@@ -56,39 +70,45 @@ export const Skeleton = memo(
56
70
  }: SkeletonProps) => {
57
71
  const theme = useTheme();
58
72
  const styles = useStyles();
73
+ const reduceMotion = useReduceMotion();
74
+ const pulsing = animated && !reduceMotion;
59
75
  const pulse = useRef(new Animated.Value(0)).current;
60
76
 
61
77
  useEffect(() => {
62
- if (!animated) return;
78
+ if (!pulsing) return;
63
79
  const loop = Animated.loop(
64
80
  Animated.sequence([
65
81
  Animated.timing(pulse, {
66
82
  toValue: 1,
67
- duration: 700,
83
+ duration: PULSE_HALF_MS,
68
84
  useNativeDriver: true,
69
85
  easing: Easing.inOut(Easing.quad),
70
86
  }),
71
87
  Animated.timing(pulse, {
72
88
  toValue: 0,
73
- duration: 700,
89
+ duration: PULSE_HALF_MS,
74
90
  useNativeDriver: true,
75
91
  easing: Easing.inOut(Easing.quad),
76
92
  }),
77
93
  ])
78
94
  );
79
95
  loop.start();
80
- return () => loop.stop();
81
- }, [animated, pulse]);
96
+ return () => {
97
+ loop.stop();
98
+ pulse.setValue(0);
99
+ };
100
+ }, [pulsing, pulse]);
82
101
 
83
102
  const isCircle = variant === 'circle';
84
103
  const isText = variant === 'text';
85
- const opacity = animated ? pulse.interpolate({ inputRange: [0, 1], outputRange: [1, 0.4] }) : 1;
104
+ const opacity = pulsing ? pulse.interpolate({ inputRange: [0, 1], outputRange: [1, 0.4] }) : 1;
86
105
  const resolvedHeight = isCircle ? width : isText ? theme.tokens.fontSize.md : height;
87
106
  const resolvedRadius =
88
107
  radius ?? (isCircle ? theme.tokens.radius.full : isText ? theme.tokens.radius.xs : theme.tokens.radius.sm);
89
108
 
90
- const barStyle = (barWidth: DimensionValue): StyleProp<ViewStyle> => [
109
+ const barStyle = (barWidth: DimensionValue): ComponentProps<typeof Animated.View>['style'] => [
91
110
  styles.block,
111
+ isText && styles.textLine,
92
112
  { width: barWidth, height: resolvedHeight, borderRadius: resolvedRadius, opacity },
93
113
  ];
94
114
 
@@ -96,7 +116,7 @@ export const Skeleton = memo(
96
116
 
97
117
  if (isText && lines > 1) {
98
118
  return (
99
- <View style={[styles.lines, style]} testID={testID} {...a11y}>
119
+ <View style={style} testID={testID} {...a11y}>
100
120
  {Array.from({ length: lines }, (_, i) => (
101
121
  <Animated.View
102
122
  key={i}
@@ -1,13 +1,16 @@
1
1
  import React, { memo, useEffect, useRef } from 'react';
2
2
  import { ActivityIndicator, Animated, Easing, Text, View } from 'react-native';
3
3
  import { createStyles } from '../theme/createStyles';
4
- import { useAllowFontScaling, useColors } from '../theme/UIProvider';
4
+ import { useAllowFontScaling, useColors, useLabels } from '../theme/UIProvider';
5
5
 
6
6
  export type SpinnerVariant = 'native' | 'dots' | 'ring';
7
7
 
8
8
  export interface SpinnerProps {
9
+ /** Indicator size; also scales the `dots` and `ring` variants. @default 'large' */
9
10
  size?: 'small' | 'large';
11
+ /** Indicator color. @default colors.primary */
10
12
  color?: string;
13
+ /** Message under the indicator. Also what screen readers announce. */
11
14
  text?: string;
12
15
  /** @default true. When false, doesn't take up flex:1 (useful inline, inside a button/row). */
13
16
  fullscreen?: boolean;
@@ -19,16 +22,30 @@ export interface SpinnerProps {
19
22
  variant?: SpinnerVariant;
20
23
  /** Fully custom indicator. Takes precedence over `variant`. */
21
24
  indicator?: React.ReactNode;
25
+ /**
26
+ * Shown above the indicator — typically the app logo on a splash or
27
+ * first-load screen (an `<Image>`, an `<Avatar>`, any node).
28
+ */
29
+ logo?: React.ReactNode;
30
+ /** What screen readers announce. @default text ?? labels.loading */
31
+ accessibilityLabel?: string;
22
32
  testID?: string;
23
33
  }
24
34
 
35
+ // Rhythm of the looping indicators. They are not UI transitions (those use
36
+ // theme.tokens.duration): they are the pulse of a continuous animation.
37
+ const DOT_PULSE_MS = 320;
38
+ const DOT_STAGGER_MS = 140;
39
+ const RING_TURN_MS = 900;
40
+
25
41
  const useStyles = createStyles((theme) => ({
26
42
  container: { justifyContent: 'center', alignItems: 'center', padding: theme.tokens.spacing.xl },
27
43
  text: { marginTop: theme.tokens.spacing.md, color: theme.colors.textLight, fontSize: theme.tokens.fontSize.md },
44
+ logo: { marginBottom: theme.tokens.spacing.xl },
28
45
  dots: { flexDirection: 'row', gap: theme.tokens.spacing.sm },
29
46
  }));
30
47
 
31
- /** Tres puntos que laten en secuencia. Animated + useNativeDriver: corre en el hilo nativo. */
48
+ /** Three dots that pulse in sequence. Animated + useNativeDriver: runs on the native thread. */
32
49
  const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number }) => {
33
50
  const dots = [useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current];
34
51
 
@@ -36,16 +53,16 @@ const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number
36
53
  const animations = dots.map((dot, i) =>
37
54
  Animated.loop(
38
55
  Animated.sequence([
39
- Animated.delay(i * 140),
40
- Animated.timing(dot, { toValue: 1, duration: 320, useNativeDriver: true, easing: Easing.out(Easing.quad) }),
41
- Animated.timing(dot, { toValue: 0, duration: 320, useNativeDriver: true, easing: Easing.in(Easing.quad) }),
42
- Animated.delay((2 - i) * 140),
56
+ Animated.delay(i * DOT_STAGGER_MS),
57
+ Animated.timing(dot, { toValue: 1, duration: DOT_PULSE_MS, useNativeDriver: true, easing: Easing.out(Easing.quad) }),
58
+ Animated.timing(dot, { toValue: 0, duration: DOT_PULSE_MS, useNativeDriver: true, easing: Easing.in(Easing.quad) }),
59
+ Animated.delay((2 - i) * DOT_STAGGER_MS),
43
60
  ])
44
61
  )
45
62
  );
46
63
  animations.forEach((a) => a.start());
47
- // Sin stop() los loops siguen corriendo tras desmontar y mantienen vivo
48
- // el árbol de Animated.
64
+ // Without stop() the loops keep running after unmount and keep the
65
+ // Animated tree alive.
49
66
  return () => animations.forEach((a) => a.stop());
50
67
  }, []);
51
68
 
@@ -69,37 +86,74 @@ const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number
69
86
  });
70
87
  DotsIndicator.displayName = 'DotsIndicator';
71
88
 
72
- /** Anillo que gira: un borde con un solo lado coloreado. */
89
+ /**
90
+ * Spinning ring: a faint fixed track and, on top, an arc (a single side of
91
+ * the border) that spins. The track uses `opacity` instead of appending alpha
92
+ * to the color (`color + '33'`), which only worked with 6-digit hex and broke
93
+ * with `rgb()` or color names.
94
+ */
73
95
  const RingIndicator = memo(({ color, diameter }: { color: string; diameter: number }) => {
74
96
  const spin = useRef(new Animated.Value(0)).current;
75
97
 
76
98
  useEffect(() => {
77
99
  const animation = Animated.loop(
78
- Animated.timing(spin, { toValue: 1, duration: 900, useNativeDriver: true, easing: Easing.linear })
100
+ Animated.timing(spin, { toValue: 1, duration: RING_TURN_MS, useNativeDriver: true, easing: Easing.linear })
79
101
  );
80
102
  animation.start();
81
103
  return () => animation.stop();
82
104
  }, []);
83
105
 
106
+ const ring = { width: diameter, height: diameter, borderRadius: diameter / 2, borderWidth: Math.max(2, diameter / 10) };
84
107
  return (
85
- <Animated.View
86
- style={{
87
- width: diameter,
88
- height: diameter,
89
- borderRadius: diameter / 2,
90
- borderWidth: Math.max(2, diameter / 10),
91
- borderColor: color + '33',
92
- borderTopColor: color,
93
- transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) }],
94
- }}
95
- />
108
+ <View style={{ width: diameter, height: diameter }}>
109
+ <View style={[ring, { position: 'absolute', borderColor: color, opacity: 0.2 }]} />
110
+ <Animated.View
111
+ style={[
112
+ ring,
113
+ {
114
+ borderColor: 'transparent',
115
+ borderTopColor: color,
116
+ transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) }],
117
+ },
118
+ ]}
119
+ />
120
+ </View>
96
121
  );
97
122
  });
98
123
  RingIndicator.displayName = 'RingIndicator';
99
124
 
125
+ /**
126
+ * Spinner
127
+ * Indeterminate loading indicator, with optional text below.
128
+ *
129
+ * Gestalt:
130
+ * - Common fate: the three `dots` pulse in sequence, at the same rhythm, and
131
+ * read as a single indicator moving forward.
132
+ * - Proximity: the text sits `spacing.md` from the indicator, so it reads as
133
+ * its explanation and not as loose text on the screen. The `logo` sits
134
+ * further away (`spacing.xl`): it is the screen's brand, not part of the indicator.
135
+ * - Focal point: with `logo`, the logo is the first thing seen and the
136
+ * indicator stays as a secondary signal that the app is loading.
137
+ *
138
+ * Accessibility: it is announced as a busy `progressbar`, with `text` (or
139
+ * `labels.loading`) as its name. The animation doesn't stop with Reduce
140
+ * Motion: it is the signal that something is happening, like the system's
141
+ * ActivityIndicator.
142
+ */
100
143
  export const Spinner = memo(
101
- ({ size = 'large', color, text, fullscreen = true, variant = 'native', indicator, testID }: SpinnerProps) => {
144
+ ({
145
+ size = 'large',
146
+ color,
147
+ text,
148
+ fullscreen = true,
149
+ variant = 'native',
150
+ indicator,
151
+ logo,
152
+ accessibilityLabel,
153
+ testID,
154
+ }: SpinnerProps) => {
102
155
  const colors = useColors();
156
+ const labels = useLabels();
103
157
  const styles = useStyles();
104
158
  const allowFontScaling = useAllowFontScaling();
105
159
  const resolvedColor = color || colors.primary;
@@ -113,9 +167,18 @@ export const Spinner = memo(
113
167
  };
114
168
 
115
169
  return (
116
- <View style={[styles.container, fullscreen && { flex: 1 }]} testID={testID}>
170
+ <View
171
+ style={[styles.container, fullscreen && { flex: 1 }]}
172
+ testID={testID}
173
+ accessible
174
+ accessibilityRole="progressbar"
175
+ accessibilityLabel={accessibilityLabel ?? (text || labels.loading)}
176
+ accessibilityState={{ busy: true }}
177
+ accessibilityLiveRegion="polite"
178
+ >
179
+ {logo != null && <View style={styles.logo}>{logo}</View>}
117
180
  {renderIndicator()}
118
- {text && (
181
+ {!!text && (
119
182
  <Text allowFontScaling={allowFontScaling} style={styles.text}>
120
183
  {text}
121
184
  </Text>
@@ -1,5 +1,11 @@
1
1
  import React, { memo } from 'react';
2
- import { Text as RNText, type StyleProp, type TextProps, type TextStyle } from 'react-native';
2
+ import {
3
+ Text as RNText,
4
+ type AccessibilityRole,
5
+ type StyleProp,
6
+ type TextProps,
7
+ type TextStyle,
8
+ } from 'react-native';
3
9
  import { createStyles } from '../theme/createStyles';
4
10
  import { useAllowFontScaling, useColors } from '../theme/UIProvider';
5
11
 
@@ -13,13 +19,15 @@ export interface TypographyProps extends TextProps {
13
19
  const useStyles = createStyles((theme) => ({
14
20
  title: {
15
21
  fontSize: theme.tokens.fontSize.xxl,
22
+ lineHeight: theme.tokens.lineHeight.xl,
16
23
  fontWeight: theme.tokens.fontWeight.bold,
17
- letterSpacing: -0.5,
24
+ letterSpacing: theme.tokens.letterSpacing.tight,
18
25
  color: theme.colors.text,
19
26
  },
20
27
  subtitle: {
21
28
  fontSize: theme.tokens.fontSize.lg,
22
- fontWeight: theme.tokens.fontWeight.medium,
29
+ lineHeight: theme.tokens.lineHeight.lg,
30
+ fontWeight: theme.tokens.fontWeight.semibold,
23
31
  color: theme.colors.text,
24
32
  },
25
33
  body: {
@@ -29,11 +37,16 @@ const useStyles = createStyles((theme) => ({
29
37
  },
30
38
  caption: {
31
39
  fontSize: theme.tokens.fontSize.sm,
40
+ lineHeight: theme.tokens.lineHeight.sm,
32
41
  color: theme.colors.textLight,
33
42
  },
34
43
  }));
35
44
 
36
- function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor: 'text' | 'textLight') {
45
+ function makeVariant(
46
+ variant: keyof ReturnType<typeof useStyles>,
47
+ defaultColor: 'text' | 'textLight',
48
+ defaultRole?: AccessibilityRole,
49
+ ) {
37
50
  const Component = memo(({ children, style, color, align = 'left', ...props }: TypographyProps) => {
38
51
  const styles = useStyles();
39
52
  const colors = useColors();
@@ -41,6 +54,7 @@ function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor:
41
54
  return (
42
55
  <RNText
43
56
  allowFontScaling={allowFontScaling}
57
+ accessibilityRole={defaultRole}
44
58
  style={[styles[variant], { color: color || colors[defaultColor], textAlign: align }, style]}
45
59
  {...props}
46
60
  >
@@ -48,11 +62,57 @@ function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor:
48
62
  </RNText>
49
63
  );
50
64
  });
51
- Component.displayName = variant;
65
+ Component.displayName = String(variant);
52
66
  return Component;
53
67
  }
54
68
 
55
- export const Title = makeVariant('title', 'text');
69
+ /**
70
+ * Screen or section title: the highest step of the typographic hierarchy.
71
+ *
72
+ * Gestalt, focal point (Von Restorff): it is the only text in its block with
73
+ * size `xxl` and weight `bold`, so it breaks the series of Body/Caption and is
74
+ * the first thing read. That is why there should be only one per block: two
75
+ * Titles together cancel each other out. The `tight` tracking offsets the room
76
+ * the large size opens between letters so the word reads as a single shape
77
+ * (Prägnanz), and `lineHeight.xl` keeps the block compact when the title wraps.
78
+ *
79
+ * Accessibility: it is announced with `accessibilityRole="header"`, so
80
+ * VoiceOver/TalkBack can jump from title to title. It can be overridden by
81
+ * passing a different `accessibilityRole`.
82
+ */
83
+ export const Title = makeVariant('title', 'text', 'header');
84
+ /**
85
+ * Second step of the hierarchy: heads a group within the screen or
86
+ * accompanies a Title with a short piece of data.
87
+ *
88
+ * Gestalt, similarity: it shares its color with Body but steps up size (`lg`)
89
+ * and weight (`semibold`), so it is perceived as part of the same family and,
90
+ * at the same time, as the label of the block that follows. Proximity: it
91
+ * should sit closer to the content it heads than to the previous block. It is
92
+ * not an accessibility heading: if it marks a navigable section, use Title (or
93
+ * pass `accessibilityRole="header"`).
94
+ * `lineHeight.lg` (1.5×) keeps the text legible when it spans several lines.
95
+ */
56
96
  export const Subtitle = makeVariant('subtitle', 'text');
97
+ /**
98
+ * Running text: the default style for paragraphs, descriptions and values.
99
+ *
100
+ * Gestalt, similarity: all reading content shares size (`md`), regular weight
101
+ * and the `text` color, so it is perceived as a single level and the steps
102
+ * above (Title, Subtitle) and below (Caption) stand out by contrast.
103
+ * `lineHeight.md` (≈1.43×) gives the room between lines to read long
104
+ * paragraphs. If `color` is passed, the color/background pair must meet WCAG
105
+ * AA (4.5:1); the theme colors already guarantee it.
106
+ */
57
107
  export const Body = makeVariant('body', 'text');
108
+ /**
109
+ * Secondary text: hints, metadata, dates, help below a field.
110
+ *
111
+ * Gestalt, figure and ground: size `sm` and color `textLight` bring it one
112
+ * step below Body, so it reads as context and doesn't compete with the
113
+ * content. Proximity: it sits right next to the element it explains.
114
+ * `textLight` meets WCAG AA over `surface` and `background` in light and dark
115
+ * (palettes tests); don't lighten it further. `lineHeight.sm` (≈1.33×) keeps
116
+ * the lines together when the hint spans several.
117
+ */
58
118
  export const Caption = makeVariant('caption', 'textLight');
@@ -1,6 +1,7 @@
1
1
  import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
2
- import { AccessibilityInfo, Animated, Easing, type StyleProp, type ViewStyle } from 'react-native';
2
+ import { Animated, Easing, type StyleProp, type ViewStyle } from 'react-native';
3
3
  import { useTheme } from '../theme/UIProvider';
4
+ import { useReduceMotion } from '../theme/useReduceMotion';
4
5
 
5
6
  export type TransitionPreset =
6
7
  | 'fade'
@@ -12,6 +13,7 @@ export type TransitionPreset =
12
13
  | 'slide-right';
13
14
 
14
15
  export interface TransitionProps {
16
+ /** Content that enters and exits. */
15
17
  children: React.ReactNode;
16
18
  /** Enters when true, exits (and unmounts) when false. @default true */
17
19
  visible?: boolean;
@@ -21,7 +23,7 @@ export interface TransitionProps {
21
23
  duration?: number;
22
24
  /** ms before starting. A per-index delay staggers a list. @default 0 */
23
25
  delay?: number;
24
- /** Pixels traveled by the slide presets. @default 24 */
26
+ /** Pixels traveled by the slide presets. @default tokens.spacing.xxl (24) */
25
27
  distance?: number;
26
28
  /** Spring instead of timing (implicit in 'pop'). */
27
29
  spring?: boolean;
@@ -34,50 +36,39 @@ export interface TransitionProps {
34
36
  * whoever passes it decides when and how it advances (a PanResponder, for example).
35
37
  */
36
38
  value?: Animated.Value;
39
+ /** Called when the enter animation finishes. Not called when driven by `value`. */
37
40
  onEntered?: () => void;
41
+ /** Called when the exit animation finishes, before unmounting. Not called when driven by `value`. */
38
42
  onExited?: () => void;
39
43
  style?: StyleProp<ViewStyle>;
40
44
  testID?: string;
41
45
  }
42
46
 
43
47
  const SCALE_FROM: Record<'scale' | 'pop', number> = { scale: 0.92, pop: 0.8 };
48
+ const hiddenStyle: ViewStyle = { pointerEvents: 'none' };
49
+ /** 'pop' spring: bounces once and settles (~350 ms), without oscillating. */
50
+ const POP_SPRING = { friction: 9, tension: 90 } as const;
44
51
 
45
- /**
46
- * Sigue el ajuste de "reducir movimiento" del sistema: con él activo las
47
- * animaciones saltan al estado final en vez de desactivarse, así que los
48
- * callbacks y el desmontaje siguen ocurriendo igual.
49
- */
50
- export function useReduceMotion(): boolean {
51
- const [reduceMotion, setReduceMotion] = useState(false);
52
-
53
- useEffect(() => {
54
- let alive = true;
55
- // Sólo se actualiza el estado si el ajuste está activo: el valor inicial ya
56
- // es `false` y un setState de false a false costaría un render por montaje.
57
- AccessibilityInfo.isReduceMotionEnabled().then((enabled) => {
58
- if (alive && enabled) setReduceMotion(true);
59
- });
60
- const sub = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotion);
61
- return () => {
62
- alive = false;
63
- sub.remove();
64
- };
65
- }, []);
66
-
67
- return reduceMotion;
68
- }
52
+ // Lives in theme/ (UIProvider uses it too); re-exported here so existing
53
+ // imports don't break.
54
+ export { useReduceMotion };
69
55
 
70
56
  /**
71
57
  * Transition
72
- * Envuelve cualquier árbol y lo anima al entrar y al salir. Todos los presets
73
- * se reducen a `opacity` y `transform` sobre un único Animated.Value, que es
74
- * lo que `useNativeDriver` sabe mandar al hilo nativo: la animación corre ahí
75
- * y el hilo de JS no participa de ningún frame — por eso no hay presets de
76
- * alto, ancho o color, que obligarían a volver a JS en cada frame.
58
+ * Wraps any tree and animates it on enter and exit. Every preset boils down
59
+ * to `opacity` and `transform` over a single Animated.Value, which is what
60
+ * `useNativeDriver` knows how to send to the native thread: the animation runs
61
+ * there and the JS thread takes part in no frame — that is why there are no
62
+ * height, width or color presets, which would force a return to JS every frame.
63
+ *
64
+ * The node stays mounted until the exit animation finishes, and the behavior
65
+ * is identical on iOS and Android: there is no per-platform branch. While
66
+ * exiting (or hidden with `keepMounted`) it stops receiving touches and leaves
67
+ * the accessibility tree: what is invisible isn't read.
77
68
  *
78
- * El nodo se mantiene montado hasta que termina la animación de salida, y el
79
- * comportamiento es idéntico en iOS y Android: no hay ninguna rama por
80
- * plataforma.
69
+ * Gestalt, common fate: what enters or exits together is perceived as a group;
70
+ * with a per-index `delay` the list enters in reading order (continuity).
71
+ * Respects Reduce Motion: jumps to the final state, callbacks still fire.
81
72
  */
82
73
  export const Transition = memo(
83
74
  ({
@@ -86,7 +77,7 @@ export const Transition = memo(
86
77
  preset = 'fade',
87
78
  duration,
88
79
  delay = 0,
89
- distance = 24,
80
+ distance,
90
81
  spring,
91
82
  appear = true,
92
83
  keepMounted = false,
@@ -97,6 +88,10 @@ export const Transition = memo(
97
88
  testID,
98
89
  }: TransitionProps) => {
99
90
  const theme = useTheme();
91
+ const travel = distance ?? theme.tokens.spacing.xxl;
92
+ // Resolved here, not inside the effect: depending on `theme` restarted the
93
+ // animation (and fired onEntered again) every time the theme changed.
94
+ const resolvedDuration = duration ?? theme.tokens.duration.base;
100
95
  const reduceMotion = useReduceMotion();
101
96
  const internal = useRef(new Animated.Value(visible && !appear ? 1 : 0)).current;
102
97
  const progress = value ?? internal;
@@ -104,8 +99,8 @@ export const Transition = memo(
104
99
 
105
100
  const [mounted, setMounted] = useState(visible || keepMounted);
106
101
 
107
- // Los callbacks viven en un ref: pasados inline cambian de identidad en
108
- // cada render y, como dependencias del efecto, reiniciarían la animación.
102
+ // The callbacks live in a ref: passed inline they change identity on
103
+ // every render and, as effect dependencies, would restart the animation.
109
104
  const callbacks = useRef({ onEntered, onExited });
110
105
  useEffect(() => {
111
106
  callbacks.current = { onEntered, onExited };
@@ -126,11 +121,11 @@ export const Transition = memo(
126
121
  const animation = reduceMotion
127
122
  ? Animated.timing(progress, { toValue, duration: 0, delay, useNativeDriver: true })
128
123
  : useSpring
129
- ? Animated.spring(progress, { toValue, delay, friction: 9, tension: 90, useNativeDriver: true })
124
+ ? Animated.spring(progress, { toValue, delay, ...POP_SPRING, useNativeDriver: true })
130
125
  : Animated.timing(progress, {
131
126
  toValue,
132
127
  delay,
133
- duration: duration ?? theme.tokens.duration.base,
128
+ duration: resolvedDuration,
134
129
  easing: visible ? Easing.out(Easing.cubic) : Easing.in(Easing.cubic),
135
130
  useNativeDriver: true,
136
131
  });
@@ -146,7 +141,7 @@ export const Transition = memo(
146
141
  });
147
142
 
148
143
  return () => animation.stop();
149
- }, [visible, driven, reduceMotion, spring, delay, duration, keepMounted, presets, progress, theme]);
144
+ }, [visible, driven, reduceMotion, spring, delay, resolvedDuration, keepMounted, presets, progress]);
150
145
 
151
146
  const animatedStyle = useMemo(() => {
152
147
  type Interpolated = Animated.AnimatedInterpolation<number>;
@@ -165,21 +160,22 @@ export const Transition = memo(
165
160
  continue;
166
161
  }
167
162
  const vertical = item === 'slide-up' || item === 'slide-down';
168
- const from = item === 'slide-up' || item === 'slide-left' ? distance : -distance;
163
+ const from = item === 'slide-up' || item === 'slide-left' ? travel : -travel;
169
164
  const offset = progress.interpolate({ inputRange: [0, 1], outputRange: [from, 0] });
170
165
  transform.push(vertical ? { translateY: offset } : { translateX: offset });
171
166
  }
172
167
 
173
168
  return { opacity, transform };
174
- }, [presets, progress, distance]);
169
+ }, [presets, progress, travel]);
175
170
 
176
171
  if (!mounted) return null;
177
172
 
178
173
  return (
179
174
  <Animated.View
180
175
  testID={testID}
181
- pointerEvents={visible ? undefined : 'none'}
182
- style={[style, animatedStyle]}
176
+ accessibilityElementsHidden={!visible}
177
+ importantForAccessibility={visible ? 'auto' : 'no-hide-descendants'}
178
+ style={[style, animatedStyle, !visible && hiddenStyle]}
183
179
  >
184
180
  {children}
185
181
  </Animated.View>
@@ -5,7 +5,7 @@ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button';
5
5
  export { IconButton } from './IconButton';
6
6
  export type { IconButtonProps } from './IconButton';
7
7
  export { Input } from './Input';
8
- export type { InputProps } from './Input';
8
+ export type { InputProps, InputHandle, InputRules, InputRuleValue } from './Input';
9
9
  export { Checkbox } from './Checkbox';
10
10
  export type { CheckboxProps } from './Checkbox';
11
11
  export { Badge } from './Badge';
@@ -16,7 +16,7 @@ export { Divider } from './Divider';
16
16
  export type { DividerProps } from './Divider';
17
17
  export { Gradient } from './Gradient';
18
18
  export type { GradientProps, GradientDirection } from './Gradient';
19
- export { Avatar } from './Avatar';
19
+ export { Avatar, initialsOf } from './Avatar';
20
20
  export type { AvatarProps } from './Avatar';
21
21
  export { Image, prefetchImage } from './Image';
22
22
  export type { ImageProps } from './Image';
@@ -29,7 +29,7 @@ export type { TransitionProps, TransitionPreset } from './Transition';
29
29
  export { ShinyText } from './ShinyText';
30
30
  export type { ShinyTextProps } from './ShinyText';
31
31
  export { EmptyState } from './EmptyState';
32
- export type { EmptyStateProps } from './EmptyState';
32
+ export type { EmptyStateProps, EmptyStateAction } from './EmptyState';
33
33
  export { KeyValueRow } from './KeyValueRow';
34
34
  export type { KeyValueRowProps } from './KeyValueRow';
35
35
  export { Fab } from './Fab';