pixelize-native-library 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/lib/module/core/MODULE.md +2 -1
  2. package/lib/module/core/gradient/AccentGradientFill.js +80 -0
  3. package/lib/module/core/gradient/darkenHex.js +13 -0
  4. package/lib/module/core/gradient/gradientStops.js +27 -0
  5. package/lib/module/core/gradient/index.js +7 -0
  6. package/lib/module/core/gradient/withAlpha.js +19 -0
  7. package/lib/module/core/haptics/MODULE.md +4 -0
  8. package/lib/module/core/haptics/context.js +7 -0
  9. package/lib/module/core/haptics/haptics.js +17 -0
  10. package/lib/module/core/haptics/index.js +6 -0
  11. package/lib/module/core/haptics/useHaptics.js +73 -0
  12. package/lib/module/core/icon/MODULE.md +16 -9
  13. package/lib/module/core/icon/icons/trending-up.js +10 -0
  14. package/lib/module/core/icon/resolve.js +2 -0
  15. package/lib/module/core/media/expoImage.js +6 -0
  16. package/lib/module/core/motion/MODULE.md +12 -12
  17. package/lib/module/core/motion/config.js +4 -1
  18. package/lib/module/core/motion/index.js +2 -1
  19. package/lib/module/core/motion/usePressState.js +145 -0
  20. package/lib/module/core/style/index.js +1 -0
  21. package/lib/module/core/style/radius.js +4 -0
  22. package/lib/module/index.js +1 -0
  23. package/lib/module/modules/accordion/Accordion.js +69 -49
  24. package/lib/module/modules/accordion/Accordion.variants.js +4 -3
  25. package/lib/module/modules/accordion/MODULE.md +2 -1
  26. package/lib/module/modules/alert-dialog/AlertDialog.js +6 -5
  27. package/lib/module/modules/alert-dialog/AlertDialog.variants.js +4 -0
  28. package/lib/module/modules/app-bar/AppBar.js +6 -4
  29. package/lib/module/modules/app-bar/AppBar.variants.js +1 -2
  30. package/lib/module/modules/avatar/Avatar.js +7 -1
  31. package/lib/module/modules/avatar/Avatar.variants.js +1 -1
  32. package/lib/module/modules/avatar/MODULE.md +2 -2
  33. package/lib/module/modules/avatar-group/AvatarGroup.js +10 -6
  34. package/lib/module/modules/avatar-group/AvatarGroup.variants.js +23 -0
  35. package/lib/module/modules/avatar-group/MODULE.md +16 -0
  36. package/lib/module/modules/badge/Badge.js +11 -5
  37. package/lib/module/modules/badge/Badge.variants.js +2 -1
  38. package/lib/module/modules/badge/MODULE.md +5 -5
  39. package/lib/module/modules/banner/Banner.js +106 -60
  40. package/lib/module/modules/banner/Banner.variants.js +2 -2
  41. package/lib/module/modules/banner/MODULE.md +7 -2
  42. package/lib/module/modules/bottom-nav/BottomNav.js +6 -3
  43. package/lib/module/modules/bottom-nav/BottomNav.variants.js +9 -10
  44. package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js +28 -4
  45. package/lib/module/modules/bottom-nav/BottomNavTab.js +28 -4
  46. package/lib/module/modules/bottom-nav/MODULE.md +10 -1
  47. package/lib/module/modules/bottom-sheet/BottomSheet.js +20 -7
  48. package/lib/module/modules/bottom-sheet/BottomSheet.variants.js +15 -5
  49. package/lib/module/modules/bottom-sheet/MODULE.md +13 -2
  50. package/lib/module/modules/button/Button.js +87 -101
  51. package/lib/module/modules/button/Button.variants.js +8 -7
  52. package/lib/module/modules/button/MODULE.md +6 -0
  53. package/lib/module/modules/button-group/ButtonGroup.js +36 -37
  54. package/lib/module/modules/button-group/ButtonGroup.variants.js +21 -46
  55. package/lib/module/modules/button-group/MODULE.md +25 -30
  56. package/lib/module/modules/card/Card.js +117 -19
  57. package/lib/module/modules/card/Card.variants.js +1 -0
  58. package/lib/module/modules/card/MODULE.md +13 -10
  59. package/lib/module/modules/charts/BarChart.js +29 -14
  60. package/lib/module/modules/charts/BarList.js +31 -18
  61. package/lib/module/modules/charts/Charts.variants.js +66 -2
  62. package/lib/module/modules/charts/DonutChart.js +9 -4
  63. package/lib/module/modules/charts/LineChart.js +5 -3
  64. package/lib/module/modules/charts/MODULE.md +24 -11
  65. package/lib/module/modules/charts/PieChart.js +13 -4
  66. package/lib/module/modules/charts/Sparkline.js +4 -2
  67. package/lib/module/modules/checkbox/Checkbox.js +10 -2
  68. package/lib/module/modules/checkbox/MODULE.md +5 -0
  69. package/lib/module/modules/chip/Chip.js +83 -38
  70. package/lib/module/modules/chip/Chip.variants.js +15 -3
  71. package/lib/module/modules/chip/MODULE.md +6 -4
  72. package/lib/module/modules/combobox/Combobox.js +93 -57
  73. package/lib/module/modules/combobox/Combobox.variants.js +22 -7
  74. package/lib/module/modules/combobox/MODULE.md +14 -4
  75. package/lib/module/modules/composer/Composer.js +9 -2
  76. package/lib/module/modules/composer/Composer.variants.js +2 -0
  77. package/lib/module/modules/composer/MODULE.md +5 -0
  78. package/lib/module/modules/copy-button/CopyButton.js +22 -4
  79. package/lib/module/modules/copy-button/CopyButton.variants.js +4 -2
  80. package/lib/module/modules/copy-button/MODULE.md +5 -0
  81. package/lib/module/modules/data-table/DataTable.js +28 -9
  82. package/lib/module/modules/data-table/DataTable.variants.js +3 -2
  83. package/lib/module/modules/data-table/MODULE.md +1 -0
  84. package/lib/module/modules/date-picker/Calendar.js +75 -29
  85. package/lib/module/modules/date-picker/DatePicker.variants.js +24 -9
  86. package/lib/module/modules/date-picker/MODULE.md +25 -4
  87. package/lib/module/modules/date-picker/PickerField.js +13 -4
  88. package/lib/module/modules/date-picker/PickerShell.js +2 -0
  89. package/lib/module/modules/date-picker/TimePicker.js +13 -18
  90. package/lib/module/modules/divider/Divider.variants.js +6 -5
  91. package/lib/module/modules/divider/MODULE.md +2 -0
  92. package/lib/module/modules/drawer/Drawer.js +20 -8
  93. package/lib/module/modules/drawer/Drawer.variants.js +4 -4
  94. package/lib/module/modules/drawer/MODULE.md +3 -0
  95. package/lib/module/modules/empty-state/EmptyState.js +18 -29
  96. package/lib/module/modules/empty-state/EmptyState.variants.js +7 -0
  97. package/lib/module/modules/empty-state/MODULE.md +1 -0
  98. package/lib/module/modules/fab/Fab.js +41 -61
  99. package/lib/module/modules/fab/Fab.variants.js +15 -1
  100. package/lib/module/modules/fab/FabGroup.js +84 -57
  101. package/lib/module/modules/fab/MODULE.md +19 -6
  102. package/lib/module/modules/file-grid/FileGrid.js +30 -16
  103. package/lib/module/modules/file-grid/FileGrid.variants.js +2 -2
  104. package/lib/module/modules/file-grid/MODULE.md +3 -1
  105. package/lib/module/modules/file-upload/FileUpload.variants.js +3 -1
  106. package/lib/module/modules/file-upload/MODULE.md +2 -0
  107. package/lib/module/modules/filter-sheet/FilterChip.js +11 -3
  108. package/lib/module/modules/filter-sheet/FilterSheetBody.js +15 -3
  109. package/lib/module/modules/filter-sheet/MODULE.md +9 -0
  110. package/lib/module/modules/folder-row/FolderRow.js +29 -17
  111. package/lib/module/modules/folder-row/FolderRow.variants.js +4 -2
  112. package/lib/module/modules/folder-row/MODULE.md +2 -1
  113. package/lib/module/modules/gantt/Gantt.js +30 -9
  114. package/lib/module/modules/gantt/Gantt.variants.js +36 -0
  115. package/lib/module/modules/gantt/MODULE.md +11 -1
  116. package/lib/module/modules/image-viewer/ImageViewer.js +35 -5
  117. package/lib/module/modules/image-viewer/MODULE.md +6 -0
  118. package/lib/module/modules/input/Input.js +20 -7
  119. package/lib/module/modules/input/Input.variants.js +8 -7
  120. package/lib/module/modules/input/MODULE.md +2 -0
  121. package/lib/module/modules/list-item/ListItem.js +48 -26
  122. package/lib/module/modules/list-item/ListItem.variants.js +11 -2
  123. package/lib/module/modules/list-item/MODULE.md +2 -3
  124. package/lib/module/modules/markdown/MODULE.md +8 -1
  125. package/lib/module/modules/markdown/Markdown.js +57 -22
  126. package/lib/module/modules/markdown/Markdown.variants.js +2 -1
  127. package/lib/module/modules/menu/MODULE.md +11 -0
  128. package/lib/module/modules/menu/Menu.js +99 -40
  129. package/lib/module/modules/menu/Menu.variants.js +3 -3
  130. package/lib/module/modules/message-bubble/MODULE.md +4 -1
  131. package/lib/module/modules/message-bubble/MessageBubble.js +4 -5
  132. package/lib/module/modules/message-bubble/MessageBubble.variants.js +5 -5
  133. package/lib/module/modules/modal/MODULE.md +11 -0
  134. package/lib/module/modules/modal/Modal.js +87 -35
  135. package/lib/module/modules/modal/Modal.variants.js +2 -2
  136. package/lib/module/modules/more-items/MODULE.md +5 -0
  137. package/lib/module/modules/more-items/MoreItems.js +7 -1
  138. package/lib/module/modules/more-items/MoreItems.variants.js +4 -1
  139. package/lib/module/modules/multi-select/MODULE.md +5 -0
  140. package/lib/module/modules/multi-select/MultiSelect.js +23 -1
  141. package/lib/module/modules/multi-select/MultiSelect.variants.js +4 -2
  142. package/lib/module/modules/number-input/MODULE.md +2 -1
  143. package/lib/module/modules/number-input/NumberInput.js +97 -84
  144. package/lib/module/modules/number-input/NumberInput.variants.js +9 -6
  145. package/lib/module/modules/org-switcher/MODULE.md +13 -1
  146. package/lib/module/modules/org-switcher/OrgSwitcher.js +13 -2
  147. package/lib/module/modules/org-switcher/OrgSwitcher.variants.js +4 -2
  148. package/lib/module/modules/pagination/MODULE.md +2 -2
  149. package/lib/module/modules/pagination/Pagination.js +76 -37
  150. package/lib/module/modules/pagination/Pagination.variants.js +4 -2
  151. package/lib/module/modules/pagination/PaginationControls.js +55 -35
  152. package/lib/module/modules/pin-input/MODULE.md +5 -1
  153. package/lib/module/modules/pin-input/PinInput.js +9 -2
  154. package/lib/module/modules/pin-input/PinInput.variants.js +2 -1
  155. package/lib/module/modules/radio-group/MODULE.md +2 -2
  156. package/lib/module/modules/radio-group/RadioGroup.js +122 -63
  157. package/lib/module/modules/radio-group/RadioGroup.variants.js +2 -1
  158. package/lib/module/modules/reorder/MODULE.md +2 -0
  159. package/lib/module/modules/reorder/Reorder.js +4 -3
  160. package/lib/module/modules/reorder/Reorder.variants.js +4 -2
  161. package/lib/module/modules/rich-text/MODULE.md +3 -1
  162. package/lib/module/modules/rich-text/RichText.js +42 -22
  163. package/lib/module/modules/rich-text-editor/MODULE.md +4 -1
  164. package/lib/module/modules/rich-text-editor/RichTextEditor.js +8 -1
  165. package/lib/module/modules/rich-text-editor/RichTextEditor.variants.js +9 -6
  166. package/lib/module/modules/screen/MODULE.md +7 -0
  167. package/lib/module/modules/screen/Screen.js +50 -17
  168. package/lib/module/modules/screen/Screen.variants.js +18 -0
  169. package/lib/module/modules/search-bar/MODULE.md +1 -0
  170. package/lib/module/modules/search-bar/SearchBar.js +46 -26
  171. package/lib/module/modules/search-bar/SearchBar.variants.js +11 -8
  172. package/lib/module/modules/section/MODULE.md +2 -0
  173. package/lib/module/modules/section/Section.js +8 -15
  174. package/lib/module/modules/section/Section.variants.js +1 -6
  175. package/lib/module/modules/segmented-control/MODULE.md +3 -1
  176. package/lib/module/modules/segmented-control/SegmentedControl.js +110 -46
  177. package/lib/module/modules/segmented-control/SegmentedControl.variants.js +3 -2
  178. package/lib/module/modules/select/MODULE.md +26 -5
  179. package/lib/module/modules/select/Select.js +39 -12
  180. package/lib/module/modules/select/Select.variants.js +36 -12
  181. package/lib/module/modules/skeleton/MODULE.md +23 -27
  182. package/lib/module/modules/skeleton/Skeleton.js +46 -51
  183. package/lib/module/modules/skeleton/Skeleton.variants.js +17 -75
  184. package/lib/module/modules/slider/MODULE.md +2 -0
  185. package/lib/module/modules/slider/Slider.js +2 -1
  186. package/lib/module/modules/stage-progress/MODULE.md +12 -8
  187. package/lib/module/modules/stage-progress/StageProgress.js +94 -47
  188. package/lib/module/modules/stage-progress/StageProgress.variants.js +17 -12
  189. package/lib/module/modules/stat-tile/MODULE.md +2 -0
  190. package/lib/module/modules/stat-tile/StatTile.js +15 -10
  191. package/lib/module/modules/stat-tile/StatTile.variants.js +2 -0
  192. package/lib/module/modules/state-block/MODULE.md +3 -0
  193. package/lib/module/modules/state-block/StateBlock.js +11 -6
  194. package/lib/module/modules/state-block/StateBlock.variants.js +7 -0
  195. package/lib/module/modules/surface/MODULE.md +59 -0
  196. package/lib/module/modules/surface/Surface.js +42 -0
  197. package/lib/module/modules/surface/Surface.variants.js +33 -0
  198. package/lib/module/modules/surface/index.js +4 -0
  199. package/lib/module/modules/swipeable-row/MODULE.md +9 -0
  200. package/lib/module/modules/swipeable-row/SwipeableRow.js +28 -7
  201. package/lib/module/modules/switch/MODULE.md +2 -0
  202. package/lib/module/modules/switch/Switch.js +8 -2
  203. package/lib/module/modules/tabs/MODULE.md +2 -1
  204. package/lib/module/modules/tabs/Tabs.js +37 -18
  205. package/lib/module/modules/tabs/Tabs.variants.js +4 -2
  206. package/lib/module/modules/text/MODULE.md +5 -2
  207. package/lib/module/modules/text/Text.js +18 -6
  208. package/lib/module/modules/text/Text.variants.js +108 -44
  209. package/lib/module/modules/textarea/MODULE.md +2 -0
  210. package/lib/module/modules/textarea/Textarea.js +3 -2
  211. package/lib/module/modules/textarea/Textarea.variants.js +2 -1
  212. package/lib/module/modules/toast/MODULE.md +8 -4
  213. package/lib/module/modules/toast/Toast.js +31 -13
  214. package/lib/module/modules/toast/Toast.variants.js +5 -0
  215. package/lib/module/modules/tooltip/MODULE.md +15 -11
  216. package/lib/module/modules/tooltip/Tooltip.js +41 -9
  217. package/lib/module/modules/tooltip/Tooltip.variants.js +8 -1
  218. package/lib/module/theme/MODULE.md +3 -1
  219. package/lib/module/theme/platform/MODULE.md +14 -2
  220. package/lib/module/theme/platform/elevation.native.js +0 -44
  221. package/lib/module/theme/platform/floatingSurface.native.js +75 -0
  222. package/lib/module/theme/platform/highlight.native.js +59 -0
  223. package/lib/module/theme/platform/index.js +5 -0
  224. package/lib/module/theme/platform/motion.native.js +31 -11
  225. package/lib/module/theme/platform/stateLayer.native.js +14 -0
  226. package/lib/module/theme/platform/surfaces.native.js +11 -0
  227. package/lib/module/theme/provider/PixelizeProvider.js +12 -5
  228. package/lib/module/theme/tokens/MODULE.md +32 -28
  229. package/lib/module/theme/tokens/THEME-CONTRACT.md +137 -0
  230. package/lib/module/theme/tokens/assertPalette.js +29 -0
  231. package/lib/module/theme/tokens/brands/emerald/palette.light.js +7 -6
  232. package/lib/module/theme/tokens/brands/lavender/palette.light.js +3 -2
  233. package/lib/module/theme/tokens/brands/meadow/palette.light.js +7 -6
  234. package/lib/module/theme/tokens/brands/radiant/palette.light.js +7 -6
  235. package/lib/module/theme/tokens/brands/rosewood/palette.light.js +7 -6
  236. package/lib/module/theme/tokens/brands/skyline/palette.light.js +7 -6
  237. package/lib/module/theme/tokens/brands/slate/palette.light.js +8 -10
  238. package/lib/module/theme/tokens/brands/storefront/palette.light.js +7 -6
  239. package/lib/module/theme/tokens/brands/zinc/palette.dark.js +3 -2
  240. package/lib/module/theme/tokens/brands/zinc/palette.light.js +3 -2
  241. package/lib/module/theme/tokens/builders/buildDarkPalette.js +3 -2
  242. package/lib/module/theme/tokens/builders/finalizePalette.js +34 -0
  243. package/lib/module/theme/tokens/builders/liftToContrast.js +44 -0
  244. package/lib/module/theme/tokens/builders/placeholderInk.js +22 -0
  245. package/lib/module/theme/tokens/builders/semanticText.js +14 -0
  246. package/lib/module/theme/tokens/builders/surfaceRungs.js +44 -0
  247. package/lib/module/theme/tokens/index.js +5 -0
  248. package/lib/module/theme/tokens/roles/index.js +5 -0
  249. package/lib/typescript/core/gradient/AccentGradientFill.d.ts +7 -0
  250. package/lib/typescript/core/gradient/darkenHex.d.ts +2 -0
  251. package/lib/typescript/core/gradient/gradientStops.d.ts +10 -0
  252. package/lib/typescript/core/gradient/index.d.ts +5 -0
  253. package/lib/typescript/core/gradient/withAlpha.d.ts +2 -0
  254. package/lib/typescript/core/haptics/context.d.ts +3 -0
  255. package/lib/typescript/core/haptics/haptics.d.ts +33 -0
  256. package/lib/typescript/core/haptics/index.d.ts +6 -0
  257. package/lib/typescript/core/haptics/useHaptics.d.ts +12 -0
  258. package/lib/typescript/core/icon/icons/trending-up.d.ts +3 -0
  259. package/lib/typescript/core/icon/names.d.ts +1 -1
  260. package/lib/typescript/core/media/expoImage.d.ts +15 -6
  261. package/lib/typescript/core/media/pickers.d.ts +5 -5
  262. package/lib/typescript/core/motion/config.d.ts +2 -1
  263. package/lib/typescript/core/motion/index.d.ts +3 -1
  264. package/lib/typescript/core/motion/usePressState.d.ts +21 -0
  265. package/lib/typescript/core/style/index.d.ts +1 -0
  266. package/lib/typescript/core/style/radius.d.ts +2 -0
  267. package/lib/typescript/index.d.ts +4 -2
  268. package/lib/typescript/modules/accordion/Accordion.variants.d.ts +2 -2
  269. package/lib/typescript/modules/alert-dialog/AlertDialog.variants.d.ts +1 -0
  270. package/lib/typescript/modules/avatar/Avatar.variants.d.ts +1 -1
  271. package/lib/typescript/modules/avatar-group/AvatarGroup.d.ts +4 -2
  272. package/lib/typescript/modules/avatar-group/AvatarGroup.variants.d.ts +19 -0
  273. package/lib/typescript/modules/banner/Banner.d.ts +2 -0
  274. package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts +1 -3
  275. package/lib/typescript/modules/bottom-sheet/BottomSheet.variants.d.ts +3 -1
  276. package/lib/typescript/modules/button/Button.d.ts +0 -25
  277. package/lib/typescript/modules/button/Button.variants.d.ts +6 -6
  278. package/lib/typescript/modules/button-group/ButtonGroup.d.ts +0 -19
  279. package/lib/typescript/modules/button-group/ButtonGroup.variants.d.ts +22 -56
  280. package/lib/typescript/modules/card/Card.d.ts +7 -5
  281. package/lib/typescript/modules/charts/Charts.variants.d.ts +29 -1
  282. package/lib/typescript/modules/chip/Chip.d.ts +3 -1
  283. package/lib/typescript/modules/chip/Chip.variants.d.ts +6 -2
  284. package/lib/typescript/modules/chip/index.d.ts +1 -1
  285. package/lib/typescript/modules/combobox/Combobox.variants.d.ts +17 -4
  286. package/lib/typescript/modules/data-table/DataTable.variants.d.ts +1 -1
  287. package/lib/typescript/modules/date-picker/DatePicker.variants.d.ts +15 -3
  288. package/lib/typescript/modules/date-picker/TimePicker.d.ts +1 -7
  289. package/lib/typescript/modules/divider/Divider.variants.d.ts +4 -4
  290. package/lib/typescript/modules/empty-state/EmptyState.d.ts +2 -0
  291. package/lib/typescript/modules/empty-state/EmptyState.variants.d.ts +1 -0
  292. package/lib/typescript/modules/fab/Fab.variants.d.ts +2 -0
  293. package/lib/typescript/modules/folder-row/FolderRow.d.ts +0 -8
  294. package/lib/typescript/modules/gantt/Gantt.variants.d.ts +21 -0
  295. package/lib/typescript/modules/input/Input.variants.d.ts +6 -6
  296. package/lib/typescript/modules/list-item/ListItem.d.ts +1 -5
  297. package/lib/typescript/modules/list-item/ListItem.variants.d.ts +137 -1
  298. package/lib/typescript/modules/markdown/Markdown.d.ts +7 -0
  299. package/lib/typescript/modules/message-bubble/MessageBubble.d.ts +2 -2
  300. package/lib/typescript/modules/message-bubble/MessageBubble.variants.d.ts +1 -2
  301. package/lib/typescript/modules/number-input/NumberInput.variants.d.ts +7 -5
  302. package/lib/typescript/modules/pagination/PaginationControls.d.ts +1 -4
  303. package/lib/typescript/modules/reorder/Reorder.d.ts +1 -1
  304. package/lib/typescript/modules/screen/Screen.d.ts +3 -9
  305. package/lib/typescript/modules/screen/Screen.variants.d.ts +4 -0
  306. package/lib/typescript/modules/search-bar/SearchBar.variants.d.ts +6 -6
  307. package/lib/typescript/modules/section/Section.variants.d.ts +0 -3
  308. package/lib/typescript/modules/segmented-control/SegmentedControl.variants.d.ts +1 -1
  309. package/lib/typescript/modules/select/Select.d.ts +4 -1
  310. package/lib/typescript/modules/select/Select.variants.d.ts +22 -8
  311. package/lib/typescript/modules/select/index.d.ts +1 -1
  312. package/lib/typescript/modules/skeleton/Skeleton.d.ts +3 -18
  313. package/lib/typescript/modules/skeleton/Skeleton.variants.d.ts +12 -68
  314. package/lib/typescript/modules/stage-progress/StageProgress.variants.d.ts +15 -6
  315. package/lib/typescript/modules/state-block/StateBlock.d.ts +4 -0
  316. package/lib/typescript/modules/state-block/StateBlock.variants.d.ts +1 -0
  317. package/lib/typescript/modules/surface/Surface.d.ts +19 -0
  318. package/lib/typescript/modules/surface/Surface.variants.d.ts +15 -0
  319. package/lib/typescript/modules/surface/index.d.ts +4 -0
  320. package/lib/typescript/modules/text/Text.d.ts +8 -4
  321. package/lib/typescript/modules/text/Text.variants.d.ts +14 -11
  322. package/lib/typescript/modules/toast/Toast.variants.d.ts +2 -0
  323. package/lib/typescript/modules/tooltip/Tooltip.variants.d.ts +7 -0
  324. package/lib/typescript/theme/index.d.ts +1 -1
  325. package/lib/typescript/theme/platform/elevation.native.d.ts +0 -30
  326. package/lib/typescript/theme/platform/floatingSurface.native.d.ts +10 -0
  327. package/lib/typescript/theme/platform/highlight.native.d.ts +17 -0
  328. package/lib/typescript/theme/platform/index.d.ts +9 -0
  329. package/lib/typescript/theme/platform/motion.native.d.ts +33 -13
  330. package/lib/typescript/theme/platform/stateLayer.native.d.ts +11 -0
  331. package/lib/typescript/theme/platform/surfaces.native.d.ts +8 -0
  332. package/lib/typescript/theme/provider/PixelizeProvider.d.ts +1 -1
  333. package/lib/typescript/theme/provider/types.d.ts +8 -0
  334. package/lib/typescript/theme/tokens/assertPalette.d.ts +10 -0
  335. package/lib/typescript/theme/tokens/brands/emerald/palette.light.d.ts +4 -3
  336. package/lib/typescript/theme/tokens/brands/lavender/palette.light.d.ts +4 -3
  337. package/lib/typescript/theme/tokens/brands/meadow/palette.light.d.ts +4 -3
  338. package/lib/typescript/theme/tokens/brands/radiant/palette.light.d.ts +4 -3
  339. package/lib/typescript/theme/tokens/brands/rosewood/palette.light.d.ts +4 -3
  340. package/lib/typescript/theme/tokens/brands/skyline/palette.light.d.ts +4 -3
  341. package/lib/typescript/theme/tokens/brands/slate/palette.light.d.ts +4 -3
  342. package/lib/typescript/theme/tokens/brands/storefront/palette.light.d.ts +4 -3
  343. package/lib/typescript/theme/tokens/brands/zinc/palette.light.d.ts +4 -3
  344. package/lib/typescript/theme/tokens/builders/finalizePalette.d.ts +4 -0
  345. package/lib/typescript/theme/tokens/builders/liftToContrast.d.ts +9 -0
  346. package/lib/typescript/theme/tokens/builders/placeholderInk.d.ts +13 -0
  347. package/lib/typescript/theme/tokens/builders/semanticText.d.ts +4 -0
  348. package/lib/typescript/theme/tokens/builders/surfaceRungs.d.ts +12 -0
  349. package/lib/typescript/theme/tokens/index.d.ts +5 -0
  350. package/lib/typescript/theme/tokens/roles/index.d.ts +1 -0
  351. package/lib/typescript/theme/tokens/types.d.ts +8 -7
  352. package/package.json +10 -2
  353. package/registry.json +5 -0
@@ -17,13 +17,72 @@
17
17
  */
18
18
 
19
19
  import { memo, useCallback, useEffect, useMemo, useRef } from "react";
20
- import { ActivityIndicator, Animated, Pressable, ScrollView, Text, View } from "react-native";
20
+ import { ActivityIndicator, Animated, Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
21
+ import Reanimated, { FadeInDown, ReduceMotion } from "react-native-reanimated";
21
22
  import { useAnnounce } from "../../core/a11y/index.js";
22
23
  import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
24
+ import { usePressState } from "../../core/motion/usePressState.js";
23
25
  import { useTheme } from "../../theme/hooks.js";
26
+ import { floatingBackground, floatingSurfaceStyle } from "../../theme/platform/index.js";
27
+ import { stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
24
28
  import { DEFAULT_LOAD_MORE_LABEL, PAGINATION_SIZES, clampPage, buildPageRange, formatPageLabel, normalizePageCount, paginationLoadMoreStructure, paginationRowStructure, paginationScrollContentStructure, paginationStripRootStructure, resolvePaginationColors, resolvePaginationHitSlop } from "./Pagination.variants.js";
25
29
  import { PaginationEllipsis, PaginationPageControl, PaginationStepControl } from "./PaginationControls.js";
26
30
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
31
+ const AnimatedPressable = Reanimated.createAnimatedComponent(Pressable);
32
+ function LoadMoreButton({
33
+ inert,
34
+ loading,
35
+ loadMoreLabel,
36
+ onLoadMore,
37
+ theme,
38
+ colors,
39
+ hitSlop,
40
+ size,
41
+ spec,
42
+ testID
43
+ }) {
44
+ const press = usePressState(inert);
45
+ const overlayStaticStyle = useMemo(() => ({
46
+ backgroundColor: stateLayerScrim(theme.mode),
47
+ borderRadius: theme.radii.md,
48
+ borderCurve: "continuous"
49
+ }), [theme.mode, theme.radii.md]);
50
+ return /*#__PURE__*/_jsxs(AnimatedPressable, {
51
+ testID: testID ? `${testID}-load-more` : undefined,
52
+ accessibilityRole: "button",
53
+ accessibilityLabel: loadMoreLabel,
54
+ "aria-disabled": inert,
55
+ "aria-busy": loading,
56
+ disabled: inert,
57
+ onPress: inert ? undefined : onLoadMore,
58
+ onPressIn: press.handlers.onPressIn,
59
+ onPressOut: press.handlers.onPressOut,
60
+ onLayout: press.onLayout,
61
+ hitSlop: hitSlop,
62
+ style: [paginationLoadMoreStructure(theme, {
63
+ size
64
+ }), {
65
+ borderColor: colors.border,
66
+ overflow: "hidden"
67
+ }, press.animatedStyle],
68
+ children: [/*#__PURE__*/_jsx(Reanimated.View, {
69
+ pointerEvents: "none",
70
+ style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
71
+ }), loading && /*#__PURE__*/_jsx(ActivityIndicator, {
72
+ size: "small",
73
+ color: colors.inactiveLabel,
74
+ accessibilityElementsHidden: true,
75
+ importantForAccessibility: "no-hide-descendants"
76
+ }), /*#__PURE__*/_jsx(Text, {
77
+ numberOfLines: 1,
78
+ style: [theme.fontStyleForWeight(theme.fontWeights.semibold), {
79
+ fontSize: spec.fontSize,
80
+ color: inert ? colors.inactiveLabel : colors.label
81
+ }],
82
+ children: loadMoreLabel
83
+ })]
84
+ });
85
+ }
27
86
  function PaginationImpl({
28
87
  page,
29
88
  pageCount,
@@ -95,7 +154,10 @@ function PaginationImpl({
95
154
  opacity: summaryOpacity
96
155
  }], [theme, spec.fontSize, blocked, colors, summaryOpacity]);
97
156
  const rowStyle = useMemo(() => [paginationRowStructure(theme), style], [theme, style]);
98
- const stripStyle = useMemo(() => [paginationStripRootStructure(), style], [style]);
157
+ const stripStyle = useMemo(() => [paginationStripRootStructure(), {
158
+ backgroundColor: floatingBackground(theme, "sm"),
159
+ ...floatingSurfaceStyle(theme, "sm")
160
+ }, style], [theme, style]);
99
161
  if (variant === "loadMore") {
100
162
  if (!hasMore && !loading) return null;
101
163
  const inert = blocked || onLoadMore === undefined;
@@ -103,41 +165,17 @@ function PaginationImpl({
103
165
  testID: testID,
104
166
  accessibilityRole: "none",
105
167
  style: rowStyle,
106
- children: /*#__PURE__*/_jsxs(Pressable, {
107
- testID: testID ? `${testID}-load-more` : undefined,
108
- accessibilityRole: "button",
109
- accessibilityLabel: loadMoreLabel,
110
- "aria-disabled": inert,
111
- "aria-busy": loading,
112
- disabled: inert,
113
- onPress: inert ? undefined : onLoadMore,
168
+ children: /*#__PURE__*/_jsx(LoadMoreButton, {
169
+ inert: inert,
170
+ loading: loading,
171
+ loadMoreLabel: loadMoreLabel,
172
+ onLoadMore: onLoadMore,
173
+ theme: theme,
174
+ colors: colors,
114
175
  hitSlop: hitSlop,
115
- style: ({
116
- pressed
117
- }) => [paginationLoadMoreStructure(theme, {
118
- size
119
- }), {
120
- borderColor: colors.border
121
- }, pressed && {
122
- backgroundColor: colors.pressedFill
123
- }],
124
- children: [loading &&
125
- /*#__PURE__*/
126
- // Never the sole loading signal — `aria-busy` announces it and the label
127
- // stays visible. Hidden from AT so it isn't read as a separate element (Button's spinner).
128
- _jsx(ActivityIndicator, {
129
- size: "small",
130
- color: colors.inactiveLabel,
131
- accessibilityElementsHidden: true,
132
- importantForAccessibility: "no-hide-descendants"
133
- }), /*#__PURE__*/_jsx(Text, {
134
- numberOfLines: 1,
135
- style: [theme.fontStyleForWeight(theme.fontWeights.semibold), {
136
- fontSize: spec.fontSize,
137
- color: inert ? colors.inactiveLabel : colors.label
138
- }],
139
- children: loadMoreLabel
140
- })]
176
+ size: size,
177
+ spec: spec,
178
+ testID: testID
141
179
  })
142
180
  });
143
181
  }
@@ -158,7 +196,8 @@ function PaginationImpl({
158
196
  }), renderStep("next", "chevron-right"), showFirstLast && renderStep("last", "chevrons-right")]
159
197
  });
160
198
  }
161
- return /*#__PURE__*/_jsx(View, {
199
+ return /*#__PURE__*/_jsx(Reanimated.View, {
200
+ entering: FadeInDown.springify().reduceMotion(ReduceMotion.System),
162
201
  testID: testID,
163
202
  accessibilityRole: "none",
164
203
  style: stripStyle,
@@ -241,7 +241,8 @@ export const paginationControlStructure = createThemedVariants(theme => ({
241
241
  justifyContent: "center",
242
242
  minWidth: PAGINATION_CONTROL_MIN_WIDTH,
243
243
  paddingHorizontal: theme.space[1],
244
- borderRadius: theme.radii.base
244
+ borderRadius: theme.radii.md,
245
+ borderCurve: "continuous"
245
246
  },
246
247
  variants: {
247
248
  size: {
@@ -287,7 +288,8 @@ export const paginationLoadMoreStructure = createThemedVariants(theme => ({
287
288
  columnGap: theme.space[2],
288
289
  minWidth: PAGINATION_CONTROL_MIN_WIDTH,
289
290
  paddingHorizontal: theme.space[4],
290
- borderRadius: theme.radii.base,
291
+ borderRadius: theme.radii.md,
292
+ borderCurve: "continuous",
291
293
  borderWidth: theme.borderWidths.thin
292
294
  },
293
295
  variants: {
@@ -1,23 +1,22 @@
1
1
  "use strict";
2
2
 
3
3
  /**
4
- * PRIVATE sub-components (not exported from `index.ts`). One control per node, each `React.memo`'d
5
- * and fed primitives only, so a page change re-renders the two controls whose state actually
6
- * changed instead of the whole strip — and so no `onPress`/`style` closure is rebuilt per control
7
- * per render.
4
+ * PRIVATE sub-components for Pagination controls.
8
5
  */
9
6
 
10
7
  import { memo, useCallback, useMemo, useState } from "react";
11
- import { Pressable, Text, View } from "react-native";
8
+ import { Pressable, StyleSheet, Text, View } from "react-native";
9
+ import Animated from "react-native-reanimated";
12
10
  import { Icon } from "../../core/icon/index.js";
11
+ import { usePressState } from "../../core/motion/usePressState.js";
12
+ import { stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
13
13
  import { paginationControlStructure, paginationEllipsisStructure, resolvePaginationPage, resolvePaginationStep } from "./Pagination.variants.js";
14
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  const ICON_STROKE = 2;
16
16
  const ELLIPSIS_GLYPH = "…";
17
17
  const FOCUS_RING_WIDTH = 2;
18
18
  const FOCUS_RING_INSET = 2;
19
-
20
- // Inset, not Button's outside offsets: the strip's ScrollView is one control tall and clips.
19
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
21
20
  const focusRingStyleFor = theme => ({
22
21
  position: "absolute",
23
22
  pointerEvents: "none",
@@ -27,8 +26,20 @@ const focusRingStyleFor = theme => ({
27
26
  bottom: FOCUS_RING_INSET,
28
27
  borderWidth: FOCUS_RING_WIDTH,
29
28
  borderColor: theme.colors.border.focus,
30
- borderRadius: Math.max(0, theme.radii.base - FOCUS_RING_INSET)
29
+ borderRadius: Math.max(0, theme.radii.md - FOCUS_RING_INSET)
31
30
  });
31
+ function usePaginationPress(theme, disabled) {
32
+ const press = usePressState(disabled);
33
+ const overlayStaticStyle = useMemo(() => ({
34
+ backgroundColor: stateLayerScrim(theme.mode),
35
+ borderRadius: theme.radii.md,
36
+ borderCurve: "continuous"
37
+ }), [theme.mode, theme.radii.md]);
38
+ return {
39
+ press,
40
+ overlayStaticStyle
41
+ };
42
+ }
32
43
  export const PaginationStepControl = /*#__PURE__*/memo(function PaginationStepControl({
33
44
  kind,
34
45
  icon,
@@ -52,38 +63,43 @@ export const PaginationStepControl = /*#__PURE__*/memo(function PaginationStepCo
52
63
  loading
53
64
  });
54
65
  const target = a11y.targetPage;
66
+ const inert = a11y.disabled;
67
+ const {
68
+ press,
69
+ overlayStaticStyle
70
+ } = usePaginationPress(theme, inert);
55
71
  const handlePress = useCallback(() => {
56
72
  if (target !== undefined) onPageChange(target);
57
73
  }, [target, onPageChange]);
58
- const pressedFill = colors.pressedFill;
59
- const inert = a11y.disabled;
60
- const controlStyle = useCallback(({
61
- pressed
62
- }) => [paginationControlStructure(theme, {
63
- size
64
- }), pressed && !inert ? {
65
- backgroundColor: pressedFill
66
- } : null], [theme, size, inert, pressedFill]);
67
74
  const [focused, setFocused] = useState(false);
68
75
  const handleFocus = useCallback(() => setFocused(true), []);
69
76
  const handleBlur = useCallback(() => setFocused(false), []);
70
77
  const focusRingStyle = useMemo(() => focusRingStyleFor(theme), [theme]);
71
- return /*#__PURE__*/_jsxs(Pressable, {
78
+ const controlStyle = useMemo(() => [paginationControlStructure(theme, {
79
+ size
80
+ }), {
81
+ overflow: "hidden"
82
+ }, press.animatedStyle], [theme, size, press.animatedStyle]);
83
+ return /*#__PURE__*/_jsxs(AnimatedPressable, {
72
84
  testID: testID,
73
85
  accessibilityRole: a11y.accessibilityRole,
74
86
  accessibilityLabel: a11y.accessibilityLabel,
75
87
  "aria-disabled": a11y["aria-disabled"],
76
88
  "aria-busy": a11y["aria-busy"],
77
- disabled: inert
78
- // RN's Pressable stays `focusable` when disabled, so a TV remote could land on a boundary arrow.
79
- ,
89
+ disabled: inert,
80
90
  focusable: !inert,
81
91
  onPress: target === undefined ? undefined : handlePress,
92
+ onPressIn: press.handlers.onPressIn,
93
+ onPressOut: press.handlers.onPressOut,
94
+ onLayout: press.onLayout,
82
95
  onFocus: handleFocus,
83
96
  onBlur: handleBlur,
84
97
  hitSlop: hitSlop,
85
98
  style: controlStyle,
86
- children: [focused && !inert && /*#__PURE__*/_jsx(View, {
99
+ children: [/*#__PURE__*/_jsx(Animated.View, {
100
+ pointerEvents: "none",
101
+ style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
102
+ }), focused && !inert && /*#__PURE__*/_jsx(View, {
87
103
  testID: testID ? `${testID}-focus-ring` : undefined,
88
104
  style: focusRingStyle
89
105
  }), /*#__PURE__*/_jsx(Icon, {
@@ -118,22 +134,20 @@ export const PaginationPageControl = /*#__PURE__*/memo(function PaginationPageCo
118
134
  });
119
135
  const target = a11y.targetPage;
120
136
  const current = a11y.current;
137
+ const {
138
+ press,
139
+ overlayStaticStyle
140
+ } = usePaginationPress(theme, a11y.disabled);
121
141
  const handlePress = useCallback(() => {
122
142
  if (target !== undefined) onPageChange(target);
123
143
  }, [target, onPageChange]);
124
- const {
125
- currentFill,
126
- pressedFill
127
- } = colors;
128
- const controlStyle = useCallback(({
129
- pressed
130
- }) => [paginationControlStructure(theme, {
144
+ const controlStyle = useMemo(() => [paginationControlStructure(theme, {
131
145
  size
132
146
  }), current ? {
133
- backgroundColor: currentFill
134
- } : null, !current && pressed ? {
135
- backgroundColor: pressedFill
136
- } : null], [theme, size, current, currentFill, pressedFill]);
147
+ backgroundColor: colors.currentFill
148
+ } : null, {
149
+ overflow: "hidden"
150
+ }, press.animatedStyle], [theme, size, current, colors.currentFill, press.animatedStyle]);
137
151
  const labelStyle = useMemo(() => [theme.fontStyleForWeight(current ? theme.fontWeights.semibold : theme.fontWeights.regular), {
138
152
  fontSize,
139
153
  color: current ? colors.onCurrentFill : blocked ? colors.inactiveLabel : colors.label
@@ -142,7 +156,7 @@ export const PaginationPageControl = /*#__PURE__*/memo(function PaginationPageCo
142
156
  const handleFocus = useCallback(() => setFocused(true), []);
143
157
  const handleBlur = useCallback(() => setFocused(false), []);
144
158
  const focusRingStyle = useMemo(() => focusRingStyleFor(theme), [theme]);
145
- return /*#__PURE__*/_jsxs(Pressable, {
159
+ return /*#__PURE__*/_jsxs(AnimatedPressable, {
146
160
  testID: testID,
147
161
  accessibilityRole: a11y.accessibilityRole,
148
162
  accessibilityLabel: a11y.accessibilityLabel,
@@ -153,11 +167,17 @@ export const PaginationPageControl = /*#__PURE__*/memo(function PaginationPageCo
153
167
  disabled: a11y.disabled,
154
168
  focusable: !a11y.disabled,
155
169
  onPress: target === undefined ? undefined : handlePress,
170
+ onPressIn: press.handlers.onPressIn,
171
+ onPressOut: press.handlers.onPressOut,
172
+ onLayout: press.onLayout,
156
173
  onFocus: handleFocus,
157
174
  onBlur: handleBlur,
158
175
  hitSlop: hitSlop,
159
176
  style: controlStyle,
160
- children: [focused && !a11y.disabled && /*#__PURE__*/_jsx(View, {
177
+ children: [!current && /*#__PURE__*/_jsx(Animated.View, {
178
+ pointerEvents: "none",
179
+ style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
180
+ }), focused && !a11y.disabled && /*#__PURE__*/_jsx(View, {
161
181
  testID: testID ? `${testID}-focus-ring` : undefined,
162
182
  style: focusRingStyle
163
183
  }), /*#__PURE__*/_jsx(Text, {
@@ -79,7 +79,9 @@ Tapping ANY box focuses the same single underlying field — splitting the touch
79
79
  would just be N different ways to trigger the identical action, with no independent affordance
80
80
  each box could offer on its own. So the whole row is ONE `Pressable` (wrapping both the boxes and
81
81
  the hidden field), and `hitSlop` (via the same `slopFor` formula Button/Input use) is computed
82
- once against the row/box height, not per box. `PinInput.test.ts` asserts
82
+ once against the row/box height, not per box. The row also carries `android_ripple`
83
+ (`rippleColor(theme.mode)`, `borderless: false`) when not disabled, gated on
84
+ `Platform.OS === "android"`. `PinInput.test.ts` asserts
83
85
  `boxSize + 2·hitSlop ≥ 44` arithmetically for every size; `PinInput.render.test.tsx` additionally
84
86
  asserts the REAL rendered `hitSlop` prop and box dimensions (not just the constants) reach 44dp,
85
87
  same pattern as `Input`/`ButtonGroup`/`Reorder`'s render-level touch-target checks.
@@ -147,3 +149,5 @@ Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLA
147
149
  - Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
148
150
  - List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
149
151
  - `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
152
+
153
+ - **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
@@ -13,9 +13,10 @@
13
13
  * per box would just be N ways to trigger the identical action.
14
14
  */
15
15
 
16
- import { memo, useEffect, useRef, useState } from "react";
16
+ import { memo, useEffect, useMemo, useRef, useState } from "react";
17
17
  import { Platform, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
18
18
  import { useTheme } from "../../theme/hooks.js";
19
+ import { rippleColor } from "../../theme/platform/stateLayer.native.js";
19
20
  import { clampPinInputValue, isPinInputComplete, PIN_INPUT_SIZES, pinInputBoxStructure, pinInputRowStructure, resolvePinInputAccessibility, resolvePinInputActiveIndex, resolvePinInputBoxColors } from "./PinInput.variants.js";
20
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
22
  const FOCUS_RING_WIDTH = 2;
@@ -51,6 +52,10 @@ export const PinInput = /*#__PURE__*/memo(function PinInput(props) {
51
52
  errorText
52
53
  });
53
54
  const activeIndex = resolvePinInputActiveIndex(value, length);
55
+ const androidRipple = useMemo(() => Platform.OS === "android" && !disabled ? {
56
+ color: rippleColor(theme.mode),
57
+ borderless: false
58
+ } : undefined, [disabled, theme.mode]);
54
59
 
55
60
  // Always reads the LATEST `onComplete` without making it an effect dependency — a caller passing
56
61
  // a fresh inline arrow every render must not re-fire the completion effect on every render, only
@@ -76,6 +81,7 @@ export const PinInput = /*#__PURE__*/memo(function PinInput(props) {
76
81
  disabled: disabled,
77
82
  onPress: disabled ? undefined : focusInput,
78
83
  hitSlop: spec.hitSlop,
84
+ android_ripple: androidRipple,
79
85
  style: [pinInputRowStructure(theme, {
80
86
  size
81
87
  }), disabled && styles.dimmed],
@@ -105,7 +111,8 @@ export const PinInput = /*#__PURE__*/memo(function PinInput(props) {
105
111
  bottom: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
106
112
  borderWidth: FOCUS_RING_WIDTH,
107
113
  borderColor: theme.colors.border.focus,
108
- borderRadius: theme.radii.base + FOCUS_RING_GAP + FOCUS_RING_WIDTH
114
+ borderRadius: theme.radii.md + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
115
+ borderCurve: "continuous"
109
116
  }
110
117
  }), char !== undefined && (secureTextEntry ? /*#__PURE__*/_jsx(View, {
111
118
  testID: testID ? `${testID}-dot-${index}` : undefined,
@@ -166,7 +166,8 @@ export const pinInputBoxStructure = createThemedVariants(theme => ({
166
166
  alignItems: "center",
167
167
  justifyContent: "center",
168
168
  borderWidth: theme.borderWidths.thin,
169
- borderRadius: theme.radii.base
169
+ borderRadius: theme.radii.md,
170
+ borderCurve: "continuous"
170
171
  },
171
172
  variants: {
172
173
  size: {
@@ -65,8 +65,8 @@ closed union of appearances. The ring is always `border.interactive`; the select
65
65
  in the group clips), on the focused row only, never while disabled. Rows also carry
66
66
  `focusable={!disabled}` — RN's `Pressable` stays focusable when disabled, which on a TV remote
67
67
  would otherwise land on a row that renders no ring (same fix NumberInput's steppers use).
68
- - **2.3.3** — n/a: nothing here animates. The dot appears/disappears by conditional render (not a
69
- fade or a slide), so there is no transition for `useReducedMotion` to gate.
68
+ - **2.3.3** — n/a for selection dot (conditional render). Row presses use `usePressState` (scale +
69
+ state-layer overlay), which snaps under reduce motion.
70
70
  - Disabled rows are exempt from the contrast minimum (WCAG 1.4.3), so the uniform `opacity: 0.5`
71
71
  dim is correct, same as Button.
72
72
 
@@ -10,8 +10,12 @@
10
10
  * so there is nothing for `useReducedMotion` (WCAG 2.3.3) to gate — unlike Button's press fade.
11
11
  */
12
12
 
13
- import { memo, useRef, useState } from "react";
14
- import { Pressable, StyleSheet, Text, View } from "react-native";
13
+ import { memo, useRef, useState, useMemo, useCallback } from "react";
14
+ import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
15
+ import Animated from "react-native-reanimated";
16
+ import { usePressState } from "../../core/motion/usePressState.js";
17
+ import { useHaptics } from "../../core/haptics/index.js";
18
+ import { rippleColor, stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
15
19
  import { useTheme } from "../../theme/hooks.js";
16
20
  import { RADIO_GROUP_SIZES, radioDotStructure, radioGroupStructure, radioRingStructure, radioRowStructure, resolveRadioGroupColors, resolveRadioGroupKeyIndex, resolveRadioRowAccessibility } from "./RadioGroup.variants.js";
17
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -25,6 +29,94 @@ const KeyboardView = View;
25
29
  // the surface that role token is proven ≥ 3:1 against (WCAG 2.4.11).
26
30
  const FOCUS_RING_WIDTH = 2;
27
31
  const FOCUS_RING_GAP = 2;
32
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
33
+ function RadioRow({
34
+ option,
35
+ index,
36
+ selected,
37
+ disabled,
38
+ active,
39
+ size,
40
+ colors,
41
+ spec,
42
+ theme,
43
+ focusRingStyle,
44
+ focusedIndex,
45
+ setFocusedIndex,
46
+ selectValue,
47
+ rowRefs,
48
+ testID
49
+ }) {
50
+ const press = usePressState(disabled);
51
+ const a11y = resolveRadioRowAccessibility({
52
+ selected,
53
+ disabled
54
+ });
55
+ const overlayStaticStyle = useMemo(() => ({
56
+ backgroundColor: stateLayerScrim(theme.mode),
57
+ borderRadius: theme.radii.md,
58
+ borderCurve: "continuous"
59
+ }), [theme.mode, theme.radii.md]);
60
+ return /*#__PURE__*/_jsxs(View, {
61
+ style: styles.rowHost,
62
+ children: [focusedIndex === index && !disabled && /*#__PURE__*/_jsx(View, {
63
+ pointerEvents: "none",
64
+ testID: testID ? `${testID}-${option.value}-focus-ring` : undefined,
65
+ style: [styles.focusRing, focusRingStyle]
66
+ }), /*#__PURE__*/_jsxs(AnimatedPressable, {
67
+ ref: node => {
68
+ rowRefs.current[index] = node;
69
+ },
70
+ testID: testID ? `${testID}-${option.value}` : undefined,
71
+ accessibilityRole: a11y.accessibilityRole,
72
+ "aria-checked": a11y["aria-checked"],
73
+ "aria-disabled": a11y["aria-disabled"],
74
+ accessibilityLabel: option.label,
75
+ disabled: a11y.disabled,
76
+ tabIndex: !disabled && active ? 0 : -1,
77
+ focusable: !disabled,
78
+ onFocus: () => setFocusedIndex(() => index),
79
+ onBlur: () => setFocusedIndex(current => current === index ? null : current),
80
+ onPress: disabled ? undefined : () => selectValue(option.value),
81
+ onPressIn: press.handlers.onPressIn,
82
+ onPressOut: press.handlers.onPressOut,
83
+ onLayout: press.onLayout,
84
+ hitSlop: spec.hitSlop,
85
+ android_ripple: Platform.OS === "android" && !disabled ? {
86
+ color: rippleColor(theme.mode),
87
+ borderless: false
88
+ } : undefined,
89
+ style: [radioRowStructure(theme, {
90
+ size
91
+ }), {
92
+ overflow: "hidden"
93
+ }, press.animatedStyle, disabled && styles.dimmed],
94
+ children: [/*#__PURE__*/_jsx(Animated.View, {
95
+ pointerEvents: "none",
96
+ style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
97
+ }), /*#__PURE__*/_jsx(View, {
98
+ style: [radioRingStructure(theme, {
99
+ size
100
+ }), {
101
+ borderColor: colors.ring
102
+ }],
103
+ children: selected && /*#__PURE__*/_jsx(View, {
104
+ style: [radioDotStructure({
105
+ size
106
+ }), {
107
+ backgroundColor: colors.dot
108
+ }]
109
+ })
110
+ }), /*#__PURE__*/_jsx(Text, {
111
+ style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
112
+ fontSize: spec.fontSize,
113
+ color: colors.label
114
+ }],
115
+ children: option.label
116
+ })]
117
+ }, option.value)]
118
+ });
119
+ }
28
120
  export const RadioGroup = /*#__PURE__*/memo(function RadioGroup({
29
121
  options,
30
122
  value,
@@ -36,6 +128,7 @@ export const RadioGroup = /*#__PURE__*/memo(function RadioGroup({
36
128
  testID
37
129
  }) {
38
130
  const theme = useTheme();
131
+ const haptics = useHaptics();
39
132
  const spec = RADIO_GROUP_SIZES[size];
40
133
  const colors = resolveRadioGroupColors(theme.colors);
41
134
 
@@ -46,6 +139,10 @@ export const RadioGroup = /*#__PURE__*/memo(function RadioGroup({
46
139
  const activeIndex = selectedIndex >= 0 ? selectedIndex : 0;
47
140
  const rowRefs = useRef([]);
48
141
  const [focusedIndex, setFocusedIndex] = useState(null);
142
+ const selectValue = useCallback(nextValue => {
143
+ haptics.selection();
144
+ onValueChange(nextValue);
145
+ }, [haptics, onValueChange]);
49
146
  const handleKeyDown = event => {
50
147
  if (disabled) return;
51
148
  const next = resolveRadioGroupKeyIndex({
@@ -57,13 +154,14 @@ export const RadioGroup = /*#__PURE__*/memo(function RadioGroup({
57
154
  if (next === undefined || option === undefined) return;
58
155
  // Arrow/Home/End would otherwise scroll the page out from under the group.
59
156
  event.preventDefault?.();
60
- onValueChange(option.value);
157
+ selectValue(option.value);
61
158
  // The tab stop moves with the selection, so DOM focus has to follow it or the ring is stranded.
62
159
  rowRefs.current[next]?.focus();
63
160
  };
64
161
  const focusRingStyle = {
65
162
  borderColor: theme.colors.border.focus,
66
- borderRadius: theme.radii.base + FOCUS_RING_GAP + FOCUS_RING_WIDTH
163
+ borderRadius: theme.radii.md + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
164
+ borderCurve: "continuous"
67
165
  };
68
166
  return /*#__PURE__*/_jsx(KeyboardView, {
69
167
  testID: testID,
@@ -74,71 +172,32 @@ export const RadioGroup = /*#__PURE__*/memo(function RadioGroup({
74
172
  style: [radioGroupStructure(theme, {
75
173
  size
76
174
  }), style],
77
- children: options.map((option, index) => {
78
- const selected = option.value === value;
79
- const a11y = resolveRadioRowAccessibility({
80
- selected,
81
- disabled
82
- });
83
- return /*#__PURE__*/_jsxs(Pressable, {
84
- ref: node => {
85
- rowRefs.current[index] = node;
86
- },
87
- testID: testID ? `${testID}-${option.value}` : undefined,
88
- accessibilityRole: a11y.accessibilityRole,
89
- "aria-checked": a11y["aria-checked"],
90
- "aria-disabled": a11y["aria-disabled"],
91
- accessibilityLabel: option.label,
92
- disabled: a11y.disabled,
93
- tabIndex: !disabled && index === activeIndex ? 0 : -1
94
- // RN's Pressable stays `focusable` when disabled, so a TV remote could otherwise land on
95
- // a row that renders no ring (WCAG 2.4.7) — the same fix NumberInput's steppers use.
96
- ,
97
- focusable: !disabled,
98
- onFocus: () => setFocusedIndex(index),
99
- onBlur: () => setFocusedIndex(current => current === index ? null : current),
100
- onPress: disabled ? undefined : () => onValueChange(option.value),
101
- hitSlop: spec.hitSlop,
102
- style: ({
103
- pressed
104
- }) => [radioRowStructure(theme, {
105
- size
106
- }), pressed && !disabled && {
107
- backgroundColor: colors.pressedRow
108
- }, disabled && styles.dimmed],
109
- children: [focusedIndex === index && !disabled && /*#__PURE__*/_jsx(View, {
110
- pointerEvents: "none",
111
- testID: testID ? `${testID}-${option.value}-focus-ring` : undefined,
112
- style: [styles.focusRing, focusRingStyle]
113
- }), /*#__PURE__*/_jsx(View, {
114
- style: [radioRingStructure(theme, {
115
- size
116
- }), {
117
- borderColor: colors.ring
118
- }],
119
- children: selected && /*#__PURE__*/_jsx(View, {
120
- style: [radioDotStructure({
121
- size
122
- }), {
123
- backgroundColor: colors.dot
124
- }]
125
- })
126
- }), /*#__PURE__*/_jsx(Text, {
127
- style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
128
- fontSize: spec.fontSize,
129
- color: colors.label
130
- }],
131
- children: option.label
132
- })]
133
- }, option.value);
134
- })
175
+ children: options.map((option, index) => /*#__PURE__*/_jsx(RadioRow, {
176
+ option: option,
177
+ index: index,
178
+ selected: option.value === value,
179
+ disabled: disabled,
180
+ active: index === activeIndex,
181
+ size: size,
182
+ colors: colors,
183
+ spec: spec,
184
+ theme: theme,
185
+ focusRingStyle: focusRingStyle,
186
+ focusedIndex: focusedIndex,
187
+ setFocusedIndex: setFocusedIndex,
188
+ selectValue: selectValue,
189
+ rowRefs: rowRefs,
190
+ testID: testID
191
+ }, option.value))
135
192
  });
136
193
  });
137
194
  const styles = StyleSheet.create({
138
- // A disabled row is exempt from the contrast minimum (WCAG 1.4.3), so a uniform dim is correct.
139
195
  dimmed: {
140
196
  opacity: 0.5
141
197
  },
198
+ rowHost: {
199
+ position: "relative"
200
+ },
142
201
  focusRing: {
143
202
  position: "absolute",
144
203
  top: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
@@ -129,7 +129,8 @@ export const radioRowStructure = createThemedVariants(theme => ({
129
129
  base: {
130
130
  flexDirection: "row",
131
131
  alignItems: "center",
132
- borderRadius: theme.radii.base
132
+ borderRadius: theme.radii.md,
133
+ borderCurve: "continuous"
133
134
  },
134
135
  variants: {
135
136
  size: {
@@ -136,3 +136,5 @@ Replaced the original `PanResponder` + per-row `Animated.Value` implementation
136
136
  one animated node per row, no virtualization, unusable past a few hundred rows — with the single
137
137
  shared gesture + `VirtualList` described above. `react-native-gesture-handler` and
138
138
  `react-native-reanimated` are non-optional peers. **No public prop API change.**
139
+
140
+ Drag completion uses `scheduleOnRN` from `react-native-worklets` (not deprecated `runOnJS`).