orn-ui 0.2.10 → 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 +66 -51
  2. package/README.md +3 -7
  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 +174 -154
  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 +176 -156
  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 +193 -164
  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, { useCallback, useEffect, useMemo, useRef } from 'react';
1
+ import React, { useCallback, useEffect, useMemo, useRef, type ComponentRef } from 'react';
2
2
  import {
3
3
  Animated,
4
4
  ScrollView,
@@ -24,8 +24,11 @@ export interface OptionWheelOption<T> {
24
24
  export type OptionWheelVariant = 'window' | 'spotlight';
25
25
 
26
26
  export interface OptionWheelProps<T> {
27
+ /** The range, in order. Each option has a label, its value, and may be disabled. */
27
28
  options: OptionWheelOption<T>[];
29
+ /** Value of the option in the centre row (controlled). */
28
30
  selectedValue: T | undefined;
31
+ /** Called with the value of the option the wheel settles on. */
29
32
  onSelect: (value: T) => void;
30
33
  /** Title above the wheel. */
31
34
  label?: string;
@@ -64,26 +67,27 @@ export interface OptionWheelProps<T> {
64
67
  curveRadius?: number;
65
68
  /** Which side the wheel's centre is on. @default 'left' */
66
69
  curveFrom?: 'left' | 'right';
70
+ /** Dims the wheel and stops it from turning. @default false */
67
71
  disabled?: boolean;
68
72
  style?: StyleProp<ViewStyle>;
69
73
  testID?: string;
70
74
  }
71
75
 
72
76
  const DEFAULT_VISIBLE_COUNT = 5;
73
- /** 44pt: el mínimo táctil de iOS, y alcanza para una línea `lg` con aire. */
77
+ /** 44pt: iOS's touch minimum, and enough for an `lg` line with room to spare. */
74
78
  const DEFAULT_ITEM_HEIGHT = 44;
75
79
  /**
76
- * Filas hacia cada lado que la interpolación distingue; más lejos, todas
77
- * iguales (`extrapolate: 'clamp'`). Los tres rangos son simétricos respecto
78
- * del centro: la fila de arriba y la de abajo se ven igual, sólo que la de
79
- * arriba se inclina hacia atrás y la de abajo hacia adelante.
80
+ * Rows toward each side that the interpolation distinguishes; further out,
81
+ * all the same (`extrapolate: 'clamp'`). The three ranges are symmetric
82
+ * around the center: the row above and the row below look the same, except
83
+ * the one above tilts backward and the one below forward.
80
84
  */
81
85
  const FALLOFF = 2;
82
86
 
83
87
  /**
84
- * Cada variante es un juego de rangos. 'spotlight' cae mucho más rápido y se
85
- * inclina más porque no tiene banda que señale el centro: todo el trabajo de
86
- * decir cuál está elegida lo hacen el contraste y la nitidez.
88
+ * Each variant is a set of ranges. 'spotlight' falls off much faster and
89
+ * tilts more because it has no band marking the center: all the work of
90
+ * saying which one is selected is done by contrast and sharpness.
87
91
  */
88
92
  const RANGES: Record<OptionWheelVariant, { opacity: number[]; scale: number[]; rotation: string[] }> = {
89
93
  window: {
@@ -99,28 +103,28 @@ const RANGES: Record<OptionWheelVariant, { opacity: number[]; scale: number[]; r
99
103
  };
100
104
 
101
105
  /**
102
- * React Native no tiene desenfoque sin dependencia nativa, así que en
103
- * 'spotlight' cada fila que no está en el centro se dibuja además dos veces
104
- * corrida y a media tinta. La superposición emborrona el trazo: no es un blur
105
- * gaussiano, pero a ese tamaño y con esa opacidad lee igual, y sigue siendo
106
- * `opacity` y `transform` sobre el mismo scroll, o sea el hilo nativo.
106
+ * React Native has no blur without a native dependency, so in 'spotlight'
107
+ * each row that isn't in the center is also drawn twice, offset and at half
108
+ * ink. The overlap smears the stroke: it isn't a gaussian blur, but at that
109
+ * size and opacity it reads the same, and it is still `opacity` and
110
+ * `transform` over the same scroll, i.e. the native thread.
107
111
  */
108
112
  /**
109
- * Dónde cae cada punto del `inputRange` sobre el arco. `Animated` no sabe
110
- * calcular raíces ni arcosenos, pero no hace falta: las cinco distancias al
111
- * centro son fijas por fila, así que la flecha del arco y el ángulo de la
112
- * tangente se resuelven una vez acá y entran como `outputRange`.
113
+ * Where each point of the `inputRange` falls on the arc. `Animated` can't
114
+ * compute roots or arcsines, but it doesn't need to: the five distances to
115
+ * the center are fixed per row, so the arc's sagitta and the tangent's angle
116
+ * are resolved once here and go in as `outputRange`.
113
117
  */
114
118
  function arcOffsets(radius: number, itemHeight: number, sign: number) {
115
119
  const shift: number[] = [];
116
120
  const angle: string[] = [];
117
121
  for (let step = -FALLOFF; step <= FALLOFF; step += 1) {
118
- // Más allá del radio la fila ya dio la vuelta: se corta ahí en vez de
119
- // sacarle la raíz a un negativo.
122
+ // Beyond the radius the row has already turned over: cut it off there
123
+ // instead of taking the root of a negative.
120
124
  const dy = Math.min(Math.abs(step * itemHeight), radius);
121
- // Flecha del arco: cuánto se mete la fila hacia el centro de la rueda.
125
+ // Arc sagitta: how far the row moves in toward the center of the wheel.
122
126
  shift.push(sign * (radius - Math.sqrt(radius * radius - dy * dy)));
123
- // La tangente del arco, para que la fila siga la curva en vez de cruzarla.
127
+ // The arc's tangent, so the row follows the curve instead of crossing it.
124
128
  const degrees = Math.asin(dy / radius) * (180 / Math.PI);
125
129
  angle.push(`${-sign * Math.sign(step) * degrees}deg`);
126
130
  }
@@ -140,7 +144,7 @@ const useStyles = createStyles((theme) => ({
140
144
  },
141
145
  viewport: { overflow: 'hidden' },
142
146
  disabled: { opacity: 0.5 },
143
- // La ventana central: figura contra el fondo de opciones que pasan.
147
+ // The center window: figure against the ground of options passing by.
144
148
  window: {
145
149
  position: 'absolute',
146
150
  left: 0,
@@ -166,7 +170,7 @@ const useStyles = createStyles((theme) => ({
166
170
  unit: { fontSize: theme.tokens.fontSize.sm, color: theme.colors.textLight },
167
171
  }));
168
172
 
169
- /** El índice habilitado más cercano a `index`, o -1 si no hay ninguno. */
173
+ /** The enabled index closest to `index`, or -1 if there is none. */
170
174
  function nearestEnabled<T>(options: OptionWheelOption<T>[], index: number): number {
171
175
  if (options.length === 0) return -1;
172
176
  for (let step = 0; step < options.length; step += 1) {
@@ -180,25 +184,25 @@ function nearestEnabled<T>(options: OptionWheelOption<T>[], index: number): numb
180
184
 
181
185
  /**
182
186
  * OptionWheel
183
- * Selector de rueda: las opciones pasan por una ventana fija y la que queda en
184
- * el centro es la elegida. El scroll hace snap a la altura de fila, así que
185
- * soltar el dedo en cualquier lado siempre deja una opción centrada y no media.
187
+ * Wheel picker: the options pass through a fixed window and the one left in
188
+ * the center is the selected one. The scroll snaps to the row height, so
189
+ * lifting the finger anywhere always leaves one option centered, never half.
186
190
  *
187
- * Gestalt, figura y fondo: lo que marca la selección no es un estilo sobre la
188
- * fila —que viajaría con ella— sino una ventana quieta encima de la lista. La
189
- * figura se queda, el fondo se mueve, y por eso la rueda se lee sin leer: el
190
- * lugar señala, no el color. Y destino común: todas las filas se achican y se
191
- * inclinan con la misma ley respecto del centro, de modo que se perciben como
192
- * una superficie rígida que gira y no como N filas animándose por su cuenta.
191
+ * Gestalt, figure and ground: what marks the selection isn't a style on the
192
+ * row —which would travel with it— but a still window on top of the list. The
193
+ * figure stays, the ground moves, and that is why the wheel reads without
194
+ * reading: the place signals, not the color. And common fate: all rows shrink
195
+ * and tilt by the same law relative to the center, so they are perceived as a
196
+ * rigid surface that turns and not as N rows animating on their own.
193
197
  *
194
- * La escala, la opacidad y la inclinación salen de interpolar el
195
- * `contentOffset` del scroll, no del estado de React: se calculan en el hilo
196
- * nativo (`useNativeDriver`) y el hilo de JS sólo participa cuando la rueda ya
197
- * frenó, para avisar qué quedó elegido. Con "reducir movimiento" activo se
198
- * apaga la inclinación y queda el tamaño, que es información, no decoración.
198
+ * Scale, opacity and tilt come from interpolating the scroll's
199
+ * `contentOffset`, not from React state: they are computed on the native
200
+ * thread (`useNativeDriver`) and the JS thread only takes part once the wheel
201
+ * has stopped, to report what was selected. With "reduce motion" on, the tilt
202
+ * is turned off and the size stays, since it is information, not decoration.
199
203
  *
200
- * `disabled` en una opción no puede impedir que el snap la centre, así que la
201
- * rueda la centra y se corre sola a la habilitada más cercana.
204
+ * `disabled` on an option can't keep the snap from centering it, so the
205
+ * wheel centers it and moves on its own to the nearest enabled one.
202
206
  */
203
207
  export function OptionWheel<T extends string | number>({
204
208
  options,
@@ -223,14 +227,14 @@ export function OptionWheel<T extends string | number>({
223
227
  const allowFontScaling = useAllowFontScaling();
224
228
  const reduceMotion = useReduceMotion();
225
229
 
226
- const scrollRef = useRef<ScrollView>(null);
230
+ const scrollRef = useRef<ComponentRef<typeof ScrollView>>(null);
227
231
  const scrollY = useRef(new Animated.Value(0)).current;
228
- // El primer posicionamiento no se anima: la rueda tiene que aparecer ya
229
- // puesta en su valor, no viajando hasta él.
232
+ // The first positioning isn't animated: the wheel has to appear already
233
+ // set at its value, not traveling to it.
230
234
  const settled = useRef(false);
231
235
 
232
- // Impar siempre: con un número par no hay fila central que alinear con la
233
- // ventana, y el snap dejaría la selección entre dos filas.
236
+ // Always odd: with an even number there is no center row to line up with
237
+ // the window, and the snap would leave the selection between two rows.
234
238
  const rows = visibleCount % 2 === 0 ? visibleCount + 1 : visibleCount;
235
239
  const padding = ((rows - 1) / 2) * itemHeight;
236
240
  const height = rows * itemHeight;
@@ -244,11 +248,11 @@ export function OptionWheel<T extends string | number>({
244
248
  (index: number, animated: boolean) => {
245
249
  const y = index * itemHeight;
246
250
  scrollRef.current?.scrollTo({ y, animated });
247
- // `scrollY` sólo lo alimenta `onScroll`, y un salto sin animar no
248
- // siempre lo emite: sin esto el valor se queda en 0, la interpolación
249
- // cree que la fila centrada es la primera y apaga la que de verdad está
250
- // en la ventana. El scroll animado sí emite en todo el recorrido, así
251
- // que ahí forzarlo pelearía con la animación.
251
+ // `scrollY` is only fed by `onScroll`, and an unanimated jump doesn't
252
+ // always emit it: without this the value stays at 0, the interpolation
253
+ // thinks the centered row is the first one and dims the one that is
254
+ // really in the window. The animated scroll does emit along the whole
255
+ // path, so forcing it there would fight the animation.
252
256
  if (!animated) scrollY.setValue(y);
253
257
  },
254
258
  [itemHeight, scrollY]
@@ -261,10 +265,10 @@ export function OptionWheel<T extends string | number>({
261
265
  }, [selectedIndex, scrollToIndex, reduceMotion]);
262
266
 
263
267
  /**
264
- * Corre tanto al final del arrastre como al final de la inercia: en Android
265
- * un arrastre corto sin impulso no dispara `onMomentumScrollEnd`, y la rueda
266
- * se quedaría con la selección vieja. Reentrar con el mismo índice es inocuo
267
- * porque sólo avisa cuando cambia.
268
+ * Runs both at the end of the drag and at the end of momentum: on Android
269
+ * a short drag with no momentum doesn't fire `onMomentumScrollEnd`, and the
270
+ * wheel would keep the old selection. Re-entering with the same index is
271
+ * harmless because it only reports when it changes.
268
272
  */
269
273
  const commit = useCallback(
270
274
  (event: NativeSyntheticEvent<NativeScrollEvent>) => {
@@ -274,8 +278,8 @@ export function OptionWheel<T extends string | number>({
274
278
  if (!landed) return;
275
279
  const target = landed.disabled ? nearestEnabled(options, clamped) : clamped;
276
280
  const option = options[target];
277
- // Sin opciones habilitadas no hay dónde parar: la rueda se queda donde
278
- // la dejaron y no avisa nada.
281
+ // With no enabled options there is nowhere to stop: the wheel stays where
282
+ // it was left and reports nothing.
279
283
  if (!option) return;
280
284
  if (target !== clamped) scrollToIndex(target, true);
281
285
  if (option.value !== selectedValue) onSelect(option.value);
@@ -283,13 +287,13 @@ export function OptionWheel<T extends string | number>({
283
287
  [options, itemHeight, selectedValue, onSelect, scrollToIndex]
284
288
  );
285
289
 
286
- /** VoiceOver/TalkBack recorren la rueda con increment/decrement, no con el dedo. */
290
+ /** VoiceOver/TalkBack go through the wheel with increment/decrement, not the finger. */
287
291
  const step = useCallback(
288
292
  (delta: number) => {
289
293
  if (disabled || selectedIndex < 0) return;
290
294
  const next = nearestEnabled(options, selectedIndex + delta);
291
295
  const option = options[next];
292
- // En el borde, `nearestEnabled` devuelve la fila donde ya estamos.
296
+ // At the edge, `nearestEnabled` returns the row we are already on.
293
297
  if (!option || next === selectedIndex) return;
294
298
  onSelect(option.value);
295
299
  },
@@ -305,9 +309,9 @@ export function OptionWheel<T extends string | number>({
305
309
 
306
310
  const selected = selectedIndex >= 0 ? options[selectedIndex] : undefined;
307
311
  const ranges = RANGES[variant];
308
- // El desenfoque simulado triplica los nodos de texto: sólo va donde aporta,
309
- // y con "reducir movimiento" no va, porque ahí la nitidez es lo único que
310
- // queda para distinguir la fila elegida.
312
+ // The simulated blur triples the text nodes: it only goes where it helps,
313
+ // and not with "reduce motion", because there sharpness is the only thing
314
+ // left to tell the selected row apart.
311
315
  const smeared = variant === 'spotlight' && !reduceMotion;
312
316
  const arc = useMemo(
313
317
  () =>
@@ -379,8 +383,8 @@ export function OptionWheel<T extends string | number>({
379
383
  { scale: scrollY.interpolate({ inputRange, outputRange: ranges.scale, extrapolate: 'clamp' }) },
380
384
  ];
381
385
  if (perspective && !reduceMotion) {
382
- // El perspective va primero: aplicado después de la rotación no
383
- // deforma nada y la fila se ve plana aunque esté rotada.
386
+ // perspective goes first: applied after the rotation it doesn't
387
+ // distort anything and the row looks flat even though it's rotated.
384
388
  transform.unshift({ perspective: height * 2 });
385
389
  transform.push({
386
390
  rotateX: scrollY.interpolate({ inputRange, outputRange: ranges.rotation, extrapolate: 'clamp' }),
@@ -425,9 +429,9 @@ export function OptionWheel<T extends string | number>({
425
429
  <Animated.View
426
430
  key={direction}
427
431
  pointerEvents="none"
428
- // `accessibilityElementsHidden` no alcanza: el lector
429
- // leería la fila tres veces igual, porque la rueda entera
430
- // ya es un solo elemento y esto vive adentro.
432
+ // `accessibilityElementsHidden` isn't enough: the reader
433
+ // would read the row three times over, because the whole
434
+ // wheel is already a single element and this lives inside it.
431
435
  style={[
432
436
  styles.ghost,
433
437
  {
@@ -1,12 +1,16 @@
1
1
  import React, { useRef, useState } from 'react';
2
2
  import { Animated, PanResponder, View, type StyleProp, type ViewStyle } from 'react-native';
3
3
  import { createStyles } from '../theme/createStyles';
4
+ import { useLabels } from '../theme/UIProvider';
4
5
 
5
6
  export interface ReorderableListProps<T> {
7
+ /** Items, in their current order. */
6
8
  data: T[];
9
+ /** Stable key per item. */
7
10
  keyExtractor: (item: T, index: number) => string;
8
11
  /** Fixed height of each row: needed to calculate the target index without measuring layout async. */
9
12
  itemHeight: number;
13
+ /** Renders each row; the third argument is true while that row is being dragged. */
10
14
  renderItem: (item: T, index: number, dragging: boolean) => React.ReactElement;
11
15
  /** Called on release, with the array already reordered. Does not mutate `data`. */
12
16
  onReorder: (data: T[]) => void;
@@ -19,11 +23,12 @@ export interface ReorderableListProps<T> {
19
23
  onDragStart?: (index: number) => void;
20
24
  /** Ends the drag — on release or cancellation. Always runs if `onDragStart` ran. */
21
25
  onDragEnd?: () => void;
26
+ /** Turns off dragging. @default false */
22
27
  disabled?: boolean;
23
28
  style?: StyleProp<ViewStyle>;
24
29
  }
25
30
 
26
- /** Reordena moviendo el ítem de `from` a `to`, sin mutar `data`. Exportada aparte por ser testeable sin simular gestos. */
31
+ /** Reorders by moving the item from `from` to `to`, without mutating `data`. Exported separately so it can be tested without simulating gestures. */
27
32
  export function move<T>(data: T[], from: number, to: number): T[] {
28
33
  const next = data.slice();
29
34
  const [item] = next.splice(from, 1) as [T];
@@ -37,18 +42,23 @@ const useStyles = createStyles(() => ({
37
42
 
38
43
  /**
39
44
  * ReorderableList
40
- * Ley de destino común (common fate): al arrastrar una fila, las filas que
41
- * tiene que atravesar se desplazan juntas en el mismo sentido — eso es lo
42
- * que comunica "van a intercambiar lugar" antes de soltar el dedo, no un
43
- * simple resaltado del ítem activo.
45
+ * Law of common fate: when dragging a row, the rows it has to cross shift
46
+ * together in the same direction — that is what communicates "they are
47
+ * going to swap places" before the finger lifts, not a simple highlight of
48
+ * the active item.
44
49
  *
45
- * Sin dependencias de gestos/animación externas (reanimated, gesture-handler):
46
- * PanResponder + Animated alcanzan porque el cálculo de índice destino
47
- * necesita el valor de arrastre en JS en cada movimiento (no algo que
48
- * useNativeDriver pueda resolver solo).
50
+ * No external gesture/animation dependencies (reanimated, gesture-handler):
51
+ * PanResponder + Animated are enough because computing the target index
52
+ * needs the drag value in JS on every move (not something useNativeDriver
53
+ * can resolve on its own).
49
54
  *
50
- * Dentro de un scroll vertical hay que cablear `onDragStart`/`onDragEnd` a
51
- * `scrollEnabled`, o en iOS el arrastre no llega a empezar:
55
+ * Inside a vertical scroll you have to wire `onDragStart`/`onDragEnd` to
56
+ * `scrollEnabled`, or on iOS the drag never gets to start:
57
+ *
58
+ * Screen readers can't drag: each row is one accessible element with two
59
+ * actions, "Move up" and "Move down" (`labels.moveUp` / `labels.moveDown`),
60
+ * that call `onReorder` the same way a drop does. The row's content is read
61
+ * as its label, so keep interactive controls out of reorderable rows.
52
62
  *
53
63
  * ```tsx
54
64
  * const [dragging, setDragging] = useState(false);
@@ -69,24 +79,25 @@ export function ReorderableList<T>({
69
79
  style,
70
80
  }: ReorderableListProps<T>) {
71
81
  const styles = useStyles();
82
+ const labels = useLabels();
72
83
  const [activeIndex, setActiveIndex] = useState<number | null>(null);
73
84
  const [targetIndex, setTargetIndex] = useState<number | null>(null);
74
85
  const dy = useRef(new Animated.Value(0)).current;
75
86
  const activeIndexRef = useRef<number | null>(null);
76
- // El PanResponder de cada fila se crea una sola vez (se cachea en el Map de
77
- // abajo) y su closure queda fijo al render de esa primera vez: leer
78
- // `targetIndex` (state) directamente ahí siempre daría el valor del
79
- // montaje. Un ref sí refleja la última escritura sin importar cuándo se
80
- // creó la closure que lo lee.
87
+ // Each row's PanResponder is created only once (cached in the Map below)
88
+ // and its closure stays fixed to that first render: reading `targetIndex`
89
+ // (state) directly there would always give the value from mount. A ref
90
+ // does reflect the latest write no matter when the closure reading it was
91
+ // created.
81
92
  const targetIndexRef = useRef<number | null>(null);
82
93
  const dataRef = useRef(data);
83
94
  dataRef.current = data;
84
- // Igual razón que targetIndexRef: el responder de cada fila se crea una
85
- // sola vez, así que leer `disabled` directo del closure congelaría el
86
- // valor del momento en que esa fila se creó.
95
+ // Same reason as targetIndexRef: each row's responder is created only
96
+ // once, so reading `disabled` straight from the closure would freeze the
97
+ // value from when that row was created.
87
98
  const disabledRef = useRef(disabled);
88
99
  disabledRef.current = disabled;
89
- // Misma razón: los callbacks se leen desde closures creadas una sola vez.
100
+ // Same reason: the callbacks are read from closures created only once.
90
101
  const onReorderRef = useRef(onReorder);
91
102
  onReorderRef.current = onReorder;
92
103
  const onDragStartRef = useRef(onDragStart);
@@ -95,8 +106,8 @@ export function ReorderableList<T>({
95
106
  onDragEndRef.current = onDragEnd;
96
107
 
97
108
  const panResponders = useRef(new Map<number, ReturnType<typeof PanResponder.create>>()).current;
98
- // Si `data` se achica, los responders de índices que ya no existen quedan
99
- // colgados en el Map para siempre: se podan en cada render.
109
+ // If `data` shrinks, the responders for indexes that no longer exist stay
110
+ // stuck in the Map forever: they are pruned on every render.
100
111
  for (const index of panResponders.keys()) {
101
112
  if (index >= data.length) panResponders.delete(index);
102
113
  }
@@ -117,9 +128,9 @@ export function ReorderableList<T>({
117
128
  responder = PanResponder.create({
118
129
  onStartShouldSetPanResponder: () => !disabledRef.current,
119
130
  onMoveShouldSetPanResponder: (_, gesture) => !disabledRef.current && Math.abs(gesture.dy) > 2,
120
- // Un scroll padre pide el responder apenas su gesto vertical arranca —
121
- // el mismo eje que el arrastre. Cederlo cancelaría el drag a mitad de
122
- // camino, así que la fila se lo queda hasta soltar.
131
+ // A parent scroll requests the responder as soon as its vertical gesture
132
+ // starts — the same axis as the drag. Yielding it would cancel the drag
133
+ // midway, so the row keeps it until release.
123
134
  onPanResponderTerminationRequest: () => false,
124
135
  onPanResponderGrant: () => {
125
136
  activeIndexRef.current = index;
@@ -155,8 +166,8 @@ export function ReorderableList<T>({
155
166
  <View style={style}>
156
167
  {data.map((item, index) => {
157
168
  const isActive = activeIndex === index;
158
- // Filas entre el origen y el destino se corren un lugar entero en el
159
- // sentido del arrastre: es el efecto de "grupo que se mueve junto".
169
+ // Rows between the origin and the target shift one full place in the
170
+ // drag direction: it is the "group moving together" effect.
160
171
  let shift = 0;
161
172
  if (activeIndex !== null && targetIndex !== null && !isActive) {
162
173
  if (activeIndex < targetIndex && index > activeIndex && index <= targetIndex) shift = -itemHeight;
@@ -173,6 +184,17 @@ export function ReorderableList<T>({
173
184
  : { transform: [{ translateY: shift }] },
174
185
  ]}
175
186
  {...panResponderFor(index).panHandlers}
187
+ accessible
188
+ accessibilityActions={[
189
+ ...(index > 0 ? [{ name: 'moveUp', label: labels.moveUp }] : []),
190
+ ...(index < data.length - 1 ? [{ name: 'moveDown', label: labels.moveDown }] : []),
191
+ ]}
192
+ onAccessibilityAction={(event) => {
193
+ if (disabled) return;
194
+ const to = event.nativeEvent.actionName === 'moveUp' ? index - 1 : index + 1;
195
+ if (to < 0 || to >= data.length) return;
196
+ onReorder(move(data, index, to));
197
+ }}
176
198
  >
177
199
  {renderItem(item, index, isActive)}
178
200
  </Animated.View>
@@ -1,23 +1,32 @@
1
1
  import React, { memo } from 'react';
2
2
  import { KeyboardAvoidingView, Platform, ScrollView, View, type ViewStyle } from 'react-native';
3
3
  import { createStyles } from '../theme/createStyles';
4
- import { useInsets } from '../theme/UIProvider';
4
+ import { useInsets, useTheme } from '../theme/UIProvider';
5
+ import { KeyboardHandled, KeyboardPanArea, useKeyboardHost } from '../theme/KeyboardAvoidance';
5
6
 
6
7
  export type ScreenEdge = 'top' | 'bottom';
7
8
 
8
9
  export interface ScreenProps {
10
+ /** Content of the screen. */
9
11
  children: React.ReactNode;
12
+ /**
13
+ * Fixed bar on top (back button, title, actions). It stays in place while
14
+ * the content scrolls or moves up for the keyboard. The top safe area goes
15
+ * above it.
16
+ */
17
+ header?: React.ReactNode;
10
18
  style?: ViewStyle;
19
+ /** Wraps the content in a ScrollView. @default true */
11
20
  scrollable?: boolean;
21
+ /** Style of the ScrollView's content container. Only applies when `scrollable`. */
12
22
  contentContainerStyle?: ViewStyle;
13
23
  /** Which safe area insets to apply. @default ['top', 'bottom'] */
14
24
  edges?: ScreenEdge[];
15
25
  /**
16
- * Compensates for the keyboard: on iOS with scroll the ScrollView itself does it, in
17
- * other cases a KeyboardAvoidingView does. Set to false when
18
- * the content already brings its own scroller that handles the keyboard (Wizard,
19
- * List, SearchList): the two compensations add up and the focused field
20
- * ends up pushed off screen.
26
+ * Keeps the focused Input above the keyboard by moving only the content
27
+ * (the `header` and a tab bar outside the Screen stay put). On iOS with
28
+ * scroll, the ScrollView scrolls to it instead. Set to false when the
29
+ * content brings its own keyboard handling.
21
30
  * @default true
22
31
  */
23
32
  keyboardAvoiding?: boolean;
@@ -27,15 +36,28 @@ const useStyles = createStyles((theme) => ({
27
36
  wrapper: { flex: 1, backgroundColor: theme.colors.background },
28
37
  container: { flex: 1 },
29
38
  contentContainer: { flexGrow: 1 },
39
+ header: { backgroundColor: theme.colors.background },
30
40
  }));
31
41
 
32
42
  /**
33
43
  * Screen
34
- * Contenedor raíz de pantalla: fondo del theme, safe area (via insets del
35
- * UIProvider), teclado y scroll opcional resueltos de forma consistente.
44
+ * Root screen container: theme background, safe area (via the UIProvider's
45
+ * insets), keyboard and optional scroll handled consistently.
46
+ *
47
+ * Keyboard: with the UIProvider handling it (default), Screen shifts only its
48
+ * content — clipped below the `header` — to keep the focused Input above the
49
+ * keyboard. The header stays fixed and a tab bar outside the Screen stays
50
+ * behind the keyboard, as in a native app. On iOS with scroll, the ScrollView
51
+ * already brings the field into view (automaticallyAdjustKeyboardInsets) and
52
+ * nothing is added. Without a host (`keyboardAvoidance={false}` on the
53
+ * provider) the usual KeyboardAvoidingView remains.
54
+ *
55
+ * Gestalt, common region: the header shares the screen's background and stays
56
+ * fixed; only the content moves, so navigation isn't lost.
36
57
  */
37
58
  export const Screen = memo(({
38
59
  children,
60
+ header,
39
61
  style,
40
62
  scrollable = true,
41
63
  contentContainerStyle,
@@ -44,47 +66,62 @@ export const Screen = memo(({
44
66
  }: ScreenProps) => {
45
67
  const insets = useInsets();
46
68
  const styles = useStyles();
69
+ const theme = useTheme();
70
+ const host = useKeyboardHost();
47
71
  const applyTop = edges.includes('top');
48
72
  const applyBottom = edges.includes('bottom');
73
+ const topInset = applyTop ? insets.top : 0;
74
+
75
+ const scrollHandles = keyboardAvoiding && scrollable && Platform.OS === 'ios';
76
+ const panArea = keyboardAvoiding && !scrollHandles && !!host;
77
+ const avoidWithView = keyboardAvoiding && !scrollHandles && !host;
49
78
 
50
- // En iOS el ScrollView de abajo ya sube el campo enfocado con
51
- // automaticallyAdjustKeyboardInsets; envolverlo además en un
52
- // KeyboardAvoidingView compensa el teclado dos veces y el input termina
53
- // empujado fuera del borde superior. Android no tiene ese prop, así que ahí
54
- // el KeyboardAvoidingView sigue siendo el único mecanismo.
55
- const avoidWithView = keyboardAvoiding && !(scrollable && Platform.OS === 'ios');
79
+ // With a header, the top inset goes above the header; the content starts
80
+ // right below it.
81
+ const contentTop = header ? 0 : topInset;
82
+
83
+ let content = scrollable ? (
84
+ <ScrollView
85
+ style={styles.container}
86
+ automaticallyAdjustKeyboardInsets={scrollHandles}
87
+ contentContainerStyle={[
88
+ styles.contentContainer,
89
+ { paddingTop: contentTop },
90
+ applyBottom && { paddingBottom: insets.bottom },
91
+ contentContainerStyle,
92
+ ]}
93
+ keyboardShouldPersistTaps="handled"
94
+ >
95
+ {scrollHandles ? <KeyboardHandled>{children}</KeyboardHandled> : children}
96
+ </ScrollView>
97
+ ) : (
98
+ <View style={[styles.container, { paddingTop: contentTop, paddingBottom: applyBottom ? insets.bottom : 0 }]}>
99
+ {children}
100
+ </View>
101
+ );
56
102
 
57
- const KeyboardWrapper: React.ComponentType<any> = avoidWithView ? KeyboardAvoidingView : View;
58
- const keyboardProps = avoidWithView
59
- ? {
60
- behavior: Platform.OS === 'ios' ? ('padding' as const) : ('height' as const),
61
- keyboardVerticalOffset: Platform.OS === 'ios' ? 0 : 20,
62
- }
63
- : {};
103
+ if (panArea) {
104
+ content = (
105
+ <KeyboardPanArea margin={theme.tokens.spacing.md} topLimit={insets.top} clip>
106
+ {content}
107
+ </KeyboardPanArea>
108
+ );
109
+ } else if (avoidWithView) {
110
+ content = (
111
+ <KeyboardAvoidingView
112
+ style={styles.container}
113
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
114
+ keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : theme.tokens.spacing.xl}
115
+ >
116
+ {content}
117
+ </KeyboardAvoidingView>
118
+ );
119
+ }
64
120
 
65
121
  return (
66
122
  <View style={[styles.wrapper, style]}>
67
- <KeyboardWrapper style={styles.container} {...keyboardProps}>
68
- {scrollable ? (
69
- <ScrollView
70
- style={styles.container}
71
- automaticallyAdjustKeyboardInsets
72
- contentContainerStyle={[
73
- styles.contentContainer,
74
- { paddingTop: applyTop ? insets.top : 0 },
75
- applyBottom && { paddingBottom: insets.bottom },
76
- contentContainerStyle,
77
- ]}
78
- keyboardShouldPersistTaps="handled"
79
- >
80
- {children}
81
- </ScrollView>
82
- ) : (
83
- <View style={[styles.container, { paddingTop: applyTop ? insets.top : 0, paddingBottom: applyBottom ? insets.bottom : 0 }]}>
84
- {children}
85
- </View>
86
- )}
87
- </KeyboardWrapper>
123
+ {header && <View style={[styles.header, { paddingTop: topInset }]}>{header}</View>}
124
+ {content}
88
125
  </View>
89
126
  );
90
127
  });