orn-ui 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/AGENTS.md +67 -52
  2. package/README.md +5 -9
  3. package/lib/commonjs/atoms/Avatar.js +77 -5
  4. package/lib/commonjs/atoms/Avatar.js.map +1 -1
  5. package/lib/commonjs/atoms/Badge.js +17 -8
  6. package/lib/commonjs/atoms/Badge.js.map +1 -1
  7. package/lib/commonjs/atoms/Button.js +108 -39
  8. package/lib/commonjs/atoms/Button.js.map +1 -1
  9. package/lib/commonjs/atoms/Card.js +24 -2
  10. package/lib/commonjs/atoms/Card.js.map +1 -1
  11. package/lib/commonjs/atoms/Checkbox.js +41 -10
  12. package/lib/commonjs/atoms/Checkbox.js.map +1 -1
  13. package/lib/commonjs/atoms/Divider.js +30 -5
  14. package/lib/commonjs/atoms/Divider.js.map +1 -1
  15. package/lib/commonjs/atoms/EmptyState.js +58 -20
  16. package/lib/commonjs/atoms/EmptyState.js.map +1 -1
  17. package/lib/commonjs/atoms/Fab.js +32 -12
  18. package/lib/commonjs/atoms/Fab.js.map +1 -1
  19. package/lib/commonjs/atoms/Gradient.js +102 -36
  20. package/lib/commonjs/atoms/Gradient.js.map +1 -1
  21. package/lib/commonjs/atoms/IconButton.js +25 -4
  22. package/lib/commonjs/atoms/IconButton.js.map +1 -1
  23. package/lib/commonjs/atoms/Image.js +61 -25
  24. package/lib/commonjs/atoms/Image.js.map +1 -1
  25. package/lib/commonjs/atoms/Input.js +105 -17
  26. package/lib/commonjs/atoms/Input.js.map +1 -1
  27. package/lib/commonjs/atoms/KeyValueRow.js +37 -9
  28. package/lib/commonjs/atoms/KeyValueRow.js.map +1 -1
  29. package/lib/commonjs/atoms/PressableScale.js +25 -5
  30. package/lib/commonjs/atoms/PressableScale.js.map +1 -1
  31. package/lib/commonjs/atoms/ShinyText.js +29 -29
  32. package/lib/commonjs/atoms/Skeleton.js +28 -13
  33. package/lib/commonjs/atoms/Skeleton.js.map +1 -1
  34. package/lib/commonjs/atoms/Spinner.js +81 -22
  35. package/lib/commonjs/atoms/Spinner.js.map +1 -1
  36. package/lib/commonjs/atoms/Text.js +56 -5
  37. package/lib/commonjs/atoms/Text.js.map +1 -1
  38. package/lib/commonjs/atoms/Transition.js +46 -43
  39. package/lib/commonjs/atoms/Transition.js.map +1 -1
  40. package/lib/commonjs/atoms/index.js +6 -0
  41. package/lib/commonjs/atoms/index.js.map +1 -1
  42. package/lib/commonjs/atoms/inputValidation.js +56 -0
  43. package/lib/commonjs/atoms/inputValidation.js.map +1 -0
  44. package/lib/commonjs/icons/Icon.js +4 -4
  45. package/lib/commonjs/icons/defaultIcons.js +576 -24
  46. package/lib/commonjs/icons/defaultIcons.js.map +1 -1
  47. package/lib/commonjs/icons/index.js +6 -0
  48. package/lib/commonjs/icons/index.js.map +1 -1
  49. package/lib/commonjs/molecules/AvatarHeader.js +47 -14
  50. package/lib/commonjs/molecules/AvatarHeader.js.map +1 -1
  51. package/lib/commonjs/molecules/FormActions.js +25 -9
  52. package/lib/commonjs/molecules/FormActions.js.map +1 -1
  53. package/lib/commonjs/molecules/InfoRow.js +30 -14
  54. package/lib/commonjs/molecules/InfoRow.js.map +1 -1
  55. package/lib/commonjs/molecules/OptionCard.js +37 -22
  56. package/lib/commonjs/molecules/OptionCard.js.map +1 -1
  57. package/lib/commonjs/molecules/SegmentedControl.js +103 -14
  58. package/lib/commonjs/molecules/SegmentedControl.js.map +1 -1
  59. package/lib/commonjs/molecules/Stepper.js +61 -16
  60. package/lib/commonjs/molecules/Stepper.js.map +1 -1
  61. package/lib/commonjs/molecules/Steps.js +105 -41
  62. package/lib/commonjs/molecules/Steps.js.map +1 -1
  63. package/lib/commonjs/molecules/SymmetricGrid.js +26 -18
  64. package/lib/commonjs/molecules/SymmetricGrid.js.map +1 -1
  65. package/lib/commonjs/organisms/Alert.js +49 -35
  66. package/lib/commonjs/organisms/Alert.js.map +1 -1
  67. package/lib/commonjs/organisms/AlertProvider.js +10 -10
  68. package/lib/commonjs/organisms/BottomSheet.js +137 -85
  69. package/lib/commonjs/organisms/BottomSheet.js.map +1 -1
  70. package/lib/commonjs/organisms/Chart.js +197 -156
  71. package/lib/commonjs/organisms/Chart.js.map +1 -1
  72. package/lib/commonjs/organisms/DateField.js +36 -20
  73. package/lib/commonjs/organisms/DateField.js.map +1 -1
  74. package/lib/commonjs/organisms/DatePicker.js +56 -33
  75. package/lib/commonjs/organisms/DatePicker.js.map +1 -1
  76. package/lib/commonjs/organisms/List.js +62 -34
  77. package/lib/commonjs/organisms/List.js.map +1 -1
  78. package/lib/commonjs/organisms/Modal.js +120 -82
  79. package/lib/commonjs/organisms/Modal.js.map +1 -1
  80. package/lib/commonjs/organisms/NavigationBar.js +63 -24
  81. package/lib/commonjs/organisms/NavigationBar.js.map +1 -1
  82. package/lib/commonjs/organisms/OptionWheel.js +64 -64
  83. package/lib/commonjs/organisms/OptionWheel.js.map +1 -1
  84. package/lib/commonjs/organisms/ReorderableList.js +48 -27
  85. package/lib/commonjs/organisms/ReorderableList.js.map +1 -1
  86. package/lib/commonjs/organisms/Screen.js +68 -35
  87. package/lib/commonjs/organisms/Screen.js.map +1 -1
  88. package/lib/commonjs/organisms/SearchList.js +56 -26
  89. package/lib/commonjs/organisms/SearchList.js.map +1 -1
  90. package/lib/commonjs/organisms/Select.js +45 -24
  91. package/lib/commonjs/organisms/Select.js.map +1 -1
  92. package/lib/commonjs/organisms/Slides.js +36 -23
  93. package/lib/commonjs/organisms/Slides.js.map +1 -1
  94. package/lib/commonjs/organisms/ThemeToggle.js +10 -9
  95. package/lib/commonjs/organisms/ThemeToggle.js.map +1 -1
  96. package/lib/commonjs/organisms/Timeline.js +73 -56
  97. package/lib/commonjs/organisms/Timeline.js.map +1 -1
  98. package/lib/commonjs/organisms/Toast.js +46 -15
  99. package/lib/commonjs/organisms/Toast.js.map +1 -1
  100. package/lib/commonjs/organisms/ToastProvider.js +14 -10
  101. package/lib/commonjs/organisms/ToastProvider.js.map +1 -1
  102. package/lib/commonjs/organisms/Wizard.js +40 -15
  103. package/lib/commonjs/organisms/Wizard.js.map +1 -1
  104. package/lib/commonjs/organisms/chart/frame.js +25 -25
  105. package/lib/commonjs/organisms/chart/frame.js.map +1 -1
  106. package/lib/commonjs/organisms/chart/marks.js +42 -42
  107. package/lib/commonjs/organisms/chart/math.js +84 -85
  108. package/lib/commonjs/organisms/chart/math.js.map +1 -1
  109. package/lib/commonjs/organisms/chart/palette.js +28 -28
  110. package/lib/commonjs/organisms/imperativeBridge.js +5 -5
  111. package/lib/commonjs/organisms/imperativeBridge.js.map +1 -1
  112. package/lib/commonjs/organisms/useSlides.js +53 -21
  113. package/lib/commonjs/organisms/useSlides.js.map +1 -1
  114. package/lib/commonjs/safe-area/SafeAreaUIProvider.js +9 -66
  115. package/lib/commonjs/safe-area/SafeAreaUIProvider.js.map +1 -1
  116. package/lib/commonjs/safe-area/index.js.map +1 -1
  117. package/lib/commonjs/theme/KeyboardAvoidance.js +206 -0
  118. package/lib/commonjs/theme/KeyboardAvoidance.js.map +1 -0
  119. package/lib/commonjs/theme/NativeOverlay.js +263 -0
  120. package/lib/commonjs/theme/NativeOverlay.js.map +1 -0
  121. package/lib/commonjs/theme/UIProvider.js +86 -33
  122. package/lib/commonjs/theme/UIProvider.js.map +1 -1
  123. package/lib/commonjs/theme/colors.js +17 -17
  124. package/lib/commonjs/theme/colors.js.map +1 -1
  125. package/lib/commonjs/theme/createStyles.js +19 -16
  126. package/lib/commonjs/theme/createStyles.js.map +1 -1
  127. package/lib/commonjs/theme/createTheme.js +6 -6
  128. package/lib/commonjs/theme/index.js +6 -0
  129. package/lib/commonjs/theme/index.js.map +1 -1
  130. package/lib/commonjs/theme/insets.js +1 -1
  131. package/lib/commonjs/theme/labels.js +29 -1
  132. package/lib/commonjs/theme/labels.js.map +1 -1
  133. package/lib/commonjs/theme/palettes.js +25 -23
  134. package/lib/commonjs/theme/palettes.js.map +1 -1
  135. package/lib/commonjs/theme/tokens.js +28 -14
  136. package/lib/commonjs/theme/tokens.js.map +1 -1
  137. package/lib/commonjs/theme/useKeyboardField.js +36 -0
  138. package/lib/commonjs/theme/useKeyboardField.js.map +1 -0
  139. package/lib/commonjs/theme/useReduceMotion.js +31 -0
  140. package/lib/commonjs/theme/useReduceMotion.js.map +1 -0
  141. package/lib/module/atoms/Avatar.js +79 -8
  142. package/lib/module/atoms/Avatar.js.map +1 -1
  143. package/lib/module/atoms/Badge.js +17 -8
  144. package/lib/module/atoms/Badge.js.map +1 -1
  145. package/lib/module/atoms/Button.js +110 -41
  146. package/lib/module/atoms/Button.js.map +1 -1
  147. package/lib/module/atoms/Card.js +24 -2
  148. package/lib/module/atoms/Card.js.map +1 -1
  149. package/lib/module/atoms/Checkbox.js +42 -11
  150. package/lib/module/atoms/Checkbox.js.map +1 -1
  151. package/lib/module/atoms/Divider.js +31 -6
  152. package/lib/module/atoms/Divider.js.map +1 -1
  153. package/lib/module/atoms/EmptyState.js +58 -20
  154. package/lib/module/atoms/EmptyState.js.map +1 -1
  155. package/lib/module/atoms/Fab.js +33 -13
  156. package/lib/module/atoms/Fab.js.map +1 -1
  157. package/lib/module/atoms/Gradient.js +103 -37
  158. package/lib/module/atoms/Gradient.js.map +1 -1
  159. package/lib/module/atoms/IconButton.js +25 -4
  160. package/lib/module/atoms/IconButton.js.map +1 -1
  161. package/lib/module/atoms/Image.js +61 -25
  162. package/lib/module/atoms/Image.js.map +1 -1
  163. package/lib/module/atoms/Input.js +108 -20
  164. package/lib/module/atoms/Input.js.map +1 -1
  165. package/lib/module/atoms/KeyValueRow.js +37 -9
  166. package/lib/module/atoms/KeyValueRow.js.map +1 -1
  167. package/lib/module/atoms/PressableScale.js +25 -5
  168. package/lib/module/atoms/PressableScale.js.map +1 -1
  169. package/lib/module/atoms/ShinyText.js +29 -29
  170. package/lib/module/atoms/Skeleton.js +30 -13
  171. package/lib/module/atoms/Skeleton.js.map +1 -1
  172. package/lib/module/atoms/Spinner.js +82 -23
  173. package/lib/module/atoms/Spinner.js.map +1 -1
  174. package/lib/module/atoms/Text.js +56 -5
  175. package/lib/module/atoms/Text.js.map +1 -1
  176. package/lib/module/atoms/Transition.js +41 -42
  177. package/lib/module/atoms/Transition.js.map +1 -1
  178. package/lib/module/atoms/index.js +1 -1
  179. package/lib/module/atoms/index.js.map +1 -1
  180. package/lib/module/atoms/inputValidation.js +52 -0
  181. package/lib/module/atoms/inputValidation.js.map +1 -0
  182. package/lib/module/icons/Icon.js +4 -4
  183. package/lib/module/icons/defaultIcons.js +574 -24
  184. package/lib/module/icons/defaultIcons.js.map +1 -1
  185. package/lib/module/icons/index.js +1 -1
  186. package/lib/module/icons/index.js.map +1 -1
  187. package/lib/module/molecules/AvatarHeader.js +47 -14
  188. package/lib/module/molecules/AvatarHeader.js.map +1 -1
  189. package/lib/module/molecules/FormActions.js +25 -9
  190. package/lib/module/molecules/FormActions.js.map +1 -1
  191. package/lib/module/molecules/InfoRow.js +30 -14
  192. package/lib/module/molecules/InfoRow.js.map +1 -1
  193. package/lib/module/molecules/OptionCard.js +37 -22
  194. package/lib/module/molecules/OptionCard.js.map +1 -1
  195. package/lib/module/molecules/SegmentedControl.js +107 -18
  196. package/lib/module/molecules/SegmentedControl.js.map +1 -1
  197. package/lib/module/molecules/Stepper.js +63 -18
  198. package/lib/module/molecules/Stepper.js.map +1 -1
  199. package/lib/module/molecules/Steps.js +107 -43
  200. package/lib/module/molecules/Steps.js.map +1 -1
  201. package/lib/module/molecules/SymmetricGrid.js +26 -18
  202. package/lib/module/molecules/SymmetricGrid.js.map +1 -1
  203. package/lib/module/organisms/Alert.js +51 -37
  204. package/lib/module/organisms/Alert.js.map +1 -1
  205. package/lib/module/organisms/AlertProvider.js +10 -10
  206. package/lib/module/organisms/BottomSheet.js +142 -88
  207. package/lib/module/organisms/BottomSheet.js.map +1 -1
  208. package/lib/module/organisms/Chart.js +199 -158
  209. package/lib/module/organisms/Chart.js.map +1 -1
  210. package/lib/module/organisms/DateField.js +36 -20
  211. package/lib/module/organisms/DateField.js.map +1 -1
  212. package/lib/module/organisms/DatePicker.js +56 -33
  213. package/lib/module/organisms/DatePicker.js.map +1 -1
  214. package/lib/module/organisms/List.js +62 -34
  215. package/lib/module/organisms/List.js.map +1 -1
  216. package/lib/module/organisms/Modal.js +122 -84
  217. package/lib/module/organisms/Modal.js.map +1 -1
  218. package/lib/module/organisms/NavigationBar.js +64 -25
  219. package/lib/module/organisms/NavigationBar.js.map +1 -1
  220. package/lib/module/organisms/OptionWheel.js +64 -64
  221. package/lib/module/organisms/OptionWheel.js.map +1 -1
  222. package/lib/module/organisms/ReorderableList.js +48 -27
  223. package/lib/module/organisms/ReorderableList.js.map +1 -1
  224. package/lib/module/organisms/Screen.js +70 -37
  225. package/lib/module/organisms/Screen.js.map +1 -1
  226. package/lib/module/organisms/SearchList.js +56 -26
  227. package/lib/module/organisms/SearchList.js.map +1 -1
  228. package/lib/module/organisms/Select.js +46 -25
  229. package/lib/module/organisms/Select.js.map +1 -1
  230. package/lib/module/organisms/Slides.js +37 -24
  231. package/lib/module/organisms/Slides.js.map +1 -1
  232. package/lib/module/organisms/ThemeToggle.js +11 -10
  233. package/lib/module/organisms/ThemeToggle.js.map +1 -1
  234. package/lib/module/organisms/Timeline.js +73 -56
  235. package/lib/module/organisms/Timeline.js.map +1 -1
  236. package/lib/module/organisms/Toast.js +47 -16
  237. package/lib/module/organisms/Toast.js.map +1 -1
  238. package/lib/module/organisms/ToastProvider.js +15 -11
  239. package/lib/module/organisms/ToastProvider.js.map +1 -1
  240. package/lib/module/organisms/Wizard.js +41 -16
  241. package/lib/module/organisms/Wizard.js.map +1 -1
  242. package/lib/module/organisms/chart/frame.js +25 -25
  243. package/lib/module/organisms/chart/frame.js.map +1 -1
  244. package/lib/module/organisms/chart/marks.js +42 -42
  245. package/lib/module/organisms/chart/math.js +84 -85
  246. package/lib/module/organisms/chart/math.js.map +1 -1
  247. package/lib/module/organisms/chart/palette.js +28 -28
  248. package/lib/module/organisms/imperativeBridge.js +5 -5
  249. package/lib/module/organisms/imperativeBridge.js.map +1 -1
  250. package/lib/module/organisms/useSlides.js +53 -21
  251. package/lib/module/organisms/useSlides.js.map +1 -1
  252. package/lib/module/safe-area/SafeAreaUIProvider.js +10 -65
  253. package/lib/module/safe-area/SafeAreaUIProvider.js.map +1 -1
  254. package/lib/module/safe-area/index.js +1 -0
  255. package/lib/module/safe-area/index.js.map +1 -1
  256. package/lib/module/theme/KeyboardAvoidance.js +198 -0
  257. package/lib/module/theme/KeyboardAvoidance.js.map +1 -0
  258. package/lib/module/theme/NativeOverlay.js +257 -0
  259. package/lib/module/theme/NativeOverlay.js.map +1 -0
  260. package/lib/module/theme/UIProvider.js +88 -35
  261. package/lib/module/theme/UIProvider.js.map +1 -1
  262. package/lib/module/theme/colors.js +17 -17
  263. package/lib/module/theme/colors.js.map +1 -1
  264. package/lib/module/theme/createStyles.js +20 -16
  265. package/lib/module/theme/createStyles.js.map +1 -1
  266. package/lib/module/theme/createTheme.js +6 -6
  267. package/lib/module/theme/index.js +1 -1
  268. package/lib/module/theme/index.js.map +1 -1
  269. package/lib/module/theme/insets.js +1 -1
  270. package/lib/module/theme/labels.js +29 -1
  271. package/lib/module/theme/labels.js.map +1 -1
  272. package/lib/module/theme/palettes.js +25 -23
  273. package/lib/module/theme/palettes.js.map +1 -1
  274. package/lib/module/theme/tokens.js +27 -13
  275. package/lib/module/theme/tokens.js.map +1 -1
  276. package/lib/module/theme/useKeyboardField.js +33 -0
  277. package/lib/module/theme/useKeyboardField.js.map +1 -0
  278. package/lib/module/theme/useReduceMotion.js +28 -0
  279. package/lib/module/theme/useReduceMotion.js.map +1 -0
  280. package/lib/typescript/atoms/Avatar.d.ts +35 -5
  281. package/lib/typescript/atoms/Avatar.d.ts.map +1 -1
  282. package/lib/typescript/atoms/Badge.d.ts +14 -3
  283. package/lib/typescript/atoms/Badge.d.ts.map +1 -1
  284. package/lib/typescript/atoms/Button.d.ts +34 -3
  285. package/lib/typescript/atoms/Button.d.ts.map +1 -1
  286. package/lib/typescript/atoms/Card.d.ts +13 -2
  287. package/lib/typescript/atoms/Card.d.ts.map +1 -1
  288. package/lib/typescript/atoms/Checkbox.d.ts +26 -1
  289. package/lib/typescript/atoms/Checkbox.d.ts.map +1 -1
  290. package/lib/typescript/atoms/Divider.d.ts +18 -1
  291. package/lib/typescript/atoms/Divider.d.ts.map +1 -1
  292. package/lib/typescript/atoms/EmptyState.d.ts +30 -3
  293. package/lib/typescript/atoms/EmptyState.d.ts.map +1 -1
  294. package/lib/typescript/atoms/Fab.d.ts +24 -4
  295. package/lib/typescript/atoms/Fab.d.ts.map +1 -1
  296. package/lib/typescript/atoms/Gradient.d.ts +21 -15
  297. package/lib/typescript/atoms/Gradient.d.ts.map +1 -1
  298. package/lib/typescript/atoms/IconButton.d.ts +18 -4
  299. package/lib/typescript/atoms/IconButton.d.ts.map +1 -1
  300. package/lib/typescript/atoms/Image.d.ts +39 -17
  301. package/lib/typescript/atoms/Image.d.ts.map +1 -1
  302. package/lib/typescript/atoms/Input.d.ts +57 -7
  303. package/lib/typescript/atoms/Input.d.ts.map +1 -1
  304. package/lib/typescript/atoms/KeyValueRow.d.ts +16 -4
  305. package/lib/typescript/atoms/KeyValueRow.d.ts.map +1 -1
  306. package/lib/typescript/atoms/PressableScale.d.ts +12 -5
  307. package/lib/typescript/atoms/PressableScale.d.ts.map +1 -1
  308. package/lib/typescript/atoms/ShinyText.d.ts +17 -17
  309. package/lib/typescript/atoms/ShinyText.d.ts.map +1 -1
  310. package/lib/typescript/atoms/Skeleton.d.ts +12 -7
  311. package/lib/typescript/atoms/Skeleton.d.ts.map +1 -1
  312. package/lib/typescript/atoms/Spinner.d.ts +29 -1
  313. package/lib/typescript/atoms/Spinner.d.ts.map +1 -1
  314. package/lib/typescript/atoms/Text.d.ts +46 -0
  315. package/lib/typescript/atoms/Text.d.ts.map +1 -1
  316. package/lib/typescript/atoms/Transition.d.ts +19 -15
  317. package/lib/typescript/atoms/Transition.d.ts.map +1 -1
  318. package/lib/typescript/atoms/index.d.ts +3 -3
  319. package/lib/typescript/atoms/index.d.ts.map +1 -1
  320. package/lib/typescript/atoms/inputValidation.d.ts +29 -0
  321. package/lib/typescript/atoms/inputValidation.d.ts.map +1 -0
  322. package/lib/typescript/icons/Icon.d.ts +4 -4
  323. package/lib/typescript/icons/defaultIcons.d.ts +19 -2
  324. package/lib/typescript/icons/defaultIcons.d.ts.map +1 -1
  325. package/lib/typescript/icons/index.d.ts +2 -2
  326. package/lib/typescript/icons/index.d.ts.map +1 -1
  327. package/lib/typescript/icons/types.d.ts +13 -3
  328. package/lib/typescript/icons/types.d.ts.map +1 -1
  329. package/lib/typescript/molecules/AvatarHeader.d.ts +23 -4
  330. package/lib/typescript/molecules/AvatarHeader.d.ts.map +1 -1
  331. package/lib/typescript/molecules/FormActions.d.ts +21 -4
  332. package/lib/typescript/molecules/FormActions.d.ts.map +1 -1
  333. package/lib/typescript/molecules/InfoRow.d.ts +17 -3
  334. package/lib/typescript/molecules/InfoRow.d.ts.map +1 -1
  335. package/lib/typescript/molecules/OptionCard.d.ts +20 -5
  336. package/lib/typescript/molecules/OptionCard.d.ts.map +1 -1
  337. package/lib/typescript/molecules/SegmentedControl.d.ts +18 -2
  338. package/lib/typescript/molecules/SegmentedControl.d.ts.map +1 -1
  339. package/lib/typescript/molecules/Stepper.d.ts +23 -7
  340. package/lib/typescript/molecules/Stepper.d.ts.map +1 -1
  341. package/lib/typescript/molecules/Steps.d.ts +18 -4
  342. package/lib/typescript/molecules/Steps.d.ts.map +1 -1
  343. package/lib/typescript/molecules/SymmetricGrid.d.ts +15 -5
  344. package/lib/typescript/molecules/SymmetricGrid.d.ts.map +1 -1
  345. package/lib/typescript/organisms/Alert.d.ts +28 -2
  346. package/lib/typescript/organisms/Alert.d.ts.map +1 -1
  347. package/lib/typescript/organisms/AlertProvider.d.ts +10 -10
  348. package/lib/typescript/organisms/AlertProvider.d.ts.map +1 -1
  349. package/lib/typescript/organisms/BottomSheet.d.ts +20 -5
  350. package/lib/typescript/organisms/BottomSheet.d.ts.map +1 -1
  351. package/lib/typescript/organisms/Chart.d.ts +86 -75
  352. package/lib/typescript/organisms/Chart.d.ts.map +1 -1
  353. package/lib/typescript/organisms/DateField.d.ts +17 -3
  354. package/lib/typescript/organisms/DateField.d.ts.map +1 -1
  355. package/lib/typescript/organisms/DatePicker.d.ts +7 -11
  356. package/lib/typescript/organisms/DatePicker.d.ts.map +1 -1
  357. package/lib/typescript/organisms/List.d.ts +30 -3
  358. package/lib/typescript/organisms/List.d.ts.map +1 -1
  359. package/lib/typescript/organisms/Modal.d.ts +30 -3
  360. package/lib/typescript/organisms/Modal.d.ts.map +1 -1
  361. package/lib/typescript/organisms/NavigationBar.d.ts +26 -7
  362. package/lib/typescript/organisms/NavigationBar.d.ts.map +1 -1
  363. package/lib/typescript/organisms/OptionWheel.d.ts +20 -16
  364. package/lib/typescript/organisms/OptionWheel.d.ts.map +1 -1
  365. package/lib/typescript/organisms/ReorderableList.d.ts +20 -11
  366. package/lib/typescript/organisms/ReorderableList.d.ts.map +1 -1
  367. package/lib/typescript/organisms/Screen.d.ts +27 -8
  368. package/lib/typescript/organisms/Screen.d.ts.map +1 -1
  369. package/lib/typescript/organisms/SearchList.d.ts +46 -3
  370. package/lib/typescript/organisms/SearchList.d.ts.map +1 -1
  371. package/lib/typescript/organisms/Select.d.ts +26 -6
  372. package/lib/typescript/organisms/Select.d.ts.map +1 -1
  373. package/lib/typescript/organisms/Slides.d.ts +44 -26
  374. package/lib/typescript/organisms/Slides.d.ts.map +1 -1
  375. package/lib/typescript/organisms/ThemeToggle.d.ts +6 -2
  376. package/lib/typescript/organisms/ThemeToggle.d.ts.map +1 -1
  377. package/lib/typescript/organisms/Timeline.d.ts +26 -9
  378. package/lib/typescript/organisms/Timeline.d.ts.map +1 -1
  379. package/lib/typescript/organisms/Toast.d.ts +19 -4
  380. package/lib/typescript/organisms/Toast.d.ts.map +1 -1
  381. package/lib/typescript/organisms/ToastProvider.d.ts +8 -8
  382. package/lib/typescript/organisms/ToastProvider.d.ts.map +1 -1
  383. package/lib/typescript/organisms/Wizard.d.ts +24 -6
  384. package/lib/typescript/organisms/Wizard.d.ts.map +1 -1
  385. package/lib/typescript/organisms/chart/frame.d.ts +21 -21
  386. package/lib/typescript/organisms/chart/frame.d.ts.map +1 -1
  387. package/lib/typescript/organisms/chart/marks.d.ts +28 -28
  388. package/lib/typescript/organisms/chart/marks.d.ts.map +1 -1
  389. package/lib/typescript/organisms/chart/math.d.ts +69 -70
  390. package/lib/typescript/organisms/chart/math.d.ts.map +1 -1
  391. package/lib/typescript/organisms/chart/palette.d.ts +2 -2
  392. package/lib/typescript/organisms/chart/palette.d.ts.map +1 -1
  393. package/lib/typescript/organisms/imperativeBridge.d.ts +4 -4
  394. package/lib/typescript/organisms/useSlides.d.ts +8 -16
  395. package/lib/typescript/organisms/useSlides.d.ts.map +1 -1
  396. package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts +9 -7
  397. package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts.map +1 -1
  398. package/lib/typescript/safe-area/index.d.ts.map +1 -1
  399. package/lib/typescript/theme/KeyboardAvoidance.d.ts +62 -0
  400. package/lib/typescript/theme/KeyboardAvoidance.d.ts.map +1 -0
  401. package/lib/typescript/theme/NativeOverlay.d.ts +43 -0
  402. package/lib/typescript/theme/NativeOverlay.d.ts.map +1 -0
  403. package/lib/typescript/theme/UIProvider.d.ts +38 -20
  404. package/lib/typescript/theme/UIProvider.d.ts.map +1 -1
  405. package/lib/typescript/theme/colors.d.ts +13 -13
  406. package/lib/typescript/theme/colors.d.ts.map +1 -1
  407. package/lib/typescript/theme/createStyles.d.ts +20 -14
  408. package/lib/typescript/theme/createStyles.d.ts.map +1 -1
  409. package/lib/typescript/theme/createTheme.d.ts +5 -5
  410. package/lib/typescript/theme/index.d.ts +1 -1
  411. package/lib/typescript/theme/index.d.ts.map +1 -1
  412. package/lib/typescript/theme/insets.d.ts +1 -1
  413. package/lib/typescript/theme/insets.d.ts.map +1 -1
  414. package/lib/typescript/theme/labels.d.ts +57 -2
  415. package/lib/typescript/theme/labels.d.ts.map +1 -1
  416. package/lib/typescript/theme/palettes.d.ts +25 -19
  417. package/lib/typescript/theme/palettes.d.ts.map +1 -1
  418. package/lib/typescript/theme/tokens.d.ts +15 -8
  419. package/lib/typescript/theme/tokens.d.ts.map +1 -1
  420. package/lib/typescript/theme/types.d.ts +7 -7
  421. package/lib/typescript/theme/types.d.ts.map +1 -1
  422. package/lib/typescript/theme/useKeyboardField.d.ts +17 -0
  423. package/lib/typescript/theme/useKeyboardField.d.ts.map +1 -0
  424. package/lib/typescript/theme/useReduceMotion.d.ts +7 -0
  425. package/lib/typescript/theme/useReduceMotion.d.ts.map +1 -0
  426. package/llms.txt +4 -4
  427. package/package.json +15 -14
  428. package/registry/alert-provider.json +4 -3
  429. package/registry/alert.json +3 -2
  430. package/registry/avatar-header.json +1 -1
  431. package/registry/avatar.json +3 -2
  432. package/registry/badge.json +1 -1
  433. package/registry/bottom-sheet.json +1 -1
  434. package/registry/button.json +3 -2
  435. package/registry/card.json +1 -1
  436. package/registry/chart.json +5 -5
  437. package/registry/checkbox.json +3 -2
  438. package/registry/core.json +31 -15
  439. package/registry/date-field.json +1 -1
  440. package/registry/date-picker.json +3 -2
  441. package/registry/divider.json +1 -1
  442. package/registry/empty-state.json +4 -2
  443. package/registry/fab.json +3 -2
  444. package/registry/form-actions.json +3 -2
  445. package/registry/gradient.json +1 -1
  446. package/registry/icon-button.json +3 -2
  447. package/registry/image.json +1 -1
  448. package/registry/index.json +79 -61
  449. package/registry/info-row.json +1 -1
  450. package/registry/input.json +5 -1
  451. package/registry/key-value-row.json +1 -1
  452. package/registry/list.json +3 -1
  453. package/registry/manifest.json +3 -1
  454. package/registry/modal.json +1 -1
  455. package/registry/navigation-bar.json +1 -1
  456. package/registry/option-card.json +3 -2
  457. package/registry/option-wheel.json +1 -1
  458. package/registry/pressable-scale.json +3 -2
  459. package/registry/reorderable-list.json +1 -1
  460. package/registry/screen.json +1 -1
  461. package/registry/search-list.json +7 -1
  462. package/registry/segmented-control.json +1 -1
  463. package/registry/select.json +1 -1
  464. package/registry/shiny-text.json +1 -1
  465. package/registry/skeleton.json +3 -2
  466. package/registry/slides.json +2 -2
  467. package/registry/spinner.json +1 -1
  468. package/registry/stepper.json +1 -1
  469. package/registry/steps.json +1 -1
  470. package/registry/symmetric-grid.json +1 -1
  471. package/registry/theme-toggle.json +1 -1
  472. package/registry/timeline.json +1 -1
  473. package/registry/title.json +1 -1
  474. package/registry/toast-provider.json +2 -2
  475. package/registry/toast.json +1 -1
  476. package/registry/transition.json +1 -1
  477. package/registry/wizard.json +1 -1
  478. package/src/atoms/Avatar.tsx +117 -26
  479. package/src/atoms/Badge.tsx +20 -9
  480. package/src/atoms/Button.tsx +102 -30
  481. package/src/atoms/Card.tsx +23 -3
  482. package/src/atoms/Checkbox.tsx +49 -12
  483. package/src/atoms/Divider.tsx +34 -4
  484. package/src/atoms/EmptyState.tsx +63 -16
  485. package/src/atoms/Fab.tsx +56 -9
  486. package/src/atoms/Gradient.tsx +92 -41
  487. package/src/atoms/IconButton.tsx +27 -4
  488. package/src/atoms/Image.tsx +74 -28
  489. package/src/atoms/Input.tsx +129 -19
  490. package/src/atoms/KeyValueRow.tsx +72 -28
  491. package/src/atoms/PressableScale.tsx +31 -7
  492. package/src/atoms/ShinyText.tsx +31 -31
  493. package/src/atoms/Skeleton.tsx +37 -17
  494. package/src/atoms/Spinner.tsx +87 -24
  495. package/src/atoms/Text.tsx +66 -6
  496. package/src/atoms/Transition.tsx +40 -44
  497. package/src/atoms/index.ts +3 -3
  498. package/src/atoms/inputValidation.ts +59 -0
  499. package/src/icons/Icon.tsx +4 -4
  500. package/src/icons/defaultIcons.tsx +445 -22
  501. package/src/icons/index.ts +2 -2
  502. package/src/icons/types.ts +26 -4
  503. package/src/molecules/AvatarHeader.tsx +88 -34
  504. package/src/molecules/FormActions.tsx +36 -6
  505. package/src/molecules/InfoRow.tsx +39 -12
  506. package/src/molecules/OptionCard.tsx +55 -20
  507. package/src/molecules/SegmentedControl.tsx +135 -15
  508. package/src/molecules/Stepper.tsx +73 -19
  509. package/src/molecules/Steps.tsx +121 -39
  510. package/src/molecules/SymmetricGrid.tsx +28 -12
  511. package/src/organisms/Alert.tsx +97 -26
  512. package/src/organisms/AlertProvider.tsx +13 -13
  513. package/src/organisms/BottomSheet.tsx +115 -43
  514. package/src/organisms/Chart.tsx +223 -165
  515. package/src/organisms/DateField.tsx +40 -15
  516. package/src/organisms/DatePicker.tsx +53 -32
  517. package/src/organisms/List.tsx +64 -15
  518. package/src/organisms/Modal.tsx +122 -63
  519. package/src/organisms/NavigationBar.tsx +73 -23
  520. package/src/organisms/OptionWheel.tsx +70 -66
  521. package/src/organisms/ReorderableList.tsx +49 -27
  522. package/src/organisms/Screen.tsx +79 -42
  523. package/src/organisms/SearchList.tsx +84 -20
  524. package/src/organisms/Select.tsx +63 -29
  525. package/src/organisms/Slides.tsx +63 -44
  526. package/src/organisms/ThemeToggle.tsx +15 -6
  527. package/src/organisms/Timeline.tsx +79 -62
  528. package/src/organisms/Toast.tsx +50 -15
  529. package/src/organisms/ToastProvider.tsx +17 -13
  530. package/src/organisms/Wizard.tsx +58 -21
  531. package/src/organisms/chart/frame.tsx +35 -35
  532. package/src/organisms/chart/marks.tsx +53 -53
  533. package/src/organisms/chart/math.ts +93 -94
  534. package/src/organisms/chart/palette.ts +28 -28
  535. package/src/organisms/imperativeBridge.ts +5 -5
  536. package/src/organisms/useSlides.ts +66 -31
  537. package/src/safe-area/SafeAreaUIProvider.tsx +9 -70
  538. package/src/safe-area/index.ts +1 -0
  539. package/src/theme/KeyboardAvoidance.tsx +216 -0
  540. package/src/theme/NativeOverlay.tsx +269 -0
  541. package/src/theme/UIProvider.tsx +109 -46
  542. package/src/theme/colors.ts +21 -21
  543. package/src/theme/createStyles.ts +23 -19
  544. package/src/theme/createTheme.ts +6 -6
  545. package/src/theme/index.ts +1 -1
  546. package/src/theme/insets.ts +1 -1
  547. package/src/theme/labels.ts +85 -2
  548. package/src/theme/palettes.ts +33 -25
  549. package/src/theme/tokens.ts +27 -13
  550. package/src/theme/types.ts +7 -7
  551. package/src/theme/useKeyboardField.ts +33 -0
  552. package/src/theme/useReduceMotion.ts +27 -0
@@ -1,7 +1,8 @@
1
1
  import React, { memo } from 'react';
2
- import { Modal, Text, TouchableWithoutFeedback, View } from 'react-native';
2
+ import { Text, TouchableWithoutFeedback, View } from 'react-native';
3
+ import { NativeOverlay } from '../theme/NativeOverlay';
3
4
  import { createStyles } from '../theme/createStyles';
4
- import { useAllowFontScaling, useColors, useLabels } from '../theme/UIProvider';
5
+ import { useAllowFontScaling, useColors, useLabels, useTheme } from '../theme/UIProvider';
5
6
  import { Button, type ButtonVariant } from '../atoms/Button';
6
7
  import { Icon } from '../icons/Icon';
7
8
  import type { IconName } from '../icons/types';
@@ -9,23 +10,40 @@ import type { IconName } from '../icons/types';
9
10
  export type AlertType = 'success' | 'error' | 'warning' | 'info' | 'question';
10
11
 
11
12
  export interface AlertButton {
13
+ /** Button label. */
12
14
  text: string;
15
+ /** Called on press; without it the button calls `onClose`. */
13
16
  onPress?: () => void;
17
+ /** 'cancel' renders outline, 'destructive' renders in the error color. */
14
18
  style?: 'cancel' | 'default' | 'destructive';
19
+ /** Explicit Button variant; wins over `style`. */
15
20
  variant?: ButtonVariant;
16
21
  }
17
22
 
18
23
  export interface AlertProps {
24
+ /** Shows or hides the dialog. */
19
25
  visible: boolean;
26
+ /** Short heading; screen readers announce it as a header. */
20
27
  title: string;
28
+ /** Optional explanation under the title. */
21
29
  message?: string;
30
+ /** Icon and color of the dialog. @default 'info' */
22
31
  type?: AlertType;
32
+ /** Tap on the backdrop, Android back, VoiceOver escape. Without it the backdrop does nothing. */
23
33
  onClose?: () => void;
34
+ /** Custom buttons; three or more stack vertically. */
24
35
  buttons?: AlertButton[];
36
+ /** Shorthand: label of the confirm button. @default labels.confirm */
25
37
  confirmText?: string;
38
+ /** Shorthand: label of the cancel button (shown with `onCancel` or `cancelText`). @default labels.cancel */
26
39
  cancelText?: string;
40
+ /** Shorthand: confirm action. */
27
41
  onConfirm?: () => void;
42
+ /** Shorthand: cancel action (falls back to `onClose`). */
28
43
  onCancel?: () => void;
44
+ /** The confirm button uses the destructive color (delete, discard). @default false */
45
+ destructive?: boolean;
46
+ /** Draws the dialog inside its parent instead of over the screen (docs, previews). @default false */
29
47
  inline?: boolean;
30
48
  }
31
49
 
@@ -37,31 +55,62 @@ const ICON_BY_TYPE: Record<AlertType, IconName> = {
37
55
  info: 'info',
38
56
  };
39
57
 
58
+ /** Readable line length for a short dialog on tablets too. */
59
+ const DIALOG_MAX_WIDTH = 340;
60
+ const ICON_SIZE = 48;
61
+ /** Above any sibling of the inline host. */
62
+ const INLINE_Z = 9999;
63
+
40
64
  const useStyles = createStyles((theme) => ({
41
- overlay: { flex: 1, backgroundColor: theme.colors.overlay, justifyContent: 'center', alignItems: 'center', padding: theme.tokens.spacing.xl },
42
- overlayInline: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 9999 },
65
+ overlay: {
66
+ flex: 1,
67
+ backgroundColor: theme.colors.overlay,
68
+ justifyContent: 'center',
69
+ alignItems: 'center',
70
+ padding: theme.tokens.spacing.xl,
71
+ },
72
+ fill: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 },
73
+ overlayInline: { zIndex: INLINE_Z },
43
74
  container: {
44
- backgroundColor: theme.colors.surface,
75
+ // Raised: in dark mode the plain surface sank into the dimmed backdrop.
76
+ backgroundColor: theme.colors.surfaceRaised,
45
77
  borderRadius: theme.tokens.radius.xl,
46
78
  padding: theme.tokens.spacing.xl,
47
79
  width: '100%',
48
- maxWidth: 340,
80
+ maxWidth: DIALOG_MAX_WIDTH,
49
81
  alignItems: 'center',
50
82
  ...theme.tokens.shadow.md,
51
83
  },
52
- iconContainer: { marginBottom: theme.tokens.spacing.lg - 1 },
53
- title: { fontSize: theme.tokens.fontSize.xl, fontWeight: theme.tokens.fontWeight.bold, color: theme.colors.text, textAlign: 'center', marginBottom: theme.tokens.spacing.md - 2 },
54
- message: { fontSize: theme.tokens.fontSize.md, color: theme.colors.textLight, textAlign: 'center', marginBottom: theme.tokens.spacing.xl, lineHeight: theme.tokens.lineHeight.md },
55
- buttonContainer: { flexDirection: 'row', justifyContent: 'center', gap: theme.tokens.spacing.sm + 2, width: '100%' },
84
+ iconContainer: { marginBottom: theme.tokens.spacing.lg },
85
+ title: {
86
+ fontSize: theme.tokens.fontSize.xl,
87
+ lineHeight: theme.tokens.lineHeight.lg,
88
+ fontWeight: theme.tokens.fontWeight.bold,
89
+ color: theme.colors.text,
90
+ textAlign: 'center',
91
+ marginBottom: theme.tokens.spacing.sm,
92
+ },
93
+ message: {
94
+ fontSize: theme.tokens.fontSize.md,
95
+ lineHeight: theme.tokens.lineHeight.md,
96
+ color: theme.colors.textLight,
97
+ textAlign: 'center',
98
+ },
99
+ buttonContainer: {
100
+ flexDirection: 'row',
101
+ justifyContent: 'center',
102
+ gap: theme.tokens.spacing.sm,
103
+ width: '100%',
104
+ marginTop: theme.tokens.spacing.xl,
105
+ },
56
106
  buttonContainerVertical: { flexDirection: 'column' },
57
- button: { paddingVertical: theme.tokens.spacing.md - 2, paddingHorizontal: theme.tokens.spacing.xl },
58
107
  buttonHorizontal: { flex: 1 },
59
108
  buttonVertical: { width: '100%' },
60
109
  }));
61
110
 
62
- /** Deriva la lista de botones a partir de props, sin mutar `buttons` recibido por props. */
111
+ /** Derives the list of buttons from props, without mutating the `buttons` received through props. */
63
112
  function resolveButtons(props: AlertProps, labels: { confirm: string; cancel: string; close: string }): AlertButton[] {
64
- const { buttons, confirmText, cancelText, onConfirm, onCancel, onClose } = props;
113
+ const { buttons, confirmText, cancelText, onConfirm, onCancel, onClose, destructive } = props;
65
114
  if (buttons && buttons.length > 0) return buttons;
66
115
 
67
116
  if (confirmText || onConfirm) {
@@ -69,7 +118,7 @@ function resolveButtons(props: AlertProps, labels: { confirm: string; cancel: st
69
118
  if (cancelText || onCancel) {
70
119
  list.push({ text: cancelText || labels.cancel, onPress: onCancel || onClose, variant: 'outline', style: 'cancel' });
71
120
  }
72
- list.push({ text: confirmText || labels.confirm, onPress: onConfirm, variant: 'primary' });
121
+ list.push({ text: confirmText || labels.confirm, onPress: onConfirm, variant: destructive ? 'destructive' : 'primary' });
73
122
  return list;
74
123
  }
75
124
 
@@ -78,11 +127,21 @@ function resolveButtons(props: AlertProps, labels: { confirm: string; cancel: st
78
127
 
79
128
  /**
80
129
  * Alert
81
- * Componente declarativo de diálogo. Para uso imperativo (mostrar desde
82
- * un handler sin levantar estado propio), usar AlertProvider + useAlert().
130
+ * Declarative dialog component. For imperative use (showing it from a
131
+ * handler without lifting your own state), use AlertProvider + useAlert().
132
+ *
133
+ * Gestalt, figure-ground: the overlay dims everything behind, so the dialog
134
+ * is the only figure. Proximity: icon, title and message sit together and the
135
+ * buttons a larger step below, as the answer block. Von Restorff: only the
136
+ * main action is filled (or red when `destructive`); cancel is outline.
137
+ * Hick: two buttons side by side; three or more stack so each reads alone.
138
+ *
139
+ * Accessibility: the title is a header, the dialog is modal for VoiceOver and
140
+ * the escape gesture (two-finger Z) calls `onClose`.
83
141
  */
84
142
  export const Alert = memo((props: AlertProps) => {
85
143
  const { visible, title, message, type = 'info', onClose, inline = false } = props;
144
+ const theme = useTheme();
86
145
  const colors = useColors();
87
146
  const styles = useStyles();
88
147
  const labels = useLabels();
@@ -91,7 +150,7 @@ export const Alert = memo((props: AlertProps) => {
91
150
  if (!visible) return null;
92
151
 
93
152
  const iconColor: Record<AlertType, string> = {
94
- // Íconos sobre la superficie del diálogo: rol `*Text`, no el acento pleno.
153
+ // Icons over the dialog's surface: `*Text` role, not the full accent.
95
154
  success: colors.successText,
96
155
  error: colors.errorText,
97
156
  warning: colors.warningText,
@@ -104,14 +163,19 @@ export const Alert = memo((props: AlertProps) => {
104
163
 
105
164
  const content = (
106
165
  <TouchableWithoutFeedback onPress={onClose} accessibilityRole="none">
107
- <View style={[styles.overlay, inline && styles.overlayInline]}>
166
+ <View style={[styles.overlay, inline && [styles.fill, styles.overlayInline]]}>
108
167
  <TouchableWithoutFeedback>
109
- <View style={styles.container} accessibilityRole="alert" accessibilityViewIsModal>
168
+ <View
169
+ style={styles.container}
170
+ accessibilityRole="alert"
171
+ accessibilityViewIsModal
172
+ onAccessibilityEscape={onClose}
173
+ >
110
174
  <View style={styles.iconContainer}>
111
- <Icon name={ICON_BY_TYPE[type]} size={48} color={iconColor[type]} />
175
+ <Icon name={ICON_BY_TYPE[type]} size={ICON_SIZE} color={iconColor[type]} />
112
176
  </View>
113
177
 
114
- <Text allowFontScaling={allowFontScaling} style={styles.title}>
178
+ <Text allowFontScaling={allowFontScaling} style={styles.title} accessibilityRole="header">
115
179
  {title}
116
180
  </Text>
117
181
 
@@ -134,8 +198,8 @@ export const Alert = memo((props: AlertProps) => {
134
198
  title={btn.text}
135
199
  onPress={btn.onPress || onClose || (() => {})}
136
200
  variant={variant}
137
- style={[styles.button, vertical ? styles.buttonVertical : styles.buttonHorizontal]}
138
- textStyle={{ fontSize: 14 }}
201
+ style={vertical ? styles.buttonVertical : styles.buttonHorizontal}
202
+ textStyle={{ fontSize: theme.tokens.fontSize.md }}
139
203
  />
140
204
  );
141
205
  })}
@@ -148,16 +212,23 @@ export const Alert = memo((props: AlertProps) => {
148
212
 
149
213
  if (inline) {
150
214
  return (
151
- <View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }} pointerEvents="box-none">
215
+ <View style={styles.fill} pointerEvents="box-none">
152
216
  {content}
153
217
  </View>
154
218
  );
155
219
  }
156
220
 
157
221
  return (
158
- <Modal transparent visible={visible} animationType="fade" statusBarTranslucent presentationStyle="overFullScreen" onRequestClose={onClose || (() => {})}>
222
+ <NativeOverlay
223
+ dialog
224
+ transparent
225
+ animationType="fade"
226
+ statusBarTranslucent
227
+ presentationStyle="overFullScreen"
228
+ onRequestClose={onClose || (() => {})}
229
+ >
159
230
  {content}
160
- </Modal>
231
+ </NativeOverlay>
161
232
  );
162
233
  });
163
234
  Alert.displayName = 'Alert';
@@ -11,14 +11,14 @@ export interface AlertOptions {
11
11
  }
12
12
 
13
13
  export interface ConfirmOptions extends AlertOptions {
14
- /** Botón de confirmar en rojo/destructivo (para "eliminar", etc). */
14
+ /** Shows the confirm button as destructive/red (for "delete", etc.). */
15
15
  destructive?: boolean;
16
16
  }
17
17
 
18
18
  interface AlertContextValue {
19
- /** Muestra un alert de un solo botón. Resuelve cuando se cierra. */
19
+ /** Shows a single-button alert. Resolves when it closes. */
20
20
  alert: (options: AlertOptions) => Promise<void>;
21
- /** Muestra confirmar/cancelar. Resuelve true si se confirmó, false si se canceló. */
21
+ /** Shows confirm/cancel. Resolves true if confirmed, false if cancelled. */
22
22
  confirm: (options: ConfirmOptions) => Promise<boolean>;
23
23
  hide: () => void;
24
24
  }
@@ -27,15 +27,15 @@ const AlertContext = createContext<AlertContextValue | undefined>(undefined);
27
27
  const bridge = createImperativeBridge<AlertContextValue>('AlertProvider');
28
28
 
29
29
  /**
30
- * Abre un alert desde fuera del árbol de React —un servicio, un interceptor—
31
- * sin pasar por el hook. Sin <AlertProvider> montado resuelve de inmediato, así
32
- * que un `await` nunca queda colgado.
30
+ * Opens an alert from outside the React tree —a service, an interceptor—
31
+ * without going through the hook. Without a mounted <AlertProvider> it
32
+ * resolves immediately, so an `await` never hangs.
33
33
  */
34
34
  export function showAlert(options: AlertOptions): Promise<void> {
35
35
  return bridge.get()?.alert(options) ?? Promise.resolve();
36
36
  }
37
37
 
38
- /** Igual que showAlert, pero resuelve true/false. Sin provider, false. */
38
+ /** Same as showAlert, but resolves true/false. Without a provider, false. */
39
39
  export function showConfirm(options: ConfirmOptions): Promise<boolean> {
40
40
  return bridge.get()?.confirm(options) ?? Promise.resolve(false);
41
41
  }
@@ -56,16 +56,16 @@ const HIDDEN: InternalState = { visible: false, title: '', type: 'info', buttons
56
56
 
57
57
  /**
58
58
  * AlertProvider
59
- * Monta un único <Alert> controlado imperativamente. Colocar una vez cerca
60
- * de la raíz (dentro de UIProvider). Los handlers async pueden hacer
61
- * `const ok = await confirm({ title: 'Eliminar', destructive: true })`.
59
+ * Mounts a single imperatively controlled <Alert>. Place it once near the
60
+ * root (inside UIProvider). Async handlers can do
61
+ * `const ok = await confirm({ title: 'Delete', destructive: true })`.
62
62
  */
63
63
  export function AlertProvider({ children }: { children: React.ReactNode }) {
64
64
  const [state, setState] = useState<InternalState>(HIDDEN);
65
65
  const resolverRef = useRef<((value: any) => void) | null>(null);
66
- // Si alert()/confirm() se llaman de nuevo mientras ya hay uno abierto, el
67
- // pedido anterior se resuelve (no se descarta) antes de mostrar el nuevo:
68
- // evita que su promise quede colgada para siempre.
66
+ // If alert()/confirm() are called again while one is already open, the
67
+ // previous request is resolved (not discarded) before showing the new one:
68
+ // this keeps its promise from hanging forever.
69
69
  const settlePending = useCallback(() => {
70
70
  resolverRef.current?.(undefined);
71
71
  resolverRef.current = null;
@@ -1,31 +1,42 @@
1
1
  import React, { memo, useEffect, useRef, useState } from 'react';
2
2
  import {
3
3
  Animated,
4
- Dimensions,
5
4
  Keyboard,
6
5
  KeyboardAvoidingView,
7
- Modal,
8
6
  PanResponder,
9
7
  Platform,
10
8
  Pressable,
11
9
  ScrollView,
12
10
  View,
11
+ useWindowDimensions,
13
12
  type ViewStyle,
14
13
  } from 'react-native';
15
14
  import { createStyles } from '../theme/createStyles';
16
- import { useColors, useModalSafeAreaBoundary } from '../theme/UIProvider';
15
+ import { useColors, useLabels, useModalSafeAreaBoundary, useTheme } from '../theme/UIProvider';
16
+ import { useReduceMotion } from '../theme/useReduceMotion';
17
+ import { KeyboardHandled } from '../theme/KeyboardAvoidance';
18
+ import { NativeOverlay } from '../theme/NativeOverlay';
17
19
  import { Title } from '../atoms/Text';
18
20
  import { IconButton } from '../atoms/IconButton';
19
21
  import { Transition } from '../atoms/Transition';
20
22
 
21
- const { height: SCREEN_HEIGHT } = Dimensions.get('window');
22
- const DISMISS_THRESHOLD = 100;
23
+ /** Drag distance (pt) that closes the sheet on release. */
24
+ const DISMISS_DISTANCE = 100;
25
+ /** Downward release speed that closes it even after a short drag (a flick). */
26
+ const DISMISS_VELOCITY = 0.5;
27
+ const HANDLE_WIDTH = 40;
28
+ const HANDLE_HEIGHT = 5;
29
+ const HANDLE_OPACITY = 0.4;
30
+ const CLOSE_ICON_SIZE = 24;
23
31
 
24
32
  export type FooterPlacement = 'fixed' | 'scroll' | 'hide-with-keyboard';
25
33
 
26
34
  export interface BottomSheetProps {
35
+ /** Shows or hides the sheet (it slides in and out). */
27
36
  visible: boolean;
37
+ /** Called by the backdrop, the close button, the drag and Android back. */
28
38
  onClose: () => void;
39
+ /** Sheet content. */
29
40
  children: React.ReactNode;
30
41
  /** With a title, the header appears, with its close button. */
31
42
  title?: string;
@@ -43,9 +54,14 @@ export interface BottomSheetProps {
43
54
  draggable?: boolean;
44
55
  /** Fraction of the screen (0-1) or pixels. @default 0.9 */
45
56
  maxHeight?: number;
57
+ /** Accessible name of the close button and backdrop. @default labels.close */
46
58
  closeAccessibilityLabel?: string;
59
+ /** Style of the sheet itself (background, radius). */
47
60
  containerStyle?: ViewStyle;
61
+ /** Style of the content area (padding). */
48
62
  contentStyle?: ViewStyle;
63
+ /** Draws the sheet inside its parent instead of over the screen (docs, previews). @default false */
64
+ inline?: boolean;
49
65
  testID?: string;
50
66
  }
51
67
 
@@ -53,13 +69,22 @@ const useStyles = createStyles((theme) => ({
53
69
  container: { flex: 1, justifyContent: 'flex-end' },
54
70
  backdrop: { backgroundColor: theme.colors.overlay },
55
71
  sheet: {
56
- backgroundColor: theme.colors.surface,
72
+ // Raised: in dark mode the plain surface sank into the dimmed backdrop.
73
+ backgroundColor: theme.colors.surfaceRaised,
57
74
  borderTopLeftRadius: theme.tokens.radius.xxl,
58
75
  borderTopRightRadius: theme.tokens.radius.xxl,
59
76
  ...theme.tokens.shadow.lg,
60
77
  },
61
78
  handleArea: { paddingVertical: theme.tokens.spacing.md, alignItems: 'center' },
62
- handle: { width: 40, height: 5, borderRadius: 3, backgroundColor: theme.colors.border },
79
+ handle: {
80
+ width: HANDLE_WIDTH,
81
+ height: HANDLE_HEIGHT,
82
+ borderRadius: HANDLE_HEIGHT / 2,
83
+ // textLight, faded: `border` was nearly invisible on a white sheet, and
84
+ // the handle is the only hint that the sheet can be dragged.
85
+ backgroundColor: theme.colors.textLight,
86
+ opacity: HANDLE_OPACITY,
87
+ },
63
88
  header: {
64
89
  flexDirection: 'row',
65
90
  alignItems: 'center',
@@ -84,10 +109,17 @@ const absoluteFill: ViewStyle = { position: 'absolute', top: 0, left: 0, right:
84
109
 
85
110
  /**
86
111
  * BottomSheet
87
- * Hoja que entra desde abajo, con arrastre para cerrar (PanResponder, no un
88
- * gesture-handler externo: la librería es cero dependencias). Header, footer y
89
- * scroll son opcionales, así que cubre tanto la hoja desnuda como el formulario
90
- * completo.
112
+ * Sheet that slides in from the bottom, with drag to close (PanResponder, not
113
+ * an external gesture-handler: the library is zero-dependency). Header, footer
114
+ * and scroll are optional, so it covers both the bare sheet and the full
115
+ * form.
116
+ *
117
+ * Gestalt, figure-ground: the backdrop dims the screen, so the sheet is the
118
+ * only figure. Common region: header, content and footer share one panel;
119
+ * the footer's top border separates the actions from the content. Continuity:
120
+ * it slides from the edge it lives on and the drag follows the finger back
121
+ * down; a short flick closes it too. Fitts: content sits in the thumb zone.
122
+ * Reduce Motion: it appears and leaves without sliding.
91
123
  */
92
124
  export const BottomSheet = memo(
93
125
  ({
@@ -100,36 +132,50 @@ export const BottomSheet = memo(
100
132
  scrollable = true,
101
133
  draggable = true,
102
134
  maxHeight = 0.9,
103
- closeAccessibilityLabel = 'Close',
135
+ closeAccessibilityLabel,
104
136
  containerStyle,
105
137
  contentStyle,
138
+ inline = false,
106
139
  testID,
107
140
  }: BottomSheetProps) => {
108
141
  const styles = useStyles();
109
142
  const colors = useColors();
143
+ const theme = useTheme();
144
+ const labels = useLabels();
145
+ const reduceMotion = useReduceMotion();
146
+ const { height: screenHeight } = useWindowDimensions();
147
+ const closeLabel = closeAccessibilityLabel ?? labels.close;
148
+ const { duration } = theme.tokens;
149
+ // The PanResponder is created once: it reads these through refs.
150
+ const screenHeightRef = useRef(screenHeight);
151
+ screenHeightRef.current = screenHeight;
152
+ const snapBackMs = useRef(duration.fast);
153
+ snapBackMs.current = reduceMotion ? 0 : duration.fast;
110
154
  const ModalSafeAreaBoundary = useModalSafeAreaBoundary();
111
155
  const [mounted, setMounted] = useState(visible);
112
156
  const [keyboardOpen, setKeyboardOpen] = useState(false);
113
157
  const progress = useRef(new Animated.Value(0)).current;
114
- // El PanResponder de más abajo se crea una sola vez; leer `onClose`
115
- // directo del closure daría siempre el de ese primer render. El ref
116
- // refleja la última prop sin importar cuándo se creó la closure.
158
+ // The PanResponder further down is created only once; reading `onClose`
159
+ // straight from the closure would always give the one from that first
160
+ // render. The ref reflects the latest prop no matter when the closure was created.
117
161
  const onCloseRef = useRef(onClose);
118
162
  onCloseRef.current = onClose;
119
163
 
120
164
  useEffect(() => {
121
- const animation = visible
122
- ? Animated.timing(progress, { toValue: 1, duration: 250, useNativeDriver: true })
123
- : Animated.timing(progress, { toValue: 0, duration: 200, useNativeDriver: true });
165
+ const animation = Animated.timing(progress, {
166
+ toValue: visible ? 1 : 0,
167
+ duration: reduceMotion ? 0 : visible ? duration.slow : duration.base,
168
+ useNativeDriver: true,
169
+ });
124
170
  if (visible) setMounted(true);
125
171
  animation.start(({ finished }) => {
126
172
  if (!visible && finished) setMounted(false);
127
173
  });
128
- // Si el efecto vuelve a correr (o el componente se desmonta) antes de
129
- // que termine, se corta: si no, un `finished` tardío podría llamar
130
- // `setMounted` sobre un componente ya desmontado.
174
+ // If the effect runs again (or the component unmounts) before it
175
+ // finishes, it is cut short: otherwise, a late `finished` could call
176
+ // `setMounted` on an already unmounted component.
131
177
  return () => animation.stop();
132
- }, [visible, progress]);
178
+ }, [visible, progress, reduceMotion, duration.slow, duration.base]);
133
179
 
134
180
  useEffect(() => {
135
181
  if (footerPlacement !== 'hide-with-keyboard') return;
@@ -146,13 +192,14 @@ export const BottomSheet = memo(
146
192
  PanResponder.create({
147
193
  onMoveShouldSetPanResponder: (_, gesture) => gesture.dy > 5 && Math.abs(gesture.dy) > Math.abs(gesture.dx),
148
194
  onPanResponderMove: (_, gesture) => {
149
- if (gesture.dy > 0) progress.setValue(1 - Math.min(gesture.dy, SCREEN_HEIGHT) / SCREEN_HEIGHT);
195
+ const h = screenHeightRef.current;
196
+ if (gesture.dy > 0) progress.setValue(1 - Math.min(gesture.dy, h) / h);
150
197
  },
151
198
  onPanResponderRelease: (_, gesture) => {
152
- if (gesture.dy > DISMISS_THRESHOLD) {
199
+ if (gesture.dy > DISMISS_DISTANCE || (gesture.dy > 0 && gesture.vy > DISMISS_VELOCITY)) {
153
200
  onCloseRef.current();
154
201
  } else {
155
- Animated.timing(progress, { toValue: 1, duration: 150, useNativeDriver: true }).start();
202
+ Animated.timing(progress, { toValue: 1, duration: snapBackMs.current, useNativeDriver: true }).start();
156
203
  }
157
204
  },
158
205
  })
@@ -160,8 +207,8 @@ export const BottomSheet = memo(
160
207
 
161
208
  if (!mounted) return null;
162
209
 
163
- // Porcentaje y no píxeles: se mide contra el contenedor, que con el teclado
164
- // abierto es más bajo, así que la hoja entra siempre entera.
210
+ // Percentage, not pixels: it is measured against the container, which is
211
+ // shorter with the keyboard open, so the sheet always fits entirely.
165
212
  const resolvedMaxHeight: number | `${number}%` = maxHeight <= 1 ? `${maxHeight * 100}%` : maxHeight;
166
213
  const hasHeader = !!title;
167
214
 
@@ -190,44 +237,53 @@ export const BottomSheet = memo(
190
237
  </View>
191
238
  );
192
239
 
193
- return (
194
- <Modal visible transparent animationType="none" statusBarTranslucent onRequestClose={onClose}>
195
- {/* La hoja está anclada abajo, así que el teclado la tapa entera: hay
196
- que empujarla, no ajustar insets adentro del scroll. Una sola
197
- compensación, la del contenedor. */}
240
+ const tree = (
241
+ <>
242
+ {/* The sheet is anchored at the bottom, so the keyboard covers it
243
+ entirely: it has to be pushed up, not adjusted with insets inside
244
+ the scroll. A single compensation, the container's. */}
245
+ <KeyboardHandled>
198
246
  <KeyboardAvoidingView
199
247
  style={styles.container}
200
248
  behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
201
249
  >
202
250
  <Transition value={progress} preset="fade" style={[absoluteFill, styles.backdrop]}>
203
- {/* Con header, el botón de cerrar ya expone la acción: repetir el
204
- label acá deja dos elementos con el mismo nombre. */}
251
+ {/* With a header, the close button already exposes the action:
252
+ repeating the label here leaves two elements with the same name. */}
205
253
  <Pressable
206
254
  style={absoluteFill}
207
255
  onPress={onClose}
208
256
  testID="bottom-sheet-backdrop"
209
257
  accessibilityRole={hasHeader ? undefined : 'button'}
210
- accessibilityLabel={hasHeader ? undefined : closeAccessibilityLabel}
258
+ accessibilityLabel={hasHeader ? undefined : closeLabel}
211
259
  />
212
260
  </Transition>
213
261
 
214
- {/* Insets medidos dentro de esta ventana nativa (el Modal nativo que
215
- usa BottomSheet por debajo), no los de la raíz de la app. */}
262
+ {/* Insets measured inside this native window (the native Modal
263
+ BottomSheet uses underneath), not the app root's. */}
216
264
  <ModalSafeAreaBoundary>
217
265
  {(insets) => (
218
266
  <Transition
219
267
  value={progress}
220
268
  preset="slide-up"
221
- distance={SCREEN_HEIGHT}
269
+ distance={screenHeight}
222
270
  testID={testID}
223
271
  style={[
224
272
  styles.sheet,
225
- { maxHeight: resolvedMaxHeight, paddingBottom: Math.max(insets.bottom, 20) },
273
+ { maxHeight: resolvedMaxHeight, paddingBottom: Math.max(insets.bottom, theme.tokens.spacing.xl) },
226
274
  containerStyle,
227
275
  ]}
228
276
  >
229
277
  {draggable && (
230
- <View style={styles.handleArea} testID="bottom-sheet-handle" {...panResponder.panHandlers}>
278
+ // Decorative for screen readers: closing is already exposed by the
279
+ // close button (with a title) or by the backdrop (without one).
280
+ <View
281
+ style={styles.handleArea}
282
+ testID="bottom-sheet-handle"
283
+ accessibilityElementsHidden
284
+ importantForAccessibility="no-hide-descendants"
285
+ {...panResponder.panHandlers}
286
+ >
231
287
  <View style={styles.handle} />
232
288
  </View>
233
289
  )}
@@ -239,10 +295,10 @@ export const BottomSheet = memo(
239
295
  </Title>
240
296
  <IconButton
241
297
  iconName="close"
242
- size={24}
298
+ size={CLOSE_ICON_SIZE}
243
299
  color={colors.text}
244
300
  onPress={onClose}
245
- accessibilityLabel={closeAccessibilityLabel}
301
+ accessibilityLabel={closeLabel}
246
302
  />
247
303
  </View>
248
304
  )}
@@ -254,7 +310,23 @@ export const BottomSheet = memo(
254
310
  )}
255
311
  </ModalSafeAreaBoundary>
256
312
  </KeyboardAvoidingView>
257
- </Modal>
313
+ </KeyboardHandled>
314
+ </>
315
+ );
316
+
317
+ if (inline) {
318
+ return (
319
+ <View style={absoluteFill} pointerEvents="box-none">
320
+ {tree}
321
+ </View>
322
+ );
323
+ }
324
+
325
+ return (
326
+ // closing: while the exit animation plays, no other overlay layers into it.
327
+ <NativeOverlay closing={!visible} transparent animationType="none" statusBarTranslucent onRequestClose={onClose}>
328
+ {tree}
329
+ </NativeOverlay>
258
330
  );
259
331
  }
260
332
  );