@astryxdesign/core 0.7.5-canary.fccd771 → 0.7.5

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 (1346) hide show
  1. package/CHANGELOG.md +211 -10
  2. package/README.md +15 -12
  3. package/dist/AlertDialog/AlertDialog.js +1 -1
  4. package/dist/AppShell/AppShell.d.ts +0 -22
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +155 -1
  7. package/dist/Avatar/AvatarStatusDot.js +2 -2
  8. package/dist/Badge/Badge.d.ts.map +1 -1
  9. package/dist/Badge/Badge.js +18 -2
  10. package/dist/Banner/Banner.d.ts +1 -0
  11. package/dist/Banner/Banner.d.ts.map +1 -1
  12. package/dist/Banner/Banner.js +64 -9
  13. package/dist/BottomSheet/BottomSheet.d.ts +53 -5
  14. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  15. package/dist/BottomSheet/BottomSheet.js +435 -198
  16. package/dist/BottomSheet/BottomSheetHostContext.d.ts +8 -0
  17. package/dist/BottomSheet/BottomSheetHostContext.d.ts.map +1 -0
  18. package/dist/BottomSheet/BottomSheetHostContext.js +35 -0
  19. package/dist/BottomSheet/BottomSheetPanel.d.ts +9 -1
  20. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  21. package/dist/BottomSheet/BottomSheetPanel.js +77 -23
  22. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +53 -14
  23. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  24. package/dist/BottomSheet/BottomSheetSwitcher.js +229 -27
  25. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +6 -0
  26. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
  27. package/dist/BottomSheet/bottomSheetEscape.d.ts +3 -0
  28. package/dist/BottomSheet/bottomSheetEscape.d.ts.map +1 -0
  29. package/dist/BottomSheet/bottomSheetEscape.js +20 -0
  30. package/dist/BottomSheet/bottomSheetStack.d.ts +262 -0
  31. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -0
  32. package/dist/BottomSheet/bottomSheetStack.js +1675 -0
  33. package/dist/BottomSheet/useSheetGestures.d.ts +19 -3
  34. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  35. package/dist/BottomSheet/useSheetGestures.js +43 -14
  36. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  37. package/dist/Breadcrumbs/BreadcrumbItem.js +36 -3
  38. package/dist/Button/Button.d.ts.map +1 -1
  39. package/dist/Button/Button.js +18 -7
  40. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  41. package/dist/Chat/ChatComposer.js +25 -32
  42. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposerInput.js +55 -16
  44. package/dist/Chat/ChatMessageMetadata.js +2 -2
  45. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  46. package/dist/Chat/ChatPastedTextToken.js +7 -6
  47. package/dist/Chat/ChatToolCalls.js +4 -4
  48. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  49. package/dist/ClickableCard/ClickableCard.js +10 -6
  50. package/dist/CodeBlock/CodeBlock.d.ts +25 -2
  51. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  52. package/dist/CodeBlock/CodeBlock.js +58 -19
  53. package/dist/CodeBlock/grammar.d.ts +134 -0
  54. package/dist/CodeBlock/grammar.d.ts.map +1 -0
  55. package/dist/CodeBlock/grammar.js +219 -0
  56. package/dist/CodeBlock/index.d.ts +2 -0
  57. package/dist/CodeBlock/index.d.ts.map +1 -1
  58. package/dist/CodeBlock/index.js +1 -0
  59. package/dist/CodeBlock/languages/dockerfile.d.ts +3 -0
  60. package/dist/CodeBlock/languages/dockerfile.d.ts.map +1 -0
  61. package/dist/CodeBlock/languages/dockerfile.js +45 -0
  62. package/dist/CodeBlock/languages/graphql.d.ts +3 -0
  63. package/dist/CodeBlock/languages/graphql.d.ts.map +1 -0
  64. package/dist/CodeBlock/languages/graphql.js +27 -0
  65. package/dist/CodeBlock/languages/java.d.ts +3 -0
  66. package/dist/CodeBlock/languages/java.d.ts.map +1 -0
  67. package/dist/CodeBlock/languages/java.js +24 -0
  68. package/dist/CodeBlock/languages/lua.d.ts +3 -0
  69. package/dist/CodeBlock/languages/lua.d.ts.map +1 -0
  70. package/dist/CodeBlock/languages/lua.js +21 -0
  71. package/dist/CodeBlock/languages/objective-c.d.ts +3 -0
  72. package/dist/CodeBlock/languages/objective-c.d.ts.map +1 -0
  73. package/dist/CodeBlock/languages/objective-c.js +27 -0
  74. package/dist/CodeBlock/languages/powershell.d.ts +3 -0
  75. package/dist/CodeBlock/languages/powershell.d.ts.map +1 -0
  76. package/dist/CodeBlock/languages/powershell.js +30 -0
  77. package/dist/CodeBlock/languages/ruby.d.ts +3 -0
  78. package/dist/CodeBlock/languages/ruby.d.ts.map +1 -0
  79. package/dist/CodeBlock/languages/ruby.js +24 -0
  80. package/dist/CodeBlock/languages/thrift.d.ts +3 -0
  81. package/dist/CodeBlock/languages/thrift.d.ts.map +1 -0
  82. package/dist/CodeBlock/languages/thrift.js +18 -0
  83. package/dist/CodeBlock/languages/toml.d.ts +3 -0
  84. package/dist/CodeBlock/languages/toml.d.ts.map +1 -0
  85. package/dist/CodeBlock/languages/toml.js +53 -0
  86. package/dist/CodeBlock/tokenizer.d.ts +8 -4
  87. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  88. package/dist/CodeBlock/tokenizer.js +158 -8
  89. package/dist/Collapsible/Collapsible.d.ts +8 -1
  90. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  91. package/dist/Collapsible/Collapsible.js +84 -2
  92. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  93. package/dist/CommandPalette/CommandPalette.js +15 -1
  94. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  95. package/dist/CommandPalette/CommandPaletteEmpty.js +1 -0
  96. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  97. package/dist/CommandPalette/CommandPaletteInput.js +14 -2
  98. package/dist/CommandPalette/busyStartSettle.d.ts +4 -0
  99. package/dist/CommandPalette/busyStartSettle.d.ts.map +1 -0
  100. package/dist/CommandPalette/busyStartSettle.js +23 -0
  101. package/dist/ComplexSelector/ComplexSelector.d.ts +20 -2
  102. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  103. package/dist/ComplexSelector/ComplexSelector.js +42 -7
  104. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  105. package/dist/ContextMenu/ContextMenu.js +48 -13
  106. package/dist/DateInput/DateInput.d.ts.map +1 -1
  107. package/dist/DateInput/DateInput.js +12 -5
  108. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  109. package/dist/DateInput/NativeDateField.js +2 -1
  110. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  111. package/dist/DateInput/TouchDateField.js +2 -1
  112. package/dist/DateInput/Wheel.d.ts.map +1 -1
  113. package/dist/DateInput/Wheel.js +1 -1
  114. package/dist/Dialog/Dialog.d.ts +4 -0
  115. package/dist/Dialog/Dialog.d.ts.map +1 -1
  116. package/dist/Dialog/Dialog.js +20 -8
  117. package/dist/Drawer/Drawer.d.ts.map +1 -1
  118. package/dist/Drawer/Drawer.js +18 -13
  119. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  120. package/dist/DropdownMenu/DropdownMenu.js +34 -30
  121. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +7 -4
  122. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  123. package/dist/DropdownMenu/DropdownMenuGroup.js +10 -4
  124. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  125. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +10 -5
  126. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  127. package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
  128. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -6
  129. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  130. package/dist/DropdownMenu/DropdownMenuSubMenu.js +0 -3
  131. package/dist/DropdownMenu/MenuBottomSheet.d.ts +11 -4
  132. package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -1
  133. package/dist/DropdownMenu/MenuBottomSheet.js +35 -9
  134. package/dist/DropdownMenu/MenuBottomSheetActionList.js +3 -3
  135. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +2 -0
  136. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  137. package/dist/DropdownMenu/lazyMenuBottomSheet.js +25 -3
  138. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts +23 -0
  139. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts.map +1 -0
  140. package/dist/DropdownMenu/menuBottomSheet.stylex.js +29 -0
  141. package/dist/DropdownMenu/menuItemHover.d.ts +3 -0
  142. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -1
  143. package/dist/DropdownMenu/menuItemHover.js +14 -1
  144. package/dist/DropdownMenu/menuTouchAction.stylex.d.ts +25 -0
  145. package/dist/DropdownMenu/menuTouchAction.stylex.d.ts.map +1 -0
  146. package/dist/DropdownMenu/menuTouchAction.stylex.js +29 -0
  147. package/dist/DropdownMenu/useMenuDrillIn.d.ts.map +1 -1
  148. package/dist/DropdownMenu/useMenuDrillIn.js +7 -5
  149. package/dist/EmptyState/EmptyState.d.ts +4 -2
  150. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  151. package/dist/EmptyState/EmptyState.js +6 -4
  152. package/dist/Field/Field.js +1 -1
  153. package/dist/Field/FieldLabel.js +1 -1
  154. package/dist/Field/PanelSearchInput.d.ts +9 -1
  155. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  156. package/dist/Field/PanelSearchInput.js +31 -22
  157. package/dist/Field/inputDisabledFocus.d.ts +14 -0
  158. package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
  159. package/dist/Field/inputDisabledFocus.js +19 -0
  160. package/dist/Field/inputStyles.stylex.d.ts +9 -9
  161. package/dist/Field/inputStyles.stylex.js +9 -9
  162. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  163. package/dist/FieldStatus/FieldStatus.js +7 -3
  164. package/dist/FileInput/FileInput.d.ts.map +1 -1
  165. package/dist/FileInput/FileInput.js +22 -12
  166. package/dist/Icon/Icon.d.ts +37 -5
  167. package/dist/Icon/Icon.d.ts.map +1 -1
  168. package/dist/Icon/Icon.js +65 -11
  169. package/dist/Icon/IconSize.stylex.d.ts +16 -11
  170. package/dist/Icon/IconSize.stylex.d.ts.map +1 -1
  171. package/dist/Icon/IconSize.stylex.js +27 -11
  172. package/dist/Icon/globalIconRegistry.d.ts +71 -4
  173. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  174. package/dist/Icon/globalIconRegistry.js +163 -23
  175. package/dist/Icon/index.d.ts +26 -2
  176. package/dist/Icon/index.d.ts.map +1 -1
  177. package/dist/Icon/index.js +24 -1
  178. package/dist/Icon/useIcon.d.ts +5 -1
  179. package/dist/Icon/useIcon.d.ts.map +1 -1
  180. package/dist/Icon/useIcon.js +5 -1
  181. package/dist/InputGroup/InputGroup.d.ts +1 -1
  182. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  183. package/dist/InputGroup/InputGroup.js +46 -36
  184. package/dist/InputGroup/InputGroupInternalContext.d.ts +4 -0
  185. package/dist/InputGroup/InputGroupInternalContext.d.ts.map +1 -0
  186. package/dist/InputGroup/InputGroupInternalContext.js +15 -0
  187. package/dist/InputGroup/InputGroupText.d.ts.map +1 -1
  188. package/dist/InputGroup/InputGroupText.js +2 -0
  189. package/dist/InputGroup/groupStyles.d.ts +9 -0
  190. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  191. package/dist/InputGroup/groupStyles.js +28 -14
  192. package/dist/Item/Item.d.ts +5 -1
  193. package/dist/Item/Item.d.ts.map +1 -1
  194. package/dist/Item/Item.js +23 -7
  195. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts +2 -0
  196. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts.map +1 -0
  197. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.js +132 -0
  198. package/dist/Item/ItemMarkerColumnsContext.d.ts +14 -0
  199. package/dist/Item/ItemMarkerColumnsContext.d.ts.map +1 -0
  200. package/dist/Item/ItemMarkerColumnsContext.js +18 -0
  201. package/dist/Item/ItemSwipeLayer.d.ts.map +1 -1
  202. package/dist/Item/ItemSwipeLayer.js +3 -0
  203. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  204. package/dist/Item/useSwipeAction.js +60 -5
  205. package/dist/Kbd/Kbd.d.ts +2 -2
  206. package/dist/Kbd/Kbd.d.ts.map +1 -1
  207. package/dist/Kbd/Kbd.js +18 -11
  208. package/dist/Layer/layerAnimations.stylex.d.ts +9 -5
  209. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  210. package/dist/Layer/layerAnimations.stylex.js +23 -10
  211. package/dist/Layer/layerSlideRules.d.ts +62 -2
  212. package/dist/Layer/layerSlideRules.d.ts.map +1 -1
  213. package/dist/Layer/layerSlideRules.js +124 -3
  214. package/dist/Layer/layerStack.d.ts +12 -9
  215. package/dist/Layer/layerStack.d.ts.map +1 -1
  216. package/dist/Layer/layerStack.js +116 -53
  217. package/dist/Layer/modalOutlet.d.ts +44 -6
  218. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  219. package/dist/Layer/modalOutlet.js +150 -14
  220. package/dist/Layer/preserveAnimations.d.ts +11 -0
  221. package/dist/Layer/preserveAnimations.d.ts.map +1 -0
  222. package/dist/Layer/preserveAnimations.js +245 -0
  223. package/dist/Layer/useLayer.d.ts +19 -2
  224. package/dist/Layer/useLayer.d.ts.map +1 -1
  225. package/dist/Layer/useLayer.js +531 -44
  226. package/dist/Layer/useLayerDismissal.d.ts +10 -7
  227. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  228. package/dist/Layer/useLayerDismissal.js +8 -8
  229. package/dist/Layer/useTouchTrigger.d.ts +14 -1
  230. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  231. package/dist/Layer/useTouchTrigger.js +72 -17
  232. package/dist/Layout/Layout.d.ts.map +1 -1
  233. package/dist/Layout/Layout.js +4 -0
  234. package/dist/Layout/LayoutContent.d.ts.map +1 -1
  235. package/dist/Layout/LayoutContent.js +2 -2
  236. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  237. package/dist/Layout/LayoutFooter.js +2 -1
  238. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  239. package/dist/Layout/LayoutHeader.js +2 -1
  240. package/dist/Layout/layoutEdges.stylex.d.ts +20 -0
  241. package/dist/Layout/layoutEdges.stylex.d.ts.map +1 -0
  242. package/dist/Layout/layoutEdges.stylex.js +28 -0
  243. package/dist/Lightbox/Lightbox.d.ts +5 -2
  244. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  245. package/dist/Lightbox/Lightbox.js +111 -89
  246. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +2 -0
  247. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts.map +1 -0
  248. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +78 -0
  249. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +2 -0
  250. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts.map +1 -0
  251. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +65 -0
  252. package/dist/List/List.d.ts +2 -1
  253. package/dist/List/List.d.ts.map +1 -1
  254. package/dist/List/List.js +9 -2
  255. package/dist/List/ListContext.d.ts +16 -4
  256. package/dist/List/ListContext.d.ts.map +1 -1
  257. package/dist/List/ListContext.js +10 -5
  258. package/dist/List/ListItem.d.ts +7 -1
  259. package/dist/List/ListItem.d.ts.map +1 -1
  260. package/dist/List/ListItem.js +52 -8
  261. package/dist/List/ListMarkers.a11y.chromium.spec.d.ts +2 -0
  262. package/dist/List/ListMarkers.a11y.chromium.spec.d.ts.map +1 -0
  263. package/dist/List/ListMarkers.a11y.chromium.spec.js +677 -0
  264. package/dist/Markdown/Markdown.d.ts +11 -1
  265. package/dist/Markdown/Markdown.d.ts.map +1 -1
  266. package/dist/Markdown/Markdown.fr23.bench.js +3 -1
  267. package/dist/Markdown/Markdown.fr23.sampling.d.ts +16 -0
  268. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -1
  269. package/dist/Markdown/Markdown.fr23.sampling.js +13 -4
  270. package/dist/Markdown/Markdown.js +41 -14
  271. package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +1 -0
  272. package/dist/MobileNav/MobileNav.d.ts +2 -1
  273. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  274. package/dist/MobileNav/MobileNav.js +46 -37
  275. package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +1 -0
  276. package/dist/MobileNav/MobileNavToggle.d.ts +7 -3
  277. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  278. package/dist/MobileNav/MobileNavToggle.js +11 -3
  279. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +53 -6
  280. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  281. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  282. package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +1 -0
  283. package/dist/MultiSelector/MultiSelector.js +21 -5
  284. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +1 -0
  285. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  286. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  287. package/dist/NavMenu/NavHeadingMenu.js +29 -5
  288. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  289. package/dist/NavMenu/NavHeadingMenuItem.js +51 -7
  290. package/dist/NavMenu/NavMenuContext.d.ts +9 -0
  291. package/dist/NavMenu/NavMenuContext.d.ts.map +1 -1
  292. package/dist/NavMenu/NavMenuContext.js +9 -0
  293. package/dist/NumberInput/NumberInput.d.ts +4 -4
  294. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  295. package/dist/NumberInput/NumberInput.js +61 -24
  296. package/dist/Overlay/Overlay.d.ts +3 -3
  297. package/dist/Overlay/Overlay.d.ts.map +1 -1
  298. package/dist/Overlay/Overlay.js +12 -5
  299. package/dist/Popover/Popover.d.ts +41 -2
  300. package/dist/Popover/Popover.d.ts.map +1 -1
  301. package/dist/Popover/Popover.js +276 -44
  302. package/dist/Popover/index.d.ts +1 -1
  303. package/dist/Popover/index.d.ts.map +1 -1
  304. package/dist/Popover/lazyPopoverBottomSheet.d.ts +23 -0
  305. package/dist/Popover/lazyPopoverBottomSheet.d.ts.map +1 -0
  306. package/dist/Popover/lazyPopoverBottomSheet.js +40 -0
  307. package/dist/Popover/usePopover.d.ts.map +1 -1
  308. package/dist/Popover/usePopover.js +11 -5
  309. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  310. package/dist/PowerSearch/PowerSearch.js +7 -5
  311. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  312. package/dist/ProgressBar/ProgressBar.js +8 -0
  313. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  314. package/dist/RadioList/RadioListItem.js +10 -2
  315. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  316. package/dist/ScrollableArea/ScrollableArea.js +1 -1
  317. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  318. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  319. package/dist/SegmentedControl/SegmentedControl.js +6 -2
  320. package/dist/SelectableCard/SelectableCard.d.ts +5 -5
  321. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  322. package/dist/SelectableCard/SelectableCard.js +15 -11
  323. package/dist/Selector/Selector.d.ts.map +1 -1
  324. package/dist/Selector/Selector.js +27 -8
  325. package/dist/Selector/hooks.d.ts +52 -6
  326. package/dist/Selector/hooks.d.ts.map +1 -1
  327. package/dist/Selector/hooks.js +145 -2
  328. package/dist/SideNav/SideNav.d.ts.map +1 -1
  329. package/dist/SideNav/SideNav.js +58 -2
  330. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  331. package/dist/SideNav/SideNavHeading.js +79 -3
  332. package/dist/SideNav/SideNavItem.d.ts +5 -1
  333. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  334. package/dist/SideNav/SideNavItem.js +36 -13
  335. package/dist/SideNav/railMotion.d.ts +54 -0
  336. package/dist/SideNav/railMotion.d.ts.map +1 -0
  337. package/dist/SideNav/railMotion.js +253 -0
  338. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  339. package/dist/Skeleton/Skeleton.js +12 -3
  340. package/dist/Slider/Slider.d.ts.map +1 -1
  341. package/dist/Slider/Slider.js +52 -15
  342. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  343. package/dist/StatusDot/StatusDot.js +12 -0
  344. package/dist/Stepper/Step.d.ts.map +1 -1
  345. package/dist/Stepper/Step.js +10 -6
  346. package/dist/Switch/Switch.d.ts.map +1 -1
  347. package/dist/Switch/Switch.js +5 -5
  348. package/dist/Switch/switch.markers.stylex.d.ts +7 -2
  349. package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
  350. package/dist/Switch/switch.markers.stylex.js +8 -3
  351. package/dist/TabList/Tab.d.ts.map +1 -1
  352. package/dist/TabList/Tab.js +5 -1
  353. package/dist/TabList/TabMenu.d.ts.map +1 -1
  354. package/dist/TabList/TabMenu.js +25 -3
  355. package/dist/Table/TableCell.d.ts.map +1 -1
  356. package/dist/Table/TableCell.js +5 -1
  357. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  358. package/dist/Table/TableHeaderCell.js +1 -0
  359. package/dist/Table/TableRow.d.ts.map +1 -1
  360. package/dist/Table/TableRow.js +3 -0
  361. package/dist/Table/glidingDivider.d.ts +96 -0
  362. package/dist/Table/glidingDivider.d.ts.map +1 -0
  363. package/dist/Table/glidingDivider.js +275 -0
  364. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  365. package/dist/Table/plugins/columnResize/useTableColumnResize.js +11 -2
  366. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +8 -0
  367. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  368. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +374 -13
  369. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  370. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +244 -6
  371. package/dist/Table/rowDivider.d.ts +34 -0
  372. package/dist/Table/rowDivider.d.ts.map +1 -0
  373. package/dist/Table/rowDivider.js +118 -0
  374. package/dist/TextArea/TextArea.d.ts +6 -4
  375. package/dist/TextArea/TextArea.d.ts.map +1 -1
  376. package/dist/TextArea/TextArea.js +15 -12
  377. package/dist/TextInput/TextInput.d.ts +7 -5
  378. package/dist/TextInput/TextInput.d.ts.map +1 -1
  379. package/dist/TextInput/TextInput.js +43 -22
  380. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  381. package/dist/Thumbnail/Thumbnail.js +45 -11
  382. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  383. package/dist/TimeInput/TimeInput.js +12 -4
  384. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  385. package/dist/TimeInput/TouchTimeField.js +2 -1
  386. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  387. package/dist/Toast/ToastViewport.js +62 -6
  388. package/dist/Tokenizer/Tokenizer.d.ts +71 -4
  389. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  390. package/dist/Tokenizer/Tokenizer.js +430 -45
  391. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +98 -0
  392. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -0
  393. package/dist/Tokenizer/TokenizerBottomSheet.js +721 -0
  394. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  395. package/dist/Tooltip/useTooltip.js +9 -3
  396. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  397. package/dist/TopNav/TopNavHeading.js +26 -0
  398. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  399. package/dist/TopNav/TopNavMegaMenu.js +4 -4
  400. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  401. package/dist/TopNav/TopNavMenu.js +32 -4
  402. package/dist/TreeList/TreeList.d.ts +8 -23
  403. package/dist/TreeList/TreeList.d.ts.map +1 -1
  404. package/dist/TreeList/TreeList.js +175 -3
  405. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  406. package/dist/TreeList/TreeListBranches.js +7 -5
  407. package/dist/TreeList/TreeListItem.d.ts +7 -1
  408. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  409. package/dist/TreeList/TreeListItem.js +5 -3
  410. package/dist/Typeahead/BaseTypeahead.d.ts +1 -1
  411. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  412. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts +2 -0
  413. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts.map +1 -0
  414. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.js +118 -0
  415. package/dist/Typeahead/BaseTypeahead.js +27 -11
  416. package/dist/Typeahead/Typeahead.d.ts +1 -1
  417. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  418. package/dist/Typeahead/Typeahead.js +31 -14
  419. package/dist/astryx.css +164 -41
  420. package/dist/gestures/GestureArena.d.ts +175 -0
  421. package/dist/gestures/GestureArena.d.ts.map +1 -0
  422. package/dist/gestures/GestureArena.js +816 -0
  423. package/dist/gestures/GestureRecognizer.d.ts +239 -0
  424. package/dist/gestures/GestureRecognizer.d.ts.map +1 -0
  425. package/dist/gestures/GestureRecognizer.js +487 -0
  426. package/dist/gestures/LongPressGestureRecognizer.d.ts +32 -0
  427. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -0
  428. package/dist/gestures/LongPressGestureRecognizer.js +135 -0
  429. package/dist/gestures/PanGestureRecognizer.d.ts +117 -0
  430. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -0
  431. package/dist/gestures/PanGestureRecognizer.js +349 -0
  432. package/dist/gestures/TapGestureRecognizer.d.ts +39 -0
  433. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -0
  434. package/dist/gestures/TapGestureRecognizer.js +151 -0
  435. package/dist/gestures/VelocityTracker.d.ts +51 -0
  436. package/dist/gestures/VelocityTracker.d.ts.map +1 -0
  437. package/dist/gestures/VelocityTracker.js +186 -0
  438. package/dist/gestures/geometry.d.ts +17 -0
  439. package/dist/gestures/geometry.d.ts.map +1 -0
  440. package/dist/gestures/geometry.js +55 -0
  441. package/dist/gestures/types.d.ts +139 -0
  442. package/dist/gestures/types.d.ts.map +1 -0
  443. package/dist/gestures/types.js +67 -0
  444. package/dist/hooks/AnnounceRenderedText.d.ts +17 -0
  445. package/dist/hooks/AnnounceRenderedText.d.ts.map +1 -0
  446. package/dist/hooks/AnnounceRenderedText.js +32 -0
  447. package/dist/hooks/ModalAnnounceProvider.d.ts +41 -0
  448. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -0
  449. package/dist/hooks/ModalAnnounceProvider.js +133 -0
  450. package/dist/hooks/actionGroupTracker.d.ts +98 -0
  451. package/dist/hooks/actionGroupTracker.d.ts.map +1 -0
  452. package/dist/hooks/actionGroupTracker.js +338 -0
  453. package/dist/hooks/index.d.ts +2 -0
  454. package/dist/hooks/index.d.ts.map +1 -1
  455. package/dist/hooks/index.js +1 -0
  456. package/dist/hooks/menuPressOnItems.d.ts +19 -0
  457. package/dist/hooks/menuPressOnItems.d.ts.map +1 -0
  458. package/dist/hooks/menuPressOnItems.js +32 -0
  459. package/dist/hooks/modalAnnounce.d.ts +18 -0
  460. package/dist/hooks/modalAnnounce.d.ts.map +1 -0
  461. package/dist/hooks/modalAnnounce.js +382 -0
  462. package/dist/hooks/scrollGeometry.d.ts +28 -0
  463. package/dist/hooks/scrollGeometry.d.ts.map +1 -1
  464. package/dist/hooks/scrollGeometry.js +36 -2
  465. package/dist/hooks/useAdaptivePresentation.d.ts +9 -1
  466. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  467. package/dist/hooks/useAdaptivePresentation.js +33 -8
  468. package/dist/hooks/useAnimatedLayout.d.ts +42 -0
  469. package/dist/hooks/useAnimatedLayout.d.ts.map +1 -0
  470. package/dist/hooks/useAnimatedLayout.js +46 -0
  471. package/dist/hooks/useAnnounce.d.ts +132 -1
  472. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  473. package/dist/hooks/useAnnounce.js +356 -27
  474. package/dist/hooks/useAnnounceRenderedText.d.ts +19 -2
  475. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  476. package/dist/hooks/useAnnounceRenderedText.js +52 -11
  477. package/dist/hooks/useBusyAnnouncement.d.ts +9 -5
  478. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  479. package/dist/hooks/useBusyAnnouncement.js +58 -46
  480. package/dist/hooks/useFocusTrap.d.ts +1 -1
  481. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  482. package/dist/hooks/useFocusTrap.js +57 -26
  483. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  484. package/dist/hooks/useMenuHover.js +6 -2
  485. package/dist/hooks/useMenuPress.d.ts +4 -2
  486. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  487. package/dist/hooks/useMenuPress.js +58 -33
  488. package/dist/hooks/usePressFeedback.d.ts +5 -2
  489. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  490. package/dist/hooks/usePressFeedback.js +5 -2
  491. package/dist/hooks/useScrollableArea.d.ts +5 -0
  492. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  493. package/dist/hooks/useScrollableArea.js +104 -11
  494. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  495. package/dist/i18n/generated-locales/en.generated.js +33 -0
  496. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  497. package/dist/i18n/generated-locales/pseudo.generated.js +33 -0
  498. package/dist/internal/tokenizer-presentation.d.ts +21 -0
  499. package/dist/internal/tokenizer-presentation.d.ts.map +1 -0
  500. package/dist/internal/tokenizer-presentation.js +21 -0
  501. package/dist/internal/touch.d.ts +26 -0
  502. package/dist/internal/touch.d.ts.map +1 -0
  503. package/dist/internal/touch.js +28 -0
  504. package/dist/motion/LayoutChangeSnapshot.d.ts +33 -0
  505. package/dist/motion/LayoutChangeSnapshot.d.ts.map +1 -0
  506. package/dist/motion/LayoutChangeSnapshot.js +37 -0
  507. package/dist/motion/animatedLayout.d.ts +190 -0
  508. package/dist/motion/animatedLayout.d.ts.map +1 -0
  509. package/dist/motion/animatedLayout.js +1502 -0
  510. package/dist/motion/animator.d.ts +240 -0
  511. package/dist/motion/animator.d.ts.map +1 -0
  512. package/dist/motion/animator.js +2203 -0
  513. package/dist/motion/bezier.d.ts +18 -0
  514. package/dist/motion/bezier.d.ts.map +1 -0
  515. package/dist/motion/bezier.js +60 -0
  516. package/dist/motion/coast.d.ts +61 -0
  517. package/dist/motion/coast.d.ts.map +1 -0
  518. package/dist/motion/coast.js +107 -0
  519. package/dist/motion/decay.d.ts +41 -0
  520. package/dist/motion/decay.d.ts.map +1 -0
  521. package/dist/motion/decay.js +90 -0
  522. package/dist/motion/projection.d.ts +36 -0
  523. package/dist/motion/projection.d.ts.map +1 -0
  524. package/dist/motion/projection.js +92 -0
  525. package/dist/motion/reducedMotion.d.ts +25 -0
  526. package/dist/motion/reducedMotion.d.ts.map +1 -0
  527. package/dist/motion/reducedMotion.js +85 -0
  528. package/dist/motion/reducedMotion.stylex.d.ts +19 -0
  529. package/dist/motion/reducedMotion.stylex.d.ts.map +1 -0
  530. package/dist/motion/reducedMotion.stylex.js +37 -0
  531. package/dist/motion/reducedMotionPlan.d.ts +89 -0
  532. package/dist/motion/reducedMotionPlan.d.ts.map +1 -0
  533. package/dist/motion/reducedMotionPlan.js +194 -0
  534. package/dist/motion/resolveSnapPoint.d.ts +52 -0
  535. package/dist/motion/resolveSnapPoint.d.ts.map +1 -0
  536. package/dist/motion/resolveSnapPoint.js +135 -0
  537. package/dist/motion/roleValue.d.ts +33 -0
  538. package/dist/motion/roleValue.d.ts.map +1 -0
  539. package/dist/motion/roleValue.js +84 -0
  540. package/dist/motion/roles.d.ts +79 -0
  541. package/dist/motion/roles.d.ts.map +1 -0
  542. package/dist/motion/roles.js +199 -0
  543. package/dist/motion/rubberBand.d.ts +20 -0
  544. package/dist/motion/rubberBand.d.ts.map +1 -0
  545. package/dist/motion/rubberBand.js +91 -0
  546. package/dist/motion/selectPage.d.ts +26 -0
  547. package/dist/motion/selectPage.d.ts.map +1 -0
  548. package/dist/motion/selectPage.js +55 -0
  549. package/dist/motion/spring.d.ts +193 -0
  550. package/dist/motion/spring.d.ts.map +1 -0
  551. package/dist/motion/spring.js +442 -0
  552. package/dist/motion/transientCopy.d.ts +33 -0
  553. package/dist/motion/transientCopy.d.ts.map +1 -0
  554. package/dist/motion/transientCopy.js +314 -0
  555. package/dist/motion/uikit/gestures.d.ts +642 -0
  556. package/dist/motion/uikit/gestures.d.ts.map +1 -0
  557. package/dist/motion/uikit/gestures.js +428 -0
  558. package/dist/motion/uikit/index.d.ts +24 -0
  559. package/dist/motion/uikit/index.d.ts.map +1 -0
  560. package/dist/motion/uikit/index.js +26 -0
  561. package/dist/motion/uikit/navigation.d.ts +54 -0
  562. package/dist/motion/uikit/navigation.d.ts.map +1 -0
  563. package/dist/motion/uikit/navigation.js +83 -0
  564. package/dist/motion/uikit/scroll.d.ts +116 -0
  565. package/dist/motion/uikit/scroll.d.ts.map +1 -0
  566. package/dist/motion/uikit/scroll.js +146 -0
  567. package/dist/motion/uikit/springs.d.ts +545 -0
  568. package/dist/motion/uikit/springs.d.ts.map +1 -0
  569. package/dist/motion/uikit/springs.js +548 -0
  570. package/dist/motion/uikit/timing.d.ts +202 -0
  571. package/dist/motion/uikit/timing.d.ts.map +1 -0
  572. package/dist/motion/uikit/timing.js +201 -0
  573. package/dist/reset.a11y.chromium.spec.js +1 -0
  574. package/dist/reset.until-found.a11y.browser.spec.js +1 -0
  575. package/dist/theme/declarationBoundary.d.ts +13 -0
  576. package/dist/theme/declarationBoundary.d.ts.map +1 -1
  577. package/dist/theme/declarationBoundary.js +264 -1
  578. package/dist/theme/defineTheme.d.ts +111 -11
  579. package/dist/theme/defineTheme.d.ts.map +1 -1
  580. package/dist/theme/defineTheme.js +97 -7
  581. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  582. package/dist/theme/derivedVarRegistry.js +9 -0
  583. package/dist/theme/generateThemeRules.d.ts +6 -2
  584. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  585. package/dist/theme/generateThemeRules.js +468 -24
  586. package/dist/theme/index.d.ts +2 -2
  587. package/dist/theme/index.d.ts.map +1 -1
  588. package/dist/theme/index.js +1 -1
  589. package/dist/theme/statusColor.d.ts +48 -0
  590. package/dist/theme/statusColor.d.ts.map +1 -0
  591. package/dist/theme/statusColor.js +203 -0
  592. package/dist/theme/statusRoleDerivation.d.ts +11 -0
  593. package/dist/theme/statusRoleDerivation.d.ts.map +1 -0
  594. package/dist/theme/statusRoleDerivation.js +236 -0
  595. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  596. package/dist/theme/syntax/SyntaxTheme.js +1 -1
  597. package/dist/theme/syntax/defineSyntaxTheme.js +1 -1
  598. package/dist/theme/syntax/presets.d.ts +1 -1
  599. package/dist/theme/syntax/presets.js +1 -1
  600. package/dist/theme/syntax/tokens.d.ts +1 -1
  601. package/dist/theme/syntax/tokens.js +1 -1
  602. package/dist/theme/themeAdaptations.d.ts +25 -1
  603. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  604. package/dist/theme/themeAdaptations.js +30 -1
  605. package/dist/theme/tokens.d.ts.map +1 -1
  606. package/dist/theme/tokens.js +16 -1
  607. package/dist/theme/tokens.stylex.d.ts +42 -2
  608. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  609. package/dist/theme/tokens.stylex.js +54 -3
  610. package/dist/theme/useTheme.d.ts +4 -2
  611. package/dist/theme/useTheme.d.ts.map +1 -1
  612. package/dist/theme/useTheme.js +10 -4
  613. package/dist/utils/edgeAutoscroll.d.ts +53 -0
  614. package/dist/utils/edgeAutoscroll.d.ts.map +1 -0
  615. package/dist/utils/edgeAutoscroll.js +81 -0
  616. package/dist/utils/hitArea.d.ts +72 -0
  617. package/dist/utils/hitArea.d.ts.map +1 -0
  618. package/dist/utils/hitArea.js +681 -0
  619. package/dist/utils/interactionOverlay.stylex.d.ts +4 -1
  620. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  621. package/dist/utils/interactionOverlay.stylex.js +4 -1
  622. package/dist/utils/pressFeedback.d.ts +5 -1
  623. package/dist/utils/pressFeedback.d.ts.map +1 -1
  624. package/dist/utils/pressFeedback.js +285 -54
  625. package/dist/utils/pressGesture.d.ts +13 -1
  626. package/dist/utils/pressGesture.d.ts.map +1 -1
  627. package/dist/utils/pressGesture.js +40 -1
  628. package/dist/utils/touchPresentation.d.ts +48 -0
  629. package/dist/utils/touchPresentation.d.ts.map +1 -0
  630. package/dist/utils/touchPresentation.js +133 -0
  631. package/locales/af-ZA.json +1 -1
  632. package/locales/ar-SA.json +1 -1
  633. package/locales/ca-ES.json +1 -1
  634. package/locales/cs-CZ.json +1 -1
  635. package/locales/da-DK.json +1 -1
  636. package/locales/de-DE.json +1 -1
  637. package/locales/el-GR.json +1 -1
  638. package/locales/en.json +132 -0
  639. package/locales/es-ES.json +1 -1
  640. package/locales/fi-FI.json +1 -1
  641. package/locales/fr-FR.json +1 -1
  642. package/locales/he-IL.json +1 -1
  643. package/locales/hu-HU.json +1 -1
  644. package/locales/it-IT.json +1 -1
  645. package/locales/ja-JP.json +1 -1
  646. package/locales/ko-KR.json +1 -1
  647. package/locales/nl-NL.json +1 -1
  648. package/locales/no-NO.json +1 -1
  649. package/locales/pl-PL.json +1 -1
  650. package/locales/pseudo.json +99 -0
  651. package/locales/pt-BR.json +1 -1
  652. package/locales/pt-PT.json +1 -1
  653. package/locales/ro-RO.json +1 -1
  654. package/locales/ru-RU.json +1 -1
  655. package/locales/sr-SP.json +1 -1
  656. package/locales/sv-SE.json +1 -1
  657. package/locales/tr-TR.json +1 -1
  658. package/locales/uk-UA.json +1 -1
  659. package/locales/vi-VN.json +1 -1
  660. package/locales/zh-CN.json +1 -1
  661. package/locales/zh-TW.json +1 -1
  662. package/package.json +63 -8
  663. package/src/AlertDialog/AlertDialog.spec.md +85 -31
  664. package/src/AlertDialog/AlertDialog.tsx +1 -1
  665. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +1 -0
  666. package/src/AppShell/AppShell.spec.md +334 -0
  667. package/src/AppShell/AppShell.tsx +170 -2
  668. package/src/AspectRatio/AspectRatio.spec.md +179 -0
  669. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +1 -0
  670. package/src/Avatar/Avatar.spec.md +253 -0
  671. package/src/Avatar/AvatarStatusDot.spec.md +93 -79
  672. package/src/Avatar/AvatarStatusDot.test.tsx +22 -0
  673. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  674. package/src/AvatarGroup/AvatarGroup.spec.md +205 -0
  675. package/src/AvatarGroup/AvatarGroupOverflow.spec.md +123 -120
  676. package/src/Badge/Badge.spec.md +207 -0
  677. package/src/Badge/Badge.test.tsx +13 -0
  678. package/src/Badge/Badge.tsx +38 -2
  679. package/src/Banner/Banner.spec.md +41 -28
  680. package/src/Banner/Banner.test.tsx +118 -16
  681. package/src/Banner/Banner.tsx +94 -7
  682. package/src/Blockquote/Blockquote.spec.md +171 -0
  683. package/src/BottomSheet/BottomSheet.doc.mjs +106 -24
  684. package/src/BottomSheet/BottomSheet.spec.md +271 -40
  685. package/src/BottomSheet/BottomSheet.test.tsx +491 -5
  686. package/src/BottomSheet/BottomSheet.tsx +544 -145
  687. package/src/BottomSheet/BottomSheetHostContext.ts +44 -0
  688. package/src/BottomSheet/BottomSheetPanel.test.tsx +73 -19
  689. package/src/BottomSheet/BottomSheetPanel.tsx +178 -63
  690. package/src/BottomSheet/BottomSheetReplace.test.tsx +1638 -0
  691. package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +246 -0
  692. package/src/BottomSheet/BottomSheetStacking.test.tsx +3184 -0
  693. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +27 -31
  694. package/src/BottomSheet/BottomSheetSwitcher.spec.md +138 -43
  695. package/src/BottomSheet/BottomSheetSwitcher.tsx +275 -26
  696. package/src/BottomSheet/BottomSheetSwitcherContext.ts +6 -0
  697. package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +1 -0
  698. package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +1 -0
  699. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +4 -1
  700. package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +1 -0
  701. package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +1 -0
  702. package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +83 -0
  703. package/src/BottomSheet/bottomSheetEscape.ts +21 -0
  704. package/src/BottomSheet/bottomSheetStack.ts +2054 -0
  705. package/src/BottomSheet/useSheetGestures.ts +68 -12
  706. package/src/Breadcrumbs/BreadcrumbItem.spec.md +104 -60
  707. package/src/Breadcrumbs/BreadcrumbItem.tsx +30 -1
  708. package/src/Breadcrumbs/Breadcrumbs.spec.md +165 -0
  709. package/src/Breadcrumbs/Breadcrumbs.test.tsx +90 -0
  710. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +1 -0
  711. package/src/Button/Button.spec.md +322 -0
  712. package/src/Button/Button.test.tsx +8 -1
  713. package/src/Button/Button.tsx +36 -7
  714. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +1 -0
  715. package/src/ButtonGroup/ButtonGroup.spec.md +220 -0
  716. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +1 -0
  717. package/src/Card/Card.spec.md +205 -0
  718. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +1 -0
  719. package/src/Center/Center.spec.md +104 -124
  720. package/src/Chat/ChatComposer.test.tsx +54 -0
  721. package/src/Chat/ChatComposer.tsx +41 -27
  722. package/src/Chat/ChatComposerInput.test.tsx +165 -21
  723. package/src/Chat/ChatComposerInput.tsx +73 -16
  724. package/src/Chat/ChatMessageMetadata.tsx +1 -1
  725. package/src/Chat/ChatPastedTextToken.test.tsx +71 -0
  726. package/src/Chat/ChatPastedTextToken.tsx +8 -7
  727. package/src/Chat/ChatToolCalls.tsx +5 -5
  728. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +22 -4
  729. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +1 -0
  730. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +1 -0
  731. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +1 -0
  732. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1 -0
  733. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1 -0
  734. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +1 -0
  735. package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +1 -0
  736. package/src/CheckboxInput/CheckboxInput.spec.md +97 -66
  737. package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +1 -0
  738. package/src/CheckboxList/CheckboxList.spec.md +92 -78
  739. package/src/CheckboxList/CheckboxListItem.spec.md +86 -60
  740. package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +1 -0
  741. package/src/ClickableCard/ClickableCard.doc.mjs +1 -2
  742. package/src/ClickableCard/ClickableCard.spec.md +124 -128
  743. package/src/ClickableCard/ClickableCard.test.tsx +14 -3
  744. package/src/ClickableCard/ClickableCard.tsx +44 -28
  745. package/src/Code/Code.spec.md +30 -32
  746. package/src/CodeBlock/CodeBlock.doc.mjs +21 -4
  747. package/src/CodeBlock/CodeBlock.spec.md +96 -61
  748. package/src/CodeBlock/CodeBlock.test.tsx +97 -1
  749. package/src/CodeBlock/CodeBlock.tsx +132 -22
  750. package/src/CodeBlock/CodeLanguage.test.tsx +173 -0
  751. package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +290 -0
  752. package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +64 -0
  753. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +1 -0
  754. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +1 -0
  755. package/src/CodeBlock/grammar.ts +291 -0
  756. package/src/CodeBlock/index.ts +7 -0
  757. package/src/CodeBlock/languages/dockerfile.ts +43 -0
  758. package/src/CodeBlock/languages/graphql.ts +30 -0
  759. package/src/CodeBlock/languages/java.ts +28 -0
  760. package/src/CodeBlock/languages/lua.ts +21 -0
  761. package/src/CodeBlock/languages/objective-c.ts +26 -0
  762. package/src/CodeBlock/languages/powershell.ts +31 -0
  763. package/src/CodeBlock/languages/ruby.ts +29 -0
  764. package/src/CodeBlock/languages/thrift.ts +32 -0
  765. package/src/CodeBlock/languages/toml.ts +36 -0
  766. package/src/CodeBlock/languages.test.ts +402 -0
  767. package/src/CodeBlock/tokenizer.ts +176 -16
  768. package/src/CodeBlock/tokenizerBudget.test.ts +112 -0
  769. package/src/Collapsible/Collapsible.doc.mjs +6 -0
  770. package/src/Collapsible/Collapsible.spec.md +26 -23
  771. package/src/Collapsible/Collapsible.tsx +121 -2
  772. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +1 -0
  773. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +1 -0
  774. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +1 -0
  775. package/src/CommandPalette/CommandPalette.perf.test.ts +8 -4
  776. package/src/CommandPalette/CommandPalette.tsx +17 -1
  777. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +6 -3
  778. package/src/CommandPalette/CommandPaletteEmpty.spec.md +190 -0
  779. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -0
  780. package/src/CommandPalette/CommandPaletteInput.tsx +21 -2
  781. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +1 -0
  782. package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +715 -0
  783. package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +3 -2
  784. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +1 -0
  785. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +1 -0
  786. package/src/CommandPalette/busyStartSettle.ts +26 -0
  787. package/src/ComplexSelector/ComplexSelector.doc.mjs +1 -1
  788. package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +1 -1
  789. package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +9 -9
  790. package/src/ComplexSelector/ComplexSelector.spec.md +161 -107
  791. package/src/ComplexSelector/ComplexSelector.test.tsx +236 -17
  792. package/src/ComplexSelector/ComplexSelector.tsx +69 -4
  793. package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +965 -0
  794. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  795. package/src/ContextMenu/ContextMenu.spec.md +38 -30
  796. package/src/ContextMenu/ContextMenu.test.tsx +189 -11
  797. package/src/ContextMenu/ContextMenu.tsx +75 -17
  798. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +1 -0
  799. package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +1 -0
  800. package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +117 -0
  801. package/src/DateInput/DateInput.tsx +9 -4
  802. package/src/DateInput/DateInputTouch.test.tsx +10 -1
  803. package/src/DateInput/NativeDateField.tsx +2 -1
  804. package/src/DateInput/TouchDateField.tsx +2 -1
  805. package/src/DateInput/Wheel.tsx +4 -1
  806. package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +1 -0
  807. package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +171 -0
  808. package/src/Dialog/Dialog.doc.mjs +201 -47
  809. package/src/Dialog/Dialog.spec.md +20 -4
  810. package/src/Dialog/Dialog.tsx +37 -10
  811. package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +1 -0
  812. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +1 -0
  813. package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +252 -0
  814. package/src/Divider/Divider.spec.md +79 -70
  815. package/src/Drawer/Drawer.tsx +38 -35
  816. package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +1 -0
  817. package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +1 -0
  818. package/src/DropdownMenu/DropdownMenu.spec.md +14 -6
  819. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +44 -8
  820. package/src/DropdownMenu/DropdownMenu.test.tsx +107 -5
  821. package/src/DropdownMenu/DropdownMenu.tsx +51 -34
  822. package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +2 -2
  823. package/src/DropdownMenu/DropdownMenuGroup.tsx +12 -6
  824. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -5
  825. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
  826. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
  827. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
  828. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
  829. package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +72 -0
  830. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +9 -0
  831. package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +225 -0
  832. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +105 -0
  833. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +6 -6
  834. package/src/DropdownMenu/MenuBottomSheet.tsx +42 -7
  835. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +3 -3
  836. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +1 -0
  837. package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +1 -0
  838. package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +1 -0
  839. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +1 -0
  840. package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +1 -0
  841. package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +1 -0
  842. package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +540 -0
  843. package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +671 -0
  844. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +1 -0
  845. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +1 -0
  846. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  847. package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +238 -0
  848. package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +1 -0
  849. package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +1 -0
  850. package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  851. package/src/DropdownMenu/lazyMenuBottomSheet.ts +28 -2
  852. package/src/DropdownMenu/menuBottomSheet.stylex.ts +33 -0
  853. package/src/DropdownMenu/menuItemHover.ts +13 -1
  854. package/src/DropdownMenu/menuTouchAction.stylex.ts +28 -0
  855. package/src/DropdownMenu/modules/useMenuPress.spec.md +90 -62
  856. package/src/DropdownMenu/useMenuDrillIn.tsx +7 -5
  857. package/src/EmptyState/EmptyState.announce.test.tsx +227 -0
  858. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  859. package/src/EmptyState/EmptyState.spec.md +22 -14
  860. package/src/EmptyState/EmptyState.test.tsx +8 -8
  861. package/src/EmptyState/EmptyState.tsx +7 -5
  862. package/src/Field/Field.spec.md +57 -48
  863. package/src/Field/Field.tsx +1 -1
  864. package/src/Field/FieldLabel.spec.md +70 -59
  865. package/src/Field/FieldLabel.tsx +1 -1
  866. package/src/Field/PanelSearchInput.tsx +23 -13
  867. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +1 -0
  868. package/src/Field/inputDisabledFocus.ts +28 -0
  869. package/src/Field/inputStyles.stylex.ts +15 -15
  870. package/src/FieldStatus/FieldStatus.test.tsx +12 -0
  871. package/src/FieldStatus/FieldStatus.tsx +12 -3
  872. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +1 -0
  873. package/src/FileInput/FileInput.doc.mjs +1 -1
  874. package/src/FileInput/FileInput.test.tsx +102 -0
  875. package/src/FileInput/FileInput.tsx +18 -12
  876. package/src/FormLayout/FormLayout.spec.md +69 -51
  877. package/src/Grid/Grid.spec.md +72 -69
  878. package/src/Grid/GridSpan.spec.md +158 -0
  879. package/src/Heading/Heading.spec.md +198 -0
  880. package/src/HoverCard/HoverCard.spec.md +244 -0
  881. package/src/HoverCard/HoverCard.test.tsx +93 -3
  882. package/src/Icon/Icon.doc.mjs +67 -5
  883. package/src/Icon/Icon.test.tsx +548 -9
  884. package/src/Icon/Icon.tsx +79 -15
  885. package/src/Icon/IconSize.stylex.ts +27 -11
  886. package/src/Icon/globalIconRegistry.test.tsx +395 -3
  887. package/src/Icon/globalIconRegistry.tsx +184 -36
  888. package/src/Icon/index.ts +29 -1
  889. package/src/Icon/useIcon.ts +5 -1
  890. package/src/IconButton/IconButton.spec.md +197 -0
  891. package/src/IconButton/IconButton.test.tsx +5 -2
  892. package/src/InputGroup/InputGroup.spec.md +199 -0
  893. package/src/InputGroup/InputGroup.test.tsx +120 -0
  894. package/src/InputGroup/InputGroup.tsx +59 -52
  895. package/src/InputGroup/InputGroupInternalContext.ts +15 -0
  896. package/src/InputGroup/InputGroupText.spec.md +139 -0
  897. package/src/InputGroup/InputGroupText.tsx +2 -0
  898. package/src/InputGroup/groupStyles.ts +22 -11
  899. package/src/Item/Item.test.tsx +158 -1
  900. package/src/Item/Item.tsx +42 -7
  901. package/src/Item/ItemMarkerColumns.a11y.chromium.spec.ts +211 -0
  902. package/src/Item/ItemMarkerColumnsContext.tsx +20 -0
  903. package/src/Item/ItemSwipeLayer.tsx +9 -0
  904. package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +1 -0
  905. package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +186 -0
  906. package/src/Item/useSwipeAction.ts +71 -5
  907. package/src/Kbd/Kbd.test.tsx +95 -0
  908. package/src/Kbd/Kbd.tsx +30 -23
  909. package/src/Layer/LayerProvider.spec.md +149 -0
  910. package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +176 -0
  911. package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +200 -0
  912. package/src/Layer/layerAnimations.stylex.ts +22 -2
  913. package/src/Layer/layerDismissalInvariants.test.tsx +9 -0
  914. package/src/Layer/layerSlideRules.ts +141 -8
  915. package/src/Layer/layerStack.ts +129 -62
  916. package/src/Layer/modalOutlet.ts +156 -15
  917. package/src/Layer/preserveAnimations.ts +304 -0
  918. package/src/Layer/useLayer.doc.mjs +1 -1
  919. package/src/Layer/useLayer.test.tsx +850 -0
  920. package/src/Layer/useLayer.tsx +644 -58
  921. package/src/Layer/useLayerDismissal.test.tsx +85 -2
  922. package/src/Layer/useLayerDismissal.ts +12 -9
  923. package/src/Layer/useTouchTrigger.ts +95 -41
  924. package/src/Layout/Layout.tsx +18 -0
  925. package/src/Layout/LayoutContent.tsx +5 -14
  926. package/src/Layout/LayoutFooter.tsx +2 -0
  927. package/src/Layout/LayoutHeader.tsx +2 -0
  928. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +1 -0
  929. package/src/Layout/layoutEdges.stylex.ts +25 -0
  930. package/src/Lightbox/Lightbox.spec.md +9 -8
  931. package/src/Lightbox/Lightbox.test.tsx +83 -0
  932. package/src/Lightbox/Lightbox.tsx +149 -125
  933. package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +78 -0
  934. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +70 -0
  935. package/src/Link/Link.spec.md +229 -0
  936. package/src/Link/LinkProvider.spec.md +167 -0
  937. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +1 -0
  938. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +1 -0
  939. package/src/List/List.spec.md +113 -34
  940. package/src/List/List.tsx +13 -1
  941. package/src/List/ListContext.tsx +19 -5
  942. package/src/List/ListItem.doc.mjs +3 -3
  943. package/src/List/ListItem.tsx +97 -28
  944. package/src/List/ListMarkers.a11y.chromium.spec.ts +904 -0
  945. package/src/Markdown/Markdown.codeLanguages.test.tsx +137 -0
  946. package/src/Markdown/Markdown.doc.mjs +12 -0
  947. package/src/Markdown/Markdown.fr23.bench.ts +3 -1
  948. package/src/Markdown/Markdown.fr23.perf.test.ts +45 -3
  949. package/src/Markdown/Markdown.fr23.sampling.ts +13 -4
  950. package/src/Markdown/Markdown.spec.md +71 -59
  951. package/src/Markdown/Markdown.test.tsx +50 -0
  952. package/src/Markdown/Markdown.tsx +61 -8
  953. package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +1 -0
  954. package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +1 -0
  955. package/src/MobileNav/MobileNav.doc.mjs +2 -2
  956. package/src/MobileNav/MobileNav.spec.md +161 -64
  957. package/src/MobileNav/MobileNav.test.tsx +27 -10
  958. package/src/MobileNav/MobileNav.tsx +51 -38
  959. package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +1 -0
  960. package/src/MobileNav/MobileNavToggle.test.tsx +63 -0
  961. package/src/MobileNav/MobileNavToggle.tsx +13 -5
  962. package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +103 -0
  963. package/src/MoreMenu/MoreMenu.doc.mjs +2 -2
  964. package/src/MoreMenu/MoreMenu.spec.md +88 -53
  965. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +67 -9
  966. package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +1 -0
  967. package/src/MultiSelector/MultiSelector.test.tsx +122 -10
  968. package/src/MultiSelector/MultiSelector.tsx +24 -4
  969. package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +1 -0
  970. package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +1 -0
  971. package/src/NavIcon/NavIcon.spec.md +66 -38
  972. package/src/NavMenu/NavHeadingMenu.spec.md +104 -46
  973. package/src/NavMenu/NavHeadingMenu.test.tsx +276 -2
  974. package/src/NavMenu/NavHeadingMenu.tsx +42 -4
  975. package/src/NavMenu/NavHeadingMenuItem.tsx +60 -6
  976. package/src/NavMenu/NavMenuContext.tsx +11 -0
  977. package/src/NavMenu/__tests__/NavMenusSlideSelection.a11y.chromium.spec.ts +137 -0
  978. package/src/NumberInput/NumberInput.doc.mjs +6 -6
  979. package/src/NumberInput/NumberInput.spec.md +248 -0
  980. package/src/NumberInput/NumberInput.test.tsx +187 -14
  981. package/src/NumberInput/NumberInput.tsx +86 -24
  982. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +1 -0
  983. package/src/Overlay/Overlay.doc.mjs +2 -2
  984. package/src/Overlay/Overlay.test.tsx +72 -4
  985. package/src/Overlay/Overlay.tsx +18 -8
  986. package/src/Pagination/Pagination.test.tsx +2 -2
  987. package/src/Popover/Popover.doc.mjs +38 -2
  988. package/src/Popover/Popover.spec.md +90 -11
  989. package/src/Popover/Popover.test.tsx +340 -2
  990. package/src/Popover/Popover.tsx +401 -35
  991. package/src/Popover/PopoverPresentation.test.tsx +952 -0
  992. package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +205 -0
  993. package/src/Popover/index.ts +5 -1
  994. package/src/Popover/lazyPopoverBottomSheet.ts +57 -0
  995. package/src/Popover/usePopover.tsx +11 -5
  996. package/src/PowerSearch/PowerSearch.spec.md +423 -53
  997. package/src/PowerSearch/PowerSearch.test.tsx +77 -1
  998. package/src/PowerSearch/PowerSearch.tsx +7 -5
  999. package/src/ProgressBar/ProgressBar.test.tsx +12 -0
  1000. package/src/ProgressBar/ProgressBar.tsx +18 -0
  1001. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +1 -0
  1002. package/src/RadioList/RadioList.spec.md +227 -0
  1003. package/src/RadioList/RadioList.test.tsx +34 -7
  1004. package/src/RadioList/RadioListItem.press.source-build.test.mjs +80 -0
  1005. package/src/RadioList/RadioListItem.spec.md +223 -0
  1006. package/src/RadioList/RadioListItem.tsx +26 -12
  1007. package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +1 -0
  1008. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +1 -0
  1009. package/src/ScrollableArea/ScrollableArea.spec.md +6 -5
  1010. package/src/ScrollableArea/ScrollableArea.test.tsx +5 -0
  1011. package/src/ScrollableArea/ScrollableArea.tsx +4 -0
  1012. package/src/Section/Section.spec.md +102 -44
  1013. package/src/SegmentedControl/SegmentedControl.spec.md +162 -53
  1014. package/src/SegmentedControl/SegmentedControl.test.tsx +46 -0
  1015. package/src/SegmentedControl/SegmentedControl.tsx +7 -3
  1016. package/src/SegmentedControl/SegmentedControlItem.spec.md +206 -0
  1017. package/src/SelectableCard/SelectableCard.doc.mjs +7 -6
  1018. package/src/SelectableCard/SelectableCard.spec.md +230 -0
  1019. package/src/SelectableCard/SelectableCard.test.tsx +11 -1
  1020. package/src/SelectableCard/SelectableCard.tsx +49 -33
  1021. package/src/Selector/Selector.sheetActiveDescendant.test.tsx +95 -0
  1022. package/src/Selector/Selector.spec.md +12 -4
  1023. package/src/Selector/Selector.test.tsx +114 -8
  1024. package/src/Selector/Selector.tsx +30 -6
  1025. package/src/Selector/__tests__/ComboboxField.a11y.chromium.spec.ts +458 -0
  1026. package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +1 -0
  1027. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +1 -0
  1028. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +1 -0
  1029. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +1 -0
  1030. package/src/Selector/hooks.ts +234 -10
  1031. package/src/Selector/useCombobox.doc.mjs +156 -9
  1032. package/src/Selector/useCombobox.public.test.tsx +89 -0
  1033. package/src/Selector/useCombobox.test.tsx +444 -0
  1034. package/src/SideNav/SideNav.spec.md +50 -30
  1035. package/src/SideNav/SideNav.test.tsx +425 -25
  1036. package/src/SideNav/SideNav.tsx +85 -1
  1037. package/src/SideNav/SideNavCollapseButton.spec.md +161 -0
  1038. package/src/SideNav/SideNavHeading.spec.md +226 -0
  1039. package/src/SideNav/SideNavHeading.tsx +102 -6
  1040. package/src/SideNav/SideNavItem.spec.md +246 -0
  1041. package/src/SideNav/SideNavItem.tsx +40 -9
  1042. package/src/SideNav/SideNavRailMotion.test.tsx +620 -0
  1043. package/src/SideNav/SideNavSection.spec.md +153 -0
  1044. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +417 -0
  1045. package/src/SideNav/railMotion.ts +315 -0
  1046. package/src/Skeleton/Skeleton.spec.md +99 -42
  1047. package/src/Skeleton/Skeleton.test.tsx +108 -1
  1048. package/src/Skeleton/Skeleton.tsx +30 -2
  1049. package/src/Slider/Slider.fr10.test.tsx +34 -0
  1050. package/src/Slider/Slider.test.tsx +172 -0
  1051. package/src/Slider/Slider.tsx +70 -14
  1052. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +1 -0
  1053. package/src/Spinner/Spinner.spec.md +231 -0
  1054. package/src/Stack/Stack.spec.md +104 -56
  1055. package/src/StatusDot/StatusDot.spec.md +139 -51
  1056. package/src/StatusDot/StatusDot.test.tsx +13 -0
  1057. package/src/StatusDot/StatusDot.tsx +27 -0
  1058. package/src/Stepper/Step.spec.md +206 -0
  1059. package/src/Stepper/Step.tsx +19 -3
  1060. package/src/Stepper/Stepper.test.tsx +50 -0
  1061. package/src/Switch/Switch.focusRing.source-build.test.mjs +81 -0
  1062. package/src/Switch/Switch.spec.md +150 -66
  1063. package/src/Switch/Switch.tsx +11 -9
  1064. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +1 -0
  1065. package/src/Switch/switch.markers.stylex.ts +7 -2
  1066. package/src/TabList/Tab.spec.md +201 -0
  1067. package/src/TabList/Tab.tsx +7 -1
  1068. package/src/TabList/TabList.doc.mjs +3 -3
  1069. package/src/TabList/TabList.test.tsx +27 -0
  1070. package/src/TabList/TabMenu.spec.md +198 -0
  1071. package/src/TabList/TabMenu.tsx +24 -1
  1072. package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +99 -0
  1073. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +1 -0
  1074. package/src/Table/Table.spec.md +54 -30
  1075. package/src/Table/TableCell.tsx +9 -0
  1076. package/src/Table/TableHeaderCell.tsx +2 -0
  1077. package/src/Table/TableRow.tsx +3 -0
  1078. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +129 -0
  1079. package/src/Table/__tests__/Table.a11y.contracts.ts +35 -0
  1080. package/src/Table/__tests__/Table.a11y.renders.tsx +112 -0
  1081. package/src/Table/__tests__/Table.a11y.states.ts +140 -0
  1082. package/src/Table/__tests__/Table.a11y.test.tsx +198 -0
  1083. package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +1 -0
  1084. package/src/Table/__tests__/TableRowGlide.a11y.browser.spec.ts +382 -0
  1085. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +1 -0
  1086. package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +560 -0
  1087. package/src/Table/glidingDivider.ts +336 -0
  1088. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +23 -8
  1089. package/src/Table/plugins/rowExpansion/useTableRowExpansion.glide.test.tsx +280 -0
  1090. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +91 -9
  1091. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +471 -10
  1092. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +4 -4
  1093. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +174 -0
  1094. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +86 -0
  1095. package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -12
  1096. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +51 -1
  1097. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +312 -12
  1098. package/src/Table/rowDivider.ts +154 -0
  1099. package/src/Table/useTableRowExpansion.doc.mjs +8 -0
  1100. package/src/Text/Text.spec.md +114 -127
  1101. package/src/TextArea/TextArea.doc.mjs +6 -6
  1102. package/src/TextArea/TextArea.spec.md +164 -64
  1103. package/src/TextArea/TextArea.test.tsx +65 -6
  1104. package/src/TextArea/TextArea.tsx +27 -15
  1105. package/src/TextInput/TextInput.doc.mjs +8 -8
  1106. package/src/TextInput/TextInput.spec.md +260 -0
  1107. package/src/TextInput/TextInput.test.tsx +126 -10
  1108. package/src/TextInput/TextInput.tsx +57 -23
  1109. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +1 -0
  1110. package/src/Thumbnail/Thumbnail.doc.mjs +1 -2
  1111. package/src/Thumbnail/Thumbnail.spec.md +244 -0
  1112. package/src/Thumbnail/Thumbnail.test.tsx +120 -7
  1113. package/src/Thumbnail/Thumbnail.tsx +77 -31
  1114. package/src/TimeInput/TimeInput.spec.md +273 -0
  1115. package/src/TimeInput/TimeInput.tsx +12 -4
  1116. package/src/TimeInput/TouchTimeField.tsx +2 -1
  1117. package/src/Timestamp/Timestamp.spec.md +252 -0
  1118. package/src/Toast/Toast.spec.md +300 -0
  1119. package/src/Toast/ToastViewport.modalHost.test.tsx +630 -5
  1120. package/src/Toast/ToastViewport.test.tsx +137 -0
  1121. package/src/Toast/ToastViewport.tsx +63 -6
  1122. package/src/ToggleButton/ToggleButton.spec.md +256 -0
  1123. package/src/ToggleButton/ToggleButtonGroup.spec.md +195 -0
  1124. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +1 -0
  1125. package/src/Token/Token.spec.md +271 -0
  1126. package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +1 -0
  1127. package/src/Tokenizer/Tokenizer.props-type.test.tsx +126 -0
  1128. package/src/Tokenizer/Tokenizer.spec.md +313 -72
  1129. package/src/Tokenizer/Tokenizer.ssr.test.tsx +196 -0
  1130. package/src/Tokenizer/Tokenizer.test.tsx +44 -8
  1131. package/src/Tokenizer/Tokenizer.tsx +586 -41
  1132. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +2719 -0
  1133. package/src/Tokenizer/TokenizerBottomSheet.tsx +957 -0
  1134. package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +61 -27
  1135. package/src/Toolbar/Toolbar.spec.md +103 -49
  1136. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +1 -0
  1137. package/src/Tooltip/Tooltip.spec.md +161 -36
  1138. package/src/Tooltip/Tooltip.test.tsx +171 -3
  1139. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +1 -0
  1140. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
  1141. package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +1 -0
  1142. package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +1 -0
  1143. package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +673 -0
  1144. package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +1162 -0
  1145. package/src/Tooltip/useTooltip.tsx +7 -2
  1146. package/src/TopNav/TopNav.spec.md +190 -0
  1147. package/src/TopNav/TopNav.test.tsx +89 -0
  1148. package/src/TopNav/TopNavHeading.spec.md +211 -0
  1149. package/src/TopNav/TopNavHeading.tsx +35 -2
  1150. package/src/TopNav/TopNavItem.spec.md +189 -0
  1151. package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +83 -0
  1152. package/src/TopNav/TopNavMegaMenu.spec.md +190 -0
  1153. package/src/TopNav/TopNavMegaMenu.tsx +21 -4
  1154. package/src/TopNav/TopNavMegaMenuFeaturedCard.spec.md +150 -0
  1155. package/src/TopNav/TopNavMegaMenuItem.spec.md +155 -0
  1156. package/src/TopNav/TopNavMenu.spec.md +202 -0
  1157. package/src/TopNav/TopNavMenu.test.tsx +65 -1
  1158. package/src/TopNav/TopNavMenu.tsx +30 -1
  1159. package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +1 -0
  1160. package/src/TreeList/TreeList.doc.mjs +13 -0
  1161. package/src/TreeList/TreeList.spec.md +54 -35
  1162. package/src/TreeList/TreeList.tsx +234 -2
  1163. package/src/TreeList/TreeListBranches.tsx +8 -6
  1164. package/src/TreeList/TreeListItem.tsx +12 -6
  1165. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +19 -6
  1166. package/src/TreeList/__tests__/TreeListGuideAlignment.interaction.browser.spec.ts +127 -0
  1167. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +1 -0
  1168. package/src/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.ts +138 -0
  1169. package/src/Typeahead/BaseTypeahead.test.tsx +201 -4
  1170. package/src/Typeahead/BaseTypeahead.tsx +26 -10
  1171. package/src/Typeahead/Typeahead.test.tsx +114 -1
  1172. package/src/Typeahead/Typeahead.tsx +34 -16
  1173. package/src/VisuallyHidden/VisuallyHidden.spec.md +170 -0
  1174. package/src/__tests__/BusyOwnerAnnouncement.test.tsx +66 -5
  1175. package/src/__tests__/CardPress.a11y.chromium.spec.ts +353 -0
  1176. package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +2 -1
  1177. package/src/__tests__/PressModality.a11y.chromium.spec.ts +392 -0
  1178. package/src/__tests__/PressedState.a11y.chromium.spec.ts +1 -0
  1179. package/src/__tests__/pressState.ts +43 -1
  1180. package/src/__tests__/unthemedLength.ts +34 -0
  1181. package/src/gestures/GestureArena.ts +966 -0
  1182. package/src/gestures/GestureRecognizer.ts +626 -0
  1183. package/src/gestures/LongPressGestureRecognizer.ts +186 -0
  1184. package/src/gestures/PanGestureRecognizer.ts +410 -0
  1185. package/src/gestures/TapGestureRecognizer.ts +192 -0
  1186. package/src/gestures/VelocityTracker.ts +194 -0
  1187. package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +141 -0
  1188. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +327 -0
  1189. package/src/gestures/__tests__/TapGestureRecognizer.test.ts +154 -0
  1190. package/src/gestures/__tests__/VelocityTracker.streams.test.ts +243 -0
  1191. package/src/gestures/__tests__/VelocityTracker.test.ts +261 -0
  1192. package/src/gestures/__tests__/arena.test.ts +824 -0
  1193. package/src/gestures/__tests__/arenaContinuous.test.ts +207 -0
  1194. package/src/gestures/__tests__/arenaTapLongPress.test.ts +211 -0
  1195. package/src/gestures/__tests__/fixtures/pointer-streams/README.md +82 -0
  1196. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-fling.json +130 -0
  1197. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-slow.json +860 -0
  1198. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-stop-release.json +357 -0
  1199. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-fling.json +66 -0
  1200. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-slow.json +268 -0
  1201. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-stop-release.json +128 -0
  1202. package/src/gestures/__tests__/fixtures/pointer-streams/capture.html +123 -0
  1203. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-fling.json +64 -0
  1204. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-slow.json +268 -0
  1205. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-stop-release.json +124 -0
  1206. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-fling.json +64 -0
  1207. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-slow.json +268 -0
  1208. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-stop-release.json +124 -0
  1209. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-fling.json +84 -0
  1210. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-slow.json +381 -0
  1211. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-stop-release.json +171 -0
  1212. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-fling.json +45 -0
  1213. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-slow.json +101 -0
  1214. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-stop-release.json +130 -0
  1215. package/src/gestures/__tests__/harness.ts +204 -0
  1216. package/src/gestures/geometry.ts +55 -0
  1217. package/src/gestures/types.ts +161 -0
  1218. package/src/hooks/AnnounceRenderedText.tsx +27 -0
  1219. package/src/hooks/ModalAnnounceProvider.tsx +155 -0
  1220. package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +98 -4
  1221. package/src/hooks/__tests__/menuLinkClicks.ts +71 -0
  1222. package/src/hooks/actionGroupTracker.exports.test.ts +28 -0
  1223. package/src/hooks/actionGroupTracker.test.ts +510 -0
  1224. package/src/hooks/actionGroupTracker.ts +449 -0
  1225. package/src/hooks/index.ts +6 -0
  1226. package/src/hooks/menuPressOnItems.ts +40 -0
  1227. package/src/hooks/modalAnnounce.ts +439 -0
  1228. package/src/hooks/scrollGeometry.ts +71 -4
  1229. package/src/hooks/useAdaptivePresentation.ts +46 -9
  1230. package/src/hooks/useAnimatedLayout.doc.mjs +101 -0
  1231. package/src/hooks/useAnimatedLayout.ts +61 -0
  1232. package/src/hooks/useAnnounce.doc.mjs +4 -4
  1233. package/src/hooks/useAnnounce.modal.test.tsx +1291 -0
  1234. package/src/hooks/useAnnounce.test.tsx +64 -4
  1235. package/src/hooks/useAnnounce.ts +452 -28
  1236. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +226 -0
  1237. package/src/hooks/useAnnounceRenderedText.ts +81 -11
  1238. package/src/hooks/useBusyAnnouncement.adopters.test.tsx +69 -0
  1239. package/src/hooks/useBusyAnnouncement.test.tsx +112 -0
  1240. package/src/hooks/useBusyAnnouncement.ts +64 -54
  1241. package/src/hooks/useFocusTrap.doc.mjs +3 -3
  1242. package/src/hooks/useFocusTrap.test.tsx +135 -2
  1243. package/src/hooks/useFocusTrap.ts +59 -27
  1244. package/src/hooks/useMenuHover.ts +6 -2
  1245. package/src/hooks/useMenuPress.doc.mjs +2 -2
  1246. package/src/hooks/useMenuPress.test.tsx +5 -2
  1247. package/src/hooks/useMenuPress.ts +72 -37
  1248. package/src/hooks/usePressFeedback.doc.mjs +4 -4
  1249. package/src/hooks/usePressFeedback.ts +5 -2
  1250. package/src/hooks/useScrollableArea.test.tsx +344 -3
  1251. package/src/hooks/useScrollableArea.ts +120 -12
  1252. package/src/i18n/generated-locales/en.generated.ts +35 -0
  1253. package/src/i18n/generated-locales/pseudo.generated.ts +37 -0
  1254. package/src/internal/tokenizer-presentation.test.ts +29 -0
  1255. package/src/internal/tokenizer-presentation.ts +25 -0
  1256. package/src/internal/touch.test.ts +44 -0
  1257. package/src/internal/touch.ts +41 -0
  1258. package/src/motion/LayoutChangeSnapshot.tsx +50 -0
  1259. package/src/motion/MEASUREMENTS.md +271 -0
  1260. package/src/motion/README.md +218 -0
  1261. package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +1613 -0
  1262. package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +217 -0
  1263. package/src/motion/__tests__/animatedLayoutBundle.ts +17 -0
  1264. package/src/motion/animatedLayout.boundary.test.ts +155 -0
  1265. package/src/motion/animatedLayout.swap.test.ts +827 -0
  1266. package/src/motion/animatedLayout.test.ts +1154 -0
  1267. package/src/motion/animatedLayout.ts +1801 -0
  1268. package/src/motion/animatedLayoutAdopters.test.tsx +500 -0
  1269. package/src/motion/animator.test.ts +2653 -0
  1270. package/src/motion/animator.ts +2794 -0
  1271. package/src/motion/bezier.test.ts +52 -0
  1272. package/src/motion/bezier.ts +64 -0
  1273. package/src/motion/coast.test.ts +99 -0
  1274. package/src/motion/coast.ts +150 -0
  1275. package/src/motion/decay.test.ts +120 -0
  1276. package/src/motion/decay.ts +126 -0
  1277. package/src/motion/projection.test.ts +107 -0
  1278. package/src/motion/projection.ts +116 -0
  1279. package/src/motion/reducedMotion.stylex.ts +41 -0
  1280. package/src/motion/reducedMotion.test.ts +129 -0
  1281. package/src/motion/reducedMotion.ts +94 -0
  1282. package/src/motion/reducedMotionPlan.test.ts +182 -0
  1283. package/src/motion/reducedMotionPlan.ts +263 -0
  1284. package/src/motion/resolveSnapPoint.test.ts +189 -0
  1285. package/src/motion/resolveSnapPoint.ts +169 -0
  1286. package/src/motion/roleValue.ts +105 -0
  1287. package/src/motion/roles.test.ts +256 -0
  1288. package/src/motion/roles.ts +262 -0
  1289. package/src/motion/rubberBand.test.ts +88 -0
  1290. package/src/motion/rubberBand.ts +115 -0
  1291. package/src/motion/selectPage.test.ts +31 -0
  1292. package/src/motion/selectPage.ts +55 -0
  1293. package/src/motion/spring.test.ts +650 -0
  1294. package/src/motion/spring.ts +551 -0
  1295. package/src/motion/transientCopy.ts +374 -0
  1296. package/src/motion/uikit/gestures.test.ts +89 -0
  1297. package/src/motion/uikit/gestures.ts +359 -0
  1298. package/src/motion/uikit/index.ts +80 -0
  1299. package/src/motion/uikit/navigation.ts +83 -0
  1300. package/src/motion/uikit/scroll.ts +141 -0
  1301. package/src/motion/uikit/springRows.test.ts +71 -0
  1302. package/src/motion/uikit/springs.ts +514 -0
  1303. package/src/motion/uikit/timing.ts +210 -0
  1304. package/src/motion/uikit/uikit.test.ts +364 -0
  1305. package/src/motion/uikit/values.test.ts +110 -0
  1306. package/src/reset.a11y.chromium.spec.ts +1 -0
  1307. package/src/reset.until-found.a11y.browser.spec.ts +1 -0
  1308. package/src/serverSafeComponents.test.ts +10 -0
  1309. package/src/tailwind-theme.css +51 -1
  1310. package/src/tailwind-theme.test.ts +51 -0
  1311. package/src/theme/Theme.test.tsx +28 -0
  1312. package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +1 -0
  1313. package/src/theme/declarationBoundary.ts +282 -1
  1314. package/src/theme/defineTheme.test.ts +529 -12
  1315. package/src/theme/defineTheme.ts +231 -19
  1316. package/src/theme/derivedVarRegistry.test.ts +34 -5
  1317. package/src/theme/derivedVarRegistry.ts +4 -0
  1318. package/src/theme/expandMotionScale.test.ts +17 -0
  1319. package/src/theme/extensibleAxes.test.ts +74 -29
  1320. package/src/theme/generateThemeRules.ts +772 -35
  1321. package/src/theme/index.ts +3 -0
  1322. package/src/theme/onMediaTokens.test.ts +186 -0
  1323. package/src/theme/statusColor.ts +189 -0
  1324. package/src/theme/statusRoleDerivation.ts +289 -0
  1325. package/src/theme/syntax/SyntaxTheme.tsx +1 -1
  1326. package/src/theme/syntax/defineSyntaxTheme.ts +1 -1
  1327. package/src/theme/syntax/presets.ts +1 -1
  1328. package/src/theme/syntax/tokens.ts +1 -1
  1329. package/src/theme/themeAdaptations.test.ts +412 -0
  1330. package/src/theme/themeAdaptations.ts +43 -1
  1331. package/src/theme/tokens.stylex.ts +36 -2
  1332. package/src/theme/tokens.test.ts +111 -1
  1333. package/src/theme/tokens.ts +23 -1
  1334. package/src/theme/useTheme.ts +10 -4
  1335. package/src/utils/customPropertyArmLayering.test.ts +131 -0
  1336. package/src/utils/edgeAutoscroll.test.ts +192 -0
  1337. package/src/utils/edgeAutoscroll.ts +111 -0
  1338. package/src/utils/hitArea.test.ts +628 -0
  1339. package/src/utils/hitArea.ts +770 -0
  1340. package/src/utils/interactionOverlay.stylex.ts +4 -1
  1341. package/src/utils/pressFeedback.test.ts +310 -2
  1342. package/src/utils/pressFeedback.ts +306 -54
  1343. package/src/utils/pressGesture.test.ts +50 -0
  1344. package/src/utils/pressGesture.ts +40 -2
  1345. package/src/utils/touchPresentation.test.ts +323 -0
  1346. package/src/utils/touchPresentation.ts +153 -0
@@ -0,0 +1,1291 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ /**
3
+ * @file useAnnounce.modal.test.tsx
4
+ * @input Uses vitest, Testing Library, useAnnounce, and the Astryx modals
5
+ * @output Proof of spec:AST-086 FR14: a message follows the nearest open
6
+ * native modal enclosing its caller — inside an Astryx Dialog, modal
7
+ * BottomSheet, modal Drawer or Lightbox it reaches that dialog's own
8
+ * persistent containers; a caller outside, or inside a non-modal sheet
9
+ * with no modal above it, keeps the shared channel; a non-modal sheet
10
+ * nested in a modal routes to the modal; a modal over a modal routes to
11
+ * the top one; a message unexposed when its modal closes is handed to the
12
+ * channel exposed after the close; join, identical-repeat and empty-message
13
+ * rules hold inside the dialog
14
+ * @position Core a11y tests beside the hook
15
+ */
16
+ import {act, fireEvent, render, screen} from '@testing-library/react';
17
+ import {
18
+ useEffect,
19
+ useLayoutEffect,
20
+ useRef,
21
+ useState,
22
+ type ReactNode,
23
+ } from 'react';
24
+ import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
25
+ import {BottomSheet} from '../BottomSheet/BottomSheet';
26
+ import {Dialog} from '../Dialog/Dialog';
27
+ import {Drawer} from '../Drawer/Drawer';
28
+ import {BottomSheetSwitcher} from '../BottomSheet/BottomSheetSwitcher';
29
+ import {Lightbox} from '../Lightbox/Lightbox';
30
+ import {MobileNav} from '../MobileNav/MobileNav';
31
+ import {Popover} from '../Popover/Popover';
32
+ import {DropdownMenu} from '../DropdownMenu/DropdownMenu';
33
+ import {useBusyAnnouncement} from './useBusyAnnouncement';
34
+ import {ModalAnnounceProvider} from './ModalAnnounceProvider';
35
+ import {__resetLiveRegionsForTest, useAnnounce} from './useAnnounce';
36
+
37
+ function Owner({
38
+ message = 'Added Design',
39
+ urgency,
40
+ label = 'Say',
41
+ }: {
42
+ message?: string;
43
+ urgency?: 'assertive';
44
+ label?: string;
45
+ }) {
46
+ const announce = useAnnounce();
47
+ return (
48
+ <button type="button" onClick={() => announce(message, urgency)}>
49
+ {label}
50
+ </button>
51
+ );
52
+ }
53
+
54
+ function TwoMessageOwner() {
55
+ const announce = useAnnounce();
56
+ return (
57
+ <>
58
+ <button
59
+ type="button"
60
+ onClick={() => {
61
+ announce('Added Design');
62
+ announce('Removed Eng');
63
+ }}>
64
+ Both
65
+ </button>
66
+ <button type="button" onClick={() => announce('Loading')}>
67
+ Busy
68
+ </button>
69
+ <button type="button" onClick={() => announce('')}>
70
+ Withdraw
71
+ </button>
72
+ </>
73
+ );
74
+ }
75
+
76
+ /** jsdom has no showModal(); stand in for a dialog opened modally. */
77
+ function stubDialogs() {
78
+ HTMLDialogElement.prototype.showModal = vi.fn(function (
79
+ this: HTMLDialogElement,
80
+ ) {
81
+ this.setAttribute('open', '');
82
+ this.dataset.modal = 'true';
83
+ });
84
+ HTMLDialogElement.prototype.show = vi.fn(function (this: HTMLDialogElement) {
85
+ this.setAttribute('open', '');
86
+ delete this.dataset.modal;
87
+ });
88
+ HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
89
+ this.removeAttribute('open');
90
+ delete this.dataset.modal;
91
+ this.dispatchEvent(new Event('close'));
92
+ });
93
+ const matches = Element.prototype.matches;
94
+ vi.spyOn(Element.prototype, 'matches').mockImplementation(function (
95
+ this: Element,
96
+ selector: string,
97
+ ) {
98
+ return selector === ':modal'
99
+ ? this instanceof HTMLDialogElement &&
100
+ this.open &&
101
+ this.dataset.modal === 'true'
102
+ : matches.call(this, selector);
103
+ });
104
+ }
105
+
106
+ async function nextFrame() {
107
+ await act(
108
+ async () =>
109
+ new Promise<void>(resolve => requestAnimationFrame(() => resolve())),
110
+ );
111
+ }
112
+
113
+ const shared = (politeness = 'polite') =>
114
+ document.querySelector(`[data-astryx-live-region="${politeness}"]`);
115
+ const regionIn = (dialog: Element, politeness = 'polite') =>
116
+ dialog.querySelector(
117
+ `:scope > [data-astryx-modal-live-region="${politeness}"]`,
118
+ );
119
+
120
+ beforeEach(() => {
121
+ __resetLiveRegionsForTest();
122
+ stubDialogs();
123
+ });
124
+ afterEach(() => {
125
+ vi.restoreAllMocks();
126
+ });
127
+
128
+ describe('useAnnounce inside Astryx modals (spec:AST-086 FR14)', () => {
129
+ it('uses the shared channel outside any modal', async () => {
130
+ render(<Owner />);
131
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
132
+ await nextFrame();
133
+ expect(shared()).toHaveTextContent('Added Design');
134
+ expect(
135
+ document.querySelector('[data-astryx-modal-live-region]'),
136
+ ).toBeNull();
137
+ });
138
+
139
+ it.each([
140
+ [
141
+ 'Dialog',
142
+ (children: ReactNode) => (
143
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
144
+ {children}
145
+ </Dialog>
146
+ ),
147
+ ],
148
+ [
149
+ 'modal BottomSheet',
150
+ (children: ReactNode) => (
151
+ <BottomSheet isOpen onOpenChange={() => {}} label="Modal">
152
+ {children}
153
+ </BottomSheet>
154
+ ),
155
+ ],
156
+ [
157
+ 'modal Drawer',
158
+ (children: ReactNode) => (
159
+ <Drawer isOpen onOpenChange={() => {}} label="Modal">
160
+ {children}
161
+ </Drawer>
162
+ ),
163
+ ],
164
+ ] as const)(
165
+ 'routes a caller inside an open %s into that dialog, not the shared channel',
166
+ async (_name, wrap) => {
167
+ render(wrap(<Owner />));
168
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
169
+ expect(dialog.matches(':modal')).toBe(true);
170
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
171
+ // Inserted empty (FR3), filled on the next frame.
172
+ const region = regionIn(dialog);
173
+ expect(region).not.toBeNull();
174
+ expect(region).toHaveAttribute('role', 'status');
175
+ expect(region).toHaveAttribute('aria-live', 'polite');
176
+ expect(region).toHaveTextContent('');
177
+ await nextFrame();
178
+ expect(region).toHaveTextContent('Added Design');
179
+ expect(shared()?.textContent ?? '').toBe('');
180
+ },
181
+ );
182
+
183
+ it("routes a caller inside a Popover's bottom-sheet presentation into that sheet", async () => {
184
+ // Popover's `presentation="bottom-sheet"` lazily renders the shared
185
+ // BottomSheet, so the provider BottomSheet renders covers it.
186
+ render(
187
+ <Popover label="Filters" presentation="bottom-sheet" content={<Owner />}>
188
+ <button type="button">Filter</button>
189
+ </Popover>,
190
+ );
191
+ fireEvent.click(screen.getByRole('button', {name: 'Filter'}));
192
+ const dialog = await screen.findByRole('dialog', {name: 'Filters'});
193
+ await screen.findByRole('button', {name: 'Say'});
194
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
195
+ await nextFrame();
196
+ expect(regionIn(dialog)).toHaveTextContent('Added Design');
197
+ expect(shared()?.textContent ?? '').toBe('');
198
+ });
199
+
200
+ it("routes a caller inside a DropdownMenu's bottom-sheet presentation into that sheet", async () => {
201
+ render(
202
+ <DropdownMenu
203
+ button={{label: 'Project actions'}}
204
+ presentation="bottom-sheet"
205
+ items={[{label: 'Edit project', onClick: () => {}}]}
206
+ footer={<Owner />}
207
+ />,
208
+ );
209
+ fireEvent.click(screen.getByRole('button', {name: /Project actions/}));
210
+ const dialog = await screen.findByRole('dialog', {name: 'Project actions'});
211
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
212
+ await nextFrame();
213
+ expect(regionIn(dialog)).toHaveTextContent('Added Design');
214
+ expect(shared()?.textContent ?? '').toBe('');
215
+ });
216
+
217
+ it('holds no MutationObserver for a dialog closed at rest; observes from the open intent until the real close (runtime INV5)', async () => {
218
+ // The provider's watch is the one filtering on open/inert/aria-hidden.
219
+ const isPresentationWatch = (options?: MutationObserverInit) =>
220
+ options?.attributeFilter?.join() === 'open,inert,aria-hidden';
221
+ const observed: Node[] = [];
222
+ const disconnected: number[] = [];
223
+ const Original = globalThis.MutationObserver;
224
+ class Counting extends Original {
225
+ #isWatch = false;
226
+ observe(target: Node, options?: MutationObserverInit) {
227
+ if (isPresentationWatch(options)) {
228
+ this.#isWatch = true;
229
+ observed.push(target);
230
+ }
231
+ super.observe(target, options);
232
+ }
233
+ disconnect() {
234
+ if (this.#isWatch) {
235
+ disconnected.push(1);
236
+ }
237
+ super.disconnect();
238
+ }
239
+ }
240
+ vi.stubGlobal('MutationObserver', Counting);
241
+ try {
242
+ function Closed({isOpen}: {isOpen: boolean}) {
243
+ return (
244
+ <BottomSheet isOpen={isOpen} onOpenChange={() => {}} label="Rest">
245
+ <Owner />
246
+ </BottomSheet>
247
+ );
248
+ }
249
+ const {rerender} = render(<Closed isOpen={false} />);
250
+ expect(observed).toHaveLength(0);
251
+ rerender(<Closed isOpen />);
252
+ await nextFrame();
253
+ expect(observed).toHaveLength(1);
254
+ expect(observed[0]).toBe(screen.getByRole('dialog', {name: 'Rest'}));
255
+ const before = disconnected.length;
256
+ rerender(<Closed isOpen={false} />);
257
+ // The sheet runs its exit, then closes the dialog for real.
258
+ fireEvent.transitionEnd(document.querySelector('.astryx-bottom-sheet')!, {
259
+ propertyName: 'transform',
260
+ });
261
+ await nextFrame();
262
+ await nextFrame();
263
+ expect(disconnected.length).toBeGreaterThan(before);
264
+ } finally {
265
+ vi.unstubAllGlobals();
266
+ }
267
+ });
268
+
269
+ it('routes a caller inside an open Lightbox into its dialog', async () => {
270
+ // Lightbox renders no children; a caption is content inside its dialog.
271
+ render(
272
+ <Lightbox
273
+ isOpen
274
+ onOpenChange={() => {}}
275
+ media={{src: '/photo.jpg', alt: 'Photo', caption: <Owner />}}
276
+ />,
277
+ );
278
+ const dialog = screen.getByRole('dialog', {name: 'Photo'});
279
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
280
+ await nextFrame();
281
+ expect(regionIn(dialog)).toHaveTextContent('Added Design');
282
+ expect(shared()?.textContent ?? '').toBe('');
283
+ });
284
+
285
+ it('keeps the shared channel inside a non-modal sheet with no modal above it', async () => {
286
+ render(
287
+ <BottomSheet
288
+ isOpen
289
+ onOpenChange={() => {}}
290
+ hasScrim={false}
291
+ label="Sheet">
292
+ <Owner />
293
+ </BottomSheet>,
294
+ );
295
+ const dialog = screen.getByRole('dialog', {name: 'Sheet'});
296
+ expect(dialog.matches(':modal')).toBe(false);
297
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
298
+ await nextFrame();
299
+ expect(shared()).toHaveTextContent('Added Design');
300
+ expect(regionIn(dialog)).toBeNull();
301
+ });
302
+
303
+ it('routes a caller inside a non-modal sheet nested in a Dialog to the Dialog', async () => {
304
+ render(
305
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
306
+ <BottomSheet
307
+ isOpen
308
+ onOpenChange={() => {}}
309
+ hasScrim={false}
310
+ label="Sheet">
311
+ <Owner />
312
+ </BottomSheet>
313
+ </Dialog>,
314
+ );
315
+ const modal = screen.getByRole('dialog', {name: 'Modal'});
316
+ const sheet = screen.getByRole('dialog', {name: 'Sheet'});
317
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
318
+ await nextFrame();
319
+ expect(regionIn(modal)).toHaveTextContent('Added Design');
320
+ expect(regionIn(sheet)).toBeNull();
321
+ expect(shared()?.textContent ?? '').toBe('');
322
+ });
323
+
324
+ it('routes a caller inside a modal over a modal to the top one', async () => {
325
+ function Host() {
326
+ const [isUpperOpen, setIsUpperOpen] = useState(false);
327
+ return (
328
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Lower">
329
+ <Owner label="Lower say" message="Lower words" />
330
+ <button type="button" onClick={() => setIsUpperOpen(true)}>
331
+ Open upper
332
+ </button>
333
+ <Dialog
334
+ isOpen={isUpperOpen}
335
+ onOpenChange={setIsUpperOpen}
336
+ aria-label="Upper">
337
+ <Owner label="Upper say" message="Upper words" />
338
+ </Dialog>
339
+ </Dialog>
340
+ );
341
+ }
342
+ render(<Host />);
343
+ const lower = screen.getByRole('dialog', {name: 'Lower'});
344
+ await nextFrame();
345
+ fireEvent.click(screen.getByRole('button', {name: 'Open upper'}));
346
+ const upper = screen.getByRole('dialog', {name: 'Upper'});
347
+ await nextFrame();
348
+ fireEvent.click(screen.getByRole('button', {name: 'Upper say'}));
349
+ fireEvent.click(screen.getByRole('button', {name: 'Lower say'}));
350
+ await nextFrame();
351
+ expect(regionIn(upper)).toHaveTextContent('Upper words');
352
+ // The lower modal is covered: its owner is not operable until the upper
353
+ // one closes, and a message it announces meanwhile is not heard — its
354
+ // container is clear before it is on top again (FR14).
355
+ expect(regionIn(lower)?.textContent ?? '').toBe('');
356
+ expect(shared()?.textContent ?? '').toBe('');
357
+ });
358
+
359
+ it('clears words a modal received while covered before it is on top again (FR14)', async () => {
360
+ function Host() {
361
+ const [isUpperOpen, setIsUpperOpen] = useState(false);
362
+ return (
363
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Lower">
364
+ <Owner label="Lower say" message="Lower words" />
365
+ <button type="button" onClick={() => setIsUpperOpen(true)}>
366
+ Cover
367
+ </button>
368
+ <Dialog
369
+ isOpen={isUpperOpen}
370
+ onOpenChange={setIsUpperOpen}
371
+ aria-label="Upper">
372
+ <button type="button" onClick={() => setIsUpperOpen(false)}>
373
+ Uncover
374
+ </button>
375
+ </Dialog>
376
+ </Dialog>
377
+ );
378
+ }
379
+ render(<Host />);
380
+ const lower = screen.getByRole('dialog', {name: 'Lower'});
381
+ await nextFrame();
382
+ fireEvent.click(screen.getByRole('button', {name: 'Cover'}));
383
+ await nextFrame();
384
+ fireEvent.click(screen.getByRole('button', {name: 'Lower say'}));
385
+ await nextFrame();
386
+ fireEvent.click(screen.getByRole('button', {name: 'Uncover'}));
387
+ await nextFrame();
388
+ await nextFrame();
389
+ // On top again within the clear delay, holding nothing from the time it
390
+ // was covered.
391
+ expect(lower.matches(':modal')).toBe(true);
392
+ expect(regionIn(lower)?.textContent ?? '').toBe('');
393
+ expect(shared()?.textContent ?? '').toBe('');
394
+ // Heard again now that it is on top.
395
+ fireEvent.click(screen.getByRole('button', {name: 'Lower say'}));
396
+ await nextFrame();
397
+ expect(regionIn(lower)).toHaveTextContent('Lower words');
398
+ });
399
+
400
+ it('routes a message announced in the commit that opens its Dialog into the Dialog (the field error a mounting form announces)', async () => {
401
+ function FieldError() {
402
+ const announce = useAnnounce();
403
+ useEffect(() => {
404
+ // The Dialog presents from its own Effect, which runs after this one.
405
+ announce('Name is required', 'assertive');
406
+ }, [announce]);
407
+ return <span>Name is required</span>;
408
+ }
409
+ function Host() {
410
+ const [isOpen, setIsOpen] = useState(false);
411
+ return (
412
+ <>
413
+ <button type="button" onClick={() => setIsOpen(true)}>
414
+ Open
415
+ </button>
416
+ {isOpen && (
417
+ <Dialog isOpen onOpenChange={setIsOpen} aria-label="Edit">
418
+ <FieldError />
419
+ </Dialog>
420
+ )}
421
+ </>
422
+ );
423
+ }
424
+ render(<Host />);
425
+ fireEvent.click(screen.getByRole('button', {name: 'Open'}));
426
+ const dialog = screen.getByRole('dialog', {name: 'Edit'});
427
+ expect(dialog.matches(':modal')).toBe(true);
428
+ await nextFrame();
429
+ await nextFrame();
430
+ expect(regionIn(dialog, 'assertive')).toHaveTextContent('Name is required');
431
+ expect(shared('assertive')?.textContent ?? '').toBe('');
432
+ });
433
+
434
+ it('lets an empty message in the commit that opens the Dialog withdraw a message deferred in that commit (FR9)', async () => {
435
+ function FieldError() {
436
+ const announce = useAnnounce();
437
+ useEffect(() => {
438
+ announce('Name is required', 'assertive');
439
+ // Taken back in the same commit, before the Dialog has presented.
440
+ announce('', 'assertive');
441
+ }, [announce]);
442
+ return <span>Name</span>;
443
+ }
444
+ function Host() {
445
+ const [isOpen, setIsOpen] = useState(false);
446
+ return (
447
+ <>
448
+ <button type="button" onClick={() => setIsOpen(true)}>
449
+ Open
450
+ </button>
451
+ {isOpen && (
452
+ <Dialog isOpen onOpenChange={setIsOpen} aria-label="Edit">
453
+ <FieldError />
454
+ </Dialog>
455
+ )}
456
+ </>
457
+ );
458
+ }
459
+ render(<Host />);
460
+ fireEvent.click(screen.getByRole('button', {name: 'Open'}));
461
+ const dialog = screen.getByRole('dialog', {name: 'Edit'});
462
+ await nextFrame();
463
+ await nextFrame();
464
+ expect(regionIn(dialog, 'assertive')?.textContent ?? '').toBe('');
465
+ expect(shared('assertive')?.textContent ?? '').toBe('');
466
+ });
467
+
468
+ it('lets an empty message withdraw a message announced in the same commit inside an already-open Dialog (FR9)', async () => {
469
+ function Pair() {
470
+ const announce = useAnnounce();
471
+ return (
472
+ <button
473
+ type="button"
474
+ onClick={() => {
475
+ announce('3 results');
476
+ announce('');
477
+ }}>
478
+ Pair
479
+ </button>
480
+ );
481
+ }
482
+ render(
483
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
484
+ <Pair />
485
+ </Dialog>,
486
+ );
487
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
488
+ await nextFrame();
489
+ fireEvent.click(screen.getByRole('button', {name: 'Pair'}));
490
+ await nextFrame();
491
+ await nextFrame();
492
+ expect(regionIn(dialog)?.textContent ?? '').toBe('');
493
+ expect(shared()?.textContent ?? '').toBe('');
494
+ });
495
+
496
+ it("routes a caller inside a closed Dialog (content still mounted) to the shared channel at once, joined with the frame's other messages (FR9)", async () => {
497
+ function Announcer({message}: {message: string}) {
498
+ const announce = useAnnounce();
499
+ useEffect(() => {
500
+ announce(message);
501
+ }, [announce, message]);
502
+ return null;
503
+ }
504
+ render(
505
+ <>
506
+ <Announcer message="Page loaded" />
507
+ <Dialog isOpen={false} onOpenChange={() => {}} aria-label="Closed">
508
+ <Announcer message="Inside closed" />
509
+ </Dialog>
510
+ </>,
511
+ );
512
+ await nextFrame();
513
+ await nextFrame();
514
+ // Both written in one commit, both exposed, in order: neither dropped.
515
+ expect(shared()?.textContent).toBe('Page loaded Inside closed');
516
+ expect(
517
+ document.querySelector('[data-astryx-modal-live-region]'),
518
+ ).toBeNull();
519
+ });
520
+
521
+ it.each([
522
+ [
523
+ 'Dialog',
524
+ (children: ReactNode) => (
525
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Inner">
526
+ {children}
527
+ </Dialog>
528
+ ),
529
+ ],
530
+ [
531
+ 'modal BottomSheet',
532
+ (children: ReactNode) => (
533
+ <BottomSheet isOpen onOpenChange={() => {}} label="Inner">
534
+ {children}
535
+ </BottomSheet>
536
+ ),
537
+ ],
538
+ ] as const)(
539
+ 'routes a message announced in the commit that opens a %s inside an already-open Dialog into the inner modal, not the outer one',
540
+ async (_name, wrapInner) => {
541
+ function FieldError() {
542
+ const announce = useAnnounce();
543
+ useEffect(() => {
544
+ announce('Name is required', 'assertive');
545
+ }, [announce]);
546
+ return <span>Name</span>;
547
+ }
548
+ function Host() {
549
+ const [isInnerOpen, setIsInnerOpen] = useState(false);
550
+ return (
551
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Outer">
552
+ <button type="button" onClick={() => setIsInnerOpen(true)}>
553
+ Open inner
554
+ </button>
555
+ {isInnerOpen && wrapInner(<FieldError />)}
556
+ </Dialog>
557
+ );
558
+ }
559
+ render(<Host />);
560
+ const outer = screen.getByRole('dialog', {name: 'Outer'});
561
+ await nextFrame();
562
+ fireEvent.click(screen.getByRole('button', {name: 'Open inner'}));
563
+ const inner = screen.getByRole('dialog', {name: 'Inner'});
564
+ expect(inner.matches(':modal')).toBe(true);
565
+ await nextFrame();
566
+ await nextFrame();
567
+ expect(regionIn(inner, 'assertive')).toHaveTextContent(
568
+ 'Name is required',
569
+ );
570
+ expect(regionIn(outer, 'assertive')).toBeNull();
571
+ expect(shared('assertive')?.textContent ?? '').toBe('');
572
+ },
573
+ );
574
+
575
+ it('is heard from app code rendered inside a Dialog', async () => {
576
+ function AppForm() {
577
+ const announce = useAnnounce();
578
+ return (
579
+ <form
580
+ onSubmit={event => {
581
+ event.preventDefault();
582
+ announce('Saved');
583
+ }}>
584
+ <button type="submit">Save</button>
585
+ </form>
586
+ );
587
+ }
588
+ render(
589
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Edit">
590
+ <AppForm />
591
+ </Dialog>,
592
+ );
593
+ fireEvent.click(screen.getByRole('button', {name: 'Save'}));
594
+ await nextFrame();
595
+ expect(
596
+ regionIn(screen.getByRole('dialog', {name: 'Edit'})),
597
+ ).toHaveTextContent('Saved');
598
+ expect(shared()?.textContent ?? '').toBe('');
599
+ });
600
+
601
+ it('joins different messages written before the previous is exposed, says an identical repeat once, and clears on an empty message (FR9, FR5)', async () => {
602
+ render(
603
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
604
+ <TwoMessageOwner />
605
+ <Owner urgency="assertive" message="Failed" label="Fail" />
606
+ </Dialog>,
607
+ );
608
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
609
+ fireEvent.click(screen.getByRole('button', {name: 'Both'}));
610
+ fireEvent.click(screen.getByRole('button', {name: 'Both'}));
611
+ await nextFrame();
612
+ expect(regionIn(dialog)?.textContent).toBe('Added Design Removed Eng');
613
+ // A message in the frame the words were written still joins.
614
+ fireEvent.click(screen.getByRole('button', {name: 'Busy'}));
615
+ await nextFrame();
616
+ expect(regionIn(dialog)?.textContent).toBe(
617
+ 'Added Design Removed Eng Loading',
618
+ );
619
+ // A frame later the words count as exposed: a new message starts fresh.
620
+ await nextFrame();
621
+ fireEvent.click(screen.getByRole('button', {name: 'Busy'}));
622
+ await nextFrame();
623
+ expect(regionIn(dialog)?.textContent).toBe('Loading');
624
+ // Assertive has its own container.
625
+ fireEvent.click(screen.getByRole('button', {name: 'Fail'}));
626
+ await nextFrame();
627
+ expect(regionIn(dialog, 'assertive')).toHaveAttribute('role', 'alert');
628
+ expect(regionIn(dialog, 'assertive')).toHaveTextContent('Failed');
629
+ expect(regionIn(dialog)?.textContent).toBe('Loading');
630
+ // An empty message withdraws the pending and shown polite text at once.
631
+ fireEvent.click(screen.getByRole('button', {name: 'Both'}));
632
+ fireEvent.click(screen.getByRole('button', {name: 'Withdraw'}));
633
+ await nextFrame();
634
+ expect(regionIn(dialog)?.textContent).toBe('');
635
+ expect(shared()?.textContent ?? '').toBe('');
636
+ });
637
+
638
+ it('hands a message unexposed when its Dialog closes to the shared channel', async () => {
639
+ function SaveAndClose({onDone}: {onDone: () => void}) {
640
+ const announce = useAnnounce();
641
+ return (
642
+ <button
643
+ type="button"
644
+ onClick={() => {
645
+ announce('Saved');
646
+ onDone();
647
+ }}>
648
+ Save and close
649
+ </button>
650
+ );
651
+ }
652
+ function Host() {
653
+ const [isOpen, setIsOpen] = useState(true);
654
+ return (
655
+ <Dialog isOpen={isOpen} onOpenChange={setIsOpen} aria-label="Edit">
656
+ <SaveAndClose onDone={() => setIsOpen(false)} />
657
+ </Dialog>
658
+ );
659
+ }
660
+ render(<Host />);
661
+ fireEvent.click(screen.getByRole('button', {name: 'Save and close'}));
662
+ await nextFrame();
663
+ await nextFrame();
664
+ // Not lost in the closed dialog: the page-body channel has it.
665
+ expect(shared()).toHaveTextContent('Saved');
666
+ });
667
+
668
+ it('hands a message unexposed when an upper modal closes to the modal then on top', async () => {
669
+ function Palette({onDone}: {onDone: () => void}) {
670
+ const announce = useAnnounce();
671
+ return (
672
+ <button
673
+ type="button"
674
+ onClick={() => {
675
+ announce('3 results');
676
+ onDone();
677
+ }}>
678
+ Pick
679
+ </button>
680
+ );
681
+ }
682
+ function Host() {
683
+ const [isUpperOpen, setIsUpperOpen] = useState(true);
684
+ return (
685
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Lower">
686
+ <Dialog
687
+ isOpen={isUpperOpen}
688
+ onOpenChange={setIsUpperOpen}
689
+ aria-label="Upper">
690
+ <Palette onDone={() => setIsUpperOpen(false)} />
691
+ </Dialog>
692
+ </Dialog>
693
+ );
694
+ }
695
+ render(<Host />);
696
+ const lower = screen.getByRole('dialog', {name: 'Lower'});
697
+ fireEvent.click(screen.getByRole('button', {name: 'Pick'}));
698
+ await nextFrame();
699
+ await nextFrame();
700
+ expect(regionIn(lower)).toHaveTextContent('3 results');
701
+ expect(shared()?.textContent ?? '').toBe('');
702
+ });
703
+
704
+ it('keeps a waiting message in a dialog that is closed and shown again in one task (a hand-over, not a close)', async () => {
705
+ // A switcher moves one shared dialog between steps: close() then
706
+ // showModal() in the same task. The native close event must not hand the
707
+ // step's words to the page body the person cannot hear.
708
+ render(
709
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
710
+ <Owner message="80 results" />
711
+ </Dialog>,
712
+ );
713
+ const dialog = document.querySelector<HTMLDialogElement>('dialog')!;
714
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
715
+ act(() => {
716
+ dialog.close();
717
+ dialog.showModal();
718
+ });
719
+ await nextFrame();
720
+ await nextFrame();
721
+ expect(regionIn(dialog)).toHaveTextContent('80 results');
722
+ expect(shared()?.textContent ?? '').toBe('');
723
+ });
724
+
725
+ it('keeps a waiting message when the dialog is re-presented from a later layout effect', async () => {
726
+ // The entering step is presented in a layout effect of a later commit,
727
+ // not in the task that closed the leaving step.
728
+ function Steps() {
729
+ const [step, setStep] = useState(1);
730
+ const dialogRef = useRef<HTMLDialogElement>(null);
731
+ useLayoutEffect(() => {
732
+ const dialog = dialogRef.current;
733
+ if (dialog != null && !dialog.open) {
734
+ dialog.showModal();
735
+ }
736
+ }, [step]);
737
+ return (
738
+ <Dialog
739
+ ref={dialogRef}
740
+ isOpen
741
+ onOpenChange={() => {}}
742
+ aria-label="Modal">
743
+ <Owner message={`Step ${step} words`} />
744
+ <button
745
+ type="button"
746
+ onClick={() => {
747
+ // Close the dialog as the leaving step would, and move on; the
748
+ // next commit's layout effect presents the entering step.
749
+ dialogRef.current?.close();
750
+ setStep(2);
751
+ }}>
752
+ Next
753
+ </button>
754
+ </Dialog>
755
+ );
756
+ }
757
+ render(<Steps />);
758
+ const dialog = document.querySelector<HTMLDialogElement>('dialog')!;
759
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
760
+ fireEvent.click(screen.getByRole('button', {name: 'Next'}));
761
+ expect(dialog.open).toBe(true);
762
+ await nextFrame();
763
+ await nextFrame();
764
+ expect(regionIn(dialog)).toHaveTextContent('Step 1 words');
765
+ expect(shared()?.textContent ?? '').toBe('');
766
+ });
767
+
768
+ it('hands a message unexposed when a step closes to the sibling step opened in its place (the modal then on top)', async () => {
769
+ // A flow of sibling modals, as a switcher presents its steps: the leaving
770
+ // step announces and closes in the same update that opens the entering
771
+ // step. The entering step is not an ancestor of the leaving one; it is
772
+ // the modal on top after the close, so the words are delivered there.
773
+ function Flow() {
774
+ const [step, setStep] = useState(1);
775
+ return (
776
+ <>
777
+ <Dialog isOpen={step === 1} onOpenChange={() => {}} aria-label="One">
778
+ <Owner message="Step one saved" label="Say" />
779
+ <button type="button" onClick={() => setStep(2)}>
780
+ Next
781
+ </button>
782
+ </Dialog>
783
+ <Dialog isOpen={step === 2} onOpenChange={() => {}} aria-label="Two">
784
+ <span>Step two</span>
785
+ </Dialog>
786
+ </>
787
+ );
788
+ }
789
+ render(<Flow />);
790
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
791
+ fireEvent.click(screen.getByRole('button', {name: 'Next'}));
792
+ const two = screen.getByRole('dialog', {name: 'Two'});
793
+ await nextFrame();
794
+ await nextFrame();
795
+ expect(regionIn(two)).toHaveTextContent('Step one saved');
796
+ expect(shared()?.textContent ?? '').toBe('');
797
+ });
798
+
799
+ it('holds words sent as a modal BottomSheet closes — open but inert and aria-hidden through its exit — and delivers them to the page body at the real close', async () => {
800
+ function Host() {
801
+ const [isOpen, setIsOpen] = useState(true);
802
+ return (
803
+ <BottomSheet isOpen={isOpen} onOpenChange={setIsOpen} label="Sheet">
804
+ <Owner message="Saved" />
805
+ <button type="button" onClick={() => setIsOpen(false)}>
806
+ Done
807
+ </button>
808
+ </BottomSheet>
809
+ );
810
+ }
811
+ render(<Host />);
812
+ const sheet = document.querySelector<HTMLDialogElement>('dialog')!;
813
+ await nextFrame();
814
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
815
+ fireEvent.click(screen.getByRole('button', {name: 'Done'}));
816
+ // The sheet keeps its dialog open and modal while it leaves, but takes
817
+ // it out of the accessibility tree; the page body is behind an active
818
+ // modal until the dialog closes, so nothing is exposed yet and the
819
+ // words wait.
820
+ expect(sheet.open).toBe(true);
821
+ expect(sheet).toHaveAttribute('aria-hidden', 'true');
822
+ expect(sheet).toHaveAttribute('inert');
823
+ await nextFrame();
824
+ await nextFrame();
825
+ expect(regionIn(sheet)?.textContent ?? '').toBe('');
826
+ expect(shared()?.textContent ?? '').toBe('');
827
+ // The exit motion ends: the dialog closes and the page body is exposed.
828
+ act(() => {
829
+ sheet.close();
830
+ });
831
+ await nextFrame();
832
+ await nextFrame();
833
+ expect(shared()).toHaveTextContent('Saved');
834
+ });
835
+ it('drops held words when an empty message withdraws them while the sheet exits, so nothing is delivered after the close', async () => {
836
+ function Host() {
837
+ const [isOpen, setIsOpen] = useState(true);
838
+ return (
839
+ <BottomSheet isOpen={isOpen} onOpenChange={setIsOpen} label="Sheet">
840
+ <TwoMessageOwner />
841
+ <button type="button" onClick={() => setIsOpen(false)}>
842
+ Done
843
+ </button>
844
+ </BottomSheet>
845
+ );
846
+ }
847
+ render(<Host />);
848
+ const sheet = document.querySelector<HTMLDialogElement>('dialog')!;
849
+ await nextFrame();
850
+ fireEvent.click(screen.getByRole('button', {name: 'Busy'}));
851
+ fireEvent.click(screen.getByRole('button', {name: 'Done'}));
852
+ // Held for the real close, as the sheet-exit test shows...
853
+ expect(sheet).toHaveAttribute('inert');
854
+ await nextFrame();
855
+ // ...until the owner takes the words back with an empty message (the
856
+ // exiting sheet is aria-hidden, so reach its control by element).
857
+ fireEvent.click(screen.getByText('Withdraw'));
858
+ act(() => {
859
+ sheet.close();
860
+ });
861
+ await nextFrame();
862
+ await nextFrame();
863
+ expect(shared()?.textContent ?? '').toBe('');
864
+ expect(regionIn(sheet)?.textContent ?? '').toBe('');
865
+ });
866
+
867
+ it('hands words sent as a switcher step hands over to the entering step', async () => {
868
+ window.scrollTo = vi.fn();
869
+ vi.stubGlobal(
870
+ 'matchMedia',
871
+ vi.fn().mockReturnValue({
872
+ matches: false,
873
+ media: '',
874
+ onchange: null,
875
+ addEventListener: vi.fn(),
876
+ removeEventListener: vi.fn(),
877
+ addListener: vi.fn(),
878
+ removeListener: vi.fn(),
879
+ dispatchEvent: vi.fn(),
880
+ }),
881
+ );
882
+ function Flow() {
883
+ const [activeSheet, setActiveSheet] = useState<string | null>('one');
884
+ return (
885
+ <BottomSheetSwitcher
886
+ activeSheet={activeSheet}
887
+ onActiveSheetChange={setActiveSheet}>
888
+ <BottomSheet sheetId="one" label="One">
889
+ <Owner message="Overview saved" />
890
+ <button type="button" onClick={() => setActiveSheet('two')}>
891
+ Continue
892
+ </button>
893
+ </BottomSheet>
894
+ <BottomSheet sheetId="two" label="Two">
895
+ <span>Step two</span>
896
+ </BottomSheet>
897
+ </BottomSheetSwitcher>
898
+ );
899
+ }
900
+ render(<Flow />);
901
+ const one = screen.getByRole('dialog', {name: 'One'});
902
+ await nextFrame();
903
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
904
+ fireEvent.click(screen.getByRole('button', {name: 'Continue'}));
905
+ const two = screen.getByRole('dialog', {name: 'Two'});
906
+ // The leaving step stays open but inert through its exit; the entering
907
+ // step is the exposed modal.
908
+ expect(one).toHaveAttribute('open');
909
+ expect(one).toHaveAttribute('inert');
910
+ expect(two.matches(':modal')).toBe(true);
911
+ await nextFrame();
912
+ await nextFrame();
913
+ expect(regionIn(two)).toHaveTextContent('Overview saved');
914
+ expect(regionIn(one)?.textContent ?? '').toBe('');
915
+ expect(shared()?.textContent ?? '').toBe('');
916
+ vi.unstubAllGlobals();
917
+ });
918
+
919
+ it('hands words sent just before an open Dialog is unmounted to the shared channel', async () => {
920
+ function Host() {
921
+ const [isOpen, setIsOpen] = useState(true);
922
+ return isOpen ? (
923
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Edit">
924
+ <Owner message="Saved" />
925
+ <button type="button" onClick={() => setIsOpen(false)}>
926
+ Remove
927
+ </button>
928
+ </Dialog>
929
+ ) : null;
930
+ }
931
+ render(<Host />);
932
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
933
+ fireEvent.click(screen.getByRole('button', {name: 'Remove'}));
934
+ expect(screen.queryByRole('dialog')).toBeNull();
935
+ await nextFrame();
936
+ await nextFrame();
937
+ expect(shared()).toHaveTextContent('Saved');
938
+ });
939
+
940
+ it('announces a busy start inside a native modal an app renders without Astryx, opened inside a Dialog, in the app modal (FR14)', async () => {
941
+ function BusyThing({isBusy}: {isBusy: boolean}) {
942
+ const ref = useRef<HTMLDivElement>(null);
943
+ useBusyAnnouncement(isBusy, 'Loading', ref);
944
+ return <div ref={ref}>thing</div>;
945
+ }
946
+ function Host() {
947
+ const appDialogRef = useRef<HTMLDialogElement>(null);
948
+ const [isBusy, setIsBusy] = useState(false);
949
+ useLayoutEffect(() => {
950
+ appDialogRef.current?.showModal();
951
+ }, []);
952
+ return (
953
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Outer">
954
+ <dialog ref={appDialogRef} aria-label="App">
955
+ <BusyThing isBusy={isBusy} />
956
+ <button type="button" onClick={() => setIsBusy(true)}>
957
+ Start
958
+ </button>
959
+ </dialog>
960
+ </Dialog>
961
+ );
962
+ }
963
+ render(<Host />);
964
+ const outer = screen.getByRole('dialog', {name: 'Outer'});
965
+ const app = screen.getByRole('dialog', {name: 'App'});
966
+ expect(app.matches(':modal')).toBe(true);
967
+ fireEvent.click(screen.getByRole('button', {name: 'Start'}));
968
+ // The busy hook chooses its route a frame later and the region fills a
969
+ // frame after that.
970
+ await nextFrame();
971
+ await nextFrame();
972
+ expect(regionIn(app)).toHaveTextContent('Loading');
973
+ expect(regionIn(outer)).toBeNull();
974
+ expect(shared()?.textContent ?? '').toBe('');
975
+ });
976
+
977
+ it('routes a caller inside an open MobileNav into its dialog', async () => {
978
+ render(
979
+ <MobileNav isOpen onOpenChange={() => {}} label="Menu">
980
+ <Owner />
981
+ </MobileNav>,
982
+ );
983
+ const nav = screen.getByRole('dialog', {name: 'Menu'});
984
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
985
+ await nextFrame();
986
+ expect(regionIn(nav)).toHaveTextContent('Added Design');
987
+ expect(shared()?.textContent ?? '').toBe('');
988
+ });
989
+
990
+ it('keeps the step the person went back to on top while the leaving step exits, so its messages are heard', async () => {
991
+ window.scrollTo = vi.fn();
992
+ vi.stubGlobal(
993
+ 'matchMedia',
994
+ vi.fn().mockReturnValue({
995
+ matches: false,
996
+ media: '',
997
+ onchange: null,
998
+ addEventListener: vi.fn(),
999
+ removeEventListener: vi.fn(),
1000
+ addListener: vi.fn(),
1001
+ removeListener: vi.fn(),
1002
+ dispatchEvent: vi.fn(),
1003
+ }),
1004
+ );
1005
+ function Flow() {
1006
+ const [activeSheet, setActiveSheet] = useState<string | null>('one');
1007
+ return (
1008
+ <BottomSheetSwitcher
1009
+ activeSheet={activeSheet}
1010
+ onActiveSheetChange={setActiveSheet}>
1011
+ <BottomSheet sheetId="one" label="One">
1012
+ <Owner message="Back on one" />
1013
+ <button type="button" onClick={() => setActiveSheet('two')}>
1014
+ Continue
1015
+ </button>
1016
+ </BottomSheet>
1017
+ <BottomSheet sheetId="two" label="Two">
1018
+ <button type="button" onClick={() => setActiveSheet('one')}>
1019
+ Back
1020
+ </button>
1021
+ </BottomSheet>
1022
+ </BottomSheetSwitcher>
1023
+ );
1024
+ }
1025
+ render(<Flow />);
1026
+ const one = screen.getByRole('dialog', {name: 'One'});
1027
+ // Hidden steps are out of the accessibility tree; reach it by element.
1028
+ const two = document.querySelector<HTMLDialogElement>(
1029
+ 'dialog[aria-label="Two"]',
1030
+ )!;
1031
+ await nextFrame();
1032
+ fireEvent.click(screen.getByRole('button', {name: 'Continue'}));
1033
+ await nextFrame();
1034
+ fireEvent.click(screen.getByRole('button', {name: 'Back'}));
1035
+ await nextFrame();
1036
+ // Two is leaving: still open, inert; one is the exposed step again.
1037
+ expect(two).toHaveAttribute('open');
1038
+ expect(two).toHaveAttribute('inert');
1039
+ expect(one.matches(':modal')).toBe(true);
1040
+ expect(one).not.toHaveAttribute('inert');
1041
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
1042
+ await nextFrame();
1043
+ expect(regionIn(one)).toHaveTextContent('Back on one');
1044
+ expect(shared()?.textContent ?? '').toBe('');
1045
+ vi.unstubAllGlobals();
1046
+ });
1047
+
1048
+ it('holds words sent as a modal BottomSheet over a Dialog closes and delivers them to the Dialog at the real close', async () => {
1049
+ function Host() {
1050
+ const [isSheetOpen, setIsSheetOpen] = useState(false);
1051
+ return (
1052
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Edit">
1053
+ <button type="button" onClick={() => setIsSheetOpen(true)}>
1054
+ Open sheet
1055
+ </button>
1056
+ <BottomSheet
1057
+ isOpen={isSheetOpen}
1058
+ onOpenChange={setIsSheetOpen}
1059
+ label="Sheet">
1060
+ <Owner message="Saved" />
1061
+ <button type="button" onClick={() => setIsSheetOpen(false)}>
1062
+ Done
1063
+ </button>
1064
+ </BottomSheet>
1065
+ </Dialog>
1066
+ );
1067
+ }
1068
+ render(<Host />);
1069
+ const edit = screen.getByRole('dialog', {name: 'Edit'});
1070
+ await nextFrame();
1071
+ fireEvent.click(screen.getByRole('button', {name: 'Open sheet'}));
1072
+ const sheet = screen.getByRole('dialog', {name: 'Sheet'});
1073
+ await nextFrame();
1074
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
1075
+ fireEvent.click(screen.getByRole('button', {name: 'Done'}));
1076
+ // The sheet, still an open modal through its exit, covers the Dialog:
1077
+ // nothing is exposed yet, so the words wait rather than being written
1078
+ // to the covered Dialog (which would clear them).
1079
+ expect(sheet).toHaveAttribute('inert');
1080
+ await nextFrame();
1081
+ await nextFrame();
1082
+ expect(regionIn(sheet)?.textContent ?? '').toBe('');
1083
+ expect(regionIn(edit)?.textContent ?? '').toBe('');
1084
+ expect(shared()?.textContent ?? '').toBe('');
1085
+ act(() => {
1086
+ (sheet as HTMLDialogElement).close();
1087
+ });
1088
+ await nextFrame();
1089
+ await nextFrame();
1090
+ expect(regionIn(edit)).toHaveTextContent('Saved');
1091
+ expect(shared()?.textContent ?? '').toBe('');
1092
+ });
1093
+ it('withdraws a busy start written inside a modal but not yet exposed when its owner settles with its outcome (AST-086 FR8)', async () => {
1094
+ function Search() {
1095
+ const ref = useRef<HTMLDivElement>(null);
1096
+ const announce = useAnnounce();
1097
+ const [isBusy, setIsBusy] = useState(false);
1098
+ const settle = useBusyAnnouncement(isBusy, 'Loading', ref);
1099
+ return (
1100
+ <div ref={ref}>
1101
+ <button type="button" onClick={() => setIsBusy(true)}>
1102
+ Start
1103
+ </button>
1104
+ <button
1105
+ type="button"
1106
+ onClick={() => {
1107
+ settle();
1108
+ setIsBusy(false);
1109
+ announce('3 results');
1110
+ }}>
1111
+ Outcome
1112
+ </button>
1113
+ </div>
1114
+ );
1115
+ }
1116
+ render(
1117
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
1118
+ <Search />
1119
+ </Dialog>,
1120
+ );
1121
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
1122
+ await nextFrame();
1123
+ fireEvent.click(screen.getByRole('button', {name: 'Start'}));
1124
+ // The busy hook chooses its route a frame later and writes "Loading" to
1125
+ // the dialog's container, to be exposed a frame after that...
1126
+ await nextFrame();
1127
+ // ...but the outcome arrives first and the owner settles.
1128
+ fireEvent.click(screen.getByRole('button', {name: 'Outcome'}));
1129
+ await nextFrame();
1130
+ await nextFrame();
1131
+ expect(regionIn(dialog)?.textContent).toBe('3 results');
1132
+ expect(shared()?.textContent ?? '').toBe('');
1133
+ });
1134
+
1135
+ it('withdraws only its own busy start inside a modal when another owner wrote the same words (AST-086 FR8, FR9)', async () => {
1136
+ function Busy({label}: {label: string}) {
1137
+ const ref = useRef<HTMLDivElement>(null);
1138
+ const [isBusy, setIsBusy] = useState(false);
1139
+ const settle = useBusyAnnouncement(isBusy, 'Loading', ref);
1140
+ return (
1141
+ <div ref={ref}>
1142
+ <button type="button" onClick={() => setIsBusy(true)}>
1143
+ Start {label}
1144
+ </button>
1145
+ <button type="button" onClick={() => settle()}>
1146
+ Settle {label}
1147
+ </button>
1148
+ </div>
1149
+ );
1150
+ }
1151
+ render(
1152
+ <Dialog isOpen onOpenChange={() => {}} aria-label="Modal">
1153
+ <Busy label="one" />
1154
+ <Busy label="two" />
1155
+ </Dialog>,
1156
+ );
1157
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
1158
+ await nextFrame();
1159
+ fireEvent.click(screen.getByRole('button', {name: 'Start one'}));
1160
+ fireEvent.click(screen.getByRole('button', {name: 'Start two'}));
1161
+ await nextFrame();
1162
+ fireEvent.click(screen.getByRole('button', {name: 'Settle one'}));
1163
+ await nextFrame();
1164
+ await nextFrame();
1165
+ expect(regionIn(dialog)?.textContent).toBe('Loading');
1166
+ });
1167
+
1168
+ describe('a non-modal Drawer (hasScrim={false}, shown with showPopover(), never `open`)', () => {
1169
+ beforeEach(() => {
1170
+ // The real showPopover() leaves the dialog's `open` attribute unset.
1171
+ HTMLElement.prototype.showPopover = vi.fn();
1172
+ HTMLElement.prototype.hidePopover = vi.fn();
1173
+ });
1174
+
1175
+ it('routes a caller inside it to the shared channel at once, joined with a page message from the same task (FR9)', async () => {
1176
+ function Announcer({message}: {message: string}) {
1177
+ const announce = useAnnounce();
1178
+ useEffect(() => {
1179
+ announce(message);
1180
+ }, [announce, message]);
1181
+ return null;
1182
+ }
1183
+ render(
1184
+ <>
1185
+ <Announcer message="Page loaded" />
1186
+ <Drawer isOpen onOpenChange={() => {}} hasScrim={false} label="Side">
1187
+ <Announcer message="Inside drawer" />
1188
+ </Drawer>
1189
+ </>,
1190
+ );
1191
+ const drawer = document.querySelector<HTMLDialogElement>('dialog')!;
1192
+ expect(drawer.open).toBe(false);
1193
+ expect(HTMLElement.prototype.showPopover).toHaveBeenCalled();
1194
+ await nextFrame();
1195
+ await nextFrame();
1196
+ expect(shared()?.textContent).toBe('Page loaded Inside drawer');
1197
+ expect(regionIn(drawer)).toBeNull();
1198
+ });
1199
+
1200
+ it('lets a busy start inside it be withdrawn by its outcome (FR8)', async () => {
1201
+ function Search() {
1202
+ const ref = useRef<HTMLDivElement>(null);
1203
+ const announce = useAnnounce();
1204
+ const [isBusy, setIsBusy] = useState(false);
1205
+ const settle = useBusyAnnouncement(isBusy, 'Loading', ref);
1206
+ return (
1207
+ <div ref={ref}>
1208
+ <button type="button" onClick={() => setIsBusy(true)}>
1209
+ Start
1210
+ </button>
1211
+ <button
1212
+ type="button"
1213
+ onClick={() => {
1214
+ settle();
1215
+ setIsBusy(false);
1216
+ announce('3 results');
1217
+ }}>
1218
+ Outcome
1219
+ </button>
1220
+ </div>
1221
+ );
1222
+ }
1223
+ render(
1224
+ <Drawer isOpen onOpenChange={() => {}} hasScrim={false} label="Side">
1225
+ <Search />
1226
+ </Drawer>,
1227
+ );
1228
+ await nextFrame();
1229
+ fireEvent.click(screen.getByRole('button', {name: 'Start'}));
1230
+ await nextFrame();
1231
+ fireEvent.click(screen.getByRole('button', {name: 'Outcome'}));
1232
+ await nextFrame();
1233
+ await nextFrame();
1234
+ expect(shared()?.textContent).toBe('3 results');
1235
+ });
1236
+ });
1237
+
1238
+ it('takes the route of where the call is: a component that renders a Dialog but announces from above it uses the shared channel', async () => {
1239
+ function Opener() {
1240
+ const announce = useAnnounce();
1241
+ const dialogRef = useRef<HTMLDialogElement>(null);
1242
+ return (
1243
+ <>
1244
+ <button type="button" onClick={() => announce('From above')}>
1245
+ Above
1246
+ </button>
1247
+ <Dialog
1248
+ ref={dialogRef}
1249
+ isOpen
1250
+ onOpenChange={() => {}}
1251
+ aria-label="Modal">
1252
+ <Owner message="From inside" label="Inside" />
1253
+ </Dialog>
1254
+ </>
1255
+ );
1256
+ }
1257
+ render(<Opener />);
1258
+ const dialog = screen.getByRole('dialog', {name: 'Modal'});
1259
+ fireEvent.click(screen.getByRole('button', {name: 'Above'}));
1260
+ fireEvent.click(screen.getByRole('button', {name: 'Inside'}));
1261
+ await nextFrame();
1262
+ expect(shared()).toHaveTextContent('From above');
1263
+ expect(regionIn(dialog)).toHaveTextContent('From inside');
1264
+ });
1265
+
1266
+ it('lets a component that owns a modal route its own messages into it through the provider it renders', async () => {
1267
+ // The FR14 route for CommandPalette's counts and Lightbox's position:
1268
+ // the owner renders the provider around the part of itself that
1269
+ // announces about the modal's content.
1270
+ function OwnerOfModal() {
1271
+ const dialogRef = useRef<HTMLDialogElement>(null);
1272
+ return (
1273
+ <Dialog
1274
+ ref={dialogRef}
1275
+ isOpen
1276
+ onOpenChange={() => {}}
1277
+ aria-label="Modal">
1278
+ <ModalAnnounceProvider dialogRef={dialogRef} isOpen>
1279
+ <Owner message="Routed in" />
1280
+ </ModalAnnounceProvider>
1281
+ </Dialog>
1282
+ );
1283
+ }
1284
+ render(<OwnerOfModal />);
1285
+ fireEvent.click(screen.getByRole('button', {name: 'Say'}));
1286
+ await nextFrame();
1287
+ expect(
1288
+ regionIn(screen.getByRole('dialog', {name: 'Modal'})),
1289
+ ).toHaveTextContent('Routed in');
1290
+ });
1291
+ });