@astryxdesign/core 0.1.8 → 0.1.9-canary.02ef052

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 (728) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +6 -2
  4. package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
  5. package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
  6. package/dist/Avatar/Avatar.d.ts +58 -3
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +240 -53
  9. package/dist/Avatar/AvatarStatusDot.d.ts +35 -5
  10. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  11. package/dist/Avatar/AvatarStatusDot.js +144 -19
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  15. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  16. package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
  17. package/dist/Banner/Banner.d.ts +9 -1
  18. package/dist/Banner/Banner.d.ts.map +1 -1
  19. package/dist/Banner/Banner.js +33 -4
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
  21. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  22. package/dist/Breadcrumbs/BreadcrumbItem.js +215 -6
  23. package/dist/Breadcrumbs/index.d.ts +6 -0
  24. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  25. package/dist/Breadcrumbs/index.js +10 -1
  26. package/dist/Button/Button.d.ts +8 -2
  27. package/dist/Button/Button.d.ts.map +1 -1
  28. package/dist/Button/Button.js +33 -4
  29. package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
  30. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  31. package/dist/ButtonGroup/ButtonGroup.js +30 -1
  32. package/dist/Calendar/Calendar.d.ts.map +1 -1
  33. package/dist/Calendar/Calendar.js +80 -11
  34. package/dist/Calendar/dayCellUtils.d.ts +4 -4
  35. package/dist/Calendar/dayCellUtils.js +3 -3
  36. package/dist/Calendar/styles.d.ts +30 -31
  37. package/dist/Calendar/styles.d.ts.map +1 -1
  38. package/dist/Calendar/styles.js +30 -31
  39. package/dist/Card/Card.d.ts +8 -2
  40. package/dist/Card/Card.d.ts.map +1 -1
  41. package/dist/Card/Card.js +28 -2
  42. package/dist/Carousel/Carousel.d.ts +4 -1
  43. package/dist/Carousel/Carousel.d.ts.map +1 -1
  44. package/dist/Carousel/Carousel.js +46 -16
  45. package/dist/Chat/ChatComposer.d.ts +8 -0
  46. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  47. package/dist/Chat/ChatComposer.js +46 -7
  48. package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
  49. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  50. package/dist/Chat/ChatComposerDrawer.js +11 -1
  51. package/dist/Chat/ChatComposerInput.d.ts +20 -3
  52. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  53. package/dist/Chat/ChatComposerInput.js +36 -4
  54. package/dist/Chat/ChatContext.d.ts +33 -0
  55. package/dist/Chat/ChatContext.d.ts.map +1 -1
  56. package/dist/Chat/ChatContext.js +16 -2
  57. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  58. package/dist/Chat/ChatDictationButton.js +4 -2
  59. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  60. package/dist/Chat/ChatLayout.js +4 -4
  61. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  62. package/dist/Chat/ChatLayoutScrollButton.js +4 -4
  63. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  64. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  65. package/dist/Chat/ChatSendButton.js +7 -1
  66. package/dist/Chat/ChatToolCalls.d.ts +5 -1
  67. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  68. package/dist/Chat/ChatToolCalls.js +27 -11
  69. package/dist/Chat/index.d.ts +2 -1
  70. package/dist/Chat/index.d.ts.map +1 -1
  71. package/dist/Chat/index.js +1 -1
  72. package/dist/Chat/useChatStreamScroll.d.ts +2 -1
  73. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  74. package/dist/Chat/useChatStreamScroll.js +22 -8
  75. package/dist/Chat/useSpeechRecognition.d.ts +0 -1
  76. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  77. package/dist/Chat/useSpeechRecognition.js +1 -1
  78. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  79. package/dist/Chat/useTriggerMenu.js +2 -2
  80. package/dist/CheckboxInput/CheckboxInput.js +5 -5
  81. package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
  82. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  83. package/dist/CheckboxList/CheckboxListItem.js +11 -1
  84. package/dist/Citation/Citation.d.ts +22 -1
  85. package/dist/Citation/Citation.d.ts.map +1 -1
  86. package/dist/Citation/Citation.js +20 -6
  87. package/dist/ClickableCard/ClickableCard.d.ts +9 -2
  88. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  89. package/dist/ClickableCard/ClickableCard.js +5 -2
  90. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  91. package/dist/CodeBlock/CodeBlock.js +22 -9
  92. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  93. package/dist/Collapsible/Collapsible.js +3 -1
  94. package/dist/CommandPalette/CommandPalette.d.ts +2 -2
  95. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  96. package/dist/CommandPalette/CommandPalette.js +45 -4
  97. package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
  98. package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
  99. package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
  100. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  101. package/dist/CommandPalette/CommandPaletteInput.js +6 -1
  102. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  103. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  104. package/dist/ContextMenu/ContextMenu.js +14 -5
  105. package/dist/ContextMenu/index.d.ts +1 -0
  106. package/dist/ContextMenu/index.d.ts.map +1 -1
  107. package/dist/ContextMenu/index.js +3 -1
  108. package/dist/DateInput/DateInput.d.ts +56 -2
  109. package/dist/DateInput/DateInput.d.ts.map +1 -1
  110. package/dist/DateInput/DateInput.js +59 -21
  111. package/dist/DateInput/index.d.ts +1 -1
  112. package/dist/DateInput/index.d.ts.map +1 -1
  113. package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
  114. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  115. package/dist/DateRangeInput/DateRangeInput.js +23 -20
  116. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  117. package/dist/DateTimeInput/DateTimeInput.js +33 -19
  118. package/dist/Dialog/Dialog.d.ts +3 -0
  119. package/dist/Dialog/Dialog.d.ts.map +1 -1
  120. package/dist/Dialog/Dialog.js +57 -6
  121. package/dist/Dialog/DialogContext.d.ts +7 -0
  122. package/dist/Dialog/DialogContext.d.ts.map +1 -1
  123. package/dist/Dialog/DialogContext.js +2 -2
  124. package/dist/Dialog/DialogHeader.d.ts +5 -2
  125. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  126. package/dist/Dialog/DialogHeader.js +6 -1
  127. package/dist/Divider/Divider.js +1 -1
  128. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  129. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  130. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  131. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
  132. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  133. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +5 -3
  134. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  135. package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
  136. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
  137. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  138. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
  139. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  140. package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
  141. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  142. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  143. package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
  144. package/dist/DropdownMenu/index.d.ts +10 -0
  145. package/dist/DropdownMenu/index.d.ts.map +1 -1
  146. package/dist/DropdownMenu/index.js +13 -0
  147. package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
  148. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  149. package/dist/DropdownMenu/menuItemHover.js +33 -0
  150. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  151. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  152. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  153. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  154. package/dist/DropdownMenu/renderDropdownItems.js +21 -6
  155. package/dist/Field/Field.d.ts +3 -1
  156. package/dist/Field/Field.d.ts.map +1 -1
  157. package/dist/Field/Field.js +6 -4
  158. package/dist/Field/FieldLabel.d.ts +1 -1
  159. package/dist/Field/FieldLabel.d.ts.map +1 -1
  160. package/dist/Field/FieldLabel.js +43 -16
  161. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  162. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  163. package/dist/Field/inputStyles.stylex.js +1 -0
  164. package/dist/FieldStatus/FieldStatus.d.ts +18 -0
  165. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  166. package/dist/FieldStatus/FieldStatus.js +60 -6
  167. package/dist/FileInput/FileInput.d.ts +10 -2
  168. package/dist/FileInput/FileInput.d.ts.map +1 -1
  169. package/dist/FileInput/FileInput.js +54 -35
  170. package/dist/HoverCard/HoverCard.d.ts +9 -1
  171. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  172. package/dist/HoverCard/HoverCard.js +2 -0
  173. package/dist/HoverCard/useHoverCard.d.ts +8 -0
  174. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  175. package/dist/HoverCard/useHoverCard.js +17 -6
  176. package/dist/Icon/Icon.d.ts +22 -3
  177. package/dist/Icon/Icon.d.ts.map +1 -1
  178. package/dist/Icon/Icon.js +19 -3
  179. package/dist/Item/Item.d.ts +6 -1
  180. package/dist/Item/Item.d.ts.map +1 -1
  181. package/dist/Item/Item.js +22 -1
  182. package/dist/Layer/useLayer.d.ts +6 -0
  183. package/dist/Layer/useLayer.d.ts.map +1 -1
  184. package/dist/Layer/useLayer.js +2 -0
  185. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  186. package/dist/Lightbox/Lightbox.js +19 -13
  187. package/dist/Markdown/Markdown.d.ts.map +1 -1
  188. package/dist/Markdown/Markdown.js +7 -0
  189. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  190. package/dist/MobileNav/MobileNav.js +6 -1
  191. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  192. package/dist/MobileNav/MobileNavToggle.js +4 -0
  193. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  194. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  195. package/dist/MultiSelector/MultiSelector.js +104 -50
  196. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  197. package/dist/MultiSelector/hooks.js +16 -0
  198. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  199. package/dist/NumberInput/NumberInput.d.ts +10 -2
  200. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  201. package/dist/NumberInput/NumberInput.js +22 -17
  202. package/dist/Outline/Outline.d.ts +0 -1
  203. package/dist/Outline/Outline.d.ts.map +1 -1
  204. package/dist/Outline/Outline.js +0 -1
  205. package/dist/OverflowList/OverflowList.d.ts +20 -3
  206. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  207. package/dist/OverflowList/OverflowList.js +29 -4
  208. package/dist/Pagination/Pagination.d.ts.map +1 -1
  209. package/dist/Pagination/Pagination.js +11 -3
  210. package/dist/Popover/Popover.d.ts.map +1 -1
  211. package/dist/Popover/Popover.js +3 -2
  212. package/dist/Popover/usePopover.d.ts.map +1 -1
  213. package/dist/Popover/usePopover.js +3 -9
  214. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  215. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  216. package/dist/PowerSearch/PowerSearch.js +2 -0
  217. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  218. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  219. package/dist/RadioList/RadioList.d.ts +2 -2
  220. package/dist/RadioList/RadioListItem.js +4 -4
  221. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  222. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  223. package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
  224. package/dist/SelectableCard/SelectableCard.d.ts +9 -2
  225. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  226. package/dist/SelectableCard/SelectableCard.js +16 -13
  227. package/dist/Selector/Selector.d.ts +8 -0
  228. package/dist/Selector/Selector.d.ts.map +1 -1
  229. package/dist/Selector/Selector.js +65 -19
  230. package/dist/Selector/hooks.d.ts.map +1 -1
  231. package/dist/Selector/hooks.js +16 -0
  232. package/dist/SideNav/SideNav.d.ts.map +1 -1
  233. package/dist/SideNav/SideNav.js +5 -5
  234. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  235. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  236. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  237. package/dist/SideNav/SideNavHeading.js +21 -8
  238. package/dist/SideNav/SideNavItem.d.ts +1 -1
  239. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  240. package/dist/SideNav/SideNavItem.js +12 -10
  241. package/dist/Slider/Slider.d.ts.map +1 -1
  242. package/dist/Slider/Slider.js +106 -36
  243. package/dist/Stack/stack.stylex.d.ts +9 -9
  244. package/dist/Switch/Switch.d.ts +8 -1
  245. package/dist/Switch/Switch.d.ts.map +1 -1
  246. package/dist/Switch/Switch.js +160 -91
  247. package/dist/TabList/Tab.js +2 -2
  248. package/dist/TabList/TabMenu.js +1 -1
  249. package/dist/Table/BaseTable.d.ts.map +1 -1
  250. package/dist/Table/BaseTable.js +33 -6
  251. package/dist/Table/TableCell.js +3 -3
  252. package/dist/Table/TableHeaderCell.js +3 -3
  253. package/dist/Table/index.d.ts +2 -0
  254. package/dist/Table/index.d.ts.map +1 -1
  255. package/dist/Table/index.js +1 -0
  256. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  257. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  258. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  259. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
  260. package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
  261. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
  262. package/dist/Table/plugins/rowStatus/index.js +3 -0
  263. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
  264. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
  265. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
  266. package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
  267. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  268. package/dist/Table/plugins/selection/useTableSelection.js +7 -1
  269. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
  270. package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
  271. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  272. package/dist/Table/plugins/tree/useTableTreeData.js +105 -12
  273. package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
  274. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
  275. package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
  276. package/dist/Table/types.d.ts +32 -0
  277. package/dist/Table/types.d.ts.map +1 -1
  278. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  279. package/dist/Table/useBaseTablePlugins.js +5 -3
  280. package/dist/TextArea/TextArea.d.ts +10 -1
  281. package/dist/TextArea/TextArea.d.ts.map +1 -1
  282. package/dist/TextArea/TextArea.js +18 -19
  283. package/dist/TextInput/TextInput.d.ts +10 -2
  284. package/dist/TextInput/TextInput.d.ts.map +1 -1
  285. package/dist/TextInput/TextInput.js +20 -17
  286. package/dist/Thumbnail/Thumbnail.d.ts +26 -5
  287. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  288. package/dist/Thumbnail/Thumbnail.js +97 -54
  289. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
  290. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
  291. package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
  292. package/dist/TimeInput/TimeInput.d.ts +10 -2
  293. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  294. package/dist/TimeInput/TimeInput.js +32 -21
  295. package/dist/Timestamp/Timestamp.d.ts +3 -1
  296. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  297. package/dist/Timestamp/Timestamp.js +8 -6
  298. package/dist/Toast/useToast.d.ts.map +1 -1
  299. package/dist/Toast/useToast.js +2 -5
  300. package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
  301. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  302. package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
  303. package/dist/Token/Token.d.ts +30 -3
  304. package/dist/Token/Token.d.ts.map +1 -1
  305. package/dist/Token/Token.js +17 -2
  306. package/dist/Token/index.d.ts +1 -1
  307. package/dist/Token/index.d.ts.map +1 -1
  308. package/dist/Tokenizer/Tokenizer.d.ts +10 -3
  309. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  310. package/dist/Tokenizer/Tokenizer.js +20 -6
  311. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  312. package/dist/Tooltip/useTooltip.js +17 -1
  313. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  314. package/dist/TopNav/TopNavHeading.js +18 -8
  315. package/dist/TopNav/TopNavMegaMenu.js +10 -4
  316. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
  317. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  318. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
  319. package/dist/TopNav/TopNavMenu.d.ts +2 -1
  320. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  321. package/dist/TopNav/TopNavMenu.js +68 -6
  322. package/dist/TreeList/TreeList.d.ts +12 -3
  323. package/dist/TreeList/TreeList.d.ts.map +1 -1
  324. package/dist/TreeList/TreeList.js +3 -0
  325. package/dist/TreeList/TreeListBranches.d.ts +5 -0
  326. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  327. package/dist/TreeList/TreeListBranches.js +18 -10
  328. package/dist/TreeList/TreeListItem.d.ts +8 -2
  329. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  330. package/dist/TreeList/TreeListItem.js +59 -21
  331. package/dist/TreeList/TreeListTypes.d.ts +25 -1
  332. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  333. package/dist/TreeList/index.d.ts +2 -2
  334. package/dist/TreeList/index.d.ts.map +1 -1
  335. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  336. package/dist/Typeahead/BaseTypeahead.js +20 -11
  337. package/dist/Typeahead/Typeahead.d.ts +9 -2
  338. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  339. package/dist/Typeahead/Typeahead.js +3 -1
  340. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  341. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  342. package/dist/Typeahead/TypeaheadItem.js +20 -10
  343. package/dist/astryx.css +61 -39
  344. package/dist/astryx.umd.js +53 -53
  345. package/dist/astryx.umd.js.map +4 -4
  346. package/dist/authoring/doc.d.ts.map +1 -1
  347. package/dist/docs-types.d.ts +8 -0
  348. package/dist/docs-types.d.ts.map +1 -1
  349. package/dist/hooks/computeOverflow.d.ts +47 -0
  350. package/dist/hooks/computeOverflow.d.ts.map +1 -0
  351. package/dist/hooks/computeOverflow.js +213 -0
  352. package/dist/hooks/index.d.ts +3 -0
  353. package/dist/hooks/index.d.ts.map +1 -1
  354. package/dist/hooks/index.js +3 -1
  355. package/dist/hooks/isRtlElement.d.ts +18 -0
  356. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  357. package/dist/hooks/isRtlElement.js +27 -0
  358. package/dist/hooks/useDevWarning.d.ts +18 -0
  359. package/dist/hooks/useDevWarning.d.ts.map +1 -0
  360. package/dist/hooks/useDevWarning.js +49 -0
  361. package/dist/hooks/useGridFocus.d.ts +6 -1
  362. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  363. package/dist/hooks/useGridFocus.js +12 -9
  364. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  365. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  366. package/dist/hooks/useInputStatusIcon.js +158 -0
  367. package/dist/hooks/useListFocus.d.ts +39 -1
  368. package/dist/hooks/useListFocus.d.ts.map +1 -1
  369. package/dist/hooks/useListFocus.js +54 -9
  370. package/dist/hooks/useOverflow.d.ts +19 -0
  371. package/dist/hooks/useOverflow.d.ts.map +1 -1
  372. package/dist/hooks/useOverflow.js +36 -25
  373. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  374. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  375. package/dist/i18n/InternationalizationContext.js +3 -0
  376. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  377. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  378. package/dist/i18n/InternationalizationProvider.js +5 -1
  379. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  380. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  381. package/dist/i18n/getLocaleDirection.js +29 -0
  382. package/dist/i18n/index.d.ts +6 -0
  383. package/dist/i18n/index.d.ts.map +1 -1
  384. package/dist/i18n/index.js +7 -1
  385. package/dist/i18n/resolve.d.ts.map +1 -1
  386. package/dist/i18n/resolve.js +7 -18
  387. package/dist/i18n/useDirection.d.ts +2 -0
  388. package/dist/i18n/useDirection.d.ts.map +1 -0
  389. package/dist/i18n/useDirection.js +27 -0
  390. package/dist/theme/Theme.d.ts.map +1 -1
  391. package/dist/theme/Theme.js +2 -7
  392. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  393. package/dist/theme/derivedVarRegistry.js +13 -0
  394. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  395. package/dist/theme/generateThemeRules.js +51 -0
  396. package/dist/theme/hct.d.ts +0 -1
  397. package/dist/theme/hct.d.ts.map +1 -1
  398. package/dist/theme/hct.js +1 -1
  399. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  400. package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
  401. package/dist/utils/devWarning.d.ts +42 -0
  402. package/dist/utils/devWarning.d.ts.map +1 -0
  403. package/dist/utils/devWarning.js +88 -0
  404. package/dist/utils/index.d.ts +4 -1
  405. package/dist/utils/index.d.ts.map +1 -1
  406. package/dist/utils/index.js +4 -2
  407. package/dist/utils/plainDate.d.ts +30 -0
  408. package/dist/utils/plainDate.d.ts.map +1 -1
  409. package/dist/utils/plainDate.js +65 -3
  410. package/dist/utils/rtlStyles.d.ts +24 -0
  411. package/dist/utils/rtlStyles.d.ts.map +1 -0
  412. package/dist/utils/rtlStyles.js +27 -0
  413. package/dist/utils/types.d.ts +13 -0
  414. package/dist/utils/types.d.ts.map +1 -1
  415. package/locales/en.json +104 -0
  416. package/locales/fr-FR.json +14 -0
  417. package/locales/pseudo.json +78 -0
  418. package/package.json +6 -1
  419. package/src/AppShell/AppShell.tsx +6 -0
  420. package/src/AppShell/AppShellMobileContext.tsx +8 -0
  421. package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
  422. package/src/Avatar/Avatar.doc.mjs +64 -5
  423. package/src/Avatar/Avatar.test.tsx +374 -1
  424. package/src/Avatar/Avatar.tsx +367 -69
  425. package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
  426. package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
  427. package/src/Avatar/AvatarStatusDot.tsx +180 -21
  428. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  429. package/src/AvatarGroup/AvatarGroup.test.tsx +141 -1
  430. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  431. package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
  432. package/src/Banner/Banner.doc.mjs +9 -0
  433. package/src/Banner/Banner.test.tsx +30 -0
  434. package/src/Banner/Banner.tsx +53 -9
  435. package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
  436. package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
  437. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
  438. package/src/Breadcrumbs/Breadcrumbs.test.tsx +335 -2
  439. package/src/Breadcrumbs/index.ts +31 -0
  440. package/src/Button/Button.doc.mjs +9 -4
  441. package/src/Button/Button.test.tsx +49 -0
  442. package/src/Button/Button.tsx +27 -3
  443. package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
  444. package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
  445. package/src/ButtonGroup/ButtonGroup.tsx +32 -0
  446. package/src/Calendar/Calendar.doc.mjs +12 -1
  447. package/src/Calendar/Calendar.test.tsx +362 -19
  448. package/src/Calendar/Calendar.tsx +111 -32
  449. package/src/Calendar/dayCellUtils.test.ts +23 -18
  450. package/src/Calendar/dayCellUtils.ts +3 -3
  451. package/src/Calendar/styles.ts +33 -39
  452. package/src/Card/Card.doc.mjs +9 -0
  453. package/src/Card/Card.test.tsx +21 -3
  454. package/src/Card/Card.tsx +35 -2
  455. package/src/Carousel/Carousel.doc.mjs +1 -0
  456. package/src/Carousel/Carousel.test.tsx +53 -0
  457. package/src/Carousel/Carousel.tsx +59 -10
  458. package/src/Chat/ChatComposer.doc.mjs +12 -3
  459. package/src/Chat/ChatComposer.test.tsx +115 -0
  460. package/src/Chat/ChatComposer.tsx +73 -9
  461. package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
  462. package/src/Chat/ChatComposerDrawer.tsx +11 -1
  463. package/src/Chat/ChatComposerInput.doc.mjs +7 -0
  464. package/src/Chat/ChatComposerInput.test.tsx +103 -0
  465. package/src/Chat/ChatComposerInput.tsx +51 -5
  466. package/src/Chat/ChatContext.tsx +37 -10
  467. package/src/Chat/ChatDictationButton.tsx +11 -2
  468. package/src/Chat/ChatLayout.tsx +7 -5
  469. package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
  470. package/src/Chat/ChatMessageMetadata.tsx +1 -2
  471. package/src/Chat/ChatSendButton.tsx +11 -1
  472. package/src/Chat/ChatToolCalls.test.tsx +64 -0
  473. package/src/Chat/ChatToolCalls.tsx +33 -5
  474. package/src/Chat/index.ts +5 -1
  475. package/src/Chat/useChatStreamScroll.test.tsx +49 -0
  476. package/src/Chat/useChatStreamScroll.ts +27 -10
  477. package/src/Chat/useSpeechRecognition.ts +1 -1
  478. package/src/Chat/useTriggerMenu.tsx +4 -2
  479. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  480. package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
  481. package/src/CheckboxInput/CheckboxInput.tsx +5 -5
  482. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  483. package/src/CheckboxList/CheckboxList.test.tsx +81 -3
  484. package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
  485. package/src/CheckboxList/CheckboxListItem.tsx +41 -5
  486. package/src/Citation/Citation.doc.mjs +4 -3
  487. package/src/Citation/Citation.test.tsx +97 -0
  488. package/src/Citation/Citation.tsx +43 -11
  489. package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
  490. package/src/ClickableCard/ClickableCard.test.tsx +34 -0
  491. package/src/ClickableCard/ClickableCard.tsx +13 -3
  492. package/src/CodeBlock/CodeBlock.test.tsx +56 -0
  493. package/src/CodeBlock/CodeBlock.tsx +45 -10
  494. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  495. package/src/Collapsible/Collapsible.test.tsx +7 -0
  496. package/src/Collapsible/Collapsible.tsx +16 -6
  497. package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
  498. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  499. package/src/CommandPalette/CommandPalette.tsx +44 -3
  500. package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
  501. package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
  502. package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
  503. package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
  504. package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
  505. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  506. package/src/ContextMenu/ContextMenu.test.tsx +235 -0
  507. package/src/ContextMenu/ContextMenu.tsx +13 -11
  508. package/src/ContextMenu/index.ts +5 -0
  509. package/src/DateInput/DateInput.doc.mjs +41 -0
  510. package/src/DateInput/DateInput.test.tsx +338 -0
  511. package/src/DateInput/DateInput.tsx +119 -32
  512. package/src/DateInput/index.ts +1 -0
  513. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  514. package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
  515. package/src/DateRangeInput/DateRangeInput.tsx +42 -30
  516. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  517. package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
  518. package/src/DateTimeInput/DateTimeInput.tsx +58 -41
  519. package/src/Dialog/Dialog.doc.mjs +2 -2
  520. package/src/Dialog/Dialog.test.tsx +77 -4
  521. package/src/Dialog/Dialog.tsx +89 -5
  522. package/src/Dialog/DialogContext.ts +9 -2
  523. package/src/Dialog/DialogHeader.doc.mjs +2 -2
  524. package/src/Dialog/DialogHeader.tsx +9 -2
  525. package/src/Divider/Divider.tsx +2 -2
  526. package/src/DropdownMenu/DropdownMenu.test.tsx +229 -0
  527. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  528. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +9 -4
  529. package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
  530. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
  531. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
  532. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  533. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
  534. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
  535. package/src/DropdownMenu/index.ts +16 -0
  536. package/src/DropdownMenu/menuItemHover.ts +39 -0
  537. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  538. package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
  539. package/src/Field/Field.test.tsx +57 -12
  540. package/src/Field/Field.tsx +20 -14
  541. package/src/Field/FieldLabel.tsx +9 -1
  542. package/src/Field/inputStyles.stylex.ts +2 -0
  543. package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
  544. package/src/FieldStatus/FieldStatus.test.tsx +150 -40
  545. package/src/FieldStatus/FieldStatus.tsx +69 -5
  546. package/src/FileInput/FileInput.doc.mjs +23 -2
  547. package/src/FileInput/FileInput.test.tsx +135 -12
  548. package/src/FileInput/FileInput.tsx +65 -51
  549. package/src/HoverCard/HoverCard.doc.mjs +13 -0
  550. package/src/HoverCard/HoverCard.test.tsx +21 -2
  551. package/src/HoverCard/HoverCard.tsx +11 -0
  552. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  553. package/src/HoverCard/useHoverCard.tsx +39 -5
  554. package/src/Icon/Icon.doc.mjs +16 -2
  555. package/src/Icon/Icon.test.tsx +89 -0
  556. package/src/Icon/Icon.tsx +58 -5
  557. package/src/IconButton/IconButton.doc.mjs +8 -0
  558. package/src/IconButton/IconButton.test.tsx +15 -18
  559. package/src/Item/Item.test.tsx +40 -18
  560. package/src/Item/Item.tsx +38 -2
  561. package/src/Layer/useLayer.tsx +8 -0
  562. package/src/Lightbox/Lightbox.tsx +15 -7
  563. package/src/List/List.test.tsx +9 -8
  564. package/src/Markdown/Markdown.test.tsx +21 -0
  565. package/src/Markdown/Markdown.tsx +4 -0
  566. package/src/MobileNav/MobileNav.tsx +12 -1
  567. package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
  568. package/src/MobileNav/MobileNavToggle.tsx +9 -1
  569. package/src/MultiSelector/MultiSelector.doc.mjs +24 -2
  570. package/src/MultiSelector/MultiSelector.test.tsx +498 -3
  571. package/src/MultiSelector/MultiSelector.tsx +149 -65
  572. package/src/MultiSelector/hooks.ts +17 -0
  573. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  574. package/src/NumberInput/NumberInput.doc.mjs +21 -0
  575. package/src/NumberInput/NumberInput.test.tsx +82 -7
  576. package/src/NumberInput/NumberInput.tsx +36 -28
  577. package/src/Outline/Outline.tsx +0 -1
  578. package/src/OverflowList/OverflowList.doc.mjs +39 -6
  579. package/src/OverflowList/OverflowList.test.tsx +111 -0
  580. package/src/OverflowList/OverflowList.tsx +48 -8
  581. package/src/Pagination/Pagination.tsx +11 -3
  582. package/src/Popover/Popover.tsx +7 -4
  583. package/src/Popover/usePopover.tsx +9 -13
  584. package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
  585. package/src/PowerSearch/PowerSearch.test.tsx +43 -0
  586. package/src/PowerSearch/PowerSearch.tsx +10 -1
  587. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
  588. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  589. package/src/PowerSearch/usePowerSearchSource.ts +1 -2
  590. package/src/RadioList/RadioList.doc.mjs +6 -0
  591. package/src/RadioList/RadioList.tsx +2 -2
  592. package/src/RadioList/RadioListItem.tsx +4 -4
  593. package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
  594. package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
  595. package/src/SelectableCard/SelectableCard.test.tsx +46 -4
  596. package/src/SelectableCard/SelectableCard.tsx +29 -16
  597. package/src/Selector/Selector.doc.mjs +15 -0
  598. package/src/Selector/Selector.test.tsx +417 -0
  599. package/src/Selector/Selector.tsx +86 -21
  600. package/src/Selector/hooks.ts +17 -0
  601. package/src/SideNav/SideNav.test.tsx +119 -3
  602. package/src/SideNav/SideNav.tsx +1 -8
  603. package/src/SideNav/SideNavCollapseButton.tsx +15 -8
  604. package/src/SideNav/SideNavHeading.tsx +24 -8
  605. package/src/SideNav/SideNavItem.tsx +10 -4
  606. package/src/Slider/Slider.doc.mjs +6 -0
  607. package/src/Slider/Slider.test.tsx +314 -13
  608. package/src/Slider/Slider.tsx +117 -28
  609. package/src/Switch/Switch.doc.mjs +142 -42
  610. package/src/Switch/Switch.test.tsx +54 -1
  611. package/src/Switch/Switch.tsx +90 -33
  612. package/src/TabList/Tab.tsx +2 -2
  613. package/src/TabList/TabMenu.tsx +2 -2
  614. package/src/Table/BaseTable.tsx +37 -7
  615. package/src/Table/Table.doc.mjs +11 -0
  616. package/src/Table/Table.test.tsx +85 -0
  617. package/src/Table/TableCell.tsx +3 -3
  618. package/src/Table/TableHeaderCell.tsx +3 -3
  619. package/src/Table/index.ts +5 -0
  620. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +15 -8
  621. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
  622. package/src/Table/plugins/rowStatus/index.ts +7 -0
  623. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
  624. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
  625. package/src/Table/plugins/selection/useTableSelection.test.tsx +77 -3
  626. package/src/Table/plugins/selection/useTableSelection.tsx +22 -1
  627. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
  628. package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
  629. package/src/Table/plugins/tree/useTableTreeData.tsx +139 -8
  630. package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
  631. package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
  632. package/src/Table/types.ts +33 -0
  633. package/src/Table/useBaseTablePlugins.ts +10 -6
  634. package/src/Table/useTableRowStatus.doc.mjs +30 -0
  635. package/src/Table/useTableSelection.doc.mjs +65 -14
  636. package/src/Table/useTableTreeData.doc.mjs +29 -0
  637. package/src/Table/useTableTreeState.doc.mjs +2 -2
  638. package/src/TextArea/TextArea.doc.mjs +21 -0
  639. package/src/TextArea/TextArea.test.tsx +32 -1
  640. package/src/TextArea/TextArea.tsx +27 -26
  641. package/src/TextInput/TextInput.doc.mjs +21 -0
  642. package/src/TextInput/TextInput.test.tsx +150 -0
  643. package/src/TextInput/TextInput.tsx +28 -25
  644. package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
  645. package/src/Thumbnail/Thumbnail.test.tsx +98 -7
  646. package/src/Thumbnail/Thumbnail.tsx +142 -42
  647. package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
  648. package/src/TimeInput/TimeInput.doc.mjs +21 -0
  649. package/src/TimeInput/TimeInput.test.tsx +99 -1
  650. package/src/TimeInput/TimeInput.tsx +43 -31
  651. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  652. package/src/Timestamp/Timestamp.test.tsx +32 -0
  653. package/src/Timestamp/Timestamp.tsx +28 -8
  654. package/src/Toast/useToast.tsx +7 -8
  655. package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
  656. package/src/Token/Token.test.tsx +21 -15
  657. package/src/Token/Token.tsx +31 -14
  658. package/src/Token/index.ts +1 -1
  659. package/src/Tokenizer/Tokenizer.doc.mjs +38 -2
  660. package/src/Tokenizer/Tokenizer.test.tsx +206 -2
  661. package/src/Tokenizer/Tokenizer.tsx +30 -6
  662. package/src/Tooltip/Tooltip.test.tsx +46 -0
  663. package/src/Tooltip/useTooltip.tsx +20 -0
  664. package/src/TopNav/TopNav.test.tsx +125 -1
  665. package/src/TopNav/TopNavHeading.tsx +24 -8
  666. package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
  667. package/src/TopNav/TopNavMegaMenu.tsx +10 -4
  668. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
  669. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
  670. package/src/TopNav/TopNavMenu.test.tsx +118 -4
  671. package/src/TopNav/TopNavMenu.tsx +83 -5
  672. package/src/TreeList/TreeList.doc.mjs +28 -0
  673. package/src/TreeList/TreeList.test.tsx +272 -0
  674. package/src/TreeList/TreeList.tsx +23 -2
  675. package/src/TreeList/TreeListBranches.tsx +24 -8
  676. package/src/TreeList/TreeListItem.tsx +84 -22
  677. package/src/TreeList/TreeListTypes.ts +27 -1
  678. package/src/TreeList/index.ts +2 -2
  679. package/src/Typeahead/BaseTypeahead.tsx +30 -15
  680. package/src/Typeahead/Typeahead.doc.mjs +13 -0
  681. package/src/Typeahead/Typeahead.test.tsx +50 -0
  682. package/src/Typeahead/Typeahead.tsx +11 -1
  683. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  684. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  685. package/src/authoring/doc.ts +1 -3
  686. package/src/doc-mjs.d.ts +19 -0
  687. package/src/docs-types.ts +5 -0
  688. package/src/hooks/computeOverflow.test.ts +422 -0
  689. package/src/hooks/computeOverflow.ts +290 -0
  690. package/src/hooks/index.ts +8 -0
  691. package/src/hooks/isRtlElement.ts +27 -0
  692. package/src/hooks/useDevWarning.test.tsx +45 -0
  693. package/src/hooks/useDevWarning.ts +54 -0
  694. package/src/hooks/useGridFocus.doc.mjs +3 -3
  695. package/src/hooks/useGridFocus.test.tsx +41 -0
  696. package/src/hooks/useGridFocus.ts +21 -10
  697. package/src/hooks/useInputStatusIcon.test.tsx +162 -0
  698. package/src/hooks/useInputStatusIcon.tsx +224 -0
  699. package/src/hooks/useListFocus.doc.mjs +25 -3
  700. package/src/hooks/useListFocus.test.tsx +153 -1
  701. package/src/hooks/useListFocus.ts +102 -9
  702. package/src/hooks/useOverflow.test.ts +96 -4
  703. package/src/hooks/useOverflow.ts +74 -33
  704. package/src/i18n/InternationalizationContext.ts +4 -0
  705. package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
  706. package/src/i18n/InternationalizationProvider.tsx +12 -2
  707. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  708. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  709. package/src/i18n/getLocaleDirection.ts +29 -0
  710. package/src/i18n/index.ts +6 -0
  711. package/src/i18n/resolve.ts +9 -21
  712. package/src/i18n/useDirection.ts +29 -0
  713. package/src/reset.css +0 -26
  714. package/src/reset.test.ts +60 -0
  715. package/src/theme/Theme.tsx +11 -14
  716. package/src/theme/derivedVarRegistry.test.ts +1 -0
  717. package/src/theme/derivedVarRegistry.ts +6 -0
  718. package/src/theme/generateThemeRules.test.ts +107 -0
  719. package/src/theme/generateThemeRules.ts +56 -0
  720. package/src/theme/hct.ts +1 -1
  721. package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
  722. package/src/utils/devWarning.test.ts +56 -0
  723. package/src/utils/devWarning.ts +102 -0
  724. package/src/utils/index.ts +8 -0
  725. package/src/utils/plainDate.test.ts +46 -6
  726. package/src/utils/plainDate.ts +69 -3
  727. package/src/utils/rtlStyles.ts +27 -0
  728. package/src/utils/types.ts +14 -0
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Tokenizer.tsx
7
- * @input Uses React, BaseTypeahead, Field, Token
7
+ * @input Uses React, BaseTypeahead, Field, Token, useAnnounce
8
8
  * @output Exports Tokenizer multi-select typeahead component
9
9
  * @position Composed component; forwards DOM ref and exposes focus control via
10
10
  * handleRef
@@ -37,12 +37,14 @@ import {
37
37
  inputStatusBorderStyles,
38
38
  inputStatusHoverShadowStyles,
39
39
  inputStatusFocusWithinStyles,
40
+ type FieldStatusVariant,
40
41
  } from '../Field';
41
42
  import {Token} from '../Token';
42
43
  import {renderIconSlot, type IconType} from '../Icon';
43
44
  import {OverflowList} from '../OverflowList';
44
45
  import {useLayer} from '../Layer/useLayer';
45
46
  import {useTooltip} from '../Tooltip';
47
+ import {useAnnounce} from '../hooks/useAnnounce';
46
48
  import {
47
49
  colorVars,
48
50
  spacingVars,
@@ -110,6 +112,13 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
110
112
  isOptional?: boolean;
111
113
  /** Validation status. */
112
114
  status?: InputStatus;
115
+ /**
116
+ * How the status message is placed relative to the input.
117
+ * - 'attached': message overlaps directly below the input (bordered treatment)
118
+ * - 'detached': message floats below as a separate element with spacing
119
+ * @default 'attached'
120
+ */
121
+ statusVariant?: FieldStatusVariant;
113
122
  /**
114
123
  * Icon to display at the start of the input.
115
124
  * Accepts a ReactNode (e.g. `<Icon icon={SearchIcon} />`) or an SVG icon component directly.
@@ -369,6 +378,7 @@ export function Tokenizer<T extends SearchableItem>({
369
378
  isRequired = false,
370
379
  isOptional = false,
371
380
  status,
381
+ statusVariant = 'attached',
372
382
  startIcon,
373
383
  labelTooltip,
374
384
  searchSource,
@@ -560,6 +570,12 @@ export function Tokenizer<T extends SearchableItem>({
560
570
  [],
561
571
  );
562
572
 
573
+ // Announce token add/remove politely via the persistent live region.
574
+ // Tokens previously appeared and disappeared silently — Backspace on an
575
+ // empty input removes the trailing token, and the per-token remove buttons
576
+ // gave no audible feedback either.
577
+ const announce = useAnnounce();
578
+
563
579
  // Handle adding an item — detect creatable synthetic items
564
580
  const handleAdd = useCallback(
565
581
  (item: T | null) => {
@@ -584,6 +600,7 @@ export function Tokenizer<T extends SearchableItem>({
584
600
  const realItem = base as T;
585
601
  const newItems = [...value, realItem];
586
602
  onChange(newItems, {item: realItem, type: 'create'});
603
+ announce(`Added ${createdValue}`);
587
604
  return;
588
605
  }
589
606
 
@@ -592,18 +609,22 @@ export function Tokenizer<T extends SearchableItem>({
592
609
  }
593
610
  const newItems = [...value, item];
594
611
  onChange(newItems, {item, type: 'add'});
612
+ announce(`Added ${item.label}`);
595
613
  },
596
- [value, onChange, isAtMax, selectedIds, hasCreate],
614
+ [value, onChange, isAtMax, selectedIds, hasCreate, announce],
597
615
  );
598
616
 
599
- // Handle removing an item
617
+ // Handle removing an item. Single removal path: both Backspace on an empty
618
+ // input and the per-token remove buttons route through here, so the
619
+ // announcement covers both.
600
620
  const handleRemove = useCallback(
601
621
  (item: T) => {
602
622
  const newItems = value.filter(v => v.id !== item.id);
603
623
  onChange(newItems, {item, type: 'remove'});
624
+ announce(`Removed ${item.label}`);
604
625
  inputRef.current?.focus();
605
626
  },
606
- [value, onChange],
627
+ [value, onChange, announce],
607
628
  );
608
629
 
609
630
  // Handle clearing all items
@@ -718,7 +739,7 @@ export function Tokenizer<T extends SearchableItem>({
718
739
  isTruncated && styles.truncatedWrapper,
719
740
  isDisabled && inputWrapperStyles.disabled,
720
741
  status && inputStatusBorderStyles[status.type],
721
- status && inputStatusHoverShadowStyles[status.type],
742
+ status && !isDisabled && inputStatusHoverShadowStyles[status.type],
722
743
  status && inputStatusFocusWithinStyles[status.type],
723
744
  ),
724
745
  )}>
@@ -816,7 +837,9 @@ export function Tokenizer<T extends SearchableItem>({
816
837
  isTruncated && styles.truncatedWrapper,
817
838
  isDisabled && inputWrapperStyles.disabled,
818
839
  status && inputStatusBorderStyles[status.type],
819
- status && inputStatusHoverShadowStyles[status.type],
840
+ status &&
841
+ !isDisabled &&
842
+ inputStatusHoverShadowStyles[status.type],
820
843
  status && inputStatusFocusWithinStyles[status.type],
821
844
  ),
822
845
  )}>
@@ -879,6 +902,7 @@ export function Tokenizer<T extends SearchableItem>({
879
902
  }
880
903
  : undefined
881
904
  }
905
+ statusVariant={statusVariant}
882
906
  labelTooltip={labelTooltip}
883
907
  width={width}
884
908
  xstyle={xstyle}
@@ -221,4 +221,50 @@ describe('Tooltip', () => {
221
221
  expect(onOpenChange).not.toHaveBeenCalledWith(false);
222
222
  });
223
223
  });
224
+
225
+ describe('press-to-dismiss', () => {
226
+ it('hides the tooltip when the trigger is pressed', async () => {
227
+ const onOpenChange = vi.fn();
228
+ render(
229
+ <Tooltip content="Copy link" onOpenChange={onOpenChange} delay={0}>
230
+ <button type="button">Trigger</button>
231
+ </Tooltip>,
232
+ );
233
+
234
+ const trigger = screen.getByRole('button', {name: 'Trigger'});
235
+ fireEvent.mouseEnter(trigger);
236
+ await waitFor(() => {
237
+ expect(onOpenChange).toHaveBeenCalledWith(true);
238
+ });
239
+
240
+ fireEvent.pointerDown(trigger);
241
+ await waitFor(() => {
242
+ expect(onOpenChange).toHaveBeenCalledWith(false);
243
+ });
244
+ });
245
+
246
+ it('does not press-dismiss a controlled tooltip', async () => {
247
+ const onOpenChange = vi.fn();
248
+ render(
249
+ <Tooltip
250
+ content="Controlled"
251
+ isOpen
252
+ onOpenChange={onOpenChange}
253
+ delay={0}>
254
+ <button type="button">Trigger</button>
255
+ </Tooltip>,
256
+ );
257
+
258
+ const trigger = screen.getByRole('button', {name: 'Trigger'});
259
+ await waitFor(() => {
260
+ expect(onOpenChange).toHaveBeenCalledWith(true);
261
+ });
262
+ onOpenChange.mockClear();
263
+
264
+ fireEvent.pointerDown(trigger);
265
+ // Give any (incorrect) async hide a chance to run.
266
+ await new Promise(r => setTimeout(r, 20));
267
+ expect(onOpenChange).not.toHaveBeenCalledWith(false);
268
+ });
269
+ });
224
270
  });
@@ -366,6 +366,19 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
366
366
  scheduleHide();
367
367
  }, [scheduleHide]);
368
368
 
369
+ // Pressing the trigger hides its own tooltip: once the control is activated
370
+ // the hint has served its purpose, and a tooltip lingering over a
371
+ // just-pressed control reads as stale. Fires on pointerdown so it feels
372
+ // immediate. Uncontrolled tooltips only — a controlled tooltip's visibility
373
+ // is owned by the consumer. `layer.hide()` self-guards when already closed.
374
+ const handlePointerDown = useCallback(() => {
375
+ if (isOpen !== undefined) {
376
+ return;
377
+ }
378
+ clearTimeouts();
379
+ layer.hide();
380
+ }, [isOpen, clearTimeouts, layer]);
381
+
369
382
  // Interaction ref that handles event listeners only
370
383
  const interactionRef: RefCallback<HTMLElement> = useCallback(
371
384
  (el: HTMLElement | null) => {
@@ -375,12 +388,18 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
375
388
  triggerRef.current.removeEventListener('mouseleave', handleMouseLeave);
376
389
  triggerRef.current.removeEventListener('focusin', handleFocusIn);
377
390
  triggerRef.current.removeEventListener('focusout', handleFocusOut);
391
+ triggerRef.current.removeEventListener(
392
+ 'pointerdown',
393
+ handlePointerDown,
394
+ );
378
395
  }
379
396
 
380
397
  if (el) {
381
398
  // Attach hover listeners
382
399
  el.addEventListener('mouseenter', handleMouseEnter);
383
400
  el.addEventListener('mouseleave', handleMouseLeave);
401
+ // Press-to-dismiss: activating the trigger hides its own tooltip.
402
+ el.addEventListener('pointerdown', handlePointerDown);
384
403
 
385
404
  // Attach focus listeners based on focusTrigger option
386
405
  const shouldAttachFocus =
@@ -401,6 +420,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
401
420
  handleMouseLeave,
402
421
  handleFocusIn,
403
422
  handleFocusOut,
423
+ handlePointerDown,
404
424
  ],
405
425
  );
406
426
 
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import {describe, it, expect, vi} from 'vitest';
13
- import {render, screen} from '@testing-library/react';
13
+ import {fireEvent, render, screen} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {TopNav} from './TopNav';
16
16
  import {TopNavRenderContext} from './TopNavRenderContext';
@@ -297,6 +297,85 @@ describe('TopNavHeading', () => {
297
297
  render(<TopNavHeading heading="Test" ref={ref} />);
298
298
  expect(ref).toHaveBeenCalledWith(expect.any(HTMLElement));
299
299
  });
300
+
301
+ // ===========================================================================
302
+ // Menu popover semantics — the popup must not be announced as a modal
303
+ // dialog, and role="menu" must be scoped to the actual menu items so the
304
+ // heading button is not an invalid child of the menu.
305
+ // ===========================================================================
306
+
307
+ // The popover layer keeps `popover` content display:none in jsdom even
308
+ // when open, hiding it from role queries — so these tests assert the
309
+ // popup's ARIA semantics at the DOM level instead.
310
+ describe('menu popover semantics', () => {
311
+ const menuItems = (
312
+ <>
313
+ <div role="menuitem">Alpha</div>
314
+ <div role="menuitem">Beta</div>
315
+ </>
316
+ );
317
+
318
+ it('does not wrap the heading menu popup in a modal dialog', async () => {
319
+ const user = userEvent.setup();
320
+ render(<TopNavHeading heading="My App" menu={menuItems} />);
321
+ await user.click(screen.getByRole('button', {name: 'Open menu'}));
322
+ expect(document.querySelector('[role="dialog"]')).toBeNull();
323
+ expect(document.querySelector('[aria-modal="true"]')).toBeNull();
324
+ });
325
+
326
+ it('scopes role="menu" to only menuitem children with an accessible name', async () => {
327
+ const user = userEvent.setup();
328
+ render(<TopNavHeading heading="My App" menu={menuItems} />);
329
+ await user.click(screen.getByRole('button', {name: 'Open menu'}));
330
+ const menu = document.querySelector('[role="menu"]');
331
+ expect(menu).not.toBeNull();
332
+ expect(menu).toHaveAttribute('aria-label', 'My App');
333
+ const children = Array.from(menu!.children);
334
+ expect(children.length).toBeGreaterThan(0);
335
+ for (const child of children) {
336
+ expect(child).toHaveAttribute('role', 'menuitem');
337
+ }
338
+ });
339
+
340
+ it('keeps the popup heading button outside the menu and closes on click', async () => {
341
+ const user = userEvent.setup();
342
+ render(<TopNavHeading heading="My App" menu={menuItems} />);
343
+ const trigger = screen.getByRole('button', {name: 'Open menu'});
344
+ await user.click(trigger);
345
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
346
+ const menu = document.querySelector('[role="menu"]');
347
+ expect(menu).not.toBeNull();
348
+ // The heading replica button in the popup is a sibling of the menu,
349
+ // not an invalid menu child.
350
+ const headingButton = Array.from(
351
+ document.querySelectorAll('button'),
352
+ ).find(b => b !== trigger && b.textContent?.includes('My App'));
353
+ expect(headingButton).toBeDefined();
354
+ expect(menu!.contains(headingButton!)).toBe(false);
355
+ // Clicking it still closes the popup.
356
+ fireEvent.click(headingButton!);
357
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
358
+ });
359
+
360
+ it('applies the same semantics in mixed mode (menu + hrefs)', async () => {
361
+ const user = userEvent.setup();
362
+ render(
363
+ <TopNavHeading
364
+ heading="Product"
365
+ headingHref="/product"
366
+ menu={menuItems}
367
+ />,
368
+ );
369
+ await user.click(screen.getByRole('button', {name: 'Open menu'}));
370
+ expect(document.querySelector('[role="dialog"]')).toBeNull();
371
+ const menu = document.querySelector('[role="menu"]');
372
+ expect(menu).not.toBeNull();
373
+ expect(menu).toHaveAttribute('aria-label', 'Product');
374
+ for (const child of Array.from(menu!.children)) {
375
+ expect(child).toHaveAttribute('role', 'menuitem');
376
+ }
377
+ });
378
+ });
300
379
  });
301
380
 
302
381
  describe('NavIcon', () => {
@@ -444,4 +523,49 @@ describe('TopNavItem', () => {
444
523
  expect(card).toHaveAttribute('aria-label', 'Featured');
445
524
  });
446
525
  });
526
+
527
+ describe('TopNavMegaMenuFeaturedCard image alt handling', () => {
528
+ it('marks the image as explicitly decorative when imageAlt is omitted', () => {
529
+ render(
530
+ <TopNavMegaMenuFeaturedCard
531
+ title="What's new"
532
+ image="/promo.jpg"
533
+ data-testid="featured-card"
534
+ />,
535
+ );
536
+ const img = screen.getByTestId('featured-card').querySelector('img');
537
+ expect(img).toHaveAttribute('alt', '');
538
+ expect(img).toHaveAttribute('role', 'presentation');
539
+ expect(img).toHaveAttribute('aria-hidden', 'true');
540
+ // The image must not be exposed to assistive technology as a nameless img.
541
+ expect(screen.queryByRole('img')).toBeNull();
542
+ });
543
+
544
+ it('exposes the image with normal img semantics when imageAlt is provided', () => {
545
+ render(
546
+ <TopNavMegaMenuFeaturedCard
547
+ title="What's new"
548
+ image="/promo.jpg"
549
+ imageAlt="Team collaboration"
550
+ />,
551
+ );
552
+ const img = screen.getByRole('img', {name: 'Team collaboration'});
553
+ expect(img).not.toHaveAttribute('role');
554
+ expect(img).not.toHaveAttribute('aria-hidden');
555
+ });
556
+
557
+ it('keeps title and link semantics unchanged with a decorative image', () => {
558
+ render(
559
+ <TopNavMegaMenuFeaturedCard
560
+ title="What's new"
561
+ image="/promo.jpg"
562
+ linkLabel="Read the announcement"
563
+ linkHref="/blog/v4"
564
+ />,
565
+ );
566
+ expect(screen.getByText("What's new")).toBeInTheDocument();
567
+ const link = screen.getByRole('link', {name: /Read the announcement/});
568
+ expect(link).toHaveAttribute('href', '/blog/v4');
569
+ });
570
+ });
447
571
  });
@@ -332,6 +332,10 @@ export function TopNavHeading({
332
332
 
333
333
  const popover = usePopover({
334
334
  dialogLabel: t('@astryx.topNav.heading.dialogLabel'),
335
+ // The popup exposes its own role="menu" semantics; a role="dialog"
336
+ // aria-modal wrapper would announce "dialog, Navigation menu" around a
337
+ // menu (the anti-pattern removed in a478a3dcf).
338
+ role: 'none',
335
339
  hasCloseButton: false,
336
340
  });
337
341
 
@@ -511,13 +515,19 @@ export function TopNavHeading({
511
515
  {popover.render(
512
516
  <div
513
517
  ref={menuRef}
514
- role="menu"
515
518
  {...stylex.props(styles.popoverContent)}
516
519
  {...contentProps}>
517
520
  {popoverHeadingContent}
518
- <NavHeadingCloseContext value={closeMenuCtx}>
519
- {menu}
520
- </NavHeadingCloseContext>
521
+ {/* The menu role is scoped to the actual menu items so the
522
+ heading button above stays a valid sibling, not an invalid
523
+ child of a role="menu" element. */}
524
+ <div
525
+ role="menu"
526
+ aria-label={heading ?? t('@astryx.topNav.heading.dialogLabel')}>
527
+ <NavHeadingCloseContext value={closeMenuCtx}>
528
+ {menu}
529
+ </NavHeadingCloseContext>
530
+ </div>
521
531
  </div>,
522
532
  {
523
533
  placement: 'below',
@@ -575,13 +585,19 @@ export function TopNavHeading({
575
585
  {popover.render(
576
586
  <div
577
587
  ref={menuRef}
578
- role="menu"
579
588
  {...stylex.props(styles.popoverContent)}
580
589
  {...contentProps}>
581
590
  {popoverHeadingContent}
582
- <NavHeadingCloseContext value={closeMenuCtx}>
583
- {menu}
584
- </NavHeadingCloseContext>
591
+ {/* The menu role is scoped to the actual menu items so the
592
+ heading button above stays a valid sibling, not an invalid
593
+ child of a role="menu" element. */}
594
+ <div
595
+ role="menu"
596
+ aria-label={heading ?? t('@astryx.topNav.heading.dialogLabel')}>
597
+ <NavHeadingCloseContext value={closeMenuCtx}>
598
+ {menu}
599
+ </NavHeadingCloseContext>
600
+ </div>
585
601
  </div>,
586
602
  {
587
603
  placement: 'below',
@@ -9,7 +9,7 @@
9
9
  * SYNC: When TopNavMegaMenu changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi} from 'vitest';
12
+ import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest';
13
13
  import {render, screen} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {TopNavMegaMenu} from './TopNavMegaMenu';
@@ -75,6 +75,154 @@ describe('TopNavMegaMenu — default mode', () => {
75
75
  });
76
76
  });
77
77
 
78
+ // =============================================================================
79
+ // Popup semantics (default mode)
80
+ // =============================================================================
81
+
82
+ describe('TopNavMegaMenu — popup semantics', () => {
83
+ // Mock the Popover API (not implemented in jsdom).
84
+ const originalMatches = HTMLElement.prototype.matches;
85
+
86
+ beforeAll(() => {
87
+ HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
88
+ this.setAttribute('popover-open', '');
89
+ const event = new Event('toggle', {bubbles: false});
90
+ Object.defineProperty(event, 'newState', {value: 'open'});
91
+ this.dispatchEvent(event);
92
+ });
93
+ HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
94
+ this.removeAttribute('popover-open');
95
+ const event = new Event('toggle', {bubbles: false});
96
+ Object.defineProperty(event, 'newState', {value: 'closed'});
97
+ this.dispatchEvent(event);
98
+ });
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
+ (HTMLElement.prototype as any).matches = function (
101
+ selector: string,
102
+ ): boolean {
103
+ if (selector === ':popover-open') {
104
+ return this.hasAttribute('popover-open');
105
+ }
106
+ return originalMatches.call(this, selector);
107
+ };
108
+ });
109
+
110
+ afterAll(() => {
111
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
+ (HTMLElement.prototype as any).matches = originalMatches;
113
+ });
114
+
115
+ it('trigger aria-controls resolves to the popup element', async () => {
116
+ const user = userEvent.setup();
117
+ render(
118
+ <TopNavMegaMenu
119
+ label="Products"
120
+ items={<TopNavMegaMenuItem title="Analytics" href="/analytics" />}
121
+ />,
122
+ );
123
+
124
+ const trigger = screen.getByRole('button', {name: 'Products'});
125
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
126
+
127
+ // aria-controls must be present and point at the real popup element.
128
+ const controlsId = trigger.getAttribute('aria-controls');
129
+ expect(controlsId).toBeTruthy();
130
+ const popup = document.getElementById(controlsId as string);
131
+ expect(popup).not.toBeNull();
132
+
133
+ await user.click(trigger);
134
+
135
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
136
+ // The referenced element is the popup that contains the panel content.
137
+ expect(popup).toContainElement(
138
+ screen.getByRole('group', {name: 'Products', hidden: true}),
139
+ );
140
+ });
141
+
142
+ it('does not wrap the panel in a role="dialog" aria-modal element', async () => {
143
+ const user = userEvent.setup();
144
+ render(
145
+ <TopNavMegaMenu
146
+ label="Products"
147
+ items={<TopNavMegaMenuItem title="Analytics" href="/analytics" />}
148
+ />,
149
+ );
150
+
151
+ await user.click(screen.getByRole('button', {name: 'Products'}));
152
+
153
+ // Focus stays on the trigger while the panel is open, so a modal dialog
154
+ // wrapper would tell assistive tech the focused control is inert.
155
+ expect(
156
+ screen.queryByRole('dialog', {hidden: true}),
157
+ ).not.toBeInTheDocument();
158
+ expect(document.querySelector('[aria-modal="true"]')).toBeNull();
159
+ });
160
+
161
+ it('does not expose role="menu" — a link grid is not an ARIA menu', async () => {
162
+ const user = userEvent.setup();
163
+ render(
164
+ <TopNavMegaMenu
165
+ label="Products"
166
+ items={
167
+ <>
168
+ <TopNavMegaMenuItem title="Analytics" href="/analytics" />
169
+ <TopNavMegaMenuItem title="Reports" href="/reports" />
170
+ </>
171
+ }
172
+ />,
173
+ );
174
+
175
+ await user.click(screen.getByRole('button', {name: 'Products'}));
176
+
177
+ // Per the WAI-ARIA APG, mega menu panels of navigation links must not use
178
+ // the menu role (reserved for action menus with menuitem children).
179
+ expect(screen.queryByRole('menu', {hidden: true})).not.toBeInTheDocument();
180
+ expect(screen.queryAllByRole('menuitem', {hidden: true})).toHaveLength(0);
181
+ });
182
+
183
+ it('exposes the panel as a labeled group', async () => {
184
+ const user = userEvent.setup();
185
+ render(
186
+ <TopNavMegaMenu
187
+ label="Products"
188
+ items={<TopNavMegaMenuItem title="Analytics" href="/analytics" />}
189
+ />,
190
+ );
191
+
192
+ await user.click(screen.getByRole('button', {name: 'Products'}));
193
+
194
+ expect(
195
+ screen.getByRole('group', {name: 'Products', hidden: true}),
196
+ ).toBeInTheDocument();
197
+ });
198
+
199
+ it('keeps item links with accessible names inside the panel', async () => {
200
+ const user = userEvent.setup();
201
+ render(
202
+ <TopNavMegaMenu
203
+ label="Products"
204
+ items={
205
+ <>
206
+ <TopNavMegaMenuItem title="Analytics" href="/analytics" />
207
+ <TopNavMegaMenuItem title="Reports" href="/reports" />
208
+ </>
209
+ }
210
+ />,
211
+ );
212
+
213
+ await user.click(screen.getByRole('button', {name: 'Products'}));
214
+
215
+ const analytics = screen.getByRole('link', {
216
+ name: /Analytics/,
217
+ hidden: true,
218
+ });
219
+ expect(analytics).toHaveAttribute('href', '/analytics');
220
+ expect(
221
+ screen.getByRole('link', {name: /Reports/, hidden: true}),
222
+ ).toHaveAttribute('href', '/reports');
223
+ });
224
+ });
225
+
78
226
  // =============================================================================
79
227
  // Mobile-bar mode — should be hidden
80
228
  // =============================================================================
@@ -354,7 +354,11 @@ function DefaultMegaMenu({
354
354
  }, [onOpenChange]);
355
355
 
356
356
  const popover = usePopover({
357
- dialogLabel: label,
357
+ // role: 'none' — the panel exposes its own role="group" labeled by
358
+ // `label`. Focus stays on the trigger while the panel is open, so a
359
+ // role="dialog" aria-modal="true" wrapper would announce an unnamed
360
+ // modal dialog around a grid of links.
361
+ role: 'none',
358
362
  // hasSurface: false — mega menu provides its own surface (panelContainer)
359
363
  // with border-top and custom overflow. Animation is applied via the
360
364
  // render() call's xstyle prop (panelAnimation), not the hook options.
@@ -434,8 +438,7 @@ function DefaultMegaMenu({
434
438
  <button
435
439
  ref={mergeRefs(triggerButtonRef, ref)}
436
440
  type="button"
437
- aria-haspopup="true"
438
- aria-expanded={popover.isOpen}
441
+ {...popover.triggerProps}
439
442
  onClick={handleClick}
440
443
  onMouseEnter={handleMouseEnter}
441
444
  onMouseLeave={handleMouseLeave}
@@ -454,7 +457,10 @@ function DefaultMegaMenu({
454
457
  </button>
455
458
  {popover.render(
456
459
  <div
457
- role="menu"
460
+ // role="group" — a mega menu is a browsing grid of links, not an
461
+ // ARIA menu of menuitems (per the WAI-ARIA APG, the menu role is
462
+ // for action menus; link mega menus are the documented anti-case).
463
+ role="group"
458
464
  aria-label={label}
459
465
  onMouseEnter={handleMouseEnter}
460
466
  onMouseLeave={handleMouseLeave}
@@ -27,7 +27,7 @@ export const docs = {
27
27
  {
28
28
  name: 'imageAlt',
29
29
  type: 'string',
30
- description: 'Alt text for the image.',
30
+ description: 'Alt text for the image. When omitted, the image is explicitly decorative (alt="", role="presentation", aria-hidden), usually correct since the card already has a visible title. Provide it only when the image conveys information beyond the title and description.',
31
31
  },
32
32
  {
33
33
  name: 'linkLabel',
@@ -71,7 +71,7 @@ export const docsZh = {
71
71
  {
72
72
  name: 'imageAlt',
73
73
  type: 'string',
74
- description: '图片的替代文本。',
74
+ description: '图片的替代文本。省略时图片会被显式标记为装饰性(alt=""、role="presentation"、aria-hidden)——由于卡片已有可见标题,这通常是正确的。仅当图片传达标题和描述之外的信息时才提供。',
75
75
  },
76
76
  {
77
77
  name: 'linkLabel',
@@ -99,7 +99,7 @@ export const docsDense = {
99
99
  title: 'Card title.',
100
100
  description: 'Description below title.',
101
101
  image: 'Image URL above body.',
102
- imageAlt: 'Image alt text.',
102
+ imageAlt: 'Image alt text. Omitted → explicitly decorative (hidden from screen readers); usually correct since card has visible title.',
103
103
  linkLabel: 'CTA link text.',
104
104
  linkHref: 'CTA link URL.',
105
105
  children: 'Custom content below standard body.',
@@ -84,7 +84,15 @@ export interface TopNavMegaMenuFeaturedCardProps extends BaseProps<HTMLDivElemen
84
84
  description?: string;
85
85
  /** Optional image URL displayed above the body. */
86
86
  image?: string;
87
- /** Alt text for the image. */
87
+ /**
88
+ * Alt text for the image.
89
+ *
90
+ * When omitted, the image is explicitly decorative (`alt=""` +
91
+ * `role="presentation"` + `aria-hidden`, matching Avatar) and hidden from
92
+ * assistive technology. Since the card already has a visible `title`, a
93
+ * decorative image is usually correct; pass `imageAlt` only when the image
94
+ * conveys information beyond the title and description.
95
+ */
88
96
  imageAlt?: string;
89
97
  /** CTA link text. */
90
98
  linkLabel?: string;
@@ -149,7 +157,16 @@ export function TopNavMegaMenuFeaturedCard({
149
157
  )}
150
158
  {...rest}>
151
159
  {image && (
152
- <img src={image} alt={imageAlt ?? ''} {...stylex.props(styles.image)} />
160
+ // Without `imageAlt`, the image is explicitly decorative rather than
161
+ // silently empty-alt, matching Avatar's handling of unnamed images.
162
+ // Usually correct here: the card already has a visible title.
163
+ <img
164
+ src={image}
165
+ alt={imageAlt ?? ''}
166
+ role={imageAlt ? undefined : 'presentation'}
167
+ aria-hidden={imageAlt ? undefined : true}
168
+ {...stylex.props(styles.image)}
169
+ />
153
170
  )}
154
171
  <div {...stylex.props(styles.body)}>
155
172
  <span {...stylex.props(styles.title)}>{title}</span>