@astryxdesign/core 0.3.0 → 0.4.0-canary.3112e99

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 (594) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +10 -2
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +22 -3
  5. package/dist/AppShell/AppShell.d.ts +2 -2
  6. package/dist/AppShell/AppShell.d.ts.map +1 -1
  7. package/dist/AppShell/AppShell.js +40 -9
  8. package/dist/AspectRatio/AspectRatio.d.ts +13 -0
  9. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  10. package/dist/AspectRatio/AspectRatio.js +9 -0
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +33 -20
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +2 -3
  15. package/dist/Banner/Banner.d.ts +3 -0
  16. package/dist/Banner/Banner.d.ts.map +1 -1
  17. package/dist/Banner/Banner.js +32 -17
  18. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  19. package/dist/Breadcrumbs/BreadcrumbItem.js +21 -8
  20. package/dist/Breadcrumbs/index.d.ts +2 -1
  21. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  22. package/dist/Breadcrumbs/index.js +1 -0
  23. package/dist/Button/Button.d.ts.map +1 -1
  24. package/dist/Button/Button.js +12 -16
  25. package/dist/Calendar/Calendar.d.ts.map +1 -1
  26. package/dist/Calendar/Calendar.js +2 -1
  27. package/dist/Calendar/styles.d.ts +0 -2
  28. package/dist/Calendar/styles.d.ts.map +1 -1
  29. package/dist/Calendar/styles.js +0 -2
  30. package/dist/Carousel/Carousel.d.ts.map +1 -1
  31. package/dist/Carousel/Carousel.js +8 -12
  32. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  33. package/dist/Chat/ChatDictationButton.js +2 -1
  34. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  35. package/dist/Chat/ChatLayoutScrollButton.js +3 -1
  36. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatSendButton.js +4 -3
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +17 -17
  40. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  41. package/dist/Chat/useTriggerMenu.js +2 -6
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +36 -125
  44. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  45. package/dist/ClickableCard/ClickableCard.js +3 -11
  46. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  47. package/dist/CodeBlock/CodeBlock.js +84 -67
  48. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  49. package/dist/Collapsible/Collapsible.js +35 -15
  50. package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
  51. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  52. package/dist/CommandPalette/CommandPaletteItem.js +6 -3
  53. package/dist/CommandPalette/CommandPaletteList.js +1 -1
  54. package/dist/ComplexSelector/ComplexSelector.d.ts +1 -1
  55. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  56. package/dist/ComplexSelector/ComplexSelector.js +32 -31
  57. package/dist/ContextMenu/ContextMenu.d.ts +2 -2
  58. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  59. package/dist/ContextMenu/ContextMenu.js +1 -1
  60. package/dist/ContextMenu/index.d.ts +2 -1
  61. package/dist/ContextMenu/index.d.ts.map +1 -1
  62. package/dist/ContextMenu/index.js +1 -0
  63. package/dist/DateInput/DateInput.d.ts +9 -2
  64. package/dist/DateInput/DateInput.d.ts.map +1 -1
  65. package/dist/DateInput/DateInput.js +47 -33
  66. package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
  67. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  68. package/dist/DateRangeInput/DateRangeInput.js +55 -32
  69. package/dist/DateTimeInput/DateTimeInput.d.ts +9 -1
  70. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  71. package/dist/DateTimeInput/DateTimeInput.js +54 -30
  72. package/dist/Dialog/Dialog.d.ts.map +1 -1
  73. package/dist/Dialog/Dialog.js +4 -4
  74. package/dist/DropdownMenu/DropdownMenu.d.ts +33 -8
  75. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  76. package/dist/DropdownMenu/DropdownMenu.js +62 -20
  77. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +8 -11
  78. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  79. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +32 -31
  80. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +25 -0
  81. package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -0
  82. package/dist/DropdownMenu/DropdownMenuDivider.js +66 -0
  83. package/dist/DropdownMenu/DropdownMenuItem.d.ts +15 -2
  84. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenuItem.js +20 -8
  86. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -1
  87. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  88. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +10 -3
  89. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +5 -5
  90. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  91. package/dist/DropdownMenu/DropdownMenuRadioItem.js +24 -67
  92. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  93. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -8
  94. package/dist/DropdownMenu/index.d.ts +2 -1
  95. package/dist/DropdownMenu/index.d.ts.map +1 -1
  96. package/dist/DropdownMenu/index.js +4 -0
  97. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  98. package/dist/DropdownMenu/renderDropdownItems.js +35 -27
  99. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  100. package/dist/EmptyState/EmptyState.js +9 -5
  101. package/dist/Field/InputClearButton.d.ts +16 -3
  102. package/dist/Field/InputClearButton.d.ts.map +1 -1
  103. package/dist/Field/InputClearButton.js +15 -4
  104. package/dist/FileInput/FileInput.d.ts.map +1 -1
  105. package/dist/FileInput/FileInput.js +21 -10
  106. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  107. package/dist/HoverCard/useHoverCard.js +3 -19
  108. package/dist/Indicator/CheckIndicator.d.ts +25 -0
  109. package/dist/Indicator/CheckIndicator.d.ts.map +1 -0
  110. package/dist/Indicator/CheckIndicator.js +155 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts +22 -0
  112. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -0
  113. package/dist/Indicator/CheckboxIndicator.js +173 -0
  114. package/dist/Indicator/RadioIndicator.d.ts +23 -0
  115. package/dist/Indicator/RadioIndicator.d.ts.map +1 -0
  116. package/dist/Indicator/RadioIndicator.js +137 -0
  117. package/dist/Indicator/index.d.ts +24 -0
  118. package/dist/Indicator/index.d.ts.map +1 -0
  119. package/dist/Indicator/index.js +26 -0
  120. package/dist/Indicator/indicator.markers.stylex.d.ts +16 -0
  121. package/dist/Indicator/indicator.markers.stylex.d.ts.map +1 -0
  122. package/dist/Indicator/indicator.markers.stylex.js +21 -0
  123. package/dist/Indicator/indicatorRegistry.d.ts +71 -0
  124. package/dist/Indicator/indicatorRegistry.d.ts.map +1 -0
  125. package/dist/Indicator/indicatorRegistry.js +93 -0
  126. package/dist/Indicator/types.d.ts +177 -0
  127. package/dist/Indicator/types.d.ts.map +1 -0
  128. package/dist/Indicator/types.js +1 -0
  129. package/dist/Indicator/useIndicator.d.ts +18 -0
  130. package/dist/Indicator/useIndicator.d.ts.map +1 -0
  131. package/dist/Indicator/useIndicator.js +30 -0
  132. package/dist/Item/Item.d.ts.map +1 -1
  133. package/dist/Item/Item.js +4 -8
  134. package/dist/Layer/useLayer.d.ts +14 -0
  135. package/dist/Layer/useLayer.d.ts.map +1 -1
  136. package/dist/Layer/useLayer.js +25 -2
  137. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  138. package/dist/Lightbox/Lightbox.js +80 -103
  139. package/dist/Link/Link.d.ts.map +1 -1
  140. package/dist/Link/Link.js +4 -5
  141. package/dist/MobileNav/MobileNav.js +8 -8
  142. package/dist/MoreMenu/MoreMenu.d.ts +14 -1
  143. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  144. package/dist/MoreMenu/MoreMenu.js +4 -0
  145. package/dist/MultiSelector/MultiSelector.d.ts +8 -1
  146. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  147. package/dist/MultiSelector/MultiSelector.js +119 -95
  148. package/dist/NumberInput/NumberInput.d.ts +27 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +230 -42
  151. package/dist/Outline/Outline.d.ts.map +1 -1
  152. package/dist/Outline/Outline.js +2 -3
  153. package/dist/Pagination/Pagination.d.ts.map +1 -1
  154. package/dist/Pagination/Pagination.js +61 -63
  155. package/dist/Popover/Popover.d.ts.map +1 -1
  156. package/dist/Popover/Popover.js +6 -8
  157. package/dist/Popover/usePopover.d.ts +15 -0
  158. package/dist/Popover/usePopover.d.ts.map +1 -1
  159. package/dist/Popover/usePopover.js +14 -2
  160. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  161. package/dist/PowerSearch/PowerSearch.js +1 -1
  162. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  163. package/dist/PowerSearch/PowerSearchEditPopover.js +7 -0
  164. package/dist/ProgressBar/ProgressBar.d.ts +11 -4
  165. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  166. package/dist/ProgressBar/ProgressBar.js +95 -6
  167. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  168. package/dist/RadioList/RadioListItem.js +29 -84
  169. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  170. package/dist/Resizable/ResizeHandle.js +2 -3
  171. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  172. package/dist/SegmentedControl/SegmentedControlItem.js +2 -3
  173. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  174. package/dist/SelectableCard/SelectableCard.js +3 -11
  175. package/dist/Selector/Selector.d.ts +12 -1
  176. package/dist/Selector/Selector.d.ts.map +1 -1
  177. package/dist/Selector/Selector.js +222 -111
  178. package/dist/Selector/hooks.d.ts +18 -6
  179. package/dist/Selector/hooks.d.ts.map +1 -1
  180. package/dist/Selector/hooks.js +57 -40
  181. package/dist/SideNav/SideNav.d.ts.map +1 -1
  182. package/dist/SideNav/SideNav.js +1 -1
  183. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  184. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  185. package/dist/SideNav/SideNavCollapseButton.js +29 -14
  186. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  187. package/dist/SideNav/SideNavHeading.js +56 -20
  188. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  189. package/dist/SideNav/SideNavItem.js +28 -22
  190. package/dist/Slider/Slider.d.ts.map +1 -1
  191. package/dist/Slider/Slider.js +2 -6
  192. package/dist/Stack/stack.stylex.d.ts +3 -3
  193. package/dist/Switch/Switch.d.ts.map +1 -1
  194. package/dist/Switch/Switch.js +14 -13
  195. package/dist/TabList/Tab.d.ts.map +1 -1
  196. package/dist/TabList/Tab.js +2 -3
  197. package/dist/TabList/TabMenu.d.ts.map +1 -1
  198. package/dist/TabList/TabMenu.js +41 -19
  199. package/dist/Table/BaseTable.d.ts.map +1 -1
  200. package/dist/Table/BaseTable.js +8 -0
  201. package/dist/Table/TableRow.d.ts +1 -1
  202. package/dist/Table/TableRow.d.ts.map +1 -1
  203. package/dist/Table/TableRow.js +4 -2
  204. package/dist/Table/index.d.ts +1 -1
  205. package/dist/Table/index.d.ts.map +1 -1
  206. package/dist/Table/index.js +1 -1
  207. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  208. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +22 -18
  210. package/dist/Table/plugins/rowExpansion/index.d.ts +1 -1
  211. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -1
  212. package/dist/Table/plugins/rowExpansion/index.js +1 -1
  213. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +41 -76
  214. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  215. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +94 -345
  216. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  217. package/dist/Table/plugins/sortable/useTableSortable.js +23 -4
  218. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  219. package/dist/Table/plugins/tree/useTableTreeData.js +29 -33
  220. package/dist/Table/tableContextMenu.d.ts.map +1 -1
  221. package/dist/Table/tableContextMenu.js +2 -1
  222. package/dist/Table/types.d.ts +11 -0
  223. package/dist/Table/types.d.ts.map +1 -1
  224. package/dist/TextArea/TextArea.d.ts +10 -1
  225. package/dist/TextArea/TextArea.d.ts.map +1 -1
  226. package/dist/TextArea/TextArea.js +16 -6
  227. package/dist/TextInput/TextInput.d.ts +10 -1
  228. package/dist/TextInput/TextInput.d.ts.map +1 -1
  229. package/dist/TextInput/TextInput.js +13 -19
  230. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  231. package/dist/Thumbnail/Thumbnail.js +32 -26
  232. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  233. package/dist/TimeInput/TimeInput.js +14 -17
  234. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  235. package/dist/Timestamp/Timestamp.js +14 -3
  236. package/dist/Timestamp/TimestampHoverCard.d.ts.map +1 -1
  237. package/dist/Timestamp/TimestampHoverCard.js +16 -34
  238. package/dist/Timestamp/formatInstant.d.ts +11 -1
  239. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  240. package/dist/Timestamp/formatInstant.js +3 -1
  241. package/dist/Token/Token.d.ts.map +1 -1
  242. package/dist/Token/Token.js +20 -11
  243. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  244. package/dist/Tokenizer/Tokenizer.js +4 -2
  245. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  246. package/dist/Tooltip/useTooltip.js +3 -19
  247. package/dist/TopNav/TopNav.d.ts.map +1 -1
  248. package/dist/TopNav/TopNav.js +6 -5
  249. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  250. package/dist/TopNav/TopNavHeading.js +54 -16
  251. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavItem.js +3 -9
  253. package/dist/TopNav/TopNavMegaMenu.d.ts +7 -0
  254. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  255. package/dist/TopNav/TopNavMegaMenu.js +146 -60
  256. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMegaMenuItem.js +22 -3
  258. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavMenu.js +83 -38
  260. package/dist/TreeList/TreeList.d.ts.map +1 -1
  261. package/dist/TreeList/TreeList.js +13 -0
  262. package/dist/TreeList/TreeListBranches.d.ts +1 -1
  263. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  264. package/dist/TreeList/TreeListBranches.js +14 -4
  265. package/dist/TreeList/TreeListItem.d.ts +11 -1
  266. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  267. package/dist/TreeList/TreeListItem.js +57 -30
  268. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  269. package/dist/Typeahead/BaseTypeahead.js +16 -8
  270. package/dist/astryx.css +84 -96
  271. package/dist/astryx.umd.js +56 -56
  272. package/dist/astryx.umd.js.map +4 -4
  273. package/dist/hooks/containerReveal.stylex.d.ts +61 -0
  274. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -0
  275. package/dist/hooks/containerReveal.stylex.js +63 -0
  276. package/dist/hooks/index.d.ts +3 -0
  277. package/dist/hooks/index.d.ts.map +1 -1
  278. package/dist/hooks/index.js +2 -0
  279. package/dist/hooks/useClipboard.d.ts +59 -0
  280. package/dist/hooks/useClipboard.d.ts.map +1 -0
  281. package/dist/hooks/useClipboard.js +106 -0
  282. package/dist/hooks/useContainerReveal.d.ts +14 -8
  283. package/dist/hooks/useContainerReveal.d.ts.map +1 -1
  284. package/dist/hooks/useContainerReveal.js +28 -69
  285. package/dist/hooks/useIndicatorFocusRing.d.ts +28 -0
  286. package/dist/hooks/useIndicatorFocusRing.d.ts.map +1 -0
  287. package/dist/hooks/useIndicatorFocusRing.js +96 -0
  288. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  289. package/dist/hooks/useInputStatusIcon.js +17 -4
  290. package/dist/hooks/useLongPress.d.ts.map +1 -1
  291. package/dist/hooks/useLongPress.js +12 -2
  292. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  293. package/dist/hooks/useScrollLock.js +33 -18
  294. package/dist/hooks/useStreamingText.d.ts +18 -3
  295. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  296. package/dist/hooks/useStreamingText.js +47 -7
  297. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  298. package/dist/hooks/useTreeFocus.js +9 -3
  299. package/dist/hooks/useTypeahead.d.ts +3 -2
  300. package/dist/hooks/useTypeahead.d.ts.map +1 -1
  301. package/dist/hooks/useTypeahead.js +19 -7
  302. package/dist/index.d.ts +1 -0
  303. package/dist/index.d.ts.map +1 -1
  304. package/dist/index.js +1 -0
  305. package/dist/theme/defineTheme.d.ts +18 -2
  306. package/dist/theme/defineTheme.d.ts.map +1 -1
  307. package/dist/theme/defineTheme.js +10 -1
  308. package/dist/theme/derivedVarRegistry.d.ts +8 -0
  309. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  310. package/dist/theme/derivedVarRegistry.js +14 -13
  311. package/dist/theme/expandColorScale.d.ts +3 -1
  312. package/dist/theme/expandColorScale.d.ts.map +1 -1
  313. package/dist/theme/expandColorScale.js +17 -7
  314. package/dist/theme/expandTypeScale.d.ts.map +1 -1
  315. package/dist/theme/expandTypeScale.js +17 -0
  316. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  317. package/dist/theme/generateThemeRules.js +11 -0
  318. package/dist/theme/index.d.ts +2 -1
  319. package/dist/theme/index.d.ts.map +1 -1
  320. package/dist/theme/index.js +1 -1
  321. package/dist/theme/tokens.stylex.d.ts +12 -0
  322. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  323. package/dist/theme/tokens.stylex.js +23 -0
  324. package/dist/utils/focusOutline.stylex.d.ts +122 -0
  325. package/dist/utils/focusOutline.stylex.d.ts.map +1 -0
  326. package/dist/utils/focusOutline.stylex.js +143 -0
  327. package/dist/utils/focusReturn.d.ts +24 -0
  328. package/dist/utils/focusReturn.d.ts.map +1 -0
  329. package/dist/utils/focusReturn.js +29 -0
  330. package/dist/utils/index.d.ts +2 -0
  331. package/dist/utils/index.d.ts.map +1 -1
  332. package/dist/utils/index.js +6 -1
  333. package/dist/utils/mergeRefs.d.ts.map +1 -1
  334. package/dist/utils/mergeRefs.js +7 -5
  335. package/dist/utils/rtlStyles.d.ts +2 -2
  336. package/dist/utils/rtlStyles.js +2 -2
  337. package/dist/utils/themeProps.d.ts +20 -1
  338. package/dist/utils/themeProps.d.ts.map +1 -1
  339. package/dist/utils/themeProps.js +8 -2
  340. package/locales/en.json +52 -0
  341. package/locales/pseudo.json +39 -0
  342. package/package.json +8 -3
  343. package/src/AlertDialog/AlertDialog.doc.mjs +16 -3
  344. package/src/AlertDialog/AlertDialog.test.tsx +208 -1
  345. package/src/AlertDialog/AlertDialog.tsx +21 -3
  346. package/src/AppShell/AppShell.doc.mjs +11 -0
  347. package/src/AppShell/AppShell.test.tsx +139 -0
  348. package/src/AppShell/AppShell.tsx +32 -22
  349. package/src/AspectRatio/AspectRatio.doc.mjs +27 -3
  350. package/src/AspectRatio/AspectRatio.test.tsx +30 -0
  351. package/src/AspectRatio/AspectRatio.tsx +13 -0
  352. package/src/Avatar/Avatar.doc.mjs +2 -13
  353. package/src/Avatar/Avatar.test.tsx +33 -8
  354. package/src/Avatar/Avatar.tsx +52 -50
  355. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -9
  356. package/src/Banner/Banner.test.tsx +58 -1
  357. package/src/Banner/Banner.tsx +33 -11
  358. package/src/Breadcrumbs/BreadcrumbItem.tsx +16 -6
  359. package/src/Breadcrumbs/index.ts +5 -1
  360. package/src/Button/Button.doc.mjs +2 -2
  361. package/src/Button/Button.tsx +22 -41
  362. package/src/Calendar/Calendar.tsx +2 -1
  363. package/src/Calendar/styles.ts +0 -8
  364. package/src/Carousel/Carousel.doc.mjs +3 -0
  365. package/src/Carousel/Carousel.tsx +10 -6
  366. package/src/Chat/Chat.doc.mjs +2 -0
  367. package/src/Chat/ChatDictationButton.tsx +7 -1
  368. package/src/Chat/ChatLayoutScrollButton.test.tsx +22 -0
  369. package/src/Chat/ChatLayoutScrollButton.tsx +8 -1
  370. package/src/Chat/ChatSendButton.tsx +2 -3
  371. package/src/Chat/ChatToolCalls.test.tsx +35 -0
  372. package/src/Chat/ChatToolCalls.tsx +36 -16
  373. package/src/Chat/useTriggerMenu.tsx +2 -5
  374. package/src/CheckboxInput/CheckboxInput.doc.mjs +4 -2
  375. package/src/CheckboxInput/CheckboxInput.test.tsx +120 -0
  376. package/src/CheckboxInput/CheckboxInput.tsx +45 -202
  377. package/src/ClickableCard/ClickableCard.tsx +6 -11
  378. package/src/CodeBlock/CodeBlock.doc.mjs +3 -0
  379. package/src/CodeBlock/CodeBlock.test.tsx +91 -0
  380. package/src/CodeBlock/CodeBlock.tsx +57 -80
  381. package/src/Collapsible/Collapsible.tsx +22 -18
  382. package/src/CommandPalette/CommandPalette.test.tsx +29 -0
  383. package/src/CommandPalette/CommandPaletteItem.tsx +7 -4
  384. package/src/CommandPalette/CommandPaletteList.tsx +2 -2
  385. package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
  386. package/src/ComplexSelector/ComplexSelector.test.tsx +73 -0
  387. package/src/ComplexSelector/ComplexSelector.tsx +41 -28
  388. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  389. package/src/ContextMenu/ContextMenu.test.tsx +41 -0
  390. package/src/ContextMenu/ContextMenu.tsx +3 -3
  391. package/src/ContextMenu/index.ts +5 -1
  392. package/src/DateInput/DateInput.doc.mjs +18 -3
  393. package/src/DateInput/DateInput.test.tsx +112 -11
  394. package/src/DateInput/DateInput.tsx +44 -25
  395. package/src/DateRangeInput/DateRangeInput.doc.mjs +10 -2
  396. package/src/DateRangeInput/DateRangeInput.test.tsx +110 -14
  397. package/src/DateRangeInput/DateRangeInput.tsx +27 -21
  398. package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -2
  399. package/src/DateTimeInput/DateTimeInput.test.tsx +154 -1
  400. package/src/DateTimeInput/DateTimeInput.tsx +58 -17
  401. package/src/Dialog/Dialog.tsx +2 -9
  402. package/src/DropdownMenu/DropdownMenu.doc.mjs +5 -9
  403. package/src/DropdownMenu/DropdownMenu.test.tsx +534 -4
  404. package/src/DropdownMenu/DropdownMenu.tsx +113 -52
  405. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +27 -30
  406. package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +34 -0
  407. package/src/DropdownMenu/DropdownMenuDivider.tsx +81 -0
  408. package/src/DropdownMenu/DropdownMenuItem.doc.mjs +39 -4
  409. package/src/DropdownMenu/DropdownMenuItem.tsx +48 -10
  410. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +2 -1
  411. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +30 -76
  412. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +25 -19
  413. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +44 -14
  414. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +1 -5
  415. package/src/DropdownMenu/index.ts +8 -1
  416. package/src/DropdownMenu/renderDropdownItems.tsx +33 -34
  417. package/src/EmptyState/EmptyState.doc.mjs +4 -0
  418. package/src/EmptyState/EmptyState.test.tsx +62 -0
  419. package/src/EmptyState/EmptyState.tsx +16 -6
  420. package/src/Field/Field.doc.mjs +1 -0
  421. package/src/Field/InputClearButton.test.tsx +117 -0
  422. package/src/Field/InputClearButton.tsx +30 -3
  423. package/src/FileInput/FileInput.tsx +21 -8
  424. package/src/HoverCard/useHoverCard.tsx +2 -23
  425. package/src/Icon/Icon.doc.mjs +2 -1
  426. package/src/Indicator/CheckIndicator.tsx +174 -0
  427. package/src/Indicator/CheckboxIndicator.tsx +257 -0
  428. package/src/Indicator/Indicator.doc.mjs +344 -0
  429. package/src/Indicator/Indicator.test.tsx +393 -0
  430. package/src/Indicator/RadioIndicator.tsx +206 -0
  431. package/src/Indicator/index.ts +46 -0
  432. package/src/Indicator/indicator.markers.stylex.ts +19 -0
  433. package/src/Indicator/indicatorRegistry.test.tsx +106 -0
  434. package/src/Indicator/indicatorRegistry.ts +120 -0
  435. package/src/Indicator/types.ts +197 -0
  436. package/src/Indicator/useIndicator.ts +39 -0
  437. package/src/Item/Item.doc.mjs +1 -1
  438. package/src/Item/Item.tsx +7 -14
  439. package/src/Layer/useLayer.doc.mjs +2 -2
  440. package/src/Layer/useLayer.test.tsx +85 -0
  441. package/src/Layer/useLayer.tsx +39 -1
  442. package/src/Lightbox/Lightbox.doc.mjs +1 -1
  443. package/src/Lightbox/Lightbox.tsx +45 -49
  444. package/src/Link/Link.tsx +4 -11
  445. package/src/MobileNav/MobileNav.tsx +3 -3
  446. package/src/MoreMenu/MoreMenu.doc.mjs +31 -0
  447. package/src/MoreMenu/MoreMenu.test.tsx +68 -1
  448. package/src/MoreMenu/MoreMenu.tsx +19 -0
  449. package/src/MultiSelector/MultiSelector.doc.mjs +16 -1
  450. package/src/MultiSelector/MultiSelector.test.tsx +259 -16
  451. package/src/MultiSelector/MultiSelector.tsx +144 -121
  452. package/src/NumberInput/NumberInput.doc.mjs +265 -50
  453. package/src/NumberInput/NumberInput.test.tsx +726 -21
  454. package/src/NumberInput/NumberInput.tsx +353 -59
  455. package/src/Outline/Outline.tsx +2 -5
  456. package/src/Pagination/Pagination.doc.mjs +1 -1
  457. package/src/Pagination/Pagination.test.tsx +22 -7
  458. package/src/Pagination/Pagination.tsx +38 -35
  459. package/src/Popover/Popover.doc.mjs +2 -0
  460. package/src/Popover/Popover.tsx +6 -7
  461. package/src/Popover/usePopover.tsx +37 -4
  462. package/src/PowerSearch/PowerSearch.tsx +1 -1
  463. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +42 -0
  464. package/src/PowerSearch/PowerSearchEditPopover.tsx +7 -0
  465. package/src/ProgressBar/ProgressBar.doc.mjs +27 -5
  466. package/src/ProgressBar/ProgressBar.test.tsx +224 -1
  467. package/src/ProgressBar/ProgressBar.tsx +126 -30
  468. package/src/RadioList/RadioList.doc.mjs +4 -2
  469. package/src/RadioList/RadioListItem.tsx +31 -130
  470. package/src/Resizable/ResizeHandle.tsx +2 -9
  471. package/src/SegmentedControl/SegmentedControlItem.tsx +2 -9
  472. package/src/SelectableCard/SelectableCard.tsx +4 -9
  473. package/src/Selector/Selector.doc.mjs +15 -4
  474. package/src/Selector/Selector.test.tsx +1234 -98
  475. package/src/Selector/Selector.tsx +254 -126
  476. package/src/Selector/hooks.ts +77 -50
  477. package/src/SideNav/SideNav.test.tsx +46 -0
  478. package/src/SideNav/SideNav.tsx +1 -0
  479. package/src/SideNav/SideNavCollapseButton.tsx +15 -10
  480. package/src/SideNav/SideNavHeading.tsx +48 -10
  481. package/src/SideNav/SideNavItem.tsx +20 -12
  482. package/src/Slider/Slider.tsx +2 -11
  483. package/src/Stack/Stack.doc.mjs +110 -0
  484. package/src/StatusDot/StatusDot.doc.mjs +12 -3
  485. package/src/Switch/Switch.test.tsx +32 -0
  486. package/src/Switch/Switch.tsx +18 -10
  487. package/src/TabList/Tab.tsx +2 -9
  488. package/src/TabList/TabMenu.tsx +14 -21
  489. package/src/Table/BaseTable.tsx +11 -0
  490. package/src/Table/Table.test.tsx +31 -0
  491. package/src/Table/TableRow.tsx +6 -0
  492. package/src/Table/index.ts +1 -4
  493. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +30 -14
  494. package/src/Table/plugins/rowExpansion/index.ts +1 -4
  495. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +125 -175
  496. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +115 -458
  497. package/src/Table/plugins/sortable/useTableSortable.tsx +2 -6
  498. package/src/Table/plugins/tree/useTableTreeData.tsx +43 -24
  499. package/src/Table/tableContextMenu.test.tsx +27 -0
  500. package/src/Table/tableContextMenu.tsx +1 -0
  501. package/src/Table/types.ts +11 -0
  502. package/src/Table/useTableGroupedRows.doc.mjs +1 -1
  503. package/src/Table/useTableRowExpansion.doc.mjs +43 -66
  504. package/src/TextArea/TextArea.doc.mjs +42 -2
  505. package/src/TextArea/TextArea.test.tsx +219 -0
  506. package/src/TextArea/TextArea.tsx +34 -7
  507. package/src/TextInput/TextInput.doc.mjs +18 -2
  508. package/src/TextInput/TextInput.test.tsx +189 -0
  509. package/src/TextInput/TextInput.tsx +25 -31
  510. package/src/Thumbnail/Thumbnail.tsx +2 -9
  511. package/src/TimeInput/TimeInput.doc.mjs +2 -2
  512. package/src/TimeInput/TimeInput.test.tsx +84 -3
  513. package/src/TimeInput/TimeInput.tsx +26 -28
  514. package/src/Timestamp/Timestamp.doc.mjs +4 -3
  515. package/src/Timestamp/Timestamp.test.tsx +91 -14
  516. package/src/Timestamp/Timestamp.tsx +14 -2
  517. package/src/Timestamp/TimestampHoverCard.tsx +13 -35
  518. package/src/Timestamp/formatInstant.ts +16 -1
  519. package/src/Token/Token.tsx +5 -28
  520. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  521. package/src/Tokenizer/Tokenizer.test.tsx +45 -3
  522. package/src/Tokenizer/Tokenizer.tsx +10 -2
  523. package/src/Tooltip/useTooltip.tsx +2 -23
  524. package/src/TopNav/TopNav.tsx +1 -3
  525. package/src/TopNav/TopNavHeading.tsx +42 -13
  526. package/src/TopNav/TopNavItem.tsx +3 -21
  527. package/src/TopNav/TopNavMegaMenu.doc.mjs +5 -0
  528. package/src/TopNav/TopNavMegaMenu.test.tsx +433 -33
  529. package/src/TopNav/TopNavMegaMenu.tsx +118 -53
  530. package/src/TopNav/TopNavMegaMenuItem.tsx +2 -9
  531. package/src/TopNav/TopNavMenu.tsx +34 -37
  532. package/src/TreeList/TreeList.doc.mjs +5 -0
  533. package/src/TreeList/TreeList.test.tsx +208 -8
  534. package/src/TreeList/TreeList.tsx +22 -0
  535. package/src/TreeList/TreeListBranches.tsx +25 -2
  536. package/src/TreeList/TreeListItem.tsx +89 -52
  537. package/src/Typeahead/BaseTypeahead.tsx +19 -6
  538. package/src/Typeahead/Typeahead.doc.mjs +1 -0
  539. package/src/Typeahead/Typeahead.test.tsx +76 -3
  540. package/src/hooks/containerReveal.stylex.ts +102 -0
  541. package/src/hooks/index.ts +4 -0
  542. package/src/hooks/useClipboard.doc.mjs +87 -0
  543. package/src/hooks/useClipboard.test.tsx +151 -0
  544. package/src/hooks/useClipboard.ts +135 -0
  545. package/src/hooks/useContainerReveal.doc.mjs +7 -7
  546. package/src/hooks/useContainerReveal.test.tsx +42 -62
  547. package/src/hooks/useContainerReveal.ts +36 -91
  548. package/src/hooks/useImageMode.test.ts +1 -1
  549. package/src/hooks/useIndicatorFocusRing.tsx +120 -0
  550. package/src/hooks/useInputStatusIcon.tsx +8 -8
  551. package/src/hooks/useLongPress.test.tsx +18 -0
  552. package/src/hooks/useLongPress.ts +12 -2
  553. package/src/hooks/useScrollLock.test.ts +72 -0
  554. package/src/hooks/useScrollLock.ts +51 -19
  555. package/src/hooks/useStreamingText.test.ts +46 -1
  556. package/src/hooks/useStreamingText.ts +49 -7
  557. package/src/hooks/useTreeFocus.test.tsx +50 -0
  558. package/src/hooks/useTreeFocus.ts +14 -3
  559. package/src/hooks/useTypeahead.test.tsx +150 -0
  560. package/src/hooks/useTypeahead.ts +24 -9
  561. package/src/i18n/InternationalizationProvider.doc.mjs +7 -2
  562. package/src/index.ts +1 -0
  563. package/src/theme/defineTheme.ts +27 -0
  564. package/src/theme/derivedVarRegistry.test.ts +21 -1
  565. package/src/theme/derivedVarRegistry.ts +19 -6
  566. package/src/theme/expandColorScale.test.ts +14 -0
  567. package/src/theme/expandColorScale.ts +24 -9
  568. package/src/theme/expandTypeScale.test.ts +43 -0
  569. package/src/theme/expandTypeScale.ts +17 -0
  570. package/src/theme/generateThemeRules.test.ts +78 -20
  571. package/src/theme/generateThemeRules.ts +11 -0
  572. package/src/theme/index.ts +15 -0
  573. package/src/theme/tokens.stylex.ts +18 -0
  574. package/src/theme/tokens.test.ts +37 -0
  575. package/src/utils/focusOutline.stylex.ts +177 -0
  576. package/src/utils/focusReturn.test.ts +42 -0
  577. package/src/utils/focusReturn.ts +31 -0
  578. package/src/utils/index.ts +5 -0
  579. package/src/utils/mergeRefs.test.ts +48 -0
  580. package/src/utils/mergeRefs.ts +12 -6
  581. package/src/utils/rtlStyles.ts +2 -2
  582. package/src/utils/themeProps.ts +26 -4
  583. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts +0 -9
  584. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts.map +0 -1
  585. package/dist/CheckboxInput/checkbox.markers.stylex.js +0 -14
  586. package/dist/RadioList/radio.markers.stylex.d.ts +0 -7
  587. package/dist/RadioList/radio.markers.stylex.d.ts.map +0 -1
  588. package/dist/RadioList/radio.markers.stylex.js +0 -12
  589. package/dist/hooks/containerReveal.pool.stylex.d.ts +0 -303
  590. package/dist/hooks/containerReveal.pool.stylex.d.ts.map +0 -1
  591. package/dist/hooks/containerReveal.pool.stylex.js +0 -292
  592. package/src/CheckboxInput/checkbox.markers.stylex.ts +0 -12
  593. package/src/RadioList/radio.markers.stylex.ts +0 -10
  594. package/src/hooks/containerReveal.pool.stylex.ts +0 -571
@@ -42,6 +42,8 @@ import {
42
42
  typeScaleVars,
43
43
  } from '../theme/tokens.stylex';
44
44
  import {mergeProps} from '../utils';
45
+ import {composeEventHandlers} from '../utils/composeEventHandlers';
46
+ import {focusOutlineStyles} from '../utils/focusOutline.stylex';
45
47
  import type {SizeValue} from '../utils/types';
46
48
  import {themeProps} from '../utils/themeProps';
47
49
 
@@ -97,25 +99,28 @@ const styles = stylex.create({
97
99
  placeholder: {
98
100
  color: colorVars['--color-text-secondary'],
99
101
  },
102
+ // Only what Icon does not already provide: `sm` gives the 16px box and
103
+ // `color="secondary"` the color, but the glyph still must not shrink inside
104
+ // the flex trigger.
100
105
  triggerIcon: {
101
106
  flexShrink: 0,
102
- display: 'flex',
103
- alignItems: 'center',
104
- justifyContent: 'center',
105
- width: 16,
106
- height: 16,
107
+ },
108
+ // Rotation lives on the chevron glyph itself (passed through `xstyle`), not
109
+ // on the layout wrapper above, so the icon's
110
+ // `complex-selector-indicator-icon` theme target and the open/closed
111
+ // transform sit on one element — a theme can restyle the mark and its
112
+ // rotation through a single selector. The wrapper keeps only layout.
113
+ triggerIconRotation: {
107
114
  transitionProperty: 'transform',
108
115
  transitionDuration: durationVars['--duration-fast'],
109
116
  transitionTimingFunction: easeVars['--ease-standard'],
110
117
  transformOrigin: 'center',
111
- color: colorVars['--color-icon-secondary'],
112
118
  },
113
119
  triggerIconOpen: {
114
120
  transform: 'rotate(180deg)',
115
121
  },
116
122
  popover: {
117
123
  minWidth: 'anchor-size(width)',
118
- marginBlockStart: spacingVars['--spacing-1'],
119
124
  },
120
125
  content: {
121
126
  boxSizing: 'border-box',
@@ -135,12 +140,6 @@ const styles = stylex.create({
135
140
  disabled: {
136
141
  cursor: 'not-allowed',
137
142
  },
138
- focusRing: {
139
- ':focus-within': {
140
- outline: `2px solid ${colorVars['--color-accent']}`,
141
- outlineOffset: '2px',
142
- },
143
- },
144
143
  });
145
144
 
146
145
  export type ComplexSelectorSize = 'sm' | 'md' | 'lg';
@@ -266,6 +265,7 @@ export function ComplexSelector<Value>({
266
265
  className,
267
266
  style,
268
267
  'data-testid': testId,
268
+ onClick: onClickProp,
269
269
  ...props
270
270
  }: ComplexSelectorProps<Value>) {
271
271
  const t = useTranslator();
@@ -292,6 +292,11 @@ export function ComplexSelector<Value>({
292
292
  dialogLabel: label,
293
293
  hasCloseButton: false,
294
294
  hasAutoFocus: true,
295
+ // The popup's theme target belongs on the SURFACE — the element painting
296
+ // background, radius and elevation — which `usePopover` owns. Rendered on
297
+ // the content box below it, a theme's background or radius rule paints the
298
+ // wrong box.
299
+ surfaceTarget: 'complex-selector-popup',
295
300
  onHide: () => {
296
301
  document.getElementById(triggerId)?.focus();
297
302
  },
@@ -329,11 +334,11 @@ export function ComplexSelector<Value>({
329
334
  ref={popover.triggerRef}
330
335
  data-testid={testId}
331
336
  {...props}
332
- onClick={() => {
337
+ onClick={composeEventHandlers(onClickProp, () => {
333
338
  if (!isDisabled) {
334
339
  popover.toggle();
335
340
  }
336
- }}
341
+ })}
337
342
  {...mergeProps(
338
343
  themeProps('complex-selector', {
339
344
  size,
@@ -343,7 +348,11 @@ export function ComplexSelector<Value>({
343
348
  inputWrapperStyles.base,
344
349
  styles.triggerContainer,
345
350
  styles[size],
346
- styles.focusRing,
351
+ // The ring belongs to the wrapper (the focusable `<button>` sits
352
+ // inside it), but it must still be a KEYBOARD ring: `:focus-within`
353
+ // matched a mouse click on the trigger and drew the outline for
354
+ // pointer users too. `focusWithin` here is `:has(:focus-visible)`.
355
+ focusOutlineStyles.focusWithin,
347
356
  isDisabled && inputWrapperStyles.disabled,
348
357
  isDisabled && styles.disabled,
349
358
  triggerLabel == null && styles.placeholder,
@@ -374,25 +383,29 @@ export function ComplexSelector<Value>({
374
383
  <span {...stylex.props(styles.triggerText)}>{triggerContent}</span>
375
384
  </button>
376
385
  {isBusy && <Spinner size="sm" />}
377
- <span
378
- {...stylex.props(
386
+ <Icon
387
+ icon="chevronDown"
388
+ size="sm"
389
+ color="secondary"
390
+ // No wrapper: Icon's own span already provides the 16px box (`sm`)
391
+ // and the secondary icon color the wrapper used to set, so the glyph
392
+ // IS the trigger's icon element — one node carrying the box, the
393
+ // color, the rotation, and the theme target.
394
+ xstyle={[
379
395
  styles.triggerIcon,
396
+ styles.triggerIconRotation,
380
397
  popover.isOpen && styles.triggerIconOpen,
381
- )}>
382
- <Icon
383
- icon="chevronDown"
384
- size="sm"
385
- color="inherit"
386
- {...themeProps('complex-selector-indicator-icon', {
387
- state: popover.isOpen ? 'expanded' : 'collapsed',
388
- })}
389
- />
390
- </span>
398
+ ]}
399
+ {...themeProps('complex-selector-indicator-icon', {
400
+ state: popover.isOpen ? 'expanded' : 'collapsed',
401
+ })}
402
+ />
391
403
  </div>
392
404
 
393
405
  {popover.render(content, {
394
406
  placement,
395
407
  alignment: 'start',
408
+ offset: spacingVars['--spacing-1'],
396
409
  xstyle: [styles.popover, layerAnimations[placement]],
397
410
  })}
398
411
  </>
@@ -32,7 +32,7 @@ export const docs = {
32
32
  {
33
33
  name: 'items',
34
34
  type: 'ContextMenuOption[]',
35
- description: 'Array of menu entries. Each entry is one of: an action item `{label, onClick?, icon?, isDisabled?}`, a divider `{type: "divider"}`, or a section `{type: "section", title?, items: [...action items]}`.',
35
+ description: 'Array of menu entries. Each entry is one of: an action item `{label, onClick?, icon?, isDisabled?, variant?}` (variant `"destructive"` renders it in the error color), a divider `{type: "divider"}`, or a section `{type: "section", title?, items: [...action items]}`.',
36
36
  required: true,
37
37
  },
38
38
  {
@@ -14,6 +14,7 @@ import userEvent from '@testing-library/user-event';
14
14
  import {ContextMenu} from './ContextMenu';
15
15
  import {
16
16
  ContextMenuItem,
17
+ ContextMenuDivider,
17
18
  ContextMenuCheckboxItem,
18
19
  ContextMenuRadioGroup,
19
20
  ContextMenuRadioItem,
@@ -348,6 +349,27 @@ describe('ContextMenu items', () => {
348
349
  });
349
350
  });
350
351
 
352
+ describe('ContextMenu destructive variant', () => {
353
+ it('forwards a destructive item variant to the shared menu item', () => {
354
+ render(
355
+ <ContextMenu
356
+ items={[
357
+ {label: 'Delete', variant: 'destructive', onClick: () => {}},
358
+ {label: 'Rename', onClick: () => {}},
359
+ ]}>
360
+ <div>Right-click me</div>
361
+ </ContextMenu>,
362
+ );
363
+
364
+ expect(
365
+ screen.getByRole('menuitem', {name: 'Delete', hidden: true}),
366
+ ).toHaveAttribute('data-variant', 'destructive');
367
+ expect(
368
+ screen.getByRole('menuitem', {name: 'Rename', hidden: true}),
369
+ ).not.toHaveAttribute('data-variant');
370
+ });
371
+ });
372
+
351
373
  describe('ContextMenu sections', () => {
352
374
  it('renders section with title', () => {
353
375
  render(
@@ -448,6 +470,25 @@ describe('ContextMenu compound mode', () => {
448
470
  expect(screen.getByTestId('shortcut')).toHaveTextContent('⌘X');
449
471
  });
450
472
 
473
+ it('renders the menu divider surface through the ContextMenu alias', () => {
474
+ render(
475
+ <ContextMenu
476
+ menuContent={
477
+ <>
478
+ <ContextMenuItem label="Cut" onClick={() => {}} />
479
+ <ContextMenuDivider />
480
+ <ContextMenuItem label="Delete" onClick={() => {}} />
481
+ </>
482
+ }>
483
+ <div>Right-click me</div>
484
+ </ContextMenu>,
485
+ );
486
+
487
+ expect(screen.getByRole('separator', {hidden: true})).toHaveClass(
488
+ 'astryx-dropdown-menu-divider',
489
+ );
490
+ });
491
+
451
492
  it('calls onClick when compound item is clicked', async () => {
452
493
  const user = userEvent.setup();
453
494
  const handleClick = vi.fn();
@@ -71,7 +71,7 @@ import {useTranslator} from '../i18n';
71
71
  import type {
72
72
  DropdownMenuOption,
73
73
  DropdownMenuItemData,
74
- DropdownMenuDivider,
74
+ DropdownMenuDividerData,
75
75
  DropdownMenuSection,
76
76
  } from '../DropdownMenu/DropdownMenu';
77
77
 
@@ -128,7 +128,7 @@ const styles = stylex.create({
128
128
 
129
129
  export type ContextMenuItemData = DropdownMenuItemData;
130
130
 
131
- export type ContextMenuDivider = DropdownMenuDivider;
131
+ export type ContextMenuDividerData = DropdownMenuDividerData;
132
132
 
133
133
  export type ContextMenuSection = DropdownMenuSection;
134
134
 
@@ -466,9 +466,9 @@ export function ContextMenu({
466
466
  <>
467
467
  <div
468
468
  ref={mergeRefs(ref, triggerRef)}
469
+ {...triggerProps}
469
470
  onContextMenu={handleContextMenu}
470
471
  {...longPressHandlers}
471
- {...triggerProps}
472
472
  data-testid={testId}
473
473
  {...stylex.props(
474
474
  styles.trigger,
@@ -11,7 +11,7 @@ export {
11
11
  ContextMenu,
12
12
  type ContextMenuProps,
13
13
  type ContextMenuItemData,
14
- type ContextMenuDivider,
14
+ type ContextMenuDividerData,
15
15
  type ContextMenuSection,
16
16
  type ContextMenuOption,
17
17
  } from './ContextMenu';
@@ -20,6 +20,10 @@ export {
20
20
  DropdownMenuItem as ContextMenuItem,
21
21
  type DropdownMenuItemProps as ContextMenuItemProps,
22
22
  } from '../DropdownMenu/DropdownMenuItem';
23
+ export {
24
+ DropdownMenuDivider as ContextMenuDivider,
25
+ type DropdownMenuDividerProps as ContextMenuDividerProps,
26
+ } from '../DropdownMenu/DropdownMenuDivider';
23
27
 
24
28
  // Selectable items work inside a ContextMenu too — re-exported under the
25
29
  // ContextMenu name for a coherent API.
@@ -142,6 +142,13 @@ export const docs = {
142
142
  'Number of months displayed simultaneously in the calendar popover.',
143
143
  default: '1',
144
144
  },
145
+ {
146
+ name: 'weekStartsOn',
147
+ type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'",
148
+ description:
149
+ 'First day of week in the calendar popover. A number (0 = Sunday to 6 = Saturday) or a three-letter day name.',
150
+ default: '0',
151
+ },
145
152
  {
146
153
  name: 'format',
147
154
  type: "'date' | 'date_long' | 'date_weekday' | 'system_date' | ((value: ISODateString) => string)",
@@ -164,9 +171,9 @@ export const docs = {
164
171
  ],
165
172
  theming: {
166
173
  targets: [
167
- {className: 'astryx-date-input', visualProps: ['size', 'status']},
174
+ {className: 'astryx-date-input', visualProps: ['size', 'status'], states: ['disabled']},
168
175
  {className: 'astryx-date-input-toggle-icon', states: ['state']},
169
- {className: 'astryx-date-input-clear-icon'},
176
+ {className: 'astryx-date-input-clear-icon', deprecatedFor: 'input-clear-icon'},
170
177
  ],
171
178
  },
172
179
  usage: {
@@ -417,6 +424,12 @@ export const docsZh = {
417
424
  description: '日历弹出层中同时显示的月份数量。',
418
425
  default: '1',
419
426
  },
427
+ {
428
+ name: 'weekStartsOn',
429
+ type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'",
430
+ description: '日历弹出层中每周的起始日。可为数字(0=周日……6=周六)或三字母星期缩写。',
431
+ default: '0',
432
+ },
420
433
  {
421
434
  name: 'format',
422
435
  type: "'date' | 'date_long' | 'date_weekday' | 'system_date' | ((value: ISODateString) => string)",
@@ -436,9 +449,10 @@ export const docsZh = {
436
449
  {
437
450
  className: 'astryx-date-input',
438
451
  visualProps: ['size', 'status'],
452
+ states: ['disabled'],
439
453
  },
440
454
  {className: 'astryx-date-input-toggle-icon', states: ['state']},
441
- {className: 'astryx-date-input-clear-icon'},
455
+ {className: 'astryx-date-input-clear-icon', deprecatedFor: 'input-clear-icon'},
442
456
  ],
443
457
  },
444
458
  };
@@ -520,6 +534,7 @@ export const docsDense = {
520
534
  labelTooltip: 'tooltip text via info icon at label end',
521
535
  hasClear: 'Shows clear button when date is set. Clears value on click.',
522
536
  numberOfMonths: 'months shown simultaneously in calendar popover',
537
+ weekStartsOn: 'first day of week in calendar (0=Sunday, or name e.g. "mon")',
523
538
  format:
524
539
  "committed-value display: 'date_long' (default, March 21, 2026), 'date' (Mar 21, 2026), 'date_weekday' (Wed, Mar 21, 2026), 'system_date' (2026-03-21), or (iso)=>string; reuses Timestamp vocabulary. Committed value only, not while typing.",
525
540
  xstyle: 'StyleX styles for layout; must be stylex.create() value',
@@ -25,6 +25,7 @@ import {InputGroup} from '../InputGroup';
25
25
  import {InputGroupText} from '../InputGroup/InputGroupText';
26
26
  import {defineTheme} from '../theme/defineTheme';
27
27
  import {generateThemeCSS} from '../theme/generateThemeRules';
28
+ import {InternationalizationProvider} from '../i18n';
28
29
 
29
30
  function generateThemeTestCSS(theme: Parameters<typeof generateThemeCSS>[0]) {
30
31
  const {prose, component} = generateThemeCSS(theme);
@@ -170,6 +171,24 @@ describe('DateInput', () => {
170
171
  expect(screen.queryByText('Invalid date')).not.toBeInTheDocument();
171
172
  });
172
173
 
174
+ it('resolves the invalid-date announcement from the i18n catalog', () => {
175
+ const {container} = render(
176
+ <InternationalizationProvider
177
+ locale="en"
178
+ overrides={{en: {'@astryx.dateInput.invalidDate': 'Ungültiges Datum'}}}>
179
+ <DateInput label="Date" onChange={() => {}} />
180
+ </InternationalizationProvider>,
181
+ );
182
+
183
+ fireEvent.change(screen.getByRole('combobox'), {
184
+ target: {value: '13/45/2024'},
185
+ });
186
+
187
+ expect(within(container).getByRole('alert')).toHaveTextContent(
188
+ 'Ungültiges Datum',
189
+ );
190
+ });
191
+
173
192
  it('reverts to previous value on blur when input is invalid', async () => {
174
193
  const onChange = vi.fn();
175
194
  render(<DateInput label="Date" value="2026-01-25" onChange={onChange} />);
@@ -949,6 +968,61 @@ describe('DateInput', () => {
949
968
  expect(screen.getByDisplayValue('Mar 10, 2026')).toBeInTheDocument();
950
969
  });
951
970
  });
971
+ describe('weekStartsOn', () => {
972
+ // The calendar popover renders in the top layer; jsdom keeps the content in
973
+ // the DOM but role queries skip it, so read the columnheaders directly.
974
+ const openAndReadWeekdays = (container: HTMLElement): (string | null)[] => {
975
+ fireEvent.keyDown(screen.getByRole('combobox'), {key: 'ArrowDown'});
976
+ return Array.from(container.querySelectorAll('[role="columnheader"]'))
977
+ .slice(0, 7)
978
+ .map(h => h.textContent);
979
+ };
980
+
981
+ it('defaults to a Sunday-first week', () => {
982
+ const {container} = render(
983
+ <DateInput label="Date" onChange={() => {}} />,
984
+ );
985
+ expect(openAndReadWeekdays(container)).toEqual([
986
+ 'Su',
987
+ 'Mo',
988
+ 'Tu',
989
+ 'We',
990
+ 'Th',
991
+ 'Fr',
992
+ 'Sa',
993
+ ]);
994
+ });
995
+
996
+ it('forwards a numeric weekStartsOn to the calendar', () => {
997
+ const {container} = render(
998
+ <DateInput label="Date" onChange={() => {}} weekStartsOn={1} />,
999
+ );
1000
+ expect(openAndReadWeekdays(container)).toEqual([
1001
+ 'Mo',
1002
+ 'Tu',
1003
+ 'We',
1004
+ 'Th',
1005
+ 'Fr',
1006
+ 'Sa',
1007
+ 'Su',
1008
+ ]);
1009
+ });
1010
+
1011
+ it('accepts a three-letter day name', () => {
1012
+ const {container} = render(
1013
+ <DateInput label="Date" onChange={() => {}} weekStartsOn="mon" />,
1014
+ );
1015
+ expect(openAndReadWeekdays(container)).toEqual([
1016
+ 'Mo',
1017
+ 'Tu',
1018
+ 'We',
1019
+ 'Th',
1020
+ 'Fr',
1021
+ 'Sa',
1022
+ 'Su',
1023
+ ]);
1024
+ });
1025
+ });
952
1026
  });
953
1027
 
954
1028
  describe('DateInput statusVariant forwarding', () => {
@@ -994,7 +1068,7 @@ describe('DateInput clear icon theme target', () => {
994
1068
  return icon as HTMLElement;
995
1069
  };
996
1070
 
997
- it('renders the astryx-date-input-clear-icon target on the clear glyph', () => {
1071
+ it('renders the astryx-input-clear-icon target (plus the legacy alias) on the clear glyph', () => {
998
1072
  render(
999
1073
  <DateInput
1000
1074
  label="Date"
@@ -1003,11 +1077,13 @@ describe('DateInput clear icon theme target', () => {
1003
1077
  hasClear
1004
1078
  />,
1005
1079
  );
1006
- // The stable theme target lands on the icon element itself (not the
1007
- // button), so a theme can restyle just this glyph (color, size, hover)
1008
- // via `defineTheme` — a button-level target could not reach the icon's
1009
- // own color/size.
1080
+ // The canonical target lands on the icon element itself (not the button),
1081
+ // so a theme can restyle just this glyph (color, size, hover) via
1082
+ // `defineTheme` — a button-level target could not reach the icon's own
1083
+ // color/size. The original per-component name rides along for a
1084
+ // deprecation window.
1010
1085
  const icon = getClearIcon();
1086
+ expect(icon).toHaveClass('astryx-input-clear-icon');
1011
1087
  expect(icon).toHaveClass('astryx-date-input-clear-icon');
1012
1088
  expect(icon).toHaveClass('astryx-icon');
1013
1089
  });
@@ -1028,11 +1104,13 @@ describe('DateInput clear icon theme target', () => {
1028
1104
  expect(onChange).toHaveBeenCalledWith(undefined);
1029
1105
  });
1030
1106
 
1031
- it('renders the default icon (secondary color, sm size) byte-identically', () => {
1032
- // Pixel-identical default guard: the clear glyph must carry the exact same
1033
- // StyleX color/size classes as a standalone secondary/sm icon. The added
1034
- // target class is purely additive it changes nothing until a theme
1035
- // targets it.
1107
+ it('routes the clear glyph through the shared clear button, keeping the legacy target', () => {
1108
+ // The clear affordance now composes the shared InputClearButton (a ghost
1109
+ // Button with a secondary/sm glyph), so the icon carries the canonical
1110
+ // `astryx-input-clear-icon` target andfor a deprecation window the
1111
+ // original `astryx-date-input-clear-icon`. Aside from those target classes
1112
+ // it matches the shared button's own `close`/`sm`/`secondary` glyph
1113
+ // exactly, so the default look is defined in one place.
1036
1114
  render(
1037
1115
  <DateInput
1038
1116
  label="Date"
@@ -1042,6 +1120,8 @@ describe('DateInput clear icon theme target', () => {
1042
1120
  />,
1043
1121
  );
1044
1122
  const icon = getClearIcon();
1123
+ expect(icon).toHaveClass('astryx-input-clear-icon');
1124
+ expect(icon).toHaveClass('astryx-date-input-clear-icon');
1045
1125
 
1046
1126
  const {container: refContainer} = render(
1047
1127
  <Icon icon="close" size="sm" color="secondary" />,
@@ -1051,7 +1131,11 @@ describe('DateInput clear icon theme target', () => {
1051
1131
  const styleClasses = (el: HTMLElement) =>
1052
1132
  el.className
1053
1133
  .split(' ')
1054
- .filter(c => c !== 'astryx-date-input-clear-icon')
1134
+ .filter(
1135
+ c =>
1136
+ c !== 'astryx-input-clear-icon' &&
1137
+ c !== 'astryx-date-input-clear-icon',
1138
+ )
1055
1139
  .sort();
1056
1140
 
1057
1141
  expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
@@ -1177,3 +1261,20 @@ describe('DateInput calendar-toggle icon theme target', () => {
1177
1261
  expect(css).toContain('color: var(--color-icon-primary)');
1178
1262
  });
1179
1263
  });
1264
+
1265
+ describe('DateInput disabled theme state', () => {
1266
+ it('reflects disabled on the root target so themes can gate paint on it', () => {
1267
+ const {container} = render(
1268
+ <DateInput label="Date" onChange={() => {}} isDisabled />,
1269
+ );
1270
+ const root = container.querySelector('.astryx-date-input');
1271
+ expect(root).toHaveAttribute('data-disabled', 'disabled');
1272
+ expect(root).toHaveClass('disabled');
1273
+ });
1274
+
1275
+ it('omits data-disabled when enabled, like status does', () => {
1276
+ const {container} = render(<DateInput label="Date" onChange={() => {}} />);
1277
+ const root = container.querySelector('.astryx-date-input');
1278
+ expect(root).not.toHaveAttribute('data-disabled');
1279
+ });
1280
+ });
@@ -35,6 +35,7 @@ import {
35
35
  } from '../theme/tokens.stylex';
36
36
  import {
37
37
  Field,
38
+ InputClearButton,
38
39
  type InputStatus,
39
40
  inputWrapperStyles,
40
41
  inputStatusBorderStyles,
@@ -48,7 +49,13 @@ import {useInputGroup} from '../InputGroup/InputGroupContext';
48
49
  import {groupStyles} from '../InputGroup/groupStyles';
49
50
  import {useSize} from '../SizeContext/SizeContext';
50
51
  import {Spinner} from '../Spinner';
51
- import {Calendar, type ISODateString, type CalendarHandle} from '../Calendar';
52
+ import {
53
+ Calendar,
54
+ type ISODateString,
55
+ type CalendarHandle,
56
+ type DayOfWeek,
57
+ type DayOfWeekName,
58
+ } from '../Calendar';
52
59
  import {useCalendarConstraints} from '../Calendar/hooks';
53
60
  import {useInputStatusIcon} from '../hooks/useInputStatusIcon';
54
61
  import {usePopover} from '../Popover';
@@ -73,11 +80,6 @@ const styles = stylex.create({
73
80
  backgroundColor: 'transparent',
74
81
  cursor: 'pointer',
75
82
  borderRadius: radiusVars['--radius-element'],
76
- outline: {
77
- default: 'none',
78
- ':focus-visible': `${borderVars['--border-width']} solid ${colorVars['--color-accent']}`,
79
- },
80
- outlineOffset: 1,
81
83
  },
82
84
  iconButtonDisabled: {
83
85
  cursor: 'not-allowed',
@@ -152,10 +154,12 @@ export type {
152
154
  InputStatus as DateInputStatus,
153
155
  InputStatusType as DateInputStatusType,
154
156
  } from '../Field';
155
- import {mergeProps, mergeRefs} from '../utils';
157
+ import {mergeProps, mergeRefs, isFocusDetached} from '../utils';
156
158
  import type {BaseProps} from '../BaseProps';
157
159
  import type {SizeValue} from '../utils/types';
158
160
  import {themeProps} from '../utils/themeProps';
161
+ import {focusOutlineStyles} from '../utils/focusOutline.stylex';
162
+ import {stableClassName} from '../naming';
159
163
  import {useTranslator} from '../i18n';
160
164
 
161
165
  export interface DateInputProps extends Omit<
@@ -311,6 +315,14 @@ export interface DateInputProps extends Omit<
311
315
  */
312
316
  numberOfMonths?: 1 | 2;
313
317
 
318
+ /**
319
+ * First day of week in the calendar popover. Accepts a number
320
+ * (0 = Sunday … 6 = Saturday) or a three-letter day name ('sun'–'sat',
321
+ * case-insensitive).
322
+ * @default 0
323
+ */
324
+ weekStartsOn?: DayOfWeek | DayOfWeekName;
325
+
314
326
  /**
315
327
  * How the committed date value is displayed in the text field. Accepts a
316
328
  * named format reused from `Timestamp`'s `format` vocabulary (so the same
@@ -377,6 +389,7 @@ export function DateInput({
377
389
  labelTooltip,
378
390
  hasClear = false,
379
391
  numberOfMonths = 1,
392
+ weekStartsOn,
380
393
  format = 'date_long',
381
394
  width,
382
395
  xstyle,
@@ -489,7 +502,18 @@ export function DateInput({
489
502
  const popover = usePopover({
490
503
  dialogLabel: t('@astryx.dateInput.dialogLabel'),
491
504
  closeButtonLabel: t('@astryx.dateInput.closeCalendar'),
492
- onHide: () => inputRef.current?.focus(),
505
+ // Return focus to the input when the calendar closes — but only when the
506
+ // dismiss left focus detached (Escape, or a click on non-focusable empty
507
+ // space), which the focus trap can't restore on its own. A native
508
+ // popover="auto" light-dismiss fires synchronously with the pointer event
509
+ // that moved focus, so if the user clicked another control — the clear
510
+ // button, another field, anywhere — focus has already landed there;
511
+ // reclaiming it would fight their click.
512
+ onHide: () => {
513
+ if (isFocusDetached()) {
514
+ inputRef.current?.focus();
515
+ }
516
+ },
493
517
  });
494
518
 
495
519
  // Handle toggling the popover from button click (focus calendar)
@@ -635,7 +659,11 @@ export function DateInput({
635
659
  }}
636
660
  {...rest}
637
661
  {...mergeProps(
638
- themeProps('date-input', {size, status: status?.type ?? null}),
662
+ themeProps('date-input', {
663
+ size,
664
+ status: status?.type ?? null,
665
+ disabled: isDisabled ? 'disabled' : null,
666
+ }),
639
667
  stylex.props(
640
668
  inputWrapperStyles.base,
641
669
  sizeStyles[size],
@@ -662,6 +690,7 @@ export function DateInput({
662
690
  : t('@astryx.dateInput.openCalendar')
663
691
  }
664
692
  {...stylex.props(
693
+ focusOutlineStyles.focusVisible,
665
694
  styles.iconButton,
666
695
  isEffectivelyDisabled && styles.iconButtonDisabled,
667
696
  )}>
@@ -722,25 +751,14 @@ export function DateInput({
722
751
  user would get no feedback that their entry was rejected (WCAG 3.3.1).
723
752
  */}
724
753
  <VisuallyHidden as="div" role="alert" aria-live="assertive">
725
- {!isInputValid ? 'Invalid date' : ''}
754
+ {!isInputValid ? t('@astryx.dateInput.invalidDate') : ''}
726
755
  </VisuallyHidden>
727
756
  {hasClear && value !== undefined && !isEffectivelyDisabled && (
728
- <button
729
- type="button"
757
+ <InputClearButton
758
+ label={t('@astryx.dateInput.clear', {label})}
730
759
  onClick={handleClear}
731
- aria-label={t('@astryx.dateInput.clear', {label})}
732
- {...stylex.props(styles.iconButton)}>
733
- <Icon
734
- icon="close"
735
- size="sm"
736
- color="secondary"
737
- // Stable theme target on the clear glyph itself, so a theme can
738
- // restyle just this icon (color, size, hover) via `defineTheme`.
739
- // Same-element rules in @layer astryx-theme win over the icon's own
740
- // base color/size, which a button-level target could not reach.
741
- {...themeProps('date-input-clear-icon')}
742
- />
743
- </button>
760
+ iconClassName={stableClassName('date-input-clear-icon')}
761
+ />
744
762
  )}
745
763
  {isBusy && <Spinner size="sm" />}
746
764
  {statusIcon}
@@ -754,6 +772,7 @@ export function DateInput({
754
772
  max={max}
755
773
  dateConstraints={dateConstraints}
756
774
  numberOfMonths={numberOfMonths}
775
+ weekStartsOn={weekStartsOn}
757
776
  />,
758
777
  {placement: 'below', alignment: 'start'},
759
778
  )}