@astryxdesign/core 0.1.9 → 0.2.0-canary.0e01213

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 (625) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/Avatar/Avatar.d.ts +42 -3
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +190 -59
  5. package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  8. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  9. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  10. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  11. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  12. package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -2
  13. package/dist/Banner/Banner.js +2 -2
  14. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  15. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
  16. package/dist/Breadcrumbs/index.d.ts +1 -0
  17. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  18. package/dist/Breadcrumbs/index.js +2 -1
  19. package/dist/Button/Button.d.ts +1 -1
  20. package/dist/Button/Button.d.ts.map +1 -1
  21. package/dist/Button/Button.js +6 -4
  22. package/dist/Calendar/Calendar.d.ts.map +1 -1
  23. package/dist/Calendar/Calendar.js +50 -9
  24. package/dist/Calendar/dayCellUtils.d.ts +4 -4
  25. package/dist/Calendar/dayCellUtils.js +2 -2
  26. package/dist/Calendar/styles.d.ts +30 -31
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +30 -31
  29. package/dist/Card/Card.js +1 -1
  30. package/dist/Carousel/Carousel.d.ts.map +1 -1
  31. package/dist/Carousel/Carousel.js +22 -12
  32. package/dist/Center/Center.d.ts +20 -3
  33. package/dist/Center/Center.d.ts.map +1 -1
  34. package/dist/Center/Center.js +10 -2
  35. package/dist/Chat/ChatComposerInput.js +1 -1
  36. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatDictationButton.js +3 -1
  38. package/dist/Chat/ChatLayout.d.ts +7 -0
  39. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  40. package/dist/Chat/ChatLayout.js +16 -5
  41. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  42. package/dist/Chat/ChatMessageBubble.js +8 -8
  43. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  44. package/dist/Chat/ChatToolCalls.js +10 -3
  45. package/dist/Chat/useTriggerMenu.js +2 -2
  46. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  47. package/dist/CheckboxInput/CheckboxInput.js +6 -6
  48. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  49. package/dist/CheckboxList/CheckboxListItem.js +19 -4
  50. package/dist/Citation/Citation.d.ts +22 -1
  51. package/dist/Citation/Citation.d.ts.map +1 -1
  52. package/dist/Citation/Citation.js +20 -6
  53. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  54. package/dist/CodeBlock/CodeBlock.js +16 -10
  55. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  56. package/dist/Collapsible/Collapsible.js +3 -1
  57. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  58. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  59. package/dist/CommandPalette/CommandPalette.js +42 -3
  60. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  61. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  62. package/dist/ContextMenu/ContextMenu.js +23 -5
  63. package/dist/ContextMenu/index.d.ts +1 -0
  64. package/dist/ContextMenu/index.d.ts.map +1 -1
  65. package/dist/ContextMenu/index.js +3 -1
  66. package/dist/DateInput/DateInput.d.ts +10 -2
  67. package/dist/DateInput/DateInput.d.ts.map +1 -1
  68. package/dist/DateInput/DateInput.js +33 -19
  69. package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
  70. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  71. package/dist/DateRangeInput/DateRangeInput.js +23 -20
  72. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  73. package/dist/DateTimeInput/DateTimeInput.js +23 -18
  74. package/dist/Divider/Divider.d.ts +2 -2
  75. package/dist/Divider/Divider.d.ts.map +1 -1
  76. package/dist/Divider/Divider.js +13 -0
  77. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  78. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  79. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  80. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +18 -12
  81. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  82. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +42 -64
  83. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
  85. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
  86. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  87. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
  88. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  89. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  90. package/dist/DropdownMenu/DropdownMenuRadioItem.js +10 -3
  91. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  92. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  93. package/dist/DropdownMenu/DropdownMenuSubMenu.js +435 -0
  94. package/dist/DropdownMenu/index.d.ts +10 -0
  95. package/dist/DropdownMenu/index.d.ts.map +1 -1
  96. package/dist/DropdownMenu/index.js +13 -0
  97. package/dist/DropdownMenu/menuItemHover.d.ts +24 -0
  98. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  99. package/dist/DropdownMenu/menuItemHover.js +34 -0
  100. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  101. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  102. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  103. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  104. package/dist/DropdownMenu/renderDropdownItems.js +27 -10
  105. package/dist/Field/Field.d.ts +3 -1
  106. package/dist/Field/Field.d.ts.map +1 -1
  107. package/dist/Field/Field.js +4 -1
  108. package/dist/Field/FieldLabel.d.ts +2 -1
  109. package/dist/Field/FieldLabel.d.ts.map +1 -1
  110. package/dist/Field/FieldLabel.js +9 -5
  111. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  112. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  113. package/dist/Field/inputStyles.stylex.js +1 -0
  114. package/dist/FieldStatus/FieldStatus.d.ts +10 -0
  115. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  116. package/dist/FieldStatus/FieldStatus.js +51 -5
  117. package/dist/FileInput/FileInput.d.ts +10 -2
  118. package/dist/FileInput/FileInput.d.ts.map +1 -1
  119. package/dist/FileInput/FileInput.js +93 -65
  120. package/dist/Heading/Heading.d.ts.map +1 -1
  121. package/dist/Heading/Heading.js +3 -2
  122. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  123. package/dist/HoverCard/useHoverCard.js +10 -4
  124. package/dist/Icon/Icon.d.ts +15 -1
  125. package/dist/Icon/Icon.d.ts.map +1 -1
  126. package/dist/Icon/Icon.js +19 -3
  127. package/dist/Item/Item.d.ts +16 -3
  128. package/dist/Item/Item.d.ts.map +1 -1
  129. package/dist/Item/Item.js +31 -6
  130. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  131. package/dist/Layer/layerAnimations.stylex.js +10 -2
  132. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  133. package/dist/Lightbox/Lightbox.js +34 -15
  134. package/dist/List/List.d.ts.map +1 -1
  135. package/dist/List/List.js +6 -3
  136. package/dist/List/ListItem.d.ts +11 -1
  137. package/dist/List/ListItem.d.ts.map +1 -1
  138. package/dist/List/ListItem.js +2 -0
  139. package/dist/Markdown/Markdown.d.ts.map +1 -1
  140. package/dist/Markdown/Markdown.js +7 -0
  141. package/dist/MetadataList/MetadataList.d.ts +1 -1
  142. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  143. package/dist/MetadataList/MetadataList.js +4 -2
  144. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  145. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  146. package/dist/MultiSelector/MultiSelector.js +87 -45
  147. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  148. package/dist/NumberInput/NumberInput.d.ts +10 -2
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +22 -17
  151. package/dist/Outline/Outline.js +2 -2
  152. package/dist/Pagination/Pagination.d.ts.map +1 -1
  153. package/dist/Pagination/Pagination.js +11 -3
  154. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  155. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  156. package/dist/PowerSearch/PowerSearch.js +2 -0
  157. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  158. package/dist/ProgressBar/ProgressBar.js +6 -1
  159. package/dist/RadioList/RadioList.d.ts +2 -2
  160. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  161. package/dist/RadioList/RadioListItem.js +5 -5
  162. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  163. package/dist/Resizable/ResizeHandle.js +49 -19
  164. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  165. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  166. package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
  167. package/dist/Selector/Selector.d.ts +8 -0
  168. package/dist/Selector/Selector.d.ts.map +1 -1
  169. package/dist/Selector/Selector.js +72 -19
  170. package/dist/SideNav/SideNav.d.ts.map +1 -1
  171. package/dist/SideNav/SideNav.js +5 -5
  172. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  173. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  174. package/dist/SideNav/SideNavItem.d.ts +1 -1
  175. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  176. package/dist/SideNav/SideNavItem.js +12 -10
  177. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  178. package/dist/Skeleton/Skeleton.js +2 -2
  179. package/dist/Slider/Slider.d.ts.map +1 -1
  180. package/dist/Slider/Slider.js +87 -34
  181. package/dist/Spinner/Spinner.d.ts +3 -2
  182. package/dist/Spinner/Spinner.d.ts.map +1 -1
  183. package/dist/Spinner/Spinner.js +11 -2
  184. package/dist/Switch/Switch.d.ts +8 -1
  185. package/dist/Switch/Switch.d.ts.map +1 -1
  186. package/dist/Switch/Switch.js +171 -91
  187. package/dist/TabList/Tab.js +2 -2
  188. package/dist/TabList/TabList.d.ts +2 -11
  189. package/dist/TabList/TabList.d.ts.map +1 -1
  190. package/dist/TabList/TabList.js +5 -9
  191. package/dist/TabList/TabListContext.d.ts +0 -5
  192. package/dist/TabList/TabListContext.d.ts.map +1 -1
  193. package/dist/TabList/TabListContext.js +0 -5
  194. package/dist/TabList/TabMenu.js +1 -1
  195. package/dist/Table/BaseTable.d.ts.map +1 -1
  196. package/dist/Table/BaseTable.js +30 -4
  197. package/dist/Table/TableCell.js +3 -3
  198. package/dist/Table/TableHeaderCell.js +3 -3
  199. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  200. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  201. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +18 -3
  202. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  203. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +58 -30
  204. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  205. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  206. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  207. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +15 -7
  208. package/dist/Table/plugins/tree/useTableTreeData.d.ts +11 -0
  209. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  210. package/dist/Table/plugins/tree/useTableTreeData.js +65 -25
  211. package/dist/Table/types.d.ts +32 -0
  212. package/dist/Table/types.d.ts.map +1 -1
  213. package/dist/Text/Text.d.ts +10 -1
  214. package/dist/Text/Text.d.ts.map +1 -1
  215. package/dist/Text/Text.js +25 -2
  216. package/dist/Text/index.d.ts +2 -2
  217. package/dist/Text/index.d.ts.map +1 -1
  218. package/dist/TextArea/TextArea.d.ts +10 -1
  219. package/dist/TextArea/TextArea.d.ts.map +1 -1
  220. package/dist/TextArea/TextArea.js +119 -52
  221. package/dist/TextInput/TextInput.d.ts +10 -2
  222. package/dist/TextInput/TextInput.d.ts.map +1 -1
  223. package/dist/TextInput/TextInput.js +20 -17
  224. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  225. package/dist/Thumbnail/Thumbnail.js +51 -45
  226. package/dist/TimeInput/TimeInput.d.ts +10 -2
  227. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  228. package/dist/TimeInput/TimeInput.js +17 -17
  229. package/dist/Timestamp/Timestamp.d.ts +31 -3
  230. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  231. package/dist/Timestamp/Timestamp.js +48 -77
  232. package/dist/Timestamp/formatInstant.d.ts +41 -0
  233. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  234. package/dist/Timestamp/formatInstant.js +177 -0
  235. package/dist/Timestamp/index.d.ts +1 -0
  236. package/dist/Timestamp/index.d.ts.map +1 -1
  237. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  238. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  239. package/dist/Timestamp/tooltipEntries.js +163 -0
  240. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  241. package/dist/Toast/ToastViewport.js +61 -9
  242. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  243. package/dist/ToggleButton/ToggleButton.js +3 -1
  244. package/dist/Token/Token.d.ts +34 -4
  245. package/dist/Token/Token.d.ts.map +1 -1
  246. package/dist/Token/Token.js +85 -45
  247. package/dist/Token/TokenLink.d.ts +62 -0
  248. package/dist/Token/TokenLink.d.ts.map +1 -0
  249. package/dist/Token/TokenLink.js +76 -0
  250. package/dist/Token/index.d.ts +1 -1
  251. package/dist/Token/index.d.ts.map +1 -1
  252. package/dist/Tokenizer/Tokenizer.d.ts +9 -2
  253. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  254. package/dist/Tokenizer/Tokenizer.js +4 -2
  255. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  256. package/dist/Tooltip/useTooltip.js +17 -1
  257. package/dist/TopNav/TopNavItem.d.ts +3 -1
  258. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavItem.js +30 -3
  260. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  261. package/dist/TopNav/TopNavMegaMenu.js +9 -3
  262. package/dist/TreeList/TreeList.d.ts.map +1 -1
  263. package/dist/TreeList/TreeList.js +1 -0
  264. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  265. package/dist/TreeList/TreeListBranches.js +8 -6
  266. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  267. package/dist/TreeList/TreeListItem.js +32 -14
  268. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  269. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  270. package/dist/Typeahead/BaseTypeahead.js +22 -11
  271. package/dist/Typeahead/Typeahead.d.ts +9 -2
  272. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  273. package/dist/Typeahead/Typeahead.js +11 -2
  274. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  275. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  276. package/dist/Typeahead/TypeaheadItem.js +20 -10
  277. package/dist/astryx.css +115 -35
  278. package/dist/astryx.umd.js +51 -51
  279. package/dist/astryx.umd.js.map +4 -4
  280. package/dist/hooks/containerReveal.pool.stylex.d.ts +281 -0
  281. package/dist/hooks/containerReveal.pool.stylex.d.ts.map +1 -0
  282. package/dist/hooks/containerReveal.pool.stylex.js +281 -0
  283. package/dist/hooks/index.d.ts +4 -0
  284. package/dist/hooks/index.d.ts.map +1 -1
  285. package/dist/hooks/index.js +3 -1
  286. package/dist/hooks/isRtlElement.d.ts +18 -0
  287. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  288. package/dist/hooks/isRtlElement.js +27 -0
  289. package/dist/hooks/useAnnounce.d.ts +3 -0
  290. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  291. package/dist/hooks/useAnnounce.js +39 -1
  292. package/dist/hooks/useContainerReveal.d.ts +83 -0
  293. package/dist/hooks/useContainerReveal.d.ts.map +1 -0
  294. package/dist/hooks/useContainerReveal.js +123 -0
  295. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  296. package/dist/hooks/useFocusTrap.js +52 -11
  297. package/dist/hooks/useGridFocus.d.ts +6 -1
  298. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  299. package/dist/hooks/useGridFocus.js +12 -9
  300. package/dist/hooks/useHotkeys.d.ts +9 -0
  301. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  302. package/dist/hooks/useHotkeys.js +9 -0
  303. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  304. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  305. package/dist/hooks/useInputStatusIcon.js +169 -0
  306. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  307. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  308. package/dist/hooks/useKeyboardHint.js +4 -2
  309. package/dist/hooks/useListFocus.d.ts +39 -1
  310. package/dist/hooks/useListFocus.d.ts.map +1 -1
  311. package/dist/hooks/useListFocus.js +54 -9
  312. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  313. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  314. package/dist/i18n/InternationalizationContext.js +3 -0
  315. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  316. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  317. package/dist/i18n/InternationalizationProvider.js +5 -1
  318. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  319. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  320. package/dist/i18n/getLocaleDirection.js +29 -0
  321. package/dist/i18n/index.d.ts +6 -0
  322. package/dist/i18n/index.d.ts.map +1 -1
  323. package/dist/i18n/index.js +7 -1
  324. package/dist/i18n/useDirection.d.ts +2 -0
  325. package/dist/i18n/useDirection.d.ts.map +1 -0
  326. package/dist/i18n/useDirection.js +27 -0
  327. package/dist/theme/defineTheme.d.ts +6 -0
  328. package/dist/theme/defineTheme.d.ts.map +1 -1
  329. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  330. package/dist/theme/derivedVarRegistry.js +13 -0
  331. package/dist/theme/expandColorScale.d.ts +19 -2
  332. package/dist/theme/expandColorScale.d.ts.map +1 -1
  333. package/dist/theme/expandColorScale.js +38 -10
  334. package/dist/theme/index.d.ts +3 -3
  335. package/dist/theme/index.d.ts.map +1 -1
  336. package/dist/theme/types.d.ts +39 -2
  337. package/dist/theme/types.d.ts.map +1 -1
  338. package/dist/utils/index.d.ts +1 -0
  339. package/dist/utils/index.d.ts.map +1 -1
  340. package/dist/utils/index.js +2 -1
  341. package/dist/utils/plainDate.d.ts +17 -0
  342. package/dist/utils/plainDate.d.ts.map +1 -1
  343. package/dist/utils/plainDate.js +23 -4
  344. package/dist/utils/rtlStyles.d.ts +24 -0
  345. package/dist/utils/rtlStyles.d.ts.map +1 -0
  346. package/dist/utils/rtlStyles.js +27 -0
  347. package/locales/en.json +120 -0
  348. package/locales/pseudo.json +90 -0
  349. package/package.json +8 -3
  350. package/src/Avatar/Avatar.doc.mjs +50 -3
  351. package/src/Avatar/Avatar.test.tsx +218 -0
  352. package/src/Avatar/Avatar.tsx +285 -79
  353. package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
  354. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  355. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  356. package/src/AvatarGroup/AvatarGroup.test.tsx +162 -2
  357. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  358. package/src/AvatarGroup/AvatarGroupOverflow.tsx +5 -2
  359. package/src/Banner/Banner.tsx +6 -6
  360. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  361. package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
  362. package/src/Breadcrumbs/index.ts +4 -0
  363. package/src/Button/Button.doc.mjs +0 -4
  364. package/src/Button/Button.test.tsx +16 -0
  365. package/src/Button/Button.tsx +6 -4
  366. package/src/Calendar/Calendar.test.tsx +170 -20
  367. package/src/Calendar/Calendar.tsx +73 -16
  368. package/src/Calendar/dayCellUtils.test.ts +18 -18
  369. package/src/Calendar/dayCellUtils.ts +2 -2
  370. package/src/Calendar/styles.ts +33 -39
  371. package/src/Card/Card.tsx +1 -1
  372. package/src/Carousel/Carousel.tsx +25 -6
  373. package/src/Center/Center.doc.mjs +38 -0
  374. package/src/Center/Center.test.tsx +75 -0
  375. package/src/Center/Center.tsx +37 -2
  376. package/src/Chat/ChatComposer.doc.mjs +2 -2
  377. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  378. package/src/Chat/ChatComposerInput.tsx +2 -2
  379. package/src/Chat/ChatDictationButton.tsx +7 -1
  380. package/src/Chat/ChatLayout.test.tsx +57 -0
  381. package/src/Chat/ChatLayout.tsx +26 -5
  382. package/src/Chat/ChatMessageBubble.tsx +15 -10
  383. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  384. package/src/Chat/ChatToolCalls.tsx +9 -2
  385. package/src/Chat/useTriggerMenu.tsx +1 -1
  386. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  387. package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
  388. package/src/CheckboxInput/CheckboxInput.tsx +21 -6
  389. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  390. package/src/CheckboxList/CheckboxList.test.tsx +94 -3
  391. package/src/CheckboxList/CheckboxListItem.tsx +17 -10
  392. package/src/Citation/Citation.doc.mjs +4 -3
  393. package/src/Citation/Citation.test.tsx +97 -0
  394. package/src/Citation/Citation.tsx +43 -11
  395. package/src/CodeBlock/CodeBlock.test.tsx +17 -0
  396. package/src/CodeBlock/CodeBlock.tsx +38 -11
  397. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  398. package/src/Collapsible/Collapsible.test.tsx +7 -0
  399. package/src/Collapsible/Collapsible.tsx +16 -6
  400. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  401. package/src/CommandPalette/CommandPalette.tsx +41 -2
  402. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  403. package/src/ContextMenu/ContextMenu.test.tsx +59 -2
  404. package/src/ContextMenu/ContextMenu.tsx +22 -11
  405. package/src/ContextMenu/index.ts +5 -0
  406. package/src/DateInput/DateInput.doc.mjs +25 -0
  407. package/src/DateInput/DateInput.test.tsx +230 -0
  408. package/src/DateInput/DateInput.tsx +51 -29
  409. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  410. package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
  411. package/src/DateRangeInput/DateRangeInput.tsx +42 -30
  412. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  413. package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
  414. package/src/DateTimeInput/DateTimeInput.tsx +44 -39
  415. package/src/Divider/Divider.test.tsx +32 -8
  416. package/src/Divider/Divider.tsx +14 -1
  417. package/src/DropdownMenu/DropdownMenu.doc.mjs +5 -2
  418. package/src/DropdownMenu/DropdownMenu.test.tsx +95 -0
  419. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  420. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +49 -66
  421. package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
  422. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
  423. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
  424. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +19 -4
  425. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +84 -2
  426. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  427. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +680 -0
  428. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +569 -0
  429. package/src/DropdownMenu/index.ts +16 -0
  430. package/src/DropdownMenu/menuItemHover.ts +40 -0
  431. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  432. package/src/DropdownMenu/renderDropdownItems.tsx +40 -14
  433. package/src/Field/Field.doc.mjs +4 -0
  434. package/src/Field/Field.tsx +14 -9
  435. package/src/Field/FieldLabel.test.tsx +25 -0
  436. package/src/Field/FieldLabel.tsx +12 -3
  437. package/src/Field/inputStyles.stylex.ts +2 -0
  438. package/src/FieldStatus/FieldStatus.doc.mjs +1 -0
  439. package/src/FieldStatus/FieldStatus.test.tsx +133 -0
  440. package/src/FieldStatus/FieldStatus.tsx +61 -4
  441. package/src/FileInput/FileInput.doc.mjs +23 -2
  442. package/src/FileInput/FileInput.test.tsx +104 -13
  443. package/src/FileInput/FileInput.tsx +106 -79
  444. package/src/Heading/Heading.tsx +2 -1
  445. package/src/HoverCard/useHoverCard.tsx +15 -3
  446. package/src/Icon/Icon.doc.mjs +13 -0
  447. package/src/Icon/Icon.test.tsx +89 -0
  448. package/src/Icon/Icon.tsx +51 -3
  449. package/src/Item/Item.doc.mjs +5 -0
  450. package/src/Item/Item.test.tsx +88 -0
  451. package/src/Item/Item.tsx +57 -11
  452. package/src/Layer/layerAnimations.stylex.ts +23 -0
  453. package/src/Lightbox/Lightbox.test.tsx +33 -0
  454. package/src/Lightbox/Lightbox.tsx +30 -10
  455. package/src/List/List.test.tsx +17 -29
  456. package/src/List/List.tsx +6 -1
  457. package/src/List/ListItem.doc.mjs +12 -0
  458. package/src/List/ListItem.tsx +13 -0
  459. package/src/Markdown/Markdown.test.tsx +21 -0
  460. package/src/Markdown/Markdown.tsx +4 -0
  461. package/src/MetadataList/MetadataList.test.tsx +24 -0
  462. package/src/MetadataList/MetadataList.tsx +6 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +20 -0
  464. package/src/MultiSelector/MultiSelector.test.tsx +436 -0
  465. package/src/MultiSelector/MultiSelector.tsx +133 -67
  466. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  467. package/src/NumberInput/NumberInput.doc.mjs +21 -0
  468. package/src/NumberInput/NumberInput.test.tsx +71 -0
  469. package/src/NumberInput/NumberInput.tsx +35 -26
  470. package/src/Outline/Outline.test.tsx +12 -12
  471. package/src/Outline/Outline.tsx +2 -2
  472. package/src/Pagination/Pagination.tsx +11 -3
  473. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  474. package/src/PowerSearch/PowerSearch.test.tsx +23 -0
  475. package/src/PowerSearch/PowerSearch.tsx +10 -1
  476. package/src/ProgressBar/ProgressBar.test.tsx +34 -0
  477. package/src/ProgressBar/ProgressBar.tsx +16 -1
  478. package/src/RadioList/RadioList.doc.mjs +6 -0
  479. package/src/RadioList/RadioList.test.tsx +26 -4
  480. package/src/RadioList/RadioList.tsx +2 -2
  481. package/src/RadioList/RadioListItem.tsx +12 -5
  482. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  483. package/src/Resizable/ResizeHandle.tsx +70 -20
  484. package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
  485. package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
  486. package/src/Selector/Selector.doc.mjs +15 -0
  487. package/src/Selector/Selector.test.tsx +400 -0
  488. package/src/Selector/Selector.tsx +95 -23
  489. package/src/SideNav/SideNav.tsx +1 -8
  490. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  491. package/src/SideNav/SideNavItem.tsx +5 -3
  492. package/src/Skeleton/Skeleton.test.tsx +16 -0
  493. package/src/Skeleton/Skeleton.tsx +13 -1
  494. package/src/Slider/Slider.doc.mjs +6 -0
  495. package/src/Slider/Slider.test.tsx +240 -12
  496. package/src/Slider/Slider.tsx +96 -23
  497. package/src/Spinner/Spinner.test.tsx +10 -8
  498. package/src/Spinner/Spinner.tsx +15 -5
  499. package/src/Switch/Switch.doc.mjs +142 -42
  500. package/src/Switch/Switch.test.tsx +111 -0
  501. package/src/Switch/Switch.tsx +149 -32
  502. package/src/TabList/Tab.tsx +2 -2
  503. package/src/TabList/TabList.doc.mjs +0 -6
  504. package/src/TabList/TabList.test.tsx +3 -15
  505. package/src/TabList/TabList.tsx +6 -17
  506. package/src/TabList/TabListContext.ts +0 -6
  507. package/src/TabList/TabMenu.tsx +2 -2
  508. package/src/Table/BaseTable.tsx +34 -2
  509. package/src/Table/Table.doc.mjs +11 -0
  510. package/src/Table/Table.test.tsx +85 -0
  511. package/src/Table/TableCell.tsx +3 -3
  512. package/src/Table/TableHeaderCell.tsx +3 -3
  513. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
  514. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
  515. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +48 -21
  516. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  517. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  518. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +38 -9
  519. package/src/Table/plugins/tree/useTableTreeData.test.tsx +161 -2
  520. package/src/Table/plugins/tree/useTableTreeData.tsx +71 -14
  521. package/src/Table/types.ts +33 -0
  522. package/src/Table/useTableRowExpansion.doc.mjs +55 -2
  523. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  524. package/src/Table/useTableTreeData.doc.mjs +9 -0
  525. package/src/Text/Heading.doc.mjs +3 -3
  526. package/src/Text/Text.doc.mjs +1 -1
  527. package/src/Text/Text.test.tsx +42 -0
  528. package/src/Text/Text.tsx +25 -1
  529. package/src/Text/index.ts +2 -6
  530. package/src/TextArea/TextArea.doc.mjs +23 -2
  531. package/src/TextArea/TextArea.test.tsx +132 -4
  532. package/src/TextArea/TextArea.tsx +161 -67
  533. package/src/TextInput/TextInput.doc.mjs +21 -0
  534. package/src/TextInput/TextInput.test.tsx +150 -0
  535. package/src/TextInput/TextInput.tsx +28 -25
  536. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  537. package/src/Thumbnail/Thumbnail.test.tsx +24 -1
  538. package/src/Thumbnail/Thumbnail.tsx +28 -35
  539. package/src/TimeInput/TimeInput.doc.mjs +21 -0
  540. package/src/TimeInput/TimeInput.test.tsx +23 -0
  541. package/src/TimeInput/TimeInput.tsx +24 -25
  542. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  543. package/src/Timestamp/Timestamp.test.tsx +371 -0
  544. package/src/Timestamp/Timestamp.tsx +96 -93
  545. package/src/Timestamp/formatInstant.ts +218 -0
  546. package/src/Timestamp/index.ts +4 -0
  547. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  548. package/src/Timestamp/tooltipEntries.ts +210 -0
  549. package/src/Toast/ToastViewport.test.tsx +218 -8
  550. package/src/Toast/ToastViewport.tsx +71 -12
  551. package/src/ToggleButton/ToggleButton.test.tsx +24 -0
  552. package/src/ToggleButton/ToggleButton.tsx +19 -1
  553. package/src/Token/Token.test.tsx +166 -15
  554. package/src/Token/Token.tsx +104 -47
  555. package/src/Token/TokenLink.tsx +107 -0
  556. package/src/Token/index.ts +1 -1
  557. package/src/Tokenizer/Tokenizer.doc.mjs +23 -1
  558. package/src/Tokenizer/Tokenizer.test.tsx +23 -0
  559. package/src/Tokenizer/Tokenizer.tsx +14 -2
  560. package/src/Tooltip/Tooltip.test.tsx +46 -0
  561. package/src/Tooltip/useTooltip.tsx +20 -0
  562. package/src/TopNav/TopNav.test.tsx +93 -2
  563. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  564. package/src/TopNav/TopNavItem.tsx +35 -6
  565. package/src/TopNav/TopNavMegaMenu.tsx +26 -2
  566. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
  567. package/src/TreeList/TreeList.doc.mjs +6 -0
  568. package/src/TreeList/TreeList.test.tsx +50 -10
  569. package/src/TreeList/TreeList.tsx +5 -0
  570. package/src/TreeList/TreeListBranches.tsx +8 -6
  571. package/src/TreeList/TreeListItem.tsx +33 -11
  572. package/src/Typeahead/BaseTypeahead.tsx +42 -15
  573. package/src/Typeahead/Typeahead.doc.mjs +13 -0
  574. package/src/Typeahead/Typeahead.test.tsx +112 -0
  575. package/src/Typeahead/Typeahead.tsx +17 -1
  576. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  577. package/src/__tests__/babelPluginAddExtensions.test.ts +190 -0
  578. package/src/__tests__/forcedColors.ts +60 -0
  579. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  580. package/src/doc-mjs.d.ts +19 -0
  581. package/src/hooks/containerReveal.pool.stylex.ts +464 -0
  582. package/src/hooks/index.ts +13 -0
  583. package/src/hooks/isRtlElement.ts +27 -0
  584. package/src/hooks/useAnnounce.test.tsx +75 -2
  585. package/src/hooks/useAnnounce.ts +47 -1
  586. package/src/hooks/useContainerReveal.test.tsx +116 -0
  587. package/src/hooks/useContainerReveal.ts +180 -0
  588. package/src/hooks/useFocusTrap.test.tsx +104 -0
  589. package/src/hooks/useFocusTrap.ts +61 -12
  590. package/src/hooks/useGridFocus.doc.mjs +3 -3
  591. package/src/hooks/useGridFocus.test.tsx +41 -0
  592. package/src/hooks/useGridFocus.ts +21 -10
  593. package/src/hooks/useHotkeys.ts +9 -0
  594. package/src/hooks/useInputStatusIcon.test.tsx +221 -0
  595. package/src/hooks/useInputStatusIcon.tsx +235 -0
  596. package/src/hooks/useKeyboardHint.test.tsx +22 -0
  597. package/src/hooks/useKeyboardHint.tsx +6 -2
  598. package/src/hooks/useListFocus.doc.mjs +25 -3
  599. package/src/hooks/useListFocus.test.tsx +153 -1
  600. package/src/hooks/useListFocus.ts +102 -9
  601. package/src/i18n/InternationalizationContext.ts +4 -0
  602. package/src/i18n/InternationalizationProvider.tsx +12 -2
  603. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  604. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  605. package/src/i18n/getLocaleDirection.ts +29 -0
  606. package/src/i18n/index.ts +6 -0
  607. package/src/i18n/useDirection.ts +29 -0
  608. package/src/reset.css +0 -26
  609. package/src/reset.test.ts +60 -0
  610. package/src/theme/defineTheme.ts +6 -0
  611. package/src/theme/derivedVarRegistry.test.ts +1 -0
  612. package/src/theme/derivedVarRegistry.ts +6 -0
  613. package/src/theme/expandColorScale.test.ts +144 -0
  614. package/src/theme/expandColorScale.ts +53 -15
  615. package/src/theme/generateThemeRules.test.ts +42 -0
  616. package/src/theme/index.ts +4 -8
  617. package/src/theme/types.ts +43 -13
  618. package/src/utils/index.ts +2 -0
  619. package/src/utils/plainDate.test.ts +24 -6
  620. package/src/utils/plainDate.ts +18 -4
  621. package/src/utils/rtlStyles.ts +27 -0
  622. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +0 -9
  623. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +0 -1
  624. package/dist/Thumbnail/thumbnail.markers.stylex.js +0 -14
  625. package/src/Thumbnail/thumbnail.markers.stylex.ts +0 -12
@@ -415,6 +415,41 @@ describe('DropdownMenu dividers', () => {
415
415
  });
416
416
  });
417
417
 
418
+ describe('DropdownMenu theming slots', () => {
419
+ it('exposes a themeable slot on the section heading', () => {
420
+ render(
421
+ <DropdownMenu
422
+ button={{label: 'Actions'}}
423
+ items={[
424
+ {
425
+ type: 'section',
426
+ title: 'File Actions',
427
+ items: [{label: 'New'}],
428
+ },
429
+ ]}
430
+ />,
431
+ );
432
+
433
+ expect(screen.getByText('File Actions')).toHaveClass(
434
+ 'astryx-dropdown-menu-section-heading',
435
+ );
436
+ });
437
+
438
+ it('exposes a themeable slot on the menu divider', () => {
439
+ render(
440
+ <DropdownMenu
441
+ button={{label: 'Actions'}}
442
+ items={[{label: 'Edit'}, {type: 'divider'}, {label: 'Delete'}]}
443
+ />,
444
+ );
445
+
446
+ const divider = screen.getByRole('separator', {hidden: true});
447
+ expect(divider).toHaveClass('astryx-dropdown-menu-divider');
448
+ // Still carries the base Divider slot so global divider theming applies too.
449
+ expect(divider).toHaveClass('astryx-divider');
450
+ });
451
+ });
452
+
418
453
  describe('DropdownMenu button customization', () => {
419
454
  it('renders with different button variants', () => {
420
455
  const {rerender} = render(
@@ -781,4 +816,64 @@ describe('DropdownMenu keyboard access for menuitemradio/menuitemcheckbox (#3829
781
816
  screen.getByRole('menuitemradio', {name: 'Oldest', hidden: true}),
782
817
  ).toHaveFocus();
783
818
  });
819
+
820
+ it('moves focus to the item the mouse hovers, keeping a single highlight', async () => {
821
+ const user = userEvent.setup();
822
+ render(
823
+ <DropdownMenu button={{label: 'Actions'}}>
824
+ <DropdownMenuItem label="Edit" onClick={() => {}} />
825
+ <DropdownMenuItem label="Duplicate" onClick={() => {}} />
826
+ <DropdownMenuItem label="Delete" onClick={() => {}} />
827
+ </DropdownMenu>,
828
+ );
829
+
830
+ await user.click(screen.getByRole('button', {name: /Actions/}));
831
+ // Keyboard focus starts on the first item.
832
+ const edit = screen.getByRole('menuitem', {name: 'Edit', hidden: true});
833
+ const del = screen.getByRole('menuitem', {name: 'Delete', hidden: true});
834
+ edit.focus();
835
+ expect(edit).toHaveFocus();
836
+
837
+ // A mouse hover over another item moves focus to it, so the single
838
+ // focus-driven highlight follows the pointer instead of leaving two.
839
+ fireEvent.pointerMove(del, {pointerType: 'mouse'});
840
+ expect(del).toHaveFocus();
841
+ expect(edit).not.toHaveFocus();
842
+ });
843
+
844
+ it('does not move focus on hover for a disabled item', async () => {
845
+ const user = userEvent.setup();
846
+ render(
847
+ <DropdownMenu button={{label: 'Actions'}}>
848
+ <DropdownMenuItem label="Edit" onClick={() => {}} />
849
+ <DropdownMenuItem label="Delete" isDisabled onClick={() => {}} />
850
+ </DropdownMenu>,
851
+ );
852
+
853
+ await user.click(screen.getByRole('button', {name: /Actions/}));
854
+ const edit = screen.getByRole('menuitem', {name: 'Edit', hidden: true});
855
+ const del = screen.getByRole('menuitem', {name: 'Delete', hidden: true});
856
+ edit.focus();
857
+
858
+ fireEvent.pointerMove(del, {pointerType: 'mouse'});
859
+ expect(edit).toHaveFocus();
860
+ });
861
+
862
+ it('does not move focus for a non-mouse (touch) pointer', async () => {
863
+ const user = userEvent.setup();
864
+ render(
865
+ <DropdownMenu button={{label: 'Actions'}}>
866
+ <DropdownMenuItem label="Edit" onClick={() => {}} />
867
+ <DropdownMenuItem label="Delete" onClick={() => {}} />
868
+ </DropdownMenu>,
869
+ );
870
+
871
+ await user.click(screen.getByRole('button', {name: /Actions/}));
872
+ const edit = screen.getByRole('menuitem', {name: 'Edit', hidden: true});
873
+ const del = screen.getByRole('menuitem', {name: 'Delete', hidden: true});
874
+ edit.focus();
875
+
876
+ fireEvent.pointerMove(del, {pointerType: 'touch'});
877
+ expect(edit).toHaveFocus();
878
+ });
784
879
  });
@@ -38,7 +38,11 @@ import {Icon} from '../Icon';
38
38
  import type {IconType} from '../Icon';
39
39
 
40
40
  import {renderDropdownItems} from './renderDropdownItems';
41
- import {MENU_ITEM_ROLES, MENU_ITEM_SELECTOR} from './menuItemRoles';
41
+ import {
42
+ MENU_ITEM_ROLES,
43
+ MENU_ITEM_SELECTOR,
44
+ MENU_BOUNDARY_SELECTOR,
45
+ } from './menuItemRoles';
42
46
  import {
43
47
  DropdownMenuContext,
44
48
  type DropdownMenuContextValue,
@@ -100,6 +104,12 @@ export interface DropdownMenuItemData {
100
104
  onClick?: () => void;
101
105
  isDisabled?: boolean;
102
106
  icon?: ReactNode | IconType;
107
+ /**
108
+ * Nested submenu entries. When present, this row becomes a submenu (a
109
+ * flyout revealing `items`) instead of a leaf action — no separate item
110
+ * "type" is needed. Data-mode parity for the compound DropdownMenuSubMenu API.
111
+ */
112
+ items?: DropdownMenuOption[];
103
113
  }
104
114
 
105
115
  export interface DropdownMenuDivider {
@@ -200,6 +210,14 @@ export function DropdownMenu({
200
210
  const items = ('items' in props ? props.items : undefined) ?? [];
201
211
  const children = props.children;
202
212
 
213
+ // Extract BaseProps pass-throughs (aria-*, id, event handlers) from the
214
+ // discriminated-union rest bag so they can be forwarded to the menu element.
215
+ const {
216
+ items: _items,
217
+ children: _children,
218
+ ...rest
219
+ } = props as Record<string, unknown>;
220
+
203
221
  const menuId = useId();
204
222
  const menuSize = button.size ?? 'md';
205
223
  const buttonRef = useRef<HTMLButtonElement>(null);
@@ -265,23 +283,18 @@ export function DropdownMenu({
265
283
  handleKeyDown: listNavKeyDown,
266
284
  focusFirst,
267
285
  focusItem,
286
+ ownsEvent,
287
+ getItems: getMenuItems,
268
288
  } = useListFocus<HTMLDivElement>({
269
289
  itemSelector: MENU_ITEM_SELECTOR,
290
+ boundarySelector: MENU_BOUNDARY_SELECTOR,
270
291
  wrap: false,
271
292
  onEscape: closeMenu,
272
293
  });
273
294
 
274
295
  // First-character typeahead over the (enabled) menu items — jump to the next
275
- // item whose label starts with the typed text (menus-11).
276
- const getMenuItems = useCallback(
277
- (): HTMLElement[] =>
278
- listRef.current
279
- ? Array.from(
280
- listRef.current.querySelectorAll<HTMLElement>(MENU_ITEM_SELECTOR),
281
- )
282
- : [],
283
- [listRef],
284
- );
296
+ // item whose label starts with the typed text (menus-11). Reuses the hook's
297
+ // scoped item collection so an inline submenu flyout's items aren't swept in.
285
298
  const typeahead = useTypeahead({
286
299
  getItemLabels: () => getMenuItems().map(el => el.textContent),
287
300
  onMatch: focusItem,
@@ -307,6 +320,11 @@ export function DropdownMenu({
307
320
  // Extend useListFocus with Enter/Space activation + typeahead
308
321
  const listKeyDown = useCallback(
309
322
  (e: React.KeyboardEvent) => {
323
+ // A submenu flyout renders inline inside this menu; its key events bubble
324
+ // up here. Let that level own them — only handle events from this level.
325
+ if (!ownsEvent(e)) {
326
+ return;
327
+ }
310
328
  if (e.key === 'Enter' || e.key === ' ') {
311
329
  e.preventDefault();
312
330
  const focused = document.activeElement as HTMLElement | null;
@@ -334,7 +352,7 @@ export function DropdownMenu({
334
352
  }
335
353
  listNavKeyDown(e);
336
354
  },
337
- [listNavKeyDown, closeMenu, typeahead],
355
+ [listNavKeyDown, closeMenu, typeahead, ownsEvent],
338
356
  );
339
357
 
340
358
  const openAndFocus = useCallback(() => {
@@ -435,6 +453,7 @@ export function DropdownMenu({
435
453
 
436
454
  {popover.render(
437
455
  <div
456
+ {...rest}
438
457
  ref={listRef}
439
458
  id={menuId}
440
459
  role="menu"
@@ -4,38 +4,39 @@
4
4
 
5
5
  /**
6
6
  * @file DropdownMenuCheckboxItem.tsx
7
- * @input React, stylex, Item + Icon + DropdownMenu context + tokens from core
7
+ * @input React, stylex, Item + CheckboxInput + DropdownMenu context + tokens from core
8
8
  * @output DropdownMenuCheckboxItem — a standalone checkable menu item.
9
9
  * @position Sub-component; used inside DropdownMenu.
10
10
  *
11
11
  * A menu item that toggles an independent boolean (role="menuitemcheckbox").
12
- * Unlike CheckboxInput, there is no nested native <input>: the row itself owns
13
- * the role and aria-checked, per the WAI-ARIA menuitemcheckbox pattern.
14
- * Keyboard navigation (arrows/typeahead) and Enter/Space activation come from
15
- * the parent DropdownMenu's useListFocus + activation path, which matches
16
- * menuitemcheckbox alongside plain menuitem rows.
12
+ * Unlike CheckboxInput, there is no nested native <input> that participates in
13
+ * accessibility: the row itself owns the role and aria-checked, per the
14
+ * WAI-ARIA menuitemcheckbox pattern. Keyboard navigation (arrows/typeahead) and
15
+ * Enter/Space activation come from the parent DropdownMenu's useListFocus +
16
+ * activation path, which matches menuitemcheckbox alongside plain menuitem rows.
17
17
  *
18
- * The square checkbox visual is decorative (aria-hidden) — the row owns the
19
- * checked state. Its size is derived from the menu's item size (a `sm` menu
20
- * gets the compact control; `md`/`lg` get the standard one) and it swaps to the
21
- * inline-end of the row on coarse-pointer (touch) devices via CSS `order`, so
22
- * it lands where selection toggles are conventionally placed on mobile. The
23
- * checkmark uses the `check` icon from the active theme's icon registry.
18
+ * The checkbox visual composes the real CheckboxInput primitive so its checkmark
19
+ * matches CheckboxListItem and picks up the standard `checkbox` theming slots.
20
+ * It is purely decorative: the composed control is wrapped in an element that is
21
+ * both `aria-hidden` and `inert`, so it contributes nothing to the row's
22
+ * accessible name, and its native <input> and sr-only label stay out of the tab
23
+ * order and the accessibility tree while pointer clicks fall through to the row
24
+ * — the same shim MultiSelector uses. The row owns the checked state and
25
+ * accessible name. The control size is derived from the menu's item size (a
26
+ * `sm` menu gets the compact control; `md`/`lg` get the standard one) and it
27
+ * swaps to the inline-end of the row on coarse-pointer (touch) devices via CSS
28
+ * `order`, so it lands where selection toggles are conventionally placed on
29
+ * mobile.
24
30
  */
25
31
 
26
- import {useCallback, type ReactNode} from 'react';
32
+ import {useCallback, type PointerEvent, type ReactNode} from 'react';
27
33
  import * as stylex from '@stylexjs/stylex';
28
- import {Icon, renderIconSlot, type IconType} from '../Icon';
34
+ import {renderIconSlot, type IconType} from '../Icon';
35
+ import {CheckboxInput} from '../CheckboxInput/CheckboxInput';
29
36
  import {Item} from '../Item';
30
37
  import {useDropdownMenuContext} from './DropdownMenuContext';
31
- import {
32
- colorVars,
33
- spacingVars,
34
- radiusVars,
35
- durationVars,
36
- easeVars,
37
- borderVars,
38
- } from '../theme/tokens.stylex';
38
+ import {focusMenuItemOnHover} from './menuItemHover';
39
+ import {colorVars, spacingVars} from '../theme/tokens.stylex';
39
40
  import {mergeProps, themeProps} from '../utils';
40
41
  import type {BaseProps} from '../BaseProps';
41
42
 
@@ -47,7 +48,6 @@ const styles = stylex.create({
47
48
  backgroundColor: {
48
49
  default: 'transparent',
49
50
  ':focus': colorVars['--color-overlay-hover'],
50
- ':hover': colorVars['--color-overlay-hover'],
51
51
  },
52
52
  cursor: 'pointer',
53
53
  outline: 'none',
@@ -58,22 +58,13 @@ const styles = stylex.create({
58
58
  },
59
59
  // Rendered in Item's `marker` slot as a raw flex child, so `order` moves it
60
60
  // relative to the label within the row. On touch it moves to the inline-end.
61
- box: {
61
+ // `aria-hidden` + `inert` + pointer-events:none keep the composed CheckboxInput
62
+ // decorative: it adds no accessible name, and clicks fall through to the row,
63
+ // which owns the role and activation.
64
+ markerBox: {
62
65
  display: 'flex',
63
- alignItems: 'center',
64
- justifyContent: 'center',
65
66
  flexShrink: 0,
66
- boxSizing: 'border-box',
67
- borderWidth: borderVars['--border-width'],
68
- borderStyle: 'solid',
69
- borderRadius: radiusVars['--radius-inner'],
70
- color: colorVars['--color-on-accent'],
71
- transitionProperty: 'background-color, border-color',
72
- transitionDuration: {
73
- default: durationVars['--duration-fast'],
74
- '@media (prefers-reduced-motion: reduce)': '0s',
75
- },
76
- transitionTimingFunction: easeVars['--ease-standard'],
67
+ pointerEvents: 'none',
77
68
  order: {
78
69
  default: 0,
79
70
  '@media (pointer: coarse)': 1,
@@ -83,19 +74,6 @@ const styles = stylex.create({
83
74
  '@media (pointer: coarse)': 'auto',
84
75
  },
85
76
  },
86
- unchecked: {
87
- borderColor: colorVars['--color-border-emphasized'],
88
- backgroundColor: colorVars['--color-background-surface'],
89
- },
90
- checked: {
91
- borderColor: colorVars['--color-accent'],
92
- backgroundColor: colorVars['--color-accent'],
93
- },
94
- });
95
-
96
- const boxSizeStyles = stylex.create({
97
- sm: {width: 18, height: 18},
98
- md: {width: 22, height: 22},
99
77
  });
100
78
 
101
79
  export interface DropdownMenuCheckboxItemProps extends Omit<
@@ -180,6 +158,12 @@ export function DropdownMenuCheckboxItem({
180
158
  const menuSize = ctx?.menuSize ?? 'md';
181
159
  const controlSize = menuSize === 'sm' ? 'sm' : 'md';
182
160
 
161
+ // The composed checkbox is decorative and inert, so its label never reaches
162
+ // the accessibility tree — the row's `label` prop provides the announced
163
+ // name. CheckboxInput still requires a string label, so pass one through when
164
+ // the row label is a plain string.
165
+ const checkboxLabel = typeof label === 'string' ? label : '';
166
+
183
167
  const handleClick = useCallback(() => {
184
168
  if (isDisabled) {
185
169
  return;
@@ -190,29 +174,28 @@ export function DropdownMenuCheckboxItem({
190
174
  }
191
175
  }, [isDisabled, onChange, value, hasCloseOnSelect, ctx]);
192
176
 
177
+ const handlePointerMove = useCallback(
178
+ (e: PointerEvent<HTMLElement>) => focusMenuItemOnHover(e, isDisabled),
179
+ [isDisabled],
180
+ );
181
+
193
182
  return (
194
183
  <Item
195
184
  {...rest}
196
185
  role="menuitemcheckbox"
197
186
  aria-checked={value}
198
187
  tabIndex={isDisabled ? undefined : -1}
188
+ onPointerMove={handlePointerMove}
199
189
  marker={
200
- <span
201
- aria-hidden="true"
202
- {...mergeProps(
203
- themeProps('dropdown-menu-checkbox', {
204
- size: controlSize,
205
- checked: value ? 'checked' : null,
206
- disabled: isDisabled ? 'disabled' : null,
207
- }),
208
- stylex.props(
209
- styles.box,
210
- boxSizeStyles[controlSize],
211
- value ? styles.checked : styles.unchecked,
212
- ),
213
- )}>
214
- {value && <Icon icon="check" size="sm" color="inherit" />}
215
- </span>
190
+ <div aria-hidden="true" inert {...stylex.props(styles.markerBox)}>
191
+ <CheckboxInput
192
+ label={checkboxLabel}
193
+ isLabelHidden
194
+ value={value}
195
+ isDisabled={isDisabled}
196
+ size={controlSize}
197
+ />
198
+ </div>
216
199
  }
217
200
  startContent={
218
201
  icon
@@ -23,7 +23,7 @@
23
23
  * - /packages/cli/templates/blocks/components/DropdownMenu/ (showcase blocks)
24
24
  */
25
25
 
26
- import {useCallback, type ReactNode} from 'react';
26
+ import {useCallback, type PointerEvent, type ReactNode} from 'react';
27
27
  import * as stylex from '@stylexjs/stylex';
28
28
  import {renderIconSlot, type IconType} from '../Icon';
29
29
  import {Item} from '../Item';
@@ -36,6 +36,7 @@ import {
36
36
  import {mergeProps} from '../utils';
37
37
  import type {BaseProps} from '../BaseProps';
38
38
  import {useDropdownMenuContext} from './DropdownMenuContext';
39
+ import {focusMenuItemOnHover} from './menuItemHover';
39
40
  import {themeProps} from '../utils/themeProps';
40
41
 
41
42
  const menuItemStyles = stylex.create({
@@ -51,11 +52,10 @@ const menuItemStyles = stylex.create({
51
52
  backgroundColor: {
52
53
  default: 'transparent',
53
54
  ':focus': colorVars['--color-overlay-hover'],
54
- ':hover': colorVars['--color-overlay-hover'],
55
55
  },
56
56
  border: 'none',
57
57
  cursor: 'pointer',
58
- textAlign: 'left',
58
+ textAlign: 'start',
59
59
  outline: 'none',
60
60
  },
61
61
  disabled: {
@@ -129,10 +129,16 @@ export function DropdownMenuItem({
129
129
  ctx?.closeMenu();
130
130
  }, [isDisabled, onClick, ctx]);
131
131
 
132
+ const handlePointerMove = useCallback(
133
+ (e: PointerEvent<HTMLElement>) => focusMenuItemOnHover(e, isDisabled),
134
+ [isDisabled],
135
+ );
136
+
132
137
  return (
133
138
  <Item
134
139
  role="menuitem"
135
140
  tabIndex={isDisabled ? undefined : -1}
141
+ onPointerMove={handlePointerMove}
136
142
  startContent={
137
143
  icon
138
144
  ? renderIconSlot(icon, {size: 'sm', color: 'secondary'})
@@ -22,16 +22,10 @@ export const docs = {
22
22
  description: 'Callback fired when the selected value changes.',
23
23
  },
24
24
  {
25
- name: 'aria-label',
25
+ name: 'label',
26
26
  type: 'string',
27
27
  description:
28
- 'Accessible label for the group. Required (or aria-labelledby) so screen readers announce the radios as a named set, e.g. "Sort by".',
29
- },
30
- {
31
- name: 'aria-labelledby',
32
- type: 'string',
33
- description:
34
- 'The id of an element that labels the group, as an alternative to aria-label.',
28
+ 'Accessible name for the group, applied as aria-label so screen readers announce the radios as a named set, e.g. "Sort by". Required. Pass aria-labelledby (via base props) instead when the name already exists as a visible element.',
35
29
  },
36
30
  {
37
31
  name: 'hasCloseOnSelect',
@@ -57,8 +51,7 @@ export const docsZh = {
57
51
  propDescriptions: {
58
52
  value: '组中当前选中的值。尚无选中项时传 undefined。',
59
53
  onChange: '所选值变化时触发的回调。',
60
- 'aria-label': '组的无障碍标签。必需(或 aria-labelledby),以便屏幕阅读器将单选项作为命名集合朗读。',
61
- 'aria-labelledby': '标记该组的元素 id,作为 aria-label 的替代。',
54
+ label: '组的无障碍名称,作为 aria-label 应用,以便屏幕阅读器将单选项作为命名集合朗读,例如“Sort by”。必需。当名称已作为可见元素存在时,可改用 aria-labelledby(通过基础属性)。',
62
55
  hasCloseOnSelect: '选择某值是否关闭菜单。默认关闭。',
63
56
  children: '组成该组的 DropdownMenuRadioItem。',
64
57
  },
@@ -72,8 +65,7 @@ export const docsDense = {
72
65
  propDescriptions: {
73
66
  value: 'selected value (undefined = none)',
74
67
  onChange: 'fired when selected value changes',
75
- 'aria-label': 'accessible group name (or aria-labelledby); required',
76
- 'aria-labelledby': 'id of labelling element (alt to aria-label)',
68
+ label: 'accessible group name (applied as aria-label); required',
77
69
  hasCloseOnSelect: 'close menu on select (default true)',
78
70
  children: 'the DropdownMenuRadioItems',
79
71
  },
@@ -49,16 +49,13 @@ export interface DropdownMenuRadioGroupProps extends Omit<
49
49
  */
50
50
  onChange: (value: string) => void;
51
51
  /**
52
- * Accessible label for the group. Required (together with `aria-labelledby`,
53
- * one of the two) so screen readers announce the radios as a named set,
54
- * e.g. "Sort by".
52
+ * Accessible name for the group, announced by screen readers so the radios
53
+ * read as a named set (e.g. "Sort by"). Applied as the group's `aria-label`.
54
+ * Required -- an unnamed radio group is an accessibility defect. Pass
55
+ * `aria-labelledby` (via base props) instead if the name already exists as a
56
+ * visible element on the page.
55
57
  */
56
- 'aria-label'?: string;
57
- /**
58
- * The id of an element that labels the group, as an alternative to
59
- * `aria-label`.
60
- */
61
- 'aria-labelledby'?: string;
58
+ label: string;
62
59
  /**
63
60
  * Whether selecting a value closes the menu. Radio items default to closing
64
61
  * on selection (a single-choice commit), unlike checkbox items which stay
@@ -82,7 +79,7 @@ export interface DropdownMenuRadioGroupProps extends Omit<
82
79
  * DropdownMenuRadioItem,
83
80
  * } from '@astryxdesign/core/DropdownMenu';
84
81
  * <DropdownMenu button={{label: 'Sort'}}>
85
- * <DropdownMenuRadioGroup value={sort} onChange={setSort} aria-label="Sort by">
82
+ * <DropdownMenuRadioGroup value={sort} onChange={setSort} label="Sort by">
86
83
  * <DropdownMenuRadioItem value="newest" label="Newest" />
87
84
  * <DropdownMenuRadioItem value="oldest" label="Oldest" />
88
85
  * </DropdownMenuRadioGroup>
@@ -92,6 +89,7 @@ export interface DropdownMenuRadioGroupProps extends Omit<
92
89
  export function DropdownMenuRadioGroup({
93
90
  value,
94
91
  onChange,
92
+ label,
95
93
  hasCloseOnSelect = true,
96
94
  children,
97
95
  className,
@@ -107,6 +105,7 @@ export function DropdownMenuRadioGroup({
107
105
  <div
108
106
  {...rest}
109
107
  role="group"
108
+ aria-label={label}
110
109
  {...mergeProps(stylex.props(styles.group), {className, style})}>
111
110
  <DropdownMenuRadioGroupContext value={contextValue}>
112
111
  {children}
@@ -21,11 +21,12 @@
21
21
  * has no registry glyph).
22
22
  */
23
23
 
24
- import {useCallback, type ReactNode} from 'react';
24
+ import {useCallback, type PointerEvent, type ReactNode} from 'react';
25
25
  import * as stylex from '@stylexjs/stylex';
26
26
  import {renderIconSlot, type IconType} from '../Icon';
27
27
  import {Item} from '../Item';
28
28
  import {useDropdownMenuContext} from './DropdownMenuContext';
29
+ import {focusMenuItemOnHover} from './menuItemHover';
29
30
  import {
30
31
  colorVars,
31
32
  spacingVars,
@@ -45,7 +46,6 @@ const styles = stylex.create({
45
46
  backgroundColor: {
46
47
  default: 'transparent',
47
48
  ':focus': colorVars['--color-overlay-hover'],
48
- ':hover': colorVars['--color-overlay-hover'],
49
49
  },
50
50
  cursor: 'pointer',
51
51
  outline: 'none',
@@ -145,7 +145,7 @@ export interface DropdownMenuRadioItemProps extends Omit<
145
145
  *
146
146
  * @example
147
147
  * ```
148
- * <DropdownMenuRadioGroup value={sort} onChange={setSort} aria-label="Sort by">
148
+ * <DropdownMenuRadioGroup value={sort} onChange={setSort} label="Sort by">
149
149
  * <DropdownMenuRadioItem value="newest" label="Newest" />
150
150
  * <DropdownMenuRadioItem value="oldest" label="Oldest" icon="clock" />
151
151
  * </DropdownMenuRadioGroup>
@@ -184,12 +184,18 @@ export function DropdownMenuRadioItem({
184
184
  }
185
185
  }, [isDisabled, groupCtx, value, menuCtx]);
186
186
 
187
+ const handlePointerMove = useCallback(
188
+ (e: PointerEvent<HTMLElement>) => focusMenuItemOnHover(e, isDisabled),
189
+ [isDisabled],
190
+ );
191
+
187
192
  return (
188
193
  <Item
189
194
  {...rest}
190
195
  role="menuitemradio"
191
196
  aria-checked={isChecked}
192
197
  tabIndex={isDisabled ? undefined : -1}
198
+ onPointerMove={handlePointerMove}
193
199
  marker={
194
200
  <span
195
201
  aria-hidden="true"
@@ -206,7 +212,16 @@ export function DropdownMenuRadioItem({
206
212
  ),
207
213
  )}>
208
214
  {isChecked && (
209
- <span {...stylex.props(styles.dot, dotSizeStyles[controlSize])} />
215
+ <span
216
+ {...mergeProps(
217
+ themeProps('dropdown-menu-radio-dot', {
218
+ size: controlSize,
219
+ checked: 'checked',
220
+ disabled: isDisabled ? 'disabled' : null,
221
+ }),
222
+ stylex.props(styles.dot, dotSizeStyles[controlSize]),
223
+ )}
224
+ />
210
225
  )}
211
226
  </span>
212
227
  }