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
@@ -35,11 +35,14 @@
35
35
 
36
36
  import { memo, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
37
37
  import { Animated, Modal, Platform, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
38
+ import Reanimated, { FadeInDown, ReduceMotion } from "react-native-reanimated";
38
39
  import { useAnnounce } from "../../core/a11y/index.js";
39
40
  import { useDismissOnEscape, useFocusTrap, useSpaceActivation } from "../../core/a11y/keyboard";
40
41
  import { Icon } from "../../core/icon/index.js";
41
42
  import { VirtualList } from "../../core/list/index.js";
42
43
  import { useMotion, usePressMotion, useReveal } from "../../core/motion/index.js";
44
+ import { elevation, floatingBackground, floatingSurfaceStyle, highlight, rippleColor } from "../../theme/platform/index.js";
45
+ import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
43
46
  import { useTheme } from "../../theme/hooks.js";
44
47
  import { ModalPortalContext } from "../modal/ModalPortalContext.js";
45
48
  import { renderWebPortal } from "../modal/renderWebPortal";
@@ -109,6 +112,10 @@ const ComboboxOptionRow = /*#__PURE__*/memo(function ComboboxOptionRow({
109
112
  backgroundColor: pressed || active ? rowColors.pressedRow : rowColors.background
110
113
  }, rowDisabled && styles.dimmed], [rowColors.pressedRow, rowColors.background, rowDisabled, active]);
111
114
  const contentStyle = useMemo(() => [comboboxRowStructure(theme), press.style], [theme, press.style]);
115
+ const androidRipple = useMemo(() => Platform.OS === "android" && !rowDisabled ? {
116
+ color: rippleColor(theme.mode),
117
+ borderless: false
118
+ } : undefined, [rowDisabled, theme.mode]);
112
119
  const textWrapStyle = useMemo(() => comboboxRowTextStructure(theme), [theme]);
113
120
  const labelStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.regular), {
114
121
  fontSize: theme.fontSizes.md,
@@ -134,6 +141,7 @@ const ComboboxOptionRow = /*#__PURE__*/memo(function ComboboxOptionRow({
134
141
  onPress: handlePress,
135
142
  onPressIn: press.onPressIn,
136
143
  onPressOut: press.onPressOut,
144
+ android_ripple: androidRipple,
137
145
  style: pressableStyle,
138
146
  children: /*#__PURE__*/_jsxs(Animated.View, {
139
147
  testID: testID ? `${testID}-option-${option.value}-content` : undefined,
@@ -373,7 +381,17 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
373
381
  const fieldStyle = useMemo(() => [comboboxFieldStructure(theme), {
374
382
  backgroundColor: triggerColors.background,
375
383
  borderColor: triggerColors.border
384
+ }, {
385
+ overflow: "hidden"
376
386
  }, disabled && styles.dimmed], [theme, triggerColors.background, triggerColors.border, disabled]);
387
+ const triggerRipple = useMemo(() => Platform.OS === "android" && !disabled ? {
388
+ color: rippleColor(theme.mode),
389
+ borderless: false
390
+ } : undefined, [disabled, theme.mode]);
391
+ const clearButtonRipple = useMemo(() => Platform.OS === "android" ? {
392
+ color: rippleColor(theme.mode),
393
+ borderless: false
394
+ } : undefined, [theme.mode]);
377
395
  const focusRingStyle = useMemo(() => ({
378
396
  position: "absolute",
379
397
  top: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
@@ -382,7 +400,8 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
382
400
  bottom: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
383
401
  borderWidth: FOCUS_RING_WIDTH,
384
402
  borderColor: theme.colors.border.focus,
385
- borderRadius: theme.radii.base + FOCUS_RING_GAP + FOCUS_RING_WIDTH
403
+ borderRadius: theme.radii.md + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
404
+ borderCurve: "continuous"
386
405
  }), [theme]);
387
406
  const fieldValueStyle = useMemo(() => comboboxFieldValueStructure(theme), [theme]);
388
407
  const summaryStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.regular), {
@@ -390,7 +409,9 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
390
409
  fontSize: COMBOBOX_FIELD_FONT_SIZE,
391
410
  color: isPlaceholder ? triggerColors.placeholder : triggerColors.text
392
411
  }], [theme, isPlaceholder, triggerColors.placeholder, triggerColors.text]);
393
- const clearButtonStyle = useMemo(() => comboboxClearButtonStructure(theme), [theme]);
412
+ const clearButtonStyle = useMemo(() => [comboboxClearButtonStructure(theme), {
413
+ overflow: "hidden"
414
+ }], [theme]);
394
415
  const errorTextStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.regular), {
395
416
  fontSize: theme.fontSizes.xs,
396
417
  color: resolveComboboxErrorTextColor(theme.colors),
@@ -400,10 +421,18 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
400
421
  backgroundColor: BACKDROP_SCRIM
401
422
  }], []);
402
423
  const overlayStyle = useMemo(() => comboboxOverlayStructure(theme), [theme]);
403
- const sheetSurfaceStyle = useMemo(() => [comboboxSheetStructure(theme), {
404
- backgroundColor: theme.colors.bg.surface,
424
+ const sheetFloating = useMemo(() => {
425
+ highlight("subtle", theme.mode);
426
+ elevation(elevationTokens.md);
427
+ void theme.elevatedSurfaces;
428
+ return {
429
+ backgroundColor: floatingBackground(theme, "md"),
430
+ ...floatingSurfaceStyle(theme, "md")
431
+ };
432
+ }, [theme]);
433
+ const sheetSurfaceStyle = useMemo(() => [comboboxSheetStructure(theme), sheetFloating, {
405
434
  maxHeight
406
- }], [theme, maxHeight]);
435
+ }], [theme, sheetFloating, maxHeight]);
407
436
  const sheetStyle = useMemo(() => [sheetSurfaceStyle, reveal.style], [sheetSurfaceStyle, reveal.style]);
408
437
  const searchRowStyle = useMemo(() => [comboboxSearchRowStructure(theme), {
409
438
  borderBottomColor: theme.colors.border.default
@@ -432,60 +461,63 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
432
461
  }), /*#__PURE__*/_jsx(View, {
433
462
  style: overlayStyle,
434
463
  pointerEvents: "box-none",
435
- children: /*#__PURE__*/_jsxs(Animated.View, {
436
- ref: sheetRef,
437
- style: sheetStyle,
438
- children: [/*#__PURE__*/_jsxs(View, {
439
- style: searchRowStyle,
440
- children: [/*#__PURE__*/_jsx(Icon, {
441
- name: "search",
442
- size: COMBOBOX_FIELD_ICON_SIZE,
443
- color: rowColors.icon,
444
- strokeWidth: ICON_STROKE
445
- }), /*#__PURE__*/_jsx(TextInput, {
446
- ref: searchInputRef,
447
- testID: testID ? `${testID}-search` : undefined,
448
- value: query,
449
- onChangeText: handleQueryChange,
450
- placeholder: searchPlaceholder,
451
- placeholderTextColor: rowColors.muted,
452
- accessibilityLabel: searchPlaceholder
453
- // Hyphenated JSX attributes are not type-checked at all, which is exactly why the id
454
- // comes from `comboboxOptionNativeId` and is never interpolated here.
464
+ children: /*#__PURE__*/_jsx(Reanimated.View, {
465
+ entering: FadeInDown.springify().reduceMotion(ReduceMotion.System),
466
+ children: /*#__PURE__*/_jsxs(Animated.View, {
467
+ ref: sheetRef,
468
+ style: sheetStyle,
469
+ children: [/*#__PURE__*/_jsxs(View, {
470
+ style: searchRowStyle,
471
+ children: [/*#__PURE__*/_jsx(Icon, {
472
+ name: "search",
473
+ size: COMBOBOX_FIELD_ICON_SIZE,
474
+ color: rowColors.icon,
475
+ strokeWidth: ICON_STROKE
476
+ }), /*#__PURE__*/_jsx(TextInput, {
477
+ ref: searchInputRef,
478
+ testID: testID ? `${testID}-search` : undefined,
479
+ value: query,
480
+ onChangeText: handleQueryChange,
481
+ placeholder: searchPlaceholder,
482
+ placeholderTextColor: rowColors.placeholder,
483
+ accessibilityLabel: searchPlaceholder
484
+ // Hyphenated JSX attributes are not type-checked at all, which is exactly why the id
485
+ // comes from `comboboxOptionNativeId` and is never interpolated here.
486
+ ,
487
+ "aria-activedescendant": activeOptionId,
488
+ autoFocus: true,
489
+ autoCapitalize: "none",
490
+ autoCorrect: false,
491
+ autoComplete: "off",
492
+ importantForAutofill: "no",
493
+ style: searchInputStyle
494
+ })]
495
+ }), loading ? /*#__PURE__*/_jsx(View, {
496
+ style: listStateStyle,
497
+ children: /*#__PURE__*/_jsx(Spinner, {
498
+ size: "md",
499
+ tone: "neutral",
500
+ testID: testID ? `${testID}-spinner` : undefined
501
+ })
502
+ }) : filteredOptions.length === 0 ? /*#__PURE__*/_jsx(View, {
503
+ style: listStateStyle,
504
+ children: /*#__PURE__*/_jsx(Text, {
505
+ accessibilityLiveRegion: Platform.OS === "android" ? "polite" : undefined,
506
+ style: emptyTextStyle,
507
+ children: emptyMessage
508
+ })
509
+ }) : /*#__PURE__*/_jsx(VirtualList, {
510
+ data: filteredOptions,
511
+ keyExtractor: keyExtractor,
512
+ renderItem: renderRow,
513
+ itemHeight: uniformRowHeight ? COMBOBOX_ROW_MIN_HEIGHT : undefined,
514
+ accessibilityRole: COMBOBOX_LISTBOX_ROLE
515
+ // The search field holds focus while the sheet is open, so the default `"never"`
516
+ // spends the first tap on any row dismissing the keyboard instead of selecting.
455
517
  ,
456
- "aria-activedescendant": activeOptionId,
457
- autoFocus: true,
458
- autoCapitalize: "none",
459
- autoCorrect: false,
460
- autoComplete: "off",
461
- importantForAutofill: "no",
462
- style: searchInputStyle
518
+ keyboardShouldPersistTaps: "handled"
463
519
  })]
464
- }), loading ? /*#__PURE__*/_jsx(View, {
465
- style: listStateStyle,
466
- children: /*#__PURE__*/_jsx(Spinner, {
467
- size: "md",
468
- tone: "neutral",
469
- testID: testID ? `${testID}-spinner` : undefined
470
- })
471
- }) : filteredOptions.length === 0 ? /*#__PURE__*/_jsx(View, {
472
- style: listStateStyle,
473
- children: /*#__PURE__*/_jsx(Text, {
474
- accessibilityLiveRegion: Platform.OS === "android" ? "polite" : undefined,
475
- style: emptyTextStyle,
476
- children: emptyMessage
477
- })
478
- }) : /*#__PURE__*/_jsx(VirtualList, {
479
- data: filteredOptions,
480
- keyExtractor: keyExtractor,
481
- renderItem: renderRow,
482
- itemHeight: uniformRowHeight ? COMBOBOX_ROW_MIN_HEIGHT : undefined,
483
- accessibilityRole: COMBOBOX_LISTBOX_ROLE
484
- // The search field holds focus while the sheet is open, so the default `"never"`
485
- // spends the first tap on any row dismissing the keyboard instead of selecting.
486
- ,
487
- keyboardShouldPersistTaps: "handled"
488
- })]
520
+ })
489
521
  })
490
522
  })]
491
523
  }) : null;
@@ -499,6 +531,8 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
499
531
  }), portalContainer) : null : /*#__PURE__*/_jsx(Modal, {
500
532
  visible: open,
501
533
  transparent: true,
534
+ statusBarTranslucent: true,
535
+ navigationBarTranslucent: true,
502
536
  animationType: "none",
503
537
  onRequestClose: closeSheet
504
538
  // `autoFocus` on the search TextInput alone is timing-flaky inside a native Modal on iOS
@@ -525,6 +559,7 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
525
559
  onFocus: handleFocus,
526
560
  onBlur: handleBlur,
527
561
  hitSlop: COMBOBOX_FIELD_HIT_SLOP,
562
+ android_ripple: triggerRipple,
528
563
  style: fieldStyle,
529
564
  children: [showFocusRing && /*#__PURE__*/_jsx(View, {
530
565
  pointerEvents: "none",
@@ -548,6 +583,7 @@ export const Combobox = /*#__PURE__*/memo(function Combobox(props) {
548
583
  accessibilityLabel: "Clear",
549
584
  onPress: handleClear,
550
585
  hitSlop: COMBOBOX_CLEAR_BUTTON_HIT_SLOP,
586
+ android_ripple: clearButtonRipple,
551
587
  style: clearButtonStyle,
552
588
  children: /*#__PURE__*/_jsx(Icon, {
553
589
  name: "x",
@@ -78,6 +78,16 @@ export function normalizeForSearch(value) {
78
78
  */
79
79
  export const COMBOBOX_LISTBOX_ROLE = "listbox";
80
80
 
81
+ /**
82
+ * Each option row's role. `aria-selected` is only valid ARIA on `option`/`row`/`tab`/`gridcell`/
83
+ * `treeitem` — the row sits inside a `COMBOBOX_LISTBOX_ROLE` container, so `option` is the
84
+ * textbook-correct pairing (2026-08 sweep fixed the row from the invalid `menuitem`+`aria-selected`
85
+ * combination — a followup to `select/Select.tsx`'s identical fix, both listbox/option/aria-selected
86
+ * per the ARIA 1.2 combobox-with-listbox-popup pattern). Same type gap as `COMBOBOX_LISTBOX_ROLE`:
87
+ * RN 0.86's `AccessibilityRole` union has no `option` either.
88
+ */
89
+ export const COMBOBOX_OPTION_ROLE = "option";
90
+
81
91
  /**
82
92
  * The DOM id of one option row. `aria-activedescendant` and `nativeID` must agree exactly, and
83
93
  * every `aria-*` prop is UNCHECKED by TypeScript on an RN component (hyphenated JSX attributes are
@@ -133,7 +143,7 @@ export function resolveComboboxTriggerColors(colors, state) {
133
143
  background: colors.bg.surface,
134
144
  border: state.error ? colors.status.danger.solid : colors.border.interactive,
135
145
  text: colors.fg.default,
136
- placeholder: colors.fg.muted,
146
+ placeholder: colors.fg.placeholder,
137
147
  icon: colors.fg.muted
138
148
  };
139
149
  }
@@ -148,6 +158,7 @@ export function resolveComboboxRowColors(colors) {
148
158
  background: colors.bg.surface,
149
159
  text: colors.fg.default,
150
160
  muted: colors.fg.muted,
161
+ placeholder: colors.fg.placeholder,
151
162
  icon: colors.fg.muted,
152
163
  checkIcon: colors.fg.default,
153
164
  pressedRow: colors.bg.sunken
@@ -167,13 +178,15 @@ export function resolveComboboxAccessibility(input) {
167
178
  };
168
179
  }
169
180
  /**
170
- * Every row is `menuitem` (matching this library's `Menu`), in BOTH single and multiple mode — the
171
- * spec this module was built against fixes this role regardless of mode, unlike `MultiSelect`'s own
172
- * `checkbox` rows. Selection state rides `aria-selected`, never `aria-checked`.
181
+ * Every row is `option` (2026-08 sweep was `menuitem`, which made `aria-selected` invalid ARIA;
182
+ * the row sits inside `COMBOBOX_LISTBOX_ROLE`, so `option` is the textbook-correct pairing), in BOTH
183
+ * single and multiple mode: this module's `aria-activedescendant` pattern is one listbox regardless
184
+ * of mode, unlike `MultiSelect`'s own separate `checkbox` rows. Selection state rides `aria-selected`,
185
+ * never `aria-checked`.
173
186
  */
174
187
  export function resolveComboboxRowAccessibility(input) {
175
188
  return {
176
- accessibilityRole: "menuitem",
189
+ accessibilityRole: COMBOBOX_OPTION_ROLE,
177
190
  "aria-selected": input.selected,
178
191
  "aria-disabled": input.disabled,
179
192
  disabled: input.disabled
@@ -191,7 +204,8 @@ export const comboboxFieldStructure = createThemedVariants(theme => ({
191
204
  columnGap: theme.space[2],
192
205
  height: COMBOBOX_FIELD_HEIGHT,
193
206
  paddingHorizontal: theme.space[4],
194
- borderRadius: theme.radii.base,
207
+ borderRadius: theme.radii.md,
208
+ borderCurve: "continuous",
195
209
  borderWidth: theme.borderWidths.thin
196
210
  }
197
211
  }));
@@ -230,7 +244,8 @@ export const comboboxOverlayStructure = createThemedVariants(theme => ({
230
244
  * default `DEFAULT_MAX_HEIGHT`) and is applied inline over this at the component boundary. */
231
245
  export const comboboxSheetStructure = createThemedVariants(theme => ({
232
246
  base: {
233
- borderRadius: theme.radii.base,
247
+ borderRadius: theme.radii.md,
248
+ borderCurve: "continuous",
234
249
  ...theme.elevation.lg
235
250
  }
236
251
  }));
@@ -61,10 +61,14 @@ through the same collapsing rule): 0 → placeholder, 1 → that option's label,
61
61
  ## Accessibility contract (WCAG)
62
62
 
63
63
  - **4.1.2** — the field is `accessibilityRole="combobox"` with flat `aria-expanded` tracking the
64
- sheet. Rows are `accessibilityRole="menuitem"` (matching `Menu`, in BOTH single and multiple
65
- mode — this module's own spec, unlike `MultiSelect`'s `checkbox` rows) with flat `aria-selected` /
66
- `aria-disabled`. Flat, never `accessibilityState={{…}}`: react-native-web discards the object form
67
- — see `docs/PLATFORM-A11Y-PROPS.md`.
64
+ sheet. Rows are `accessibilityRole="option"` (in BOTH single and multiple mode — this module's own
65
+ spec, unlike `MultiSelect`'s `checkbox` rows) with flat `aria-selected` / `aria-disabled`. Flat,
66
+ never `accessibilityState={{…}}`: react-native-web discards the object form — see
67
+ `docs/PLATFORM-A11Y-PROPS.md`. **2026-08 sweep:** rows were `accessibilityRole="menuitem"`, which
68
+ made `aria-selected` invalid ARIA (only valid on `option`/`row`/`tab`/`gridcell`/`treeitem`); rows
69
+ sit inside `COMBOBOX_LISTBOX_ROLE` (`"listbox"`), so `option` + `aria-selected` is the
70
+ textbook-correct ARIA listbox pattern — the same fix `select/Select.tsx`'s identical bug got, only
71
+ the row's `accessibilityRole` changed.
68
72
  - **2.5.x target size** — the field reaches ≥ 44dp via `hitSlop`; the clear button — nested inside
69
73
  the field `Pressable`, same structure as `DatePicker`'s — reaches 44×44 the same way; option rows
70
74
  have a 44dp `minHeight` directly.
@@ -181,3 +185,9 @@ Via `core/motion` only — `opacity`/`transform`, native driver, all reduce-moti
181
185
  - Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
182
186
  - List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
183
187
  - `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
188
+
189
+ - **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
190
+ - **Round 5 (Android parity)** — `android_ripple` (`borderless: false`) added to the trigger field
191
+ (gated `!disabled`), the clear button, and each option row (gated `!rowDisabled`). The trigger
192
+ field and clear button also gained `overflow: "hidden"` so their ripple clips to the field/button
193
+ shape instead of escaping it.
@@ -13,6 +13,7 @@ import { memo, useCallback, useEffect, useMemo, useRef } from "react";
13
13
  import { ActivityIndicator, Animated, Platform, Pressable, StyleSheet, TextInput, View } from "react-native";
14
14
  import { Icon } from "../../core/icon/index.js";
15
15
  import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
16
+ import { rippleColor } from "../../theme/platform/stateLayer.native.js";
16
17
  import { useTheme } from "../../theme/hooks.js";
17
18
  import { composerFieldStructure, composerInputStructure, composerSendStructure, composerStructure } from "./Composer.variants.js";
18
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -32,6 +33,10 @@ const ComposerSend = /*#__PURE__*/memo(function ComposerSend({
32
33
  const sendStyle = useMemo(() => [composerSendStructure(theme), {
33
34
  backgroundColor: canSend ? theme.colors.accent.solid : theme.colors.bg.sunken
34
35
  }], [theme, canSend]);
36
+ const androidRipple = useMemo(() => Platform.OS === "android" && canSend ? {
37
+ color: rippleColor(theme.mode),
38
+ borderless: true
39
+ } : undefined, [canSend, theme.mode]);
35
40
  return /*#__PURE__*/_jsx(Pressable, {
36
41
  testID: testID,
37
42
  accessibilityRole: "button",
@@ -39,6 +44,7 @@ const ComposerSend = /*#__PURE__*/memo(function ComposerSend({
39
44
  "aria-disabled": !canSend,
40
45
  disabled: !canSend,
41
46
  onPress: onPress,
47
+ android_ripple: androidRipple,
42
48
  style: sendStyle,
43
49
  children: sending ? /*#__PURE__*/_jsx(ActivityIndicator, {
44
50
  color: theme.colors.accent.onSolid
@@ -110,7 +116,8 @@ export const Composer = /*#__PURE__*/memo(function Composer({
110
116
  bottom: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
111
117
  borderWidth: FOCUS_RING_WIDTH,
112
118
  borderColor: theme.colors.border.focus,
113
- borderRadius: theme.radii.lg + FOCUS_RING_GAP + FOCUS_RING_WIDTH
119
+ borderRadius: theme.radii.lg + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
120
+ borderCurve: "continuous"
114
121
  }), [theme]);
115
122
  return /*#__PURE__*/_jsxs(View, {
116
123
  testID: testID,
@@ -128,7 +135,7 @@ export const Composer = /*#__PURE__*/memo(function Composer({
128
135
  value: value,
129
136
  onChangeText: onChangeText,
130
137
  placeholder: placeholder,
131
- placeholderTextColor: theme.colors.fg.muted,
138
+ placeholderTextColor: theme.colors.fg.placeholder,
132
139
  editable: editable,
133
140
  accessibilityLabel: accessibilityLabel ?? placeholder,
134
141
  "aria-disabled": !editable,
@@ -26,6 +26,7 @@ export const composerInputStructure = createThemedVariants(theme => ({
26
26
  paddingHorizontal: theme.space[3],
27
27
  paddingVertical: theme.space[2],
28
28
  borderRadius: theme.radii.lg,
29
+ borderCurve: "continuous",
29
30
  borderWidth: theme.borderWidths.thin,
30
31
  fontSize: theme.fontSizes.md
31
32
  }
@@ -35,6 +36,7 @@ export const composerSendStructure = createThemedVariants(theme => ({
35
36
  width: 40,
36
37
  height: 40,
37
38
  borderRadius: theme.radii.full,
39
+ borderCurve: "continuous",
38
40
  alignItems: "center",
39
41
  justifyContent: "center"
40
42
  }
@@ -68,3 +68,8 @@ controlled), so:
68
68
  fresh literal per keystroke would defeat the memo above. `aria-disabled={!canSend}` is a primitive,
69
69
  not an object, so it needs no memo of its own.
70
70
  - `ComposerSend` reads `useTheme()` itself rather than taking a `theme` prop.
71
+
72
+ - **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
73
+ - **Round 5 (Android parity)** — the round send button now gets `android_ripple` (`borderless: true`,
74
+ matching its circular shape), gated on `Platform.OS === "android" && canSend` so a disabled send
75
+ button shows no ripple.
@@ -6,9 +6,10 @@
6
6
  */
7
7
 
8
8
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
9
- import { AccessibilityInfo, Animated, Pressable, Text, View } from "react-native";
9
+ import { AccessibilityInfo, Animated, Platform, Pressable, Text, View } from "react-native";
10
10
  import { Icon } from "../../core/icon/index.js";
11
11
  import { usePressMotion } from "../../core/motion/index.js";
12
+ import { rippleColor } from "../../theme/platform/stateLayer.native.js";
12
13
  import { useTheme } from "../../theme/hooks.js";
13
14
  import { COPY_BUTTON_SIZES, copyButtonMenuRowStructure, copyButtonOutlineStructure, COPY_FEEDBACK_MS, resolveCopyButtonColors, writeClipboard } from "./CopyButton.variants.js";
14
15
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -65,8 +66,9 @@ export const CopyButton = /*#__PURE__*/memo(function CopyButton({
65
66
  bottom: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
66
67
  borderWidth: FOCUS_RING_WIDTH,
67
68
  borderColor: theme.colors.border.focus,
68
- borderRadius: theme.radii.base + FOCUS_RING_GAP + FOCUS_RING_WIDTH
69
- }), [theme.colors.border.focus, theme.radii.base]);
69
+ borderRadius: theme.radii.md + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
70
+ borderCurve: "continuous"
71
+ }), [theme.colors.border.focus, theme.radii.md]);
70
72
  const spec = COPY_BUTTON_SIZES[size];
71
73
  const iconName = status === "copied" ? "check" : status === "failed" ? "triangle-alert" : "link";
72
74
  const ink = status === "copied" ? colors.success : status === "failed" ? colors.danger : colors.default;
@@ -83,9 +85,15 @@ export const CopyButton = /*#__PURE__*/memo(function CopyButton({
83
85
  onPress: handlePress,
84
86
  onFocus: onFocus,
85
87
  onBlur: onBlur,
88
+ android_ripple: Platform.OS === "android" ? {
89
+ color: rippleColor(theme.mode),
90
+ borderless: false
91
+ } : undefined,
86
92
  style: ({
87
93
  pressed
88
- }) => [copyButtonMenuRowStructure(theme), pressed ? {
94
+ }) => [copyButtonMenuRowStructure(theme), {
95
+ overflow: "hidden"
96
+ }, pressed ? {
89
97
  backgroundColor: theme.colors.bg.sunken
90
98
  } : null, style],
91
99
  children: [focusRing, /*#__PURE__*/_jsx(Icon, {
@@ -110,9 +118,15 @@ export const CopyButton = /*#__PURE__*/memo(function CopyButton({
110
118
  onPress: handlePress,
111
119
  onFocus: onFocus,
112
120
  onBlur: onBlur,
121
+ android_ripple: Platform.OS === "android" ? {
122
+ color: rippleColor(theme.mode),
123
+ borderless: false
124
+ } : undefined,
113
125
  style: ({
114
126
  pressed
115
127
  }) => [copyButtonOutlineStructure(theme), {
128
+ overflow: "hidden"
129
+ }, {
116
130
  borderColor: status === "copied" ? colors.success : status === "failed" ? colors.danger : colors.border,
117
131
  backgroundColor: pressed ? theme.colors.bg.sunken : theme.colors.bg.surface
118
132
  }, style],
@@ -140,6 +154,10 @@ export const CopyButton = /*#__PURE__*/memo(function CopyButton({
140
154
  onFocus: onFocus,
141
155
  onBlur: onBlur,
142
156
  hitSlop: spec.hitSlop,
157
+ android_ripple: Platform.OS === "android" ? {
158
+ color: rippleColor(theme.mode),
159
+ borderless: true
160
+ } : undefined,
143
161
  style: style,
144
162
  children: [focusRing, /*#__PURE__*/_jsx(Animated.View, {
145
163
  testID: "copy-button-glyph",
@@ -42,7 +42,8 @@ export const copyButtonMenuRowStructure = createThemedVariants(theme => ({
42
42
  columnGap: theme.space[2],
43
43
  paddingHorizontal: theme.space[3],
44
44
  paddingVertical: theme.space[2],
45
- borderRadius: theme.radii.base
45
+ borderRadius: theme.radii.md,
46
+ borderCurve: "continuous"
46
47
  }
47
48
  }));
48
49
  export const copyButtonOutlineStructure = createThemedVariants(theme => ({
@@ -53,7 +54,8 @@ export const copyButtonOutlineStructure = createThemedVariants(theme => ({
53
54
  columnGap: theme.space[1],
54
55
  paddingHorizontal: theme.space[3],
55
56
  paddingVertical: theme.space[2],
56
- borderRadius: theme.radii.base,
57
+ borderRadius: theme.radii.md,
58
+ borderCurve: "continuous",
57
59
  borderWidth: theme.borderWidths.thin
58
60
  }
59
61
  }));
@@ -71,3 +71,8 @@ variant) until the user retries.
71
71
  ## Performance
72
72
 
73
73
  Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLAUDE.md`).
74
+
75
+ - **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
76
+ - **Round 5 (Android parity)** — all three variants get `android_ripple`: `icon` (round, icon-only)
77
+ is `borderless: true`; `button` and `menu-item` are `borderless: false` and also gained
78
+ `overflow: "hidden"` so the ripple clips to the row/outline shape.
@@ -13,9 +13,12 @@
13
13
 
14
14
  import { memo, useCallback, useMemo, useState } from "react";
15
15
  import { Platform, Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
16
+ import Animated from "react-native-reanimated";
16
17
  import { HEADING_LEVEL, HeadingView } from "../../core/heading/index.js";
17
18
  import { Icon } from "../../core/icon/index.js";
19
+ import { usePressState } from "../../core/motion/usePressState.js";
18
20
  import { VirtualList } from "../../core/list/index.js";
21
+ import { rippleColor, stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
19
22
  import { useTheme } from "../../theme/hooks.js";
20
23
  import { Checkbox } from "../checkbox/index.js";
21
24
  import { EmptyState } from "../empty-state/index.js";
@@ -23,6 +26,7 @@ import { Skeleton } from "../skeleton/index.js";
23
26
  import { DATA_TABLE_DEFAULT_ROW_HEIGHT, DATA_TABLE_HEADER_HEIGHT, DATA_TABLE_SKELETON_CELL_HEIGHT, DATA_TABLE_SKELETON_ROW_COUNT, DATA_TABLE_SORT_ICON_SIZE, dataTableCellStructure, dataTableFocusRingStructure, dataTableHeaderRowStructure, dataTableRowStructure, dataTableSelectCellStructure, nextSortDirection, resolveColumnWidth, resolveDataTableColors, resolveDefaultCellText, resolveRowBackground, resolveSelectAllSelection, resolveSelectAllState, resolveSortAccessibilityLabel, resolveSortIcon, resolveTotalWidth, rowTouchSlop, toggleSelectionKey } from "./DataTable.variants.js";
24
27
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
25
28
  const ICON_STROKE = 2;
29
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
26
30
  const EMPTY_SELECTION = [];
27
31
  const SKELETON_ROW_INDICES = Array.from({
28
32
  length: DATA_TABLE_SKELETON_ROW_COUNT
@@ -396,7 +400,7 @@ function DataTableRowInner({
396
400
  specs,
397
401
  rowStyle,
398
402
  background,
399
- pressedBackground,
403
+ pressedBackground: _pressedBackground,
400
404
  textStyle,
401
405
  focusRingStyle,
402
406
  selectable,
@@ -406,7 +410,8 @@ function DataTableRowInner({
406
410
  hitSlop,
407
411
  testID
408
412
  }) {
409
- // Keyboard / external-keyboard / assistive-tech focus (no-op on pure touch, correct everywhere else).
413
+ const theme = useTheme();
414
+ const press = usePressState(onPress === undefined);
410
415
  const [focused, setFocused] = useState(false);
411
416
  const handleToggle = useCallback(() => onToggleSelect(rowKey), [onToggleSelect, rowKey]);
412
417
  const handlePress = useCallback(() => onPress?.(row, index), [onPress, row, index]);
@@ -415,11 +420,15 @@ function DataTableRowInner({
415
420
  const staticStyle = useMemo(() => [rowStyle, {
416
421
  backgroundColor: background
417
422
  }], [rowStyle, background]);
418
- const pressableStyle = useCallback(({
419
- pressed
420
- }) => [rowStyle, {
421
- backgroundColor: pressed ? pressedBackground : background
422
- }], [rowStyle, background, pressedBackground]);
423
+ const pressableStyle = useMemo(() => [rowStyle, {
424
+ backgroundColor: background,
425
+ overflow: "hidden"
426
+ }, press.animatedStyle], [rowStyle, background, press.animatedStyle]);
427
+ const overlayStaticStyle = useMemo(() => ({
428
+ backgroundColor: stateLayerScrim(theme.mode),
429
+ borderRadius: theme.radii.md,
430
+ borderCurve: "continuous"
431
+ }), [theme.mode, theme.radii.md]);
423
432
  const cells = /*#__PURE__*/_jsxs(_Fragment, {
424
433
  children: [selectable && /*#__PURE__*/_jsx(View, {
425
434
  style: SELECT_CELL_STRUCTURE,
@@ -444,15 +453,25 @@ function DataTableRowInner({
444
453
  children: cells
445
454
  });
446
455
  }
447
- return /*#__PURE__*/_jsxs(Pressable, {
456
+ return /*#__PURE__*/_jsxs(AnimatedPressable, {
448
457
  testID: testID,
449
458
  accessibilityRole: "button",
450
459
  hitSlop: hitSlop,
451
460
  onPress: handlePress,
461
+ onPressIn: press.handlers.onPressIn,
462
+ onPressOut: press.handlers.onPressOut,
463
+ onLayout: press.onLayout,
452
464
  onFocus: handleFocus,
453
465
  onBlur: handleBlur,
466
+ android_ripple: Platform.OS === "android" ? {
467
+ color: rippleColor(theme.mode),
468
+ borderless: false
469
+ } : undefined,
454
470
  style: pressableStyle,
455
- children: [focused && /*#__PURE__*/_jsx(View, {
471
+ children: [/*#__PURE__*/_jsx(Animated.View, {
472
+ pointerEvents: "none",
473
+ style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
474
+ }), focused && /*#__PURE__*/_jsx(View, {
456
475
  pointerEvents: "none",
457
476
  testID: testID === undefined ? undefined : `${testID}-focus-ring`,
458
477
  style: focusRingStyle
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { StyleSheet } from "react-native";
3
4
  /**
4
5
  * DataTable's style + behaviour resolution — the same split every sibling module copies
5
6
  * (see `Select.variants.ts` / `Menu.variants.ts`):
@@ -129,12 +130,12 @@ export const dataTableRowStructure = createVariants({
129
130
  alignItems: "stretch"
130
131
  }
131
132
  });
132
- export const dataTableHeaderRowStructure = createThemedVariants(theme => ({
133
+ export const dataTableHeaderRowStructure = createThemedVariants(_theme => ({
133
134
  base: {
134
135
  flexDirection: "row",
135
136
  alignItems: "stretch",
136
137
  height: DATA_TABLE_HEADER_HEIGHT,
137
- borderBottomWidth: theme.borderWidths.thin
138
+ borderBottomWidth: StyleSheet.hairlineWidth
138
139
  }
139
140
  }));
140
141
  export const dataTableCellStructure = createThemedVariants(theme => ({
@@ -118,6 +118,7 @@ never sorts `data` itself and never owns `selectedKeys` — it reports the next
118
118
  - **Row press vs. the selection checkbox** — the checkbox is its own nested `Pressable`; RN's
119
119
  responder system lets the innermost element claim a touch, so pressing the checkbox never also
120
120
  fires `onRowPress` (the standard, well-established RN pattern for a checkbox-in-row).
121
+ - **Row press feedback** — `usePressState` (scale + state-layer overlay) when `onRowPress` is set.
121
122
  - **Default cell text** reads `row[column.key]` through a narrow, documented `unknown` escape —
122
123
  `T` is intentionally unconstrained so any row shape works without a `render`.
123
124