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 { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1
+ import { useCallback, useEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
2
2
  import type { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, ScrollView } from 'react-native';
3
3
  import { useReduceMotion } from '../atoms/Transition';
4
4
 
@@ -10,13 +10,13 @@ export interface UseSlidesOptions {
10
10
  loop: boolean;
11
11
  autoPlay: boolean;
12
12
  interval: number;
13
- /** Índice controlado; sin él manda el estado interno. */
13
+ /** Controlled index; without it the internal state rules. */
14
14
  index?: number;
15
15
  defaultIndex: number;
16
16
  onIndexChange?: (index: number) => void;
17
17
  }
18
18
 
19
- /** Una página del scroll. Los clones del modo infinito repiten el `real` de un vecino. */
19
+ /** A page of the scroll. The infinite mode's clones repeat a neighbor's `real`. */
20
20
  export interface SlidesPage {
21
21
  real: number;
22
22
  clone: 'head' | 'tail' | null;
@@ -28,18 +28,18 @@ export interface UseSlidesResult {
28
28
  isHorizontal: boolean;
29
29
  isLoop: boolean;
30
30
  size: { width: number; height: number };
31
- /** Largo de una página sobre el eje del scroll. En 0 todavía no se midió. */
31
+ /** Length of a page along the scroll axis. At 0 it hasn't been measured yet. */
32
32
  pageSize: number;
33
- scrollRef: React.RefObject<ScrollView | null>;
33
+ scrollRef: React.RefObject<ComponentRef<typeof ScrollView> | null>;
34
34
  autoPlayPaused: boolean;
35
- /** El sistema pidió reducir movimiento: no hay autoPlay ni transiciones. */
35
+ /** The system asked to reduce motion: no autoPlay or transitions. */
36
36
  motionReduced: boolean;
37
37
  goTo: (index: number) => void;
38
38
  toggleAutoPlay: () => void;
39
39
  onLayout: (event: LayoutChangeEvent) => void;
40
40
  onMomentumScrollEnd: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
41
- onScrollBeginDrag: () => void;
42
- onScrollEndDrag: () => void;
41
+ onScrollBeginDrag: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
42
+ onScrollEndDrag: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
43
43
  }
44
44
 
45
45
  export function clampIndex(value: number, total: number): number {
@@ -51,13 +51,16 @@ export function clampIndex(value: number, total: number): number {
51
51
 
52
52
  /**
53
53
  * useSlides
54
- * Todo lo que en `Slides` no se ve: qué página está encuadrada, cuándo mover el
55
- * scroll, cómo se mapean los clones del modo infinito a índices reales, y el
56
- * reloj del avance automático.
54
+ * Everything in `Slides` that isn't visible: which page is framed, when to
55
+ * move the scroll, how the infinite mode's clones map to real indexes, and the
56
+ * autoplay clock.
57
57
  *
58
- * Trabaja sólo con índices, nunca con los ítems: así no necesita el genérico
59
- * `T` del componente, y el UI resuelve `pages[i].real` contra su propio `data`.
58
+ * It works only with indexes, never with the items: that way it doesn't need
59
+ * the component's generic `T`, and the UI resolves `pages[i].real` against its own `data`.
60
60
  */
61
+ /** Points a finger has to move the slides for the drag to count as a swipe. */
62
+ const DRAG_SLOP = 10;
63
+
61
64
  export function useSlides({
62
65
  total,
63
66
  orientation,
@@ -70,8 +73,8 @@ export function useSlides({
70
73
  }: UseSlidesOptions): UseSlidesResult {
71
74
  const motionReduced = useReduceMotion();
72
75
  const isHorizontal = orientation === 'horizontal';
73
- // Un solo elemento no tiene a dónde ciclar: quedaría deslizable entre tres
74
- // copias de lo mismo.
76
+ // A single element has nowhere to cycle to: it would be swipeable between
77
+ // three copies of the same thing.
75
78
  const isLoop = loop && total > 1;
76
79
 
77
80
  const [uncontrolled, setUncontrolled] = useState(() => clampIndex(defaultIndex, total));
@@ -83,12 +86,19 @@ export function useSlides({
83
86
  const [size, setSize] = useState({ width: 0, height: 0 });
84
87
  const pageSize = isHorizontal ? size.width : size.height;
85
88
 
86
- const scrollRef = useRef<ScrollView>(null);
87
- /** Página realmente visible (índice dentro de `pages`, clones incluidos). */
89
+ const scrollRef = useRef<ComponentRef<typeof ScrollView>>(null);
90
+ /** The page actually visible (index within `pages`, clones included). */
88
91
  const offsetPageRef = useRef(isLoop ? 1 : 0);
89
92
  const didInitRef = useRef(false);
90
93
  const lastPageSizeRef = useRef(0);
91
94
  const draggingRef = useRef(false);
95
+ /**
96
+ * Page an animated `scrollTo` was sent to and hasn't reached yet. On iOS a
97
+ * touch (tapping another indicator) stops that animation midway: the
98
+ * scroll then ends on the wrong page, and committing it undid the tap.
99
+ */
100
+ const pendingPageRef = useRef<number | null>(null);
101
+ const dragStartRef = useRef(0);
92
102
 
93
103
  const pages = useMemo<SlidesPage[]>(() => {
94
104
  const real = Array.from({ length: total }, (_, i) => ({ real: i, clone: null }));
@@ -118,19 +128,20 @@ export function useSlides({
118
128
  [index, onIndexChange]
119
129
  );
120
130
 
121
- // Sólo actúa cuando el índice y la página visible discrepan: un cambio que
122
- // vino del propio gesto no dispara un segundo scroll encima del que frenó.
131
+ // Only acts when the index and the visible page disagree: a change that
132
+ // came from the gesture itself doesn't fire a second scroll on top of the one that stopped.
123
133
  useEffect(() => {
124
134
  if (pageSize === 0 || total === 0) return;
125
135
  const target = isLoop ? active + 1 : active;
126
136
  const resized = lastPageSizeRef.current !== pageSize;
127
137
  if (offsetPageRef.current === target && didInitRef.current && !resized) return;
128
- // Ni el primer posicionamiento ni el reacomodo por rotación son un cambio
129
- // de slide: animarlos sería un deslizamiento que nadie pidió.
138
+ // Neither the first positioning nor the rearrangement on rotation is a
139
+ // slide change: animating them would be a slide nobody asked for.
130
140
  const animated = didInitRef.current && !resized;
131
141
  didInitRef.current = true;
132
142
  lastPageSizeRef.current = pageSize;
133
143
  offsetPageRef.current = target;
144
+ pendingPageRef.current = animated ? target : null;
134
145
  scrollToPage(target, animated);
135
146
  }, [active, isLoop, pageSize, scrollToPage, total]);
136
147
 
@@ -145,6 +156,16 @@ export function useSlides({
145
156
  if (pageSize === 0) return;
146
157
  const { contentOffset } = event.nativeEvent;
147
158
  const page = Math.round((isHorizontal ? contentOffset.x : contentOffset.y) / pageSize);
159
+ // A scrollTo still on its way: if it stopped short (a touch interrupted
160
+ // it), finish the trip instead of committing where it stopped.
161
+ const pending = pendingPageRef.current;
162
+ if (pending !== null) {
163
+ if (page !== pending) {
164
+ scrollToPage(pending, true);
165
+ return;
166
+ }
167
+ pendingPageRef.current = null;
168
+ }
148
169
 
149
170
  if (isLoop) {
150
171
  if (page === 0) {
@@ -170,15 +191,28 @@ export function useSlides({
170
191
  [goTo, isHorizontal, isLoop, pageSize, scrollToPage, total]
171
192
  );
172
193
 
173
- const onScrollBeginDrag = useCallback(() => {
174
- draggingRef.current = true;
175
- }, []);
194
+ const onScrollBeginDrag = useCallback(
195
+ (event: NativeSyntheticEvent<NativeScrollEvent>) => {
196
+ draggingRef.current = true;
197
+ const { contentOffset } = event.nativeEvent;
198
+ dragStartRef.current = isHorizontal ? contentOffset.x : contentOffset.y;
199
+ },
200
+ [isHorizontal]
201
+ );
176
202
 
177
- const onScrollEndDrag = useCallback(() => {
178
- // Un arrastre corto puede soltarse sin inercia y no emitir
179
- // momentumScrollEnd: sin esto el autoPlay quedaría pausado para siempre.
180
- draggingRef.current = false;
181
- }, []);
203
+ const onScrollEndDrag = useCallback(
204
+ (event: NativeSyntheticEvent<NativeScrollEvent>) => {
205
+ // A short drag can be released without momentum and not emit
206
+ // momentumScrollEnd: without this autoPlay would stay paused forever.
207
+ draggingRef.current = false;
208
+ // A finger that really moved the slides takes over from a pending
209
+ // scrollTo; a tap (no movement) doesn't.
210
+ const { contentOffset } = event.nativeEvent;
211
+ const moved = Math.abs((isHorizontal ? contentOffset.x : contentOffset.y) - dragStartRef.current);
212
+ if (moved > DRAG_SLOP) pendingPageRef.current = null;
213
+ },
214
+ [isHorizontal]
215
+ );
182
216
 
183
217
  const toggleAutoPlay = useCallback(() => setAutoPlayPaused((paused) => !paused), []);
184
218
 
@@ -192,9 +226,10 @@ export function useSlides({
192
226
  return;
193
227
  }
194
228
  if (!isLoop) return;
195
- // Última en modo infinito: avanza al clon de la primera en vez de
196
- // rebobinar; el salto al original lo cierra momentumScrollEnd.
229
+ // Last one in infinite mode: advances to the clone of the first instead
230
+ // of rewinding; momentumScrollEnd completes the jump to the original.
197
231
  offsetPageRef.current = total + 1;
232
+ pendingPageRef.current = total + 1;
198
233
  scrollToPage(total + 1, true);
199
234
  }, interval);
200
235
  return () => clearInterval(timer);
@@ -1,72 +1,11 @@
1
- import React, { useEffect, useState } from 'react';
2
- import type { ViewStyle } from 'react-native';
3
- import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
4
- import {
5
- UIProvider,
6
- useInsets,
7
- type ModalSafeAreaBoundaryProps,
8
- type UIProviderProps,
9
- } from '../theme/UIProvider';
10
- import type { EdgeInsets } from '../theme/insets';
1
+ import { UIProvider, type UIProviderProps } from '../theme/UIProvider';
11
2
 
12
- export interface SafeAreaUIProviderProps extends Omit<UIProviderProps, 'insets'> {
13
- insets?: UIProviderProps['insets'];
14
- mountSafeAreaProvider?: boolean;
15
- }
3
+ /**
4
+ * @deprecated Use `UIProvider` from 'orn-ui': it now measures the safe area
5
+ * insets itself (react-native-safe-area-context is a required peer). This
6
+ * alias stays for one minor version so existing imports keep working.
7
+ */
8
+ export type SafeAreaUIProviderProps = UIProviderProps;
16
9
 
17
- const probeStyle: ViewStyle = { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 };
18
-
19
- function sameInsets(a: EdgeInsets, b: EdgeInsets) {
20
- return a.top === b.top && a.right === b.right && a.bottom === b.bottom && a.left === b.left;
21
- }
22
-
23
- function InsetsProbe({ onMeasure }: { onMeasure: (insets: EdgeInsets) => void }) {
24
- const insets = useSafeAreaInsets();
25
- useEffect(() => {
26
- onMeasure(insets);
27
- }, [insets, onMeasure]);
28
- return null;
29
- }
30
-
31
- function RemeasuringModalSafeAreaBoundary({ children }: ModalSafeAreaBoundaryProps) {
32
- const ambient = useInsets();
33
- const [measured, setMeasured] = useState<EdgeInsets | null>(null);
34
- const onMeasure = React.useCallback(
35
- (next: EdgeInsets) => setMeasured((prev) => (prev && sameInsets(prev, next) ? prev : next)),
36
- []
37
- );
38
-
39
- return (
40
- <>
41
- <SafeAreaProvider style={probeStyle} pointerEvents="none">
42
- <InsetsProbe onMeasure={onMeasure} />
43
- </SafeAreaProvider>
44
- {children(measured ?? ambient)}
45
- </>
46
- );
47
- }
48
-
49
- function Measured({ insets: override, children, ...rest }: SafeAreaUIProviderProps) {
50
- const measured = useSafeAreaInsets();
51
- return (
52
- <UIProvider
53
- insets={override ?? measured}
54
- ModalSafeAreaBoundary={RemeasuringModalSafeAreaBoundary}
55
- {...rest}
56
- >
57
- {children}
58
- </UIProvider>
59
- );
60
- }
61
-
62
- export function SafeAreaUIProvider({
63
- mountSafeAreaProvider = true,
64
- ...props
65
- }: SafeAreaUIProviderProps) {
66
- if (!mountSafeAreaProvider) return <Measured {...props} />;
67
- return (
68
- <SafeAreaProvider>
69
- <Measured {...props} />
70
- </SafeAreaProvider>
71
- );
72
- }
10
+ /** @deprecated Use `UIProvider` from 'orn-ui' — same component. */
11
+ export const SafeAreaUIProvider = UIProvider;
@@ -1,2 +1,3 @@
1
+ // Deprecated subpath: UIProvider measures the insets itself now.
1
2
  export { SafeAreaUIProvider } from './SafeAreaUIProvider';
2
3
  export type { SafeAreaUIProviderProps } from './SafeAreaUIProvider';
@@ -0,0 +1,216 @@
1
+ import React, { createContext, useContext, useEffect, useMemo, useRef, type ComponentRef } from 'react';
2
+ import {
3
+ Animated,
4
+ Easing,
5
+ Keyboard,
6
+ Platform,
7
+ StyleSheet,
8
+ View,
9
+ type KeyboardEvent,
10
+ } from 'react-native';
11
+ import { useReduceMotion } from './useReduceMotion';
12
+
13
+ /** A focused field the host has to keep in view. */
14
+ export interface KeyboardField {
15
+ /** The field's box in window coordinates (label, field and error included). */
16
+ measure: () => Promise<{ y: number; height: number } | null>;
17
+ }
18
+
19
+ export interface KeyboardHost {
20
+ focus: (field: KeyboardField) => void;
21
+ blur: (field: KeyboardField) => void;
22
+ }
23
+
24
+ const KeyboardHostContext = createContext<KeyboardHost | null>(null);
25
+
26
+ /** The active host, or null if a container already handles the keyboard (or it is off). */
27
+ export function useKeyboardHost(): KeyboardHost | null {
28
+ return useContext(KeyboardHostContext);
29
+ }
30
+
31
+ /**
32
+ * For containers that already keep the focused field visible on their own:
33
+ * a Modal or BottomSheet (its own native window, which the root's shift
34
+ * doesn't move) or a ScrollView with `automaticallyAdjustKeyboardInsets`.
35
+ * Inside, Inputs ask nothing of the host and the keyboard isn't compensated
36
+ * twice.
37
+ */
38
+ export function KeyboardHandled({ children }: { children: React.ReactNode }) {
39
+ return <KeyboardHostContext.Provider value={null}>{children}</KeyboardHostContext.Provider>;
40
+ }
41
+
42
+ /** Duration when the keyboard event doesn't carry one (Android). */
43
+ const FALLBACK_DURATION = 250;
44
+
45
+ /**
46
+ * Vertical shift (≤ 0) so the whole field sits above the keyboard, with
47
+ * `margin` of room, without its top edge going past `topLimit`.
48
+ * `fieldY` is the position measured with the `current` shift applied.
49
+ * If the field is already visible, it moves back toward 0: it never rises more than needed.
50
+ */
51
+ export function computeKeyboardOffset({
52
+ fieldY,
53
+ fieldHeight,
54
+ keyboardTop,
55
+ current,
56
+ margin,
57
+ topLimit,
58
+ }: {
59
+ fieldY: number;
60
+ fieldHeight: number;
61
+ keyboardTop: number;
62
+ current: number;
63
+ margin: number;
64
+ topLimit: number;
65
+ }): number {
66
+ const base = fieldY - current;
67
+ let target = Math.min(0, keyboardTop - margin - (base + fieldHeight));
68
+ // A field taller than the available gap: seeing where you type (its top
69
+ // part) takes priority over its error.
70
+ target = Math.max(target, topLimit - base);
71
+ return Math.min(0, target);
72
+ }
73
+
74
+ /**
75
+ * An area that shifts so the focused Input inside it sits above the
76
+ * keyboard (transform on the native thread; it returns to 0 on close). It is
77
+ * Android's `adjustPan`, the same on both platforms.
78
+ *
79
+ * - The root UIProvider mounts one around the whole app: the fallback, so
80
+ * an Input is visible even when it isn't inside a Screen.
81
+ * - Screen mounts another around its content, with `clip`: only the content
82
+ * moves and the header (`header` prop) and the tab bar stay still, as in a
83
+ * native app. The Input registers with the nearest area, so inside a
84
+ * Screen the root doesn't move.
85
+ *
86
+ * With `clip`, whatever rises is clipped at the area's top edge and the field
87
+ * never goes above that edge (it stays under the header).
88
+ */
89
+ export function KeyboardPanArea({
90
+ margin,
91
+ topLimit,
92
+ clip = false,
93
+ children,
94
+ }: {
95
+ margin: number;
96
+ /** Top limit in window coordinates. With `clip`, the area's edge is used if it is lower. */
97
+ topLimit: number;
98
+ clip?: boolean;
99
+ children: React.ReactNode;
100
+ }) {
101
+ const areaRef = useRef<ComponentRef<typeof View>>(null);
102
+ const pan = useRef(new Animated.Value(0)).current;
103
+ const offset = useRef(0);
104
+ const field = useRef<KeyboardField | null>(null);
105
+ const keyboardTop = useRef<number | null>(null);
106
+ const reduceMotion = useReduceMotion();
107
+ const config = useRef({ margin, topLimit, reduceMotion, clip });
108
+ config.current = { margin, topLimit, reduceMotion, clip };
109
+
110
+ const host = useMemo<KeyboardHost>(() => {
111
+ const animateTo = (to: number, duration: number) => {
112
+ if (to === offset.current) return;
113
+ offset.current = to;
114
+ Animated.timing(pan, {
115
+ toValue: to,
116
+ duration: config.current.reduceMotion ? 0 : duration,
117
+ easing: Easing.out(Easing.cubic),
118
+ useNativeDriver: true,
119
+ }).start();
120
+ };
121
+
122
+ const adjust = async (duration: number) => {
123
+ const current = field.current;
124
+ const top = keyboardTop.current;
125
+ if (!current || top === null) return;
126
+ const box = await current.measure();
127
+ // While measuring, focus may have moved to another field or the keyboard closed.
128
+ if (!box || field.current !== current || keyboardTop.current === null) return;
129
+ let limit = config.current.topLimit;
130
+ if (config.current.clip) {
131
+ const areaTop = await measureTop(areaRef.current);
132
+ if (areaTop !== null) limit = Math.max(limit, areaTop);
133
+ }
134
+ animateTo(
135
+ computeKeyboardOffset({
136
+ fieldY: box.y,
137
+ fieldHeight: box.height,
138
+ keyboardTop: keyboardTop.current,
139
+ current: offset.current,
140
+ margin: config.current.margin,
141
+ topLimit: limit,
142
+ }),
143
+ duration
144
+ );
145
+ };
146
+
147
+ return {
148
+ focus(next) {
149
+ field.current = next;
150
+ // With the keyboard already open (moving from one field to another) it readjusts right away.
151
+ if (keyboardTop.current !== null) void adjust(FALLBACK_DURATION);
152
+ },
153
+ blur(prev) {
154
+ if (field.current === prev) field.current = null;
155
+ },
156
+ // Internal use by the listeners below.
157
+ _show(e: KeyboardEvent | undefined) {
158
+ if (!e?.endCoordinates) return;
159
+ keyboardTop.current = e.endCoordinates.screenY;
160
+ const duration = e.duration || FALLBACK_DURATION;
161
+ // Android emits didShow after resizing the window: measure on the
162
+ // next frame, with the layout already settled.
163
+ if (Platform.OS === 'android') requestAnimationFrame(() => void adjust(duration));
164
+ else void adjust(duration);
165
+ },
166
+ _hide(e: KeyboardEvent | undefined) {
167
+ keyboardTop.current = null;
168
+ animateTo(0, e?.duration || FALLBACK_DURATION);
169
+ },
170
+ } as KeyboardHost & { _show: (e: KeyboardEvent) => void; _hide: (e?: KeyboardEvent) => void };
171
+ }, [pan]);
172
+
173
+ useEffect(() => {
174
+ const h = host as KeyboardHost & { _show: (e: KeyboardEvent) => void; _hide: (e?: KeyboardEvent) => void };
175
+ // iOS notifies before animating (will*): the shift follows the keyboard.
176
+ // Android only has did*.
177
+ const subs =
178
+ Platform.OS === 'ios'
179
+ ? [
180
+ Keyboard.addListener('keyboardWillShow', h._show),
181
+ Keyboard.addListener('keyboardWillChangeFrame', h._show),
182
+ Keyboard.addListener('keyboardWillHide', h._hide),
183
+ ]
184
+ : [Keyboard.addListener('keyboardDidShow', h._show), Keyboard.addListener('keyboardDidHide', h._hide)];
185
+ return () => subs.forEach((s) => s.remove());
186
+ }, [host]);
187
+
188
+ const moving = <Animated.View style={[styles.fill, { transform: [{ translateY: pan }] }]}>{children}</Animated.View>;
189
+ return (
190
+ <KeyboardHostContext.Provider value={host}>
191
+ {clip ? (
192
+ <View ref={areaRef} style={[styles.fill, styles.clip]} collapsable={false}>
193
+ {moving}
194
+ </View>
195
+ ) : (
196
+ moving
197
+ )}
198
+ </KeyboardHostContext.Provider>
199
+ );
200
+ }
201
+
202
+ /** If the measurement never comes back (node unmounted), carry on without that limit. */
203
+ const MEASURE_TIMEOUT_MS = 100;
204
+
205
+ function measureTop(node: ComponentRef<typeof View> | null): Promise<number | null> {
206
+ return new Promise((resolve) => {
207
+ if (!node) return resolve(null);
208
+ const timer = setTimeout(() => resolve(null), MEASURE_TIMEOUT_MS);
209
+ node.measureInWindow((_x, y) => {
210
+ clearTimeout(timer);
211
+ resolve(y);
212
+ });
213
+ });
214
+ }
215
+
216
+ const styles = StyleSheet.create({ fill: { flex: 1 }, clip: { overflow: 'hidden' } });