@astryxdesign/core 0.7.6-canary.fa3f760 → 0.7.6-canary.fc44bc3

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 (2671) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  2. package/dist/AlertDialog/AlertDialog.js +4 -2
  3. package/dist/AppShell/AppShell.d.ts.map +1 -1
  4. package/dist/AppShell/AppShell.js +225 -35
  5. package/dist/AppShell/observeMainOverflow.d.ts +9 -0
  6. package/dist/AppShell/observeMainOverflow.d.ts.map +1 -0
  7. package/dist/AppShell/observeMainOverflow.js +125 -0
  8. package/dist/Avatar/Avatar.d.ts +1 -1
  9. package/dist/Avatar/Avatar.d.ts.map +1 -1
  10. package/dist/Avatar/Avatar.js +6 -4
  11. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.js +4 -2
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  15. package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -3
  16. package/dist/Badge/Badge.d.ts.map +1 -1
  17. package/dist/Badge/Badge.js +2 -1
  18. package/dist/Banner/Banner.d.ts.map +1 -1
  19. package/dist/Banner/Banner.js +10 -7
  20. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  21. package/dist/BottomSheet/BottomSheet.js +37 -6
  22. package/dist/BottomSheet/BottomSheetPanel.d.ts +11 -1
  23. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  24. package/dist/BottomSheet/BottomSheetPanel.js +50 -10
  25. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +11 -8
  26. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  27. package/dist/BottomSheet/BottomSheetSwitcher.js +27 -10
  28. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +8 -0
  29. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
  30. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -1
  31. package/dist/BottomSheet/useMobileKeyboard.js +44 -8
  32. package/dist/BottomSheet/useSheetGestures.d.ts +36 -6
  33. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  34. package/dist/BottomSheet/useSheetGestures.js +67 -10
  35. package/dist/Breadcrumbs/BreadcrumbItem.js +4 -2
  36. package/dist/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  37. package/dist/Breadcrumbs/Breadcrumbs.js +6 -3
  38. package/dist/Button/Button.d.ts +1 -1
  39. package/dist/Button/Button.d.ts.map +1 -1
  40. package/dist/Button/Button.js +19 -10
  41. package/dist/Calendar/Calendar.d.ts.map +1 -1
  42. package/dist/Calendar/Calendar.js +14 -12
  43. package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
  44. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -7
  45. package/dist/Carousel/Carousel.d.ts +3 -1
  46. package/dist/Carousel/Carousel.d.ts.map +1 -1
  47. package/dist/Carousel/Carousel.js +18 -6
  48. package/dist/Center/Center.d.ts +1 -1
  49. package/dist/Center/Center.js +1 -1
  50. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  51. package/dist/Chat/ChatComposer.js +21 -9
  52. package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
  53. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  54. package/dist/Chat/ChatComposerDrawer.js +5 -3
  55. package/dist/Chat/ChatComposerInput.d.ts +1 -1
  56. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  57. package/dist/Chat/ChatComposerInput.js +7 -4
  58. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  59. package/dist/Chat/ChatDictationButton.js +6 -3
  60. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  61. package/dist/Chat/ChatLayout.js +7 -4
  62. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  63. package/dist/Chat/ChatLayoutScrollButton.js +6 -3
  64. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  65. package/dist/Chat/ChatMessage.js +12 -4
  66. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  67. package/dist/Chat/ChatMessageList.js +7 -3
  68. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  69. package/dist/Chat/ChatMessageMetadata.js +4 -2
  70. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  71. package/dist/Chat/ChatPastedTextToken.js +23 -7
  72. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  73. package/dist/Chat/ChatSendButton.js +6 -3
  74. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  75. package/dist/Chat/ChatSystemMessage.js +2 -1
  76. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  77. package/dist/Chat/ChatToolCalls.js +7 -4
  78. package/dist/Chat/chatMessage.vars.stylex.d.ts +16 -0
  79. package/dist/Chat/chatMessage.vars.stylex.d.ts.map +1 -0
  80. package/dist/Chat/chatMessage.vars.stylex.js +19 -0
  81. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  82. package/dist/Chat/useSpeechRecognition.js +5 -2
  83. package/dist/Chat/useTriggerMenu.d.ts +1 -1
  84. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  85. package/dist/Chat/useTriggerMenu.js +19 -31
  86. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  87. package/dist/CheckboxInput/CheckboxInput.js +5 -3
  88. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  89. package/dist/CheckboxList/CheckboxList.js +5 -2
  90. package/dist/CheckboxList/CheckboxListContext.d.ts +8 -0
  91. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  92. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  93. package/dist/CheckboxList/CheckboxListItem.js +10 -4
  94. package/dist/Citation/Citation.d.ts.map +1 -1
  95. package/dist/Citation/Citation.js +4 -2
  96. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  97. package/dist/ClickableCard/ClickableCard.js +37 -4
  98. package/dist/Code/Code.d.ts +1 -1
  99. package/dist/Code/Code.js +1 -1
  100. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  101. package/dist/CodeBlock/CodeBlock.js +30 -8
  102. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  103. package/dist/Collapsible/Collapsible.js +23 -3
  104. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  105. package/dist/CommandPalette/CommandPalette.js +24 -8
  106. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  107. package/dist/CommandPalette/CommandPaletteEmpty.js +1 -0
  108. package/dist/CommandPalette/CommandPaletteFooter.d.ts.map +1 -1
  109. package/dist/CommandPalette/CommandPaletteFooter.js +4 -2
  110. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  111. package/dist/CommandPalette/CommandPaletteInput.js +12 -7
  112. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  113. package/dist/CommandPalette/CommandPaletteList.js +4 -2
  114. package/dist/ComplexSelector/ComplexSelector.d.ts +2 -2
  115. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  116. package/dist/ComplexSelector/ComplexSelector.js +53 -8
  117. package/dist/ContextMenu/ContextMenu.d.ts +6 -0
  118. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  119. package/dist/ContextMenu/ContextMenu.js +35 -9
  120. package/dist/DateInput/DateInput.d.ts +3 -2
  121. package/dist/DateInput/DateInput.d.ts.map +1 -1
  122. package/dist/DateInput/DateInput.js +7 -8
  123. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  124. package/dist/DateInput/MonthScroller.js +21 -21
  125. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  126. package/dist/DateInput/NativeDateField.js +7 -8
  127. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  128. package/dist/DateInput/TouchDateField.js +12 -12
  129. package/dist/DateInput/Wheel.d.ts.map +1 -1
  130. package/dist/DateInput/Wheel.js +11 -7
  131. package/dist/DateInput/usePointerDragScroll.d.ts +10 -1
  132. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  133. package/dist/DateInput/usePointerDragScroll.js +25 -9
  134. package/dist/DateInput/useScrollSettle.d.ts +3 -1
  135. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  136. package/dist/DateInput/useScrollSettle.js +37 -8
  137. package/dist/DateRangeInput/DateRangeInput.d.ts +3 -2
  138. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  139. package/dist/DateRangeInput/DateRangeInput.js +15 -12
  140. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  141. package/dist/DateTimeInput/DateTimeInput.js +41 -20
  142. package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -1
  143. package/dist/DateTimeInput/NativeDateSegment.js +5 -2
  144. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  145. package/dist/DateTimeInput/NativeTimeSegment.js +5 -2
  146. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  147. package/dist/DateTimeInput/TouchDateTimeField.js +12 -12
  148. package/dist/Dialog/Dialog.d.ts +1 -1
  149. package/dist/Dialog/Dialog.d.ts.map +1 -1
  150. package/dist/Dialog/Dialog.js +30 -18
  151. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  152. package/dist/Dialog/DialogHeader.js +4 -2
  153. package/dist/Drawer/Drawer.d.ts +2 -2
  154. package/dist/Drawer/Drawer.d.ts.map +1 -1
  155. package/dist/Drawer/Drawer.js +22 -4
  156. package/dist/Drawer/DrawerHeader.d.ts.map +1 -1
  157. package/dist/Drawer/DrawerHeader.js +4 -2
  158. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
  159. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  160. package/dist/DropdownMenu/DropdownMenu.js +60 -92
  161. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +3 -2
  162. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  163. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -3
  164. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  165. package/dist/DropdownMenu/DropdownMenuGroup.js +2 -1
  166. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  167. package/dist/DropdownMenu/DropdownMenuItem.js +4 -3
  168. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +4 -3
  169. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  170. package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -3
  171. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  172. package/dist/DropdownMenu/DropdownMenuSubMenu.js +15 -9
  173. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  174. package/dist/DropdownMenu/MenuBottomSheetActionList.js +9 -3
  175. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +17 -8
  176. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  177. package/dist/DropdownMenu/lazyMenuBottomSheet.js +23 -9
  178. package/dist/Field/Field.d.ts +2 -2
  179. package/dist/Field/Field.d.ts.map +1 -1
  180. package/dist/Field/FieldLabel.d.ts +1 -1
  181. package/dist/Field/FieldLabel.d.ts.map +1 -1
  182. package/dist/Field/FieldLabel.js +24 -5
  183. package/dist/Field/InputClearButton.d.ts.map +1 -1
  184. package/dist/Field/InputClearButton.js +5 -3
  185. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  186. package/dist/Field/PanelSearchInput.js +10 -5
  187. package/dist/Field/fieldStatusPlacement.d.ts +15 -0
  188. package/dist/Field/fieldStatusPlacement.d.ts.map +1 -0
  189. package/dist/Field/fieldStatusPlacement.js +1 -0
  190. package/dist/Field/index.d.ts +1 -0
  191. package/dist/Field/index.d.ts.map +1 -1
  192. package/dist/Field/inputDisabledFocus.d.ts +16 -3
  193. package/dist/Field/inputDisabledFocus.d.ts.map +1 -1
  194. package/dist/Field/inputDisabledFocus.js +19 -3
  195. package/dist/Field/inputStyles.stylex.d.ts +12 -9
  196. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  197. package/dist/Field/inputStyles.stylex.js +12 -9
  198. package/dist/FieldStatus/FieldStatus.d.ts +16 -28
  199. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  200. package/dist/FieldStatus/FieldStatus.js +26 -3
  201. package/dist/FieldStatus/index.d.ts +7 -0
  202. package/dist/FieldStatus/index.d.ts.map +1 -1
  203. package/dist/FileInput/FileInput.d.ts +10 -2
  204. package/dist/FileInput/FileInput.d.ts.map +1 -1
  205. package/dist/FileInput/FileInput.js +90 -37
  206. package/dist/Grid/Grid.d.ts +6 -4
  207. package/dist/Grid/Grid.d.ts.map +1 -1
  208. package/dist/Grid/GridSpan.d.ts +2 -0
  209. package/dist/Grid/GridSpan.d.ts.map +1 -1
  210. package/dist/Grid/GridSpan.js +2 -0
  211. package/dist/Heading/Heading.d.ts +5 -3
  212. package/dist/Heading/Heading.d.ts.map +1 -1
  213. package/dist/Heading/Heading.js +5 -3
  214. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  215. package/dist/HoverCard/useHoverCard.js +7 -0
  216. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  217. package/dist/InputGroup/groupStyles.js +12 -6
  218. package/dist/Item/Item.d.ts.map +1 -1
  219. package/dist/Item/Item.js +30 -13
  220. package/dist/Item/ItemSwipeLayer.d.ts.map +1 -1
  221. package/dist/Item/ItemSwipeLayer.js +8 -2
  222. package/dist/Kbd/Kbd.d.ts.map +1 -1
  223. package/dist/Kbd/Kbd.js +7 -3
  224. package/dist/Layer/layerStructureReset.stylex.d.ts +1 -0
  225. package/dist/Layer/layerStructureReset.stylex.d.ts.map +1 -1
  226. package/dist/Layer/layerStructureReset.stylex.js +1 -0
  227. package/dist/Layer/layerSurfacePress.d.ts +9 -0
  228. package/dist/Layer/layerSurfacePress.d.ts.map +1 -0
  229. package/dist/Layer/layerSurfacePress.js +39 -0
  230. package/dist/Layer/outsidePress.d.ts +25 -0
  231. package/dist/Layer/outsidePress.d.ts.map +1 -0
  232. package/dist/Layer/outsidePress.js +81 -0
  233. package/dist/Layer/popoverOperations.d.ts +27 -0
  234. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  235. package/dist/Layer/popoverOperations.js +159 -0
  236. package/dist/Layer/useLayer.d.ts +9 -1
  237. package/dist/Layer/useLayer.d.ts.map +1 -1
  238. package/dist/Layer/useLayer.js +126 -69
  239. package/dist/Layer/useTouchTrigger.d.ts +35 -3
  240. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  241. package/dist/Layer/useTouchTrigger.js +80 -11
  242. package/dist/Layout/LayoutSlotsContext.d.ts +5 -0
  243. package/dist/Layout/LayoutSlotsContext.d.ts.map +1 -1
  244. package/dist/Layout/LayoutSlotsContext.js +3 -2
  245. package/dist/Layout/layoutReset.d.ts +44 -0
  246. package/dist/Layout/layoutReset.d.ts.map +1 -0
  247. package/dist/Layout/layoutReset.js +40 -0
  248. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  249. package/dist/Lightbox/Lightbox.js +6 -3
  250. package/dist/Link/Link.d.ts.map +1 -1
  251. package/dist/Link/Link.js +23 -7
  252. package/dist/Markdown/Markdown.d.ts.map +1 -1
  253. package/dist/Markdown/Markdown.js +5 -2
  254. package/dist/Markdown/plugins/HeadingLinksRenderer.d.ts.map +1 -1
  255. package/dist/Markdown/plugins/HeadingLinksRenderer.js +4 -2
  256. package/dist/MetadataList/MetadataList.d.ts +1 -1
  257. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  258. package/dist/MetadataList/MetadataList.js +9 -5
  259. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  260. package/dist/MetadataList/MetadataListItem.js +2 -1
  261. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  262. package/dist/MobileNav/MobileNav.js +6 -3
  263. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  264. package/dist/MobileNav/MobileNavToggle.js +4 -2
  265. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  266. package/dist/MoreMenu/MoreMenu.js +4 -2
  267. package/dist/MultiSelector/MultiSelector.d.ts +2 -2
  268. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  269. package/dist/MultiSelector/MultiSelector.js +62 -40
  270. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  271. package/dist/MultiSelector/hooks.js +4 -2
  272. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  273. package/dist/NavMenu/NavHeadingMenuItem.js +5 -29
  274. package/dist/NumberInput/NumberInput.d.ts +3 -2
  275. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  276. package/dist/NumberInput/NumberInput.js +25 -4
  277. package/dist/Outline/Outline.d.ts.map +1 -1
  278. package/dist/Outline/Outline.js +31 -2
  279. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  280. package/dist/OverflowList/OverflowList.js +2 -1
  281. package/dist/Pagination/Pagination.d.ts.map +1 -1
  282. package/dist/Pagination/Pagination.js +6 -3
  283. package/dist/Popover/Popover.d.ts.map +1 -1
  284. package/dist/Popover/Popover.js +40 -17
  285. package/dist/Popover/usePopover.d.ts +7 -1
  286. package/dist/Popover/usePopover.d.ts.map +1 -1
  287. package/dist/Popover/usePopover.js +22 -7
  288. package/dist/PowerSearch/PowerSearch.d.ts +3 -2
  289. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  290. package/dist/PowerSearch/PowerSearch.js +45 -34
  291. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  292. package/dist/PowerSearch/PowerSearchEditPopover.js +7 -4
  293. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  294. package/dist/PowerSearch/PowerSearchToken.js +2 -2
  295. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  296. package/dist/PowerSearch/PowerSearchValueEditor.js +16 -13
  297. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  298. package/dist/PowerSearch/formatFilterValue.js +3 -0
  299. package/dist/PowerSearch/resolveOperatorLabel.d.ts +4 -1
  300. package/dist/PowerSearch/resolveOperatorLabel.d.ts.map +1 -1
  301. package/dist/PowerSearch/resolveOperatorLabel.js +5 -0
  302. package/dist/PowerSearch/usePowerSearchConfig.d.ts.map +1 -1
  303. package/dist/PowerSearch/usePowerSearchConfig.js +3 -0
  304. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  305. package/dist/PowerSearch/usePowerSearchSource.js +3 -2
  306. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  307. package/dist/ProgressBar/ProgressBar.js +3 -1
  308. package/dist/RadioList/RadioList.d.ts.map +1 -1
  309. package/dist/RadioList/RadioList.js +7 -2
  310. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  311. package/dist/RadioList/RadioListItem.js +19 -5
  312. package/dist/RadioList/RadioListReasonContext.d.ts +2 -0
  313. package/dist/RadioList/RadioListReasonContext.d.ts.map +1 -0
  314. package/dist/RadioList/RadioListReasonContext.js +22 -0
  315. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  316. package/dist/Resizable/ResizeHandle.js +4 -2
  317. package/dist/Resizable/resizableModel.d.ts +64 -0
  318. package/dist/Resizable/resizableModel.d.ts.map +1 -0
  319. package/dist/Resizable/resizableModel.js +287 -0
  320. package/dist/Resizable/useResizable.d.ts +2 -2
  321. package/dist/Resizable/useResizable.d.ts.map +1 -1
  322. package/dist/Resizable/useResizable.js +54 -294
  323. package/dist/SegmentedControl/SegmentedControl.d.ts +7 -5
  324. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  325. package/dist/SegmentedControl/SegmentedControl.js +26 -16
  326. package/dist/SegmentedControl/SegmentedControlContext.d.ts +4 -5
  327. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  328. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  329. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  330. package/dist/SegmentedControl/SegmentedControlItem.js +16 -13
  331. package/dist/Selector/Selector.d.ts +3 -3
  332. package/dist/Selector/Selector.d.ts.map +1 -1
  333. package/dist/Selector/Selector.js +20 -16
  334. package/dist/Selector/hooks.js +2 -2
  335. package/dist/Selector/useSelectorPresentation.d.ts +7 -1
  336. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  337. package/dist/Selector/useSelectorPresentation.js +2 -1
  338. package/dist/SideNav/SideNav.d.ts.map +1 -1
  339. package/dist/SideNav/SideNav.js +147 -17
  340. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  341. package/dist/SideNav/SideNavCollapseButton.js +16 -4
  342. package/dist/SideNav/SideNavFocusTargetsContext.d.ts +11 -0
  343. package/dist/SideNav/SideNavFocusTargetsContext.d.ts.map +1 -0
  344. package/dist/SideNav/SideNavFocusTargetsContext.js +16 -0
  345. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  346. package/dist/SideNav/SideNavHeading.js +11 -5
  347. package/dist/SideNav/SideNavItem.d.ts +2 -2
  348. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  349. package/dist/SideNav/SideNavItem.js +37 -11
  350. package/dist/SideNav/railMotion.d.ts +5 -5
  351. package/dist/SideNav/railMotion.d.ts.map +1 -1
  352. package/dist/SideNav/railMotion.js +69 -177
  353. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  354. package/dist/Skeleton/Skeleton.js +1 -1
  355. package/dist/Slider/Slider.d.ts.map +1 -1
  356. package/dist/Slider/Slider.js +107 -19
  357. package/dist/Spinner/Spinner.d.ts +1 -1
  358. package/dist/Spinner/Spinner.d.ts.map +1 -1
  359. package/dist/Spinner/Spinner.js +7 -5
  360. package/dist/Stepper/Step.d.ts.map +1 -1
  361. package/dist/Stepper/Step.js +32 -9
  362. package/dist/Stepper/Stepper.d.ts.map +1 -1
  363. package/dist/Stepper/Stepper.js +5 -3
  364. package/dist/Switch/Switch.d.ts +1 -1
  365. package/dist/Switch/Switch.d.ts.map +1 -1
  366. package/dist/Switch/Switch.js +15 -6
  367. package/dist/TabList/TabList.d.ts.map +1 -1
  368. package/dist/TabList/TabList.js +5 -3
  369. package/dist/Table/BaseTable.d.ts.map +1 -1
  370. package/dist/Table/BaseTable.js +11 -8
  371. package/dist/Table/Table.d.ts.map +1 -1
  372. package/dist/Table/Table.js +42 -13
  373. package/dist/Table/TableSelectionToolbar.d.ts.map +1 -1
  374. package/dist/Table/TableSelectionToolbar.js +4 -2
  375. package/dist/Table/glidingDivider.d.ts +8 -1
  376. package/dist/Table/glidingDivider.d.ts.map +1 -1
  377. package/dist/Table/glidingDivider.js +8 -3
  378. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  379. package/dist/Table/plugins/columnResize/useTableColumnResize.js +6 -3
  380. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  381. package/dist/Table/plugins/filtering/useTableFiltering.js +14 -10
  382. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  383. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +5 -3
  384. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  385. package/dist/Table/plugins/pagination/useTablePagination.js +6 -3
  386. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  387. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  388. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +8 -5
  389. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  390. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +6 -3
  391. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  392. package/dist/Table/plugins/selection/useTableSelection.js +7 -4
  393. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  394. package/dist/Table/plugins/sortable/useTableSortable.js +53 -62
  395. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  396. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -2
  397. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  398. package/dist/Table/plugins/tree/useTableTreeData.js +8 -5
  399. package/dist/Text/text.stylex.d.ts +2 -0
  400. package/dist/Text/text.stylex.d.ts.map +1 -1
  401. package/dist/Text/text.stylex.js +11 -0
  402. package/dist/TextArea/TextArea.d.ts +2 -2
  403. package/dist/TextArea/TextArea.d.ts.map +1 -1
  404. package/dist/TextArea/TextArea.js +11 -4
  405. package/dist/TextInput/TextInput.d.ts +3 -2
  406. package/dist/TextInput/TextInput.d.ts.map +1 -1
  407. package/dist/TextInput/TextInput.js +6 -3
  408. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  409. package/dist/Thumbnail/Thumbnail.js +4 -2
  410. package/dist/TimeInput/TimeInput.d.ts +3 -2
  411. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  412. package/dist/TimeInput/TimeInput.js +7 -10
  413. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  414. package/dist/TimeInput/TouchTimeField.js +8 -9
  415. package/dist/Timer/Timer.js +1 -1
  416. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  417. package/dist/Timestamp/Timestamp.js +5 -3
  418. package/dist/Timestamp/TimestampHoverCard.d.ts.map +1 -1
  419. package/dist/Timestamp/TimestampHoverCard.js +4 -2
  420. package/dist/Toast/Toast.d.ts.map +1 -1
  421. package/dist/Toast/Toast.js +5 -3
  422. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  423. package/dist/Toast/ToastViewport.js +23 -5
  424. package/dist/Toast/useToast.d.ts.map +1 -1
  425. package/dist/Toast/useToast.js +8 -2
  426. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  427. package/dist/ToggleButton/ToggleButton.js +11 -3
  428. package/dist/ToggleButton/ToggleButtonGroup.d.ts +7 -1
  429. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  430. package/dist/ToggleButton/ToggleButtonGroup.js +16 -2
  431. package/dist/Token/Token.d.ts +1 -1
  432. package/dist/Token/Token.d.ts.map +1 -1
  433. package/dist/Token/Token.js +66 -9
  434. package/dist/Token/TokenLink.d.ts +9 -2
  435. package/dist/Token/TokenLink.d.ts.map +1 -1
  436. package/dist/Token/TokenLink.js +16 -2
  437. package/dist/Tokenizer/Tokenizer.d.ts +12 -5
  438. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  439. package/dist/Tokenizer/Tokenizer.js +102 -60
  440. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +1 -1
  441. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
  442. package/dist/Tokenizer/TokenizerBottomSheet.js +14 -18
  443. package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts +2 -0
  444. package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts.map +1 -0
  445. package/dist/Tokenizer/TokenizerClearAllMessageContext.js +17 -0
  446. package/dist/Tooltip/Tooltip.d.ts +4 -3
  447. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  448. package/dist/Tooltip/useTooltip.d.ts +4 -3
  449. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  450. package/dist/Tooltip/useTooltip.js +40 -8
  451. package/dist/TopNav/TopNav.d.ts.map +1 -1
  452. package/dist/TopNav/TopNav.js +5 -3
  453. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  454. package/dist/TopNav/TopNavHeading.js +14 -5
  455. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  456. package/dist/TopNav/TopNavMegaMenu.js +7 -3
  457. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  458. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +9 -2
  459. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  460. package/dist/TopNav/TopNavMenu.js +1 -0
  461. package/dist/TreeList/TreeList.d.ts.map +1 -1
  462. package/dist/TreeList/TreeList.js +68 -7
  463. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  464. package/dist/TreeList/TreeListItem.js +37 -10
  465. package/dist/Typeahead/BaseTypeahead.d.ts +11 -8
  466. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  467. package/dist/Typeahead/BaseTypeahead.js +376 -66
  468. package/dist/Typeahead/Typeahead.d.ts +13 -8
  469. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  470. package/dist/Typeahead/Typeahead.disabled.a11y.chromium.spec.d.ts.map +1 -0
  471. package/dist/Typeahead/Typeahead.js +49 -19
  472. package/dist/Typeahead/index.d.ts +1 -1
  473. package/dist/Typeahead/index.d.ts.map +1 -1
  474. package/dist/Typeahead/types.d.ts +26 -3
  475. package/dist/Typeahead/types.d.ts.map +1 -1
  476. package/dist/astryx.css +38 -11
  477. package/dist/gestures/GestureArena.d.ts +40 -1
  478. package/dist/gestures/GestureArena.d.ts.map +1 -1
  479. package/dist/gestures/GestureArena.js +130 -36
  480. package/dist/gestures/GestureHost.d.ts +331 -97
  481. package/dist/gestures/GestureHost.d.ts.map +1 -1
  482. package/dist/gestures/GestureHost.js +1310 -481
  483. package/dist/gestures/GestureRecognizer.d.ts +59 -18
  484. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  485. package/dist/gestures/GestureRecognizer.js +31 -3
  486. package/dist/gestures/LongPressGestureRecognizer.d.ts +2 -0
  487. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  488. package/dist/gestures/LongPressGestureRecognizer.js +14 -1
  489. package/dist/gestures/PanGestureRecognizer.d.ts +11 -0
  490. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  491. package/dist/gestures/PanGestureRecognizer.js +25 -0
  492. package/dist/gestures/PinchGestureRecognizer.d.ts +3 -2
  493. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -1
  494. package/dist/gestures/PinchGestureRecognizer.js +10 -8
  495. package/dist/gestures/PressTracker.d.ts +140 -0
  496. package/dist/gestures/PressTracker.d.ts.map +1 -0
  497. package/dist/gestures/PressTracker.js +286 -0
  498. package/dist/gestures/TapGestureRecognizer.d.ts +2 -0
  499. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  500. package/dist/gestures/TapGestureRecognizer.js +5 -0
  501. package/dist/gestures/VelocityTracker.d.ts +12 -0
  502. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  503. package/dist/gestures/VelocityTracker.js +38 -0
  504. package/dist/gestures/fingerScroll.d.ts +14 -0
  505. package/dist/gestures/fingerScroll.d.ts.map +1 -0
  506. package/dist/gestures/fingerScroll.js +181 -0
  507. package/dist/gestures/gestureSync.d.ts +12 -0
  508. package/dist/gestures/gestureSync.d.ts.map +1 -0
  509. package/dist/gestures/gestureSync.js +59 -0
  510. package/dist/gestures/haptics.d.ts +6 -3
  511. package/dist/gestures/haptics.d.ts.map +1 -1
  512. package/dist/gestures/haptics.js +9 -10
  513. package/dist/gestures/hostRegistry.d.ts +15 -0
  514. package/dist/gestures/hostRegistry.d.ts.map +1 -0
  515. package/dist/gestures/hostRegistry.js +16 -0
  516. package/dist/gestures/index.d.ts +41 -0
  517. package/dist/gestures/index.d.ts.map +1 -0
  518. package/dist/gestures/index.js +27 -0
  519. package/dist/gestures/nativeScroll.d.ts +2 -32
  520. package/dist/gestures/nativeScroll.d.ts.map +1 -1
  521. package/dist/gestures/nativeScroll.js +5 -17
  522. package/dist/gestures/pageHold.d.ts +21 -0
  523. package/dist/gestures/pageHold.d.ts.map +1 -0
  524. package/dist/gestures/pageHold.js +216 -0
  525. package/dist/gestures/recognizerInternals.d.ts +52 -0
  526. package/dist/gestures/recognizerInternals.d.ts.map +1 -0
  527. package/dist/gestures/recognizerInternals.js +33 -0
  528. package/dist/gestures/selectionLock.d.ts +10 -0
  529. package/dist/gestures/selectionLock.d.ts.map +1 -0
  530. package/dist/gestures/selectionLock.js +12 -0
  531. package/dist/gestures/touchAction.d.ts +10 -12
  532. package/dist/gestures/touchAction.d.ts.map +1 -1
  533. package/dist/gestures/touchAction.js +13 -21
  534. package/dist/gestures/types.d.ts +17 -0
  535. package/dist/gestures/types.d.ts.map +1 -1
  536. package/dist/gestures/useFingerScroll.d.ts +35 -0
  537. package/dist/gestures/useFingerScroll.d.ts.map +1 -0
  538. package/dist/gestures/useFingerScroll.js +70 -0
  539. package/dist/gestures/useGestureRecognizer.d.ts +64 -0
  540. package/dist/gestures/useGestureRecognizer.d.ts.map +1 -0
  541. package/dist/gestures/useGestureRecognizer.js +117 -0
  542. package/dist/gestures/usePressTracker.d.ts +34 -0
  543. package/dist/gestures/usePressTracker.d.ts.map +1 -0
  544. package/dist/gestures/usePressTracker.js +168 -0
  545. package/dist/hooks/ModalAnnounceProvider.d.ts +2 -2
  546. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -1
  547. package/dist/hooks/ModalAnnounceProvider.js +9 -7
  548. package/dist/hooks/index.d.ts +1 -1
  549. package/dist/hooks/index.d.ts.map +1 -1
  550. package/dist/hooks/menuPressMarker.d.ts +13 -0
  551. package/dist/hooks/menuPressMarker.d.ts.map +1 -0
  552. package/dist/hooks/menuPressMarker.js +15 -0
  553. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  554. package/dist/hooks/modalAnnounce.js +107 -61
  555. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -1
  556. package/dist/hooks/scrollKeyboardDelegation.js +7 -3
  557. package/dist/hooks/useAnnounce.d.ts +101 -42
  558. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  559. package/dist/hooks/useAnnounce.js +161 -75
  560. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  561. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  562. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  563. package/dist/hooks/useAttachment.d.ts +22 -0
  564. package/dist/hooks/useAttachment.d.ts.map +1 -0
  565. package/dist/hooks/useAttachment.js +50 -0
  566. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  567. package/dist/hooks/useBusyAnnouncement.js +6 -12
  568. package/dist/hooks/useClickableContainer.d.ts +27 -4
  569. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  570. package/dist/hooks/useClickableContainer.js +51 -14
  571. package/dist/hooks/useFocusReturnVisibility.d.ts +8 -1
  572. package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -1
  573. package/dist/hooks/useFocusReturnVisibility.js +14 -8
  574. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  575. package/dist/hooks/useFocusTrap.js +2 -3
  576. package/dist/hooks/useInputStatusIcon.d.ts +2 -2
  577. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  578. package/dist/hooks/useInputStatusIcon.js +5 -3
  579. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  580. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  581. package/dist/hooks/useKeyboardHint.js +14 -5
  582. package/dist/hooks/useListFocus.d.ts +30 -0
  583. package/dist/hooks/useListFocus.d.ts.map +1 -1
  584. package/dist/hooks/useListFocus.js +53 -10
  585. package/dist/hooks/useLongPress.d.ts +21 -0
  586. package/dist/hooks/useLongPress.d.ts.map +1 -1
  587. package/dist/hooks/useLongPress.js +48 -7
  588. package/dist/hooks/useMenuPress.d.ts +14 -4
  589. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  590. package/dist/hooks/useMenuPress.js +76 -97
  591. package/dist/hooks/useScrollOverflow.d.ts +2 -1
  592. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  593. package/dist/hooks/useScrollOverflow.js +56 -10
  594. package/dist/hooks/useSettledOpen.d.ts +16 -0
  595. package/dist/hooks/useSettledOpen.d.ts.map +1 -0
  596. package/dist/hooks/useSettledOpen.js +44 -0
  597. package/dist/hooks/useTreeFocus.d.ts +11 -1
  598. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  599. package/dist/hooks/useTreeFocus.js +32 -8
  600. package/dist/hooks/useTypeahead.d.ts +3 -1
  601. package/dist/hooks/useTypeahead.d.ts.map +1 -1
  602. package/dist/hooks/useTypeahead.js +21 -15
  603. package/dist/i18n/InternationalizationContext.d.ts +1 -1
  604. package/dist/i18n/InternationalizationContext.js +1 -1
  605. package/dist/i18n/englishFallback.d.ts +32 -0
  606. package/dist/i18n/englishFallback.d.ts.map +1 -0
  607. package/dist/i18n/englishFallback.js +38 -0
  608. package/dist/i18n/fullEnglishFallback.d.ts +3 -0
  609. package/dist/i18n/fullEnglishFallback.d.ts.map +1 -0
  610. package/dist/i18n/fullEnglishFallback.js +26 -0
  611. package/dist/i18n/generated-english/AlertDialog/AlertDialog.generated.d.ts +8 -0
  612. package/dist/i18n/generated-english/AlertDialog/AlertDialog.generated.d.ts.map +1 -0
  613. package/dist/i18n/generated-english/AlertDialog/AlertDialog.generated.js +12 -0
  614. package/dist/i18n/generated-english/AppShell/AppShell.generated.d.ts +8 -0
  615. package/dist/i18n/generated-english/AppShell/AppShell.generated.d.ts.map +1 -0
  616. package/dist/i18n/generated-english/AppShell/AppShell.generated.js +13 -0
  617. package/dist/i18n/generated-english/Avatar/Avatar.generated.d.ts +8 -0
  618. package/dist/i18n/generated-english/Avatar/Avatar.generated.d.ts.map +1 -0
  619. package/dist/i18n/generated-english/Avatar/Avatar.generated.js +12 -0
  620. package/dist/i18n/generated-english/AvatarGroup/AvatarGroup.generated.d.ts +8 -0
  621. package/dist/i18n/generated-english/AvatarGroup/AvatarGroup.generated.d.ts.map +1 -0
  622. package/dist/i18n/generated-english/AvatarGroup/AvatarGroup.generated.js +13 -0
  623. package/dist/i18n/generated-english/AvatarGroup/AvatarGroupOverflow.generated.d.ts +8 -0
  624. package/dist/i18n/generated-english/AvatarGroup/AvatarGroupOverflow.generated.d.ts.map +1 -0
  625. package/dist/i18n/generated-english/AvatarGroup/AvatarGroupOverflow.generated.js +12 -0
  626. package/dist/i18n/generated-english/Banner/Banner.generated.d.ts +8 -0
  627. package/dist/i18n/generated-english/Banner/Banner.generated.d.ts.map +1 -0
  628. package/dist/i18n/generated-english/Banner/Banner.generated.js +15 -0
  629. package/dist/i18n/generated-english/Breadcrumbs/Breadcrumbs.generated.d.ts +8 -0
  630. package/dist/i18n/generated-english/Breadcrumbs/Breadcrumbs.generated.d.ts.map +1 -0
  631. package/dist/i18n/generated-english/Breadcrumbs/Breadcrumbs.generated.js +12 -0
  632. package/dist/i18n/generated-english/Button/Button.generated.d.ts +8 -0
  633. package/dist/i18n/generated-english/Button/Button.generated.d.ts.map +1 -0
  634. package/dist/i18n/generated-english/Button/Button.generated.js +12 -0
  635. package/dist/i18n/generated-english/Calendar/Calendar.generated.d.ts +8 -0
  636. package/dist/i18n/generated-english/Calendar/Calendar.generated.d.ts.map +1 -0
  637. package/dist/i18n/generated-english/Calendar/Calendar.generated.js +21 -0
  638. package/dist/i18n/generated-english/Carousel/Carousel.generated.d.ts +8 -0
  639. package/dist/i18n/generated-english/Carousel/Carousel.generated.d.ts.map +1 -0
  640. package/dist/i18n/generated-english/Carousel/Carousel.generated.js +15 -0
  641. package/dist/i18n/generated-english/Chat/ChatComposer.generated.d.ts +8 -0
  642. package/dist/i18n/generated-english/Chat/ChatComposer.generated.d.ts.map +1 -0
  643. package/dist/i18n/generated-english/Chat/ChatComposer.generated.js +12 -0
  644. package/dist/i18n/generated-english/Chat/ChatComposerDrawer.generated.d.ts +8 -0
  645. package/dist/i18n/generated-english/Chat/ChatComposerDrawer.generated.d.ts.map +1 -0
  646. package/dist/i18n/generated-english/Chat/ChatComposerDrawer.generated.js +14 -0
  647. package/dist/i18n/generated-english/Chat/ChatComposerInput.generated.d.ts +8 -0
  648. package/dist/i18n/generated-english/Chat/ChatComposerInput.generated.d.ts.map +1 -0
  649. package/dist/i18n/generated-english/Chat/ChatComposerInput.generated.js +13 -0
  650. package/dist/i18n/generated-english/Chat/ChatDictationButton.generated.d.ts +8 -0
  651. package/dist/i18n/generated-english/Chat/ChatDictationButton.generated.d.ts.map +1 -0
  652. package/dist/i18n/generated-english/Chat/ChatDictationButton.generated.js +13 -0
  653. package/dist/i18n/generated-english/Chat/ChatLayout.generated.d.ts +8 -0
  654. package/dist/i18n/generated-english/Chat/ChatLayout.generated.d.ts.map +1 -0
  655. package/dist/i18n/generated-english/Chat/ChatLayout.generated.js +12 -0
  656. package/dist/i18n/generated-english/Chat/ChatLayoutScrollButton.generated.d.ts +8 -0
  657. package/dist/i18n/generated-english/Chat/ChatLayoutScrollButton.generated.d.ts.map +1 -0
  658. package/dist/i18n/generated-english/Chat/ChatLayoutScrollButton.generated.js +12 -0
  659. package/dist/i18n/generated-english/Chat/ChatMessage.generated.d.ts +8 -0
  660. package/dist/i18n/generated-english/Chat/ChatMessage.generated.d.ts.map +1 -0
  661. package/dist/i18n/generated-english/Chat/ChatMessage.generated.js +12 -0
  662. package/dist/i18n/generated-english/Chat/ChatMessageList.generated.d.ts +8 -0
  663. package/dist/i18n/generated-english/Chat/ChatMessageList.generated.d.ts.map +1 -0
  664. package/dist/i18n/generated-english/Chat/ChatMessageList.generated.js +12 -0
  665. package/dist/i18n/generated-english/Chat/ChatMessageMetadata.generated.d.ts +8 -0
  666. package/dist/i18n/generated-english/Chat/ChatMessageMetadata.generated.d.ts.map +1 -0
  667. package/dist/i18n/generated-english/Chat/ChatMessageMetadata.generated.js +17 -0
  668. package/dist/i18n/generated-english/Chat/ChatPastedTextToken.generated.d.ts +8 -0
  669. package/dist/i18n/generated-english/Chat/ChatPastedTextToken.generated.d.ts.map +1 -0
  670. package/dist/i18n/generated-english/Chat/ChatPastedTextToken.generated.js +13 -0
  671. package/dist/i18n/generated-english/Chat/ChatSendButton.generated.d.ts +8 -0
  672. package/dist/i18n/generated-english/Chat/ChatSendButton.generated.d.ts.map +1 -0
  673. package/dist/i18n/generated-english/Chat/ChatSendButton.generated.js +13 -0
  674. package/dist/i18n/generated-english/Chat/ChatToolCalls.generated.d.ts +8 -0
  675. package/dist/i18n/generated-english/Chat/ChatToolCalls.generated.d.ts.map +1 -0
  676. package/dist/i18n/generated-english/Chat/ChatToolCalls.generated.js +17 -0
  677. package/dist/i18n/generated-english/Chat/useSpeechRecognition.generated.d.ts +8 -0
  678. package/dist/i18n/generated-english/Chat/useSpeechRecognition.generated.d.ts.map +1 -0
  679. package/dist/i18n/generated-english/Chat/useSpeechRecognition.generated.js +12 -0
  680. package/dist/i18n/generated-english/Chat/useTriggerMenu.generated.d.ts +8 -0
  681. package/dist/i18n/generated-english/Chat/useTriggerMenu.generated.d.ts.map +1 -0
  682. package/dist/i18n/generated-english/Chat/useTriggerMenu.generated.js +13 -0
  683. package/dist/i18n/generated-english/CheckboxInput/CheckboxInput.generated.d.ts +8 -0
  684. package/dist/i18n/generated-english/CheckboxInput/CheckboxInput.generated.d.ts.map +1 -0
  685. package/dist/i18n/generated-english/CheckboxInput/CheckboxInput.generated.js +12 -0
  686. package/dist/i18n/generated-english/CheckboxList/CheckboxListItem.generated.d.ts +8 -0
  687. package/dist/i18n/generated-english/CheckboxList/CheckboxListItem.generated.d.ts.map +1 -0
  688. package/dist/i18n/generated-english/CheckboxList/CheckboxListItem.generated.js +12 -0
  689. package/dist/i18n/generated-english/Citation/Citation.generated.d.ts +8 -0
  690. package/dist/i18n/generated-english/Citation/Citation.generated.d.ts.map +1 -0
  691. package/dist/i18n/generated-english/Citation/Citation.generated.js +12 -0
  692. package/dist/i18n/generated-english/CodeBlock/CodeBlock.generated.d.ts +8 -0
  693. package/dist/i18n/generated-english/CodeBlock/CodeBlock.generated.d.ts.map +1 -0
  694. package/dist/i18n/generated-english/CodeBlock/CodeBlock.generated.js +14 -0
  695. package/dist/i18n/generated-english/CommandPalette/CommandPalette.generated.d.ts +8 -0
  696. package/dist/i18n/generated-english/CommandPalette/CommandPalette.generated.d.ts.map +1 -0
  697. package/dist/i18n/generated-english/CommandPalette/CommandPalette.generated.js +15 -0
  698. package/dist/i18n/generated-english/CommandPalette/CommandPaletteFooter.generated.d.ts +8 -0
  699. package/dist/i18n/generated-english/CommandPalette/CommandPaletteFooter.generated.d.ts.map +1 -0
  700. package/dist/i18n/generated-english/CommandPalette/CommandPaletteFooter.generated.js +14 -0
  701. package/dist/i18n/generated-english/CommandPalette/CommandPaletteInput.generated.d.ts +8 -0
  702. package/dist/i18n/generated-english/CommandPalette/CommandPaletteInput.generated.d.ts.map +1 -0
  703. package/dist/i18n/generated-english/CommandPalette/CommandPaletteInput.generated.js +14 -0
  704. package/dist/i18n/generated-english/CommandPalette/CommandPaletteList.generated.d.ts +8 -0
  705. package/dist/i18n/generated-english/CommandPalette/CommandPaletteList.generated.d.ts.map +1 -0
  706. package/dist/i18n/generated-english/CommandPalette/CommandPaletteList.generated.js +12 -0
  707. package/dist/i18n/generated-english/ComplexSelector/ComplexSelector.generated.d.ts +8 -0
  708. package/dist/i18n/generated-english/ComplexSelector/ComplexSelector.generated.d.ts.map +1 -0
  709. package/dist/i18n/generated-english/ComplexSelector/ComplexSelector.generated.js +13 -0
  710. package/dist/i18n/generated-english/ContextMenu/ContextMenu.generated.d.ts +8 -0
  711. package/dist/i18n/generated-english/ContextMenu/ContextMenu.generated.d.ts.map +1 -0
  712. package/dist/i18n/generated-english/ContextMenu/ContextMenu.generated.js +13 -0
  713. package/dist/i18n/generated-english/DateInput/DateInput.generated.d.ts +8 -0
  714. package/dist/i18n/generated-english/DateInput/DateInput.generated.d.ts.map +1 -0
  715. package/dist/i18n/generated-english/DateInput/DateInput.generated.js +19 -0
  716. package/dist/i18n/generated-english/DateInput/NativeDateField.generated.d.ts +8 -0
  717. package/dist/i18n/generated-english/DateInput/NativeDateField.generated.d.ts.map +1 -0
  718. package/dist/i18n/generated-english/DateInput/NativeDateField.generated.js +16 -0
  719. package/dist/i18n/generated-english/DateInput/TouchDateField.generated.d.ts +8 -0
  720. package/dist/i18n/generated-english/DateInput/TouchDateField.generated.d.ts.map +1 -0
  721. package/dist/i18n/generated-english/DateInput/TouchDateField.generated.js +24 -0
  722. package/dist/i18n/generated-english/DateRangeInput/DateRangeInput.generated.d.ts +8 -0
  723. package/dist/i18n/generated-english/DateRangeInput/DateRangeInput.generated.d.ts.map +1 -0
  724. package/dist/i18n/generated-english/DateRangeInput/DateRangeInput.generated.js +20 -0
  725. package/dist/i18n/generated-english/DateTimeInput/DateTimeInput.generated.d.ts +8 -0
  726. package/dist/i18n/generated-english/DateTimeInput/DateTimeInput.generated.d.ts.map +1 -0
  727. package/dist/i18n/generated-english/DateTimeInput/DateTimeInput.generated.js +26 -0
  728. package/dist/i18n/generated-english/DateTimeInput/NativeDateSegment.generated.d.ts +8 -0
  729. package/dist/i18n/generated-english/DateTimeInput/NativeDateSegment.generated.d.ts.map +1 -0
  730. package/dist/i18n/generated-english/DateTimeInput/NativeDateSegment.generated.js +13 -0
  731. package/dist/i18n/generated-english/DateTimeInput/NativeTimeSegment.generated.d.ts +8 -0
  732. package/dist/i18n/generated-english/DateTimeInput/NativeTimeSegment.generated.d.ts.map +1 -0
  733. package/dist/i18n/generated-english/DateTimeInput/NativeTimeSegment.generated.js +12 -0
  734. package/dist/i18n/generated-english/DateTimeInput/TouchDateTimeField.generated.d.ts +8 -0
  735. package/dist/i18n/generated-english/DateTimeInput/TouchDateTimeField.generated.d.ts.map +1 -0
  736. package/dist/i18n/generated-english/DateTimeInput/TouchDateTimeField.generated.js +37 -0
  737. package/dist/i18n/generated-english/Dialog/DialogHeader.generated.d.ts +8 -0
  738. package/dist/i18n/generated-english/Dialog/DialogHeader.generated.d.ts.map +1 -0
  739. package/dist/i18n/generated-english/Dialog/DialogHeader.generated.js +12 -0
  740. package/dist/i18n/generated-english/Drawer/DrawerHeader.generated.d.ts +8 -0
  741. package/dist/i18n/generated-english/Drawer/DrawerHeader.generated.d.ts.map +1 -0
  742. package/dist/i18n/generated-english/Drawer/DrawerHeader.generated.js +12 -0
  743. package/dist/i18n/generated-english/DropdownMenu/DropdownMenu.generated.d.ts +8 -0
  744. package/dist/i18n/generated-english/DropdownMenu/DropdownMenu.generated.d.ts.map +1 -0
  745. package/dist/i18n/generated-english/DropdownMenu/DropdownMenu.generated.js +13 -0
  746. package/dist/i18n/generated-english/DropdownMenu/DropdownMenuSubMenu.generated.d.ts +8 -0
  747. package/dist/i18n/generated-english/DropdownMenu/DropdownMenuSubMenu.generated.d.ts.map +1 -0
  748. package/dist/i18n/generated-english/DropdownMenu/DropdownMenuSubMenu.generated.js +14 -0
  749. package/dist/i18n/generated-english/Field/FieldLabel.generated.d.ts +8 -0
  750. package/dist/i18n/generated-english/Field/FieldLabel.generated.d.ts.map +1 -0
  751. package/dist/i18n/generated-english/Field/FieldLabel.generated.js +13 -0
  752. package/dist/i18n/generated-english/Field/InputClearButton.generated.d.ts +8 -0
  753. package/dist/i18n/generated-english/Field/InputClearButton.generated.d.ts.map +1 -0
  754. package/dist/i18n/generated-english/Field/InputClearButton.generated.js +12 -0
  755. package/dist/i18n/generated-english/FileInput/FileInput.generated.d.ts +8 -0
  756. package/dist/i18n/generated-english/FileInput/FileInput.generated.d.ts.map +1 -0
  757. package/dist/i18n/generated-english/FileInput/FileInput.generated.js +26 -0
  758. package/dist/i18n/generated-english/Kbd/Kbd.generated.d.ts +8 -0
  759. package/dist/i18n/generated-english/Kbd/Kbd.generated.d.ts.map +1 -0
  760. package/dist/i18n/generated-english/Kbd/Kbd.generated.js +27 -0
  761. package/dist/i18n/generated-english/Lightbox/Lightbox.generated.d.ts +8 -0
  762. package/dist/i18n/generated-english/Lightbox/Lightbox.generated.d.ts.map +1 -0
  763. package/dist/i18n/generated-english/Lightbox/Lightbox.generated.js +20 -0
  764. package/dist/i18n/generated-english/Link/Link.generated.d.ts +8 -0
  765. package/dist/i18n/generated-english/Link/Link.generated.d.ts.map +1 -0
  766. package/dist/i18n/generated-english/Link/Link.generated.js +12 -0
  767. package/dist/i18n/generated-english/Markdown/Markdown.generated.d.ts +8 -0
  768. package/dist/i18n/generated-english/Markdown/Markdown.generated.d.ts.map +1 -0
  769. package/dist/i18n/generated-english/Markdown/Markdown.generated.js +12 -0
  770. package/dist/i18n/generated-english/Markdown/plugins/HeadingLinksRenderer.generated.d.ts +8 -0
  771. package/dist/i18n/generated-english/Markdown/plugins/HeadingLinksRenderer.generated.d.ts.map +1 -0
  772. package/dist/i18n/generated-english/Markdown/plugins/HeadingLinksRenderer.generated.js +13 -0
  773. package/dist/i18n/generated-english/MetadataList/MetadataList.generated.d.ts +8 -0
  774. package/dist/i18n/generated-english/MetadataList/MetadataList.generated.d.ts.map +1 -0
  775. package/dist/i18n/generated-english/MetadataList/MetadataList.generated.js +13 -0
  776. package/dist/i18n/generated-english/MobileNav/MobileNav.generated.d.ts +8 -0
  777. package/dist/i18n/generated-english/MobileNav/MobileNav.generated.d.ts.map +1 -0
  778. package/dist/i18n/generated-english/MobileNav/MobileNav.generated.js +13 -0
  779. package/dist/i18n/generated-english/MobileNav/MobileNavToggle.generated.d.ts +8 -0
  780. package/dist/i18n/generated-english/MobileNav/MobileNavToggle.generated.d.ts.map +1 -0
  781. package/dist/i18n/generated-english/MobileNav/MobileNavToggle.generated.js +12 -0
  782. package/dist/i18n/generated-english/MoreMenu/MoreMenu.generated.d.ts +8 -0
  783. package/dist/i18n/generated-english/MoreMenu/MoreMenu.generated.d.ts.map +1 -0
  784. package/dist/i18n/generated-english/MoreMenu/MoreMenu.generated.js +12 -0
  785. package/dist/i18n/generated-english/MultiSelector/MultiSelector.generated.d.ts +8 -0
  786. package/dist/i18n/generated-english/MultiSelector/MultiSelector.generated.d.ts.map +1 -0
  787. package/dist/i18n/generated-english/MultiSelector/MultiSelector.generated.js +32 -0
  788. package/dist/i18n/generated-english/NumberInput/NumberInput.generated.d.ts +8 -0
  789. package/dist/i18n/generated-english/NumberInput/NumberInput.generated.d.ts.map +1 -0
  790. package/dist/i18n/generated-english/NumberInput/NumberInput.generated.js +15 -0
  791. package/dist/i18n/generated-english/Outline/Outline.generated.d.ts +8 -0
  792. package/dist/i18n/generated-english/Outline/Outline.generated.d.ts.map +1 -0
  793. package/dist/i18n/generated-english/Outline/Outline.generated.js +12 -0
  794. package/dist/i18n/generated-english/Pagination/Pagination.generated.d.ts +8 -0
  795. package/dist/i18n/generated-english/Pagination/Pagination.generated.d.ts.map +1 -0
  796. package/dist/i18n/generated-english/Pagination/Pagination.generated.js +27 -0
  797. package/dist/i18n/generated-english/Popover/Popover.generated.d.ts +8 -0
  798. package/dist/i18n/generated-english/Popover/Popover.generated.d.ts.map +1 -0
  799. package/dist/i18n/generated-english/Popover/Popover.generated.js +12 -0
  800. package/dist/i18n/generated-english/Popover/usePopover.generated.d.ts +8 -0
  801. package/dist/i18n/generated-english/Popover/usePopover.generated.d.ts.map +1 -0
  802. package/dist/i18n/generated-english/Popover/usePopover.generated.js +12 -0
  803. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts +8 -0
  804. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -0
  805. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +16 -0
  806. package/dist/i18n/generated-english/PowerSearch/PowerSearchEditPopover.generated.d.ts +8 -0
  807. package/dist/i18n/generated-english/PowerSearch/PowerSearchEditPopover.generated.d.ts.map +1 -0
  808. package/dist/i18n/generated-english/PowerSearch/PowerSearchEditPopover.generated.js +20 -0
  809. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts +8 -0
  810. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -0
  811. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +23 -0
  812. package/dist/i18n/generated-english/PowerSearch/formatFilterValue.generated.d.ts +8 -0
  813. package/dist/i18n/generated-english/PowerSearch/formatFilterValue.generated.d.ts.map +1 -0
  814. package/dist/i18n/generated-english/PowerSearch/formatFilterValue.generated.js +15 -0
  815. package/dist/i18n/generated-english/PowerSearch/usePowerSearchConfig.generated.d.ts +8 -0
  816. package/dist/i18n/generated-english/PowerSearch/usePowerSearchConfig.generated.d.ts.map +1 -0
  817. package/dist/i18n/generated-english/PowerSearch/usePowerSearchConfig.generated.js +32 -0
  818. package/dist/i18n/generated-english/Resizable/ResizeHandle.generated.d.ts +8 -0
  819. package/dist/i18n/generated-english/Resizable/ResizeHandle.generated.d.ts.map +1 -0
  820. package/dist/i18n/generated-english/Resizable/ResizeHandle.generated.js +13 -0
  821. package/dist/i18n/generated-english/Selector/Selector.generated.d.ts +8 -0
  822. package/dist/i18n/generated-english/Selector/Selector.generated.d.ts.map +1 -0
  823. package/dist/i18n/generated-english/Selector/Selector.generated.js +24 -0
  824. package/dist/i18n/generated-english/SideNav/SideNav.generated.d.ts +8 -0
  825. package/dist/i18n/generated-english/SideNav/SideNav.generated.d.ts.map +1 -0
  826. package/dist/i18n/generated-english/SideNav/SideNav.generated.js +13 -0
  827. package/dist/i18n/generated-english/SideNav/SideNavCollapseButton.generated.d.ts +8 -0
  828. package/dist/i18n/generated-english/SideNav/SideNavCollapseButton.generated.d.ts.map +1 -0
  829. package/dist/i18n/generated-english/SideNav/SideNavCollapseButton.generated.js +13 -0
  830. package/dist/i18n/generated-english/SideNav/SideNavHeading.generated.d.ts +8 -0
  831. package/dist/i18n/generated-english/SideNav/SideNavHeading.generated.d.ts.map +1 -0
  832. package/dist/i18n/generated-english/SideNav/SideNavHeading.generated.js +13 -0
  833. package/dist/i18n/generated-english/SideNav/SideNavItem.generated.d.ts +8 -0
  834. package/dist/i18n/generated-english/SideNav/SideNavItem.generated.d.ts.map +1 -0
  835. package/dist/i18n/generated-english/SideNav/SideNavItem.generated.js +14 -0
  836. package/dist/i18n/generated-english/Slider/Slider.generated.d.ts +8 -0
  837. package/dist/i18n/generated-english/Slider/Slider.generated.d.ts.map +1 -0
  838. package/dist/i18n/generated-english/Slider/Slider.generated.js +13 -0
  839. package/dist/i18n/generated-english/Spinner/Spinner.generated.d.ts +8 -0
  840. package/dist/i18n/generated-english/Spinner/Spinner.generated.d.ts.map +1 -0
  841. package/dist/i18n/generated-english/Spinner/Spinner.generated.js +12 -0
  842. package/dist/i18n/generated-english/Stepper/Step.generated.d.ts +8 -0
  843. package/dist/i18n/generated-english/Stepper/Step.generated.d.ts.map +1 -0
  844. package/dist/i18n/generated-english/Stepper/Step.generated.js +17 -0
  845. package/dist/i18n/generated-english/Stepper/Stepper.generated.d.ts +8 -0
  846. package/dist/i18n/generated-english/Stepper/Stepper.generated.d.ts.map +1 -0
  847. package/dist/i18n/generated-english/Stepper/Stepper.generated.js +14 -0
  848. package/dist/i18n/generated-english/Switch/Switch.generated.d.ts +8 -0
  849. package/dist/i18n/generated-english/Switch/Switch.generated.d.ts.map +1 -0
  850. package/dist/i18n/generated-english/Switch/Switch.generated.js +12 -0
  851. package/dist/i18n/generated-english/TabList/TabList.generated.d.ts +8 -0
  852. package/dist/i18n/generated-english/TabList/TabList.generated.d.ts.map +1 -0
  853. package/dist/i18n/generated-english/TabList/TabList.generated.js +12 -0
  854. package/dist/i18n/generated-english/Table/BaseTable.generated.d.ts +8 -0
  855. package/dist/i18n/generated-english/Table/BaseTable.generated.d.ts.map +1 -0
  856. package/dist/i18n/generated-english/Table/BaseTable.generated.js +12 -0
  857. package/dist/i18n/generated-english/Table/Table.generated.d.ts +8 -0
  858. package/dist/i18n/generated-english/Table/Table.generated.d.ts.map +1 -0
  859. package/dist/i18n/generated-english/Table/Table.generated.js +12 -0
  860. package/dist/i18n/generated-english/Table/TableSelectionToolbar.generated.d.ts +8 -0
  861. package/dist/i18n/generated-english/Table/TableSelectionToolbar.generated.d.ts.map +1 -0
  862. package/dist/i18n/generated-english/Table/TableSelectionToolbar.generated.js +14 -0
  863. package/dist/i18n/generated-english/Table/plugins/columnResize/useTableColumnResize.generated.d.ts +8 -0
  864. package/dist/i18n/generated-english/Table/plugins/columnResize/useTableColumnResize.generated.d.ts.map +1 -0
  865. package/dist/i18n/generated-english/Table/plugins/columnResize/useTableColumnResize.generated.js +12 -0
  866. package/dist/i18n/generated-english/Table/plugins/filtering/useTableFiltering.generated.d.ts +8 -0
  867. package/dist/i18n/generated-english/Table/plugins/filtering/useTableFiltering.generated.d.ts.map +1 -0
  868. package/dist/i18n/generated-english/Table/plugins/filtering/useTableFiltering.generated.js +15 -0
  869. package/dist/i18n/generated-english/Table/plugins/groupedRows/useTableGroupedRows.generated.d.ts +8 -0
  870. package/dist/i18n/generated-english/Table/plugins/groupedRows/useTableGroupedRows.generated.d.ts.map +1 -0
  871. package/dist/i18n/generated-english/Table/plugins/groupedRows/useTableGroupedRows.generated.js +13 -0
  872. package/dist/i18n/generated-english/Table/plugins/pagination/useTablePagination.generated.d.ts +8 -0
  873. package/dist/i18n/generated-english/Table/plugins/pagination/useTablePagination.generated.d.ts.map +1 -0
  874. package/dist/i18n/generated-english/Table/plugins/pagination/useTablePagination.generated.js +14 -0
  875. package/dist/i18n/generated-english/Table/plugins/rowExpansion/useTableRowExpansion.generated.d.ts +8 -0
  876. package/dist/i18n/generated-english/Table/plugins/rowExpansion/useTableRowExpansion.generated.d.ts.map +1 -0
  877. package/dist/i18n/generated-english/Table/plugins/rowExpansion/useTableRowExpansion.generated.js +14 -0
  878. package/dist/i18n/generated-english/Table/plugins/rowStatus/useTableRowStatus.generated.d.ts +8 -0
  879. package/dist/i18n/generated-english/Table/plugins/rowStatus/useTableRowStatus.generated.d.ts.map +1 -0
  880. package/dist/i18n/generated-english/Table/plugins/rowStatus/useTableRowStatus.generated.js +12 -0
  881. package/dist/i18n/generated-english/Table/plugins/selection/useTableSelection.generated.d.ts +8 -0
  882. package/dist/i18n/generated-english/Table/plugins/selection/useTableSelection.generated.d.ts.map +1 -0
  883. package/dist/i18n/generated-english/Table/plugins/selection/useTableSelection.generated.js +14 -0
  884. package/dist/i18n/generated-english/Table/plugins/sortable/useTableSortable.generated.d.ts +8 -0
  885. package/dist/i18n/generated-english/Table/plugins/sortable/useTableSortable.generated.d.ts.map +1 -0
  886. package/dist/i18n/generated-english/Table/plugins/sortable/useTableSortable.generated.js +15 -0
  887. package/dist/i18n/generated-english/Table/plugins/tree/useTableTreeData.generated.d.ts +8 -0
  888. package/dist/i18n/generated-english/Table/plugins/tree/useTableTreeData.generated.d.ts.map +1 -0
  889. package/dist/i18n/generated-english/Table/plugins/tree/useTableTreeData.generated.js +15 -0
  890. package/dist/i18n/generated-english/TextArea/TextArea.generated.d.ts +8 -0
  891. package/dist/i18n/generated-english/TextArea/TextArea.generated.d.ts.map +1 -0
  892. package/dist/i18n/generated-english/TextArea/TextArea.generated.js +15 -0
  893. package/dist/i18n/generated-english/TextInput/TextInput.generated.d.ts +8 -0
  894. package/dist/i18n/generated-english/TextInput/TextInput.generated.d.ts.map +1 -0
  895. package/dist/i18n/generated-english/TextInput/TextInput.generated.js +13 -0
  896. package/dist/i18n/generated-english/Thumbnail/Thumbnail.generated.d.ts +8 -0
  897. package/dist/i18n/generated-english/Thumbnail/Thumbnail.generated.d.ts.map +1 -0
  898. package/dist/i18n/generated-english/Thumbnail/Thumbnail.generated.js +15 -0
  899. package/dist/i18n/generated-english/TimeInput/TimeInput.generated.d.ts +8 -0
  900. package/dist/i18n/generated-english/TimeInput/TimeInput.generated.d.ts.map +1 -0
  901. package/dist/i18n/generated-english/TimeInput/TimeInput.generated.js +18 -0
  902. package/dist/i18n/generated-english/TimeInput/TouchTimeField.generated.d.ts +8 -0
  903. package/dist/i18n/generated-english/TimeInput/TouchTimeField.generated.d.ts.map +1 -0
  904. package/dist/i18n/generated-english/TimeInput/TouchTimeField.generated.js +22 -0
  905. package/dist/i18n/generated-english/Timestamp/Timestamp.generated.d.ts +8 -0
  906. package/dist/i18n/generated-english/Timestamp/Timestamp.generated.d.ts.map +1 -0
  907. package/dist/i18n/generated-english/Timestamp/Timestamp.generated.js +12 -0
  908. package/dist/i18n/generated-english/Timestamp/TimestampHoverCard.generated.d.ts +8 -0
  909. package/dist/i18n/generated-english/Timestamp/TimestampHoverCard.generated.d.ts.map +1 -0
  910. package/dist/i18n/generated-english/Timestamp/TimestampHoverCard.generated.js +14 -0
  911. package/dist/i18n/generated-english/Toast/Toast.generated.d.ts +8 -0
  912. package/dist/i18n/generated-english/Toast/Toast.generated.d.ts.map +1 -0
  913. package/dist/i18n/generated-english/Toast/Toast.generated.js +12 -0
  914. package/dist/i18n/generated-english/Toast/ToastViewport.generated.d.ts +8 -0
  915. package/dist/i18n/generated-english/Toast/ToastViewport.generated.d.ts.map +1 -0
  916. package/dist/i18n/generated-english/Toast/ToastViewport.generated.js +12 -0
  917. package/dist/i18n/generated-english/Token/Token.generated.d.ts +8 -0
  918. package/dist/i18n/generated-english/Token/Token.generated.d.ts.map +1 -0
  919. package/dist/i18n/generated-english/Token/Token.generated.js +12 -0
  920. package/dist/i18n/generated-english/Tokenizer/Tokenizer.generated.d.ts +8 -0
  921. package/dist/i18n/generated-english/Tokenizer/Tokenizer.generated.d.ts.map +1 -0
  922. package/dist/i18n/generated-english/Tokenizer/Tokenizer.generated.js +18 -0
  923. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts +8 -0
  924. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -0
  925. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +30 -0
  926. package/dist/i18n/generated-english/TopNav/TopNav.generated.d.ts +8 -0
  927. package/dist/i18n/generated-english/TopNav/TopNav.generated.d.ts.map +1 -0
  928. package/dist/i18n/generated-english/TopNav/TopNav.generated.js +12 -0
  929. package/dist/i18n/generated-english/TopNav/TopNavHeading.generated.d.ts +8 -0
  930. package/dist/i18n/generated-english/TopNav/TopNavHeading.generated.d.ts.map +1 -0
  931. package/dist/i18n/generated-english/TopNav/TopNavHeading.generated.js +13 -0
  932. package/dist/i18n/generated-english/TreeList/TreeListItem.generated.d.ts +8 -0
  933. package/dist/i18n/generated-english/TreeList/TreeListItem.generated.d.ts.map +1 -0
  934. package/dist/i18n/generated-english/TreeList/TreeListItem.generated.js +12 -0
  935. package/dist/i18n/generated-english/Typeahead/BaseTypeahead.generated.d.ts +8 -0
  936. package/dist/i18n/generated-english/Typeahead/BaseTypeahead.generated.d.ts.map +1 -0
  937. package/dist/i18n/generated-english/Typeahead/BaseTypeahead.generated.js +16 -0
  938. package/dist/i18n/generated-english/Typeahead/Typeahead.generated.d.ts +8 -0
  939. package/dist/i18n/generated-english/Typeahead/Typeahead.generated.d.ts.map +1 -0
  940. package/dist/i18n/generated-english/Typeahead/Typeahead.generated.js +13 -0
  941. package/dist/i18n/generated-english/hooks/useInputStatusIcon.generated.d.ts +8 -0
  942. package/dist/i18n/generated-english/hooks/useInputStatusIcon.generated.d.ts.map +1 -0
  943. package/dist/i18n/generated-english/hooks/useInputStatusIcon.generated.js +14 -0
  944. package/dist/i18n/generated-english/hooks/useKeyboardHint.generated.d.ts +8 -0
  945. package/dist/i18n/generated-english/hooks/useKeyboardHint.generated.d.ts.map +1 -0
  946. package/dist/i18n/generated-english/hooks/useKeyboardHint.generated.js +12 -0
  947. package/dist/i18n/generated-locales/af-ZA.generated.d.ts.map +1 -1
  948. package/dist/i18n/generated-locales/af-ZA.generated.js +2 -7
  949. package/dist/i18n/generated-locales/ar-SA.generated.d.ts.map +1 -1
  950. package/dist/i18n/generated-locales/ar-SA.generated.js +2 -7
  951. package/dist/i18n/generated-locales/ca-ES.generated.d.ts.map +1 -1
  952. package/dist/i18n/generated-locales/ca-ES.generated.js +2 -7
  953. package/dist/i18n/generated-locales/cs-CZ.generated.d.ts.map +1 -1
  954. package/dist/i18n/generated-locales/cs-CZ.generated.js +2 -7
  955. package/dist/i18n/generated-locales/da-DK.generated.d.ts.map +1 -1
  956. package/dist/i18n/generated-locales/da-DK.generated.js +2 -7
  957. package/dist/i18n/generated-locales/de-DE.generated.d.ts.map +1 -1
  958. package/dist/i18n/generated-locales/de-DE.generated.js +2 -7
  959. package/dist/i18n/generated-locales/el-GR.generated.d.ts.map +1 -1
  960. package/dist/i18n/generated-locales/el-GR.generated.js +2 -7
  961. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  962. package/dist/i18n/generated-locales/en.generated.js +13 -7
  963. package/dist/i18n/generated-locales/es-ES.generated.d.ts.map +1 -1
  964. package/dist/i18n/generated-locales/es-ES.generated.js +2 -7
  965. package/dist/i18n/generated-locales/fi-FI.generated.d.ts.map +1 -1
  966. package/dist/i18n/generated-locales/fi-FI.generated.js +2 -7
  967. package/dist/i18n/generated-locales/fr-FR.generated.d.ts.map +1 -1
  968. package/dist/i18n/generated-locales/fr-FR.generated.js +2 -7
  969. package/dist/i18n/generated-locales/he-IL.generated.d.ts.map +1 -1
  970. package/dist/i18n/generated-locales/he-IL.generated.js +2 -7
  971. package/dist/i18n/generated-locales/hu-HU.generated.d.ts.map +1 -1
  972. package/dist/i18n/generated-locales/hu-HU.generated.js +2 -7
  973. package/dist/i18n/generated-locales/it-IT.generated.d.ts.map +1 -1
  974. package/dist/i18n/generated-locales/it-IT.generated.js +2 -7
  975. package/dist/i18n/generated-locales/ja-JP.generated.d.ts.map +1 -1
  976. package/dist/i18n/generated-locales/ja-JP.generated.js +2 -7
  977. package/dist/i18n/generated-locales/ko-KR.generated.d.ts.map +1 -1
  978. package/dist/i18n/generated-locales/ko-KR.generated.js +2 -7
  979. package/dist/i18n/generated-locales/nl-NL.generated.d.ts.map +1 -1
  980. package/dist/i18n/generated-locales/nl-NL.generated.js +2 -7
  981. package/dist/i18n/generated-locales/no-NO.generated.d.ts.map +1 -1
  982. package/dist/i18n/generated-locales/no-NO.generated.js +2 -7
  983. package/dist/i18n/generated-locales/pl-PL.generated.d.ts.map +1 -1
  984. package/dist/i18n/generated-locales/pl-PL.generated.js +2 -7
  985. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  986. package/dist/i18n/generated-locales/pseudo.generated.js +13 -7
  987. package/dist/i18n/generated-locales/pt-BR.generated.d.ts.map +1 -1
  988. package/dist/i18n/generated-locales/pt-BR.generated.js +2 -7
  989. package/dist/i18n/generated-locales/pt-PT.generated.d.ts.map +1 -1
  990. package/dist/i18n/generated-locales/pt-PT.generated.js +2 -7
  991. package/dist/i18n/generated-locales/ro-RO.generated.d.ts.map +1 -1
  992. package/dist/i18n/generated-locales/ro-RO.generated.js +2 -7
  993. package/dist/i18n/generated-locales/ru-RU.generated.d.ts.map +1 -1
  994. package/dist/i18n/generated-locales/ru-RU.generated.js +2 -7
  995. package/dist/i18n/generated-locales/sr-SP.generated.d.ts.map +1 -1
  996. package/dist/i18n/generated-locales/sr-SP.generated.js +2 -7
  997. package/dist/i18n/generated-locales/sv-SE.generated.d.ts.map +1 -1
  998. package/dist/i18n/generated-locales/sv-SE.generated.js +2 -7
  999. package/dist/i18n/generated-locales/tr-TR.generated.d.ts.map +1 -1
  1000. package/dist/i18n/generated-locales/tr-TR.generated.js +2 -7
  1001. package/dist/i18n/generated-locales/uk-UA.generated.d.ts.map +1 -1
  1002. package/dist/i18n/generated-locales/uk-UA.generated.js +2 -7
  1003. package/dist/i18n/generated-locales/vi-VN.generated.d.ts.map +1 -1
  1004. package/dist/i18n/generated-locales/vi-VN.generated.js +2 -7
  1005. package/dist/i18n/generated-locales/zh-CN.generated.d.ts.map +1 -1
  1006. package/dist/i18n/generated-locales/zh-CN.generated.js +2 -7
  1007. package/dist/i18n/generated-locales/zh-TW.generated.d.ts.map +1 -1
  1008. package/dist/i18n/generated-locales/zh-TW.generated.js +2 -7
  1009. package/dist/i18n/index.d.ts +6 -1
  1010. package/dist/i18n/index.d.ts.map +1 -1
  1011. package/dist/i18n/index.js +6 -1
  1012. package/dist/i18n/publicContext.d.ts +2 -0
  1013. package/dist/i18n/publicContext.d.ts.map +1 -0
  1014. package/dist/i18n/publicContext.js +26 -0
  1015. package/dist/i18n/resolve.d.ts +6 -2
  1016. package/dist/i18n/resolve.d.ts.map +1 -1
  1017. package/dist/i18n/resolve.js +12 -4
  1018. package/dist/i18n/useComponentTranslator.d.ts +8 -0
  1019. package/dist/i18n/useComponentTranslator.d.ts.map +1 -0
  1020. package/dist/i18n/useComponentTranslator.js +42 -0
  1021. package/dist/i18n/useListFormatter.d.ts +9 -0
  1022. package/dist/i18n/useListFormatter.d.ts.map +1 -0
  1023. package/dist/i18n/useListFormatter.js +41 -0
  1024. package/dist/i18n/useTranslator.d.ts.map +1 -1
  1025. package/dist/i18n/useTranslator.js +7 -1
  1026. package/dist/motion/animatedLayout.d.ts +130 -5
  1027. package/dist/motion/animatedLayout.d.ts.map +1 -1
  1028. package/dist/motion/animatedLayout.js +867 -47
  1029. package/dist/motion/animator.d.ts +76 -7
  1030. package/dist/motion/animator.d.ts.map +1 -1
  1031. package/dist/motion/animator.js +785 -103
  1032. package/dist/motion/coast.d.ts +4 -1
  1033. package/dist/motion/coast.d.ts.map +1 -1
  1034. package/dist/motion/coast.js +4 -2
  1035. package/dist/motion/presentation.d.ts +44 -0
  1036. package/dist/motion/presentation.d.ts.map +1 -0
  1037. package/dist/motion/presentation.js +127 -0
  1038. package/dist/motion/reducedMotion.d.ts.map +1 -1
  1039. package/dist/motion/reducedMotion.js +6 -2
  1040. package/dist/motion/reducedMotionPlan.d.ts +7 -0
  1041. package/dist/motion/reducedMotionPlan.d.ts.map +1 -1
  1042. package/dist/motion/reducedMotionPlan.js +14 -1
  1043. package/dist/motion/resolveMotion.d.ts +42 -0
  1044. package/dist/motion/resolveMotion.d.ts.map +1 -0
  1045. package/dist/motion/resolveMotion.js +43 -0
  1046. package/dist/motion/roleValue.d.ts +2 -1
  1047. package/dist/motion/roleValue.d.ts.map +1 -1
  1048. package/dist/motion/roleValue.js +2 -1
  1049. package/dist/motion/uikit/gestures.d.ts +9 -18
  1050. package/dist/motion/uikit/gestures.d.ts.map +1 -1
  1051. package/dist/motion/uikit/gestures.js +14 -9
  1052. package/dist/motion/uikit/index.d.ts +1 -1
  1053. package/dist/motion/uikit/index.d.ts.map +1 -1
  1054. package/dist/motion/uikit/index.js +1 -1
  1055. package/dist/motion/uikit/longPress.d.ts +26 -0
  1056. package/dist/motion/uikit/longPress.d.ts.map +1 -0
  1057. package/dist/motion/uikit/longPress.js +29 -0
  1058. package/dist/motion/uikit/springs.d.ts +18 -0
  1059. package/dist/motion/uikit/springs.d.ts.map +1 -1
  1060. package/dist/motion/uikit/springs.js +20 -1
  1061. package/dist/motion/uikit/timing.d.ts +7 -1
  1062. package/dist/motion/uikit/timing.d.ts.map +1 -1
  1063. package/dist/motion/uikit/timing.js +19 -1
  1064. package/dist/privateAttributes/hapticSwitch.stylex.d.ts +5 -0
  1065. package/dist/privateAttributes/hapticSwitch.stylex.d.ts.map +1 -0
  1066. package/dist/privateAttributes/hapticSwitch.stylex.js +27 -0
  1067. package/dist/privateAttributes/segmentDisabled.stylex.d.ts +5 -0
  1068. package/dist/privateAttributes/segmentDisabled.stylex.d.ts.map +1 -0
  1069. package/dist/privateAttributes/segmentDisabled.stylex.js +28 -0
  1070. package/dist/theme/Theme.d.ts +10 -0
  1071. package/dist/theme/Theme.d.ts.map +1 -1
  1072. package/dist/theme/Theme.js +8 -4
  1073. package/dist/theme/defineTheme.d.ts +19 -5
  1074. package/dist/theme/defineTheme.d.ts.map +1 -1
  1075. package/dist/theme/defineTheme.js +63 -3
  1076. package/dist/theme/index.d.ts +1 -0
  1077. package/dist/theme/index.d.ts.map +1 -1
  1078. package/dist/theme/motionKnobs.d.ts +56 -0
  1079. package/dist/theme/motionKnobs.d.ts.map +1 -0
  1080. package/dist/theme/motionKnobs.js +48 -0
  1081. package/dist/theme/resolveThemeValues.d.ts +11 -4
  1082. package/dist/theme/resolveThemeValues.d.ts.map +1 -1
  1083. package/dist/theme/resolveThemeValues.js +40 -4
  1084. package/dist/theme/themeAdaptations.d.ts +7 -3
  1085. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  1086. package/dist/theme/themeAdaptations.js +36 -7
  1087. package/dist/theme/themeMotion.d.ts +96 -0
  1088. package/dist/theme/themeMotion.d.ts.map +1 -0
  1089. package/dist/theme/themeMotion.js +177 -0
  1090. package/dist/theme/tokenReferences.d.ts +31 -0
  1091. package/dist/theme/tokenReferences.d.ts.map +1 -0
  1092. package/dist/theme/tokenReferences.js +132 -0
  1093. package/dist/theme/tokens.d.ts +1 -0
  1094. package/dist/theme/tokens.d.ts.map +1 -1
  1095. package/dist/theme/tokens.js +9 -129
  1096. package/dist/theme/tokens.stylex.d.ts +12 -0
  1097. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  1098. package/dist/theme/tokens.stylex.js +12 -0
  1099. package/dist/theme/useTheme.d.ts.map +1 -1
  1100. package/dist/theme/useTheme.js +7 -1
  1101. package/dist/utils/accessibleName.d.ts +8 -0
  1102. package/dist/utils/accessibleName.d.ts.map +1 -0
  1103. package/dist/utils/accessibleName.js +72 -0
  1104. package/dist/utils/clickGuard.d.ts +34 -0
  1105. package/dist/utils/clickGuard.d.ts.map +1 -0
  1106. package/dist/utils/clickGuard.js +150 -0
  1107. package/dist/utils/coarsePointer.d.ts +8 -0
  1108. package/dist/utils/coarsePointer.d.ts.map +1 -0
  1109. package/dist/utils/coarsePointer.js +47 -0
  1110. package/dist/utils/flatTree.d.ts +17 -0
  1111. package/dist/utils/flatTree.d.ts.map +1 -0
  1112. package/dist/utils/flatTree.js +38 -0
  1113. package/dist/utils/focusOutline.stylex.d.ts +6 -0
  1114. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  1115. package/dist/utils/focusOutline.stylex.js +7 -0
  1116. package/dist/utils/focusReturn.d.ts +40 -5
  1117. package/dist/utils/focusReturn.d.ts.map +1 -1
  1118. package/dist/utils/focusReturn.js +59 -6
  1119. package/dist/utils/getNodeText.d.ts.map +1 -1
  1120. package/dist/utils/getNodeText.js +2 -1
  1121. package/dist/utils/inputStream.d.ts +17 -0
  1122. package/dist/utils/inputStream.d.ts.map +1 -0
  1123. package/dist/utils/inputStream.js +149 -0
  1124. package/dist/utils/interactionModality.d.ts +78 -7
  1125. package/dist/utils/interactionModality.d.ts.map +1 -1
  1126. package/dist/utils/interactionModality.js +125 -42
  1127. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  1128. package/dist/utils/interactionOverlay.stylex.js +17 -8
  1129. package/dist/utils/plainDate.d.ts +9 -0
  1130. package/dist/utils/plainDate.d.ts.map +1 -1
  1131. package/dist/utils/plainDate.js +25 -0
  1132. package/dist/utils/pressDisabled.d.ts +21 -0
  1133. package/dist/utils/pressDisabled.d.ts.map +1 -0
  1134. package/dist/utils/pressDisabled.js +32 -0
  1135. package/dist/utils/pressFeedback.d.ts.map +1 -1
  1136. package/dist/utils/pressFeedback.js +97 -31
  1137. package/dist/utils/selectionLock.d.ts +14 -0
  1138. package/dist/utils/selectionLock.d.ts.map +1 -0
  1139. package/dist/utils/selectionLock.js +164 -0
  1140. package/dist/utils/sharedMutationObserver.d.ts +19 -11
  1141. package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
  1142. package/dist/utils/sharedMutationObserver.js +66 -26
  1143. package/dist/utils/standaloneMonthCapitals.generated.d.ts +7 -0
  1144. package/dist/utils/standaloneMonthCapitals.generated.d.ts.map +1 -0
  1145. package/dist/utils/standaloneMonthCapitals.generated.js +9 -0
  1146. package/dist/utils/touchPresentation.d.ts +3 -8
  1147. package/dist/utils/touchPresentation.d.ts.map +1 -1
  1148. package/dist/utils/touchPresentation.js +11 -11
  1149. package/dist/utils/touchQueries.d.ts +29 -0
  1150. package/dist/utils/touchQueries.d.ts.map +1 -0
  1151. package/dist/utils/touchQueries.js +33 -0
  1152. package/dist/utils/typeaheadMatch.d.ts +24 -0
  1153. package/dist/utils/typeaheadMatch.d.ts.map +1 -0
  1154. package/dist/utils/typeaheadMatch.js +112 -0
  1155. package/dist/utils/useFocusAcrossSwap.d.ts +19 -0
  1156. package/dist/utils/useFocusAcrossSwap.d.ts.map +1 -0
  1157. package/dist/utils/useFocusAcrossSwap.js +41 -0
  1158. package/dist/utils/useFocusLeavingChange.d.ts +13 -0
  1159. package/dist/utils/useFocusLeavingChange.d.ts.map +1 -0
  1160. package/dist/utils/useFocusLeavingChange.js +48 -0
  1161. package/locales/af-ZA.json +2 -23
  1162. package/locales/ar-SA.json +2 -23
  1163. package/locales/ca-ES.json +2 -23
  1164. package/locales/cs-CZ.json +2 -23
  1165. package/locales/da-DK.json +2 -23
  1166. package/locales/de-DE.json +2 -23
  1167. package/locales/el-GR.json +2 -23
  1168. package/locales/en.json +49 -25
  1169. package/locales/es-ES.json +2 -23
  1170. package/locales/fi-FI.json +2 -23
  1171. package/locales/fr-FR.json +2 -23
  1172. package/locales/he-IL.json +2 -23
  1173. package/locales/hu-HU.json +2 -23
  1174. package/locales/it-IT.json +2 -23
  1175. package/locales/ja-JP.json +2 -23
  1176. package/locales/ko-KR.json +2 -23
  1177. package/locales/nl-NL.json +2 -23
  1178. package/locales/no-NO.json +2 -23
  1179. package/locales/pl-PL.json +2 -23
  1180. package/locales/pseudo.json +34 -16
  1181. package/locales/pt-BR.json +2 -23
  1182. package/locales/pt-PT.json +2 -23
  1183. package/locales/ro-RO.json +2 -23
  1184. package/locales/ru-RU.json +2 -23
  1185. package/locales/sr-SP.json +2 -23
  1186. package/locales/sv-SE.json +2 -23
  1187. package/locales/tr-TR.json +2 -23
  1188. package/locales/uk-UA.json +2 -23
  1189. package/locales/vi-VN.json +2 -23
  1190. package/locales/zh-CN.json +2 -23
  1191. package/locales/zh-TW.json +2 -23
  1192. package/package.json +19 -5
  1193. package/src/AlertDialog/AlertDialog.tsx +8 -2
  1194. package/src/AppShell/AppShell.doc.mjs +1 -1
  1195. package/src/AppShell/AppShell.tsx +289 -53
  1196. package/src/AppShell/observeMainOverflow.ts +143 -0
  1197. package/src/Avatar/Avatar.tsx +10 -3
  1198. package/src/AvatarGroup/AvatarGroup.tsx +8 -2
  1199. package/src/AvatarGroup/AvatarGroupOverflow.tsx +9 -3
  1200. package/src/Badge/Badge.tsx +2 -1
  1201. package/src/Banner/Banner.tsx +12 -2
  1202. package/src/BottomSheet/BottomSheet.tsx +42 -3
  1203. package/src/BottomSheet/BottomSheetPanel.tsx +64 -8
  1204. package/src/BottomSheet/BottomSheetSwitcher.tsx +32 -9
  1205. package/src/BottomSheet/BottomSheetSwitcherContext.ts +8 -0
  1206. package/src/BottomSheet/useMobileKeyboard.ts +51 -10
  1207. package/src/BottomSheet/useSheetGestures.ts +92 -15
  1208. package/src/Breadcrumbs/BreadcrumbItem.tsx +2 -1
  1209. package/src/Breadcrumbs/Breadcrumbs.tsx +8 -2
  1210. package/src/Button/Button.tsx +19 -6
  1211. package/src/Calendar/Calendar.tsx +21 -13
  1212. package/src/Calendar/hooks/useCalendarNavigation.ts +9 -10
  1213. package/src/Carousel/Carousel.doc.mjs +1 -1
  1214. package/src/Carousel/Carousel.tsx +18 -4
  1215. package/src/Center/Center.tsx +1 -1
  1216. package/src/Chat/ChatComposer.tsx +20 -12
  1217. package/src/Chat/ChatComposerDrawer.tsx +9 -3
  1218. package/src/Chat/ChatComposerInput.tsx +9 -3
  1219. package/src/Chat/ChatDictationButton.tsx +8 -2
  1220. package/src/Chat/ChatLayout.tsx +9 -8
  1221. package/src/Chat/ChatLayoutScrollButton.tsx +8 -2
  1222. package/src/Chat/ChatMessage.tsx +21 -5
  1223. package/src/Chat/ChatMessageList.tsx +9 -2
  1224. package/src/Chat/ChatMessageMetadata.tsx +8 -2
  1225. package/src/Chat/ChatPastedTextToken.tsx +23 -6
  1226. package/src/Chat/ChatSendButton.tsx +8 -2
  1227. package/src/Chat/ChatSystemMessage.tsx +4 -1
  1228. package/src/Chat/ChatToolCalls.tsx +15 -4
  1229. package/src/Chat/chatMessage.vars.stylex.ts +18 -0
  1230. package/src/Chat/useSpeechRecognition.ts +9 -2
  1231. package/src/Chat/useTriggerMenu.tsx +25 -29
  1232. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  1233. package/src/CheckboxList/CheckboxList.tsx +7 -1
  1234. package/src/CheckboxList/CheckboxListContext.tsx +8 -0
  1235. package/src/CheckboxList/CheckboxListItem.tsx +16 -4
  1236. package/src/Citation/Citation.tsx +8 -2
  1237. package/src/ClickableCard/ClickableCard.tsx +48 -4
  1238. package/src/Code/Code.tsx +1 -1
  1239. package/src/CodeBlock/CodeBlock.tsx +14 -4
  1240. package/src/Collapsible/Collapsible.tsx +33 -4
  1241. package/src/CommandPalette/CommandPalette.tsx +28 -8
  1242. package/src/CommandPalette/CommandPaletteEmpty.tsx +2 -0
  1243. package/src/CommandPalette/CommandPaletteFooter.tsx +8 -2
  1244. package/src/CommandPalette/CommandPaletteInput.tsx +13 -10
  1245. package/src/CommandPalette/CommandPaletteList.tsx +8 -2
  1246. package/src/ComplexSelector/ComplexSelector.tsx +71 -10
  1247. package/src/ContextMenu/ContextMenu.tsx +38 -8
  1248. package/src/DateInput/DateInput.tsx +13 -18
  1249. package/src/DateInput/MonthScroller.tsx +17 -20
  1250. package/src/DateInput/NativeDateField.tsx +11 -15
  1251. package/src/DateInput/TouchDateField.tsx +13 -18
  1252. package/src/DateInput/Wheel.tsx +9 -6
  1253. package/src/DateInput/usePointerDragScroll.ts +34 -10
  1254. package/src/DateInput/useScrollSettle.ts +38 -7
  1255. package/src/DateRangeInput/DateRangeInput.tsx +31 -20
  1256. package/src/DateTimeInput/DateTimeInput.tsx +49 -26
  1257. package/src/DateTimeInput/NativeDateSegment.tsx +9 -2
  1258. package/src/DateTimeInput/NativeTimeSegment.tsx +9 -2
  1259. package/src/DateTimeInput/TouchDateTimeField.tsx +14 -18
  1260. package/src/Dialog/Dialog.tsx +29 -27
  1261. package/src/Dialog/DialogHeader.tsx +8 -2
  1262. package/src/Drawer/Drawer.tsx +25 -3
  1263. package/src/Drawer/DrawerHeader.tsx +8 -2
  1264. package/src/DropdownMenu/DropdownMenu.doc.mjs +2 -2
  1265. package/src/DropdownMenu/DropdownMenu.tsx +70 -103
  1266. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +2 -2
  1267. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +15 -5
  1268. package/src/DropdownMenu/DropdownMenuGroup.tsx +2 -1
  1269. package/src/DropdownMenu/DropdownMenuItem.tsx +7 -1
  1270. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +2 -2
  1271. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +16 -6
  1272. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +19 -6
  1273. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -3
  1274. package/src/DropdownMenu/lazyMenuBottomSheet.ts +21 -9
  1275. package/src/Field/Field.doc.mjs +2 -1
  1276. package/src/Field/Field.tsx +2 -2
  1277. package/src/Field/FieldLabel.doc.mjs +4 -2
  1278. package/src/Field/FieldLabel.tsx +27 -5
  1279. package/src/Field/InputClearButton.tsx +9 -3
  1280. package/src/Field/PanelSearchInput.tsx +7 -8
  1281. package/src/Field/fieldStatusPlacement.ts +18 -0
  1282. package/src/Field/index.ts +1 -0
  1283. package/src/Field/inputDisabledFocus.ts +62 -4
  1284. package/src/Field/inputStyles.stylex.ts +46 -9
  1285. package/src/FieldStatus/FieldStatus.tsx +35 -3
  1286. package/src/FieldStatus/index.ts +7 -0
  1287. package/src/FileInput/FileInput.doc.mjs +3 -3
  1288. package/src/FileInput/FileInput.tsx +111 -38
  1289. package/src/Grid/Grid.doc.mjs +4 -4
  1290. package/src/Grid/Grid.tsx +6 -4
  1291. package/src/Grid/GridSpan.doc.mjs +51 -2
  1292. package/src/Grid/GridSpan.tsx +2 -0
  1293. package/src/Heading/Heading.tsx +5 -3
  1294. package/src/HoverCard/HoverCard.doc.mjs +3 -3
  1295. package/src/HoverCard/useHoverCard.doc.mjs +1 -1
  1296. package/src/HoverCard/useHoverCard.tsx +7 -0
  1297. package/src/InputGroup/groupStyles.ts +9 -2
  1298. package/src/Item/Item.tsx +30 -14
  1299. package/src/Item/ItemSwipeLayer.tsx +8 -1
  1300. package/src/Kbd/Kbd.tsx +12 -3
  1301. package/src/Layer/layerStructureReset.stylex.ts +5 -0
  1302. package/src/Layer/layerSurfacePress.ts +39 -0
  1303. package/src/Layer/outsidePress.ts +99 -0
  1304. package/src/Layer/popoverOperations.ts +172 -0
  1305. package/src/Layer/useLayer.tsx +168 -81
  1306. package/src/Layer/useTouchTrigger.ts +107 -18
  1307. package/src/Layout/LayoutSlotsContext.ts +4 -2
  1308. package/src/Layout/layoutReset.ts +45 -0
  1309. package/src/Lightbox/Lightbox.tsx +8 -2
  1310. package/src/Link/Link.tsx +28 -4
  1311. package/src/Markdown/Markdown.tsx +10 -2
  1312. package/src/Markdown/plugins/HeadingLinksRenderer.tsx +8 -2
  1313. package/src/MetadataList/MetadataList.tsx +13 -5
  1314. package/src/MetadataList/MetadataListItem.tsx +2 -1
  1315. package/src/MobileNav/MobileNav.tsx +8 -2
  1316. package/src/MobileNav/MobileNavToggle.tsx +8 -2
  1317. package/src/MoreMenu/MoreMenu.tsx +8 -2
  1318. package/src/MultiSelector/MultiSelector.tsx +86 -62
  1319. package/src/MultiSelector/hooks.ts +7 -5
  1320. package/src/NavMenu/NavHeadingMenuItem.tsx +5 -39
  1321. package/src/NumberInput/NumberInput.tsx +35 -5
  1322. package/src/Outline/Outline.tsx +31 -2
  1323. package/src/OverflowList/OverflowList.tsx +2 -1
  1324. package/src/Pagination/Pagination.tsx +9 -2
  1325. package/src/Popover/Popover.tsx +44 -18
  1326. package/src/Popover/usePopover.tsx +25 -7
  1327. package/src/PowerSearch/PowerSearch.tsx +54 -35
  1328. package/src/PowerSearch/PowerSearchEditPopover.tsx +10 -4
  1329. package/src/PowerSearch/PowerSearchToken.tsx +2 -2
  1330. package/src/PowerSearch/PowerSearchValueEditor.tsx +20 -13
  1331. package/src/PowerSearch/formatFilterValue.ts +4 -0
  1332. package/src/PowerSearch/resolveOperatorLabel.ts +7 -1
  1333. package/src/PowerSearch/usePowerSearchConfig.ts +4 -0
  1334. package/src/PowerSearch/usePowerSearchSource.ts +2 -2
  1335. package/src/ProgressBar/ProgressBar.tsx +3 -1
  1336. package/src/RadioList/RadioList.tsx +13 -2
  1337. package/src/RadioList/RadioListItem.tsx +20 -3
  1338. package/src/RadioList/RadioListReasonContext.ts +25 -0
  1339. package/src/Resizable/ResizeHandle.tsx +8 -2
  1340. package/src/Resizable/resizableModel.ts +364 -0
  1341. package/src/Resizable/useResizable.ts +67 -355
  1342. package/src/SegmentedControl/SegmentedControl.doc.mjs +5 -5
  1343. package/src/SegmentedControl/SegmentedControl.tsx +58 -30
  1344. package/src/SegmentedControl/SegmentedControlContext.ts +4 -5
  1345. package/src/SegmentedControl/SegmentedControlItem.doc.mjs +1 -1
  1346. package/src/SegmentedControl/SegmentedControlItem.tsx +12 -14
  1347. package/src/Selector/Selector.tsx +33 -27
  1348. package/src/Selector/hooks.ts +2 -2
  1349. package/src/Selector/useSelectorPresentation.ts +8 -1
  1350. package/src/SideNav/SideNav.tsx +221 -27
  1351. package/src/SideNav/SideNavCollapseButton.tsx +26 -4
  1352. package/src/SideNav/SideNavFocusTargetsContext.ts +29 -0
  1353. package/src/SideNav/SideNavHeading.tsx +10 -4
  1354. package/src/SideNav/SideNavItem.tsx +54 -15
  1355. package/src/SideNav/railMotion.ts +73 -179
  1356. package/src/Skeleton/Skeleton.tsx +3 -1
  1357. package/src/Slider/Slider.tsx +126 -21
  1358. package/src/Spinner/Spinner.tsx +12 -4
  1359. package/src/Stepper/Step.tsx +41 -8
  1360. package/src/Stepper/Stepper.doc.mjs +1 -1
  1361. package/src/Stepper/Stepper.tsx +8 -2
  1362. package/src/Switch/Switch.tsx +20 -6
  1363. package/src/TabList/TabList.tsx +8 -2
  1364. package/src/Table/BaseTable.tsx +18 -8
  1365. package/src/Table/Table.tsx +51 -13
  1366. package/src/Table/TableSelectionToolbar.tsx +8 -2
  1367. package/src/Table/glidingDivider.ts +8 -3
  1368. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -2
  1369. package/src/Table/plugins/filtering/useTableFiltering.tsx +16 -9
  1370. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +8 -2
  1371. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -2
  1372. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +10 -4
  1373. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +8 -2
  1374. package/src/Table/plugins/selection/useTableSelection.tsx +9 -3
  1375. package/src/Table/plugins/sortable/useTableSortable.tsx +55 -76
  1376. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  1377. package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
  1378. package/src/Text/Heading.doc.mjs +52 -3
  1379. package/src/Text/Text.doc.mjs +1 -1
  1380. package/src/Text/text.stylex.ts +12 -0
  1381. package/src/TextArea/TextArea.tsx +18 -6
  1382. package/src/TextInput/TextInput.tsx +16 -5
  1383. package/src/Thumbnail/Thumbnail.tsx +8 -2
  1384. package/src/TimeInput/TimeInput.tsx +13 -17
  1385. package/src/TimeInput/TouchTimeField.tsx +12 -15
  1386. package/src/Timer/Timer.tsx +1 -1
  1387. package/src/Timestamp/Timestamp.tsx +8 -2
  1388. package/src/Timestamp/TimestampHoverCard.tsx +8 -2
  1389. package/src/Toast/Toast.tsx +10 -2
  1390. package/src/Toast/ToastViewport.tsx +29 -5
  1391. package/src/Toast/useToast.tsx +8 -3
  1392. package/src/ToggleButton/ToggleButton.tsx +10 -3
  1393. package/src/ToggleButton/ToggleButtonGroup.tsx +20 -1
  1394. package/src/Token/Token.doc.mjs +2 -2
  1395. package/src/Token/Token.tsx +93 -8
  1396. package/src/Token/TokenLink.tsx +37 -8
  1397. package/src/Tokenizer/Tokenizer.doc.mjs +16 -11
  1398. package/src/Tokenizer/Tokenizer.tsx +130 -69
  1399. package/src/Tokenizer/TokenizerBottomSheet.tsx +17 -17
  1400. package/src/Tokenizer/TokenizerClearAllMessageContext.ts +21 -0
  1401. package/src/Tooltip/Tooltip.doc.mjs +3 -3
  1402. package/src/Tooltip/Tooltip.tsx +4 -3
  1403. package/src/Tooltip/useTooltip.doc.mjs +3 -3
  1404. package/src/Tooltip/useTooltip.tsx +58 -15
  1405. package/src/TopNav/TopNav.tsx +8 -2
  1406. package/src/TopNav/TopNavHeading.tsx +16 -4
  1407. package/src/TopNav/TopNavMegaMenu.tsx +8 -4
  1408. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
  1409. package/src/TopNav/TopNavMenu.tsx +1 -0
  1410. package/src/TreeList/TreeList.tsx +91 -11
  1411. package/src/TreeList/TreeListItem.tsx +39 -9
  1412. package/src/Typeahead/BaseTypeahead.doc.mjs +10 -7
  1413. package/src/Typeahead/BaseTypeahead.tsx +447 -68
  1414. package/src/Typeahead/Typeahead.doc.mjs +24 -6
  1415. package/src/Typeahead/Typeahead.tsx +67 -24
  1416. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  1417. package/src/Typeahead/index.ts +1 -1
  1418. package/src/Typeahead/types.ts +27 -3
  1419. package/src/gestures/GestureArena.ts +154 -36
  1420. package/src/gestures/GestureHost.ts +1566 -567
  1421. package/src/gestures/GestureRecognizer.ts +72 -19
  1422. package/src/gestures/LongPressGestureRecognizer.ts +20 -1
  1423. package/src/gestures/PanGestureRecognizer.ts +35 -0
  1424. package/src/gestures/PinchGestureRecognizer.ts +13 -8
  1425. package/src/gestures/PressTracker.ts +433 -0
  1426. package/src/gestures/README.md +682 -0
  1427. package/src/gestures/TapGestureRecognizer.ts +5 -0
  1428. package/src/gestures/VelocityTracker.ts +35 -0
  1429. package/src/gestures/fingerScroll.ts +208 -0
  1430. package/src/gestures/gestureSync.ts +60 -0
  1431. package/src/gestures/haptics.ts +9 -13
  1432. package/src/gestures/hostRegistry.ts +18 -0
  1433. package/src/gestures/index.ts +80 -0
  1434. package/src/gestures/nativeScroll.ts +6 -20
  1435. package/src/gestures/pageHold.ts +265 -0
  1436. package/src/gestures/recognizerInternals.ts +77 -0
  1437. package/src/gestures/selectionLock.ts +12 -0
  1438. package/src/gestures/touchAction.ts +12 -24
  1439. package/src/gestures/types.ts +18 -0
  1440. package/src/gestures/useFingerScroll.ts +78 -0
  1441. package/src/gestures/useGestureRecognizer.ts +166 -0
  1442. package/src/gestures/usePressTracker.ts +212 -0
  1443. package/src/hooks/ModalAnnounceProvider.tsx +12 -9
  1444. package/src/hooks/index.ts +5 -1
  1445. package/src/hooks/menuPressMarker.ts +15 -0
  1446. package/src/hooks/modalAnnounce.ts +129 -72
  1447. package/src/hooks/scrollKeyboardDelegation.ts +9 -3
  1448. package/src/hooks/useAnnounce.doc.mjs +35 -3
  1449. package/src/hooks/useAnnounce.ts +209 -102
  1450. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  1451. package/src/hooks/useAttachment.ts +59 -0
  1452. package/src/hooks/useBusyAnnouncement.ts +7 -10
  1453. package/src/hooks/useClickableContainer.ts +58 -17
  1454. package/src/hooks/useFocusReturnVisibility.ts +15 -12
  1455. package/src/hooks/useFocusTrap.ts +2 -8
  1456. package/src/hooks/useInputStatusIcon.tsx +10 -4
  1457. package/src/hooks/useKeyboardHint.tsx +16 -4
  1458. package/src/hooks/useListFocus.ts +88 -8
  1459. package/src/hooks/useLongPress.ts +62 -8
  1460. package/src/hooks/useMenuPress.ts +85 -107
  1461. package/src/hooks/useScrollOverflow.doc.mjs +1 -1
  1462. package/src/hooks/useScrollOverflow.ts +59 -10
  1463. package/src/hooks/useSettledOpen.ts +51 -0
  1464. package/src/hooks/useTreeFocus.doc.mjs +2 -2
  1465. package/src/hooks/useTreeFocus.ts +49 -13
  1466. package/src/hooks/useTypeahead.doc.mjs +2 -2
  1467. package/src/hooks/useTypeahead.ts +21 -20
  1468. package/src/i18n/InternationalizationContext.ts +1 -1
  1469. package/src/i18n/englishFallback.ts +40 -0
  1470. package/src/i18n/fullEnglishFallback.ts +26 -0
  1471. package/src/i18n/generated-english/AlertDialog/AlertDialog.generated.ts +13 -0
  1472. package/src/i18n/generated-english/AppShell/AppShell.generated.ts +14 -0
  1473. package/src/i18n/generated-english/Avatar/Avatar.generated.ts +13 -0
  1474. package/src/i18n/generated-english/AvatarGroup/AvatarGroup.generated.ts +14 -0
  1475. package/src/i18n/generated-english/AvatarGroup/AvatarGroupOverflow.generated.ts +13 -0
  1476. package/src/i18n/generated-english/Banner/Banner.generated.ts +16 -0
  1477. package/src/i18n/generated-english/Breadcrumbs/Breadcrumbs.generated.ts +13 -0
  1478. package/src/i18n/generated-english/Button/Button.generated.ts +13 -0
  1479. package/src/i18n/generated-english/Calendar/Calendar.generated.ts +22 -0
  1480. package/src/i18n/generated-english/Carousel/Carousel.generated.ts +16 -0
  1481. package/src/i18n/generated-english/Chat/ChatComposer.generated.ts +13 -0
  1482. package/src/i18n/generated-english/Chat/ChatComposerDrawer.generated.ts +15 -0
  1483. package/src/i18n/generated-english/Chat/ChatComposerInput.generated.ts +14 -0
  1484. package/src/i18n/generated-english/Chat/ChatDictationButton.generated.ts +14 -0
  1485. package/src/i18n/generated-english/Chat/ChatLayout.generated.ts +13 -0
  1486. package/src/i18n/generated-english/Chat/ChatLayoutScrollButton.generated.ts +13 -0
  1487. package/src/i18n/generated-english/Chat/ChatMessage.generated.ts +13 -0
  1488. package/src/i18n/generated-english/Chat/ChatMessageList.generated.ts +13 -0
  1489. package/src/i18n/generated-english/Chat/ChatMessageMetadata.generated.ts +18 -0
  1490. package/src/i18n/generated-english/Chat/ChatPastedTextToken.generated.ts +14 -0
  1491. package/src/i18n/generated-english/Chat/ChatSendButton.generated.ts +14 -0
  1492. package/src/i18n/generated-english/Chat/ChatToolCalls.generated.ts +18 -0
  1493. package/src/i18n/generated-english/Chat/useSpeechRecognition.generated.ts +13 -0
  1494. package/src/i18n/generated-english/Chat/useTriggerMenu.generated.ts +14 -0
  1495. package/src/i18n/generated-english/CheckboxInput/CheckboxInput.generated.ts +13 -0
  1496. package/src/i18n/generated-english/CheckboxList/CheckboxListItem.generated.ts +13 -0
  1497. package/src/i18n/generated-english/Citation/Citation.generated.ts +13 -0
  1498. package/src/i18n/generated-english/CodeBlock/CodeBlock.generated.ts +15 -0
  1499. package/src/i18n/generated-english/CommandPalette/CommandPalette.generated.ts +16 -0
  1500. package/src/i18n/generated-english/CommandPalette/CommandPaletteFooter.generated.ts +15 -0
  1501. package/src/i18n/generated-english/CommandPalette/CommandPaletteInput.generated.ts +15 -0
  1502. package/src/i18n/generated-english/CommandPalette/CommandPaletteList.generated.ts +13 -0
  1503. package/src/i18n/generated-english/ComplexSelector/ComplexSelector.generated.ts +14 -0
  1504. package/src/i18n/generated-english/ContextMenu/ContextMenu.generated.ts +14 -0
  1505. package/src/i18n/generated-english/DateInput/DateInput.generated.ts +20 -0
  1506. package/src/i18n/generated-english/DateInput/NativeDateField.generated.ts +17 -0
  1507. package/src/i18n/generated-english/DateInput/TouchDateField.generated.ts +25 -0
  1508. package/src/i18n/generated-english/DateRangeInput/DateRangeInput.generated.ts +21 -0
  1509. package/src/i18n/generated-english/DateTimeInput/DateTimeInput.generated.ts +27 -0
  1510. package/src/i18n/generated-english/DateTimeInput/NativeDateSegment.generated.ts +14 -0
  1511. package/src/i18n/generated-english/DateTimeInput/NativeTimeSegment.generated.ts +13 -0
  1512. package/src/i18n/generated-english/DateTimeInput/TouchDateTimeField.generated.ts +38 -0
  1513. package/src/i18n/generated-english/Dialog/DialogHeader.generated.ts +13 -0
  1514. package/src/i18n/generated-english/Drawer/DrawerHeader.generated.ts +13 -0
  1515. package/src/i18n/generated-english/DropdownMenu/DropdownMenu.generated.ts +14 -0
  1516. package/src/i18n/generated-english/DropdownMenu/DropdownMenuSubMenu.generated.ts +15 -0
  1517. package/src/i18n/generated-english/Field/FieldLabel.generated.ts +14 -0
  1518. package/src/i18n/generated-english/Field/InputClearButton.generated.ts +13 -0
  1519. package/src/i18n/generated-english/FileInput/FileInput.generated.ts +27 -0
  1520. package/src/i18n/generated-english/Kbd/Kbd.generated.ts +28 -0
  1521. package/src/i18n/generated-english/Lightbox/Lightbox.generated.ts +21 -0
  1522. package/src/i18n/generated-english/Link/Link.generated.ts +13 -0
  1523. package/src/i18n/generated-english/Markdown/Markdown.generated.ts +13 -0
  1524. package/src/i18n/generated-english/Markdown/plugins/HeadingLinksRenderer.generated.ts +14 -0
  1525. package/src/i18n/generated-english/MetadataList/MetadataList.generated.ts +14 -0
  1526. package/src/i18n/generated-english/MobileNav/MobileNav.generated.ts +14 -0
  1527. package/src/i18n/generated-english/MobileNav/MobileNavToggle.generated.ts +13 -0
  1528. package/src/i18n/generated-english/MoreMenu/MoreMenu.generated.ts +13 -0
  1529. package/src/i18n/generated-english/MultiSelector/MultiSelector.generated.ts +33 -0
  1530. package/src/i18n/generated-english/NumberInput/NumberInput.generated.ts +16 -0
  1531. package/src/i18n/generated-english/Outline/Outline.generated.ts +13 -0
  1532. package/src/i18n/generated-english/Pagination/Pagination.generated.ts +28 -0
  1533. package/src/i18n/generated-english/Popover/Popover.generated.ts +13 -0
  1534. package/src/i18n/generated-english/Popover/usePopover.generated.ts +13 -0
  1535. package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +17 -0
  1536. package/src/i18n/generated-english/PowerSearch/PowerSearchEditPopover.generated.ts +21 -0
  1537. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +24 -0
  1538. package/src/i18n/generated-english/PowerSearch/formatFilterValue.generated.ts +16 -0
  1539. package/src/i18n/generated-english/PowerSearch/usePowerSearchConfig.generated.ts +33 -0
  1540. package/src/i18n/generated-english/Resizable/ResizeHandle.generated.ts +14 -0
  1541. package/src/i18n/generated-english/Selector/Selector.generated.ts +25 -0
  1542. package/src/i18n/generated-english/SideNav/SideNav.generated.ts +14 -0
  1543. package/src/i18n/generated-english/SideNav/SideNavCollapseButton.generated.ts +14 -0
  1544. package/src/i18n/generated-english/SideNav/SideNavHeading.generated.ts +14 -0
  1545. package/src/i18n/generated-english/SideNav/SideNavItem.generated.ts +15 -0
  1546. package/src/i18n/generated-english/Slider/Slider.generated.ts +14 -0
  1547. package/src/i18n/generated-english/Spinner/Spinner.generated.ts +13 -0
  1548. package/src/i18n/generated-english/Stepper/Step.generated.ts +18 -0
  1549. package/src/i18n/generated-english/Stepper/Stepper.generated.ts +15 -0
  1550. package/src/i18n/generated-english/Switch/Switch.generated.ts +13 -0
  1551. package/src/i18n/generated-english/TabList/TabList.generated.ts +13 -0
  1552. package/src/i18n/generated-english/Table/BaseTable.generated.ts +13 -0
  1553. package/src/i18n/generated-english/Table/Table.generated.ts +13 -0
  1554. package/src/i18n/generated-english/Table/TableSelectionToolbar.generated.ts +15 -0
  1555. package/src/i18n/generated-english/Table/plugins/columnResize/useTableColumnResize.generated.ts +13 -0
  1556. package/src/i18n/generated-english/Table/plugins/filtering/useTableFiltering.generated.ts +16 -0
  1557. package/src/i18n/generated-english/Table/plugins/groupedRows/useTableGroupedRows.generated.ts +14 -0
  1558. package/src/i18n/generated-english/Table/plugins/pagination/useTablePagination.generated.ts +15 -0
  1559. package/src/i18n/generated-english/Table/plugins/rowExpansion/useTableRowExpansion.generated.ts +15 -0
  1560. package/src/i18n/generated-english/Table/plugins/rowStatus/useTableRowStatus.generated.ts +13 -0
  1561. package/src/i18n/generated-english/Table/plugins/selection/useTableSelection.generated.ts +15 -0
  1562. package/src/i18n/generated-english/Table/plugins/sortable/useTableSortable.generated.ts +16 -0
  1563. package/src/i18n/generated-english/Table/plugins/tree/useTableTreeData.generated.ts +16 -0
  1564. package/src/i18n/generated-english/TextArea/TextArea.generated.ts +16 -0
  1565. package/src/i18n/generated-english/TextInput/TextInput.generated.ts +14 -0
  1566. package/src/i18n/generated-english/Thumbnail/Thumbnail.generated.ts +16 -0
  1567. package/src/i18n/generated-english/TimeInput/TimeInput.generated.ts +19 -0
  1568. package/src/i18n/generated-english/TimeInput/TouchTimeField.generated.ts +23 -0
  1569. package/src/i18n/generated-english/Timestamp/Timestamp.generated.ts +13 -0
  1570. package/src/i18n/generated-english/Timestamp/TimestampHoverCard.generated.ts +15 -0
  1571. package/src/i18n/generated-english/Toast/Toast.generated.ts +13 -0
  1572. package/src/i18n/generated-english/Toast/ToastViewport.generated.ts +13 -0
  1573. package/src/i18n/generated-english/Token/Token.generated.ts +13 -0
  1574. package/src/i18n/generated-english/Tokenizer/Tokenizer.generated.ts +19 -0
  1575. package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +31 -0
  1576. package/src/i18n/generated-english/TopNav/TopNav.generated.ts +13 -0
  1577. package/src/i18n/generated-english/TopNav/TopNavHeading.generated.ts +14 -0
  1578. package/src/i18n/generated-english/TreeList/TreeListItem.generated.ts +13 -0
  1579. package/src/i18n/generated-english/Typeahead/BaseTypeahead.generated.ts +17 -0
  1580. package/src/i18n/generated-english/Typeahead/Typeahead.generated.ts +14 -0
  1581. package/src/i18n/generated-english/hooks/useInputStatusIcon.generated.ts +15 -0
  1582. package/src/i18n/generated-english/hooks/useKeyboardHint.generated.ts +13 -0
  1583. package/src/i18n/generated-locales/af-ZA.generated.ts +3 -9
  1584. package/src/i18n/generated-locales/ar-SA.generated.ts +3 -8
  1585. package/src/i18n/generated-locales/ca-ES.generated.ts +3 -9
  1586. package/src/i18n/generated-locales/cs-CZ.generated.ts +3 -8
  1587. package/src/i18n/generated-locales/da-DK.generated.ts +3 -8
  1588. package/src/i18n/generated-locales/de-DE.generated.ts +3 -8
  1589. package/src/i18n/generated-locales/el-GR.generated.ts +3 -9
  1590. package/src/i18n/generated-locales/en.generated.ts +16 -8
  1591. package/src/i18n/generated-locales/es-ES.generated.ts +3 -9
  1592. package/src/i18n/generated-locales/fi-FI.generated.ts +3 -8
  1593. package/src/i18n/generated-locales/fr-FR.generated.ts +3 -9
  1594. package/src/i18n/generated-locales/he-IL.generated.ts +3 -8
  1595. package/src/i18n/generated-locales/hu-HU.generated.ts +3 -8
  1596. package/src/i18n/generated-locales/it-IT.generated.ts +3 -9
  1597. package/src/i18n/generated-locales/ja-JP.generated.ts +3 -8
  1598. package/src/i18n/generated-locales/ko-KR.generated.ts +3 -8
  1599. package/src/i18n/generated-locales/nl-NL.generated.ts +3 -8
  1600. package/src/i18n/generated-locales/no-NO.generated.ts +3 -8
  1601. package/src/i18n/generated-locales/pl-PL.generated.ts +3 -9
  1602. package/src/i18n/generated-locales/pseudo.generated.ts +16 -8
  1603. package/src/i18n/generated-locales/pt-BR.generated.ts +3 -9
  1604. package/src/i18n/generated-locales/pt-PT.generated.ts +3 -9
  1605. package/src/i18n/generated-locales/ro-RO.generated.ts +3 -8
  1606. package/src/i18n/generated-locales/ru-RU.generated.ts +3 -9
  1607. package/src/i18n/generated-locales/sr-SP.generated.ts +3 -8
  1608. package/src/i18n/generated-locales/sv-SE.generated.ts +3 -8
  1609. package/src/i18n/generated-locales/tr-TR.generated.ts +3 -9
  1610. package/src/i18n/generated-locales/uk-UA.generated.ts +3 -9
  1611. package/src/i18n/generated-locales/vi-VN.generated.ts +3 -8
  1612. package/src/i18n/generated-locales/zh-CN.generated.ts +3 -8
  1613. package/src/i18n/generated-locales/zh-TW.generated.ts +3 -8
  1614. package/src/i18n/index.ts +6 -1
  1615. package/src/i18n/publicContext.ts +29 -0
  1616. package/src/i18n/resolve.ts +17 -4
  1617. package/src/i18n/useComponentTranslator.ts +45 -0
  1618. package/src/i18n/useListFormatter.ts +42 -0
  1619. package/src/i18n/useTranslator.ts +8 -1
  1620. package/src/motion/MEASUREMENTS.md +3 -2
  1621. package/src/motion/README.md +113 -32
  1622. package/src/motion/animatedLayout.ts +1079 -48
  1623. package/src/motion/animator.ts +1012 -114
  1624. package/src/motion/coast.ts +10 -3
  1625. package/src/motion/presentation.ts +149 -0
  1626. package/src/motion/reducedMotion.ts +12 -2
  1627. package/src/motion/reducedMotionPlan.ts +20 -1
  1628. package/src/motion/resolveMotion.ts +68 -0
  1629. package/src/motion/roleValue.ts +2 -1
  1630. package/src/motion/uikit/gestures.ts +15 -8
  1631. package/src/motion/uikit/index.ts +1 -0
  1632. package/src/motion/uikit/longPress.ts +29 -0
  1633. package/src/motion/uikit/springs.ts +19 -0
  1634. package/src/motion/uikit/timing.ts +15 -1
  1635. package/src/privateAttributes/hapticSwitch.stylex.ts +27 -0
  1636. package/src/privateAttributes/segmentDisabled.stylex.ts +28 -0
  1637. package/src/theme/Theme.doc.mjs +1 -1
  1638. package/src/theme/Theme.tsx +8 -4
  1639. package/src/theme/defineTheme.ts +116 -7
  1640. package/src/theme/index.ts +5 -0
  1641. package/src/theme/motionKnobs.ts +82 -0
  1642. package/src/theme/resolveThemeValues.ts +68 -6
  1643. package/src/theme/themeAdaptations.ts +52 -12
  1644. package/src/theme/themeMotion.ts +221 -0
  1645. package/src/theme/tokenReferences.ts +149 -0
  1646. package/src/theme/tokens.stylex.ts +10 -0
  1647. package/src/theme/tokens.ts +15 -158
  1648. package/src/theme/useTheme.ts +6 -1
  1649. package/src/utils/accessibleName.ts +87 -0
  1650. package/src/utils/clickGuard.ts +167 -0
  1651. package/src/utils/coarsePointer.ts +53 -0
  1652. package/src/utils/flatTree.ts +40 -0
  1653. package/src/utils/focusOutline.stylex.ts +28 -0
  1654. package/src/utils/focusReturn.ts +73 -6
  1655. package/src/utils/getNodeText.ts +2 -1
  1656. package/src/utils/inputStream.ts +168 -0
  1657. package/src/utils/interactionModality.ts +165 -44
  1658. package/src/utils/interactionOverlay.stylex.ts +12 -3
  1659. package/src/utils/plainDate.ts +28 -0
  1660. package/src/utils/pressDisabled.ts +32 -0
  1661. package/src/utils/pressFeedback.ts +112 -36
  1662. package/src/utils/selectionLock.ts +193 -0
  1663. package/src/utils/sharedMutationObserver.ts +87 -29
  1664. package/src/utils/standaloneMonthCapitals.generated.ts +17 -0
  1665. package/src/utils/touchPresentation.ts +11 -11
  1666. package/src/utils/touchQueries.ts +38 -0
  1667. package/src/utils/typeaheadMatch.ts +141 -0
  1668. package/src/utils/useFocusAcrossSwap.ts +55 -0
  1669. package/src/utils/useFocusLeavingChange.ts +53 -0
  1670. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts +0 -2
  1671. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.js +0 -132
  1672. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +0 -2
  1673. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +0 -78
  1674. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +0 -2
  1675. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +0 -66
  1676. package/dist/List/ListMarkers.a11y.chromium.spec.d.ts +0 -2
  1677. package/dist/List/ListMarkers.a11y.chromium.spec.js +0 -677
  1678. package/dist/Markdown/Markdown.fr23.bench.d.ts +0 -2
  1679. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +0 -1
  1680. package/dist/Markdown/Markdown.fr23.bench.js +0 -152
  1681. package/dist/Markdown/MarkdownTable.a11y.chromium.spec.d.ts +0 -2
  1682. package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +0 -590
  1683. package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.d.ts +0 -2
  1684. package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.js +0 -657
  1685. package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.d.ts +0 -2
  1686. package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +0 -153
  1687. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.d.ts +0 -2
  1688. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +0 -116
  1689. package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.d.ts +0 -2
  1690. package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +0 -49
  1691. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.d.ts +0 -2
  1692. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +0 -273
  1693. package/dist/Outline/OutlineFocus.a11y.chromium.spec.d.ts +0 -2
  1694. package/dist/Outline/OutlineFocus.a11y.chromium.spec.js +0 -421
  1695. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts +0 -2
  1696. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.js +0 -118
  1697. package/dist/reset.a11y.chromium.spec.d.ts +0 -2
  1698. package/dist/reset.a11y.chromium.spec.js +0 -231
  1699. package/dist/reset.until-found.a11y.browser.spec.d.ts +0 -2
  1700. package/dist/reset.until-found.a11y.browser.spec.js +0 -72
  1701. package/src/AlertDialog/AlertDialog.spec.md +0 -259
  1702. package/src/AlertDialog/AlertDialog.test.tsx +0 -519
  1703. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +0 -128
  1704. package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +0 -52
  1705. package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +0 -68
  1706. package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +0 -144
  1707. package/src/AlertDialog/useImperativeAlertDialog.test.tsx +0 -163
  1708. package/src/AppShell/AppShell.spec.md +0 -334
  1709. package/src/AppShell/AppShell.test.tsx +0 -1148
  1710. package/src/AspectRatio/AspectRatio.spec.md +0 -179
  1711. package/src/AspectRatio/AspectRatio.test.tsx +0 -398
  1712. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +0 -158
  1713. package/src/Avatar/Avatar.spec.md +0 -253
  1714. package/src/Avatar/Avatar.test.tsx +0 -867
  1715. package/src/Avatar/AvatarStatusDot.spec.md +0 -208
  1716. package/src/Avatar/AvatarStatusDot.test.tsx +0 -306
  1717. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +0 -126
  1718. package/src/AvatarGroup/AvatarGroup.spec.md +0 -205
  1719. package/src/AvatarGroup/AvatarGroup.test.tsx +0 -313
  1720. package/src/AvatarGroup/AvatarGroupOverflow.spec.md +0 -210
  1721. package/src/AvatarGroup/AvatarGroupOverflow.test.tsx +0 -263
  1722. package/src/Badge/Badge.spec.md +0 -207
  1723. package/src/Badge/Badge.test.tsx +0 -125
  1724. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +0 -260
  1725. package/src/Banner/Banner.spec.md +0 -282
  1726. package/src/Banner/Banner.test.tsx +0 -879
  1727. package/src/Blockquote/Blockquote.spec.md +0 -171
  1728. package/src/Blockquote/Blockquote.test.tsx +0 -121
  1729. package/src/BottomSheet/BottomSheet.spec.md +0 -457
  1730. package/src/BottomSheet/BottomSheet.test.tsx +0 -3154
  1731. package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +0 -248
  1732. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +0 -195
  1733. package/src/BottomSheet/BottomSheetPanel.test.tsx +0 -549
  1734. package/src/BottomSheet/BottomSheetReplace.test.tsx +0 -1638
  1735. package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +0 -246
  1736. package/src/BottomSheet/BottomSheetStacking.test.tsx +0 -3184
  1737. package/src/BottomSheet/BottomSheetSwitcher.spec.md +0 -367
  1738. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +0 -2010
  1739. package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +0 -129
  1740. package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +0 -97
  1741. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +0 -415
  1742. package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +0 -462
  1743. package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +0 -247
  1744. package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +0 -83
  1745. package/src/BottomSheet/snapOffsets.test.ts +0 -254
  1746. package/src/BottomSheet/useSheetGestures.test.ts +0 -1690
  1747. package/src/Breadcrumbs/BreadcrumbItem.spec.md +0 -269
  1748. package/src/Breadcrumbs/Breadcrumbs.spec.md +0 -165
  1749. package/src/Breadcrumbs/Breadcrumbs.test.tsx +0 -921
  1750. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +0 -132
  1751. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.renders.tsx +0 -45
  1752. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.states.ts +0 -81
  1753. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.test.tsx +0 -125
  1754. package/src/Button/Button.spec.md +0 -322
  1755. package/src/Button/Button.test.tsx +0 -864
  1756. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +0 -355
  1757. package/src/Button/__tests__/Button.a11y.harnesses.tsx +0 -47
  1758. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -25
  1759. package/src/Button/__tests__/Button.a11y.renders.tsx +0 -139
  1760. package/src/Button/__tests__/Button.a11y.states.ts +0 -317
  1761. package/src/Button/__tests__/Button.a11y.test.tsx +0 -187
  1762. package/src/ButtonGroup/ButtonGroup.spec.md +0 -220
  1763. package/src/ButtonGroup/ButtonGroup.test.tsx +0 -1025
  1764. package/src/Calendar/Calendar.spec.md +0 -248
  1765. package/src/Calendar/Calendar.test.tsx +0 -2186
  1766. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +0 -141
  1767. package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +0 -12
  1768. package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +0 -57
  1769. package/src/Calendar/__tests__/Calendar.a11y.states.ts +0 -139
  1770. package/src/Calendar/__tests__/Calendar.a11y.test.tsx +0 -137
  1771. package/src/Calendar/dayCellUtils.test.ts +0 -520
  1772. package/src/Calendar/getInitialFocusDate.test.ts +0 -94
  1773. package/src/Calendar/getStandaloneShortWeekdayNames.test.ts +0 -54
  1774. package/src/Calendar/hooks/useCalendarConstraints.test.ts +0 -153
  1775. package/src/Calendar/hooks/useCalendarDays.test.ts +0 -265
  1776. package/src/Calendar/hooks/useCalendarNavigation.test.ts +0 -252
  1777. package/src/Card/Card.spec.md +0 -205
  1778. package/src/Card/Card.test.tsx +0 -202
  1779. package/src/Carousel/Carousel.spec.md +0 -146
  1780. package/src/Carousel/Carousel.test.tsx +0 -915
  1781. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +0 -207
  1782. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +0 -27
  1783. package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +0 -39
  1784. package/src/Carousel/__tests__/Carousel.a11y.states.ts +0 -139
  1785. package/src/Carousel/__tests__/Carousel.a11y.test.tsx +0 -127
  1786. package/src/Center/Center.spec.md +0 -205
  1787. package/src/Center/Center.test.tsx +0 -406
  1788. package/src/Chat/ChatComposer.spec.md +0 -230
  1789. package/src/Chat/ChatComposer.test.tsx +0 -364
  1790. package/src/Chat/ChatComposerDrawer.spec.md +0 -267
  1791. package/src/Chat/ChatComposerDrawer.test.tsx +0 -130
  1792. package/src/Chat/ChatComposerInput.spec.md +0 -224
  1793. package/src/Chat/ChatComposerInput.test.tsx +0 -2136
  1794. package/src/Chat/ChatComposerTokenElement.spec.md +0 -152
  1795. package/src/Chat/ChatComposerTokenElement.test.tsx +0 -85
  1796. package/src/Chat/ChatDictationButton.spec.md +0 -160
  1797. package/src/Chat/ChatDictationButton.test.tsx +0 -108
  1798. package/src/Chat/ChatLayout.spec.md +0 -271
  1799. package/src/Chat/ChatLayout.test.tsx +0 -311
  1800. package/src/Chat/ChatLayoutScrollButton.spec.md +0 -338
  1801. package/src/Chat/ChatLayoutScrollButton.test.tsx +0 -99
  1802. package/src/Chat/ChatMessage.spec.md +0 -265
  1803. package/src/Chat/ChatMessage.test.tsx +0 -344
  1804. package/src/Chat/ChatMessageBubble.spec.md +0 -263
  1805. package/src/Chat/ChatMessageBubble.test.tsx +0 -294
  1806. package/src/Chat/ChatMessageList.spec.md +0 -222
  1807. package/src/Chat/ChatMessageList.test.tsx +0 -198
  1808. package/src/Chat/ChatMessageMetadata.spec.md +0 -220
  1809. package/src/Chat/ChatMessageMetadata.test.tsx +0 -66
  1810. package/src/Chat/ChatPastedTextToken.test.tsx +0 -71
  1811. package/src/Chat/ChatSendButton.spec.md +0 -227
  1812. package/src/Chat/ChatSendButton.test.tsx +0 -309
  1813. package/src/Chat/ChatSystemMessage.spec.md +0 -224
  1814. package/src/Chat/ChatSystemMessage.test.tsx +0 -189
  1815. package/src/Chat/ChatTokenizedText.spec.md +0 -190
  1816. package/src/Chat/ChatTokenizedText.test.tsx +0 -163
  1817. package/src/Chat/ChatToolCalls.spec.md +0 -194
  1818. package/src/Chat/ChatToolCalls.test.tsx +0 -413
  1819. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +0 -577
  1820. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +0 -740
  1821. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +0 -457
  1822. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +0 -91
  1823. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +0 -91
  1824. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +0 -465
  1825. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +0 -416
  1826. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +0 -1523
  1827. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +0 -1004
  1828. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +0 -574
  1829. package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +0 -263
  1830. package/src/Chat/__tests__/useChatStreamScroll.fixture.tsx +0 -61
  1831. package/src/Chat/useChatDictation.test.tsx +0 -369
  1832. package/src/Chat/useChatNewMessages.test.tsx +0 -209
  1833. package/src/Chat/useChatPasteAsToken.test.ts +0 -191
  1834. package/src/Chat/useChatStreamScroll.test.tsx +0 -381
  1835. package/src/Chat/useTriggerMenu.test.tsx +0 -994
  1836. package/src/CheckboxInput/CheckboxInput.spec.md +0 -218
  1837. package/src/CheckboxInput/CheckboxInput.test.tsx +0 -926
  1838. package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +0 -354
  1839. package/src/CheckboxInput/__tests__/Checkbox.a11y.known-failures.ts +0 -54
  1840. package/src/CheckboxInput/__tests__/Checkbox.a11y.renders.tsx +0 -310
  1841. package/src/CheckboxInput/__tests__/Checkbox.a11y.states.ts +0 -404
  1842. package/src/CheckboxInput/__tests__/Checkbox.a11y.test.tsx +0 -128
  1843. package/src/CheckboxList/CheckboxList.fr10.test.tsx +0 -51
  1844. package/src/CheckboxList/CheckboxList.spec.md +0 -332
  1845. package/src/CheckboxList/CheckboxList.test.tsx +0 -1159
  1846. package/src/CheckboxList/CheckboxListItem.spec.md +0 -302
  1847. package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +0 -1998
  1848. package/src/Citation/Citation.spec.md +0 -179
  1849. package/src/Citation/Citation.test.tsx +0 -361
  1850. package/src/ClickableCard/ClickableCard.spec.md +0 -241
  1851. package/src/ClickableCard/ClickableCard.test.tsx +0 -286
  1852. package/src/Code/Code.spec.md +0 -170
  1853. package/src/Code/Code.test.tsx +0 -75
  1854. package/src/CodeBlock/CodeBlock.highlightStyles.test.tsx +0 -87
  1855. package/src/CodeBlock/CodeBlock.spec.md +0 -243
  1856. package/src/CodeBlock/CodeBlock.test.tsx +0 -752
  1857. package/src/CodeBlock/CodeLanguage.test.tsx +0 -173
  1858. package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +0 -290
  1859. package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +0 -64
  1860. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +0 -126
  1861. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +0 -94
  1862. package/src/CodeBlock/highlightRanges.test.ts +0 -253
  1863. package/src/CodeBlock/languages.test.ts +0 -402
  1864. package/src/CodeBlock/tokenizer.test.ts +0 -280
  1865. package/src/CodeBlock/tokenizerBudget.test.ts +0 -112
  1866. package/src/Collapsible/Collapsible.spec.md +0 -247
  1867. package/src/Collapsible/Collapsible.test.tsx +0 -620
  1868. package/src/Collapsible/CollapsibleGroup.spec.md +0 -229
  1869. package/src/Collapsible/CollapsibleGroup.test.tsx +0 -656
  1870. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +0 -194
  1871. package/src/Collapsible/__tests__/Collapsible.a11y.states.ts +0 -117
  1872. package/src/Collapsible/__tests__/Collapsible.a11y.test.tsx +0 -140
  1873. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +0 -559
  1874. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +0 -45
  1875. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +0 -139
  1876. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +0 -135
  1877. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +0 -141
  1878. package/src/Collapsible/useCollapsible.test.tsx +0 -236
  1879. package/src/CommandPalette/CommandPalette.perf.test.ts +0 -100
  1880. package/src/CommandPalette/CommandPalette.spec.md +0 -278
  1881. package/src/CommandPalette/CommandPalette.test.tsx +0 -750
  1882. package/src/CommandPalette/CommandPaletteEmpty.spec.md +0 -190
  1883. package/src/CommandPalette/CommandPaletteEmpty.test.tsx +0 -101
  1884. package/src/CommandPalette/CommandPaletteFooter.test.tsx +0 -122
  1885. package/src/CommandPalette/CommandPaletteGroup.test.tsx +0 -129
  1886. package/src/CommandPalette/CommandPaletteInput.spec.md +0 -215
  1887. package/src/CommandPalette/CommandPaletteInput.test.tsx +0 -539
  1888. package/src/CommandPalette/CommandPaletteItem.spec.md +0 -223
  1889. package/src/CommandPalette/CommandPaletteItem.test.tsx +0 -417
  1890. package/src/CommandPalette/CommandPaletteList.spec.md +0 -194
  1891. package/src/CommandPalette/CommandPaletteList.test.tsx +0 -184
  1892. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +0 -600
  1893. package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +0 -715
  1894. package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +0 -582
  1895. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +0 -336
  1896. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +0 -523
  1897. package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +0 -76
  1898. package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +0 -262
  1899. package/src/ComplexSelector/ComplexSelector.spec.md +0 -266
  1900. package/src/ComplexSelector/ComplexSelector.test.tsx +0 -1060
  1901. package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +0 -965
  1902. package/src/ContextMenu/ContextMenu.spec.md +0 -251
  1903. package/src/ContextMenu/ContextMenu.test.tsx +0 -1617
  1904. package/src/ContextMenu/ContextMenu.triggerProps.test.tsx +0 -54
  1905. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +0 -439
  1906. package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +0 -154
  1907. package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +0 -117
  1908. package/src/DateInput/DateInput.fr10.test.tsx +0 -283
  1909. package/src/DateInput/DateInput.spec.md +0 -319
  1910. package/src/DateInput/DateInput.test.tsx +0 -1571
  1911. package/src/DateInput/DateInputTouch.test.tsx +0 -2904
  1912. package/src/DateInput/MonthScrollerSettle.test.tsx +0 -165
  1913. package/src/DateInput/NativeDateField.test.tsx +0 -741
  1914. package/src/DateInput/Presentation.test.tsx +0 -121
  1915. package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +0 -577
  1916. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +0 -312
  1917. package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +0 -171
  1918. package/src/DateRangeInput/DateRangeInput.fr10.test.tsx +0 -165
  1919. package/src/DateRangeInput/DateRangeInput.spec.md +0 -203
  1920. package/src/DateRangeInput/DateRangeInput.test.tsx +0 -1151
  1921. package/src/DateTimeInput/DateTimeInput.fr10.test.tsx +0 -319
  1922. package/src/DateTimeInput/DateTimeInput.spec.md +0 -270
  1923. package/src/DateTimeInput/DateTimeInput.test.tsx +0 -2656
  1924. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +0 -1071
  1925. package/src/DateTimeInput/NativePickerSegments.test.tsx +0 -657
  1926. package/src/DateTimeInput/Presentation.test.tsx +0 -89
  1927. package/src/Dialog/Dialog.source-build.test.mjs +0 -43
  1928. package/src/Dialog/Dialog.spec.md +0 -189
  1929. package/src/Dialog/Dialog.test.tsx +0 -1599
  1930. package/src/Dialog/DialogHeader.test.tsx +0 -477
  1931. package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +0 -111
  1932. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +0 -218
  1933. package/src/Dialog/__tests__/Dialog.a11y.known-failures.ts +0 -28
  1934. package/src/Dialog/__tests__/Dialog.a11y.renders.tsx +0 -107
  1935. package/src/Dialog/__tests__/Dialog.a11y.states.ts +0 -104
  1936. package/src/Dialog/__tests__/Dialog.a11y.test.tsx +0 -102
  1937. package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +0 -252
  1938. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +0 -202
  1939. package/src/Dialog/modules/DialogHeader.spec.md +0 -211
  1940. package/src/Dialog/useImperativeDialog.test.tsx +0 -78
  1941. package/src/Divider/Divider.spec.md +0 -252
  1942. package/src/Divider/Divider.test.tsx +0 -155
  1943. package/src/Drawer/Drawer.spec.md +0 -388
  1944. package/src/Drawer/Drawer.test.tsx +0 -1335
  1945. package/src/Drawer/DrawerDirection.test.tsx +0 -127
  1946. package/src/Drawer/DrawerHeader.spec.md +0 -181
  1947. package/src/Drawer/DrawerHeader.test.tsx +0 -102
  1948. package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +0 -402
  1949. package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +0 -298
  1950. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +0 -267
  1951. package/src/DropdownMenu/DropdownMenu.spec.md +0 -582
  1952. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +0 -93
  1953. package/src/DropdownMenu/DropdownMenu.test.tsx +0 -4381
  1954. package/src/DropdownMenu/DropdownMenuContext.public.test.ts +0 -22
  1955. package/src/DropdownMenu/DropdownMenuDivider.spec.md +0 -192
  1956. package/src/DropdownMenu/DropdownMenuItem.spec.md +0 -209
  1957. package/src/DropdownMenu/DropdownMenuLazySheet.test.tsx +0 -126
  1958. package/src/DropdownMenu/DropdownMenuRadioGroup.spec.md +0 -190
  1959. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +0 -226
  1960. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +0 -635
  1961. package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +0 -72
  1962. package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +0 -225
  1963. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +0 -2442
  1964. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +0 -281
  1965. package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +0 -175
  1966. package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +0 -74
  1967. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +0 -335
  1968. package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +0 -367
  1969. package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +0 -328
  1970. package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +0 -540
  1971. package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +0 -671
  1972. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +0 -158
  1973. package/src/DropdownMenu/__tests__/Menu.a11y.known-failures.ts +0 -26
  1974. package/src/DropdownMenu/__tests__/Menu.a11y.renders.tsx +0 -65
  1975. package/src/DropdownMenu/__tests__/Menu.a11y.states.ts +0 -138
  1976. package/src/DropdownMenu/__tests__/Menu.a11y.test.tsx +0 -136
  1977. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +0 -149
  1978. package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +0 -12
  1979. package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +0 -67
  1980. package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +0 -141
  1981. package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +0 -138
  1982. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +0 -231
  1983. package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +0 -238
  1984. package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +0 -173
  1985. package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +0 -503
  1986. package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +0 -268
  1987. package/src/DropdownMenu/__tests__/warmMenuBottomSheet.tsx +0 -43
  1988. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +0 -53
  1989. package/src/DropdownMenu/modules/useMenuHover.spec.md +0 -283
  1990. package/src/DropdownMenu/modules/useMenuPress.spec.md +0 -348
  1991. package/src/EmptyState/EmptyState.announce.test.tsx +0 -227
  1992. package/src/EmptyState/EmptyState.spec.md +0 -197
  1993. package/src/EmptyState/EmptyState.test.tsx +0 -284
  1994. package/src/Field/Field.spec.md +0 -226
  1995. package/src/Field/Field.test.tsx +0 -800
  1996. package/src/Field/FieldLabel.spec.md +0 -183
  1997. package/src/Field/FieldLabel.test.tsx +0 -244
  1998. package/src/Field/InputClearButton.test.tsx +0 -395
  1999. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +0 -297
  2000. package/src/Field/fieldInputFamily.test.tsx +0 -160
  2001. package/src/FieldStatus/FieldStatus.spec.md +0 -224
  2002. package/src/FieldStatus/FieldStatus.test.tsx +0 -482
  2003. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +0 -206
  2004. package/src/FieldStatus/__tests__/StatusMessage.a11y.known-failures.ts +0 -13
  2005. package/src/FieldStatus/__tests__/StatusMessage.a11y.renders.tsx +0 -287
  2006. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +0 -302
  2007. package/src/FieldStatus/__tests__/StatusMessage.a11y.test.tsx +0 -154
  2008. package/src/FileInput/FileInput.fr10.test.tsx +0 -21
  2009. package/src/FileInput/FileInput.spec.md +0 -199
  2010. package/src/FileInput/FileInput.test.tsx +0 -1291
  2011. package/src/FormLayout/FormLayout.spec.md +0 -209
  2012. package/src/FormLayout/FormLayout.test.tsx +0 -444
  2013. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -46
  2014. package/src/Grid/Grid.spec.md +0 -193
  2015. package/src/Grid/Grid.test.tsx +0 -509
  2016. package/src/Grid/GridSpan.spec.md +0 -158
  2017. package/src/HStack/HStack.test.tsx +0 -129
  2018. package/src/Heading/Heading.spec.md +0 -198
  2019. package/src/Heading/Heading.test.tsx +0 -328
  2020. package/src/HoverCard/HoverCard.spec.md +0 -244
  2021. package/src/HoverCard/HoverCard.test.tsx +0 -1339
  2022. package/src/Icon/Icon.spec.md +0 -244
  2023. package/src/Icon/Icon.test.tsx +0 -990
  2024. package/src/Icon/globalIconRegistry.test.tsx +0 -613
  2025. package/src/IconButton/IconButton.spec.md +0 -197
  2026. package/src/IconButton/IconButton.test.tsx +0 -156
  2027. package/src/Indicator/CheckIndicator.spec.md +0 -164
  2028. package/src/Indicator/CheckboxIndicator.spec.md +0 -164
  2029. package/src/Indicator/Indicator.spec.md +0 -188
  2030. package/src/Indicator/Indicator.test.tsx +0 -389
  2031. package/src/Indicator/indicatorRegistry.test.tsx +0 -106
  2032. package/src/InputGroup/InputGroup.spec.md +0 -199
  2033. package/src/InputGroup/InputGroup.test.tsx +0 -502
  2034. package/src/InputGroup/InputGroupText.spec.md +0 -139
  2035. package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +0 -185
  2036. package/src/Item/Item.source-build.test.mjs +0 -88
  2037. package/src/Item/Item.spec.md +0 -226
  2038. package/src/Item/Item.swipeLayer.test.tsx +0 -74
  2039. package/src/Item/Item.test.tsx +0 -1455
  2040. package/src/Item/ItemMarkerColumns.a11y.chromium.spec.ts +0 -211
  2041. package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +0 -337
  2042. package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +0 -186
  2043. package/src/Kbd/Kbd.spec.md +0 -185
  2044. package/src/Kbd/Kbd.test.tsx +0 -299
  2045. package/src/Layer/LayerProvider.spec.md +0 -149
  2046. package/src/Layer/LayerProvider.test.tsx +0 -143
  2047. package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +0 -176
  2048. package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +0 -200
  2049. package/src/Layer/anchorName.test.ts +0 -146
  2050. package/src/Layer/layerDismissalFamilies.test.tsx +0 -487
  2051. package/src/Layer/layerDismissalInvariants.test.tsx +0 -501
  2052. package/src/Layer/layerHost.test.ts +0 -117
  2053. package/src/Layer/layerScopedContext.test.tsx +0 -499
  2054. package/src/Layer/layerViewportInset.source-build.test.mjs +0 -90
  2055. package/src/Layer/layerViewportInset.test.ts +0 -120
  2056. package/src/Layer/useLayer.test.tsx +0 -2423
  2057. package/src/Layer/useLayerDismissal.test.tsx +0 -580
  2058. package/src/Layer/useTouchTrigger.test.ts +0 -70
  2059. package/src/Layout/Layout.spec.md +0 -243
  2060. package/src/Layout/Layout.test.tsx +0 -375
  2061. package/src/Layout/LayoutContent.spec.md +0 -205
  2062. package/src/Layout/LayoutFooter.spec.md +0 -190
  2063. package/src/Layout/LayoutHeader.spec.md +0 -193
  2064. package/src/Layout/LayoutPanel.spec.md +0 -194
  2065. package/src/Layout/LayoutSlots.test.tsx +0 -376
  2066. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +0 -134
  2067. package/src/Layout/__tests__/Layout.a11y.renders.tsx +0 -110
  2068. package/src/Layout/__tests__/Layout.a11y.states.ts +0 -93
  2069. package/src/Layout/__tests__/Layout.a11y.test.tsx +0 -142
  2070. package/src/Layout/__tests__/childrenAsContent.test.tsx +0 -59
  2071. package/src/Layout/__tests__/contentWidth.test.tsx +0 -303
  2072. package/src/Layout/__tests__/edgeCompensation.test.tsx +0 -191
  2073. package/src/Layout/__tests__/nestedPadding.test.tsx +0 -264
  2074. package/src/Layout/overlayPaddingReset.test.tsx +0 -224
  2075. package/src/Lightbox/Lightbox.spec.md +0 -199
  2076. package/src/Lightbox/Lightbox.test.tsx +0 -837
  2077. package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +0 -78
  2078. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +0 -74
  2079. package/src/Lightbox/useLightbox.test.tsx +0 -263
  2080. package/src/Link/Link.spec.md +0 -229
  2081. package/src/Link/Link.test.tsx +0 -457
  2082. package/src/Link/LinkProvider.spec.md +0 -167
  2083. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +0 -153
  2084. package/src/Link/__tests__/Link.a11y.renders.tsx +0 -97
  2085. package/src/Link/__tests__/Link.a11y.states.ts +0 -104
  2086. package/src/Link/__tests__/Link.a11y.test.tsx +0 -127
  2087. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +0 -262
  2088. package/src/Link/useLinkComponent.test.tsx +0 -572
  2089. package/src/Link/useLinkify.test.tsx +0 -146
  2090. package/src/List/List.spec.md +0 -336
  2091. package/src/List/List.test.tsx +0 -1052
  2092. package/src/List/ListItem.source-build.test.mjs +0 -41
  2093. package/src/List/ListItem.spec.md +0 -205
  2094. package/src/List/ListMarkers.a11y.chromium.spec.ts +0 -904
  2095. package/src/Markdown/Markdown.codeLanguages.test.tsx +0 -137
  2096. package/src/Markdown/Markdown.fr23.bench.ts +0 -176
  2097. package/src/Markdown/Markdown.fr23.perf.test.ts +0 -484
  2098. package/src/Markdown/Markdown.helpers.perf.test.ts +0 -495
  2099. package/src/Markdown/Markdown.public.test.ts +0 -309
  2100. package/src/Markdown/Markdown.renderBoundary.test.tsx +0 -72
  2101. package/src/Markdown/Markdown.rerender.test.tsx +0 -143
  2102. package/src/Markdown/Markdown.spec.md +0 -595
  2103. package/src/Markdown/Markdown.test.tsx +0 -1383
  2104. package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +0 -727
  2105. package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +0 -102
  2106. package/src/Markdown/angleDestinations.test.tsx +0 -104
  2107. package/src/Markdown/ast.test.ts +0 -374
  2108. package/src/Markdown/atxHeadingIndentation.test.tsx +0 -53
  2109. package/src/Markdown/blockNesting.test.tsx +0 -124
  2110. package/src/Markdown/blockquoteMarkers.test.tsx +0 -69
  2111. package/src/Markdown/characterReferences.test.ts +0 -47
  2112. package/src/Markdown/codeSpans.test.tsx +0 -65
  2113. package/src/Markdown/emphasis.test.tsx +0 -214
  2114. package/src/Markdown/fenceInfo.test.tsx +0 -47
  2115. package/src/Markdown/imageAlt.test.tsx +0 -84
  2116. package/src/Markdown/incremental.test.ts +0 -1198
  2117. package/src/Markdown/incrementalIndentation.test.tsx +0 -36
  2118. package/src/Markdown/indentedFences.test.tsx +0 -374
  2119. package/src/Markdown/indentedTables.test.tsx +0 -53
  2120. package/src/Markdown/linkBrackets.test.tsx +0 -116
  2121. package/src/Markdown/linkDestinationLinear.test.tsx +0 -54
  2122. package/src/Markdown/linkDestinations.test.tsx +0 -127
  2123. package/src/Markdown/linkTextCode.test.tsx +0 -65
  2124. package/src/Markdown/listBullets.test.tsx +0 -55
  2125. package/src/Markdown/listContinuation.test.tsx +0 -94
  2126. package/src/Markdown/listThematicBreak.test.tsx +0 -49
  2127. package/src/Markdown/longLinkLabels.test.tsx +0 -49
  2128. package/src/Markdown/modules/headingLinks.spec.md +0 -262
  2129. package/src/Markdown/modules/remark.spec.md +0 -269
  2130. package/src/Markdown/modules/softBreaks.spec.md +0 -137
  2131. package/src/Markdown/modules/sourceLines.spec.md +0 -162
  2132. package/src/Markdown/openFenceFinalNewline.test.tsx +0 -85
  2133. package/src/Markdown/parser.perf.test.ts +0 -398
  2134. package/src/Markdown/parser.public.test.ts +0 -144
  2135. package/src/Markdown/parser.test.ts +0 -1925
  2136. package/src/Markdown/plugin-renderer/MarkdownPluginNodeRenderer.test.tsx +0 -300
  2137. package/src/Markdown/plugins/frontmatter.test.tsx +0 -150
  2138. package/src/Markdown/plugins/headingLinks.a11y.chromium.spec.ts +0 -856
  2139. package/src/Markdown/plugins/headingLinks.ssr.test.tsx +0 -143
  2140. package/src/Markdown/plugins/headingLinks.test.tsx +0 -637
  2141. package/src/Markdown/plugins/protocol.test.tsx +0 -1083
  2142. package/src/Markdown/plugins/semanticFence.test.tsx +0 -655
  2143. package/src/Markdown/plugins/softBreaks.test.tsx +0 -172
  2144. package/src/Markdown/plugins/sourceDecoration.test.tsx +0 -799
  2145. package/src/Markdown/plugins/sourceLines.test.tsx +0 -715
  2146. package/src/Markdown/plugins/textTransform.test.ts +0 -467
  2147. package/src/Markdown/remark.test.tsx +0 -1877
  2148. package/src/Markdown/streaming.test.ts +0 -148
  2149. package/src/Markdown/streamingListShapes.test.tsx +0 -93
  2150. package/src/Markdown/trailingSpaces.test.tsx +0 -45
  2151. package/src/MetadataList/MetadataList.test.tsx +0 -383
  2152. package/src/MobileNav/MobileNav.spec.md +0 -306
  2153. package/src/MobileNav/MobileNav.test.tsx +0 -296
  2154. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +0 -584
  2155. package/src/MobileNav/MobileNavCloseTiming.test.ts +0 -58
  2156. package/src/MobileNav/MobileNavCloseVisibility.test.tsx +0 -172
  2157. package/src/MobileNav/MobileNavEntryAnimation.test.tsx +0 -212
  2158. package/src/MobileNav/MobileNavFocus.test.tsx +0 -553
  2159. package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +0 -147
  2160. package/src/MobileNav/MobileNavReopen.test.tsx +0 -118
  2161. package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +0 -109
  2162. package/src/MobileNav/MobileNavToggle.test.tsx +0 -179
  2163. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +0 -89
  2164. package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +0 -103
  2165. package/src/MoreMenu/MoreMenu.spec.md +0 -268
  2166. package/src/MoreMenu/MoreMenu.test.tsx +0 -367
  2167. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +0 -149
  2168. package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +0 -72
  2169. package/src/MultiSelector/MultiSelector.focusableDisabled.test.tsx +0 -121
  2170. package/src/MultiSelector/MultiSelector.fr10.test.tsx +0 -221
  2171. package/src/MultiSelector/MultiSelector.spec.md +0 -357
  2172. package/src/MultiSelector/MultiSelector.test.tsx +0 -4819
  2173. package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +0 -310
  2174. package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +0 -46
  2175. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +0 -135
  2176. package/src/NavIcon/NavIcon.spec.md +0 -158
  2177. package/src/NavIcon/NavIcon.test.tsx +0 -41
  2178. package/src/NavMenu/NavHeadingMenu.spec.md +0 -264
  2179. package/src/NavMenu/NavHeadingMenu.test.tsx +0 -714
  2180. package/src/NavMenu/__tests__/NavMenusSlideSelection.a11y.chromium.spec.ts +0 -137
  2181. package/src/NumberInput/NumberInput.fr10.test.tsx +0 -21
  2182. package/src/NumberInput/NumberInput.spec.md +0 -270
  2183. package/src/NumberInput/NumberInput.test.tsx +0 -2636
  2184. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +0 -124
  2185. package/src/NumberInput/__tests__/NumberInput.a11y.known-failures.ts +0 -26
  2186. package/src/NumberInput/__tests__/NumberInput.a11y.renders.tsx +0 -77
  2187. package/src/NumberInput/__tests__/NumberInput.a11y.states.ts +0 -116
  2188. package/src/NumberInput/__tests__/NumberInput.a11y.test.tsx +0 -154
  2189. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +0 -102
  2190. package/src/NumberInput/numberInputCommit.test.ts +0 -72
  2191. package/src/NumberInput/numberParser.docblock.test.ts +0 -234
  2192. package/src/NumberInput/numberParser.test.ts +0 -222
  2193. package/src/Outline/Outline.spec.md +0 -162
  2194. package/src/Outline/Outline.test.tsx +0 -1069
  2195. package/src/Outline/OutlineFocus.a11y.chromium.spec.ts +0 -551
  2196. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +0 -151
  2197. package/src/Outline/parseOutlineFromMarkdown.test.ts +0 -104
  2198. package/src/OverflowList/OverflowList.spec.md +0 -157
  2199. package/src/OverflowList/OverflowList.test.tsx +0 -1073
  2200. package/src/Overlay/Overlay.spec.md +0 -304
  2201. package/src/Overlay/Overlay.test.tsx +0 -424
  2202. package/src/Pagination/Pagination.spec.md +0 -226
  2203. package/src/Pagination/Pagination.test.tsx +0 -1754
  2204. package/src/Popover/Popover.spec.md +0 -525
  2205. package/src/Popover/Popover.test.tsx +0 -1424
  2206. package/src/Popover/PopoverPresentation.test.tsx +0 -952
  2207. package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +0 -205
  2208. package/src/PowerSearch/PowerSearch.spec.md +0 -661
  2209. package/src/PowerSearch/PowerSearch.test.tsx +0 -1003
  2210. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +0 -1190
  2211. package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +0 -377
  2212. package/src/PowerSearch/PowerSearchToken.test.tsx +0 -230
  2213. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +0 -754
  2214. package/src/PowerSearch/formatFilterValue.test.ts +0 -339
  2215. package/src/PowerSearch/resolveDateTimeRangePart.test.ts +0 -40
  2216. package/src/PowerSearch/usePowerSearchConfig.test.ts +0 -832
  2217. package/src/PowerSearch/usePowerSearchSource.test.ts +0 -621
  2218. package/src/ProgressBar/ProgressBar.spec.md +0 -261
  2219. package/src/ProgressBar/ProgressBar.test.tsx +0 -928
  2220. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +0 -127
  2221. package/src/ProgressBar/__tests__/ProgressBar.a11y.known-failures.ts +0 -12
  2222. package/src/ProgressBar/__tests__/ProgressBar.a11y.renders.tsx +0 -38
  2223. package/src/ProgressBar/__tests__/ProgressBar.a11y.states.ts +0 -123
  2224. package/src/ProgressBar/__tests__/ProgressBar.a11y.test.tsx +0 -107
  2225. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +0 -831
  2226. package/src/RadioList/RadioList.fr10.test.tsx +0 -67
  2227. package/src/RadioList/RadioList.spec.md +0 -227
  2228. package/src/RadioList/RadioList.test.tsx +0 -967
  2229. package/src/RadioList/RadioListItem.press.source-build.test.mjs +0 -80
  2230. package/src/RadioList/RadioListItem.spec.md +0 -223
  2231. package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +0 -274
  2232. package/src/RadioList/__tests__/RadioGroup.a11y.known-failures.ts +0 -12
  2233. package/src/RadioList/__tests__/RadioGroup.a11y.renders.tsx +0 -232
  2234. package/src/RadioList/__tests__/RadioGroup.a11y.states.ts +0 -503
  2235. package/src/RadioList/__tests__/RadioGroup.a11y.test.tsx +0 -217
  2236. package/src/Resizable/Resizable.spec.md +0 -278
  2237. package/src/Resizable/ResizeHandle.test.tsx +0 -1067
  2238. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +0 -127
  2239. package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +0 -39
  2240. package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +0 -80
  2241. package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +0 -197
  2242. package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +0 -123
  2243. package/src/Resizable/shippedDirections.test.ts +0 -462
  2244. package/src/Resizable/useResizable.test.ts +0 -1725
  2245. package/src/Resizable/utils.test.ts +0 -74
  2246. package/src/ScrollableArea/ScrollableArea.spec.md +0 -190
  2247. package/src/ScrollableArea/ScrollableArea.test.tsx +0 -304
  2248. package/src/ScrollableArea/modules/useScrollableArea.spec.md +0 -149
  2249. package/src/Section/Section.spec.md +0 -197
  2250. package/src/Section/Section.test.tsx +0 -376
  2251. package/src/SegmentedControl/SegmentedControl.spec.md +0 -261
  2252. package/src/SegmentedControl/SegmentedControl.test.tsx +0 -981
  2253. package/src/SegmentedControl/SegmentedControlItem.spec.md +0 -206
  2254. package/src/SelectableCard/SelectableCard.spec.md +0 -230
  2255. package/src/SelectableCard/SelectableCard.test.tsx +0 -216
  2256. package/src/Selector/Selector.focusableDisabled.test.tsx +0 -127
  2257. package/src/Selector/Selector.fr10.test.tsx +0 -149
  2258. package/src/Selector/Selector.sheetActiveDescendant.test.tsx +0 -95
  2259. package/src/Selector/Selector.source-build.test.mjs +0 -79
  2260. package/src/Selector/Selector.spec.md +0 -379
  2261. package/src/Selector/Selector.test.tsx +0 -5117
  2262. package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +0 -27
  2263. package/src/Selector/__tests__/Combobox.a11y.states.ts +0 -145
  2264. package/src/Selector/__tests__/ComboboxField.a11y.chromium.spec.ts +0 -458
  2265. package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +0 -91
  2266. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +0 -131
  2267. package/src/Selector/__tests__/Listbox.a11y.dom.ts +0 -38
  2268. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +0 -63
  2269. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +0 -12
  2270. package/src/Selector/__tests__/Listbox.a11y.states.ts +0 -232
  2271. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +0 -46
  2272. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +0 -109
  2273. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +0 -133
  2274. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +0 -128
  2275. package/src/Selector/useCombobox.public.test.tsx +0 -89
  2276. package/src/Selector/useCombobox.test.tsx +0 -444
  2277. package/src/SideNav/SideNav.spec.md +0 -247
  2278. package/src/SideNav/SideNav.test.tsx +0 -4155
  2279. package/src/SideNav/SideNavCollapseButton.spec.md +0 -161
  2280. package/src/SideNav/SideNavHeading.spec.md +0 -226
  2281. package/src/SideNav/SideNavItem.spec.md +0 -246
  2282. package/src/SideNav/SideNavRailMotion.test.tsx +0 -620
  2283. package/src/SideNav/SideNavSection.spec.md +0 -153
  2284. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +0 -542
  2285. package/src/SizeContext/SizeContext.test.tsx +0 -226
  2286. package/src/Skeleton/Skeleton.spec.md +0 -184
  2287. package/src/Skeleton/Skeleton.test.tsx +0 -148
  2288. package/src/Slider/Slider.fr10.test.tsx +0 -93
  2289. package/src/Slider/Slider.spec.md +0 -285
  2290. package/src/Slider/Slider.test.tsx +0 -1642
  2291. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +0 -125
  2292. package/src/Slider/__tests__/Slider.a11y.known-failures.ts +0 -12
  2293. package/src/Slider/__tests__/Slider.a11y.renders.tsx +0 -42
  2294. package/src/Slider/__tests__/Slider.a11y.states.ts +0 -106
  2295. package/src/Slider/__tests__/Slider.a11y.test.tsx +0 -105
  2296. package/src/Spinner/Spinner.spec.md +0 -231
  2297. package/src/Spinner/Spinner.test.tsx +0 -484
  2298. package/src/Stack/Stack.spec.md +0 -203
  2299. package/src/Stack/Stack.test.tsx +0 -473
  2300. package/src/Stack/StackItem.test.tsx +0 -105
  2301. package/src/StatusDot/StatusDot.spec.md +0 -224
  2302. package/src/StatusDot/StatusDot.test.tsx +0 -213
  2303. package/src/Stepper/Step.spec.md +0 -206
  2304. package/src/Stepper/Stepper.public.test.ts +0 -91
  2305. package/src/Stepper/Stepper.spec.md +0 -327
  2306. package/src/Stepper/Stepper.test.tsx +0 -2068
  2307. package/src/Switch/Switch.focusRing.source-build.test.mjs +0 -81
  2308. package/src/Switch/Switch.spec.md +0 -277
  2309. package/src/Switch/Switch.test.tsx +0 -1071
  2310. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +0 -211
  2311. package/src/Switch/__tests__/Switch.a11y.known-failures.ts +0 -28
  2312. package/src/Switch/__tests__/Switch.a11y.states.ts +0 -275
  2313. package/src/Switch/__tests__/Switch.a11y.test.tsx +0 -144
  2314. package/src/TabList/Tab.spec.md +0 -201
  2315. package/src/TabList/TabList.spec.md +0 -217
  2316. package/src/TabList/TabList.test.tsx +0 -1755
  2317. package/src/TabList/TabMenu.spec.md +0 -198
  2318. package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +0 -99
  2319. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +0 -163
  2320. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +0 -199
  2321. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +0 -12
  2322. package/src/TabList/__tests__/Tabs.a11y.renders.tsx +0 -92
  2323. package/src/TabList/__tests__/Tabs.a11y.states.ts +0 -247
  2324. package/src/TabList/__tests__/Tabs.a11y.test.tsx +0 -153
  2325. package/src/Table/Table.perf.test.tsx +0 -569
  2326. package/src/Table/Table.spec.md +0 -395
  2327. package/src/Table/Table.test.tsx +0 -1851
  2328. package/src/Table/TableHeaderCell.test.tsx +0 -291
  2329. package/src/Table/TableSelectionToolbar.test.tsx +0 -109
  2330. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +0 -141
  2331. package/src/Table/__tests__/Table.a11y.contracts.ts +0 -35
  2332. package/src/Table/__tests__/Table.a11y.renders.tsx +0 -112
  2333. package/src/Table/__tests__/Table.a11y.states.ts +0 -140
  2334. package/src/Table/__tests__/Table.a11y.test.tsx +0 -198
  2335. package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +0 -75
  2336. package/src/Table/__tests__/TableRowGlide.a11y.browser.spec.ts +0 -382
  2337. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +0 -138
  2338. package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +0 -560
  2339. package/src/Table/plugins/activation/useTableActivation.spec.md +0 -254
  2340. package/src/Table/plugins/columnResize/useTableColumnResize.spec.md +0 -373
  2341. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +0 -941
  2342. package/src/Table/plugins/columnSettings/useTableColumnSettings.test.tsx +0 -175
  2343. package/src/Table/plugins/columnSettings/useTableColumnSettingsState.test.tsx +0 -296
  2344. package/src/Table/plugins/filtering/useTableFilterState.test.tsx +0 -143
  2345. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +0 -357
  2346. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +0 -112
  2347. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +0 -409
  2348. package/src/Table/plugins/infiniteScroll/useTableInfiniteScroll.spec.md +0 -244
  2349. package/src/Table/plugins/pagination/useTablePagination-perf.test.tsx +0 -232
  2350. package/src/Table/plugins/pagination/useTablePagination.test.tsx +0 -666
  2351. package/src/Table/plugins/rowExpansion/useTableRowExpansion.glide.test.tsx +0 -280
  2352. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +0 -681
  2353. package/src/Table/plugins/rowIndex/useTableRowIndex.test.tsx +0 -132
  2354. package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +0 -92
  2355. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +0 -355
  2356. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +0 -519
  2357. package/src/Table/plugins/selection/useTableSelection-perf.test.tsx +0 -258
  2358. package/src/Table/plugins/selection/useTableSelection.test.tsx +0 -424
  2359. package/src/Table/plugins/selection/useTableSelectionState.test.tsx +0 -451
  2360. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +0 -174
  2361. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +0 -86
  2362. package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -857
  2363. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +0 -592
  2364. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +0 -334
  2365. package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +0 -163
  2366. package/src/Table/plugins/tree/useTableTreeData.test.tsx +0 -992
  2367. package/src/Table/plugins/tree/useTableTreeState.test.tsx +0 -740
  2368. package/src/Table/plugins/virtualization/useTableVirtualization.spec.md +0 -266
  2369. package/src/Table/tableContextMenu.test.tsx +0 -208
  2370. package/src/Text/Text.spec.md +0 -193
  2371. package/src/Text/Text.test.tsx +0 -405
  2372. package/src/Text/useTruncation.test.tsx +0 -196
  2373. package/src/TextArea/TextArea.fr10.test.tsx +0 -21
  2374. package/src/TextArea/TextArea.spec.md +0 -300
  2375. package/src/TextArea/TextArea.test.tsx +0 -1317
  2376. package/src/TextInput/TextInput.fr10.test.tsx +0 -21
  2377. package/src/TextInput/TextInput.spec.md +0 -260
  2378. package/src/TextInput/TextInput.test.tsx +0 -1280
  2379. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +0 -214
  2380. package/src/TextInput/__tests__/TextInput.a11y.known-failures.ts +0 -40
  2381. package/src/TextInput/__tests__/TextInput.a11y.renders.tsx +0 -202
  2382. package/src/TextInput/__tests__/TextInput.a11y.states.ts +0 -384
  2383. package/src/TextInput/__tests__/TextInput.a11y.test.tsx +0 -130
  2384. package/src/Thumbnail/Thumbnail.spec.md +0 -244
  2385. package/src/Thumbnail/Thumbnail.test.tsx +0 -384
  2386. package/src/TimeInput/NativeTimeInput.test.tsx +0 -343
  2387. package/src/TimeInput/Presentation.test.tsx +0 -192
  2388. package/src/TimeInput/TimeInput.fr10.test.tsx +0 -312
  2389. package/src/TimeInput/TimeInput.spec.md +0 -270
  2390. package/src/TimeInput/TimeInput.test.tsx +0 -907
  2391. package/src/Timer/Timer.spec.md +0 -215
  2392. package/src/Timer/Timer.test.tsx +0 -302
  2393. package/src/Timestamp/Timestamp.spec.md +0 -246
  2394. package/src/Timestamp/Timestamp.test.tsx +0 -1661
  2395. package/src/Timestamp/tooltipEntries.test.ts +0 -566
  2396. package/src/Toast/Toast.spec.md +0 -294
  2397. package/src/Toast/ToastViewport.modalHost.test.tsx +0 -891
  2398. package/src/Toast/ToastViewport.test.tsx +0 -3051
  2399. package/src/Toast/useToast.test.tsx +0 -258
  2400. package/src/ToggleButton/ToggleButton.spec.md +0 -256
  2401. package/src/ToggleButton/ToggleButton.test.tsx +0 -973
  2402. package/src/ToggleButton/ToggleButtonGroup.spec.md +0 -195
  2403. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +0 -177
  2404. package/src/ToggleButton/__tests__/ToggleButton.a11y.renders.tsx +0 -133
  2405. package/src/ToggleButton/__tests__/ToggleButton.a11y.states.ts +0 -167
  2406. package/src/ToggleButton/__tests__/ToggleButton.a11y.test.tsx +0 -103
  2407. package/src/Token/Token.spec.md +0 -271
  2408. package/src/Token/Token.test.tsx +0 -640
  2409. package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +0 -87
  2410. package/src/Tokenizer/Tokenizer.fr10.test.tsx +0 -28
  2411. package/src/Tokenizer/Tokenizer.props-type.test.tsx +0 -126
  2412. package/src/Tokenizer/Tokenizer.spec.md +0 -603
  2413. package/src/Tokenizer/Tokenizer.ssr.test.tsx +0 -196
  2414. package/src/Tokenizer/Tokenizer.test.tsx +0 -2189
  2415. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +0 -2730
  2416. package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +0 -505
  2417. package/src/Toolbar/Toolbar.spec.md +0 -227
  2418. package/src/Toolbar/Toolbar.test.tsx +0 -600
  2419. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +0 -176
  2420. package/src/Toolbar/__tests__/Toolbar.a11y.renders.tsx +0 -63
  2421. package/src/Toolbar/__tests__/Toolbar.a11y.states.ts +0 -142
  2422. package/src/Toolbar/__tests__/Toolbar.a11y.test.tsx +0 -126
  2423. package/src/Tooltip/Tooltip.spec.md +0 -267
  2424. package/src/Tooltip/Tooltip.test.tsx +0 -819
  2425. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +0 -141
  2426. package/src/Tooltip/__tests__/Tooltip.a11y.renders.tsx +0 -86
  2427. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +0 -132
  2428. package/src/Tooltip/__tests__/Tooltip.a11y.test.tsx +0 -126
  2429. package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +0 -130
  2430. package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +0 -75
  2431. package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +0 -673
  2432. package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +0 -1162
  2433. package/src/Tooltip/useTooltip.test.tsx +0 -483
  2434. package/src/TopNav/TopNav.spec.md +0 -190
  2435. package/src/TopNav/TopNav.test.tsx +0 -863
  2436. package/src/TopNav/TopNavHeading.spec.md +0 -211
  2437. package/src/TopNav/TopNavItem.spec.md +0 -189
  2438. package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +0 -83
  2439. package/src/TopNav/TopNavMegaMenu.spec.md +0 -190
  2440. package/src/TopNav/TopNavMegaMenu.test.tsx +0 -1132
  2441. package/src/TopNav/TopNavMegaMenuFeaturedCard.spec.md +0 -150
  2442. package/src/TopNav/TopNavMegaMenuItem.spec.md +0 -155
  2443. package/src/TopNav/TopNavMenu.spec.md +0 -202
  2444. package/src/TopNav/TopNavMenu.test.tsx +0 -485
  2445. package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +0 -75
  2446. package/src/TreeList/TreeList.spec.md +0 -328
  2447. package/src/TreeList/TreeList.test.tsx +0 -1711
  2448. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +0 -138
  2449. package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +0 -44
  2450. package/src/TreeList/__tests__/TreeList.a11y.states.ts +0 -164
  2451. package/src/TreeList/__tests__/TreeList.a11y.test.tsx +0 -138
  2452. package/src/TreeList/__tests__/TreeListGuideAlignment.interaction.browser.spec.ts +0 -127
  2453. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +0 -83
  2454. package/src/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.ts +0 -138
  2455. package/src/Typeahead/BaseTypeahead.spec.md +0 -270
  2456. package/src/Typeahead/BaseTypeahead.test.tsx +0 -553
  2457. package/src/Typeahead/Typeahead.fr10.test.tsx +0 -28
  2458. package/src/Typeahead/Typeahead.spec.md +0 -257
  2459. package/src/Typeahead/Typeahead.test.tsx +0 -2864
  2460. package/src/Typeahead/TypeaheadItem.test.tsx +0 -134
  2461. package/src/VStack/VStack.test.tsx +0 -128
  2462. package/src/VisuallyHidden/VisuallyHidden.spec.md +0 -170
  2463. package/src/VisuallyHidden/VisuallyHidden.test.tsx +0 -115
  2464. package/src/__tests__/BusyOwnerAnnouncement.test.tsx +0 -853
  2465. package/src/__tests__/CardPress.a11y.chromium.spec.ts +0 -353
  2466. package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +0 -87
  2467. package/src/__tests__/PressModality.a11y.chromium.spec.ts +0 -392
  2468. package/src/__tests__/PressedState.a11y.chromium.spec.ts +0 -814
  2469. package/src/__tests__/TestIcon.tsx +0 -26
  2470. package/src/__tests__/babelPluginAddExtensions.test.ts +0 -190
  2471. package/src/__tests__/fastRoleQueries.ts +0 -66
  2472. package/src/__tests__/forcedColors.ts +0 -60
  2473. package/src/__tests__/pressState.ts +0 -212
  2474. package/src/__tests__/stubMatchMedia.test.ts +0 -79
  2475. package/src/__tests__/stubMatchMedia.ts +0 -95
  2476. package/src/__tests__/stylexDeclarations.ts +0 -51
  2477. package/src/__tests__/unthemedLength.ts +0 -34
  2478. package/src/docPropLiterals.test.ts +0 -964
  2479. package/src/docPropReferences.test.ts +0 -178
  2480. package/src/docs-script.test.mjs +0 -55
  2481. package/src/gestures/__tests__/GestureHost.test.ts +0 -2087
  2482. package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +0 -141
  2483. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +0 -327
  2484. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +0 -74
  2485. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +0 -498
  2486. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +0 -108
  2487. package/src/gestures/__tests__/TapGestureRecognizer.test.ts +0 -154
  2488. package/src/gestures/__tests__/VelocityTracker.streams.test.ts +0 -243
  2489. package/src/gestures/__tests__/VelocityTracker.test.ts +0 -261
  2490. package/src/gestures/__tests__/arena.test.ts +0 -829
  2491. package/src/gestures/__tests__/arenaContinuous.test.ts +0 -207
  2492. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +0 -193
  2493. package/src/gestures/__tests__/arenaTapLongPress.test.ts +0 -211
  2494. package/src/gestures/__tests__/browser/build-fixture.mjs +0 -46
  2495. package/src/gestures/__tests__/browser/fixture.ts +0 -307
  2496. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +0 -1137
  2497. package/src/gestures/__tests__/browserNegotiation.test.ts +0 -293
  2498. package/src/gestures/__tests__/fixtures/pointer-streams/README.md +0 -82
  2499. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-fling.json +0 -130
  2500. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-slow.json +0 -860
  2501. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-stop-release.json +0 -357
  2502. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-fling.json +0 -66
  2503. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-slow.json +0 -268
  2504. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-stop-release.json +0 -128
  2505. package/src/gestures/__tests__/fixtures/pointer-streams/capture.html +0 -123
  2506. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-fling.json +0 -64
  2507. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-slow.json +0 -268
  2508. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-stop-release.json +0 -124
  2509. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-fling.json +0 -64
  2510. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-slow.json +0 -268
  2511. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-stop-release.json +0 -124
  2512. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-fling.json +0 -84
  2513. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-slow.json +0 -381
  2514. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-stop-release.json +0 -171
  2515. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-fling.json +0 -45
  2516. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-slow.json +0 -101
  2517. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-stop-release.json +0 -130
  2518. package/src/gestures/__tests__/haptics.test.ts +0 -187
  2519. package/src/gestures/__tests__/harness.ts +0 -223
  2520. package/src/gestures/__tests__/recognizerKind.test.ts +0 -78
  2521. package/src/gestures/__tests__/touchActionRule.test.ts +0 -54
  2522. package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +0 -144
  2523. package/src/hooks/__tests__/menuLinkClicks.ts +0 -71
  2524. package/src/hooks/actionGroupTracker.exports.test.ts +0 -28
  2525. package/src/hooks/actionGroupTracker.test.ts +0 -510
  2526. package/src/hooks/computeOverflow.test.ts +0 -422
  2527. package/src/hooks/deprecatedApis.public.test.ts +0 -33
  2528. package/src/hooks/menuPressGesture.test.ts +0 -253
  2529. package/src/hooks/scrollKeyboardDelegation.test.ts +0 -155
  2530. package/src/hooks/scrollbarGutter.test.ts +0 -167
  2531. package/src/hooks/useAnnounce.modal.test.tsx +0 -1291
  2532. package/src/hooks/useAnnounce.test.tsx +0 -293
  2533. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +0 -226
  2534. package/src/hooks/useAutoMediaMode.test.ts +0 -109
  2535. package/src/hooks/useBusyAnnouncement.adopters.test.tsx +0 -69
  2536. package/src/hooks/useBusyAnnouncement.test.tsx +0 -112
  2537. package/src/hooks/useClickableContainer.test.tsx +0 -236
  2538. package/src/hooks/useClipboard.test.tsx +0 -151
  2539. package/src/hooks/useContainerReveal.test.tsx +0 -163
  2540. package/src/hooks/useDevWarning.test.tsx +0 -45
  2541. package/src/hooks/useEntryAnimation.ssr.test.tsx +0 -143
  2542. package/src/hooks/useFocusTrap.test.tsx +0 -635
  2543. package/src/hooks/useFocusTrapEscapeShim.test.tsx +0 -166
  2544. package/src/hooks/useGridFocus.test.tsx +0 -165
  2545. package/src/hooks/useHotkeys.test.ts +0 -265
  2546. package/src/hooks/useImageMode.test.ts +0 -133
  2547. package/src/hooks/useInputContainer.test.tsx +0 -180
  2548. package/src/hooks/useInputStatusIcon.test.tsx +0 -240
  2549. package/src/hooks/useIsHydrating.test.tsx +0 -70
  2550. package/src/hooks/useKeyboardHint.test.tsx +0 -92
  2551. package/src/hooks/useListFocus.test.tsx +0 -664
  2552. package/src/hooks/useLongPress.test.tsx +0 -152
  2553. package/src/hooks/useMediaQuery.test.ts +0 -165
  2554. package/src/hooks/useMenuHover.test.tsx +0 -536
  2555. package/src/hooks/useMenuPress.test.tsx +0 -565
  2556. package/src/hooks/useMergedRefs.test.tsx +0 -62
  2557. package/src/hooks/useOverflow.test.ts +0 -504
  2558. package/src/hooks/useRenamedProp.test.tsx +0 -95
  2559. package/src/hooks/useScrollLock.test.ts +0 -248
  2560. package/src/hooks/useScrollOverflow.test.tsx +0 -222
  2561. package/src/hooks/useScrollableArea.test.tsx +0 -836
  2562. package/src/hooks/useStreamingText.test.ts +0 -237
  2563. package/src/hooks/useTreeFocus.test.tsx +0 -351
  2564. package/src/hooks/useTypeahead.test.tsx +0 -351
  2565. package/src/i18n/InternationalizationProvider.spec.md +0 -252
  2566. package/src/i18n/__tests__/InternationalizationProvider.test.tsx +0 -128
  2567. package/src/i18n/__tests__/e2e-pagination.test.tsx +0 -172
  2568. package/src/i18n/__tests__/e2e-powersearch.test.tsx +0 -166
  2569. package/src/i18n/__tests__/getLocaleDirection.test.ts +0 -40
  2570. package/src/i18n/__tests__/resolve.test.ts +0 -325
  2571. package/src/i18n/__tests__/useCollator.test.tsx +0 -115
  2572. package/src/i18n/__tests__/useDirection.test.tsx +0 -66
  2573. package/src/i18n/__tests__/useLocale.test.tsx +0 -52
  2574. package/src/i18n/useTranslator.test.tsx +0 -267
  2575. package/src/inputFontFloor.test.ts +0 -106
  2576. package/src/internal/tokenizer-presentation.test.ts +0 -29
  2577. package/src/internal/touch.test.ts +0 -44
  2578. package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +0 -1613
  2579. package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +0 -217
  2580. package/src/motion/__tests__/animatedLayoutBundle.ts +0 -17
  2581. package/src/motion/animatedLayout.boundary.test.ts +0 -155
  2582. package/src/motion/animatedLayout.swap.test.ts +0 -827
  2583. package/src/motion/animatedLayout.test.ts +0 -1154
  2584. package/src/motion/animatedLayoutAdopters.test.tsx +0 -500
  2585. package/src/motion/animator.test.ts +0 -2801
  2586. package/src/motion/bezier.test.ts +0 -52
  2587. package/src/motion/coast.test.ts +0 -99
  2588. package/src/motion/decay.test.ts +0 -120
  2589. package/src/motion/projection.test.ts +0 -107
  2590. package/src/motion/reducedMotion.test.ts +0 -129
  2591. package/src/motion/reducedMotionPlan.test.ts +0 -182
  2592. package/src/motion/resolveSnapPoint.test.ts +0 -189
  2593. package/src/motion/roles.test.ts +0 -256
  2594. package/src/motion/rubberBand.test.ts +0 -88
  2595. package/src/motion/selectPage.test.ts +0 -31
  2596. package/src/motion/spring.test.ts +0 -650
  2597. package/src/motion/uikit/gestures.test.ts +0 -89
  2598. package/src/motion/uikit/springRows.test.ts +0 -71
  2599. package/src/motion/uikit/uikit.test.ts +0 -364
  2600. package/src/motion/uikit/values.test.ts +0 -110
  2601. package/src/naming.test.ts +0 -44
  2602. package/src/postinstall.test.mjs +0 -216
  2603. package/src/reset.a11y.chromium.spec.ts +0 -238
  2604. package/src/reset.test.ts +0 -205
  2605. package/src/reset.until-found.a11y.browser.spec.ts +0 -76
  2606. package/src/reset.until-found.test.ts +0 -32
  2607. package/src/serverSafeComponents.test.ts +0 -675
  2608. package/src/stylexValidation.source-build.test.mjs +0 -42
  2609. package/src/tailwind-theme.test.ts +0 -153
  2610. package/src/theme/MediaTheme.dom.test.tsx +0 -97
  2611. package/src/theme/Theme.test.tsx +0 -337
  2612. package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +0 -199
  2613. package/src/theme/contrast.test.ts +0 -94
  2614. package/src/theme/declarationBoundary.test.ts +0 -126
  2615. package/src/theme/defineTheme.test.ts +0 -2028
  2616. package/src/theme/derivedVarRegistry.test.ts +0 -592
  2617. package/src/theme/expandColorScale.test.ts +0 -651
  2618. package/src/theme/expandMotionScale.test.ts +0 -145
  2619. package/src/theme/expandRadiusScale.test.ts +0 -59
  2620. package/src/theme/expandTypeScale.test.ts +0 -351
  2621. package/src/theme/extensibleAxes.test.ts +0 -432
  2622. package/src/theme/generateThemeRules.test.ts +0 -1870
  2623. package/src/theme/hct.test.ts +0 -93
  2624. package/src/theme/onMediaTokens.test.ts +0 -431
  2625. package/src/theme/publicThemeHelperContract.test.ts +0 -67
  2626. package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +0 -91
  2627. package/src/theme/syntax/serverSafeSyntax.test.ts +0 -68
  2628. package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +0 -40
  2629. package/src/theme/themeAdaptations.test.ts +0 -1795
  2630. package/src/theme/themeRegistry.test.ts +0 -59
  2631. package/src/theme/themingTargets.test.ts +0 -589
  2632. package/src/theme/tokenValueCompat.test.ts +0 -204
  2633. package/src/theme/tokens.test.ts +0 -441
  2634. package/src/theme/useTheme.test.tsx +0 -322
  2635. package/src/unicodePropertyEscapes.source-build.test.mjs +0 -69
  2636. package/src/utils/chainEventHandlers.test.ts +0 -39
  2637. package/src/utils/characters.test.ts +0 -141
  2638. package/src/utils/color.test.ts +0 -233
  2639. package/src/utils/composeEventHandlers.test.ts +0 -71
  2640. package/src/utils/customPropertyArmLayering.test.ts +0 -131
  2641. package/src/utils/dateParser.test.ts +0 -402
  2642. package/src/utils/dateTypes.test.ts +0 -40
  2643. package/src/utils/devWarning.test.ts +0 -56
  2644. package/src/utils/edgeAutoscroll.test.ts +0 -192
  2645. package/src/utils/focusReturn.test.ts +0 -119
  2646. package/src/utils/getKey.test.ts +0 -25
  2647. package/src/utils/getNodeText.test.ts +0 -24
  2648. package/src/utils/hitArea.test.ts +0 -628
  2649. package/src/utils/ime.test.ts +0 -32
  2650. package/src/utils/inputAria.test.ts +0 -39
  2651. package/src/utils/interactionModality.test.ts +0 -144
  2652. package/src/utils/isApplePlatform.test.ts +0 -61
  2653. package/src/utils/mergeProps.test.ts +0 -166
  2654. package/src/utils/mergeRefs.test.ts +0 -48
  2655. package/src/utils/parseStyleKey.test.ts +0 -56
  2656. package/src/utils/plainDate.test.ts +0 -938
  2657. package/src/utils/presentation.test.ts +0 -380
  2658. package/src/utils/pressFeedback.test.ts +0 -874
  2659. package/src/utils/pressGesture.test.ts +0 -323
  2660. package/src/utils/pressPaintPriority.test.ts +0 -80
  2661. package/src/utils/pressPaintSource.test.ts +0 -65
  2662. package/src/utils/pressableCoverage.test.ts +0 -192
  2663. package/src/utils/primaryClick.test.ts +0 -38
  2664. package/src/utils/safeUrl.test.ts +0 -101
  2665. package/src/utils/sharedMutationObserver.test.ts +0 -53
  2666. package/src/utils/sharedResizeObserver.test.ts +0 -283
  2667. package/src/utils/themeProps.test.ts +0 -62
  2668. package/src/utils/timeFormat.test.ts +0 -204
  2669. package/src/utils/timeParser.test.ts +0 -295
  2670. package/src/utils/touchPresentation.test.ts +0 -462
  2671. package/src/utils/unicodeDigits.test.ts +0 -44
@@ -1,4819 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file MultiSelector.test.tsx
5
- * @input Uses vitest, @testing-library/react, @testing-library/user-event
6
- * @output Unit tests for MultiSelector
7
- * @position Tests; validates MultiSelector behavior
8
- *
9
- * SYNC: When MultiSelector.tsx API changes, update these tests.
10
- */
11
-
12
- import {
13
- describe,
14
- it,
15
- expect,
16
- vi,
17
- beforeAll,
18
- beforeEach,
19
- afterEach,
20
- } from 'vitest';
21
- import {
22
- act,
23
- render,
24
- screen,
25
- fireEvent,
26
- waitFor,
27
- within,
28
- } from '@testing-library/react';
29
- import userEvent from '@testing-library/user-event';
30
- import * as stylex from '@stylexjs/stylex';
31
- import {
32
- MultiSelector,
33
- type MultiSelectorHandle,
34
- type MultiSelectorChange,
35
- } from './MultiSelector';
36
- import {useRef, useState} from 'react';
37
- import {Icon} from '../Icon';
38
- import {InternationalizationProvider} from '../i18n';
39
- import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
40
- import {__resetInteractionModalityForTest} from '../utils/interactionModality';
41
- import {defineTheme} from '../theme/defineTheme';
42
- import {generateThemeCSS} from '../theme/generateThemeRules';
43
- import {selectorPresentationStyles} from '../Selector/selectorPresentation.stylex';
44
- import {groupStyles} from '../InputGroup/groupStyles';
45
- import {InputGroup, InputGroupText} from '../InputGroup';
46
- import {colorVars, focusVars} from '../theme/tokens.stylex';
47
- import {COMPACT_TOUCH_PRESENTATION_QUERY} from '../hooks/useAdaptivePresentation';
48
-
49
- /**
50
- * Enters a search query as one change. Typing it key by key can land several
51
- * keystrokes in one frame, whose result announcements are then joined into
52
- * one (spec:AST-086 FR9), so a test of what one query announces pastes it.
53
- */
54
- async function enterQuery(
55
- user: ReturnType<typeof userEvent.setup>,
56
- input: HTMLElement,
57
- query: string,
58
- ): Promise<void> {
59
- await user.click(input);
60
- await user.paste(query);
61
- }
62
-
63
- function generateThemeTestCSS(theme: Parameters<typeof generateThemeCSS>[0]) {
64
- const {prose, component} = generateThemeCSS(theme);
65
- return [prose, component].filter(Boolean).join('\n\n');
66
- }
67
- // Module-level constants to satisfy @eslint-react/no-unstable-default-props.
68
- const ANNOUNCE_OPTIONS = ['Apple', 'Banana', 'Orange'] as const;
69
- const EMPTY_VALUE: string[] = [];
70
-
71
- function politeRegion(): HTMLElement | null {
72
- return document.querySelector('[data-astryx-live-region="polite"]');
73
- }
74
-
75
- // Mock showPopover and hidePopover methods since they're not implemented in jsdom
76
- // The bottom-sheet presentation renders BottomSheet through React.lazy. Its
77
- // first import transforms the BottomSheet module tree, which on a loaded
78
- // runner takes longer than a query's 1 s wait, so the first sheet test timed
79
- // out before the dialog existed. Load the module once up front: lazy() then
80
- // resolves from the module cache and every sheet test waits only on the open.
81
- beforeAll(async () => {
82
- await import('../BottomSheet/BottomSheet');
83
- });
84
-
85
- beforeEach(() => {
86
- __resetInteractionModalityForTest();
87
- HTMLDialogElement.prototype.showModal = vi.fn(function (
88
- this: HTMLDialogElement,
89
- ) {
90
- this.setAttribute('open', '');
91
- });
92
- HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
93
- this.removeAttribute('open');
94
- });
95
- vi.stubGlobal(
96
- 'matchMedia',
97
- vi.fn().mockImplementation((query: string) => ({
98
- matches: false,
99
- media: query,
100
- onchange: null,
101
- addEventListener: vi.fn(),
102
- removeEventListener: vi.fn(),
103
- addListener: vi.fn(),
104
- removeListener: vi.fn(),
105
- dispatchEvent: vi.fn(),
106
- })),
107
- );
108
- HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
109
- this.setAttribute('popover-open', '');
110
- const event = new Event('toggle', {bubbles: false});
111
- Object.defineProperty(event, 'newState', {value: 'open'});
112
- this.dispatchEvent(event);
113
- });
114
- HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
115
- this.removeAttribute('popover-open');
116
- const event = new Event('toggle', {bubbles: false});
117
- Object.defineProperty(event, 'newState', {value: 'closed'});
118
- this.dispatchEvent(event);
119
- });
120
- const originalMatches = HTMLElement.prototype.matches;
121
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
- (HTMLElement.prototype as any).matches = function (
123
- selector: string,
124
- ): boolean {
125
- if (selector === ':popover-open') {
126
- return this.hasAttribute('popover-open');
127
- }
128
- return originalMatches.call(this, selector);
129
- };
130
- });
131
-
132
- afterEach(() => {
133
- __resetLiveRegionsForTest();
134
- });
135
-
136
- // Helper: jsdom popover content is in the DOM but may not be
137
- // "visible" in the accessibility tree. Use hidden: true to find it.
138
- const h = {hidden: true} as const;
139
-
140
- /** A busy control's Spinner is decorative and silent (spec:AST-086 FR8). */
141
- function expectSilentBusySpinner() {
142
- const spinner = document.querySelector('.astryx-spinner');
143
- expect(spinner).not.toBeNull();
144
- expect(spinner).toHaveAttribute('aria-hidden', 'true');
145
- expect(screen.queryByRole('status', {name: 'Loading'})).toBeNull();
146
- }
147
-
148
- // The bottom sheet is loaded on demand (SelectorBottomSheet's lazy import).
149
- // Loading its module is not part of an open, so the file waits for it once
150
- // here, and each test's open waits only for the open.
151
- beforeAll(async () => {
152
- await import('../BottomSheet/BottomSheet');
153
- });
154
-
155
- describe('MultiSelector', () => {
156
- const defaultOptions = ['Apple', 'Banana', 'Orange'];
157
-
158
- it('uses a bottom sheet and stays open while toggling options', async () => {
159
- const user = userEvent.setup();
160
- const onChange = vi.fn();
161
- render(
162
- <MultiSelector
163
- label="Fruit"
164
- options={defaultOptions}
165
- value={[]}
166
- onChange={onChange}
167
- presentation="bottom-sheet"
168
- />,
169
- );
170
-
171
- const trigger = screen.getByRole('combobox');
172
- await user.click(trigger);
173
-
174
- expect(
175
- await screen.findByRole('dialog', {name: 'Fruit'}),
176
- ).toBeInTheDocument();
177
- expect(HTMLElement.prototype.showPopover).not.toHaveBeenCalled();
178
-
179
- await user.click(screen.getByRole('option', {name: 'Banana'}));
180
- expect(onChange).toHaveBeenCalledWith(['Banana']);
181
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
182
- });
183
-
184
- it('uses a bottom sheet for adaptive presentation on compact touch', async () => {
185
- vi.stubGlobal(
186
- 'matchMedia',
187
- vi.fn().mockImplementation((query: string) => ({
188
- matches: query === COMPACT_TOUCH_PRESENTATION_QUERY,
189
- media: query,
190
- onchange: null,
191
- addEventListener: vi.fn(),
192
- removeEventListener: vi.fn(),
193
- addListener: vi.fn(),
194
- removeListener: vi.fn(),
195
- dispatchEvent: vi.fn(),
196
- })),
197
- );
198
- const user = userEvent.setup();
199
- render(
200
- <MultiSelector
201
- label="Fruit"
202
- options={defaultOptions}
203
- value={[]}
204
- onChange={() => {}}
205
- presentation="adaptive"
206
- />,
207
- );
208
-
209
- await user.click(screen.getByRole('combobox'));
210
- expect(
211
- await screen.findByRole('dialog', {name: 'Fruit'}),
212
- ).toBeInTheDocument();
213
- expect(HTMLElement.prototype.showPopover).not.toHaveBeenCalled();
214
- });
215
-
216
- it('moves keyboard focus into a bottom-sheet listbox', async () => {
217
- const user = userEvent.setup();
218
- render(
219
- <MultiSelector
220
- label="Fruit"
221
- options={defaultOptions}
222
- value={[]}
223
- onChange={() => {}}
224
- presentation="bottom-sheet"
225
- />,
226
- );
227
-
228
- const trigger = screen.getByRole('combobox');
229
- trigger.focus();
230
- await user.keyboard('{Enter}');
231
-
232
- await waitFor(() => expect(screen.getByRole('listbox')).toHaveFocus());
233
- });
234
-
235
- it('restores touch focus without painting a trigger focus ring', async () => {
236
- render(
237
- <MultiSelector
238
- label="Fruit"
239
- options={defaultOptions}
240
- value={[]}
241
- onChange={() => {}}
242
- presentation="bottom-sheet"
243
- />,
244
- );
245
-
246
- const trigger = screen.getByRole('combobox');
247
- fireEvent.pointerDown(trigger, {pointerType: 'touch'});
248
- fireEvent.click(trigger, {detail: 1});
249
- const dialog = await screen.findByRole('dialog', {name: 'Fruit'});
250
- fireEvent.pointerDown(dialog, {pointerType: 'touch'});
251
- fireEvent.click(dialog, {detail: 1});
252
-
253
- trigger.focus();
254
- expect(trigger).toHaveFocus();
255
- expect(trigger.parentElement).toHaveClass(
256
- stylex.props(selectorPresentationStyles.pointerRestoredFocus).className!,
257
- );
258
- });
259
-
260
- it('shows no disabled focus ring after a pointer pick (spec:AST-085 FR6)', async () => {
261
- const field = (isDisabled: boolean) => (
262
- <MultiSelector
263
- label="Fruit"
264
- options={defaultOptions}
265
- value={[]}
266
- onChange={() => {}}
267
- presentation="bottom-sheet"
268
- isDisabled={isDisabled}
269
- />
270
- );
271
- const {rerender} = render(field(false));
272
- const trigger = screen.getByRole('combobox');
273
- fireEvent.pointerDown(trigger, {pointerType: 'touch'});
274
- fireEvent.click(trigger, {detail: 1});
275
- const dialog = await screen.findByRole('dialog', {name: 'Fruit'});
276
- fireEvent.pointerDown(dialog, {pointerType: 'touch'});
277
- fireEvent.click(dialog, {detail: 1});
278
- rerender(field(true));
279
- const ring = stylex
280
- .props(
281
- stylex.create({
282
- ring: {
283
- boxShadow: {
284
- default: null,
285
- ':has(> [aria-disabled="true"]:focus-visible)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
286
- },
287
- },
288
- }).ring,
289
- )
290
- .className!.split(' ')
291
- .pop()!;
292
- const wrapper = screen.getByRole('combobox').parentElement!;
293
- expect(wrapper).toHaveClass(
294
- stylex.props(selectorPresentationStyles.pointerRestoredFocus).className!,
295
- );
296
- expect(wrapper).not.toHaveClass(ring);
297
- });
298
-
299
- it('renders with label', () => {
300
- render(
301
- <MultiSelector
302
- label="Fruit"
303
- options={defaultOptions}
304
- value={[]}
305
- onChange={() => {}}
306
- />,
307
- );
308
- expect(screen.getByLabelText('Fruit')).toBeInTheDocument();
309
- });
310
-
311
- it('applies distinct trigger chrome to the secondary variant', () => {
312
- // data-testid reaches the native control; the variant is on the trigger root.
313
- const triggerRoot = () =>
314
- screen
315
- .getByTestId('selector')
316
- .closest('.astryx-multi-selector') as HTMLElement;
317
- const {rerender} = render(
318
- <MultiSelector
319
- label="Fruit"
320
- options={defaultOptions}
321
- value={[]}
322
- onChange={() => {}}
323
- variant="input"
324
- data-testid="selector"
325
- />,
326
- );
327
- const inputClasses = triggerRoot().className;
328
-
329
- rerender(
330
- <MultiSelector
331
- label="Fruit"
332
- options={defaultOptions}
333
- value={[]}
334
- onChange={() => {}}
335
- variant="secondary"
336
- data-testid="selector"
337
- />,
338
- );
339
- const secondary = triggerRoot();
340
- const secondaryClasses = secondary.className;
341
- expect(secondary).toHaveAttribute('data-variant', 'secondary');
342
-
343
- rerender(
344
- <MultiSelector
345
- label="Fruit"
346
- options={defaultOptions}
347
- value={[]}
348
- onChange={() => {}}
349
- variant="ghost"
350
- data-testid="selector"
351
- />,
352
- );
353
- const ghostClasses = triggerRoot().className;
354
-
355
- expect(secondaryClasses).not.toBe(inputClasses);
356
- expect(secondaryClasses).not.toBe(ghostClasses);
357
- });
358
-
359
- it('renders custom option content with renderOption', async () => {
360
- const user = userEvent.setup();
361
- render(
362
- <MultiSelector
363
- label="Fruit"
364
- options={[{value: 'apple', label: 'Apple'}]}
365
- value={[]}
366
- onChange={() => {}}
367
- renderOption={option => (
368
- <span data-testid="custom-option">{option.label}</span>
369
- )}
370
- />,
371
- );
372
-
373
- await user.click(screen.getByRole('combobox'));
374
- expect(screen.getByTestId('custom-option')).toHaveTextContent('Apple');
375
- });
376
- it('renders placeholder when no value selected', () => {
377
- render(
378
- <MultiSelector
379
- label="Fruit"
380
- options={defaultOptions}
381
- value={[]}
382
- onChange={() => {}}
383
- placeholder="Pick fruits..."
384
- />,
385
- );
386
- expect(screen.getByText('Pick fruits...')).toBeInTheDocument();
387
- });
388
-
389
- it('shows count display by default', () => {
390
- render(
391
- <MultiSelector
392
- label="Fruit"
393
- options={defaultOptions}
394
- value={['Apple', 'Banana']}
395
- onChange={() => {}}
396
- />,
397
- );
398
- expect(screen.getByText('2 selected')).toBeInTheDocument();
399
- });
400
-
401
- it('formats the count display with formatValue', () => {
402
- render(
403
- <MultiSelector
404
- label="Spaces"
405
- options={defaultOptions}
406
- value={['Apple', 'Banana']}
407
- onChange={() => {}}
408
- formatValue={items => `${items.length} spaces selected`}
409
- />,
410
- );
411
- expect(screen.getByText('2 spaces selected')).toBeInTheDocument();
412
- });
413
-
414
- it('passes selected values and resolved labels to formatValue', () => {
415
- const formatValue = vi.fn(
416
- (items: {value: string; label: string}[]) =>
417
- `${items[0].label} and ${items.length - 1} more`,
418
- );
419
- render(
420
- <MultiSelector
421
- label="Fruit"
422
- options={[
423
- {value: 'a', label: 'Apple'},
424
- {value: 'b', label: 'Banana'},
425
- ]}
426
- value={['a', 'b']}
427
- onChange={() => {}}
428
- formatValue={formatValue}
429
- />,
430
- );
431
- expect(formatValue).toHaveBeenCalledWith([
432
- {value: 'a', label: 'Apple'},
433
- {value: 'b', label: 'Banana'},
434
- ]);
435
- expect(screen.getByText('Apple and 1 more')).toBeInTheDocument();
436
- });
437
-
438
- it('formats the labels display with formatValue', () => {
439
- render(
440
- <MultiSelector
441
- label="Fruit"
442
- options={defaultOptions}
443
- value={['Apple', 'Banana', 'Orange']}
444
- onChange={() => {}}
445
- triggerDisplay="labels"
446
- formatValue={items => items.map(item => item.label).join(' & ')}
447
- />,
448
- );
449
- expect(screen.getByText('Apple & Banana & Orange')).toBeInTheDocument();
450
- });
451
-
452
- it('ignores formatValue in badges display', () => {
453
- render(
454
- <MultiSelector
455
- label="Fruit"
456
- options={defaultOptions}
457
- value={['Apple', 'Banana']}
458
- onChange={() => {}}
459
- triggerDisplay="badges"
460
- formatValue={() => 'formatted'}
461
- />,
462
- );
463
- expect(screen.queryByText('formatted')).not.toBeInTheDocument();
464
- const trigger = within(screen.getByRole('combobox'));
465
- expect(trigger.getByText('Apple')).toBeInTheDocument();
466
- expect(trigger.getByText('Banana')).toBeInTheDocument();
467
- });
468
-
469
- it('shows the placeholder rather than calling formatValue when empty', () => {
470
- const formatValue = vi.fn(() => 'formatted');
471
- render(
472
- <MultiSelector
473
- label="Fruit"
474
- options={defaultOptions}
475
- value={[]}
476
- onChange={() => {}}
477
- placeholder="Pick fruits..."
478
- formatValue={formatValue}
479
- />,
480
- );
481
- expect(screen.getByText('Pick fruits...')).toBeInTheDocument();
482
- expect(formatValue).not.toHaveBeenCalled();
483
- });
484
-
485
- it('shows labels display', () => {
486
- render(
487
- <MultiSelector
488
- label="Fruit"
489
- options={defaultOptions}
490
- value={['Apple', 'Banana']}
491
- onChange={() => {}}
492
- triggerDisplay="labels"
493
- />,
494
- );
495
- expect(screen.getByText('Apple, Banana')).toBeInTheDocument();
496
- });
497
-
498
- it('shows labels display with overflow', () => {
499
- render(
500
- <MultiSelector
501
- label="Fruit"
502
- options={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}
503
- value={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}
504
- onChange={() => {}}
505
- triggerDisplay="labels"
506
- />,
507
- );
508
- expect(screen.getByText('Apple, Banana, Orange, +2')).toBeInTheDocument();
509
- });
510
-
511
- it('opens dropdown on click', async () => {
512
- const user = userEvent.setup();
513
- render(
514
- <MultiSelector
515
- label="Fruit"
516
- options={defaultOptions}
517
- value={[]}
518
- onChange={() => {}}
519
- />,
520
- );
521
- const trigger = screen.getByRole('combobox');
522
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
523
-
524
- await user.click(trigger);
525
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
526
- });
527
-
528
- it('toggles item on click without closing dropdown', async () => {
529
- const user = userEvent.setup();
530
- const onChange = vi.fn();
531
- render(
532
- <MultiSelector
533
- label="Fruit"
534
- options={defaultOptions}
535
- value={[]}
536
- onChange={onChange}
537
- />,
538
- );
539
-
540
- await user.click(screen.getByRole('combobox'));
541
-
542
- const options = screen.getAllByRole('option', h);
543
- await user.click(options[0]);
544
-
545
- expect(onChange).toHaveBeenCalledWith(['Apple']);
546
- // Dropdown should still be open
547
- expect(screen.getByRole('combobox')).toHaveAttribute(
548
- 'aria-expanded',
549
- 'true',
550
- );
551
- });
552
-
553
- it('deselects item when clicking selected item', async () => {
554
- const user = userEvent.setup();
555
- const onChange = vi.fn();
556
- render(
557
- <MultiSelector
558
- label="Fruit"
559
- options={defaultOptions}
560
- value={['Apple', 'Banana']}
561
- onChange={onChange}
562
- />,
563
- );
564
-
565
- await user.click(screen.getByRole('combobox'));
566
- const options = screen.getAllByRole('option', h);
567
- await user.click(options[0]); // Click Apple to deselect
568
-
569
- expect(onChange).toHaveBeenCalledWith(['Banana']);
570
- });
571
-
572
- it('does not toggle disabled items', async () => {
573
- const user = userEvent.setup();
574
- const onChange = vi.fn();
575
- render(
576
- <MultiSelector
577
- label="Fruit"
578
- options={[
579
- {value: 'apple', label: 'Apple', disabled: true},
580
- {value: 'banana', label: 'Banana'},
581
- ]}
582
- value={[]}
583
- onChange={onChange}
584
- />,
585
- );
586
-
587
- await user.click(screen.getByRole('combobox'));
588
- const options = screen.getAllByRole('option', h);
589
- await user.click(options[0]); // Click disabled Apple
590
-
591
- expect(onChange).not.toHaveBeenCalled();
592
- });
593
-
594
- it('renders disabled state', () => {
595
- render(
596
- <MultiSelector
597
- label="Fruit"
598
- options={defaultOptions}
599
- value={[]}
600
- onChange={() => {}}
601
- isDisabled
602
- />,
603
- );
604
- const trigger = screen.getByRole('combobox');
605
- expect(trigger).not.toHaveAttribute('disabled');
606
- expect(trigger).toHaveAttribute('aria-disabled', 'true');
607
- });
608
-
609
- it('has correct ARIA attributes', () => {
610
- render(
611
- <MultiSelector
612
- label="Fruit"
613
- options={defaultOptions}
614
- value={[]}
615
- onChange={() => {}}
616
- isRequired
617
- />,
618
- );
619
- const trigger = screen.getByRole('combobox');
620
- expect(trigger).toHaveAttribute('aria-haspopup', 'listbox');
621
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
622
- expect(trigger).toHaveAttribute('aria-required', 'true');
623
- });
624
-
625
- it('shows error status with aria-invalid', () => {
626
- render(
627
- <MultiSelector
628
- label="Fruit"
629
- options={defaultOptions}
630
- value={[]}
631
- onChange={() => {}}
632
- status={{type: 'error', message: 'Required'}}
633
- />,
634
- );
635
- const trigger = screen.getByRole('combobox');
636
- expect(trigger).toHaveAttribute('aria-invalid', 'true');
637
- expect(screen.getByText('Required')).toBeInTheDocument();
638
- });
639
-
640
- it('closes on Escape', async () => {
641
- const user = userEvent.setup();
642
- render(
643
- <MultiSelector
644
- label="Fruit"
645
- options={defaultOptions}
646
- value={[]}
647
- onChange={() => {}}
648
- />,
649
- );
650
-
651
- const trigger = screen.getByRole('combobox');
652
- await user.click(trigger);
653
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
654
-
655
- await user.keyboard('{Escape}');
656
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
657
- });
658
-
659
- it('closes combobox on Tab and moves focus to next element', async () => {
660
- const user = userEvent.setup();
661
- render(
662
- <>
663
- <MultiSelector
664
- label="Fruit"
665
- options={defaultOptions}
666
- value={[]}
667
- onChange={() => {}}
668
- />
669
- <button type="button">Next</button>
670
- </>,
671
- );
672
-
673
- const trigger = screen.getByRole('combobox');
674
- await user.click(trigger);
675
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
676
-
677
- await user.keyboard('{Tab}');
678
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
679
- expect(screen.getByRole('button', {name: 'Next'})).toHaveFocus();
680
- });
681
-
682
- it('supports keyboard navigation with ArrowDown/ArrowUp', async () => {
683
- const user = userEvent.setup();
684
- render(
685
- <MultiSelector
686
- label="Fruit"
687
- options={defaultOptions}
688
- value={[]}
689
- onChange={() => {}}
690
- />,
691
- );
692
-
693
- const trigger = screen.getByRole('combobox');
694
- await user.click(trigger);
695
-
696
- await user.keyboard('{ArrowDown}');
697
- const activeId = trigger.getAttribute('aria-activedescendant');
698
- expect(activeId).toBeTruthy();
699
- });
700
-
701
- it('End/Home jump the highlight to the last/first option (non-search)', async () => {
702
- const user = userEvent.setup();
703
- render(
704
- <MultiSelector
705
- label="Fruit"
706
- options={defaultOptions}
707
- value={[]}
708
- onChange={() => {}}
709
- />,
710
- );
711
-
712
- const trigger = screen.getByRole('combobox');
713
- await user.click(trigger);
714
- const options = screen.getAllByRole('option', h);
715
-
716
- await user.keyboard('{End}');
717
- expect(trigger).toHaveAttribute(
718
- 'aria-activedescendant',
719
- options[options.length - 1].id,
720
- );
721
- await user.keyboard('{Home}');
722
- expect(trigger).toHaveAttribute('aria-activedescendant', options[0].id);
723
- });
724
-
725
- it('toggles item with Enter key', async () => {
726
- const user = userEvent.setup();
727
- const onChange = vi.fn();
728
- render(
729
- <MultiSelector
730
- label="Fruit"
731
- options={defaultOptions}
732
- value={[]}
733
- onChange={onChange}
734
- />,
735
- );
736
-
737
- const trigger = screen.getByRole('combobox');
738
- await user.click(trigger);
739
- await user.keyboard('{Enter}');
740
- expect(onChange).toHaveBeenCalledWith(['Apple']);
741
- });
742
-
743
- it('does not toggle the highlighted option on a composing Enter (IME)', async () => {
744
- const user = userEvent.setup();
745
- const onChange = vi.fn();
746
- render(
747
- <MultiSelector
748
- label="Fruit"
749
- options={defaultOptions}
750
- value={[]}
751
- onChange={onChange}
752
- hasSearch
753
- />,
754
- );
755
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
756
- const search = screen.getByRole('combobox', h);
757
- // Filter to Banana and highlight it so an unguarded Enter would toggle it.
758
- await user.type(search, 'ban');
759
- await user.keyboard('{ArrowDown}');
760
- expect(search).toHaveAttribute('aria-activedescendant');
761
-
762
- // The composing keydown (isComposing / legacy keyCode 229) that commits an
763
- // IME candidate must not be read as "toggle the highlighted option".
764
- fireEvent.keyDown(search, {key: 'Enter', isComposing: true});
765
- expect(onChange).not.toHaveBeenCalled();
766
- fireEvent.keyDown(search, {key: 'Enter', keyCode: 229});
767
- expect(onChange).not.toHaveBeenCalled();
768
-
769
- // A real, non-composing Enter still toggles the highlighted option.
770
- fireEvent.keyDown(search, {key: 'Enter'});
771
- expect(onChange).toHaveBeenCalledWith(['Banana']);
772
- });
773
-
774
- it('toggles the correct item when selected items are sorted to top', async () => {
775
- const user = userEvent.setup();
776
- const onChange = vi.fn();
777
- // Orange is selected, so sorted order is: Orange, Apple, Banana
778
- render(
779
- <MultiSelector
780
- label="Fruit"
781
- options={defaultOptions}
782
- value={['Orange']}
783
- onChange={onChange}
784
- />,
785
- );
786
-
787
- const trigger = screen.getByRole('combobox');
788
- await user.click(trigger);
789
- // highlightedIndex starts at 0 which is Orange (sorted first)
790
- await user.keyboard('{ArrowDown}');
791
- // Now at index 1 which should be Apple
792
- await user.keyboard('{Enter}');
793
- expect(onChange).toHaveBeenCalledWith(['Orange', 'Apple']);
794
- });
795
-
796
- it('renders select-all checkbox when hasSelectAll', async () => {
797
- const user = userEvent.setup();
798
- render(
799
- <MultiSelector
800
- label="Fruit"
801
- options={defaultOptions}
802
- value={[]}
803
- onChange={() => {}}
804
- hasSelectAll
805
- />,
806
- );
807
-
808
- await user.click(screen.getByRole('combobox'));
809
- expect(screen.getByText('Select all')).toBeInTheDocument();
810
- });
811
-
812
- it('select-all selects all enabled items', async () => {
813
- const user = userEvent.setup();
814
- const onChange = vi.fn();
815
- render(
816
- <MultiSelector
817
- label="Fruit"
818
- options={[
819
- {value: 'apple', label: 'Apple'},
820
- {value: 'banana', label: 'Banana', disabled: true},
821
- {value: 'orange', label: 'Orange'},
822
- ]}
823
- value={[]}
824
- onChange={onChange}
825
- hasSelectAll
826
- />,
827
- );
828
-
829
- await user.click(screen.getByRole('combobox'));
830
- const selectAll = screen.getByText('Select all');
831
- await user.click(selectAll);
832
-
833
- expect(onChange).toHaveBeenCalledWith(['apple', 'orange']);
834
- });
835
-
836
- it('select-all deselects all when all are selected', async () => {
837
- const user = userEvent.setup();
838
- const onChange = vi.fn();
839
- render(
840
- <MultiSelector
841
- label="Fruit"
842
- options={defaultOptions}
843
- value={['Apple', 'Banana', 'Orange']}
844
- onChange={onChange}
845
- hasSelectAll
846
- />,
847
- );
848
-
849
- await user.click(screen.getByRole('combobox'));
850
- const selectAll = screen.getByText('Select all');
851
- await user.click(selectAll);
852
-
853
- expect(onChange).toHaveBeenCalledWith([]);
854
- });
855
-
856
- it('select-all is a role="option" in the listbox', async () => {
857
- const user = userEvent.setup();
858
- render(
859
- <MultiSelector
860
- label="Fruit"
861
- options={defaultOptions}
862
- value={[]}
863
- onChange={() => {}}
864
- hasSelectAll
865
- />,
866
- );
867
-
868
- await user.click(screen.getByRole('combobox'));
869
- const options = screen.getAllByRole('option', h);
870
- expect(options[0]).toHaveTextContent('Select all');
871
- });
872
-
873
- it('select-all accessible name reflects none/partial/all selection', async () => {
874
- const user = userEvent.setup();
875
- const options = [
876
- {value: 'apple', label: 'Apple'},
877
- {value: 'banana', label: 'Banana'},
878
- ];
879
- const {rerender} = render(
880
- <MultiSelector
881
- label="Fruit"
882
- options={options}
883
- value={[]}
884
- onChange={() => {}}
885
- hasSelectAll
886
- />,
887
- );
888
-
889
- await user.click(screen.getByRole('combobox'));
890
-
891
- // None selected: plain name, not selected
892
- let selectAll = screen.getAllByRole('option', h)[0];
893
- expect(selectAll).not.toHaveAccessibleName(/partially selected/);
894
- expect(selectAll).toHaveAttribute('aria-selected', 'false');
895
-
896
- // Partial: aria-selected="mixed" is invalid on role="option", so the
897
- // indeterminate state must be conveyed through the accessible name.
898
- rerender(
899
- <MultiSelector
900
- label="Fruit"
901
- options={options}
902
- value={['apple']}
903
- onChange={() => {}}
904
- hasSelectAll
905
- />,
906
- );
907
- selectAll = screen.getAllByRole('option', h)[0];
908
- expect(selectAll).toHaveAccessibleName('Select all, partially selected');
909
- expect(selectAll).toHaveAttribute('aria-selected', 'false');
910
-
911
- // All selected: plain name again, selected
912
- rerender(
913
- <MultiSelector
914
- label="Fruit"
915
- options={options}
916
- value={['apple', 'banana']}
917
- onChange={() => {}}
918
- hasSelectAll
919
- />,
920
- );
921
- selectAll = screen.getAllByRole('option', h)[0];
922
- expect(selectAll).not.toHaveAccessibleName(/partially selected/);
923
- expect(selectAll).toHaveAttribute('aria-selected', 'true');
924
- });
925
-
926
- it('select-all toggles via keyboard Enter', async () => {
927
- const user = userEvent.setup();
928
- const onChange = vi.fn();
929
- render(
930
- <MultiSelector
931
- label="Fruit"
932
- options={defaultOptions}
933
- value={[]}
934
- onChange={onChange}
935
- hasSelectAll
936
- />,
937
- );
938
-
939
- const trigger = screen.getByRole('combobox');
940
- await user.click(trigger);
941
- // highlightedIndex starts at 0 which is select-all
942
- await user.keyboard('{Enter}');
943
- expect(onChange).toHaveBeenCalledWith(['Apple', 'Banana', 'Orange']);
944
- });
945
-
946
- it('renders search input when hasSearch', async () => {
947
- const user = userEvent.setup();
948
- render(
949
- <MultiSelector
950
- label="Fruit"
951
- options={defaultOptions}
952
- value={[]}
953
- onChange={() => {}}
954
- hasSearch
955
- />,
956
- );
957
-
958
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
959
- const searchInput = screen.getByRole('combobox', h);
960
- expect(searchInput).toBeInTheDocument();
961
- expect(searchInput).toHaveAttribute('aria-autocomplete', 'list');
962
- });
963
-
964
- it('filters options when searching', async () => {
965
- const user = userEvent.setup();
966
- render(
967
- <MultiSelector
968
- label="Fruit"
969
- options={defaultOptions}
970
- value={[]}
971
- onChange={() => {}}
972
- hasSearch
973
- />,
974
- );
975
-
976
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
977
- const searchInput = screen.getByRole('combobox', h);
978
- await user.type(searchInput, 'app');
979
-
980
- const options = screen.getAllByRole('option', h);
981
- expect(options).toHaveLength(1);
982
- });
983
-
984
- describe('grouped search', () => {
985
- const GROUPED = [
986
- {
987
- type: 'section' as const,
988
- title: 'Citrus',
989
- options: [
990
- {value: 'orange', label: 'Orange'},
991
- {value: 'lemon', label: 'Lemon'},
992
- ],
993
- },
994
- {
995
- type: 'section' as const,
996
- title: 'Berries',
997
- options: [
998
- {value: 'strawberry', label: 'Strawberry'},
999
- {value: 'blueberry', label: 'Blueberry'},
1000
- ],
1001
- },
1002
- ];
1003
-
1004
- it('keeps the group header above matching items while searching', async () => {
1005
- const user = userEvent.setup();
1006
- render(
1007
- <MultiSelector
1008
- label="Fruit"
1009
- options={GROUPED}
1010
- value={[]}
1011
- onChange={() => {}}
1012
- hasSearch
1013
- />,
1014
- );
1015
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1016
- await user.type(screen.getByRole('combobox', h), 'orange');
1017
-
1018
- expect(
1019
- screen.getByRole('group', {name: 'Citrus', ...h}),
1020
- ).toBeInTheDocument();
1021
- const options = screen.getAllByRole('option', h);
1022
- expect(options).toHaveLength(1);
1023
- expect(options[0]).toHaveTextContent('Orange');
1024
- });
1025
-
1026
- it('hides a group whose items have no match', async () => {
1027
- const user = userEvent.setup();
1028
- render(
1029
- <MultiSelector
1030
- label="Fruit"
1031
- options={GROUPED}
1032
- value={[]}
1033
- onChange={() => {}}
1034
- hasSearch
1035
- />,
1036
- );
1037
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1038
- await user.type(screen.getByRole('combobox', h), 'berry');
1039
-
1040
- expect(
1041
- screen.getByRole('group', {name: 'Berries', ...h}),
1042
- ).toBeInTheDocument();
1043
- expect(
1044
- screen.queryByRole('group', {name: 'Citrus', ...h}),
1045
- ).not.toBeInTheDocument();
1046
- expect(screen.getAllByRole('option', h)).toHaveLength(2);
1047
- });
1048
- });
1049
-
1050
- it('PageDown/PageUp jump the highlight to the last/first filtered option', async () => {
1051
- const user = userEvent.setup();
1052
- render(
1053
- <MultiSelector
1054
- label="Fruit"
1055
- options={defaultOptions}
1056
- value={[]}
1057
- onChange={() => {}}
1058
- hasSearch
1059
- />,
1060
- );
1061
-
1062
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1063
- const searchInput = screen.getByRole('combobox', h);
1064
- // Filter to Banana and Orange so "last" means last *visible* option.
1065
- await user.type(searchInput, 'an');
1066
- const options = screen.getAllByRole('option', h);
1067
- expect(options).toHaveLength(2);
1068
-
1069
- await user.keyboard('{PageDown}');
1070
- expect(searchInput).toHaveAttribute(
1071
- 'aria-activedescendant',
1072
- options[options.length - 1].id,
1073
- );
1074
- await user.keyboard('{PageUp}');
1075
- expect(searchInput).toHaveAttribute('aria-activedescendant', options[0].id);
1076
- });
1077
-
1078
- it('Home/End move the search caret, not the option highlight', async () => {
1079
- const user = userEvent.setup();
1080
- render(
1081
- <MultiSelector
1082
- label="Fruit"
1083
- options={defaultOptions}
1084
- value={[]}
1085
- onChange={() => {}}
1086
- hasSearch
1087
- />,
1088
- );
1089
-
1090
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1091
- const searchInput = screen.getByRole<HTMLInputElement>('combobox', h);
1092
- await user.type(searchInput, 'an');
1093
- expect(searchInput.selectionStart).toBe(2);
1094
- const activeBefore = searchInput.getAttribute('aria-activedescendant');
1095
- // Home/End stay on the input for caret movement (APG editable combobox);
1096
- // the option highlight must not move.
1097
- await user.keyboard('{Home}');
1098
- expect(searchInput.selectionStart).toBe(0);
1099
- expect(searchInput.getAttribute('aria-activedescendant')).toBe(
1100
- activeBefore,
1101
- );
1102
- await user.keyboard('{End}');
1103
- expect(searchInput.selectionStart).toBe(2);
1104
- expect(searchInput.getAttribute('aria-activedescendant')).toBe(
1105
- activeBefore,
1106
- );
1107
- });
1108
-
1109
- it('shows empty state when search has no results', async () => {
1110
- const user = userEvent.setup();
1111
- render(
1112
- <MultiSelector
1113
- label="Fruit"
1114
- options={defaultOptions}
1115
- value={[]}
1116
- onChange={() => {}}
1117
- hasSearch
1118
- />,
1119
- );
1120
-
1121
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1122
- const searchInput = screen.getByRole('combobox', h);
1123
- await user.type(searchInput, 'xyz');
1124
-
1125
- expect(
1126
- within(screen.getByRole('listbox', h)).getByText('No results found'),
1127
- ).toBeInTheDocument();
1128
- });
1129
-
1130
- it('empty-state message is not exposed as a listbox child', async () => {
1131
- const user = userEvent.setup();
1132
- render(
1133
- <MultiSelector
1134
- label="Fruit"
1135
- options={defaultOptions}
1136
- value={[]}
1137
- onChange={() => {}}
1138
- hasSearch
1139
- />,
1140
- );
1141
-
1142
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1143
- await user.type(screen.getByRole('combobox', h), 'xyz');
1144
-
1145
- // role="listbox" only permits option/group children — the visual
1146
- // empty-state message must be presentational (it is announced through
1147
- // the result-count live region instead).
1148
- const listbox = screen.getByRole('listbox', h);
1149
- const empty = within(listbox).getByText('No results found');
1150
- expect(empty).toHaveAttribute('role', 'presentation');
1151
- });
1152
-
1153
- it('renders emptySearchText in place of the default message', async () => {
1154
- const user = userEvent.setup();
1155
- render(
1156
- <MultiSelector
1157
- label="Fruit"
1158
- options={defaultOptions}
1159
- value={[]}
1160
- onChange={() => {}}
1161
- hasSearch
1162
- emptySearchText="Nothing like that here"
1163
- />,
1164
- );
1165
-
1166
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1167
- await user.type(screen.getByRole('combobox', h), 'xyz');
1168
-
1169
- const listbox = screen.getByRole('listbox', h);
1170
- expect(
1171
- within(listbox).getByText('Nothing like that here'),
1172
- ).toBeInTheDocument();
1173
- expect(
1174
- within(listbox).queryByText('No results found'),
1175
- ).not.toBeInTheDocument();
1176
- });
1177
-
1178
- it('renders emptyText, not emptySearchText, with no options and no query', async () => {
1179
- const user = userEvent.setup();
1180
- render(
1181
- <MultiSelector
1182
- label="Fruit"
1183
- options={[]}
1184
- value={[]}
1185
- onChange={() => {}}
1186
- hasSearch
1187
- emptySearchText="Nothing like that here"
1188
- />,
1189
- );
1190
-
1191
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1192
-
1193
- const listbox = screen.getByRole('listbox', h);
1194
- expect(within(listbox).getByText('No options')).toBeInTheDocument();
1195
- expect(
1196
- within(listbox).queryByText('Nothing like that here'),
1197
- ).not.toBeInTheDocument();
1198
- });
1199
-
1200
- it('announces emptySearchText, not the catalog default', async () => {
1201
- const user = userEvent.setup();
1202
- render(
1203
- <MultiSelector
1204
- label="Fruit"
1205
- options={defaultOptions}
1206
- value={[]}
1207
- onChange={() => {}}
1208
- hasSearch
1209
- emptySearchText="Nothing like that here"
1210
- />,
1211
- );
1212
-
1213
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1214
- await enterQuery(user, screen.getByRole('combobox', h), 'xyz');
1215
-
1216
- // The panel message is role="presentation", so the live region is the
1217
- // only thing a screen reader gets — it has to say the same words.
1218
- await waitFor(() =>
1219
- expect(politeRegion()?.textContent).toBe('Nothing like that here'),
1220
- );
1221
- });
1222
-
1223
- // `emptySearchText` is typed ReactNode, which invites an element — a
1224
- // "no results, create one" row is exactly what a dead end is for. The
1225
- // announcement used to take the prop only when it was a string and
1226
- // announce the catalog default otherwise, so a screen-reader user was told
1227
- // something the sighted user was not reading (`spec:AST-056` AR1).
1228
- it('announces the text of an element emptySearchText', async () => {
1229
- const user = userEvent.setup();
1230
- render(
1231
- <MultiSelector
1232
- label="Fruit"
1233
- options={defaultOptions}
1234
- value={[]}
1235
- onChange={() => {}}
1236
- hasSearch
1237
- emptySearchText={
1238
- <span>
1239
- Nothing like that here. <a href="/new">Add a fruit</a>
1240
- </span>
1241
- }
1242
- />,
1243
- );
1244
-
1245
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1246
- await enterQuery(user, screen.getByRole('combobox', h), 'xyz');
1247
-
1248
- await waitFor(() =>
1249
- expect(politeRegion()?.textContent).toBe(
1250
- 'Nothing like that here. Add a fruit',
1251
- ),
1252
- );
1253
- });
1254
-
1255
- it('announces the text of an element emptyText', async () => {
1256
- const user = userEvent.setup();
1257
- render(
1258
- <MultiSelector
1259
- label="Fruit"
1260
- options={[]}
1261
- value={[]}
1262
- onChange={() => {}}
1263
- emptyText={
1264
- <span>
1265
- Add a fruit first<span aria-hidden="true"> →</span>
1266
- </span>
1267
- }
1268
- />,
1269
- );
1270
-
1271
- await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
1272
-
1273
- // The decorative arrow is hidden from the accessibility tree on screen,
1274
- // so it stays out of the announcement too.
1275
- await waitFor(() =>
1276
- expect(politeRegion()?.textContent).toBe('Add a fruit first'),
1277
- );
1278
- });
1279
-
1280
- it('announces text a child component renders, which is only in the DOM', async () => {
1281
- const user = userEvent.setup();
1282
- // The words exist nowhere in the node the caller passed — they are
1283
- // produced inside this component's own render. Reading the DOM after
1284
- // render is what makes them announceable.
1285
- function Message() {
1286
- return <span>Nothing like that here</span>;
1287
- }
1288
- render(
1289
- <MultiSelector
1290
- label="Fruit"
1291
- options={defaultOptions}
1292
- value={[]}
1293
- onChange={() => {}}
1294
- hasSearch
1295
- emptySearchText={<Message />}
1296
- />,
1297
- );
1298
-
1299
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1300
- await enterQuery(user, screen.getByRole('combobox', h), 'xyz');
1301
-
1302
- await waitFor(() =>
1303
- expect(politeRegion()?.textContent).toBe('Nothing like that here'),
1304
- );
1305
- });
1306
-
1307
- it('announces the empty state when opened with no options', async () => {
1308
- const user = userEvent.setup();
1309
- render(
1310
- <MultiSelector
1311
- label="Fruit"
1312
- options={[]}
1313
- value={[]}
1314
- onChange={() => {}}
1315
- emptyText="Add a fruit first"
1316
- />,
1317
- );
1318
-
1319
- await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
1320
-
1321
- await waitFor(() =>
1322
- expect(politeRegion()?.textContent).toBe('Add a fruit first'),
1323
- );
1324
- });
1325
-
1326
- it('shows and announces nothing while isLoading', async () => {
1327
- const user = userEvent.setup();
1328
- render(
1329
- <MultiSelector
1330
- label="Fruit"
1331
- options={[]}
1332
- value={[]}
1333
- onChange={() => {}}
1334
- isLoading
1335
- />,
1336
- );
1337
-
1338
- const trigger = screen.getByRole('combobox', {name: 'Fruit'});
1339
- await user.click(trigger);
1340
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
1341
-
1342
- // useAnnounce writes on the next animation frame, so an immediate read
1343
- // would pass whether or not anything was announced.
1344
- await act(
1345
- async () =>
1346
- void (await new Promise(resolve => requestAnimationFrame(resolve))),
1347
- );
1348
-
1349
- // The options have not arrived, so "No options" would be a claim the
1350
- // component cannot make; the trigger's spinner carries the state.
1351
- const listbox = screen.getByRole('listbox', h);
1352
- expect(within(listbox).queryByText('No options')).not.toBeInTheDocument();
1353
- // Only the busy start is spoken (spec:AST-086 FR8), never an empty or
1354
- // no-results message the panel is suppressing.
1355
- // (The channel clears its text on a timer, so it may already be empty.)
1356
- expect(['', 'Loading']).toContain(politeRegion()?.textContent ?? '');
1357
- });
1358
-
1359
- it('announces nothing while isLoading, matching the silent panel', async () => {
1360
- const user = userEvent.setup();
1361
- render(
1362
- <MultiSelector
1363
- label="Fruit"
1364
- options={defaultOptions}
1365
- value={[]}
1366
- onChange={() => {}}
1367
- hasSearch
1368
- isLoading
1369
- emptySearchText="Nothing like that here"
1370
- />,
1371
- );
1372
-
1373
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1374
- await user.type(screen.getByRole('combobox', h), 'xyz');
1375
-
1376
- // useAnnounce writes on the next animation frame, so an immediate read
1377
- // would pass whether or not anything was announced.
1378
- await act(
1379
- async () =>
1380
- void (await new Promise(resolve => requestAnimationFrame(resolve))),
1381
- );
1382
-
1383
- // The panel is deliberately blank while loading; the live region is the
1384
- // only channel left, so a result there would be a claim the screen
1385
- // refuses to make.
1386
- const listbox = screen.getByRole('listbox', h);
1387
- expect(
1388
- within(listbox).queryByText('Nothing like that here'),
1389
- ).not.toBeInTheDocument();
1390
- // Only the busy start is spoken (spec:AST-086 FR8), never an empty or
1391
- // no-results message the panel is suppressing.
1392
- // (The channel clears its text on a timer, so it may already be empty.)
1393
- expect(['', 'Loading']).toContain(politeRegion()?.textContent ?? '');
1394
- });
1395
-
1396
- it('renders emptyText when there are no options and no search input', async () => {
1397
- const user = userEvent.setup();
1398
- render(
1399
- <MultiSelector
1400
- label="Fruit"
1401
- options={[]}
1402
- value={[]}
1403
- onChange={() => {}}
1404
- emptyText="Add a fruit first"
1405
- />,
1406
- );
1407
-
1408
- // Without hasSearch the trigger itself is the combobox.
1409
- await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
1410
-
1411
- const listbox = screen.getByRole('listbox', h);
1412
- expect(within(listbox).getByText('Add a fruit first')).toBeInTheDocument();
1413
- });
1414
-
1415
- describe('count trigger text', () => {
1416
- it('shows the default count in the catalog message', () => {
1417
- render(
1418
- <MultiSelector
1419
- label="Fruit"
1420
- options={defaultOptions}
1421
- value={['Apple', 'Banana']}
1422
- onChange={() => {}}
1423
- triggerDisplay="count"
1424
- />,
1425
- );
1426
- expect(screen.getByText('2 selected')).toBeInTheDocument();
1427
- });
1428
-
1429
- it('translates the default count, with plural forms, under another locale', () => {
1430
- render(
1431
- <InternationalizationProvider
1432
- locale="fr"
1433
- overrides={{
1434
- fr: {
1435
- '@astryx.multiSelector.selectedCount':
1436
- '{count, number} {count, plural, one {sélectionné} other {sélectionnés}}',
1437
- },
1438
- }}>
1439
- <MultiSelector
1440
- label="Fruit"
1441
- options={defaultOptions}
1442
- value={['Apple', 'Banana']}
1443
- onChange={() => {}}
1444
- triggerDisplay="count"
1445
- />
1446
- </InternationalizationProvider>,
1447
- );
1448
- expect(screen.getByText('2 sélectionnés')).toBeInTheDocument();
1449
- expect(screen.queryByText('2 selected')).not.toBeInTheDocument();
1450
- });
1451
-
1452
- it('still lets formatValue replace the count text', () => {
1453
- render(
1454
- <MultiSelector
1455
- label="Fruit"
1456
- options={defaultOptions}
1457
- value={['Apple', 'Banana']}
1458
- onChange={() => {}}
1459
- triggerDisplay="count"
1460
- formatValue={items => `${items.length} fruits`}
1461
- />,
1462
- );
1463
- expect(screen.getByText('2 fruits')).toBeInTheDocument();
1464
- });
1465
- });
1466
-
1467
- describe('result announcements', () => {
1468
- it('announces the match count politely while searching', async () => {
1469
- const user = userEvent.setup();
1470
- render(
1471
- <InternationalizationProvider
1472
- locale="fr"
1473
- overrides={{
1474
- fr: {
1475
- '@astryx.multiSelector.resultCount':
1476
- '{count, number} {count, plural, one {résultat} other {résultats}}',
1477
- },
1478
- }}>
1479
- <MultiSelector
1480
- label="Fruit"
1481
- options={defaultOptions}
1482
- value={EMPTY_VALUE}
1483
- onChange={() => {}}
1484
- hasSearch
1485
- />
1486
- </InternationalizationProvider>,
1487
- );
1488
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1489
- // "an" matches Banana and Orange.
1490
- await enterQuery(user, screen.getByRole('combobox', h), 'an');
1491
- await waitFor(() => {
1492
- // The plural branch of a message no catalog supplies.
1493
- expect(politeRegion()?.textContent).toBe('2 résultats');
1494
- });
1495
- });
1496
-
1497
- it('announces the singular form when one option matches', async () => {
1498
- const user = userEvent.setup();
1499
- render(
1500
- <InternationalizationProvider
1501
- locale="fr"
1502
- overrides={{
1503
- fr: {
1504
- '@astryx.multiSelector.resultCount':
1505
- '{count, number} {count, plural, one {résultat} other {résultats}}',
1506
- },
1507
- }}>
1508
- <MultiSelector
1509
- label="Fruit"
1510
- options={defaultOptions}
1511
- value={EMPTY_VALUE}
1512
- onChange={() => {}}
1513
- hasSearch
1514
- />
1515
- </InternationalizationProvider>,
1516
- );
1517
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1518
- // "app" matches only Apple. Exact match, so "1 résultats" would fail.
1519
- await enterQuery(user, screen.getByRole('combobox', h), 'app');
1520
- await waitFor(() => {
1521
- expect(politeRegion()?.textContent).toBe('1 résultat');
1522
- });
1523
- });
1524
-
1525
- it('announces the empty-results message when nothing matches', async () => {
1526
- const user = userEvent.setup();
1527
- render(
1528
- <InternationalizationProvider
1529
- locale="fr"
1530
- overrides={{
1531
- fr: {'@astryx.multiSelector.emptySearchResults': 'Aucun résultat'},
1532
- }}>
1533
- <MultiSelector
1534
- label="Fruit"
1535
- options={defaultOptions}
1536
- value={EMPTY_VALUE}
1537
- onChange={() => {}}
1538
- hasSearch
1539
- />
1540
- </InternationalizationProvider>,
1541
- );
1542
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1543
- await enterQuery(user, screen.getByRole('combobox', h), 'xyz');
1544
- await waitFor(() => {
1545
- expect(politeRegion()?.textContent).toBe('Aucun résultat');
1546
- });
1547
- });
1548
-
1549
- it('speaks the result count from a provider catalog (plural)', async () => {
1550
- const user = userEvent.setup();
1551
- render(
1552
- <InternationalizationProvider
1553
- locale="fr"
1554
- messages={{
1555
- fr: {
1556
- '@astryx.multiSelector.resultCount': {
1557
- defaultMessage:
1558
- '{count, number} {count, plural, one {résultat} other {résultats}}',
1559
- },
1560
- },
1561
- }}>
1562
- <MultiSelector
1563
- label="Fruit"
1564
- options={defaultOptions}
1565
- value={EMPTY_VALUE}
1566
- onChange={() => {}}
1567
- hasSearch
1568
- />
1569
- </InternationalizationProvider>,
1570
- );
1571
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1572
- // "an" matches Banana and Orange.
1573
- await enterQuery(user, screen.getByRole('combobox', h), 'an');
1574
- await waitFor(() => {
1575
- // Same key through the catalog path rather than `overrides`.
1576
- expect(politeRegion()?.textContent).toBe('2 résultats');
1577
- });
1578
- });
1579
-
1580
- it('does not announce results until the user searches', async () => {
1581
- const user = userEvent.setup();
1582
- render(
1583
- <MultiSelector
1584
- label="Fruit"
1585
- options={defaultOptions}
1586
- value={EMPTY_VALUE}
1587
- onChange={() => {}}
1588
- hasSearch
1589
- />,
1590
- );
1591
- // Popover closed: nothing announced.
1592
- expect(politeRegion()?.textContent ?? '').toBe('');
1593
- // Open with an empty query: still nothing announced.
1594
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
1595
- expect(politeRegion()?.textContent ?? '').toBe('');
1596
- });
1597
- });
1598
-
1599
- it('renders with description', () => {
1600
- render(
1601
- <MultiSelector
1602
- label="Fruit"
1603
- description="Choose your fruits"
1604
- options={defaultOptions}
1605
- value={[]}
1606
- onChange={() => {}}
1607
- />,
1608
- );
1609
- expect(screen.getByText('Choose your fruits')).toBeInTheDocument();
1610
- });
1611
-
1612
- it('supports data-testid', () => {
1613
- render(
1614
- <MultiSelector
1615
- label="Fruit"
1616
- options={defaultOptions}
1617
- value={[]}
1618
- onChange={() => {}}
1619
- data-testid="fruit-selector"
1620
- />,
1621
- );
1622
- expect(screen.getByTestId('fruit-selector')).toBeInTheDocument();
1623
- });
1624
-
1625
- it('renders sections with dividers', async () => {
1626
- const user = userEvent.setup();
1627
- render(
1628
- <MultiSelector
1629
- label="Fruit"
1630
- options={[
1631
- {value: 'apple', label: 'Apple'},
1632
- {
1633
- type: 'section',
1634
- title: 'Citrus',
1635
- options: [
1636
- {value: 'orange', label: 'Orange'},
1637
- {value: 'lemon', label: 'Lemon'},
1638
- ],
1639
- },
1640
- ]}
1641
- value={[]}
1642
- onChange={() => {}}
1643
- />,
1644
- );
1645
-
1646
- await user.click(screen.getByRole('combobox'));
1647
- const options = screen.getAllByRole('option', h);
1648
- expect(options).toHaveLength(3);
1649
- expect(screen.getByText('Citrus')).toBeInTheDocument();
1650
- });
1651
-
1652
- it('shows loading state with a spinner and aria-busy', () => {
1653
- render(
1654
- <MultiSelector
1655
- label="Fruit"
1656
- options={defaultOptions}
1657
- value={[]}
1658
- onChange={() => {}}
1659
- isLoading
1660
- />,
1661
- );
1662
- expect(screen.getByRole('combobox')).toHaveAttribute('aria-busy', 'true');
1663
- expectSilentBusySpinner();
1664
- });
1665
-
1666
- it('renders with custom selectAllLabel', async () => {
1667
- const user = userEvent.setup();
1668
- render(
1669
- <MultiSelector
1670
- label="Fruit"
1671
- options={defaultOptions}
1672
- value={[]}
1673
- onChange={() => {}}
1674
- hasSelectAll
1675
- selectAllLabel="Check all"
1676
- />,
1677
- );
1678
-
1679
- await user.click(screen.getByRole('combobox'));
1680
- expect(screen.getByText('Check all')).toBeInTheDocument();
1681
- });
1682
-
1683
- it('sorts selected items to top', async () => {
1684
- const user = userEvent.setup();
1685
- render(
1686
- <MultiSelector
1687
- label="Fruit"
1688
- options={['Apple', 'Banana', 'Orange']}
1689
- value={['Orange']}
1690
- onChange={() => {}}
1691
- />,
1692
- );
1693
-
1694
- await user.click(screen.getByRole('combobox'));
1695
- const options = screen.getAllByRole('option', h);
1696
- // Orange is selected so it should appear first
1697
- expect(options[0]).toHaveAttribute('aria-selected', 'true');
1698
- expect(options[0]).toHaveTextContent('Orange');
1699
- expect(options[1]).toHaveTextContent('Apple');
1700
- expect(options[2]).toHaveTextContent('Banana');
1701
- });
1702
-
1703
- it('sorts selected items to top within sections', async () => {
1704
- const user = userEvent.setup();
1705
- render(
1706
- <MultiSelector
1707
- label="Fruit"
1708
- options={[
1709
- {
1710
- type: 'section',
1711
- title: 'Citrus',
1712
- options: [
1713
- {value: 'orange', label: 'Orange'},
1714
- {value: 'lemon', label: 'Lemon'},
1715
- {value: 'lime', label: 'Lime'},
1716
- ],
1717
- },
1718
- ]}
1719
- value={['lime']}
1720
- onChange={() => {}}
1721
- />,
1722
- );
1723
-
1724
- await user.click(screen.getByRole('combobox'));
1725
- const options = screen.getAllByRole('option', h);
1726
- // Lime is selected so it should appear first within the section
1727
- expect(options[0]).toHaveTextContent('Lime');
1728
- expect(options[1]).toHaveTextContent('Orange');
1729
- expect(options[2]).toHaveTextContent('Lemon');
1730
- });
1731
-
1732
- it('has displayName', () => {
1733
- expect(MultiSelector.displayName).toBe('MultiSelector');
1734
- });
1735
-
1736
- describe('keyboard accessibility', () => {
1737
- it('trigger is focusable via Tab when enabled', async () => {
1738
- const user = userEvent.setup();
1739
- render(
1740
- <MultiSelector
1741
- label="Fruit"
1742
- options={defaultOptions}
1743
- value={[]}
1744
- onChange={() => {}}
1745
- />,
1746
- );
1747
- await user.tab();
1748
- expect(screen.getByRole('combobox')).toHaveFocus();
1749
- });
1750
-
1751
- it('trigger keeps its tab stop when disabled (spec:AST-085 FR1)', () => {
1752
- render(
1753
- <MultiSelector
1754
- label="Fruit"
1755
- options={defaultOptions}
1756
- value={[]}
1757
- onChange={() => {}}
1758
- isDisabled
1759
- />,
1760
- );
1761
- expect(screen.getByRole('combobox')).toHaveAttribute('tabIndex', '0');
1762
- });
1763
-
1764
- it('opens the listbox with ArrowDown from a focused trigger', async () => {
1765
- const user = userEvent.setup();
1766
- render(
1767
- <MultiSelector
1768
- label="Fruit"
1769
- options={defaultOptions}
1770
- value={[]}
1771
- onChange={() => {}}
1772
- />,
1773
- );
1774
- const trigger = screen.getByRole('combobox');
1775
- await user.tab();
1776
- expect(trigger).toHaveFocus();
1777
- await user.keyboard('{ArrowDown}');
1778
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
1779
- });
1780
-
1781
- it('clear button is reachable by keyboard', () => {
1782
- render(
1783
- <MultiSelector
1784
- label="Fruit"
1785
- options={defaultOptions}
1786
- value={['Apple', 'Banana']}
1787
- onChange={() => {}}
1788
- hasClear
1789
- />,
1790
- );
1791
- const clear = screen.getByRole('button', {name: 'Clear all Fruit'});
1792
- expect(clear).not.toHaveAttribute('tabIndex', '-1');
1793
- });
1794
-
1795
- it('returns focus to the trigger when the clear button is activated by keyboard', async () => {
1796
- function Controlled() {
1797
- const [value, setValue] = useState(['Apple', 'Banana']);
1798
- return (
1799
- <MultiSelector
1800
- label="Fruit"
1801
- options={defaultOptions}
1802
- value={value}
1803
- onChange={setValue}
1804
- hasClear
1805
- />
1806
- );
1807
- }
1808
- const user = userEvent.setup();
1809
- render(<Controlled />);
1810
- screen.getByRole('button', {name: 'Clear all Fruit'}).focus();
1811
- await user.keyboard('{Enter}');
1812
- expect(
1813
- screen.queryByRole('button', {name: 'Clear all Fruit'}),
1814
- ).not.toBeInTheDocument();
1815
- expect(screen.getByRole('combobox')).toHaveFocus();
1816
- });
1817
-
1818
- it('leaves focus in the search input when the clear button is clicked with the list open', async () => {
1819
- function Controlled() {
1820
- const [value, setValue] = useState(['Apple', 'Banana']);
1821
- return (
1822
- <MultiSelector
1823
- label="Fruit"
1824
- options={defaultOptions}
1825
- value={value}
1826
- onChange={setValue}
1827
- hasClear
1828
- hasSearch
1829
- />
1830
- );
1831
- }
1832
- const user = userEvent.setup();
1833
- const {container} = render(<Controlled />);
1834
- await user.click(container.querySelector('[aria-haspopup]') as Element);
1835
- const search = screen.getByRole('combobox', h);
1836
- search.focus();
1837
- await user.click(screen.getByRole('button', {name: 'Clear all Fruit'}));
1838
- expect(
1839
- screen.queryByRole('button', {name: 'Clear all Fruit'}),
1840
- ).not.toBeInTheDocument();
1841
- expect(search).toHaveFocus();
1842
- });
1843
-
1844
- it('scrolls the highlighted option into view during arrow navigation', async () => {
1845
- const scrollIntoView = vi.fn();
1846
- Object.defineProperty(HTMLElement.prototype, 'scrollIntoView', {
1847
- configurable: true,
1848
- value: scrollIntoView,
1849
- });
1850
- try {
1851
- const user = userEvent.setup();
1852
- const longOptions = Array.from(
1853
- {length: 20},
1854
- (_, i) => `Option ${i + 1}`,
1855
- );
1856
- render(
1857
- <MultiSelector
1858
- label="Fruit"
1859
- options={longOptions}
1860
- value={[]}
1861
- onChange={() => {}}
1862
- />,
1863
- );
1864
-
1865
- const trigger = screen.getByRole('combobox');
1866
- await user.click(trigger);
1867
- scrollIntoView.mockClear();
1868
- await user.keyboard('{ArrowDown}');
1869
- await user.keyboard('{ArrowDown}');
1870
-
1871
- expect(scrollIntoView).toHaveBeenCalledWith({block: 'nearest'});
1872
- } finally {
1873
- delete (HTMLElement.prototype as unknown as {scrollIntoView?: unknown})
1874
- .scrollIntoView;
1875
- }
1876
- });
1877
-
1878
- it('highlights on hover without scrolling, keyboard still scrolls (#6077)', async () => {
1879
- // Hover must highlight only: scrollIntoView under a stationary pointer
1880
- // moves the next option under it, re-highlighting and scrolling again —
1881
- // a runaway auto-scroll loop with no user input.
1882
- const scrollIntoView = vi.fn();
1883
- Object.defineProperty(HTMLElement.prototype, 'scrollIntoView', {
1884
- configurable: true,
1885
- value: scrollIntoView,
1886
- });
1887
- try {
1888
- const user = userEvent.setup();
1889
- const longOptions = Array.from(
1890
- {length: 20},
1891
- (_, i) => `Option ${i + 1}`,
1892
- );
1893
- render(
1894
- <MultiSelector
1895
- label="Fruit"
1896
- options={longOptions}
1897
- value={[]}
1898
- onChange={() => {}}
1899
- />,
1900
- );
1901
-
1902
- const trigger = screen.getByRole('combobox');
1903
- await user.click(trigger);
1904
- scrollIntoView.mockClear();
1905
-
1906
- const options = screen.getAllByRole('option', {hidden: true});
1907
- fireEvent.mouseEnter(options[3]);
1908
-
1909
- expect(trigger.getAttribute('aria-activedescendant')).toBe(
1910
- options[3].id,
1911
- );
1912
- expect(scrollIntoView).not.toHaveBeenCalled();
1913
-
1914
- await user.keyboard('{ArrowDown}');
1915
- expect(scrollIntoView).toHaveBeenCalledWith({block: 'nearest'});
1916
- } finally {
1917
- delete (HTMLElement.prototype as unknown as {scrollIntoView?: unknown})
1918
- .scrollIntoView;
1919
- }
1920
- });
1921
-
1922
- it('clears all values via Delete on the focused trigger', async () => {
1923
- const user = userEvent.setup();
1924
- const onChange = vi.fn();
1925
- render(
1926
- <MultiSelector
1927
- label="Fruit"
1928
- options={defaultOptions}
1929
- value={['Apple', 'Banana']}
1930
- onChange={onChange}
1931
- hasClear
1932
- />,
1933
- );
1934
- const trigger = screen.getByRole('combobox');
1935
- trigger.focus();
1936
- await user.keyboard('{Delete}');
1937
- expect(onChange).toHaveBeenCalledWith([]);
1938
- });
1939
-
1940
- it('clears all values via Backspace on the focused trigger', async () => {
1941
- const user = userEvent.setup();
1942
- const onChange = vi.fn();
1943
- render(
1944
- <MultiSelector
1945
- label="Fruit"
1946
- options={defaultOptions}
1947
- value={['Apple', 'Banana']}
1948
- onChange={onChange}
1949
- hasClear
1950
- />,
1951
- );
1952
- const trigger = screen.getByRole('combobox');
1953
- trigger.focus();
1954
- await user.keyboard('{Backspace}');
1955
- expect(onChange).toHaveBeenCalledWith([]);
1956
- });
1957
-
1958
- it('does not clear via Delete when nothing is selected', async () => {
1959
- const user = userEvent.setup();
1960
- const onChange = vi.fn();
1961
- render(
1962
- <MultiSelector
1963
- label="Fruit"
1964
- options={defaultOptions}
1965
- value={[]}
1966
- onChange={onChange}
1967
- hasClear
1968
- />,
1969
- );
1970
- const trigger = screen.getByRole('combobox');
1971
- trigger.focus();
1972
- await user.keyboard('{Delete}');
1973
- expect(onChange).not.toHaveBeenCalled();
1974
- });
1975
- });
1976
-
1977
- describe('announcements', () => {
1978
- it('announces the selection count politely when toggling an option', async () => {
1979
- const user = userEvent.setup();
1980
- render(
1981
- <InternationalizationProvider
1982
- locale="fr"
1983
- overrides={{
1984
- fr: {
1985
- '@astryx.multiSelector.selectionCount':
1986
- '{count, number} sur {total, number} sélectionnés',
1987
- },
1988
- }}>
1989
- <MultiSelector
1990
- label="Fruit"
1991
- options={[...ANNOUNCE_OPTIONS]}
1992
- value={EMPTY_VALUE}
1993
- onChange={() => {}}
1994
- />
1995
- </InternationalizationProvider>,
1996
- );
1997
- await user.click(screen.getByRole('combobox'));
1998
- const options = screen.getAllByRole('option', {hidden: true});
1999
- await user.click(options[0]);
2000
- await waitFor(() => {
2001
- // Both arguments land, in the order the message asks for them.
2002
- expect(politeRegion()?.textContent).toBe('1 sur 3 sélectionnés');
2003
- });
2004
- });
2005
-
2006
- it('announces the all-selected message when select-all selects everything', async () => {
2007
- const user = userEvent.setup();
2008
- render(
2009
- <InternationalizationProvider
2010
- locale="fr"
2011
- overrides={{
2012
- fr: {'@astryx.multiSelector.allSelected': 'Tout est là'},
2013
- }}>
2014
- <MultiSelector
2015
- label="Fruit"
2016
- options={[...ANNOUNCE_OPTIONS]}
2017
- value={EMPTY_VALUE}
2018
- onChange={() => {}}
2019
- hasSelectAll
2020
- />
2021
- </InternationalizationProvider>,
2022
- );
2023
- await user.click(screen.getByRole('combobox'));
2024
- await user.click(screen.getByText('Select all'));
2025
- await waitFor(() => {
2026
- expect(politeRegion()?.textContent).toBe('Tout est là');
2027
- });
2028
- });
2029
-
2030
- it('announces the selection-cleared message when clearing', async () => {
2031
- const user = userEvent.setup();
2032
- render(
2033
- <InternationalizationProvider
2034
- locale="fr"
2035
- overrides={{
2036
- fr: {'@astryx.multiSelector.selectionCleared': 'Plus rien'},
2037
- }}>
2038
- <MultiSelector
2039
- label="Fruit"
2040
- options={[...ANNOUNCE_OPTIONS]}
2041
- value={['Apple', 'Banana']}
2042
- onChange={() => {}}
2043
- hasClear
2044
- />
2045
- </InternationalizationProvider>,
2046
- );
2047
- await user.click(screen.getByRole('button', {name: 'Clear all Fruit'}));
2048
- await waitFor(() => {
2049
- expect(politeRegion()?.textContent).toBe('Plus rien');
2050
- });
2051
- });
2052
-
2053
- it('prefers a provider override over the provider catalog', async () => {
2054
- const user = userEvent.setup();
2055
- render(
2056
- <InternationalizationProvider
2057
- locale="fr"
2058
- messages={{
2059
- fr: {
2060
- '@astryx.multiSelector.selectionCount': {
2061
- defaultMessage: '{count, number} du catalogue',
2062
- },
2063
- },
2064
- }}
2065
- overrides={{
2066
- fr: {
2067
- '@astryx.multiSelector.selectionCount':
2068
- '{count, number} remplacé',
2069
- },
2070
- }}>
2071
- <MultiSelector
2072
- label="Fruit"
2073
- options={[...ANNOUNCE_OPTIONS]}
2074
- value={EMPTY_VALUE}
2075
- onChange={() => {}}
2076
- />
2077
- </InternationalizationProvider>,
2078
- );
2079
- await user.click(screen.getByRole('combobox'));
2080
- const options = screen.getAllByRole('option', {hidden: true});
2081
- await user.click(options[0]);
2082
- await waitFor(() => {
2083
- expect(politeRegion()?.textContent).toBe('1 remplacé');
2084
- });
2085
- });
2086
- });
2087
-
2088
- describe('disabledMessage', () => {
2089
- it('shows the reason tooltip on hover when disabled with a reason', async () => {
2090
- render(
2091
- <MultiSelector
2092
- label="Fruit"
2093
- options={defaultOptions}
2094
- value={[]}
2095
- onChange={() => {}}
2096
- isDisabled
2097
- disabledMessage="Select a table first"
2098
- data-testid="fruit-multi-selector"
2099
- />,
2100
- );
2101
-
2102
- // data-testid lands on the trigger; the reason tooltip anchors to the
2103
- // control box around it.
2104
- const container = screen
2105
- .getByTestId('fruit-multi-selector')
2106
- .closest('.astryx-multi-selector') as HTMLElement;
2107
- const tooltip = screen.getByRole('tooltip', h);
2108
- expect(tooltip).toHaveTextContent('Select a table first');
2109
-
2110
- fireEvent.mouseEnter(container);
2111
- await waitFor(() => {
2112
- expect(tooltip).toHaveAttribute('popover-open');
2113
- });
2114
-
2115
- fireEvent.mouseLeave(container);
2116
- await waitFor(() => {
2117
- expect(tooltip).not.toHaveAttribute('popover-open');
2118
- });
2119
- });
2120
-
2121
- it('shows the reason tooltip on keyboard focus', async () => {
2122
- const user = userEvent.setup();
2123
- render(
2124
- <MultiSelector
2125
- label="Fruit"
2126
- options={defaultOptions}
2127
- value={[]}
2128
- onChange={() => {}}
2129
- isDisabled
2130
- disabledMessage="Select a table first"
2131
- />,
2132
- );
2133
-
2134
- const tooltip = screen.getByRole('tooltip', h);
2135
- await user.tab();
2136
- expect(screen.getByRole('combobox')).toHaveFocus();
2137
- await waitFor(() => {
2138
- expect(tooltip).toHaveAttribute('popover-open');
2139
- });
2140
- });
2141
-
2142
- it('does not render a tooltip when not disabled', () => {
2143
- render(
2144
- <MultiSelector
2145
- label="Fruit"
2146
- options={defaultOptions}
2147
- value={[]}
2148
- onChange={() => {}}
2149
- disabledMessage="Select a table first"
2150
- />,
2151
- );
2152
- expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
2153
- });
2154
-
2155
- it('does not render a tooltip when disabled without a reason', () => {
2156
- render(
2157
- <MultiSelector
2158
- label="Fruit"
2159
- options={defaultOptions}
2160
- value={[]}
2161
- onChange={() => {}}
2162
- isDisabled
2163
- />,
2164
- );
2165
- expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
2166
- });
2167
-
2168
- it('keeps the trigger focusable via aria-disabled when a reason is provided', () => {
2169
- render(
2170
- <MultiSelector
2171
- label="Fruit"
2172
- options={defaultOptions}
2173
- value={[]}
2174
- onChange={() => {}}
2175
- isDisabled
2176
- disabledMessage="Select a table first"
2177
- />,
2178
- );
2179
- const trigger = screen.getByRole('combobox');
2180
- expect(trigger).not.toBeDisabled();
2181
- expect(trigger).toHaveAttribute('aria-disabled', 'true');
2182
- expect(trigger).toHaveAttribute('tabIndex', '0');
2183
- });
2184
-
2185
- it('links the reason tooltip from the trigger via aria-describedby', () => {
2186
- render(
2187
- <MultiSelector
2188
- label="Fruit"
2189
- options={defaultOptions}
2190
- value={[]}
2191
- onChange={() => {}}
2192
- isDisabled
2193
- disabledMessage="Select a table first"
2194
- />,
2195
- );
2196
- const trigger = screen.getByRole('combobox');
2197
- const tooltip = screen.getByRole('tooltip', h);
2198
- expect(trigger.getAttribute('aria-describedby')).toContain(tooltip.id);
2199
- });
2200
-
2201
- it('blocks activation while focusable-disabled', async () => {
2202
- const user = userEvent.setup();
2203
- const onChange = vi.fn();
2204
- render(
2205
- <MultiSelector
2206
- label="Fruit"
2207
- options={defaultOptions}
2208
- value={[]}
2209
- onChange={onChange}
2210
- isDisabled
2211
- disabledMessage="Select a table first"
2212
- />,
2213
- );
2214
-
2215
- const trigger = screen.getByRole('combobox');
2216
- await user.click(trigger);
2217
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
2218
-
2219
- await user.keyboard('{Enter}');
2220
- await user.keyboard('{ArrowDown}');
2221
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
2222
- expect(onChange).not.toHaveBeenCalled();
2223
- });
2224
-
2225
- it('stays focusable when disabled without a reason (spec:AST-085 FR1)', () => {
2226
- render(
2227
- <MultiSelector
2228
- label="Fruit"
2229
- options={defaultOptions}
2230
- value={[]}
2231
- onChange={() => {}}
2232
- isDisabled
2233
- />,
2234
- );
2235
- const trigger = screen.getByRole('combobox');
2236
- expect(trigger).not.toHaveAttribute('disabled');
2237
- expect(trigger).toHaveAttribute('aria-disabled', 'true');
2238
- expect(trigger).toHaveAttribute('tabIndex', '0');
2239
- });
2240
- });
2241
- describe('isReadOnly', () => {
2242
- const readOnlyCases = [
2243
- {presentation: 'popover', hasSearch: false},
2244
- {presentation: 'popover', hasSearch: true},
2245
- {presentation: 'bottom-sheet', hasSearch: false},
2246
- {presentation: 'bottom-sheet', hasSearch: true},
2247
- {presentation: 'adaptive', hasSearch: false},
2248
- {presentation: 'adaptive', hasSearch: true},
2249
- ] as const;
2250
-
2251
- const sheetTransitionCases = [
2252
- {presentation: 'bottom-sheet', hasSearch: false},
2253
- {presentation: 'bottom-sheet', hasSearch: true},
2254
- {presentation: 'adaptive', hasSearch: false},
2255
- {presentation: 'adaptive', hasSearch: true},
2256
- ] as const;
2257
-
2258
- const disabledPrecedenceCases = (
2259
- ['popover', 'bottom-sheet', 'adaptive'] as const
2260
- ).flatMap(presentation =>
2261
- [false, true].flatMap(hasSearch =>
2262
- [false, true].map(hasDisabledMessage => ({
2263
- presentation,
2264
- hasSearch,
2265
- hasDisabledMessage,
2266
- })),
2267
- ),
2268
- );
2269
-
2270
- function stubCompactTouch(presentation: 'bottom-sheet' | 'adaptive') {
2271
- if (presentation !== 'adaptive') {
2272
- return;
2273
- }
2274
- vi.mocked(matchMedia).mockImplementation(
2275
- (query: string) =>
2276
- ({
2277
- matches: query === COMPACT_TOUCH_PRESENTATION_QUERY,
2278
- media: query,
2279
- onchange: null,
2280
- addEventListener: vi.fn(),
2281
- removeEventListener: vi.fn(),
2282
- addListener: vi.fn(),
2283
- removeListener: vi.fn(),
2284
- dispatchEvent: vi.fn(),
2285
- }) as MediaQueryList,
2286
- );
2287
- }
2288
-
2289
- it.each(readOnlyCases)(
2290
- 'uses a read-only combobox with no rendered popup ($presentation, search=$hasSearch)',
2291
- async ({presentation, hasSearch}) => {
2292
- const user = userEvent.setup();
2293
- const {container} = render(
2294
- <form>
2295
- <MultiSelector
2296
- label="Fruit"
2297
- htmlName="fruit"
2298
- options={defaultOptions}
2299
- value={['Apple', 'Banana']}
2300
- onChange={() => {}}
2301
- hasClear
2302
- hasSearch={hasSearch}
2303
- presentation={presentation}
2304
- isDefaultOpen
2305
- triggerDisplay="labels"
2306
- isReadOnly
2307
- />
2308
- </form>,
2309
- );
2310
-
2311
- const trigger = screen.getByRole('combobox', {name: 'Fruit'});
2312
- expect(trigger.tagName).toBe('BUTTON');
2313
- expect(trigger).toHaveTextContent('Apple, Banana');
2314
- expect(trigger).toHaveAttribute('aria-readonly', 'true');
2315
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
2316
- const readOnlyDescription = screen.getByText('Read only');
2317
- expect(trigger.getAttribute('aria-describedby')).toContain(
2318
- readOnlyDescription.id,
2319
- );
2320
- expect(trigger).not.toHaveAttribute('aria-controls');
2321
- expect(trigger).not.toHaveAttribute('aria-haspopup');
2322
- expect(screen.getAllByRole('combobox', h)).toHaveLength(1);
2323
- expect(screen.queryByRole('listbox', h)).not.toBeInTheDocument();
2324
- expect(screen.queryByRole('dialog', h)).not.toBeInTheDocument();
2325
- expect(
2326
- screen.queryByRole('button', {name: 'Clear all Fruit'}),
2327
- ).not.toBeInTheDocument();
2328
- expect(
2329
- container.querySelector('.astryx-multi-selector-indicator-icon'),
2330
- ).toBeNull();
2331
- expect(
2332
- container.querySelector('.astryx-multi-selector'),
2333
- ).toHaveAttribute('data-readonly', 'readonly');
2334
- expect(
2335
- new FormData(container.querySelector('form')!).getAll('fruit'),
2336
- ).toEqual(['Apple', 'Banana']);
2337
-
2338
- await user.tab();
2339
- expect(trigger).toHaveFocus();
2340
- },
2341
- );
2342
-
2343
- it('keeps loading feedback while blocking the selection surface', async () => {
2344
- const user = userEvent.setup();
2345
- render(
2346
- <MultiSelector
2347
- label="Fruit"
2348
- options={defaultOptions}
2349
- value={['Apple']}
2350
- onChange={() => {}}
2351
- isLoading
2352
- isReadOnly
2353
- />,
2354
- );
2355
-
2356
- const trigger = screen.getByRole('combobox', {name: 'Fruit'});
2357
- expect(trigger).toHaveAttribute('aria-busy', 'true');
2358
- expectSilentBusySpinner();
2359
-
2360
- await user.click(trigger);
2361
- expect(screen.queryByRole('listbox', h)).not.toBeInTheDocument();
2362
- });
2363
-
2364
- it('blocks pointer, keyboard, and typeahead changes', async () => {
2365
- const user = userEvent.setup();
2366
- const onChange = vi.fn();
2367
- const changeAction = vi.fn();
2368
- render(
2369
- <MultiSelector
2370
- label="Fruit"
2371
- options={defaultOptions}
2372
- value={['Apple']}
2373
- onChange={onChange}
2374
- changeAction={changeAction}
2375
- isReadOnly
2376
- />,
2377
- );
2378
-
2379
- const trigger = screen.getByRole('combobox');
2380
- await user.click(trigger);
2381
- trigger.focus();
2382
- await user.keyboard('{Enter}{ArrowDown}b{Backspace}');
2383
-
2384
- expect(screen.queryByRole('listbox', h)).not.toBeInTheDocument();
2385
- expect(onChange).not.toHaveBeenCalled();
2386
- expect(changeAction).not.toHaveBeenCalled();
2387
- });
2388
-
2389
- it.each([false, true])(
2390
- 'restores popover focus when an open selector becomes read-only (search=%s)',
2391
- async hasSearch => {
2392
- const user = userEvent.setup();
2393
- const selector = (isReadOnly: boolean) => (
2394
- <MultiSelector
2395
- label="Fruit"
2396
- options={defaultOptions}
2397
- value={['Apple']}
2398
- onChange={() => {}}
2399
- hasSearch={hasSearch}
2400
- isReadOnly={isReadOnly}
2401
- />
2402
- );
2403
- const {rerender} = render(selector(false));
2404
- const editableTrigger = screen.getByRole(
2405
- hasSearch ? 'button' : 'combobox',
2406
- {name: 'Fruit'},
2407
- );
2408
- await user.click(editableTrigger);
2409
- if (hasSearch) {
2410
- await waitFor(() =>
2411
- expect(screen.getByRole('combobox', h)).toHaveFocus(),
2412
- );
2413
- }
2414
-
2415
- rerender(selector(true));
2416
-
2417
- const readOnlyTrigger = screen.getByRole('combobox', {name: 'Fruit'});
2418
- await waitFor(() => expect(readOnlyTrigger).toHaveFocus());
2419
- expect(screen.queryByRole('listbox', h)).not.toBeInTheDocument();
2420
- },
2421
- );
2422
-
2423
- it.each(sheetTransitionCases)(
2424
- 'finishes $presentation close and restores focus when read-only changes (search=$hasSearch)',
2425
- async ({presentation, hasSearch}) => {
2426
- stubCompactTouch(presentation);
2427
- const user = userEvent.setup();
2428
- const selector = (isReadOnly: boolean) => (
2429
- <MultiSelector
2430
- label="Fruit"
2431
- options={defaultOptions}
2432
- value={['Apple']}
2433
- onChange={() => {}}
2434
- hasSearch={hasSearch}
2435
- presentation={presentation}
2436
- isReadOnly={isReadOnly}
2437
- />
2438
- );
2439
- const {rerender} = render(selector(false));
2440
- const editableTrigger = screen.getByRole(
2441
- hasSearch ? 'button' : 'combobox',
2442
- {name: 'Fruit'},
2443
- );
2444
- await user.click(editableTrigger);
2445
- const dialog = await screen.findByRole('dialog', {name: 'Fruit'});
2446
- const panel = dialog.querySelector<HTMLElement>('.astryx-bottom-sheet');
2447
- expect(panel).not.toBeNull();
2448
- await waitFor(() =>
2449
- expect(
2450
- hasSearch
2451
- ? screen.getByRole('combobox', h)
2452
- : screen.getByRole('listbox'),
2453
- ).toHaveFocus(),
2454
- );
2455
-
2456
- rerender(selector(true));
2457
-
2458
- await waitFor(() => expect(dialog).toHaveAttribute('inert'));
2459
- fireEvent.transitionEnd(panel!, {propertyName: 'transform'});
2460
- const readOnlyTrigger = screen.getByRole('combobox', {name: 'Fruit'});
2461
- await waitFor(() => expect(readOnlyTrigger).toHaveFocus());
2462
- expect(screen.queryByRole('dialog', h)).not.toBeInTheDocument();
2463
- expect(screen.queryByRole('listbox', h)).not.toBeInTheDocument();
2464
- },
2465
- );
2466
-
2467
- it.each(disabledPrecedenceCases)(
2468
- 'matches disabled-only semantics for $presentation (search=$hasSearch, reason=$hasDisabledMessage)',
2469
- async ({presentation, hasSearch, hasDisabledMessage}) => {
2470
- if (presentation === 'adaptive') {
2471
- stubCompactTouch(presentation);
2472
- }
2473
- const user = userEvent.setup();
2474
- const onChange = vi.fn();
2475
- const selector = (isReadOnly: boolean) => (
2476
- <form>
2477
- <MultiSelector
2478
- label="Fruit"
2479
- htmlName="fruit"
2480
- options={defaultOptions}
2481
- value={['Apple', 'Banana']}
2482
- onChange={onChange}
2483
- hasClear
2484
- hasSearch={hasSearch}
2485
- presentation={presentation}
2486
- isDisabled
2487
- isReadOnly={isReadOnly}
2488
- disabledMessage={
2489
- hasDisabledMessage ? 'Locked by policy' : undefined
2490
- }
2491
- />
2492
- </form>
2493
- );
2494
- const {container, rerender} = render(selector(false));
2495
- const getTrigger = () =>
2496
- screen.getByRole(hasSearch ? 'button' : 'combobox', {name: 'Fruit'});
2497
- const snapshot = () => {
2498
- const trigger = getTrigger();
2499
- const root = container.querySelector('.astryx-multi-selector');
2500
- return {
2501
- tagName: trigger.tagName,
2502
- role: trigger.getAttribute('role'),
2503
- hasPopup: trigger.getAttribute('aria-haspopup'),
2504
- expanded: trigger.getAttribute('aria-expanded'),
2505
- controls: trigger.getAttribute('aria-controls'),
2506
- readOnly: trigger.getAttribute('aria-readonly'),
2507
- disabled: trigger.matches(':disabled'),
2508
- ariaDisabled: trigger.getAttribute('aria-disabled'),
2509
- tabIndex: trigger.tabIndex,
2510
- rootClassName: root?.className,
2511
- rootDisabled: root?.getAttribute('data-disabled'),
2512
- rootReadOnly: root?.getAttribute('data-readonly'),
2513
- hasIndicator:
2514
- root?.querySelector('.astryx-multi-selector-indicator-icon') !=
2515
- null,
2516
- listboxes: screen.queryAllByRole('listbox', h).length,
2517
- dialogs: screen.queryAllByRole('dialog', h).length,
2518
- formEntries: [
2519
- ...new FormData(container.querySelector('form')!).entries(),
2520
- ],
2521
- };
2522
- };
2523
- const disabledOnly = snapshot();
2524
-
2525
- rerender(selector(true));
2526
-
2527
- expect(snapshot()).toEqual(disabledOnly);
2528
- expect(disabledOnly.rootDisabled).toBe('disabled');
2529
- expect(disabledOnly.rootReadOnly).toBeNull();
2530
- expect(disabledOnly.readOnly).toBeNull();
2531
- expect(disabledOnly.formEntries).toEqual([]);
2532
- const trigger = getTrigger();
2533
- await user.click(trigger);
2534
- trigger.focus();
2535
- await user.keyboard('{Enter}{ArrowDown}b{Backspace}');
2536
- expect(onChange).not.toHaveBeenCalled();
2537
- },
2538
- );
2539
- });
2540
-
2541
- describe('form participation', () => {
2542
- it('submits one entry per selected value under htmlName', () => {
2543
- const {container} = render(
2544
- <form>
2545
- <MultiSelector
2546
- label="Fruit"
2547
- htmlName="fruit"
2548
- options={['Apple', 'Banana', 'Orange']}
2549
- value={['Apple', 'Orange']}
2550
- onChange={() => {}}
2551
- />
2552
- </form>,
2553
- );
2554
- const data = new FormData(container.querySelector('form')!);
2555
- expect(data.getAll('fruit')).toEqual(['Apple', 'Orange']);
2556
- });
2557
-
2558
- it('is excluded from form data when disabled', () => {
2559
- const {container} = render(
2560
- <form>
2561
- <MultiSelector
2562
- label="Fruit"
2563
- htmlName="fruit"
2564
- options={['Apple']}
2565
- value={['Apple']}
2566
- onChange={() => {}}
2567
- isDisabled
2568
- />
2569
- </form>,
2570
- );
2571
- expect([
2572
- ...new FormData(container.querySelector('form')!).keys(),
2573
- ]).toEqual([]);
2574
- });
2575
- });
2576
- });
2577
-
2578
- describe('MultiSelector statusVariant forwarding', () => {
2579
- it('defaults to attached (status renders with data-variant="attached")', () => {
2580
- const {container} = render(
2581
- <MultiSelector
2582
- label="Fruit"
2583
- options={['Apple', 'Banana']}
2584
- value={[]}
2585
- onChange={() => {}}
2586
- status={{type: 'error', message: 'Required'}}
2587
- />,
2588
- );
2589
- expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
2590
- 'data-variant',
2591
- 'attached',
2592
- );
2593
- });
2594
-
2595
- it('forwards statusVariant="detached" to the underlying Field status', () => {
2596
- const {container} = render(
2597
- <MultiSelector
2598
- label="Fruit"
2599
- options={['Apple', 'Banana']}
2600
- value={[]}
2601
- onChange={() => {}}
2602
- status={{type: 'error', message: 'Required'}}
2603
- statusVariant="detached"
2604
- />,
2605
- );
2606
- expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
2607
- 'data-variant',
2608
- 'detached',
2609
- );
2610
- });
2611
-
2612
- it('keeps the on-field status icon for the attached variant', () => {
2613
- const {container} = render(
2614
- <MultiSelector
2615
- label="Fruit"
2616
- options={['Apple', 'Banana']}
2617
- value={[]}
2618
- onChange={() => {}}
2619
- status={{type: 'error', message: 'Required'}}
2620
- />,
2621
- );
2622
- // Attached: the status glyph replaces the chevron indicator on the field.
2623
- expect(
2624
- container.querySelector('.astryx-multi-selector-indicator-icon'),
2625
- ).toBeNull();
2626
- });
2627
-
2628
- it('suppresses the on-field status icon for the detached variant', () => {
2629
- const {container} = render(
2630
- <MultiSelector
2631
- label="Fruit"
2632
- options={['Apple', 'Banana']}
2633
- value={[]}
2634
- onChange={() => {}}
2635
- status={{type: 'error', message: 'Required'}}
2636
- statusVariant="detached"
2637
- />,
2638
- );
2639
- // Detached: the message box below carries its own leading icon, so the
2640
- // field keeps its chevron indicator rather than duplicating the glyph.
2641
- expect(
2642
- container.querySelector('.astryx-multi-selector-indicator-icon'),
2643
- ).not.toBeNull();
2644
- });
2645
-
2646
- it.each(['secondary', 'ghost'] as const)(
2647
- 'detaches attached status by default for the %s variant',
2648
- variant => {
2649
- const {container} = render(
2650
- <MultiSelector
2651
- label="Fruit"
2652
- options={['Apple', 'Banana']}
2653
- value={[]}
2654
- onChange={() => {}}
2655
- variant={variant}
2656
- status={{type: 'error', message: 'Required'}}
2657
- />,
2658
- );
2659
- expect(container.querySelector('.astryx-multi-selector')).toHaveAttribute(
2660
- 'data-variant',
2661
- variant,
2662
- );
2663
- expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
2664
- 'data-variant',
2665
- 'detached',
2666
- );
2667
- },
2668
- );
2669
-
2670
- it('uses a status tooltip for ghost multi-selectors when requested', () => {
2671
- const {container} = render(
2672
- <MultiSelector
2673
- label="Fruit"
2674
- options={['Apple', 'Banana']}
2675
- value={[]}
2676
- onChange={() => {}}
2677
- variant="ghost"
2678
- status={{type: 'warning', message: 'Some rows are hidden'}}
2679
- statusVariant="tooltip"
2680
- />,
2681
- );
2682
- expect(container.querySelector('.astryx-field-status')).toBeNull();
2683
- const statusButton = screen.getByRole('button', {
2684
- name: /warning details/i,
2685
- });
2686
- const tooltip = screen.getByRole('tooltip', h);
2687
- expect(tooltip).toHaveTextContent('Some rows are hidden');
2688
- expect(statusButton.getAttribute('aria-describedby')).toContain(tooltip.id);
2689
- expect(
2690
- screen.getByRole('combobox').getAttribute('aria-describedby'),
2691
- ).toContain(tooltip.id);
2692
- });
2693
- });
2694
-
2695
- describe('MultiSelector empty-state theme target', () => {
2696
- const OPTIONS = ['Apple', 'Banana', 'Cherry'];
2697
-
2698
- it('renders the astryx-multi-selector-empty-state target on the "No results found" element', async () => {
2699
- const user = userEvent.setup();
2700
- const {container} = render(
2701
- <MultiSelector
2702
- label="Fruit"
2703
- options={OPTIONS}
2704
- value={[]}
2705
- onChange={() => {}}
2706
- hasSearch
2707
- />,
2708
- );
2709
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
2710
- await user.type(screen.getByRole('combobox', h), 'xyz');
2711
-
2712
- const empty = container.querySelector('.astryx-multi-selector-empty-state');
2713
- expect(empty).not.toBeNull();
2714
- expect(empty).toHaveTextContent('No results found');
2715
- });
2716
- });
2717
-
2718
- describe('MultiSelector clear icon theme target', () => {
2719
- const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
2720
-
2721
- // Resolve the clear glyph span (the astryx-icon element inside the clear
2722
- // button), independent of the theme target class.
2723
- const getClearIcon = (): HTMLElement => {
2724
- const button = screen.getByRole('button', {name: 'Clear all Fruit'});
2725
- const icon = button.querySelector('.astryx-icon');
2726
- if (icon == null) {
2727
- throw new Error('clear icon not found');
2728
- }
2729
- return icon as HTMLElement;
2730
- };
2731
-
2732
- it('renders only the astryx-input-clear-icon target on the clear glyph', () => {
2733
- render(
2734
- <MultiSelector
2735
- label="Fruit"
2736
- options={ICON_OPTIONS}
2737
- value={['Banana']}
2738
- onChange={() => {}}
2739
- hasClear
2740
- />,
2741
- );
2742
- // The canonical target lands on the icon element itself (not the button),
2743
- // so a theme can restyle just this glyph (color, size, hover) via
2744
- // `defineTheme` — a button-level target could not reach the icon's own
2745
- // color/size.
2746
- const icon = getClearIcon();
2747
- expect(icon).toHaveClass('astryx-input-clear-icon');
2748
- expect(icon).not.toHaveClass('astryx-multi-selector-clear-icon');
2749
- expect(icon).toHaveClass('astryx-icon');
2750
- });
2751
-
2752
- it('keeps the clear button functional alongside the target', () => {
2753
- const onChange = vi.fn();
2754
- render(
2755
- <MultiSelector
2756
- label="Fruit"
2757
- options={ICON_OPTIONS}
2758
- value={['Banana']}
2759
- onChange={onChange}
2760
- hasClear
2761
- />,
2762
- );
2763
- const clear = screen.getByRole('button', {name: 'Clear all Fruit'});
2764
- expect(clear.tagName).toBe('BUTTON');
2765
- fireEvent.click(clear);
2766
- expect(onChange).toHaveBeenCalledWith([]);
2767
- });
2768
-
2769
- it('routes the clear glyph through the shared clear button', () => {
2770
- // The clear affordance composes the shared InputClearButton (a ghost Button
2771
- // with a secondary/sm glyph), so the icon carries the canonical
2772
- // `astryx-input-clear-icon` target. Aside from that target class it matches
2773
- // the shared button's own `close`/`sm`/`secondary` glyph exactly, so the
2774
- // default look is defined in one place.
2775
- render(
2776
- <MultiSelector
2777
- label="Fruit"
2778
- options={ICON_OPTIONS}
2779
- value={['Banana']}
2780
- onChange={() => {}}
2781
- hasClear
2782
- />,
2783
- );
2784
- const icon = getClearIcon();
2785
- expect(icon).toHaveClass('astryx-input-clear-icon');
2786
- expect(icon).not.toHaveClass('astryx-multi-selector-clear-icon');
2787
-
2788
- const {container: refContainer} = render(
2789
- <Icon icon="close" size="sm" color="secondary" />,
2790
- );
2791
- const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
2792
-
2793
- const styleClasses = (el: HTMLElement) =>
2794
- el.className
2795
- .split(' ')
2796
- .filter(c => c !== 'astryx-input-clear-icon')
2797
- .sort();
2798
-
2799
- expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
2800
- });
2801
-
2802
- it('uses input-clear-icon so a theme reaches the icon color, size, and hover', () => {
2803
- // jsdom cannot resolve the @layer cascade, so the DOM-class assertion above
2804
- // (target lands on the icon element) plus this generation assertion (the
2805
- // theme emits same-element icon rules in @layer astryx-theme) together
2806
- // prove the seam: a same-element theme rule wins over the icon's own
2807
- // base-layer color/size.
2808
- const theme = defineTheme({
2809
- name: 'multi-selector-shared-clear-icon-test',
2810
- components: {
2811
- 'input-clear-icon': {
2812
- base: {
2813
- width: '12px',
2814
- height: '12px',
2815
- fontSize: '12px',
2816
- color: 'var(--color-icon-secondary)',
2817
- ':hover': {color: 'var(--color-icon-primary)'},
2818
- },
2819
- },
2820
- },
2821
- });
2822
- const css = generateThemeTestCSS(theme);
2823
- expect(css).toContain('.astryx-input-clear-icon {');
2824
- expect(css).toContain('width: 12px');
2825
- expect(css).toContain('height: 12px');
2826
- expect(css).toContain('.astryx-input-clear-icon:hover');
2827
- expect(css).toContain('color: var(--color-icon-primary)');
2828
- });
2829
- });
2830
-
2831
- describe('MultiSelector indicator (chevron) icon theme target', () => {
2832
- const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
2833
-
2834
- const getIndicatorIcon = (container: HTMLElement): HTMLElement => {
2835
- // The chevron is the only glyph carrying the indicator target class.
2836
- const icon = container.querySelector(
2837
- '.astryx-multi-selector-indicator-icon',
2838
- );
2839
- if (icon == null) {
2840
- throw new Error('indicator icon not found');
2841
- }
2842
- return icon as HTMLElement;
2843
- };
2844
-
2845
- it('renders the astryx-multi-selector-indicator-icon target on the chevron glyph', () => {
2846
- const {container} = render(
2847
- <MultiSelector
2848
- label="Fruit"
2849
- options={ICON_OPTIONS}
2850
- value={[]}
2851
- onChange={() => {}}
2852
- />,
2853
- );
2854
- // The stable theme target lands on the icon element itself (not the trigger
2855
- // button), so a theme can restyle just this glyph (color, size, hover) —
2856
- // and each open/closed state — via `defineTheme`. A button-level target
2857
- // could not reach the icon's own color/size.
2858
- const icon = getIndicatorIcon(container);
2859
- expect(icon).toHaveClass('astryx-multi-selector-indicator-icon');
2860
- expect(icon).toHaveClass('astryx-icon');
2861
- // Open/closed state is reflected so a theme can target each state alone.
2862
- expect(icon).toHaveAttribute('data-state', 'collapsed');
2863
- });
2864
-
2865
- it('reflects the expanded state on the chevron when the popover is open', async () => {
2866
- const user = userEvent.setup();
2867
- const {container} = render(
2868
- <MultiSelector
2869
- label="Fruit"
2870
- options={ICON_OPTIONS}
2871
- value={[]}
2872
- onChange={() => {}}
2873
- />,
2874
- );
2875
- await user.click(screen.getByRole('combobox'));
2876
- await waitFor(() => {
2877
- expect(getIndicatorIcon(container)).toHaveAttribute(
2878
- 'data-state',
2879
- 'expanded',
2880
- );
2881
- });
2882
- });
2883
-
2884
- it('renders the default icon (secondary color, sm size) byte-identically', () => {
2885
- // Pixel-identical default guard: the chevron glyph must carry the exact
2886
- // same StyleX color/size classes as a standalone secondary/sm icon. The
2887
- // glyph now sets --color-icon-secondary itself rather than inheriting it
2888
- // from a wrapper span that set the same token, so the rendered color is
2889
- // unchanged. The added
2890
- // target class + data-state are purely additive — they change nothing until
2891
- // a theme targets them.
2892
- const {container} = render(
2893
- <MultiSelector
2894
- label="Fruit"
2895
- options={ICON_OPTIONS}
2896
- value={[]}
2897
- onChange={() => {}}
2898
- />,
2899
- );
2900
- const icon = getIndicatorIcon(container);
2901
-
2902
- const {container: refContainer} = render(
2903
- <Icon icon="chevronDown" size="sm" color="secondary" />,
2904
- );
2905
- const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
2906
-
2907
- // Exclude the additive theme-target classes (the stable target + its
2908
- // reflected state class) so only StyleX classes remain.
2909
- const themeTargetClasses = new Set([
2910
- 'astryx-multi-selector-indicator-icon',
2911
- 'collapsed',
2912
- 'expanded',
2913
- ]);
2914
- const styleClasses = (el: HTMLElement) =>
2915
- el.className
2916
- .split(' ')
2917
- .filter(c => !themeTargetClasses.has(c))
2918
- .sort();
2919
-
2920
- // A superset, not an exact match: the chevron additionally carries the
2921
- // rotation styles, which live on the glyph precisely so a theme can reach
2922
- // the transform through the same selector as the color. The guard that
2923
- // matters is that every color/size class of a standalone icon is still
2924
- // present — i.e. the default look has not drifted.
2925
- expect(styleClasses(icon)).toEqual(
2926
- expect.arrayContaining(styleClasses(refIcon)),
2927
- );
2928
- });
2929
-
2930
- it('exposes multi-selector-indicator-icon so a theme reaches the icon size and per-state color', () => {
2931
- // jsdom cannot resolve the @layer cascade, so the DOM-class assertions
2932
- // above (target lands on the icon element) plus this generation assertion
2933
- // (the theme emits same-element icon rules in @layer astryx-theme) together
2934
- // prove the seam: a same-element theme rule wins over the icon's own
2935
- // base-layer color/size.
2936
- const theme = defineTheme({
2937
- name: 'multi-selector-indicator-icon-test',
2938
- components: {
2939
- 'multi-selector-indicator-icon': {
2940
- base: {width: '14px', height: '14px', fontSize: '14px'},
2941
- 'state:expanded': {color: 'var(--color-icon-primary)'},
2942
- },
2943
- },
2944
- });
2945
- const css = generateThemeTestCSS(theme);
2946
- expect(css).toContain('.astryx-multi-selector-indicator-icon {');
2947
- expect(css).toContain('width: 14px');
2948
- expect(css).toContain('height: 14px');
2949
- expect(css).toContain(
2950
- '.astryx-multi-selector-indicator-icon[data-state="expanded"]',
2951
- );
2952
- expect(css).toContain('color: var(--color-icon-primary)');
2953
- });
2954
- });
2955
-
2956
- describe('MultiSelector list structure', () => {
2957
- it('does not draw a divider under select-all', async () => {
2958
- const user = userEvent.setup();
2959
- render(
2960
- <MultiSelector
2961
- label="Fruit"
2962
- options={['Apple', 'Banana', 'Orange']}
2963
- value={[]}
2964
- onChange={() => {}}
2965
- hasSelectAll
2966
- />,
2967
- );
2968
- await user.click(screen.getByRole('combobox'));
2969
- // Select-all is the first row of the list, not a section of its own. No
2970
- // option here declares a divider and there is no search row, so the panel
2971
- // should contain no rule at all.
2972
- expect(document.querySelectorAll('[role="separator"]')).toHaveLength(0);
2973
- const [first] = screen.getAllByRole('option', h);
2974
- expect(first).toHaveTextContent('Select all');
2975
- });
2976
-
2977
- it('renders a section title as a plain heading inside the group, not a divider', async () => {
2978
- const user = userEvent.setup();
2979
- render(
2980
- <MultiSelector
2981
- label="Fruit"
2982
- options={[
2983
- {
2984
- type: 'section',
2985
- title: 'Citrus',
2986
- options: [
2987
- {value: 'orange', label: 'Orange'},
2988
- {value: 'lemon', label: 'Lemon'},
2989
- ],
2990
- },
2991
- ]}
2992
- value={[]}
2993
- onChange={() => {}}
2994
- />,
2995
- );
2996
- await user.click(screen.getByRole('combobox'));
2997
-
2998
- // A labeled Divider used to stand in for the heading; it rendered a
2999
- // role="separator" as a direct child of the listbox and stacked a second
3000
- // rule under the search row's own.
3001
- expect(document.querySelectorAll('[role="separator"]')).toHaveLength(0);
3002
-
3003
- const group = screen.getByRole('group', {name: 'Citrus', ...h});
3004
- const heading = group.querySelector(
3005
- '.astryx-multi-selector-section-heading',
3006
- );
3007
- expect(heading).toBeTruthy();
3008
- expect(heading).toHaveTextContent('Citrus');
3009
- // The group already carries the title as its accessible name, so the
3010
- // visible heading must not announce it a second time.
3011
- expect(heading).toHaveAttribute('aria-hidden', 'true');
3012
- // ...and it precedes the options it heads.
3013
- const [firstOption] = within(group).getAllByRole('option', h);
3014
- expect(
3015
- heading!.compareDocumentPosition(firstOption) &
3016
- Node.DOCUMENT_POSITION_FOLLOWING,
3017
- ).toBeTruthy();
3018
- });
3019
-
3020
- it('hides a standalone divider from the accessibility tree (#4994)', async () => {
3021
- const user = userEvent.setup();
3022
- render(
3023
- <MultiSelector
3024
- label="Fruit"
3025
- options={['Apple', {type: 'divider'}, 'Banana']}
3026
- value={[]}
3027
- onChange={() => {}}
3028
- />,
3029
- );
3030
- await user.click(screen.getByRole('combobox'));
3031
-
3032
- // role="listbox" only permits option/group children. The divider still
3033
- // renders role="separator" (unchanged visual/DOM), but must be excluded
3034
- // from the accessibility tree so it never reaches the listbox's exposed
3035
- // children (axe aria-required-children).
3036
- const divider = document.querySelector('[role="separator"]');
3037
- expect(divider).toBeTruthy();
3038
- expect(divider).toHaveAttribute('aria-hidden', 'true');
3039
- });
3040
- });
3041
-
3042
- describe('MultiSelector search affordances', () => {
3043
- it('renders the search row seamlessly — no nested input box, a divider under it', async () => {
3044
- const user = userEvent.setup();
3045
- render(
3046
- <MultiSelector
3047
- label="Fruit"
3048
- options={['Apple', 'Banana', 'Orange']}
3049
- value={[]}
3050
- onChange={() => {}}
3051
- hasSearch
3052
- />,
3053
- );
3054
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3055
-
3056
- const search = screen.getByRole('combobox', h);
3057
- // The row is the outer gutter; the input sits inside the rounded field.
3058
- const row = search.closest('.astryx-multi-selector-search');
3059
- const field = search.parentElement;
3060
- if (!row || !field) {
3061
- throw new Error('search row not found');
3062
- }
3063
- // The panel is already a bordered surface: the field inside it must not be
3064
- // a second bordered box (this used to render a TextInput).
3065
- expect(row).not.toHaveClass('astryx-text-input');
3066
- expect(search.closest('.astryx-text-input')).toBeNull();
3067
- // The field is a rounded box inset from the panel edge, shaped like the
3068
- // option rows under it — not a full-bleed header strip.
3069
- expect(field).not.toBe(row);
3070
- // ...and a divider separates it from the options.
3071
- const separator = document.querySelector('[role="separator"]');
3072
- if (!separator) {
3073
- throw new Error('divider not found');
3074
- }
3075
- // Order: row, then divider, then the listbox.
3076
- expect(
3077
- row.compareDocumentPosition(separator) & Node.DOCUMENT_POSITION_FOLLOWING,
3078
- ).toBeTruthy();
3079
- const listbox = screen.getByRole('listbox', h);
3080
- expect(
3081
- separator.compareDocumentPosition(listbox) &
3082
- Node.DOCUMENT_POSITION_FOLLOWING,
3083
- ).toBeTruthy();
3084
- });
3085
-
3086
- it('keeps the search row outside the scrolling option list', async () => {
3087
- const user = userEvent.setup();
3088
- render(
3089
- <MultiSelector
3090
- label="Fruit"
3091
- options={['Apple', 'Banana', 'Orange']}
3092
- value={[]}
3093
- onChange={() => {}}
3094
- hasSearch
3095
- />,
3096
- );
3097
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3098
- // The options scroll under the header rather than carrying it away, so the
3099
- // field stays reachable in a long list.
3100
- const search = screen.getByRole('combobox', h);
3101
- const listbox = screen.getByRole('listbox', h);
3102
- expect(listbox.contains(search)).toBe(false);
3103
- });
3104
-
3105
- it('renders a decorative (aria-hidden) magnifier icon whenever hasSearch is on', async () => {
3106
- const user = userEvent.setup();
3107
- render(
3108
- <MultiSelector
3109
- label="Fruit"
3110
- options={['Apple', 'Banana', 'Orange']}
3111
- value={[]}
3112
- onChange={() => {}}
3113
- hasSearch
3114
- />,
3115
- );
3116
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3117
- const search = screen.getByRole('combobox', h);
3118
- // The magnifier leads the search row, as a sibling of the <input>.
3119
- const wrapper = search.parentElement;
3120
- const magnifier = wrapper?.querySelector('.astryx-icon');
3121
- expect(magnifier).toBeTruthy();
3122
- expect(magnifier?.getAttribute('aria-hidden')).toBe('true');
3123
- expect(magnifier?.getAttribute('aria-label')).toBeNull();
3124
- });
3125
-
3126
- it('renders the clear button once a query is typed and clears + refocuses on click', async () => {
3127
- const user = userEvent.setup();
3128
- render(
3129
- <MultiSelector
3130
- label="Fruit"
3131
- options={['Apple', 'Banana', 'Orange']}
3132
- value={[]}
3133
- onChange={() => {}}
3134
- hasSearch
3135
- />,
3136
- );
3137
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3138
- const search = screen.getByRole('combobox', h);
3139
- await user.type(search, 'ap');
3140
- expect(search).toHaveValue('ap');
3141
-
3142
- // The clear button is TextInput's built-in hasClear affordance; its name is
3143
- // derived from the field label ("Search options").
3144
- const clear = screen.getByRole('button', {
3145
- name: 'Clear Search options',
3146
- hidden: true,
3147
- });
3148
-
3149
- await user.click(clear);
3150
- expect(search).toHaveValue('');
3151
- expect(search).toHaveFocus();
3152
- });
3153
-
3154
- it('does not render the clear button when the query is empty', async () => {
3155
- const user = userEvent.setup();
3156
- render(
3157
- <MultiSelector
3158
- label="Fruit"
3159
- options={['Apple', 'Banana', 'Orange']}
3160
- value={[]}
3161
- onChange={() => {}}
3162
- hasSearch
3163
- />,
3164
- );
3165
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3166
- expect(
3167
- screen.queryByRole('button', {
3168
- name: 'Clear Search options',
3169
- hidden: true,
3170
- }),
3171
- ).not.toBeInTheDocument();
3172
- });
3173
-
3174
- it('keeps the combobox contract on the input, not the affordances', async () => {
3175
- const user = userEvent.setup();
3176
- render(
3177
- <MultiSelector
3178
- label="Fruit"
3179
- options={['Apple', 'Banana', 'Orange']}
3180
- value={[]}
3181
- onChange={() => {}}
3182
- hasSearch
3183
- />,
3184
- );
3185
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3186
- const search = screen.getByRole('combobox', h);
3187
- expect(search.tagName).toBe('INPUT');
3188
- expect(search).toHaveAttribute('aria-autocomplete', 'list');
3189
- });
3190
-
3191
- it('tabs from the search input to the clear button (keeping the popup open) when a query is showing it', async () => {
3192
- const user = userEvent.setup();
3193
- render(
3194
- <MultiSelector
3195
- label="Fruit"
3196
- options={['Apple', 'Banana', 'Orange']}
3197
- value={[]}
3198
- onChange={() => {}}
3199
- hasSearch
3200
- />,
3201
- );
3202
- await user.click(screen.getByRole('button', {name: 'Fruit'}));
3203
- const trigger = screen.getByRole('button', {name: 'Fruit'});
3204
- const search = screen.getByRole('combobox', h);
3205
- await user.type(search, 'ap');
3206
- expect(search).toHaveFocus();
3207
-
3208
- // Forward-tab lands on the clear (✕) button and the popup stays open, so
3209
- // the affordance is keyboard-reachable rather than being skipped when the
3210
- // input's Tab dismisses the popup.
3211
- await user.tab();
3212
- const clear = screen.getByRole('button', {
3213
- name: 'Clear Search options',
3214
- hidden: true,
3215
- });
3216
- expect(clear).toHaveFocus();
3217
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
3218
- });
3219
-
3220
- it('dismisses on Tab from the search input when there is no query (no clear button)', async () => {
3221
- const user = userEvent.setup();
3222
- render(
3223
- <MultiSelector
3224
- label="Fruit"
3225
- options={['Apple', 'Banana', 'Orange']}
3226
- value={[]}
3227
- onChange={() => {}}
3228
- hasSearch
3229
- />,
3230
- );
3231
- const trigger = screen.getByRole('button', {name: 'Fruit'});
3232
- await user.click(trigger);
3233
- const search = screen.getByRole('combobox', h);
3234
- // Focus moves into the search input on open (via rAF).
3235
- await waitFor(() => expect(search).toHaveFocus());
3236
-
3237
- // With no query there is no clear button, so Tab dismisses the popup as a
3238
- // plain combobox does.
3239
- await user.tab();
3240
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
3241
- });
3242
- });
3243
-
3244
- describe('MultiSelector disabled state theme target', () => {
3245
- const getSelectorRoot = (container: HTMLElement): HTMLElement => {
3246
- const root = container.querySelector('.astryx-multi-selector');
3247
- if (root == null) {
3248
- throw new Error('multi-selector root not found');
3249
- }
3250
- return root as HTMLElement;
3251
- };
3252
-
3253
- it('reflects data-state="disabled" on the root when disabled', () => {
3254
- const {container} = render(
3255
- <MultiSelector
3256
- label="Fruit"
3257
- options={['Apple', 'Banana', 'Orange']}
3258
- value={[]}
3259
- onChange={() => {}}
3260
- isDisabled
3261
- />,
3262
- );
3263
- expect(getSelectorRoot(container)).toHaveAttribute(
3264
- 'data-disabled',
3265
- 'disabled',
3266
- );
3267
- });
3268
-
3269
- it('omits the disabled class/attribute when enabled', () => {
3270
- const {container} = render(
3271
- <MultiSelector
3272
- label="Fruit"
3273
- options={['Apple', 'Banana', 'Orange']}
3274
- value={[]}
3275
- onChange={() => {}}
3276
- />,
3277
- );
3278
- const root = getSelectorRoot(container);
3279
- expect(root).not.toHaveAttribute('data-disabled');
3280
- expect(root).not.toHaveAttribute('data-disabled');
3281
- });
3282
-
3283
- it('exposes the disabled state so a theme can key on it', () => {
3284
- const theme = defineTheme({
3285
- name: 'multi-selector-disabled-state-test',
3286
- components: {
3287
- 'multi-selector': {
3288
- 'disabled:disabled': {opacity: '0.4'},
3289
- },
3290
- },
3291
- });
3292
- const css = generateThemeTestCSS(theme);
3293
- expect(css).toContain('.astryx-multi-selector[data-disabled="disabled"]');
3294
- expect(css).toContain('opacity: 0.4');
3295
- });
3296
- });
3297
-
3298
- describe('MultiSelector dropdown option theme target', () => {
3299
- const ROW_OPTIONS = ['Apple', 'Banana', 'Orange'];
3300
-
3301
- it('renders astryx-multi-selector-option, with its size, on every dropdown row', async () => {
3302
- const user = userEvent.setup();
3303
- render(
3304
- <MultiSelector
3305
- label="Fruit"
3306
- options={ROW_OPTIONS}
3307
- value={[]}
3308
- onChange={() => {}}
3309
- size="lg"
3310
- />,
3311
- );
3312
- await user.click(screen.getByRole('combobox'));
3313
- const options = screen.getAllByRole('option', h);
3314
- expect(options).toHaveLength(3);
3315
- for (const option of options) {
3316
- expect(option).toHaveClass('astryx-multi-selector-option');
3317
- expect(option).toHaveAttribute('data-size', 'lg');
3318
- expect(option).toHaveAttribute('data-size', 'lg');
3319
- }
3320
- });
3321
-
3322
- it('carries the selected and disabled states a theme keys on', async () => {
3323
- const user = userEvent.setup();
3324
- render(
3325
- <MultiSelector
3326
- label="Fruit"
3327
- options={[
3328
- {value: 'apple', label: 'Apple'},
3329
- {value: 'banana', label: 'Banana'},
3330
- {value: 'orange', label: 'Orange', disabled: true},
3331
- ]}
3332
- value={['apple']}
3333
- onChange={() => {}}
3334
- />,
3335
- );
3336
- await user.click(screen.getByRole('combobox'));
3337
- const [selected, plain, disabled] = screen.getAllByRole('option', h);
3338
-
3339
- expect(selected).toHaveAttribute('data-selected', 'selected');
3340
- expect(selected).toHaveAttribute('data-selected', 'selected');
3341
- expect(plain).not.toHaveAttribute('data-selected');
3342
- expect(plain).not.toHaveAttribute('data-selected');
3343
-
3344
- expect(disabled).toHaveAttribute('data-disabled', 'disabled');
3345
- expect(disabled).toHaveAttribute('data-disabled', 'disabled');
3346
- expect(plain).not.toHaveAttribute('data-disabled');
3347
- });
3348
-
3349
- it('marks the Select All row with the select-all state, not a separate target', async () => {
3350
- const user = userEvent.setup();
3351
- render(
3352
- <MultiSelector
3353
- label="Fruit"
3354
- options={ROW_OPTIONS}
3355
- value={[]}
3356
- onChange={() => {}}
3357
- hasSelectAll
3358
- />,
3359
- );
3360
- await user.click(screen.getByRole('combobox'));
3361
-
3362
- const [selectAllRow, ...regularRows] = screen.getAllByRole('option', h);
3363
- expect(selectAllRow).toHaveTextContent('Select all');
3364
- expect(selectAllRow).toHaveClass('astryx-multi-selector-option');
3365
- expect(selectAllRow).toHaveAttribute('data-select-all', 'select-all');
3366
- expect(selectAllRow).toHaveAttribute('data-select-all', 'select-all');
3367
-
3368
- for (const row of regularRows) {
3369
- expect(row).toHaveClass('astryx-multi-selector-option');
3370
- expect(row).not.toHaveClass('select-all');
3371
- expect(row).not.toHaveAttribute('data-select-all');
3372
- }
3373
- });
3374
-
3375
- it('keeps the row targetable when renderOption replaces the label', async () => {
3376
- const user = userEvent.setup();
3377
- render(
3378
- <MultiSelector
3379
- label="Fruit"
3380
- options={[{value: 'apple', label: 'Apple'}]}
3381
- value={[]}
3382
- onChange={() => {}}
3383
- renderOption={option => (
3384
- <span data-testid="custom-row">{option.label}</span>
3385
- )}
3386
- />,
3387
- );
3388
- await user.click(screen.getByRole('combobox'));
3389
- const option = screen.getAllByRole('option', h)[0];
3390
- // The row owns the typography, so custom content inherits the same
3391
- // treatment the fallback label gets — and one row override reaches both.
3392
- expect(option).toHaveClass('astryx-multi-selector-option');
3393
- expect(within(option).getByTestId('custom-row')).toHaveTextContent('Apple');
3394
- });
3395
-
3396
- it('exposes the row target, its states and its size to defineTheme', () => {
3397
- const theme = defineTheme({
3398
- name: 'multi-selector-option-target-test',
3399
- components: {
3400
- 'multi-selector-option': {
3401
- base: {borderRadius: '8px', fontWeight: '600'},
3402
- selected: {backgroundColor: 'var(--color-background-muted)'},
3403
- 'select-all': {fontWeight: '700'},
3404
- 'size:lg': {borderRadius: '12px'},
3405
- },
3406
- },
3407
- });
3408
- const css = generateThemeTestCSS(theme);
3409
- expect(css).toContain('.astryx-multi-selector-option {');
3410
- expect(css).toContain(
3411
- '.astryx-multi-selector-option[data-selected="selected"]',
3412
- );
3413
- expect(css).toContain(
3414
- '.astryx-multi-selector-option[data-select-all="select-all"]',
3415
- );
3416
- expect(css).toContain('.astryx-multi-selector-option[data-size="lg"]');
3417
- });
3418
- });
3419
-
3420
- describe('MultiSelector popup theme target', () => {
3421
- it('puts astryx-multi-selector-popup on the surface that paints, not the list inside it', async () => {
3422
- const user = userEvent.setup();
3423
- render(
3424
- <MultiSelector
3425
- label="Fruit"
3426
- options={['Apple', 'Banana']}
3427
- value={[]}
3428
- onChange={() => {}}
3429
- />,
3430
- );
3431
- await user.click(screen.getByRole('combobox', {name: /Fruit/}));
3432
-
3433
- const popup = document.querySelector(
3434
- '.astryx-multi-selector-popup',
3435
- ) as HTMLElement;
3436
- expect(popup).not.toBeNull();
3437
- expect(popup).toHaveClass('astryx-popover');
3438
- // The scrolling list is a descendant, not the target itself.
3439
- expect(popup.querySelector('[role="listbox"]')).not.toBeNull();
3440
- expect(popup.getAttribute('role')).toBeNull();
3441
-
3442
- const layer = document.querySelector('[popover]') as HTMLElement;
3443
- expect(popup).not.toBe(layer);
3444
- expect(layer.contains(popup)).toBe(true);
3445
- });
3446
-
3447
- it('stays closed when the trigger click follows its own light dismiss (#5004)', async () => {
3448
- const user = userEvent.setup();
3449
- render(
3450
- <MultiSelector
3451
- label="Fruit"
3452
- options={['Apple', 'Banana', 'Cherry']}
3453
- value={[]}
3454
- onChange={() => {}}
3455
- />,
3456
- );
3457
- const trigger = screen.getByRole('combobox');
3458
- await user.click(trigger);
3459
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
3460
-
3461
- // The browser dismissed the popup on pointerup and queued the toggle. When
3462
- // that event lands before the click — WebKit, or any engine under load —
3463
- // the click used to read a closed popup and reopen it.
3464
- fireEvent.pointerDown(trigger);
3465
- const popover = document.querySelector('[popover]') as HTMLElement;
3466
- act(() => {
3467
- popover.dispatchEvent(
3468
- Object.assign(new Event('toggle'), {
3469
- oldState: 'open',
3470
- newState: 'closed',
3471
- }),
3472
- );
3473
- });
3474
- // Synchronously: the click falls inside the one gesture the guard covers,
3475
- // as it does in a browser a few milliseconds behind the dismissal.
3476
- fireEvent.click(trigger);
3477
-
3478
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
3479
- expect(trigger.parentElement).toHaveClass(
3480
- stylex.props(selectorPresentationStyles.pointerRestoredFocus).className!,
3481
- );
3482
- });
3483
- });
3484
-
3485
- describe('MultiSelector trigger render prop', () => {
3486
- const OPTIONS = [
3487
- {value: 'bug', label: 'Bug'},
3488
- {value: 'feature', label: 'Feature'},
3489
- {value: 'docs', label: 'Docs'},
3490
- ];
3491
-
3492
- it('renders the caller control instead of the field and button', () => {
3493
- render(
3494
- <MultiSelector
3495
- label="Labels"
3496
- options={OPTIONS}
3497
- value={[]}
3498
- onChange={() => {}}
3499
- renderTrigger={props => (
3500
- <button type="button" {...props}>
3501
- Pick labels
3502
- </button>
3503
- )}
3504
- />,
3505
- );
3506
- const opener = screen.getByRole('button', {name: 'Pick labels'});
3507
- expect(opener).toHaveAttribute('aria-haspopup', 'listbox');
3508
- expect(opener).toHaveAttribute('aria-expanded', 'false');
3509
- expect(opener).toHaveAttribute('aria-controls');
3510
- // No field chrome: exactly one button, and no Field label element.
3511
- expect(screen.getAllByRole('button')).toHaveLength(1);
3512
- expect(screen.queryByText('Labels')).toBeNull();
3513
- });
3514
-
3515
- // spec:AST-055 AR3: a light dismiss returns focus to the caller's control,
3516
- // even when the press that closed the list focused another field.
3517
- it('returns focus to the caller control after a light dismiss onto another field', async () => {
3518
- const user = userEvent.setup();
3519
- render(
3520
- <>
3521
- <MultiSelector
3522
- label="Labels"
3523
- options={OPTIONS}
3524
- value={[]}
3525
- onChange={() => {}}
3526
- renderTrigger={props => (
3527
- <button type="button" {...props}>
3528
- Pick labels
3529
- </button>
3530
- )}
3531
- />
3532
- <input aria-label="Notes" />
3533
- </>,
3534
- );
3535
- const opener = screen.getByRole('button', {name: 'Pick labels'});
3536
- await user.click(opener);
3537
- expect(opener).toHaveAttribute('aria-expanded', 'true');
3538
-
3539
- act(() => {
3540
- screen.getByRole('textbox', {name: 'Notes'}).focus();
3541
- });
3542
- const popover = document.querySelector('[popover]') as HTMLElement;
3543
- act(() => {
3544
- popover.dispatchEvent(
3545
- Object.assign(new Event('toggle'), {
3546
- oldState: 'open',
3547
- newState: 'closed',
3548
- }),
3549
- );
3550
- });
3551
-
3552
- expect(opener).toHaveAttribute('aria-expanded', 'false');
3553
- expect(opener).toHaveFocus();
3554
- });
3555
-
3556
- it('opens against the caller control and names the listbox by label', async () => {
3557
- const user = userEvent.setup();
3558
- render(
3559
- <MultiSelector
3560
- label="Labels"
3561
- options={OPTIONS}
3562
- value={['bug']}
3563
- onChange={() => {}}
3564
- renderTrigger={props => (
3565
- <button type="button" {...props}>
3566
- Pick labels
3567
- </button>
3568
- )}
3569
- />,
3570
- );
3571
- const opener = screen.getByRole('button', {name: 'Pick labels'});
3572
- await user.click(opener);
3573
-
3574
- expect(opener).toHaveAttribute('aria-expanded', 'true');
3575
- const listbox = screen.getByRole('listbox', {name: 'Labels', ...h});
3576
- expect(opener.getAttribute('aria-controls')).toBe(listbox.id);
3577
- expect(screen.getAllByRole('option', h)).toHaveLength(3);
3578
- expect(screen.getByRole('option', {name: 'Bug', ...h})).toHaveAttribute(
3579
- 'aria-selected',
3580
- 'true',
3581
- );
3582
- });
3583
-
3584
- it('the listbox owns the keyboard once open and toggles on Enter', async () => {
3585
- const user = userEvent.setup();
3586
- const onChange = vi.fn();
3587
- render(
3588
- <MultiSelector
3589
- label="Labels"
3590
- options={OPTIONS}
3591
- value={[]}
3592
- onChange={onChange}
3593
- renderTrigger={props => (
3594
- <button type="button" {...props}>
3595
- Pick labels
3596
- </button>
3597
- )}
3598
- />,
3599
- );
3600
- await user.click(screen.getByRole('button', {name: 'Pick labels'}));
3601
- const listbox = screen.getByRole('listbox', h);
3602
- expect(listbox).toHaveAttribute('tabindex', '0');
3603
- await waitFor(() => expect(listbox).toHaveFocus());
3604
-
3605
- // Opening by click highlights the first option; Enter toggles it.
3606
- fireEvent.keyDown(listbox, {key: 'ArrowDown'});
3607
- fireEvent.keyDown(listbox, {key: 'Enter'});
3608
- expect(onChange).toHaveBeenCalledWith(['feature']);
3609
- });
3610
-
3611
- it('handleRef opens and closes the panel and onOpenChange reports it', async () => {
3612
- const onOpenChange = vi.fn();
3613
- function Harness() {
3614
- const handleRef = useRef<MultiSelectorHandle>(null);
3615
- return (
3616
- <>
3617
- <button type="button" onClick={() => handleRef.current?.open()}>
3618
- open from outside
3619
- </button>
3620
- <button type="button" onClick={() => handleRef.current?.close()}>
3621
- close from outside
3622
- </button>
3623
- <MultiSelector
3624
- label="Labels"
3625
- options={OPTIONS}
3626
- value={[]}
3627
- onChange={() => {}}
3628
- handleRef={handleRef}
3629
- onOpenChange={onOpenChange}
3630
- renderTrigger={props => (
3631
- <button type="button" {...props}>
3632
- anchor
3633
- </button>
3634
- )}
3635
- />
3636
- </>
3637
- );
3638
- }
3639
- const user = userEvent.setup();
3640
- render(<Harness />);
3641
- const anchor = screen.getByRole('button', {name: 'anchor'});
3642
- expect(anchor).toHaveAttribute('aria-expanded', 'false');
3643
- expect(onOpenChange).not.toHaveBeenCalled();
3644
-
3645
- await user.click(screen.getByRole('button', {name: 'open from outside'}));
3646
- expect(anchor).toHaveAttribute('aria-expanded', 'true');
3647
- expect(onOpenChange).toHaveBeenLastCalledWith(true);
3648
-
3649
- await user.click(screen.getByRole('button', {name: 'close from outside'}));
3650
- await waitFor(() => {
3651
- expect(anchor).toHaveAttribute('aria-expanded', 'false');
3652
- });
3653
- expect(onOpenChange).toHaveBeenLastCalledWith(false);
3654
- expect(onOpenChange).toHaveBeenCalledTimes(2);
3655
- });
3656
-
3657
- it('the handle does not open a disabled selector', () => {
3658
- const handleRef = {current: null as MultiSelectorHandle | null};
3659
- render(
3660
- <MultiSelector
3661
- label="Labels"
3662
- options={OPTIONS}
3663
- value={[]}
3664
- onChange={() => {}}
3665
- isDisabled
3666
- handleRef={handleRef}
3667
- renderTrigger={props => (
3668
- <button type="button" {...props}>
3669
- anchor
3670
- </button>
3671
- )}
3672
- />,
3673
- );
3674
- act(() => {
3675
- handleRef.current?.open();
3676
- });
3677
- expect(handleRef.current?.isOpen()).toBe(false);
3678
- expect(screen.getByRole('button', {name: 'anchor'})).toHaveAttribute(
3679
- 'aria-expanded',
3680
- 'false',
3681
- );
3682
- });
3683
- });
3684
-
3685
- describe('MultiSelector renderTrigger — read-only', () => {
3686
- it("a read-only selector advertises no panel on the caller's control", () => {
3687
- // spec:AST-011 FR4. A read-only selector has no surface to open, so a
3688
- // control that says "collapsed, has popup" sends a screen-reader user
3689
- // to press Enter on something that cannot respond — with nothing to
3690
- // tell them the value is read-only rather than the control broken.
3691
- const onOpen = vi.fn();
3692
- render(
3693
- <MultiSelector
3694
- label="Labels"
3695
- value={['a']}
3696
- onChange={() => {}}
3697
- isReadOnly
3698
- options={[
3699
- {value: 'a', label: 'Alpha'},
3700
- {value: 'b', label: 'Beta'},
3701
- ]}
3702
- renderTrigger={props => (
3703
- <button type="button" {...props} onClick={onOpen}>
3704
- Labels
3705
- </button>
3706
- )}
3707
- />,
3708
- );
3709
-
3710
- const trigger = screen.getByRole('button', {name: 'Labels'});
3711
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
3712
- expect(trigger).not.toHaveAttribute('aria-haspopup');
3713
- expect(trigger).not.toHaveAttribute('aria-controls');
3714
- // Withholding the disclosure attributes stops the control lying about a
3715
- // panel; this says why it does not open, which the field path conveys
3716
- // through chrome the caller's control does not have.
3717
- expect(trigger).toHaveAttribute('aria-readonly', 'true');
3718
- });
3719
-
3720
- it('still advertises the panel when the selector is not read-only', () => {
3721
- render(
3722
- <MultiSelector
3723
- label="Labels"
3724
- value={[]}
3725
- onChange={() => {}}
3726
- options={[{value: 'a', label: 'Alpha'}]}
3727
- renderTrigger={props => (
3728
- <button type="button" {...props}>
3729
- Labels
3730
- </button>
3731
- )}
3732
- />,
3733
- );
3734
-
3735
- const trigger = screen.getByRole('button', {name: 'Labels'});
3736
- expect(trigger).toHaveAttribute('aria-haspopup', 'listbox');
3737
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
3738
- expect(trigger).toHaveAttribute('aria-controls');
3739
- });
3740
- });
3741
-
3742
- describe('MultiSelector renderTrigger — focus return', () => {
3743
- it('returns focus to a control that takes no focus of its own', async () => {
3744
- // A glyph is not keyboard-openable, but when it IS opened by pointer the
3745
- // panel still has to give focus back somewhere the person recognises.
3746
- // Without the fallback focus lands on the body and they lose their place.
3747
- const user = userEvent.setup();
3748
- render(
3749
- <MultiSelector
3750
- label="Labels"
3751
- value={[]}
3752
- onChange={() => {}}
3753
- options={[
3754
- {value: 'a', label: 'Alpha'},
3755
- {value: 'b', label: 'Beta'},
3756
- ]}
3757
- renderTrigger={props => (
3758
- <span {...props} data-testid="glyph">
3759
- #
3760
- </span>
3761
- )}
3762
- />,
3763
- );
3764
-
3765
- const glyph = screen.getByTestId('glyph');
3766
- expect(glyph).toHaveAttribute('tabindex', '-1');
3767
-
3768
- await user.click(glyph);
3769
- await waitFor(() => expect(glyph).toHaveAttribute('aria-expanded', 'true'));
3770
- await user.keyboard('{Escape}');
3771
- await waitFor(() => expect(glyph).toHaveFocus());
3772
- expect(document.body).not.toHaveFocus();
3773
- });
3774
-
3775
- it('leaves a real control\u2019s own focusability alone', () => {
3776
- render(
3777
- <MultiSelector
3778
- label="Labels"
3779
- value={[]}
3780
- onChange={() => {}}
3781
- options={[{value: 'a', label: 'Alpha'}]}
3782
- renderTrigger={props => (
3783
- <button type="button" {...props}>
3784
- Labels
3785
- </button>
3786
- )}
3787
- />,
3788
- );
3789
-
3790
- expect(screen.getByRole('button', {name: 'Labels'})).not.toHaveAttribute(
3791
- 'tabindex',
3792
- );
3793
- });
3794
- });
3795
-
3796
- describe('MultiSelector hasCreate', () => {
3797
- const OPTIONS = [
3798
- {value: 'bug', label: 'Bug'},
3799
- {value: 'feature', label: 'Feature'},
3800
- {value: 'cafe', label: 'Café'},
3801
- ];
3802
-
3803
- it('offers Create "<query>" first and reports the creation through onChange', async () => {
3804
- const user = userEvent.setup();
3805
- const onChange =
3806
- vi.fn<(value: string[], change?: MultiSelectorChange) => void>();
3807
- render(
3808
- <MultiSelector
3809
- label="Labels"
3810
- options={OPTIONS}
3811
- value={['bug']}
3812
- onChange={onChange}
3813
- hasSearch
3814
- hasCreate
3815
- />,
3816
- );
3817
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3818
- const search = screen.getByRole('combobox', h);
3819
- await user.type(search, 'Urgent');
3820
-
3821
- const options = screen.getAllByRole('option', h);
3822
- expect(options).toHaveLength(1);
3823
- expect(options[0]).toHaveTextContent('Create "Urgent"');
3824
- expect(options[0]).toHaveAttribute('aria-selected', 'false');
3825
- expect(options[0].querySelector('input[type="checkbox"]')).toBeNull();
3826
- expect(screen.queryByText('No results found')).toBeNull();
3827
-
3828
- await user.click(options[0]);
3829
- // One update: the query joins the value and the change says it is a
3830
- // creation, so the caller adds the option and accepts the value together.
3831
- expect(onChange).toHaveBeenCalledTimes(1);
3832
- expect(onChange).toHaveBeenCalledWith(['bug', 'Urgent'], {
3833
- type: 'create',
3834
- query: 'Urgent',
3835
- });
3836
- // The filter is cleared so the option the caller adds is visible.
3837
- expect(search).toHaveValue('');
3838
- });
3839
-
3840
- it('a plain toggle passes no descriptor, so a one-argument handler is unchanged', async () => {
3841
- const user = userEvent.setup();
3842
- const onChange = vi.fn();
3843
- render(
3844
- <MultiSelector
3845
- label="Labels"
3846
- options={OPTIONS}
3847
- value={[]}
3848
- onChange={onChange}
3849
- hasSearch
3850
- hasCreate
3851
- />,
3852
- );
3853
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3854
- await user.click(screen.getByRole('option', {name: 'Bug', ...h}));
3855
- expect(onChange).toHaveBeenCalledWith(['bug']);
3856
- expect(onChange.mock.calls[0]).toHaveLength(1);
3857
- });
3858
-
3859
- it('sits above partial matches and is skipped for a label the filter matches exactly', async () => {
3860
- const user = userEvent.setup();
3861
- render(
3862
- <MultiSelector
3863
- label="Labels"
3864
- options={OPTIONS}
3865
- value={[]}
3866
- onChange={() => {}}
3867
- hasSearch
3868
- hasCreate
3869
- />,
3870
- );
3871
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3872
- const search = screen.getByRole('combobox', h);
3873
-
3874
- await user.type(search, 'Bu');
3875
- expect(screen.getAllByRole('option', h).map(o => o.textContent)).toEqual([
3876
- 'Create "Bu"',
3877
- 'Bug',
3878
- ]);
3879
-
3880
- await user.type(search, 'g');
3881
- expect(screen.getAllByRole('option', h).map(o => o.textContent)).toEqual([
3882
- 'Bug',
3883
- ]);
3884
-
3885
- await user.clear(search);
3886
- await user.type(search, 'bug');
3887
- // Case-insensitive, like the filter: "bug" is Bug, so nothing to create.
3888
- expect(screen.getAllByRole('option', h).map(o => o.textContent)).toEqual([
3889
- 'Bug',
3890
- ]);
3891
-
3892
- await user.clear(search);
3893
- await user.type(search, 'CAFE');
3894
- // The duplicate rule is the filter's rule: the filter cannot surface
3895
- // Café for CAFE, so refusing to create would be a dead end.
3896
- expect(screen.getAllByRole('option', h).map(o => o.textContent)).toEqual([
3897
- 'Create "CAFE"',
3898
- ]);
3899
- });
3900
-
3901
- it('leads the select-all row and is not handed to renderOption', async () => {
3902
- const user = userEvent.setup();
3903
- const renderOption = vi.fn((option: {label?: string}) => (
3904
- <span>{`row:${option.label}`}</span>
3905
- ));
3906
- render(
3907
- <MultiSelector
3908
- label="Labels"
3909
- options={OPTIONS}
3910
- value={[]}
3911
- onChange={() => {}}
3912
- hasSearch
3913
- hasSelectAll
3914
- hasCreate
3915
- renderOption={renderOption}
3916
- />,
3917
- );
3918
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3919
- await user.type(screen.getByRole('combobox', h), 'Bu');
3920
- const options = screen.getAllByRole('option', h);
3921
- expect(options[0]).toHaveTextContent('Create "Bu"');
3922
- expect(options[1]).toHaveTextContent('Select all');
3923
- expect(options[2]).toHaveTextContent('row:Bug');
3924
- expect(
3925
- renderOption.mock.calls.some(([option]) =>
3926
- (option.label ?? '').startsWith('Create'),
3927
- ),
3928
- ).toBe(false);
3929
- });
3930
-
3931
- it('Enter with nothing highlighted commits the create row; ArrowDown reaches it', async () => {
3932
- const user = userEvent.setup();
3933
- const onChange = vi.fn();
3934
- render(
3935
- <MultiSelector
3936
- label="Labels"
3937
- options={OPTIONS}
3938
- value={[]}
3939
- onChange={onChange}
3940
- hasSearch
3941
- hasCreate
3942
- />,
3943
- );
3944
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3945
- const search = screen.getByRole('combobox', h);
3946
- await user.type(search, 'Urgent');
3947
- await user.keyboard('{Enter}');
3948
- expect(onChange).toHaveBeenLastCalledWith(['Urgent'], {
3949
- type: 'create',
3950
- query: 'Urgent',
3951
- });
3952
-
3953
- await user.type(search, 'Later');
3954
- fireEvent.keyDown(search, {key: 'ArrowDown'});
3955
- const createRow = screen.getByRole('option', {
3956
- name: 'Create "Later"',
3957
- ...h,
3958
- });
3959
- expect(search).toHaveAttribute('aria-activedescendant', createRow.id);
3960
- fireEvent.keyDown(search, {key: 'Enter'});
3961
- expect(onChange).toHaveBeenLastCalledWith(
3962
- expect.arrayContaining(['Later']),
3963
- {type: 'create', query: 'Later'},
3964
- );
3965
- });
3966
-
3967
- it('offers nothing while isLoading, and Enter commits nothing', async () => {
3968
- const user = userEvent.setup();
3969
- const onChange = vi.fn();
3970
- const {rerender} = render(
3971
- <MultiSelector
3972
- label="Labels"
3973
- options={[]}
3974
- value={[]}
3975
- onChange={onChange}
3976
- hasSearch
3977
- hasCreate
3978
- isLoading
3979
- />,
3980
- );
3981
- await user.click(screen.getByRole('button', {name: 'Labels'}));
3982
- const search = screen.getByRole('combobox', h);
3983
- await user.type(search, 'Bug');
3984
- expect(screen.queryAllByRole('option', h)).toHaveLength(0);
3985
- expect(politeRegion()?.textContent ?? '').toBe('');
3986
- await user.keyboard('{Enter}');
3987
- expect(onChange).not.toHaveBeenCalled();
3988
-
3989
- // The options land: Bug exists, so still no create row for "Bug" — the
3990
- // duplicate the gate was there to prevent.
3991
- rerender(
3992
- <MultiSelector
3993
- label="Labels"
3994
- options={OPTIONS}
3995
- value={[]}
3996
- onChange={onChange}
3997
- hasSearch
3998
- hasCreate
3999
- />,
4000
- );
4001
- expect(screen.getAllByRole('option', h).map(o => o.textContent)).toEqual([
4002
- 'Bug',
4003
- ]);
4004
- });
4005
-
4006
- it('announces the create row, not "No results found", when it is the only result', async () => {
4007
- const user = userEvent.setup();
4008
- render(
4009
- <MultiSelector
4010
- label="Labels"
4011
- options={OPTIONS}
4012
- value={[]}
4013
- onChange={() => {}}
4014
- hasSearch
4015
- hasCreate
4016
- />,
4017
- );
4018
- await user.click(screen.getByRole('button', {name: 'Labels'}));
4019
- await enterQuery(user, screen.getByRole('combobox', h), 'Urgent');
4020
- // The empty-state message is role="presentation", so the live region is
4021
- // what a screen reader gets — it must say what is on screen: a row.
4022
- await waitFor(() => {
4023
- expect(politeRegion()?.textContent).toBe('Create "Urgent"');
4024
- });
4025
- });
4026
-
4027
- it('warns in development and offers nothing when hasCreate is set without hasSearch', async () => {
4028
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
4029
- try {
4030
- const user = userEvent.setup();
4031
- render(
4032
- <MultiSelector
4033
- label="Labels"
4034
- options={OPTIONS}
4035
- value={[]}
4036
- onChange={() => {}}
4037
- hasCreate
4038
- />,
4039
- );
4040
- expect(warn).toHaveBeenCalledWith(
4041
- expect.stringMatching(/MultiSelector[\s\S]*hasSearch/),
4042
- );
4043
- await user.click(screen.getByRole('combobox', {name: 'Labels'}));
4044
- // No search input, no query, no create row: the three real options only.
4045
- expect(
4046
- screen.queryByRole('combobox', {name: /search/i, ...h}),
4047
- ).toBeNull();
4048
- expect(screen.getAllByRole('option', h)).toHaveLength(3);
4049
- } finally {
4050
- warn.mockRestore();
4051
- }
4052
- });
4053
-
4054
- it('is off by default', async () => {
4055
- const user = userEvent.setup();
4056
- render(
4057
- <MultiSelector
4058
- label="Labels"
4059
- options={OPTIONS}
4060
- value={[]}
4061
- onChange={() => {}}
4062
- hasSearch
4063
- />,
4064
- );
4065
- await user.click(screen.getByRole('button', {name: 'Labels'}));
4066
- await user.type(screen.getByRole('combobox', h), 'Urgent');
4067
- expect(screen.queryAllByRole('option', h)).toHaveLength(0);
4068
- expect(screen.getByText('No results found')).toBeInTheDocument();
4069
- });
4070
- });
4071
-
4072
- describe('MultiSelector option actions (grid)', () => {
4073
- const edit = vi.fn();
4074
- const OPTIONS = [
4075
- {
4076
- value: 'bug',
4077
- label: 'Bug',
4078
- action: (
4079
- <button
4080
- type="button"
4081
- onClick={() => {
4082
- edit('bug');
4083
- }}>
4084
- Edit Bug
4085
- </button>
4086
- ),
4087
- },
4088
- {value: 'feature', label: 'Feature'},
4089
- {
4090
- value: 'docs',
4091
- label: 'Docs',
4092
- disabled: true,
4093
- action: (
4094
- <button
4095
- type="button"
4096
- onClick={() => {
4097
- edit('docs');
4098
- }}>
4099
- Edit Docs
4100
- </button>
4101
- ),
4102
- },
4103
- ];
4104
- beforeEach(() => {
4105
- edit.mockClear();
4106
- });
4107
-
4108
- it('stays a listbox when no option carries an action, and action: null is none', async () => {
4109
- const user = userEvent.setup();
4110
- render(
4111
- <MultiSelector
4112
- label="Labels"
4113
- options={[
4114
- {value: 'bug', label: 'Bug', action: null},
4115
- {value: 'feature', label: 'Feature'},
4116
- ]}
4117
- value={[]}
4118
- onChange={() => {}}
4119
- />,
4120
- );
4121
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4122
- expect(trigger).toHaveAttribute('aria-haspopup', 'listbox');
4123
- await user.click(trigger);
4124
- expect(screen.getByRole('listbox', h)).toBeInTheDocument();
4125
- expect(screen.queryByRole('grid', h)).toBeNull();
4126
- expect(screen.getAllByRole('option', h)).toHaveLength(2);
4127
- });
4128
-
4129
- it('is a grid of rows with exactly two gridcells once an option carries an action', async () => {
4130
- const user = userEvent.setup();
4131
- render(
4132
- <MultiSelector
4133
- label="Labels"
4134
- options={OPTIONS}
4135
- value={['bug']}
4136
- onChange={() => {}}
4137
- hasSelectAll
4138
- />,
4139
- );
4140
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4141
- expect(trigger).toHaveAttribute('aria-haspopup', 'grid');
4142
- await user.click(trigger);
4143
-
4144
- const grid = screen.getByRole('grid', h);
4145
- expect(screen.queryByRole('listbox', h)).toBeNull();
4146
- expect(screen.queryByRole('option', h)).toBeNull();
4147
- expect(grid).toHaveAttribute('aria-multiselectable', 'true');
4148
- expect(trigger.getAttribute('aria-controls')).toBe(grid.id);
4149
-
4150
- const rows = screen.getAllByRole('row', h);
4151
- // select-all + 3 options
4152
- expect(rows).toHaveLength(4);
4153
- for (const row of rows) {
4154
- const cells = Array.from(row.children);
4155
- expect(cells).toHaveLength(2);
4156
- expect(cells[0]).toHaveAttribute('role', 'gridcell');
4157
- expect(cells[1]).toHaveAttribute('role', 'gridcell');
4158
- }
4159
- // Every exposed child of the grid is a row.
4160
- expect(
4161
- Array.from(grid.children).every(c => c.getAttribute('role') === 'row'),
4162
- ).toBe(true);
4163
-
4164
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4165
- expect(bug).toHaveAttribute('aria-selected', 'true');
4166
- expect(bug.children[1]).toContainElement(
4167
- screen.getByRole('button', {name: 'Edit Bug', ...h}),
4168
- );
4169
- // Rows without an action, and the select-all row, have an empty cell.
4170
- expect(
4171
- screen.getByRole('row', {name: 'Feature', ...h}).children[1],
4172
- ).toBeEmptyDOMElement();
4173
- expect(rows[0].children[1]).toBeEmptyDOMElement();
4174
- // The row's name is the option; the control keeps its own.
4175
- expect(bug).toHaveAccessibleName('Bug');
4176
- });
4177
-
4178
- it('latches: a query that filters the actioned option out keeps the grid', async () => {
4179
- const user = userEvent.setup();
4180
- const {rerender} = render(
4181
- <MultiSelector
4182
- label="Labels"
4183
- options={OPTIONS}
4184
- value={[]}
4185
- onChange={() => {}}
4186
- hasSearch
4187
- />,
4188
- );
4189
- await user.click(screen.getByRole('button', {name: 'Labels'}));
4190
- expect(screen.getByRole('grid', h)).toBeInTheDocument();
4191
- await user.type(screen.getByRole('combobox', h), 'Feat');
4192
- expect(screen.getAllByRole('row', h).map(r => r.textContent)).toEqual([
4193
- 'Feature',
4194
- ]);
4195
- expect(screen.getByRole('grid', h)).toBeInTheDocument();
4196
- // The action removed on a later render: still a grid.
4197
- rerender(
4198
- <MultiSelector
4199
- label="Labels"
4200
- options={[{value: 'feature', label: 'Feature'}]}
4201
- value={[]}
4202
- onChange={() => {}}
4203
- hasSearch
4204
- />,
4205
- );
4206
- expect(screen.getByRole('grid', h)).toBeInTheDocument();
4207
- });
4208
-
4209
- it('becomes a grid when options arrive after loading, inside a section too', async () => {
4210
- const user = userEvent.setup();
4211
- const {rerender} = render(
4212
- <MultiSelector
4213
- label="Labels"
4214
- options={[]}
4215
- value={[]}
4216
- onChange={() => {}}
4217
- isLoading
4218
- />,
4219
- );
4220
- expect(screen.getByRole('combobox', {name: 'Labels'})).toHaveAttribute(
4221
- 'aria-haspopup',
4222
- 'listbox',
4223
- );
4224
- rerender(
4225
- <MultiSelector
4226
- label="Labels"
4227
- options={[
4228
- {
4229
- type: 'section',
4230
- title: 'Type',
4231
- options: OPTIONS,
4232
- },
4233
- ]}
4234
- value={[]}
4235
- onChange={() => {}}
4236
- />,
4237
- );
4238
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4239
- expect(trigger).toHaveAttribute('aria-haspopup', 'grid');
4240
- await user.click(trigger);
4241
- const group = screen.getByRole('rowgroup', {name: 'Type', ...h});
4242
- expect(screen.queryByRole('group', h)).toBeNull();
4243
- expect(group.querySelectorAll('[role="row"]')).toHaveLength(3);
4244
- });
4245
-
4246
- it('pressing the option cell toggles; pressing the action fires only the action', async () => {
4247
- const user = userEvent.setup();
4248
- const onChange = vi.fn();
4249
- render(
4250
- <MultiSelector
4251
- label="Labels"
4252
- options={OPTIONS}
4253
- value={[]}
4254
- onChange={onChange}
4255
- />,
4256
- );
4257
- await user.click(screen.getByRole('combobox', {name: 'Labels'}));
4258
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4259
- await user.click(bug.children[0]);
4260
- expect(onChange).toHaveBeenCalledWith(['bug']);
4261
-
4262
- onChange.mockClear();
4263
- await user.click(screen.getByRole('button', {name: 'Edit Bug', ...h}));
4264
- expect(edit).toHaveBeenCalledWith('bug');
4265
- expect(onChange).not.toHaveBeenCalled();
4266
- // The panel stays open.
4267
- expect(screen.getByRole('grid', h)).toBeInTheDocument();
4268
-
4269
- // A disabled option's action is the caller's control, still live.
4270
- await user.click(screen.getByRole('button', {name: 'Edit Docs', ...h}));
4271
- expect(edit).toHaveBeenCalledWith('docs');
4272
- expect(onChange).not.toHaveBeenCalled();
4273
- });
4274
-
4275
- it('draws the standard focus ring on the active action cell, from the focus tokens', async () => {
4276
- // jsdom resolves no custom property, so the ring is read from StyleX
4277
- // classes: a class name hashes one property and its value, and the same
4278
- // declaration yields the same class wherever it is written.
4279
- const ring = stylex.create({
4280
- active: {
4281
- outlineWidth: focusVars['--focus-outline-width'],
4282
- outlineStyle: focusVars['--focus-outline-style'],
4283
- outlineColor: focusVars['--focus-outline-color'],
4284
- outlineOffset: focusVars['--focus-outline-offset'],
4285
- },
4286
- });
4287
- const ringClasses = stylex
4288
- .props(ring.active)
4289
- .className!.split(' ')
4290
- .filter(token => /^x[a-z0-9]+$/.test(token));
4291
- expect(ringClasses).toHaveLength(4);
4292
-
4293
- const user = userEvent.setup();
4294
- render(
4295
- <MultiSelector
4296
- label="Labels"
4297
- options={OPTIONS}
4298
- value={[]}
4299
- onChange={() => {}}
4300
- />,
4301
- );
4302
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4303
- await user.click(trigger);
4304
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4305
- const actionCell = bug.children[1] as HTMLElement;
4306
- for (const token of ringClasses) {
4307
- expect(actionCell).not.toHaveClass(token);
4308
- }
4309
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4310
- expect(trigger).toHaveAttribute('aria-activedescendant', actionCell.id);
4311
- for (const token of ringClasses) {
4312
- expect(actionCell).toHaveClass(token);
4313
- }
4314
- });
4315
-
4316
- it('draws no focus ring on an action cell highlighted after pointer input, until a key moves the highlight', async () => {
4317
- const ring = stylex.create({
4318
- active: {
4319
- outlineWidth: focusVars['--focus-outline-width'],
4320
- outlineStyle: focusVars['--focus-outline-style'],
4321
- outlineColor: focusVars['--focus-outline-color'],
4322
- outlineOffset: focusVars['--focus-outline-offset'],
4323
- },
4324
- });
4325
- const ringClasses = stylex
4326
- .props(ring.active)
4327
- .className!.split(' ')
4328
- .filter(token => /^x[a-z0-9]+$/.test(token));
4329
- expect(ringClasses).toHaveLength(4);
4330
-
4331
- const user = userEvent.setup();
4332
- render(
4333
- <MultiSelector
4334
- label="Labels"
4335
- options={OPTIONS}
4336
- value={[]}
4337
- onChange={() => {}}
4338
- />,
4339
- );
4340
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4341
- await user.click(trigger);
4342
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4343
- const actionCell = bug.children[1] as HTMLElement;
4344
- fireEvent.mouseEnter(actionCell);
4345
- // The hover moved the highlight onto the action cell, without the ring.
4346
- expect(trigger).toHaveAttribute('aria-activedescendant', actionCell.id);
4347
- for (const token of ringClasses) {
4348
- expect(actionCell).not.toHaveClass(token);
4349
- }
4350
- // Keyboard navigation back onto the cell draws it.
4351
- fireEvent.keyDown(trigger, {key: 'ArrowLeft'});
4352
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4353
- expect(trigger).toHaveAttribute('aria-activedescendant', actionCell.id);
4354
- for (const token of ringClasses) {
4355
- expect(actionCell).toHaveClass(token);
4356
- }
4357
- });
4358
-
4359
- describe('ring under mixed input', () => {
4360
- const ringClasses = () => {
4361
- const ring = stylex.create({
4362
- active: {
4363
- outlineWidth: focusVars['--focus-outline-width'],
4364
- outlineStyle: focusVars['--focus-outline-style'],
4365
- outlineColor: focusVars['--focus-outline-color'],
4366
- outlineOffset: focusVars['--focus-outline-offset'],
4367
- },
4368
- });
4369
- return stylex
4370
- .props(ring.active)
4371
- .className!.split(' ')
4372
- .filter(token => /^x[a-z0-9]+$/.test(token));
4373
- };
4374
- const hasRing = (cell: HTMLElement) =>
4375
- ringClasses().every(token => cell.classList.contains(token));
4376
-
4377
- async function openWithKeyboardOnBugAction() {
4378
- const user = userEvent.setup();
4379
- render(
4380
- <MultiSelector
4381
- label="Labels"
4382
- options={OPTIONS}
4383
- value={[]}
4384
- onChange={() => {}}
4385
- />,
4386
- );
4387
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4388
- await user.click(trigger);
4389
- const row = (name: string) => screen.getByRole('row', {name, ...h});
4390
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4391
- const bugAction = row('Bug').children[1] as HTMLElement;
4392
- expect(trigger).toHaveAttribute('aria-activedescendant', bugAction.id);
4393
- expect(hasRing(bugAction)).toBe(true);
4394
- return {trigger, row, bugAction};
4395
- }
4396
-
4397
- it('keeps the ring when the pointer crosses a disabled option the highlight ignores', async () => {
4398
- const {trigger, row, bugAction} = await openWithKeyboardOnBugAction();
4399
- fireEvent.mouseEnter(row('Docs').children[0]);
4400
- expect(trigger).toHaveAttribute('aria-activedescendant', bugAction.id);
4401
- expect(hasRing(bugAction)).toBe(true);
4402
- });
4403
-
4404
- it('follows the keyboard modality when a hover moves the highlight to another action', async () => {
4405
- const {trigger, row} = await openWithKeyboardOnBugAction();
4406
- const docsAction = row('Docs').children[1] as HTMLElement;
4407
- fireEvent.mouseEnter(docsAction);
4408
- expect(trigger).toHaveAttribute('aria-activedescendant', docsAction.id);
4409
- expect(hasRing(docsAction)).toBe(true);
4410
- });
4411
-
4412
- it('draws no ring for a modifier chord after pointer input', async () => {
4413
- const user = userEvent.setup();
4414
- render(
4415
- <MultiSelector
4416
- label="Labels"
4417
- options={OPTIONS}
4418
- value={[]}
4419
- onChange={() => {}}
4420
- />,
4421
- );
4422
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4423
- await user.click(trigger);
4424
- const bugAction = screen.getByRole('row', {name: 'Bug', ...h})
4425
- .children[1] as HTMLElement;
4426
- fireEvent.mouseEnter(bugAction);
4427
- expect(hasRing(bugAction)).toBe(false);
4428
- fireEvent.keyDown(trigger, {key: 'ArrowRight', ctrlKey: true});
4429
- expect(hasRing(bugAction)).toBe(false);
4430
- });
4431
- });
4432
-
4433
- it('the inline-end arrow reaches the action cell, Enter fires it, inline-start returns', async () => {
4434
- const user = userEvent.setup();
4435
- const onChange = vi.fn();
4436
- render(
4437
- <MultiSelector
4438
- label="Labels"
4439
- options={OPTIONS}
4440
- value={[]}
4441
- onChange={onChange}
4442
- />,
4443
- );
4444
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4445
- await user.click(trigger);
4446
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4447
- // Click-open highlights the first row, on its option cell.
4448
- expect(trigger).toHaveAttribute('aria-activedescendant', bug.id);
4449
-
4450
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4451
- expect(trigger).toHaveAttribute(
4452
- 'aria-activedescendant',
4453
- bug.children[1].id,
4454
- );
4455
- fireEvent.keyDown(trigger, {key: 'Enter'});
4456
- expect(edit).toHaveBeenCalledWith('bug');
4457
- expect(onChange).not.toHaveBeenCalled();
4458
- // The highlight stays where it was.
4459
- expect(trigger).toHaveAttribute(
4460
- 'aria-activedescendant',
4461
- bug.children[1].id,
4462
- );
4463
-
4464
- fireEvent.keyDown(trigger, {key: 'ArrowLeft'});
4465
- expect(trigger).toHaveAttribute('aria-activedescendant', bug.id);
4466
- fireEvent.keyDown(trigger, {key: 'Enter'});
4467
- expect(onChange).toHaveBeenCalledWith(['bug']);
4468
-
4469
- // A row without an action: the inline-end arrow is a no-op there, and
4470
- // Down from the action cell lands on the next row's option cell.
4471
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4472
- fireEvent.keyDown(trigger, {key: 'ArrowDown'});
4473
- const feature = screen.getByRole('row', {name: 'Feature', ...h});
4474
- expect(trigger).toHaveAttribute('aria-activedescendant', feature.id);
4475
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4476
- expect(trigger).toHaveAttribute('aria-activedescendant', feature.id);
4477
- });
4478
-
4479
- it('follows visual direction under RTL', async () => {
4480
- const user = userEvent.setup();
4481
- const original = window.getComputedStyle;
4482
- const spy = vi
4483
- .spyOn(window, 'getComputedStyle')
4484
- .mockImplementation((el: Element, pseudo?: string | null) => {
4485
- const style = original.call(window, el, pseudo);
4486
- Object.defineProperty(style, 'direction', {value: 'rtl'});
4487
- return style;
4488
- });
4489
- try {
4490
- render(
4491
- <MultiSelector
4492
- label="Labels"
4493
- options={OPTIONS}
4494
- value={[]}
4495
- onChange={() => {}}
4496
- />,
4497
- );
4498
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4499
- await user.click(trigger);
4500
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4501
- fireEvent.keyDown(trigger, {key: 'ArrowRight'});
4502
- expect(trigger).toHaveAttribute('aria-activedescendant', bug.id);
4503
- fireEvent.keyDown(trigger, {key: 'ArrowLeft'});
4504
- expect(trigger).toHaveAttribute(
4505
- 'aria-activedescendant',
4506
- bug.children[1].id,
4507
- );
4508
- } finally {
4509
- spy.mockRestore();
4510
- }
4511
- });
4512
-
4513
- it('with search, Left/Right move the caret until a row is highlighted', async () => {
4514
- const user = userEvent.setup();
4515
- render(
4516
- <MultiSelector
4517
- label="Labels"
4518
- options={OPTIONS}
4519
- value={[]}
4520
- onChange={() => {}}
4521
- hasSearch
4522
- />,
4523
- );
4524
- await user.click(screen.getByRole('button', {name: 'Labels'}));
4525
- const search = screen.getByRole('combobox', h);
4526
- await user.type(search, 'Bu');
4527
- // No row highlighted: the arrow is the input's.
4528
- const right = fireEvent.keyDown(search, {key: 'ArrowRight'});
4529
- expect(right).toBe(true);
4530
- expect(search).not.toHaveAttribute('aria-activedescendant');
4531
-
4532
- fireEvent.keyDown(search, {key: 'ArrowDown'});
4533
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4534
- expect(search).toHaveAttribute('aria-activedescendant', bug.id);
4535
- const moved = fireEvent.keyDown(search, {key: 'ArrowRight'});
4536
- expect(moved).toBe(false);
4537
- expect(search).toHaveAttribute('aria-activedescendant', bug.children[1].id);
4538
- fireEvent.keyDown(search, {key: 'Enter'});
4539
- expect(edit).toHaveBeenCalledWith('bug');
4540
- expect(search).toHaveValue('Bu');
4541
- });
4542
-
4543
- it('hovering the action cell highlights that row on its action cell', async () => {
4544
- const user = userEvent.setup();
4545
- render(
4546
- <MultiSelector
4547
- label="Labels"
4548
- options={OPTIONS}
4549
- value={[]}
4550
- onChange={() => {}}
4551
- />,
4552
- );
4553
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4554
- await user.click(trigger);
4555
- const bug = screen.getByRole('row', {name: 'Bug', ...h});
4556
- const feature = screen.getByRole('row', {name: 'Feature', ...h});
4557
- fireEvent.mouseEnter(feature.children[0]);
4558
- expect(trigger).toHaveAttribute('aria-activedescendant', feature.id);
4559
- fireEvent.mouseEnter(bug.children[1]);
4560
- expect(trigger).toHaveAttribute(
4561
- 'aria-activedescendant',
4562
- bug.children[1].id,
4563
- );
4564
- fireEvent.mouseEnter(bug.children[0]);
4565
- expect(trigger).toHaveAttribute('aria-activedescendant', bug.id);
4566
- });
4567
-
4568
- it('Tab closes the panel as before: no action control is a stop inside it', async () => {
4569
- const user = userEvent.setup();
4570
- render(
4571
- <MultiSelector
4572
- label="Labels"
4573
- options={OPTIONS}
4574
- value={[]}
4575
- onChange={() => {}}
4576
- />,
4577
- );
4578
- const trigger = screen.getByRole('combobox', {name: 'Labels'});
4579
- await user.click(trigger);
4580
- expect(trigger).toHaveAttribute('aria-expanded', 'true');
4581
- fireEvent.keyDown(trigger, {key: 'Tab'});
4582
- await waitFor(() => {
4583
- expect(trigger).toHaveAttribute('aria-expanded', 'false');
4584
- });
4585
- });
4586
-
4587
- it('warns in development about an action control with no accessible name', async () => {
4588
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
4589
- try {
4590
- const user = userEvent.setup();
4591
- render(
4592
- <MultiSelector
4593
- label="Labels"
4594
- options={[
4595
- {value: 'bug', label: 'Bug', action: <button type="button" />},
4596
- ]}
4597
- value={[]}
4598
- onChange={() => {}}
4599
- />,
4600
- );
4601
- await user.click(screen.getByRole('combobox', {name: 'Labels'}));
4602
- expect(warn).toHaveBeenCalledWith(
4603
- expect.stringMatching(/MultiSelector[\s\S]*accessible name/),
4604
- );
4605
- } finally {
4606
- warn.mockRestore();
4607
- }
4608
- });
4609
- });
4610
-
4611
- describe('MultiSelector create row inside a grid', () => {
4612
- it('is a row with exactly two gridcells, the action cell empty, and the arrow stays on the option', async () => {
4613
- // spec:AST-058 FR3: in a grid every row has exactly two cells, and a
4614
- // system-minted row is no exception. The create row has no control of
4615
- // its own, so its action cell is present and empty, and the inline-end
4616
- // arrow has nowhere to go.
4617
- const user = userEvent.setup();
4618
- const onChange =
4619
- vi.fn<(value: string[], change?: MultiSelectorChange) => void>();
4620
- render(
4621
- <MultiSelector
4622
- label="Labels"
4623
- options={[
4624
- {
4625
- value: 'bug',
4626
- label: 'Bug',
4627
- action: <button type="button">Edit Bug</button>,
4628
- },
4629
- {value: 'feature', label: 'Feature'},
4630
- ]}
4631
- value={[]}
4632
- onChange={onChange}
4633
- hasSearch
4634
- hasCreate
4635
- />,
4636
- );
4637
- await user.click(screen.getByRole('button', {name: 'Labels'}));
4638
- const search = screen.getByRole('combobox', {hidden: true});
4639
- await user.type(search, 'Urgent');
4640
-
4641
- const rows = screen.getAllByRole('row', {hidden: true});
4642
- expect(rows).toHaveLength(1);
4643
- const create = rows[0];
4644
- expect(create).toHaveTextContent('Create "Urgent"');
4645
- const cells = Array.from(create.children).filter(
4646
- c => c.getAttribute('role') === 'gridcell',
4647
- );
4648
- expect(cells).toHaveLength(2);
4649
- expect(cells[1]).toBeEmptyDOMElement();
4650
-
4651
- await user.keyboard('{ArrowDown}{ArrowRight}{Enter}');
4652
- expect(onChange).toHaveBeenCalledWith(['Urgent'], {
4653
- type: 'create',
4654
- query: 'Urgent',
4655
- });
4656
- });
4657
- });
4658
-
4659
- describe('MultiSelector in an InputGroup', () => {
4660
- const groupClasses = () =>
4661
- stylex.props(groupStyles.inGroup).className!.split(' ');
4662
- const triggerBox = (name: RegExp) =>
4663
- screen
4664
- .getByRole('combobox', {name})
4665
- .closest('.astryx-multi-selector') as HTMLElement;
4666
-
4667
- it.each(['input', 'secondary'] as const)(
4668
- 'gives a grouped %s trigger the connected group geometry in every position',
4669
- variant => {
4670
- const selector = (label: string) => (
4671
- <MultiSelector
4672
- label={label}
4673
- isLabelHidden
4674
- variant={variant}
4675
- options={['Apple', 'Banana', 'Cherry']}
4676
- value={EMPTY_VALUE}
4677
- onChange={() => {}}
4678
- />
4679
- );
4680
- render(
4681
- <>
4682
- <InputGroup label="First">
4683
- {selector('Fruit first')}
4684
- <InputGroupText>kg</InputGroupText>
4685
- </InputGroup>
4686
- <InputGroup label="Middle">
4687
- <InputGroupText>#</InputGroupText>
4688
- {selector('Fruit middle')}
4689
- <InputGroupText>kg</InputGroupText>
4690
- </InputGroup>
4691
- <InputGroup label="Last">
4692
- <InputGroupText>#</InputGroupText>
4693
- {selector('Fruit last')}
4694
- </InputGroup>
4695
- </>,
4696
- );
4697
-
4698
- // Row height, seam radii, and focus stacking come from these classes;
4699
- // a secondary trigger keeps its fill but not its standalone edges.
4700
- for (const position of ['first', 'middle', 'last']) {
4701
- const classes = new Set(
4702
- triggerBox(new RegExp(`Fruit ${position}`)).className.split(' '),
4703
- );
4704
- expect(groupClasses().every(c => classes.has(c))).toBe(true);
4705
- }
4706
- },
4707
- );
4708
-
4709
- it('keeps a standalone secondary trigger out of the group geometry', () => {
4710
- render(
4711
- <MultiSelector
4712
- label="Fruit"
4713
- variant="secondary"
4714
- options={['Apple', 'Banana', 'Cherry']}
4715
- value={EMPTY_VALUE}
4716
- onChange={() => {}}
4717
- />,
4718
- );
4719
- const classes = new Set(triggerBox(/Fruit/).className.split(' '));
4720
- expect(groupClasses().some(c => classes.has(c))).toBe(false);
4721
- });
4722
- });
4723
-
4724
- describe('MultiSelector caller aria-labelledby', () => {
4725
- const FRUITS = ['Apple', 'Banana', 'Cherry'];
4726
-
4727
- it('names the trigger by its label and a caller aria-labelledby', () => {
4728
- render(
4729
- <>
4730
- <span id="lunch-heading">Lunch</span>
4731
- <MultiSelector
4732
- label="Fruits"
4733
- options={FRUITS}
4734
- value={[]}
4735
- onChange={() => {}}
4736
- aria-labelledby="lunch-heading"
4737
- />
4738
- </>,
4739
- );
4740
- const trigger = screen.getByRole('combobox', {name: 'Fruits Lunch'});
4741
- expect(trigger.getAttribute('aria-labelledby')?.split(' ')).toContain(
4742
- 'lunch-heading',
4743
- );
4744
- });
4745
-
4746
- it('names a grouped trigger by the group, its label, and a caller aria-labelledby', () => {
4747
- render(
4748
- <>
4749
- <span id="lunch-heading">Lunch</span>
4750
- <InputGroup label="Order">
4751
- <MultiSelector
4752
- label="Fruits"
4753
- options={FRUITS}
4754
- value={[]}
4755
- onChange={() => {}}
4756
- aria-labelledby="lunch-heading"
4757
- />
4758
- </InputGroup>
4759
- </>,
4760
- );
4761
- expect(
4762
- screen.getByRole('combobox', {name: 'Order Fruits Lunch'}),
4763
- ).toBeInTheDocument();
4764
- });
4765
-
4766
- it('leaves a standalone trigger named by its label element without a caller aria-labelledby', () => {
4767
- render(
4768
- <MultiSelector
4769
- label="Fruits"
4770
- options={FRUITS}
4771
- value={[]}
4772
- onChange={() => {}}
4773
- />,
4774
- );
4775
- const trigger = screen.getByRole('combobox', {name: 'Fruits'});
4776
- expect(trigger).not.toHaveAttribute('aria-labelledby');
4777
- });
4778
-
4779
- it('still hands a caller aria-labelledby to a renderTrigger control unchanged', () => {
4780
- render(
4781
- <>
4782
- <span id="lunch-heading">Lunch</span>
4783
- <MultiSelector
4784
- label="Fruits"
4785
- options={FRUITS}
4786
- value={[]}
4787
- onChange={() => {}}
4788
- aria-labelledby="lunch-heading"
4789
- renderTrigger={props => (
4790
- <button type="button" {...props}>
4791
- Pick fruits
4792
- </button>
4793
- )}
4794
- />
4795
- </>,
4796
- );
4797
- const opener = screen.getByRole('button', {name: 'Lunch'});
4798
- expect(opener).toHaveAttribute('aria-labelledby', 'lunch-heading');
4799
- });
4800
-
4801
- it("leaves a renderTrigger control's own aria-labelledby in place without a caller value", () => {
4802
- render(
4803
- <>
4804
- <span id="row-title">Lunch fruits</span>
4805
- <MultiSelector
4806
- label="Fruits"
4807
- options={FRUITS}
4808
- value={[]}
4809
- onChange={() => {}}
4810
- renderTrigger={props => (
4811
- <button type="button" aria-labelledby="row-title" {...props} />
4812
- )}
4813
- />
4814
- </>,
4815
- );
4816
- const opener = screen.getByRole('button', {name: 'Lunch fruits'});
4817
- expect(opener).toHaveAttribute('aria-labelledby', 'row-title');
4818
- });
4819
- });