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,15 @@
17
17
  */
18
18
 
19
19
  import { memo, useMemo } from "react";
20
- import { StyleSheet, Text, View } from "react-native";
20
+ import { View } from "react-native";
21
+ import Reanimated, { FadeInDown, FadeOut, ReduceMotion } from "react-native-reanimated";
21
22
  import { useAnnounce } from "../../core/a11y/index.js";
22
- import { HEADING_LEVEL, HeadingText } from "../../core/heading/index.js";
23
23
  import { Icon } from "../../core/icon/index.js";
24
24
  import { useTheme } from "../../theme/hooks.js";
25
+ import { floatingBackground, floatingSurfaceStyle } from "../../theme/platform/index.js";
25
26
  import { Button } from "../button/index.js";
26
- import { EMPTY_STATE_ICON_SIZE, emptyStateStructure, resolveEmptyStateAnnouncement, resolveEmptyStateColors } from "./EmptyState.variants.js";
27
+ import { Text, Heading } from "../text/index.js";
28
+ import { EMPTY_STATE_ICON_SIZE, emptyStateFillStructure, emptyStateStructure, resolveEmptyStateAnnouncement, resolveEmptyStateColors } from "./EmptyState.variants.js";
27
29
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
30
  // A lighter stroke than the default 2 — at 48dp a 2px stroke reads heavier than the muted,
29
31
  // secondary role this glyph plays next to the title.
@@ -33,6 +35,7 @@ export const EmptyState = /*#__PURE__*/memo(function EmptyState({
33
35
  title,
34
36
  description,
35
37
  action,
38
+ fill = false,
36
39
  style,
37
40
  testID
38
41
  }) {
@@ -42,24 +45,16 @@ export const EmptyState = /*#__PURE__*/memo(function EmptyState({
42
45
  // No `accessibilityLiveRegion` alongside this — it is Android-only and would announce twice there
43
46
  // (the contract `core/a11y/MODULE.md` states, same as `Input`/`FormField`).
44
47
  useAnnounce(resolveEmptyStateAnnouncement(title, description));
45
- const rootStyle = useMemo(() => [emptyStateStructure(theme), style], [theme, style]);
46
- const titleStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.bold), styles.text, {
47
- fontSize: theme.fontSizes.lg,
48
- color: colors.title
49
- }], [theme, colors]);
50
- const descriptionStyle = useMemo(() => [styles.text, {
51
- fontSize: theme.fontSizes.sm,
52
- color: colors.description
53
- }], [theme, colors]);
54
- return /*#__PURE__*/_jsxs(View, {
48
+ const rootStyle = useMemo(() => [emptyStateStructure(theme), fill && emptyStateFillStructure(theme), fill && {
49
+ backgroundColor: floatingBackground(theme, "sm"),
50
+ ...floatingSurfaceStyle(theme, "sm")
51
+ }, style], [theme, fill, style]);
52
+ return /*#__PURE__*/_jsxs(Reanimated.View, {
55
53
  testID: testID,
54
+ entering: FadeInDown.springify().reduceMotion(ReduceMotion.System),
55
+ exiting: FadeOut.reduceMotion(ReduceMotion.System),
56
56
  style: rootStyle,
57
- children: [icon !== undefined &&
58
- /*#__PURE__*/
59
- // Decorative — redundant with the visible title below, so it is hidden from assistive
60
- // tech rather than announced as a second, unexplained element (same contract `Avatar` and
61
- // `Skeleton` give their own decorative default).
62
- _jsx(View, {
57
+ children: [icon !== undefined && /*#__PURE__*/_jsx(View, {
63
58
  testID: testID === undefined ? undefined : `${testID}-icon`,
64
59
  accessibilityElementsHidden: true,
65
60
  importantForAccessibility: "no-hide-descendants",
@@ -69,13 +64,12 @@ export const EmptyState = /*#__PURE__*/memo(function EmptyState({
69
64
  color: colors.icon,
70
65
  strokeWidth: ICON_STROKE
71
66
  })
72
- }), /*#__PURE__*/_jsx(HeadingText, {
73
- accessibilityRole: "header",
74
- "aria-level": HEADING_LEVEL.section,
75
- style: titleStyle,
67
+ }), /*#__PURE__*/_jsx(Heading, {
68
+ variant: "h3",
76
69
  children: title
77
70
  }), description !== undefined && /*#__PURE__*/_jsx(Text, {
78
- style: descriptionStyle,
71
+ variant: "body-sm",
72
+ color: "muted",
79
73
  children: description
80
74
  }), action !== undefined && /*#__PURE__*/_jsx(Button, {
81
75
  label: action.label,
@@ -85,9 +79,4 @@ export const EmptyState = /*#__PURE__*/memo(function EmptyState({
85
79
  })]
86
80
  });
87
81
  });
88
- const styles = StyleSheet.create({
89
- text: {
90
- textAlign: "center"
91
- }
92
- });
93
82
  //# sourceMappingURL=EmptyState.js.map
@@ -60,4 +60,11 @@ export const emptyStateStructure = createThemedVariants(theme => ({
60
60
  rowGap: theme.space[3]
61
61
  }
62
62
  }));
63
+ export const emptyStateFillStructure = createThemedVariants(_theme => ({
64
+ base: {
65
+ flex: 1,
66
+ alignSelf: "stretch",
67
+ width: "100%"
68
+ }
69
+ }));
63
70
  //# sourceMappingURL=EmptyState.variants.js.map
@@ -23,6 +23,7 @@ identity, same reasoning `Divider`/`Avatar` give for theirs.
23
23
  | `title` | `string` | — | Required. Rendered bold, `fg.default`, centred. |
24
24
  | `description` | `string` | — | Optional. Rendered `fg.muted`, centred, below the title. |
25
25
  | `action` | `{ label: string; onPress: () => void }` | — | Optional. Rendered via this library's own `Button` (`tone="accent" variant="solid"`) — a justified composition, same reasoning `AlertDialog` documents for its own footer buttons. |
26
+ | `fill` | `boolean` | `false` | `flex: 1` + centred — fills a list/screen slot without a wrapper. |
26
27
  | `style` | `LayoutStyle` | — | Layout-only, outermost, applied exactly once, last. |
27
28
  | `testID` | `string` | — | Forwarded to the outermost `View`; the icon wrapper (when rendered) gets `${testID}-icon`. |
28
29
 
@@ -20,12 +20,17 @@
20
20
  * documents for its own duplicated `MIN_TOUCH_TARGET`.
21
21
  */
22
22
 
23
- import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
24
- import { ActivityIndicator, Animated, Platform, Pressable, StyleSheet, Text, View } from "react-native";
25
- import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
23
+ import { memo, useCallback, useMemo, useState } from "react";
24
+ import { ActivityIndicator, Platform, Pressable, StyleSheet, Text, View } from "react-native";
25
+ import Animated from "react-native-reanimated";
26
+ import { usePressState } from "../../core/motion/usePressState.js";
26
27
  import { Icon } from "../../core/icon/index.js";
28
+ import { AccentGradientFill } from "../../core/gradient/index.js";
29
+ import { elevation, floatingSurfaceStyle, highlight } from "../../theme/platform/index.js";
30
+ import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
31
+ import { rippleColor } from "../../theme/platform/stateLayer.native.js";
27
32
  import { useTheme } from "../../theme/hooks.js";
28
- import { fabCircleStructure, fabExtendedStructure, FAB_SIZES, resolveFabAccessibility, resolveFabAnchorStyle, resolveFabBottomInset, resolveFabFocusRingStyle, resolveFabHorizontalInset, resolveFabTone } from "./Fab.variants.js";
33
+ import { fabCircleStructure, fabExtendedStructure, fabOverlayColor, FAB_SIZES, resolveFabAccessibility, resolveFabAnchorStyle, resolveFabBottomInset, resolveFabFocusRingStyle, resolveFabHorizontalInset, resolveFabTone } from "./Fab.variants.js";
29
34
 
30
35
  /** A Fab with a visible text label — the EXTENDED variant (a pill, icon + text). */
31
36
 
@@ -34,19 +39,6 @@ import { fabCircleStructure, fabExtendedStructure, FAB_SIZES, resolveFabAccessib
34
39
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
35
40
  const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
36
41
  const ICON_STROKE = 2;
37
- // State-layer scrims — direction chosen by the label's brightness so the fill moves AWAY from the
38
- // label on press (its contrast can only rise), the identical technique `Button.tsx` uses.
39
- const PRESS_SCRIM_DARK = "#00000026";
40
- const PRESS_SCRIM_LIGHT = "#ffffff26";
41
-
42
- /** Cheap perceived-brightness split; `onFill` is only ever a near-white or near-black role value. */
43
- function isLight(hex) {
44
- const n = parseInt(hex.slice(1, 7), 16);
45
- const r = n >> 16 & 0xff;
46
- const g = n >> 8 & 0xff;
47
- const b = n & 0xff;
48
- return r * 0.299 + g * 0.587 + b * 0.114 > 140;
49
- }
50
42
  function FabImpl(props) {
51
43
  const {
52
44
  icon,
@@ -71,10 +63,8 @@ function FabImpl(props) {
71
63
  "aria-describedby": ariaDescribedBy
72
64
  } = props;
73
65
  const theme = useTheme();
74
- const motion = useMotion();
75
- // One value drives both the state-layer scrim and the press scale, so they can never desync.
76
- const press = useAnimatedValue(0);
77
- const pressAnimation = useRef(null);
66
+ const blocked = disabled || loading;
67
+ const press = usePressState(blocked);
78
68
  // Keyboard / external-keyboard / assistive-tech focus (no-op on pure touch, correct everywhere else).
79
69
  const [focused, setFocused] = useState(false);
80
70
  const spec = FAB_SIZES[size];
@@ -86,7 +76,7 @@ function FabImpl(props) {
86
76
  loading,
87
77
  onPress
88
78
  });
89
- const overlayColor = isLight(toneColors.onFill) ? PRESS_SCRIM_DARK : PRESS_SCRIM_LIGHT;
79
+ const overlayColor = fabOverlayColor(toneColors.onFill);
90
80
  const extended = label !== undefined;
91
81
  const bottomInset = resolveFabBottomInset(theme.space[4], Platform.OS, offset?.bottom ?? 0);
92
82
  const horizontalInset = resolveFabHorizontalInset(theme.space[4], offset?.horizontal ?? 0);
@@ -96,27 +86,10 @@ function FabImpl(props) {
96
86
  horizontalInset,
97
87
  zIndex: theme.zIndices.docked
98
88
  });
99
- const setPressed = useCallback(pressed => {
100
- pressAnimation.current?.stop();
101
- const to = pressed ? 1 : 0;
102
- if (!motion.enabled) {
103
- press.setValue(to);
104
- return;
105
- }
106
- pressAnimation.current = motion.timing(press, to, {
107
- duration: "fast"
108
- });
109
- pressAnimation.current.start();
110
- }, [motion, press]);
111
- useEffect(() => () => pressAnimation.current?.stop(), []);
112
-
113
- // Own state first, then the incoming handler — an outer handler that throws can never strand the
114
- // press/focus ring in its active state.
115
- const handlePressIn = useCallback(() => setPressed(true), [setPressed]);
116
89
  const handlePressOut = useCallback(event => {
117
- setPressed(false);
90
+ press.handlers.onPressOut();
118
91
  onPressOut?.(event);
119
- }, [setPressed, onPressOut]);
92
+ }, [press.handlers, onPressOut]);
120
93
  const handleFocus = useCallback(event => {
121
94
  setFocused(true);
122
95
  onFocus?.(event);
@@ -125,14 +98,22 @@ function FabImpl(props) {
125
98
  setFocused(false);
126
99
  onBlur?.(event);
127
100
  }, [onBlur]);
128
- const pressScale = useMemo(() => press.interpolate({
129
- inputRange: [0, 1],
130
- outputRange: [1, motion.transform.pressScale]
131
- }), [press, motion.transform.pressScale]);
132
101
  const focusRingStyle = useMemo(() => resolveFabFocusRingStyle(theme.colors.border.focus, theme.radii.full), [theme.colors.border.focus, theme.radii.full]);
102
+ const floatingDepth = useMemo(() => {
103
+ highlight("subtle", theme.mode);
104
+ elevation(elevationTokens.md);
105
+ void theme.elevatedSurfaces;
106
+ return floatingSurfaceStyle(theme, "md");
107
+ }, [theme]);
108
+ const androidRipple = useMemo(() => {
109
+ if (Platform.OS !== "android" || blocked) return undefined;
110
+ return {
111
+ color: rippleColor(theme.mode),
112
+ borderless: !extended
113
+ };
114
+ }, [blocked, theme.mode, extended]);
133
115
 
134
- // The spinner is never the sole loading signal `aria-busy` announces it. Hidden from AT so it
135
- // isn't read as a separate element, the same contract Button's own spinner has.
116
+ // aria-busy already announces loading; the spinner itself is hidden from AT.
136
117
  const content = loading ? /*#__PURE__*/_jsx(ActivityIndicator, {
137
118
  size: "small",
138
119
  color: toneColors.onFill,
@@ -157,32 +138,31 @@ function FabImpl(props) {
157
138
  disabled: a11y.disabled,
158
139
  onPress: a11y.onPress,
159
140
  onLongPress: onLongPress,
160
- onPressIn: handlePressIn,
141
+ onPressIn: press.handlers.onPressIn,
161
142
  onPressOut: handlePressOut,
162
143
  onHoverIn: onHoverIn,
163
144
  onHoverOut: onHoverOut,
164
145
  onFocus: handleFocus,
165
146
  onBlur: handleBlur,
147
+ onLayout: press.onLayout,
148
+ android_ripple: androidRipple,
166
149
  style: [extended ? fabExtendedStructure(theme, {
167
150
  size
168
151
  }) : fabCircleStructure(theme, {
169
152
  size
170
153
  }), {
171
- backgroundColor: toneColors.fill,
172
- transform: [{
173
- scale: pressScale
174
- }]
175
- }, (disabled || loading) && styles.dimmed, theme.elevation.lg],
176
- children: [/*#__PURE__*/_jsx(Animated.View, {
177
- pointerEvents: "none"
178
- // Matches the control's own radius: the control isn't `overflow: hidden` (that would clip
179
- // the focus ring below), so the state layer rounds itself instead of showing square corners.
180
- ,
154
+ overflow: "hidden",
155
+ ...floatingDepth
156
+ }, press.animatedStyle, (disabled || loading) && styles.dimmed],
157
+ children: [/*#__PURE__*/_jsx(AccentGradientFill, {
158
+ color: toneColors.fill
159
+ }), /*#__PURE__*/_jsx(Animated.View, {
160
+ pointerEvents: "none",
181
161
  style: [StyleSheet.absoluteFill, {
182
162
  backgroundColor: overlayColor,
183
- opacity: press,
184
- borderRadius: theme.radii.full
185
- }]
163
+ borderRadius: theme.radii.full,
164
+ borderCurve: "continuous"
165
+ }, press.overlayStyle]
186
166
  }), focused && /*#__PURE__*/_jsx(View, {
187
167
  pointerEvents: "none",
188
168
  testID: testID ? `${testID}-focus-ring` : undefined,
@@ -71,6 +71,20 @@ export function resolveFabTone(colors, tone) {
71
71
  };
72
72
  }
73
73
  }
74
+ const FAB_PRESS_SCRIM_DARK = "#00000026";
75
+ const FAB_PRESS_SCRIM_LIGHT = "#ffffff26";
76
+ function isLightOnFill(hex) {
77
+ const n = parseInt(hex.slice(1, 7), 16);
78
+ const r = n >> 16 & 0xff;
79
+ const g = n >> 8 & 0xff;
80
+ const b = n & 0xff;
81
+ return r * 0.299 + g * 0.587 + b * 0.114 > 140;
82
+ }
83
+
84
+ /** Press scrim direction, chosen by brightness — shared by `Fab` and `FabGroup`'s trigger. */
85
+ export function fabOverlayColor(onFill) {
86
+ return isLightOnFill(onFill) ? FAB_PRESS_SCRIM_DARK : FAB_PRESS_SCRIM_LIGHT;
87
+ }
74
88
  /**
75
89
  * Same disabled/loading→busy, gated-onPress derivation as `resolveButtonAccessibility` (WCAG 1.4.1
76
90
  * busy announcement / 4.1.2 name-role-value), kept pure so it's testable without rendering RN.
@@ -338,7 +352,7 @@ export const fabGroupActionCircleStructure = createThemedVariants(theme => ({
338
352
  * "selection/emphasis isn't conveyed by a background swap" reasoning `Select`'s row fill documents. */
339
353
  export const fabGroupActionLabelStructure = createThemedVariants(theme => ({
340
354
  base: {
341
- borderRadius: theme.radii.base,
355
+ borderRadius: theme.radii.full,
342
356
  paddingHorizontal: theme.space[3],
343
357
  paddingVertical: theme.space[2]
344
358
  }
@@ -31,13 +31,16 @@
31
31
 
32
32
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
33
33
  import { Animated, Platform, Pressable, StyleSheet, Text, View } from "react-native";
34
+ import Reanimated from "react-native-reanimated";
34
35
  import { useDismissOnEscape, useFocusTrap } from "../../core/a11y/keyboard";
35
36
  import { Icon } from "../../core/icon/index.js";
36
- import { useAnimatedValue, useMotion, usePressMotion } from "../../core/motion/index.js";
37
+ import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
38
+ import { usePressState } from "../../core/motion/usePressState.js";
39
+ import { rippleColor } from "../../theme/platform/stateLayer.native.js";
37
40
  import { useTheme } from "../../theme/hooks.js";
38
- import { fabCircleStructure, FAB_ACTION_ICON_SIZE, fabGroupActionCircleStructure, fabGroupActionLabelStructure, fabGroupActionRowStructure, fabGroupActionsStackStructure, FAB_GROUP_SCRIM, FAB_SIZES, resolveFabAccessibility, resolveFabAnchorStyle, resolveFabBottomInset, resolveFabFocusRingStyle, resolveFabGroupActionDirection, resolveFabGroupActionWindow, resolveFabGroupStackAlign, resolveFabGroupTriggerAccessibilityLabel, resolveFabHorizontalInset, resolveFabTone } from "./Fab.variants.js";
41
+ import { fabCircleStructure, fabOverlayColor, FAB_ACTION_ICON_SIZE, fabGroupActionCircleStructure, fabGroupActionLabelStructure, fabGroupActionRowStructure, fabGroupActionsStackStructure, FAB_GROUP_SCRIM, FAB_SIZES, resolveFabAccessibility, resolveFabAnchorStyle, resolveFabBottomInset, resolveFabFocusRingStyle, resolveFabGroupActionDirection, resolveFabGroupActionWindow, resolveFabGroupStackAlign, resolveFabGroupTriggerAccessibilityLabel, resolveFabHorizontalInset, resolveFabTone } from "./Fab.variants.js";
39
42
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
40
- const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
43
+ const AnimatedPressable = Reanimated.createAnimatedComponent(Pressable);
41
44
  const ICON_STROKE = 2;
42
45
  const ACTION_ICON_STROKE = 2;
43
46
  const DEFAULT_ICON = "plus";
@@ -66,7 +69,7 @@ function FabGroupActionRowImpl({
66
69
  }) {
67
70
  const theme = useTheme();
68
71
  const motion = useMotion();
69
- const pressMotion = usePressMotion();
72
+ const press = usePressState();
70
73
  const colors = resolveFabTone(theme.colors, action.tone ?? fallbackTone);
71
74
  const handlePress = useCallback(() => onSelect(action), [onSelect, action]);
72
75
  const [start, end] = window;
@@ -80,49 +83,59 @@ function FabGroupActionRowImpl({
80
83
  outputRange: [motion.transform.offsetY, 0],
81
84
  extrapolate: "clamp"
82
85
  }), [progress, start, end, motion.transform.offsetY]);
83
- const pressOpacity = pressMotion.style.opacity;
84
- const pressScale = pressMotion.style.transform[0].scale;
85
- const opacity = useMemo(() => Animated.multiply(revealOpacity, pressOpacity), [revealOpacity, pressOpacity]);
86
- const transform = useMemo(() => [{
87
- translateY
88
- }, {
89
- scale: pressScale
90
- }], [translateY, pressScale]);
91
- return /*#__PURE__*/_jsxs(AnimatedPressable, {
92
- testID: testID,
93
- accessibilityRole: "button",
94
- accessibilityLabel: action.label,
95
- onPress: handlePress,
96
- onPressIn: pressMotion.onPressIn,
97
- onPressOut: pressMotion.onPressOut,
98
- style: [fabGroupActionRowStructure(theme), {
99
- flexDirection: direction,
100
- opacity,
101
- transform
102
- }],
103
- children: [/*#__PURE__*/_jsx(View, {
104
- style: [fabGroupActionLabelStructure(theme), {
105
- backgroundColor: theme.colors.bg.raised
106
- }, theme.elevation.sm],
107
- children: /*#__PURE__*/_jsx(Text, {
108
- numberOfLines: 1,
109
- style: [theme.fontStyleForWeight(theme.fontWeights.medium), {
110
- fontSize: theme.fontSizes.sm,
111
- color: theme.colors.fg.default
112
- }],
113
- children: action.label
114
- })
115
- }), /*#__PURE__*/_jsx(View, {
116
- style: [fabGroupActionCircleStructure(theme), {
117
- backgroundColor: colors.fill
118
- }, theme.elevation.md],
119
- children: /*#__PURE__*/_jsx(Icon, {
120
- name: action.icon,
121
- size: FAB_ACTION_ICON_SIZE,
122
- color: colors.onFill,
123
- strokeWidth: ACTION_ICON_STROKE
124
- })
125
- })]
86
+ const revealStyle = useMemo(() => ({
87
+ opacity: revealOpacity,
88
+ transform: [{
89
+ translateY
90
+ }]
91
+ }), [revealOpacity, translateY]);
92
+ const androidRipple = useMemo(() => {
93
+ if (Platform.OS !== "android") return undefined;
94
+ return {
95
+ color: rippleColor(theme.mode),
96
+ borderless: false
97
+ };
98
+ }, [theme.mode]);
99
+
100
+ // Reveal (classic Animated) nests press feedback (Reanimated `usePressState`) — fades compose.
101
+ return /*#__PURE__*/_jsx(Animated.View, {
102
+ style: revealStyle,
103
+ children: /*#__PURE__*/_jsxs(AnimatedPressable, {
104
+ testID: testID,
105
+ accessibilityRole: "button",
106
+ accessibilityLabel: action.label,
107
+ onPress: handlePress,
108
+ onPressIn: press.handlers.onPressIn,
109
+ onPressOut: press.handlers.onPressOut,
110
+ onLayout: press.onLayout,
111
+ android_ripple: androidRipple,
112
+ style: [fabGroupActionRowStructure(theme), {
113
+ flexDirection: direction
114
+ }, press.animatedStyle],
115
+ children: [/*#__PURE__*/_jsx(View, {
116
+ style: [fabGroupActionLabelStructure(theme), {
117
+ backgroundColor: theme.colors.bg.raised
118
+ }, theme.elevation.sm],
119
+ children: /*#__PURE__*/_jsx(Text, {
120
+ numberOfLines: 1,
121
+ style: [theme.fontStyleForWeight(theme.fontWeights.medium), {
122
+ fontSize: theme.fontSizes.sm,
123
+ color: theme.colors.fg.default
124
+ }],
125
+ children: action.label
126
+ })
127
+ }), /*#__PURE__*/_jsx(View, {
128
+ style: [fabGroupActionCircleStructure(theme), {
129
+ backgroundColor: colors.fill
130
+ }, theme.elevation.md],
131
+ children: /*#__PURE__*/_jsx(Icon, {
132
+ name: action.icon,
133
+ size: FAB_ACTION_ICON_SIZE,
134
+ color: colors.onFill,
135
+ strokeWidth: ACTION_ICON_STROKE
136
+ })
137
+ })]
138
+ })
126
139
  });
127
140
  }
128
141
  const FabGroupActionRow = /*#__PURE__*/memo(FabGroupActionRowImpl);
@@ -237,10 +250,17 @@ function FabGroupImpl({
237
250
  inputRange: [0, 1],
238
251
  outputRange: ["0deg", "45deg"]
239
252
  }), [progress]);
240
- const triggerPress = usePressMotion(disabled);
253
+ const triggerPress = usePressState(disabled);
254
+ const triggerOverlayColor = fabOverlayColor(triggerColors.onFill);
255
+ const triggerRipple = useMemo(() => {
256
+ if (Platform.OS !== "android" || disabled) return undefined;
257
+ return {
258
+ color: rippleColor(theme.mode),
259
+ borderless: true
260
+ };
261
+ }, [disabled, theme.mode]);
241
262
 
242
- // Keyboard / external-keyboard / assistive-tech focus, identical to `Fab`'s the trigger is the
243
- // same circular control, so the ring geometry is shared rather than re-derived.
263
+ // Same circular control as `Fab`, so the ring geometry is shared, not re-derived.
244
264
  const [focused, setFocused] = useState(false);
245
265
  const handleFocus = useCallback(() => setFocused(true), []);
246
266
  const handleBlur = useCallback(() => setFocused(false), []);
@@ -285,18 +305,25 @@ function FabGroupImpl({
285
305
  "aria-expanded": expanded,
286
306
  disabled: a11y.disabled,
287
307
  onPress: a11y.onPress,
288
- onPressIn: triggerPress.onPressIn,
289
- onPressOut: triggerPress.onPressOut,
308
+ onPressIn: triggerPress.handlers.onPressIn,
309
+ onPressOut: triggerPress.handlers.onPressOut,
290
310
  onFocus: handleFocus,
291
311
  onBlur: handleBlur,
312
+ onLayout: triggerPress.onLayout,
313
+ android_ripple: triggerRipple,
292
314
  style: [fabCircleStructure(theme, {
293
315
  size
294
316
  }), {
295
- backgroundColor: triggerColors.fill,
296
- opacity: triggerPress.style.opacity,
297
- transform: triggerPress.style.transform
298
- }, disabled && styles.dimmed, theme.elevation.lg],
299
- children: [focused && /*#__PURE__*/_jsx(View, {
317
+ backgroundColor: triggerColors.fill
318
+ }, triggerPress.animatedStyle, disabled && styles.dimmed, theme.elevation.lg],
319
+ children: [/*#__PURE__*/_jsx(Reanimated.View, {
320
+ pointerEvents: "none",
321
+ style: [StyleSheet.absoluteFill, {
322
+ backgroundColor: triggerOverlayColor,
323
+ borderRadius: theme.radii.full,
324
+ borderCurve: "continuous"
325
+ }, triggerPress.overlayStyle]
326
+ }), focused && /*#__PURE__*/_jsx(View, {
300
327
  pointerEvents: "none",
301
328
  testID: testID ? `${testID}-trigger-focus-ring` : undefined,
302
329
  style: focusRingStyle
@@ -125,6 +125,11 @@ its trigger is not a tooltip target.
125
125
 
126
126
  ## Known gaps
127
127
 
128
+ - **Fab's own focus ring can be clipped by its `overflow: "hidden"`** — the ring is drawn with
129
+ negative offsets outside the control's own bounds, and the Pressable clips to its own rect. Found
130
+ in the Round 5 Android-parity pass, not fixed here (unrelated to that pass's scope). FabGroup's
131
+ trigger avoids this: it carries no `overflow: "hidden"`, since its overlay self-clips via its own
132
+ `borderRadius`.
128
133
  - **No safe-area inset awareness** beyond the static iOS home-indicator approximation (see pattern
129
134
  #3) — same documented gap `Toast`/`Drawer`/`BottomNav` already carry.
130
135
  - **No focus ring on the mini action ROWS.** The trigger reached parity with `Fab` (identical
@@ -153,16 +158,18 @@ Nothing in this module owns a duration, easing or `Animated.timing` config — a
153
158
  `useMotion()` / `usePressMotion()` in `core/motion`, so retuning `core/motion/config.ts` retunes the
154
159
  Fab too. Everything animates `opacity`/`transform` only, always on the native driver.
155
160
 
156
- - **Fab press** — one `Animated.Value` drives both the tone-aware state-layer scrim and the press
157
- scale (`motion.transform.pressScale`), so the two can never desync.
158
- - **FabGroup expand/collapse** one `progress` value; the trigger glyph rotates 0→45°, the scrim
159
- fades, and each action row reveals over its own slice of that same value.
161
+ - **Press feedback** — Fab, the FabGroup trigger, and each action row all use `usePressState`
162
+ (`core/motion/usePressState`), the same width-aware scale + state-layer overlay + spring settle
163
+ every other pressable in this library uses (Round 5 press-feedback unification).
164
+ - **FabGroup expand/collapse** one classic `progress` value; the trigger glyph rotates 0→45°, the
165
+ scrim fades, and each action row reveals over its own slice of that same value.
160
166
  - **The action stagger is decorative** (`motion.decorative`, high tier only). It is expressed as a
161
167
  per-row interpolation *window* (`resolveFabGroupActionWindow`), not per-row animations: no extra
162
168
  timers or `Animated.Value`s, and it reverses correctly on close. On low/mid tier every row shares
163
169
  the full `[0, 1]` window and the rows reveal together.
164
- - **Action rows and the trigger** use `usePressMotion`; a row's reveal opacity and its press opacity
165
- are combined with `Animated.multiply` rather than fighting over the same style key.
170
+ - **Action rows nest two animation systems**: an outer classic-`Animated.View` reveal (opacity +
171
+ translateY, tied to `progress`) wraps the inner `usePressState`-driven `AnimatedPressable` the
172
+ two fades compose by nesting instead of `Animated.multiply`.
166
173
  - In-flight animations are stopped on effect cleanup and on unmount.
167
174
 
168
175
  ## Performance
@@ -179,3 +186,9 @@ identical "sheet content built only while open" convention.
179
186
  - Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
180
187
  - List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
181
188
  - `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
189
+
190
+ - **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
191
+ - **Round 5 (Android parity + press unification)** — Fab, the trigger, and action rows switched from
192
+ hand-rolled classic-`Animated` press timing to the shared `usePressState`; `android_ripple` added
193
+ everywhere it was missing (`borderless: true` on the two circular icon-only targets, `false`
194
+ elsewhere); the trigger gained a press-state overlay matching Fab's own.