@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
@@ -15,6 +15,8 @@ import userEvent from '@testing-library/user-event';
15
15
  import {getButton, queryButton} from '../__tests__/fastRoleQueries';
16
16
  import {DateTimeInput} from './DateTimeInput';
17
17
  import type {ISODateTimeString} from './DateTimeInput';
18
+ import {defineTheme} from '../theme/defineTheme';
19
+ import {generateThemeCSSFlat} from '../theme/generateThemeRules';
18
20
 
19
21
  describe('DateTimeInput', () => {
20
22
  it('renders with label', () => {
@@ -185,6 +187,41 @@ describe('DateTimeInput', () => {
185
187
  );
186
188
  });
187
189
 
190
+ it('opens the calendar popover on ArrowDown (keyboard, forms-13)', () => {
191
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
192
+ const input = screen.getByRole('combobox');
193
+ input.focus();
194
+ expect(input).toHaveAttribute('aria-expanded', 'false');
195
+ fireEvent.keyDown(input, {key: 'ArrowDown'});
196
+ expect(input).toHaveAttribute('aria-expanded', 'true');
197
+ // skipAutoFocus keeps focus in the input, per the APG date-picker pattern
198
+ expect(input).toHaveFocus();
199
+ });
200
+
201
+ it('opens the calendar popover on Alt+ArrowDown (keyboard, forms-13)', () => {
202
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
203
+ const input = screen.getByRole('combobox');
204
+ fireEvent.keyDown(input, {key: 'ArrowDown', altKey: true});
205
+ expect(input).toHaveAttribute('aria-expanded', 'true');
206
+ });
207
+
208
+ it('does not open on ArrowDown when disabled', () => {
209
+ render(<DateTimeInput label="Meeting" isDisabled onChange={() => {}} />);
210
+ const input = screen.getByRole('combobox');
211
+ fireEvent.keyDown(input, {key: 'ArrowDown'});
212
+ expect(input).toHaveAttribute('aria-expanded', 'false');
213
+ });
214
+
215
+ it('does not re-trigger on ArrowDown when the calendar is already open', () => {
216
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
217
+ const input = screen.getByRole('combobox');
218
+ fireEvent.keyDown(input, {key: 'ArrowDown'});
219
+ expect(input).toHaveAttribute('aria-expanded', 'true');
220
+ // A second ArrowDown is a no-op: the calendar stays open
221
+ fireEvent.keyDown(input, {key: 'ArrowDown'});
222
+ expect(input).toHaveAttribute('aria-expanded', 'true');
223
+ });
224
+
188
225
  it('calendar button is focusable and clickable', () => {
189
226
  render(<DateTimeInput label="Meeting" onChange={() => {}} />);
190
227
  const button = getButton('Open calendar');
@@ -779,4 +816,114 @@ describe('DateTimeInput', () => {
779
816
  expect(onChange.mock.calls[0][0]).toContain('14:31');
780
817
  });
781
818
  });
819
+ // ===========================================================================
820
+ // Segment theme targets (#4075)
821
+ // ===========================================================================
822
+
823
+ describe('segment theme targets', () => {
824
+ // The root only publishes `astryx-date-time-input`; the date and time
825
+ // wrappers were anonymous nodes carrying hashed atomic classes only, so a
826
+ // theme that restyles input geometry through the text-input/date-input/
827
+ // time-input targets could not reach them and DateTimeInput rendered
828
+ // shorter than every other input under that theme.
829
+
830
+ it('renders the date segment target on the date wrapper', () => {
831
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
832
+ const wrapper = screen
833
+ .getByLabelText('Meeting')
834
+ .closest('.astryx-date-time-input-date-segment');
835
+
836
+ expect(wrapper).not.toBeNull();
837
+ // The wrapper is the input's own container, not an ancestor further up.
838
+ expect(wrapper).toBe(screen.getByLabelText('Meeting').parentElement);
839
+ });
840
+
841
+ it('renders the time segment target on the time wrapper', () => {
842
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
843
+ const wrapper = screen
844
+ .getByLabelText('Meeting time')
845
+ .closest('.astryx-date-time-input-time-segment');
846
+
847
+ expect(wrapper).not.toBeNull();
848
+ expect(wrapper).toBe(screen.getByLabelText('Meeting time').parentElement);
849
+ });
850
+
851
+ it('reflects size on both segments so themes can restyle geometry', () => {
852
+ render(<DateTimeInput label="Meeting" size="lg" onChange={() => {}} />);
853
+
854
+ const date = screen
855
+ .getByLabelText('Meeting')
856
+ .closest('.astryx-date-time-input-date-segment');
857
+ const time = screen
858
+ .getByLabelText('Meeting time')
859
+ .closest('.astryx-date-time-input-time-segment');
860
+
861
+ expect(date).toHaveAttribute('data-size', 'lg');
862
+ expect(date).toHaveClass('lg');
863
+ expect(time).toHaveAttribute('data-size', 'lg');
864
+ expect(time).toHaveClass('lg');
865
+ });
866
+
867
+ it('reflects status on both segments, mirroring the root', () => {
868
+ render(
869
+ <DateTimeInput
870
+ label="Meeting"
871
+ status={{type: 'error', message: 'Required'}}
872
+ onChange={() => {}}
873
+ />,
874
+ );
875
+
876
+ const date = screen
877
+ .getByLabelText('Meeting')
878
+ .closest('.astryx-date-time-input-date-segment');
879
+ const time = screen
880
+ .getByLabelText('Meeting time')
881
+ .closest('.astryx-date-time-input-time-segment');
882
+
883
+ expect(date).toHaveAttribute('data-status', 'error');
884
+ expect(time).toHaveAttribute('data-status', 'error');
885
+ });
886
+
887
+ it('omits data-status when there is no status, like the root does', () => {
888
+ render(<DateTimeInput label="Meeting" onChange={() => {}} />);
889
+
890
+ const date = screen
891
+ .getByLabelText('Meeting')
892
+ .closest('.astryx-date-time-input-date-segment');
893
+
894
+ expect(date).not.toHaveAttribute('data-status');
895
+ });
896
+
897
+ it('keeps the root target intact', () => {
898
+ const {container} = render(
899
+ <DateTimeInput label="Meeting" onChange={() => {}} />,
900
+ );
901
+ // Additive change — the existing root target still renders.
902
+ expect(container.querySelector('.astryx-date-time-input')).not.toBeNull();
903
+ });
904
+
905
+ it('exposes both segments as themeable defineTheme targets', () => {
906
+ // jsdom cannot resolve the @layer cascade, so the generated CSS is what
907
+ // proves a theme can actually reach these nodes.
908
+ const theme = defineTheme({
909
+ name: 'date-time-input-segments-test',
910
+ components: {
911
+ 'date-time-input-date-segment': {
912
+ base: {blockSize: 'var(--size-element-lg)'},
913
+ lg: {paddingInline: 'var(--spacing-4)'},
914
+ },
915
+ 'date-time-input-time-segment': {
916
+ base: {blockSize: 'var(--size-element-lg)'},
917
+ },
918
+ },
919
+ });
920
+ const css = generateThemeCSSFlat(theme);
921
+
922
+ expect(css).toContain('.astryx-date-time-input-date-segment {');
923
+ expect(css).toContain('.astryx-date-time-input-date-segment.lg');
924
+ expect(css).toContain('.astryx-date-time-input-time-segment {');
925
+ expect(css).toContain('block-size: var(--size-element-lg)');
926
+ expect(css).toContain('padding-inline: var(--spacing-4)');
927
+ });
928
+ });
782
929
  });
@@ -27,7 +27,6 @@ import {
27
27
  type KeyboardEvent,
28
28
  } from 'react';
29
29
  import * as stylex from '@stylexjs/stylex';
30
- import type {IconName} from '../Icon';
31
30
  import {
32
31
  colorVars,
33
32
  sizeVars,
@@ -40,7 +39,6 @@ import {
40
39
  import {
41
40
  Field,
42
41
  type InputStatus,
43
- type InputStatusType,
44
42
  inputWrapperStyles,
45
43
  inputStatusBorderStyles,
46
44
  inputStatusHoverShadowStyles,
@@ -54,6 +52,7 @@ import {useCalendarConstraints} from '../Calendar/hooks';
54
52
  import {usePopover} from '../Popover';
55
53
  import {useTooltip} from '../Tooltip';
56
54
  import {useInputContainer} from '../hooks/useInputContainer';
55
+ import {useInputStatusIcon} from '../hooks/useInputStatusIcon';
57
56
  import {
58
57
  type ISOTimeString,
59
58
  parseDateInput,
@@ -470,25 +469,21 @@ export function DateTimeInput({
470
469
  isEnabled: showsDisabledMessage,
471
470
  });
472
471
 
473
- const statusIconMap: Record<InputStatusType, IconName> = {
474
- warning: 'warning',
475
- error: 'error',
476
- success: 'success',
477
- };
478
-
479
- const statusIconColorMap: Record<
480
- InputStatusType,
481
- 'warning' | 'error' | 'success'
482
- > = {
483
- warning: 'warning',
484
- error: 'error',
485
- success: 'success',
486
- };
472
+ // DateTimeInput fixes its status presentation to the detached message box,
473
+ // so the shared helper suppresses the on-field icon (the message box carries
474
+ // its own leading glyph). Routed through the helper for consistency with the
475
+ // rest of the bordered input family.
476
+ const {statusIcon, describedBy: statusTooltipDescribedBy} =
477
+ useInputStatusIcon({
478
+ status,
479
+ statusVariant: 'detached',
480
+ });
487
481
 
488
482
  const ariaDescribedBy =
489
483
  [
490
484
  description ? descriptionID : null,
491
485
  status?.message ? statusMessageID : null,
486
+ statusTooltipDescribedBy,
492
487
  showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
493
488
  ]
494
489
  .filter(Boolean)
@@ -719,12 +714,22 @@ export function DateTimeInput({
719
714
  if (e.key === 'Escape' && popover.isOpen) {
720
715
  e.preventDefault();
721
716
  popover.hide();
717
+ } else if (
718
+ (e.key === 'ArrowDown' || (e.altKey && e.key === 'ArrowDown')) &&
719
+ !popover.isOpen
720
+ ) {
721
+ // APG combobox: ArrowDown (and Alt+ArrowDown) opens the calendar
722
+ // popover from the keyboard, keeping focus in the input (forms-13).
723
+ e.preventDefault();
724
+ if (!isEffectivelyDisabled) {
725
+ popover.show({skipAutoFocus: true});
726
+ }
722
727
  } else if (e.key === 'Enter') {
723
728
  e.preventDefault();
724
729
  commitDatePendingInput();
725
730
  }
726
731
  },
727
- [popover, commitDatePendingInput],
732
+ [popover, commitDatePendingInput, isEffectivelyDisabled],
728
733
  );
729
734
 
730
735
  // --- Time handlers ---
@@ -880,14 +885,22 @@ export function DateTimeInput({
880
885
  {/* Date input */}
881
886
  <div
882
887
  ref={popover.triggerRef}
883
- {...stylex.props(
884
- inputWrapperStyles.base,
885
- sizeStyles[size],
886
- styles.dateWrapper,
887
- isEffectivelyDisabled && inputWrapperStyles.disabled,
888
- status && inputStatusBorderStyles[status.type],
889
- status && inputStatusHoverShadowStyles[status.type],
890
- status && inputStatusFocusWithinStyles[status.type],
888
+ {...mergeProps(
889
+ themeProps('date-time-input-date-segment', {
890
+ size,
891
+ status: status?.type ?? null,
892
+ }),
893
+ stylex.props(
894
+ inputWrapperStyles.base,
895
+ sizeStyles[size],
896
+ styles.dateWrapper,
897
+ isEffectivelyDisabled && inputWrapperStyles.disabled,
898
+ status && inputStatusBorderStyles[status.type],
899
+ status &&
900
+ !isEffectivelyDisabled &&
901
+ inputStatusHoverShadowStyles[status.type],
902
+ status && inputStatusFocusWithinStyles[status.type],
903
+ ),
891
904
  )}>
892
905
  <button
893
906
  type="button"
@@ -958,13 +971,7 @@ export function DateTimeInput({
958
971
  </button>
959
972
  )}
960
973
  {isBusy && <Spinner size="sm" />}
961
- {status && (
962
- <Icon
963
- icon={statusIconMap[status.type]}
964
- size="md"
965
- color={statusIconColorMap[status.type]}
966
- />
967
- )}
974
+ {statusIcon}
968
975
  </div>
969
976
 
970
977
  {/* Time input */}
@@ -972,14 +979,22 @@ export function DateTimeInput({
972
979
  ref={timeContainerRef}
973
980
  onClick={handleTimeWrapperClick}
974
981
  onMouseUp={handleTimeWrapperMouseUp}
975
- {...stylex.props(
976
- inputWrapperStyles.base,
977
- sizeStyles[size],
978
- styles.timeWrapper,
979
- isEffectivelyDisabled && inputWrapperStyles.disabled,
980
- status && inputStatusBorderStyles[status.type],
981
- status && inputStatusHoverShadowStyles[status.type],
982
- status && inputStatusFocusWithinStyles[status.type],
982
+ {...mergeProps(
983
+ themeProps('date-time-input-time-segment', {
984
+ size,
985
+ status: status?.type ?? null,
986
+ }),
987
+ stylex.props(
988
+ inputWrapperStyles.base,
989
+ sizeStyles[size],
990
+ styles.timeWrapper,
991
+ isEffectivelyDisabled && inputWrapperStyles.disabled,
992
+ status && inputStatusBorderStyles[status.type],
993
+ status &&
994
+ !isEffectivelyDisabled &&
995
+ inputStatusHoverShadowStyles[status.type],
996
+ status && inputStatusFocusWithinStyles[status.type],
997
+ ),
983
998
  )}>
984
999
  <div {...stylex.props(styles.icon)}>
985
1000
  <Icon icon="clock" size="sm" color="secondary" />
@@ -1000,7 +1015,9 @@ export function DateTimeInput({
1000
1015
  disabled={isEffectivelyDisabled && !showsDisabledMessage}
1001
1016
  aria-disabled={showsDisabledMessage ? 'true' : undefined}
1002
1017
  readOnly={showsDisabledMessage || undefined}
1003
- aria-label={timeLabel ?? t('@astryx.dateTimeInput.timeSuffix', {label})}
1018
+ aria-label={
1019
+ timeLabel ?? t('@astryx.dateTimeInput.timeSuffix', {label})
1020
+ }
1004
1021
  aria-describedby={ariaDescribedBy}
1005
1022
  aria-required={isRequired === true ? 'true' : undefined}
1006
1023
  aria-invalid={
@@ -111,7 +111,7 @@ export const docs = {
111
111
  { guidance: false, description: 'Use the fullscreen variant for simple confirmations; it is meant for complex content like editors or long forms.' },
112
112
  ],
113
113
  anatomy: [
114
- {name: 'Header', required: true, description: 'Title, optional subtitle, and close button. The title receives focus on open for accessibility.'},
114
+ {name: 'Header', required: true, description: 'Title, optional subtitle, and close button. The title receives focus on open and labels the dialog via aria-labelledby.'},
115
115
  {name: 'Body', required: true, description: 'The main content area: text, forms, lists, or any layout.'},
116
116
  {name: 'Footer', required: false, description: 'Action buttons like Save/Cancel or Accept/Decline, aligned to the end.'},
117
117
  {name: 'Backdrop', required: true, description: 'Semi-transparent overlay behind the dialog that blocks page interaction.'},
@@ -133,7 +133,7 @@ export const docsZh = {
133
133
  { guidance: false, description: 'Use the fullscreen variant for simple confirmations; it is meant for complex content like editors or long forms.' },
134
134
  ],
135
135
  anatomy: [
136
- {name: 'Header', required: true, description: 'Title, optional subtitle, and close button. The title receives focus on open for accessibility.'},
136
+ {name: 'Header', required: true, description: 'Title, optional subtitle, and close button. The title receives focus on open and labels the dialog via aria-labelledby.'},
137
137
  {name: 'Body', required: true, description: 'The main content area: text, forms, lists, or any layout.'},
138
138
  {name: 'Footer', required: false, description: 'Action buttons like Save/Cancel or Accept/Decline, aligned to the end.'},
139
139
  {name: 'Backdrop', required: true, description: 'Semi-transparent overlay behind the dialog that blocks page interaction.'},
@@ -212,10 +212,7 @@ describe('Dialog', () => {
212
212
 
213
213
  it('forwards additional props to dialog element', () => {
214
214
  render(
215
- <Dialog
216
- isOpen={true}
217
- onOpenChange={() => {}}
218
- data-testid="custom-dialog">
215
+ <Dialog isOpen={true} onOpenChange={() => {}} data-testid="custom-dialog">
219
216
  Content
220
217
  </Dialog>,
221
218
  );
@@ -267,6 +264,82 @@ describe('Dialog', () => {
267
264
  });
268
265
  });
269
266
 
267
+ describe('accessible name', () => {
268
+ it('is labelled by the DialogHeader title by default', () => {
269
+ render(
270
+ <Dialog isOpen={true} onOpenChange={() => {}}>
271
+ <DialogHeader title="Dialog title" />
272
+ </Dialog>,
273
+ );
274
+ const dialog = screen.getByRole('dialog');
275
+ const heading = screen.getByRole('heading', {name: 'Dialog title'});
276
+ expect(heading.id).not.toBe('');
277
+ expect(dialog).toHaveAttribute('aria-labelledby', heading.id);
278
+ expect(dialog).toHaveAccessibleName('Dialog title');
279
+ });
280
+
281
+ it('prefers a consumer-provided aria-label over the header title', () => {
282
+ render(
283
+ <Dialog isOpen={true} onOpenChange={() => {}} aria-label="Custom name">
284
+ <DialogHeader title="Dialog title" />
285
+ </Dialog>,
286
+ );
287
+ const dialog = screen.getByRole('dialog');
288
+ expect(dialog).not.toHaveAttribute('aria-labelledby');
289
+ expect(dialog).toHaveAccessibleName('Custom name');
290
+ });
291
+
292
+ it('prefers a consumer-provided aria-labelledby over the header title', () => {
293
+ render(
294
+ <>
295
+ <span id="external-label">External name</span>
296
+ <Dialog
297
+ isOpen={true}
298
+ onOpenChange={() => {}}
299
+ aria-labelledby="external-label">
300
+ <DialogHeader title="Dialog title" />
301
+ </Dialog>
302
+ </>,
303
+ );
304
+ const dialog = screen.getByRole('dialog');
305
+ expect(dialog).toHaveAttribute('aria-labelledby', 'external-label');
306
+ expect(dialog).toHaveAccessibleName('External name');
307
+ });
308
+
309
+ it('omits aria-labelledby and warns when open with no name source', () => {
310
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
311
+ try {
312
+ render(
313
+ <Dialog isOpen={true} onOpenChange={() => {}}>
314
+ Content
315
+ </Dialog>,
316
+ );
317
+ const dialog = screen.getByRole('dialog');
318
+ expect(dialog).not.toHaveAttribute('aria-labelledby');
319
+ expect(warnSpy).toHaveBeenCalledTimes(1);
320
+ expect(warnSpy).toHaveBeenCalledWith(
321
+ expect.stringContaining('accessible name'),
322
+ );
323
+ } finally {
324
+ warnSpy.mockRestore();
325
+ }
326
+ });
327
+
328
+ it('does not warn when the header provides a title', () => {
329
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
330
+ try {
331
+ render(
332
+ <Dialog isOpen={true} onOpenChange={() => {}}>
333
+ <DialogHeader title="Dialog title" />
334
+ </Dialog>,
335
+ );
336
+ expect(warnSpy).not.toHaveBeenCalled();
337
+ } finally {
338
+ warnSpy.mockRestore();
339
+ }
340
+ });
341
+ });
342
+
270
343
  describe('inner flex wrapper', () => {
271
344
  it('wraps children in a flex container for scroll support', () => {
272
345
  render(
@@ -16,7 +16,14 @@
16
16
  * - /packages/cli/templates/blocks/components/Dialog/ (showcase blocks)
17
17
  */
18
18
 
19
- import {useEffect, useMemo, useRef, type ReactNode} from 'react';
19
+ import {
20
+ useCallback,
21
+ useEffect,
22
+ useId,
23
+ useMemo,
24
+ useRef,
25
+ type ReactNode,
26
+ } from 'react';
20
27
  import type {BaseProps} from '../BaseProps';
21
28
  import * as stylex from '@stylexjs/stylex';
22
29
  import {useScrollLock} from '../hooks/useScrollLock';
@@ -39,6 +46,7 @@ import {
39
46
  } from '../Layout/padding.stylex';
40
47
  import type {SpacingStep} from '../utils/types';
41
48
  import {mergeProps, mergeRefs} from '../utils';
49
+ import {devWarn} from '../utils/devWarning';
42
50
  import {DialogContext} from './DialogContext';
43
51
  import {themeProps} from '../utils/themeProps';
44
52
 
@@ -152,7 +160,13 @@ const styles = stylex.create({
152
160
  open: {
153
161
  display: 'flex',
154
162
  opacity: 1,
155
- animationName: enterDirectional,
163
+ // Disable the entry keyframe animation under
164
+ // `prefers-reduced-motion: reduce` so the dialog appears instantly
165
+ // instead of translating/scaling in (same pattern as layerAnimations).
166
+ animationName: {
167
+ default: enterDirectional,
168
+ '@media (prefers-reduced-motion: reduce)': 'none',
169
+ },
156
170
  },
157
171
  // Backdrop using ::backdrop pseudo-element
158
172
  backdrop: {
@@ -312,6 +326,9 @@ export interface DialogProps extends BaseProps<HTMLDialogElement> {
312
326
  *
313
327
  * Designed to be used with Layout as its child for structured content.
314
328
  * Uses the browser's built-in modal behavior for optimal accessibility.
329
+ * When a DialogHeader is rendered inside, its title automatically names the
330
+ * dialog via aria-labelledby; pass `aria-label` or `aria-labelledby` to
331
+ * override.
315
332
  *
316
333
  * @example
317
334
  * ```
@@ -348,10 +365,47 @@ export function Dialog({
348
365
  const paddingToken = spacingStepToToken[effectivePadding] as SpacingToken;
349
366
 
350
367
  const isFullscreen = variant === 'fullscreen';
351
- const dialogContextValue = useMemo(() => ({isInline}), [isInline]);
368
+
369
+ // Default accessible name: publish a title id through DialogContext so a
370
+ // DialogHeader applies it to its heading (mirrors AlertDialog's explicit
371
+ // useId wiring). Whether to emit the default aria-labelledby is decided
372
+ // imperatively in the callback ref below by checking whether the title
373
+ // element actually rendered — so a dialog with no header never points at a
374
+ // missing id, and we avoid the extra render a registration-via-state effect
375
+ // would cost at the dialog level.
376
+ const titleId = useId();
377
+
378
+ const dialogContextValue = useMemo(
379
+ () => ({isInline, titleId}),
380
+ [isInline, titleId],
381
+ );
382
+
383
+ // Consumer-provided labels always win over the DialogHeader default.
384
+ const hasConsumerName =
385
+ props['aria-label'] != null || props['aria-labelledby'] != null;
352
386
 
353
387
  const dialogRef = useRef<HTMLDialogElement>(null);
354
388
 
389
+ // Callback ref on the <dialog>: sync the default aria-labelledby from the
390
+ // DialogHeader title (if one rendered) in the same commit, with no second
391
+ // render. Consumer aria-label/aria-labelledby win — when present we leave
392
+ // the attribute to the {...safeProps} spread and never touch it here.
393
+ const attachDialog = useCallback(
394
+ (node: HTMLDialogElement | null) => {
395
+ dialogRef.current = node;
396
+ if (!node || hasConsumerName) {
397
+ return;
398
+ }
399
+ const hasTitle = node.querySelector(`#${CSS.escape(titleId)}`) != null;
400
+ if (hasTitle) {
401
+ node.setAttribute('aria-labelledby', titleId);
402
+ } else {
403
+ node.removeAttribute('aria-labelledby');
404
+ }
405
+ },
406
+ [titleId, hasConsumerName],
407
+ );
408
+
355
409
  // Capture the element that was focused when the dialog opened,
356
410
  // for directional animation origin and focus restoration on close.
357
411
  const triggerElementRef = useRef<HTMLElement | null>(null);
@@ -440,6 +494,29 @@ export function Dialog({
440
494
  return () => dialog.removeEventListener('keydown', handleKeyDown);
441
495
  }, [isOpen, isInline, allowEscape, onOpenChange]);
442
496
 
497
+ // Dev-time guardrail: an open modal should always have an accessible name.
498
+ // The header-title check reads the DOM, so this stays in an effect; the ref
499
+ // keeps it to one warning per component instance.
500
+ const warnedUnnamedDialogRef = useRef(false);
501
+ useEffect(() => {
502
+ const hasHeaderTitle =
503
+ dialogRef.current?.querySelector(`#${CSS.escape(titleId)}`) != null;
504
+ if (
505
+ isOpen &&
506
+ !isInline &&
507
+ !hasConsumerName &&
508
+ !hasHeaderTitle &&
509
+ !warnedUnnamedDialogRef.current
510
+ ) {
511
+ warnedUnnamedDialogRef.current = true;
512
+ devWarn(
513
+ 'Dialog',
514
+ 'open dialog has no accessible name. Add a DialogHeader ' +
515
+ 'with a `title`, or pass `aria-label`/`aria-labelledby`.',
516
+ );
517
+ }
518
+ }, [isOpen, isInline, hasConsumerName, titleId]);
519
+
443
520
  // Handle backdrop click — when the user clicks the ::backdrop pseudo-element,
444
521
  // the event target is the <dialog> element itself; clicks on child content
445
522
  // always target the child. This avoids false positives from native browser
@@ -531,7 +608,11 @@ export function Dialog({
531
608
  ),
532
609
  className,
533
610
  style,
534
- )}>
611
+ )}
612
+ data-testid={
613
+ (props as Record<string, unknown>)['data-testid'] as
614
+ string | undefined
615
+ }>
535
616
  {innerContent}
536
617
  </div>
537
618
  );
@@ -541,7 +622,7 @@ export function Dialog({
541
622
 
542
623
  return (
543
624
  <dialog
544
- ref={mergeRefs(ref, dialogRef)}
625
+ ref={mergeRefs(ref, attachDialog)}
545
626
  {...safeProps}
546
627
  {...mergeProps(
547
628
  themeProps('dialog', {variant}),
@@ -566,6 +647,9 @@ export function Dialog({
566
647
  onClick={handleClick}
567
648
  onCancel={handleCancel}
568
649
  aria-modal="true"
650
+ // The default aria-labelledby (from a DialogHeader title) is set
651
+ // imperatively in `attachDialog`; a consumer-provided aria-labelledby
652
+ // flows through {...safeProps} above and wins.
569
653
  {...(purpose === 'required' ? {role: 'alertdialog'} : undefined)}>
570
654
  {innerContent}
571
655
  </dialog>
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @file DialogContext.ts
7
7
  * @input React context
8
- * @output Internal dialog context for child focus behavior
9
- * @position Dialog internals; consumed by focus-managing children
8
+ * @output Internal dialog context for child focus behavior and default labelling
9
+ * @position Dialog internals; consumed by focus-managing children and DialogHeader
10
10
  */
11
11
 
12
12
  import {createContext, use} from 'react';
@@ -14,6 +14,13 @@ import {createContext, use} from 'react';
14
14
  export interface DialogContextValue {
15
15
  /** Whether the dialog is rendered inline for docs/showcases. */
16
16
  isInline: boolean;
17
+ /**
18
+ * Id the DialogHeader title should render with so the dialog can name
19
+ * itself via aria-labelledby. The dialog detects the title element's
20
+ * presence directly (via a callback ref), so it only emits aria-labelledby
21
+ * when the title actually rendered — never pointing at a nonexistent id.
22
+ */
23
+ titleId?: string;
17
24
  }
18
25
 
19
26
  export const DialogContext = createContext<DialogContextValue | null>(null);
@@ -12,7 +12,7 @@ export const docs = {
12
12
  {
13
13
  name: 'title',
14
14
  type: 'string',
15
- description: 'Dialog title (receives focus on open).',
15
+ description: 'Dialog title (receives focus on open and labels the dialog via aria-labelledby).',
16
16
  },
17
17
  {
18
18
  name: 'subtitle',
@@ -158,7 +158,7 @@ export const docsDense = {
158
158
  displayName: 'Dialog Header',
159
159
  description: 'dialog header w/ title, optional subtitle, close button, start/end content slots',
160
160
  propDescriptions: {
161
- title: 'dialog title (receives focus on open)',
161
+ title: 'dialog title (focused on open; labels dialog via aria-labelledby)',
162
162
  subtitle: 'subtitle below title',
163
163
  onOpenChange: 'close button callback (omit=no button)',
164
164
  startContent: 'content before title (e.g. back button)',