@astryxdesign/core 0.1.8 → 0.1.9-canary.09e9ddd

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 (610) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +6 -2
  4. package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
  5. package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
  6. package/dist/Avatar/Avatar.d.ts +53 -3
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +203 -49
  9. package/dist/Avatar/AvatarStatusDot.d.ts +33 -5
  10. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  11. package/dist/Avatar/AvatarStatusDot.js +144 -19
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  15. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  16. package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
  17. package/dist/Banner/Banner.d.ts +9 -1
  18. package/dist/Banner/Banner.d.ts.map +1 -1
  19. package/dist/Banner/Banner.js +33 -4
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
  21. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  22. package/dist/Breadcrumbs/BreadcrumbItem.js +208 -6
  23. package/dist/Breadcrumbs/index.d.ts +5 -0
  24. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  25. package/dist/Breadcrumbs/index.js +9 -1
  26. package/dist/Button/Button.d.ts +8 -2
  27. package/dist/Button/Button.d.ts.map +1 -1
  28. package/dist/Button/Button.js +33 -4
  29. package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
  30. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  31. package/dist/ButtonGroup/ButtonGroup.js +30 -1
  32. package/dist/Calendar/Calendar.d.ts.map +1 -1
  33. package/dist/Calendar/Calendar.js +30 -2
  34. package/dist/Calendar/dayCellUtils.js +1 -1
  35. package/dist/Card/Card.d.ts +8 -2
  36. package/dist/Card/Card.d.ts.map +1 -1
  37. package/dist/Card/Card.js +28 -2
  38. package/dist/Carousel/Carousel.d.ts +4 -1
  39. package/dist/Carousel/Carousel.d.ts.map +1 -1
  40. package/dist/Carousel/Carousel.js +24 -4
  41. package/dist/Chat/ChatComposer.d.ts +8 -0
  42. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposer.js +46 -7
  44. package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
  45. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  46. package/dist/Chat/ChatComposerDrawer.js +11 -1
  47. package/dist/Chat/ChatComposerInput.d.ts +20 -3
  48. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  49. package/dist/Chat/ChatComposerInput.js +36 -4
  50. package/dist/Chat/ChatContext.d.ts +33 -0
  51. package/dist/Chat/ChatContext.d.ts.map +1 -1
  52. package/dist/Chat/ChatContext.js +16 -2
  53. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  54. package/dist/Chat/ChatDictationButton.js +1 -1
  55. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  56. package/dist/Chat/ChatLayout.js +4 -4
  57. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  58. package/dist/Chat/ChatLayoutScrollButton.js +4 -4
  59. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  60. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  61. package/dist/Chat/ChatSendButton.js +7 -1
  62. package/dist/Chat/ChatToolCalls.d.ts +5 -1
  63. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  64. package/dist/Chat/ChatToolCalls.js +18 -9
  65. package/dist/Chat/index.d.ts +2 -1
  66. package/dist/Chat/index.d.ts.map +1 -1
  67. package/dist/Chat/index.js +1 -1
  68. package/dist/Chat/useChatStreamScroll.d.ts +2 -1
  69. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  70. package/dist/Chat/useChatStreamScroll.js +22 -8
  71. package/dist/Chat/useSpeechRecognition.d.ts +0 -1
  72. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  73. package/dist/Chat/useSpeechRecognition.js +1 -1
  74. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  75. package/dist/Chat/useTriggerMenu.js +2 -2
  76. package/dist/CheckboxInput/CheckboxInput.js +1 -1
  77. package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
  78. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  79. package/dist/CheckboxList/CheckboxListItem.js +11 -1
  80. package/dist/Citation/Citation.d.ts +22 -1
  81. package/dist/Citation/Citation.d.ts.map +1 -1
  82. package/dist/Citation/Citation.js +20 -6
  83. package/dist/ClickableCard/ClickableCard.d.ts +9 -2
  84. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  85. package/dist/ClickableCard/ClickableCard.js +5 -2
  86. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  87. package/dist/CodeBlock/CodeBlock.js +9 -2
  88. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  89. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  90. package/dist/CommandPalette/CommandPalette.js +3 -1
  91. package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
  92. package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
  93. package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
  94. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  95. package/dist/CommandPalette/CommandPaletteInput.js +6 -1
  96. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  97. package/dist/DateInput/DateInput.d.ts +55 -2
  98. package/dist/DateInput/DateInput.d.ts.map +1 -1
  99. package/dist/DateInput/DateInput.js +28 -2
  100. package/dist/DateInput/index.d.ts +1 -1
  101. package/dist/DateInput/index.d.ts.map +1 -1
  102. package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
  103. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  104. package/dist/DateRangeInput/DateRangeInput.js +3 -1
  105. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  106. package/dist/DateTimeInput/DateTimeInput.js +18 -3
  107. package/dist/Dialog/Dialog.d.ts +3 -0
  108. package/dist/Dialog/Dialog.d.ts.map +1 -1
  109. package/dist/Dialog/Dialog.js +57 -6
  110. package/dist/Dialog/DialogContext.d.ts +7 -0
  111. package/dist/Dialog/DialogContext.d.ts.map +1 -1
  112. package/dist/Dialog/DialogContext.js +2 -2
  113. package/dist/Dialog/DialogHeader.d.ts +5 -2
  114. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  115. package/dist/Dialog/DialogHeader.js +6 -1
  116. package/dist/Divider/Divider.js +1 -1
  117. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
  118. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  119. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -2
  120. package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
  121. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
  122. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  123. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
  124. package/dist/Field/Field.d.ts.map +1 -1
  125. package/dist/Field/Field.js +2 -3
  126. package/dist/Field/FieldLabel.d.ts +1 -1
  127. package/dist/Field/FieldLabel.d.ts.map +1 -1
  128. package/dist/Field/FieldLabel.js +43 -16
  129. package/dist/FieldStatus/FieldStatus.d.ts +15 -0
  130. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  131. package/dist/FieldStatus/FieldStatus.js +58 -6
  132. package/dist/FileInput/FileInput.d.ts +9 -2
  133. package/dist/FileInput/FileInput.d.ts.map +1 -1
  134. package/dist/FileInput/FileInput.js +42 -20
  135. package/dist/HoverCard/HoverCard.d.ts +9 -1
  136. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  137. package/dist/HoverCard/HoverCard.js +2 -0
  138. package/dist/HoverCard/useHoverCard.d.ts +8 -0
  139. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  140. package/dist/HoverCard/useHoverCard.js +7 -2
  141. package/dist/Icon/Icon.d.ts +7 -2
  142. package/dist/Icon/Icon.d.ts.map +1 -1
  143. package/dist/Item/Item.d.ts +6 -1
  144. package/dist/Item/Item.d.ts.map +1 -1
  145. package/dist/Item/Item.js +22 -1
  146. package/dist/Layer/useLayer.d.ts +6 -0
  147. package/dist/Layer/useLayer.d.ts.map +1 -1
  148. package/dist/Layer/useLayer.js +2 -0
  149. package/dist/Lightbox/Lightbox.js +4 -4
  150. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  151. package/dist/MobileNav/MobileNav.js +6 -1
  152. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  153. package/dist/MobileNav/MobileNavToggle.js +4 -0
  154. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  155. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  156. package/dist/MultiSelector/MultiSelector.js +41 -12
  157. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  158. package/dist/MultiSelector/hooks.js +16 -0
  159. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  160. package/dist/NumberInput/NumberInput.d.ts +9 -2
  161. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  162. package/dist/NumberInput/NumberInput.js +8 -1
  163. package/dist/Outline/Outline.d.ts +0 -1
  164. package/dist/Outline/Outline.d.ts.map +1 -1
  165. package/dist/Outline/Outline.js +0 -1
  166. package/dist/OverflowList/OverflowList.d.ts +20 -3
  167. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  168. package/dist/OverflowList/OverflowList.js +29 -4
  169. package/dist/Pagination/Pagination.d.ts.map +1 -1
  170. package/dist/Pagination/Pagination.js +11 -3
  171. package/dist/Popover/Popover.d.ts.map +1 -1
  172. package/dist/Popover/Popover.js +3 -2
  173. package/dist/Popover/usePopover.d.ts.map +1 -1
  174. package/dist/Popover/usePopover.js +3 -9
  175. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  176. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  177. package/dist/PowerSearch/PowerSearch.js +2 -0
  178. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  179. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  180. package/dist/SelectableCard/SelectableCard.d.ts +9 -2
  181. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  182. package/dist/SelectableCard/SelectableCard.js +16 -13
  183. package/dist/Selector/Selector.d.ts +8 -0
  184. package/dist/Selector/Selector.d.ts.map +1 -1
  185. package/dist/Selector/Selector.js +7 -3
  186. package/dist/Selector/hooks.d.ts.map +1 -1
  187. package/dist/Selector/hooks.js +16 -0
  188. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  189. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  190. package/dist/SideNav/SideNavHeading.js +21 -8
  191. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +19 -2
  194. package/dist/Stack/stack.stylex.d.ts +9 -9
  195. package/dist/TabList/Tab.js +2 -2
  196. package/dist/TabList/TabMenu.js +1 -1
  197. package/dist/Table/BaseTable.d.ts.map +1 -1
  198. package/dist/Table/BaseTable.js +3 -2
  199. package/dist/Table/TableCell.js +3 -3
  200. package/dist/Table/TableHeaderCell.js +3 -3
  201. package/dist/Table/index.d.ts +2 -0
  202. package/dist/Table/index.d.ts.map +1 -1
  203. package/dist/Table/index.js +1 -0
  204. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  205. package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
  206. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
  207. package/dist/Table/plugins/rowStatus/index.js +3 -0
  208. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
  209. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
  210. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
  211. package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +4 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
  215. package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
  216. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  217. package/dist/Table/plugins/tree/useTableTreeData.js +87 -0
  218. package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
  219. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
  220. package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
  221. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  222. package/dist/Table/useBaseTablePlugins.js +5 -3
  223. package/dist/TextArea/TextArea.d.ts +9 -1
  224. package/dist/TextArea/TextArea.d.ts.map +1 -1
  225. package/dist/TextArea/TextArea.js +2 -0
  226. package/dist/TextInput/TextInput.d.ts +9 -2
  227. package/dist/TextInput/TextInput.d.ts.map +1 -1
  228. package/dist/TextInput/TextInput.js +6 -1
  229. package/dist/Thumbnail/Thumbnail.d.ts +26 -5
  230. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  231. package/dist/Thumbnail/Thumbnail.js +97 -54
  232. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
  233. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
  234. package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
  235. package/dist/TimeInput/TimeInput.d.ts +9 -2
  236. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  237. package/dist/TimeInput/TimeInput.js +17 -4
  238. package/dist/Timestamp/Timestamp.d.ts +3 -1
  239. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  240. package/dist/Timestamp/Timestamp.js +8 -6
  241. package/dist/Toast/useToast.d.ts.map +1 -1
  242. package/dist/Toast/useToast.js +2 -5
  243. package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
  244. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  245. package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
  246. package/dist/Tokenizer/Tokenizer.d.ts +10 -3
  247. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  248. package/dist/Tokenizer/Tokenizer.js +18 -4
  249. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  250. package/dist/TopNav/TopNavHeading.js +18 -8
  251. package/dist/TopNav/TopNavMegaMenu.js +10 -4
  252. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
  253. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
  255. package/dist/TopNav/TopNavMenu.d.ts +2 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +68 -6
  258. package/dist/TreeList/TreeList.d.ts +12 -3
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +2 -0
  261. package/dist/TreeList/TreeListBranches.d.ts +5 -0
  262. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  263. package/dist/TreeList/TreeListBranches.js +10 -4
  264. package/dist/TreeList/TreeListItem.d.ts +8 -2
  265. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  266. package/dist/TreeList/TreeListItem.js +28 -8
  267. package/dist/TreeList/TreeListTypes.d.ts +25 -1
  268. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  269. package/dist/TreeList/index.d.ts +2 -2
  270. package/dist/TreeList/index.d.ts.map +1 -1
  271. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  272. package/dist/Typeahead/BaseTypeahead.js +20 -11
  273. package/dist/Typeahead/Typeahead.d.ts +9 -2
  274. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  275. package/dist/Typeahead/Typeahead.js +2 -0
  276. package/dist/astryx.css +41 -31
  277. package/dist/astryx.umd.js +51 -51
  278. package/dist/astryx.umd.js.map +4 -4
  279. package/dist/authoring/doc.d.ts.map +1 -1
  280. package/dist/docs-types.d.ts +8 -0
  281. package/dist/docs-types.d.ts.map +1 -1
  282. package/dist/hooks/computeOverflow.d.ts +47 -0
  283. package/dist/hooks/computeOverflow.d.ts.map +1 -0
  284. package/dist/hooks/computeOverflow.js +213 -0
  285. package/dist/hooks/index.d.ts +1 -0
  286. package/dist/hooks/index.d.ts.map +1 -1
  287. package/dist/hooks/index.js +2 -1
  288. package/dist/hooks/isRtlElement.d.ts +18 -0
  289. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  290. package/dist/hooks/isRtlElement.js +27 -0
  291. package/dist/hooks/useDevWarning.d.ts +18 -0
  292. package/dist/hooks/useDevWarning.d.ts.map +1 -0
  293. package/dist/hooks/useDevWarning.js +49 -0
  294. package/dist/hooks/useGridFocus.d.ts +6 -1
  295. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  296. package/dist/hooks/useGridFocus.js +12 -9
  297. package/dist/hooks/useListFocus.d.ts +6 -1
  298. package/dist/hooks/useListFocus.d.ts.map +1 -1
  299. package/dist/hooks/useListFocus.js +12 -4
  300. package/dist/hooks/useOverflow.d.ts +19 -0
  301. package/dist/hooks/useOverflow.d.ts.map +1 -1
  302. package/dist/hooks/useOverflow.js +36 -25
  303. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  304. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  305. package/dist/i18n/InternationalizationContext.js +3 -0
  306. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  307. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  308. package/dist/i18n/InternationalizationProvider.js +5 -1
  309. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  310. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  311. package/dist/i18n/getLocaleDirection.js +29 -0
  312. package/dist/i18n/index.d.ts +6 -0
  313. package/dist/i18n/index.d.ts.map +1 -1
  314. package/dist/i18n/index.js +7 -1
  315. package/dist/i18n/resolve.d.ts.map +1 -1
  316. package/dist/i18n/resolve.js +7 -18
  317. package/dist/i18n/useDirection.d.ts +2 -0
  318. package/dist/i18n/useDirection.d.ts.map +1 -0
  319. package/dist/i18n/useDirection.js +27 -0
  320. package/dist/theme/Theme.d.ts.map +1 -1
  321. package/dist/theme/Theme.js +2 -7
  322. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  323. package/dist/theme/derivedVarRegistry.js +13 -0
  324. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  325. package/dist/theme/generateThemeRules.js +51 -0
  326. package/dist/theme/hct.d.ts +0 -1
  327. package/dist/theme/hct.d.ts.map +1 -1
  328. package/dist/theme/hct.js +1 -1
  329. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  330. package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
  331. package/dist/utils/devWarning.d.ts +42 -0
  332. package/dist/utils/devWarning.d.ts.map +1 -0
  333. package/dist/utils/devWarning.js +88 -0
  334. package/dist/utils/index.d.ts +3 -1
  335. package/dist/utils/index.d.ts.map +1 -1
  336. package/dist/utils/index.js +3 -2
  337. package/dist/utils/plainDate.d.ts +30 -0
  338. package/dist/utils/plainDate.d.ts.map +1 -1
  339. package/dist/utils/plainDate.js +53 -0
  340. package/dist/utils/types.d.ts +13 -0
  341. package/dist/utils/types.d.ts.map +1 -1
  342. package/locales/en.json +32 -0
  343. package/locales/fr-FR.json +14 -0
  344. package/locales/pseudo.json +24 -0
  345. package/package.json +1 -1
  346. package/src/AppShell/AppShell.tsx +6 -0
  347. package/src/AppShell/AppShellMobileContext.tsx +8 -0
  348. package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
  349. package/src/Avatar/Avatar.doc.mjs +60 -3
  350. package/src/Avatar/Avatar.test.tsx +281 -1
  351. package/src/Avatar/Avatar.tsx +324 -64
  352. package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
  353. package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
  354. package/src/Avatar/AvatarStatusDot.tsx +178 -21
  355. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  356. package/src/AvatarGroup/AvatarGroup.test.tsx +125 -0
  357. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  358. package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
  359. package/src/Banner/Banner.doc.mjs +9 -0
  360. package/src/Banner/Banner.test.tsx +30 -0
  361. package/src/Banner/Banner.tsx +53 -9
  362. package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
  363. package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
  364. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
  365. package/src/Breadcrumbs/Breadcrumbs.test.tsx +284 -2
  366. package/src/Breadcrumbs/index.ts +27 -0
  367. package/src/Button/Button.doc.mjs +9 -4
  368. package/src/Button/Button.test.tsx +49 -0
  369. package/src/Button/Button.tsx +27 -3
  370. package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
  371. package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
  372. package/src/ButtonGroup/ButtonGroup.tsx +32 -0
  373. package/src/Calendar/Calendar.doc.mjs +12 -1
  374. package/src/Calendar/Calendar.test.tsx +193 -0
  375. package/src/Calendar/Calendar.tsx +38 -16
  376. package/src/Calendar/dayCellUtils.test.ts +5 -0
  377. package/src/Calendar/dayCellUtils.ts +1 -1
  378. package/src/Card/Card.doc.mjs +9 -0
  379. package/src/Card/Card.test.tsx +21 -3
  380. package/src/Card/Card.tsx +35 -2
  381. package/src/Carousel/Carousel.doc.mjs +1 -0
  382. package/src/Carousel/Carousel.test.tsx +53 -0
  383. package/src/Carousel/Carousel.tsx +34 -4
  384. package/src/Chat/ChatComposer.doc.mjs +12 -3
  385. package/src/Chat/ChatComposer.test.tsx +115 -0
  386. package/src/Chat/ChatComposer.tsx +73 -9
  387. package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
  388. package/src/Chat/ChatComposerDrawer.tsx +11 -1
  389. package/src/Chat/ChatComposerInput.doc.mjs +7 -0
  390. package/src/Chat/ChatComposerInput.test.tsx +103 -0
  391. package/src/Chat/ChatComposerInput.tsx +51 -5
  392. package/src/Chat/ChatContext.tsx +37 -10
  393. package/src/Chat/ChatDictationButton.tsx +4 -1
  394. package/src/Chat/ChatLayout.tsx +7 -5
  395. package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
  396. package/src/Chat/ChatMessageMetadata.tsx +1 -2
  397. package/src/Chat/ChatSendButton.tsx +11 -1
  398. package/src/Chat/ChatToolCalls.test.tsx +64 -0
  399. package/src/Chat/ChatToolCalls.tsx +25 -4
  400. package/src/Chat/index.ts +5 -1
  401. package/src/Chat/useChatStreamScroll.test.tsx +49 -0
  402. package/src/Chat/useChatStreamScroll.ts +27 -10
  403. package/src/Chat/useSpeechRecognition.ts +1 -1
  404. package/src/Chat/useTriggerMenu.tsx +4 -2
  405. package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
  406. package/src/CheckboxInput/CheckboxInput.tsx +1 -1
  407. package/src/CheckboxList/CheckboxList.test.tsx +81 -3
  408. package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
  409. package/src/CheckboxList/CheckboxListItem.tsx +41 -5
  410. package/src/Citation/Citation.doc.mjs +4 -3
  411. package/src/Citation/Citation.test.tsx +97 -0
  412. package/src/Citation/Citation.tsx +43 -11
  413. package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
  414. package/src/ClickableCard/ClickableCard.test.tsx +34 -0
  415. package/src/ClickableCard/ClickableCard.tsx +13 -3
  416. package/src/CodeBlock/CodeBlock.test.tsx +56 -0
  417. package/src/CodeBlock/CodeBlock.tsx +10 -2
  418. package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
  419. package/src/CommandPalette/CommandPalette.tsx +3 -1
  420. package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
  421. package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
  422. package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
  423. package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
  424. package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
  425. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  426. package/src/ContextMenu/ContextMenu.test.tsx +193 -0
  427. package/src/DateInput/DateInput.doc.mjs +31 -0
  428. package/src/DateInput/DateInput.test.tsx +131 -0
  429. package/src/DateInput/DateInput.tsx +78 -3
  430. package/src/DateInput/index.ts +1 -0
  431. package/src/DateRangeInput/DateRangeInput.doc.mjs +8 -0
  432. package/src/DateRangeInput/DateRangeInput.test.tsx +23 -0
  433. package/src/DateRangeInput/DateRangeInput.tsx +13 -3
  434. package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -1
  435. package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
  436. package/src/DateTimeInput/DateTimeInput.tsx +42 -18
  437. package/src/Dialog/Dialog.doc.mjs +2 -2
  438. package/src/Dialog/Dialog.test.tsx +77 -4
  439. package/src/Dialog/Dialog.tsx +89 -5
  440. package/src/Dialog/DialogContext.ts +9 -2
  441. package/src/Dialog/DialogHeader.doc.mjs +2 -2
  442. package/src/Dialog/DialogHeader.tsx +9 -2
  443. package/src/Divider/Divider.tsx +2 -2
  444. package/src/DropdownMenu/DropdownMenu.test.tsx +169 -0
  445. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
  446. package/src/DropdownMenu/DropdownMenuItem.tsx +1 -1
  447. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
  448. package/src/Field/Field.test.tsx +57 -12
  449. package/src/Field/Field.tsx +6 -5
  450. package/src/Field/FieldLabel.tsx +9 -1
  451. package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
  452. package/src/FieldStatus/FieldStatus.test.tsx +150 -40
  453. package/src/FieldStatus/FieldStatus.tsx +63 -5
  454. package/src/FileInput/FileInput.doc.mjs +17 -2
  455. package/src/FileInput/FileInput.test.tsx +135 -12
  456. package/src/FileInput/FileInput.tsx +53 -28
  457. package/src/HoverCard/HoverCard.doc.mjs +13 -0
  458. package/src/HoverCard/HoverCard.test.tsx +21 -2
  459. package/src/HoverCard/HoverCard.tsx +11 -0
  460. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  461. package/src/HoverCard/useHoverCard.tsx +24 -2
  462. package/src/Icon/Icon.doc.mjs +3 -2
  463. package/src/Icon/Icon.tsx +7 -2
  464. package/src/IconButton/IconButton.doc.mjs +8 -0
  465. package/src/IconButton/IconButton.test.tsx +15 -18
  466. package/src/Item/Item.test.tsx +40 -18
  467. package/src/Item/Item.tsx +38 -2
  468. package/src/Layer/useLayer.tsx +8 -0
  469. package/src/Lightbox/Lightbox.tsx +4 -4
  470. package/src/List/List.test.tsx +9 -8
  471. package/src/MobileNav/MobileNav.tsx +12 -1
  472. package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
  473. package/src/MobileNav/MobileNavToggle.tsx +9 -1
  474. package/src/MultiSelector/MultiSelector.doc.mjs +13 -2
  475. package/src/MultiSelector/MultiSelector.test.tsx +195 -3
  476. package/src/MultiSelector/MultiSelector.tsx +65 -12
  477. package/src/MultiSelector/hooks.ts +17 -0
  478. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  479. package/src/NumberInput/NumberInput.doc.mjs +15 -0
  480. package/src/NumberInput/NumberInput.test.tsx +82 -7
  481. package/src/NumberInput/NumberInput.tsx +21 -4
  482. package/src/Outline/Outline.tsx +0 -1
  483. package/src/OverflowList/OverflowList.doc.mjs +39 -6
  484. package/src/OverflowList/OverflowList.test.tsx +111 -0
  485. package/src/OverflowList/OverflowList.tsx +48 -8
  486. package/src/Pagination/Pagination.tsx +11 -3
  487. package/src/Popover/Popover.tsx +7 -4
  488. package/src/Popover/usePopover.tsx +9 -13
  489. package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
  490. package/src/PowerSearch/PowerSearch.test.tsx +43 -0
  491. package/src/PowerSearch/PowerSearch.tsx +10 -1
  492. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
  493. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  494. package/src/PowerSearch/usePowerSearchSource.ts +1 -2
  495. package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
  496. package/src/SelectableCard/SelectableCard.test.tsx +46 -4
  497. package/src/SelectableCard/SelectableCard.tsx +29 -16
  498. package/src/Selector/Selector.doc.mjs +7 -0
  499. package/src/Selector/Selector.test.tsx +92 -0
  500. package/src/Selector/Selector.tsx +16 -2
  501. package/src/Selector/hooks.ts +17 -0
  502. package/src/SideNav/SideNav.test.tsx +119 -3
  503. package/src/SideNav/SideNavCollapseButton.tsx +6 -1
  504. package/src/SideNav/SideNavHeading.tsx +24 -8
  505. package/src/SideNav/SideNavItem.tsx +5 -1
  506. package/src/Slider/Slider.test.tsx +75 -2
  507. package/src/Slider/Slider.tsx +21 -5
  508. package/src/Switch/Switch.test.tsx +32 -1
  509. package/src/TabList/Tab.tsx +2 -2
  510. package/src/TabList/TabMenu.tsx +2 -2
  511. package/src/Table/BaseTable.tsx +3 -5
  512. package/src/Table/TableCell.tsx +3 -3
  513. package/src/Table/TableHeaderCell.tsx +3 -3
  514. package/src/Table/index.ts +5 -0
  515. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
  516. package/src/Table/plugins/rowStatus/index.ts +7 -0
  517. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
  518. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
  519. package/src/Table/plugins/selection/useTableSelection.test.tsx +16 -0
  520. package/src/Table/plugins/selection/useTableSelection.tsx +19 -1
  521. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
  522. package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
  523. package/src/Table/plugins/tree/useTableTreeData.tsx +128 -1
  524. package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
  525. package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
  526. package/src/Table/useBaseTablePlugins.ts +10 -6
  527. package/src/Table/useTableRowStatus.doc.mjs +30 -0
  528. package/src/Table/useTableSelection.doc.mjs +65 -14
  529. package/src/Table/useTableTreeData.doc.mjs +29 -0
  530. package/src/Table/useTableTreeState.doc.mjs +2 -2
  531. package/src/TextArea/TextArea.doc.mjs +15 -0
  532. package/src/TextArea/TextArea.test.tsx +32 -1
  533. package/src/TextArea/TextArea.tsx +10 -0
  534. package/src/TextInput/TextInput.doc.mjs +15 -0
  535. package/src/TextInput/TextInput.test.tsx +44 -0
  536. package/src/TextInput/TextInput.tsx +13 -1
  537. package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
  538. package/src/Thumbnail/Thumbnail.test.tsx +98 -7
  539. package/src/Thumbnail/Thumbnail.tsx +142 -42
  540. package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
  541. package/src/TimeInput/TimeInput.doc.mjs +15 -0
  542. package/src/TimeInput/TimeInput.test.tsx +99 -1
  543. package/src/TimeInput/TimeInput.tsx +29 -6
  544. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  545. package/src/Timestamp/Timestamp.test.tsx +32 -0
  546. package/src/Timestamp/Timestamp.tsx +28 -8
  547. package/src/Toast/useToast.tsx +7 -8
  548. package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
  549. package/src/Tokenizer/Tokenizer.doc.mjs +30 -1
  550. package/src/Tokenizer/Tokenizer.test.tsx +206 -2
  551. package/src/Tokenizer/Tokenizer.tsx +26 -4
  552. package/src/TopNav/TopNav.test.tsx +125 -1
  553. package/src/TopNav/TopNavHeading.tsx +24 -8
  554. package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
  555. package/src/TopNav/TopNavMegaMenu.tsx +10 -4
  556. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
  557. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
  558. package/src/TopNav/TopNavMenu.test.tsx +118 -4
  559. package/src/TopNav/TopNavMenu.tsx +83 -5
  560. package/src/TreeList/TreeList.doc.mjs +22 -0
  561. package/src/TreeList/TreeList.test.tsx +232 -0
  562. package/src/TreeList/TreeList.tsx +18 -2
  563. package/src/TreeList/TreeListBranches.tsx +16 -2
  564. package/src/TreeList/TreeListItem.tsx +52 -12
  565. package/src/TreeList/TreeListTypes.ts +27 -1
  566. package/src/TreeList/index.ts +2 -2
  567. package/src/Typeahead/BaseTypeahead.tsx +30 -15
  568. package/src/Typeahead/Typeahead.doc.mjs +7 -0
  569. package/src/Typeahead/Typeahead.test.tsx +50 -0
  570. package/src/Typeahead/Typeahead.tsx +10 -0
  571. package/src/authoring/doc.ts +1 -3
  572. package/src/docs-types.ts +5 -0
  573. package/src/hooks/computeOverflow.test.ts +422 -0
  574. package/src/hooks/computeOverflow.ts +290 -0
  575. package/src/hooks/index.ts +2 -0
  576. package/src/hooks/isRtlElement.ts +27 -0
  577. package/src/hooks/useDevWarning.test.tsx +45 -0
  578. package/src/hooks/useDevWarning.ts +54 -0
  579. package/src/hooks/useGridFocus.doc.mjs +3 -3
  580. package/src/hooks/useGridFocus.test.tsx +41 -0
  581. package/src/hooks/useGridFocus.ts +21 -10
  582. package/src/hooks/useListFocus.doc.mjs +3 -3
  583. package/src/hooks/useListFocus.test.tsx +67 -1
  584. package/src/hooks/useListFocus.ts +21 -5
  585. package/src/hooks/useOverflow.test.ts +96 -4
  586. package/src/hooks/useOverflow.ts +74 -33
  587. package/src/i18n/InternationalizationContext.ts +4 -0
  588. package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
  589. package/src/i18n/InternationalizationProvider.tsx +12 -2
  590. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  591. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  592. package/src/i18n/getLocaleDirection.ts +29 -0
  593. package/src/i18n/index.ts +6 -0
  594. package/src/i18n/resolve.ts +9 -21
  595. package/src/i18n/useDirection.ts +29 -0
  596. package/src/reset.css +0 -26
  597. package/src/reset.test.ts +60 -0
  598. package/src/theme/Theme.tsx +11 -14
  599. package/src/theme/derivedVarRegistry.test.ts +1 -0
  600. package/src/theme/derivedVarRegistry.ts +6 -0
  601. package/src/theme/generateThemeRules.test.ts +107 -0
  602. package/src/theme/generateThemeRules.ts +56 -0
  603. package/src/theme/hct.ts +1 -1
  604. package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
  605. package/src/utils/devWarning.test.ts +56 -0
  606. package/src/utils/devWarning.ts +102 -0
  607. package/src/utils/index.ts +6 -0
  608. package/src/utils/plainDate.test.ts +22 -0
  609. package/src/utils/plainDate.ts +61 -0
  610. package/src/utils/types.ts +14 -0
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import * as stylex from '@stylexjs/stylex';
4
+
5
+ /**
6
+ * Scoped marker for Thumbnail ancestor selectors. Applied to the image
7
+ * container so the remove button's hover/focus reveal (`showRemoveOn="hover"`)
8
+ * responds only to this thumbnail — not to hover/focus state from an outer
9
+ * container the thumbnail happens to sit inside.
10
+ */
11
+ export const thumbnailScope: ReturnType<typeof stylex.defineMarker> =
12
+ stylex.defineMarker();
@@ -229,6 +229,13 @@ export const docs = {
229
229
  description:
230
230
  'Status indicator that colors the border and displays an icon. When a message is provided it is rendered below the input.',
231
231
  },
232
+ {
233
+ name: 'statusVariant',
234
+ type: "'attached' | 'detached'",
235
+ description:
236
+ 'How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing.',
237
+ default: "'attached'",
238
+ },
232
239
  {
233
240
  name: 'labelTooltip',
234
241
  type: 'string',
@@ -372,6 +379,13 @@ export const docsZh = {
372
379
  description:
373
380
  '为边框着色并显示图标的状态指示器。当提供消息时,消息渲染在输入框下方。',
374
381
  },
382
+ {
383
+ name: 'statusVariant',
384
+ type: "'attached' | 'detached'",
385
+ description:
386
+ '状态消息相对于输入框的放置方式。attached 直接叠加在输入框下方(带边框处理);detached 作为独立元素浮于下方并留有间距。',
387
+ default: "'attached'",
388
+ },
375
389
  {
376
390
  name: 'labelTooltip',
377
391
  type: 'string',
@@ -545,6 +559,7 @@ export const docsDense = {
545
559
  placeholder: 'Placeholder when empty. Focused+empty shows format hint.',
546
560
  size: 'Input element height.',
547
561
  status: 'Colored border+icon. Message rendered below input.',
562
+ statusVariant: 'How status message is placed: attached overlaps below input; detached floats below w/ spacing.',
548
563
  labelTooltip: 'Tooltip as info icon at label row end.',
549
564
  xstyle:
550
565
  'StyleX styles for layout customization. Must be stylex.create() value, not inline style.',
@@ -9,12 +9,24 @@
9
9
  * SYNC: When TimeInput.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi, beforeEach} from 'vitest';
12
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
13
  import {render, screen, fireEvent, waitFor} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {TimeInput} from './TimeInput';
16
16
  import {InputGroup, InputGroupText} from '../InputGroup';
17
17
  import type {ISOTimeString} from '../utils';
18
+ import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
19
+
20
+ function politeRegion(): HTMLElement | null {
21
+ return document.querySelector('[data-astryx-live-region="polite"]');
22
+ }
23
+ function assertiveRegion(): HTMLElement | null {
24
+ return document.querySelector('[data-astryx-live-region="assertive"]');
25
+ }
26
+
27
+ afterEach(() => {
28
+ __resetLiveRegionsForTest();
29
+ });
18
30
 
19
31
  describe('TimeInput', () => {
20
32
  it('renders with label', () => {
@@ -352,6 +364,69 @@ describe('TimeInput', () => {
352
364
  // duplicated.
353
365
  expect(container.querySelectorAll('svg')).toHaveLength(1);
354
366
  });
367
+
368
+ // The grouped status node exists only for aria-describedby; announcing
369
+ // happens through the persistent useAnnounce regions because a live
370
+ // region mounted together with its content is not reliably announced.
371
+ it('keeps the grouped status node role-free while announcing via the persistent region', async () => {
372
+ render(
373
+ <InputGroup label="Schedule">
374
+ <InputGroupText>Starts</InputGroupText>
375
+ <TimeInput
376
+ label="Start time"
377
+ isLabelHidden
378
+ value={'09:00' as ISOTimeString}
379
+ onChange={() => {}}
380
+ status={{type: 'error', message: 'Start time is required'}}
381
+ />
382
+ </InputGroup>,
383
+ );
384
+
385
+ const input = screen.getByRole('textbox', {
386
+ name: 'Schedule Start time',
387
+ });
388
+ const describedByIDs =
389
+ input.getAttribute('aria-describedby')?.split(' ') ?? [];
390
+ const statusNode = describedByIDs
391
+ .map(id => document.getElementById(id))
392
+ .find(el => el?.textContent === 'Start time is required');
393
+ expect(statusNode).toBeTruthy();
394
+ expect(statusNode).not.toHaveAttribute('role');
395
+ expect(statusNode).not.toHaveAttribute('aria-live');
396
+
397
+ await waitFor(() => {
398
+ expect(assertiveRegion()).toHaveTextContent('Start time is required');
399
+ });
400
+ });
401
+
402
+ // Regression: a grouped status message appearing after mount (the common
403
+ // validation flow) must land in the persistent announce region.
404
+ it('announces a grouped status message that appears after mount', async () => {
405
+ const grouped = (status?: {
406
+ type: 'error' | 'warning';
407
+ message: string;
408
+ }) => (
409
+ <InputGroup label="Schedule">
410
+ <InputGroupText>Starts</InputGroupText>
411
+ <TimeInput
412
+ label="Start time"
413
+ isLabelHidden
414
+ value={'09:00' as ISOTimeString}
415
+ onChange={() => {}}
416
+ status={status}
417
+ />
418
+ </InputGroup>
419
+ );
420
+ const {rerender} = render(grouped());
421
+ expect(politeRegion()).toBeNull();
422
+
423
+ rerender(grouped({type: 'warning', message: 'Schedule is unusual'}));
424
+ await waitFor(() => {
425
+ expect(politeRegion()).toHaveTextContent('Schedule is unusual');
426
+ });
427
+ // Non-error statuses stay on the polite channel.
428
+ expect(assertiveRegion()).toHaveTextContent('');
429
+ });
355
430
  });
356
431
 
357
432
  describe('disabledMessage', () => {
@@ -496,3 +571,26 @@ describe('TimeInput', () => {
496
571
  });
497
572
  });
498
573
  });
574
+
575
+
576
+ describe('TimeInput statusVariant forwarding', () => {
577
+ it('defaults to attached (status renders with data-variant="attached")', () => {
578
+ const {container} = render(
579
+ <TimeInput label="Start" value={undefined} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
580
+ );
581
+ expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
582
+ 'data-variant',
583
+ 'attached',
584
+ );
585
+ });
586
+
587
+ it('forwards statusVariant="detached" to the underlying Field status', () => {
588
+ const {container} = render(
589
+ <TimeInput label="Start" value={undefined} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
590
+ );
591
+ expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
592
+ 'data-variant',
593
+ 'detached',
594
+ );
595
+ });
596
+ });
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file TimeInput.tsx
7
- * @input Uses React, useId, useState, useCallback, useRef, Field, Icon, InputGroupContext
7
+ * @input Uses React, useId, useState, useCallback, useRef, Field, Icon, InputGroupContext, useAnnounce
8
8
  * @output Exports TimeInput component, TimeInputProps
9
9
  * @position Core implementation; consumed by index.ts, tested by TimeInput.test.tsx
10
10
  *
@@ -20,6 +20,7 @@ import {
20
20
  useId,
21
21
  useState,
22
22
  useCallback,
23
+ useEffect,
23
24
  useRef,
24
25
  useMemo,
25
26
  useOptimistic,
@@ -45,6 +46,7 @@ import {
45
46
  inputStatusBorderStyles,
46
47
  inputStatusHoverShadowStyles,
47
48
  inputStatusFocusWithinStyles,
49
+ type FieldStatusVariant,
48
50
  } from '../Field';
49
51
  import {Icon} from '../Icon';
50
52
  import {Spinner} from '../Spinner';
@@ -64,6 +66,7 @@ import {
64
66
  import type {BaseProps} from '../BaseProps';
65
67
  import type {SizeValue} from '../utils/types';
66
68
  import {useSize} from '../SizeContext/SizeContext';
69
+ import {useAnnounce} from '../hooks/useAnnounce';
67
70
  import {useInputContainer} from '../hooks/useInputContainer';
68
71
  import {useInputGroup} from '../InputGroup/InputGroupContext';
69
72
  import {groupStyles} from '../InputGroup/groupStyles';
@@ -296,6 +299,13 @@ export interface TimeInputProps extends Omit<
296
299
  * If message is provided, displays below the input.
297
300
  */
298
301
  status?: InputStatus;
302
+ /**
303
+ * How the status message is placed relative to the input.
304
+ * - 'attached': message overlaps directly below the input (bordered treatment)
305
+ * - 'detached': message floats below as a separate element with spacing
306
+ * @default 'attached'
307
+ */
308
+ statusVariant?: FieldStatusVariant;
299
309
 
300
310
  /**
301
311
  * Width of the field. Numbers are treated as pixels, strings are used as-is
@@ -345,6 +355,7 @@ export function TimeInput({
345
355
  placeholder: placeholderFromProps,
346
356
  size: sizeProp,
347
357
  status,
358
+ statusVariant = 'attached',
348
359
  labelTooltip,
349
360
  width,
350
361
  xstyle,
@@ -369,6 +380,21 @@ export function TimeInput({
369
380
  const [optimisticValue, setOptimisticValue] = useOptimistic(value);
370
381
  const isBusy = isLoading || optimisticValue !== value;
371
382
 
383
+ // In grouped mode the status message renders as a visually-hidden node that
384
+ // exists only for aria-describedby. Announce it through the persistent
385
+ // useAnnounce live regions instead of role/aria-live on that node — a live
386
+ // region mounted together with its content is not reliably announced.
387
+ // Ungrouped mode delegates to Field -> FieldStatus, which announces itself.
388
+ const announce = useAnnounce();
389
+ useEffect(() => {
390
+ if (inputGroup && status?.message) {
391
+ announce(
392
+ status.message,
393
+ status.type === 'error' ? 'assertive' : 'polite',
394
+ );
395
+ }
396
+ }, [announce, inputGroup, status?.message, status?.type]);
397
+
372
398
  // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
373
399
  // tooltip listeners attach to the input container (which already exists) and
374
400
  // the input stays perceivable via aria-disabled instead of the disabled
@@ -611,11 +637,7 @@ export function TimeInput({
611
637
  </VisuallyHidden>
612
638
  )}
613
639
  {inputGroup && status?.message && (
614
- <VisuallyHidden
615
- as="div"
616
- id={statusMessageID}
617
- role={status.type === 'error' ? 'alert' : 'status'}
618
- aria-live={status.type === 'error' ? 'assertive' : 'polite'}>
640
+ <VisuallyHidden as="div" id={statusMessageID}>
619
641
  {status.message}
620
642
  </VisuallyHidden>
621
643
  )}
@@ -707,6 +729,7 @@ export function TimeInput({
707
729
  }
708
730
  : undefined
709
731
  }
732
+ statusVariant={statusVariant}
710
733
  labelTooltip={labelTooltip}
711
734
  width={width}>
712
735
  {inputWrapper}
@@ -26,9 +26,9 @@ export const docs = {
26
26
  },
27
27
  {
28
28
  name: 'format',
29
- type: "'relative' | 'auto' | 'date' | 'date_time' | 'time' | 'system_date' | 'system_date_time' | 'system_time'",
29
+ type: "'relative' | 'auto' | 'date' | 'date_long' | 'date_weekday' | 'date_time' | 'time' | 'system_date' | 'system_date_time' | 'system_time'",
30
30
  description:
31
- "Display format. 'relative' shows '2 hours ago', 'date' shows 'Mar 21, 2025', 'date_time' shows 'Mar 21, 2025, 2:51 PM', 'time' shows '2:51 PM', 'system_*' variants use ISO-style formatting, 'auto' switches from relative to date_time based on recency.",
31
+ "Display format. 'relative' shows '2 hours ago', 'date' shows 'Mar 21, 2025', 'date_long' shows 'March 21, 2025', 'date_weekday' shows 'Wed, Mar 21, 2025', 'date_time' shows 'Mar 21, 2025, 2:51 PM', 'time' shows '2:51 PM', 'system_*' variants use ISO-style formatting, 'auto' switches from relative to date_time based on recency.",
32
32
  default: "'auto'",
33
33
  },
34
34
  {
@@ -110,7 +110,7 @@ export const docs = {
110
110
  export const docsZh = {
111
111
  propDescriptions: {
112
112
  value: '\u8981\u663e\u793a\u7684\u65e5\u671f/\u65f6\u95f4\u3002\u63a5\u53d7 Unix \u65f6\u95f4\u6233\uff08\u79d2\uff09\u6216 ISO 8601 \u5b57\u7b26\u4e32\u3002',
113
- format: "\u663e\u793a\u683c\u5f0f\u3002'relative' \u663e\u793a '2\u5c0f\u65f6\u524d'\uff0c'date' \u663e\u793a\u65e5\u671f\uff0c'auto' \u6839\u636e\u65f6\u95f4\u8fdc\u8fd1\u81ea\u52a8\u5207\u6362\u3002",
113
+ format: "\u663e\u793a\u683c\u5f0f\u3002'relative' \u663e\u793a '2\u5c0f\u65f6\u524d'\uff0c'date' \u663e\u793a\u65e5\u671f\uff0c'date_long' \u663e\u793a\u957f\u6708\u4efd\u65e5\u671f\uff0c'date_weekday' \u663e\u793a\u661f\u671f+\u65e5\u671f\uff0c'auto' \u6839\u636e\u65f6\u95f4\u8fdc\u8fd1\u81ea\u52a8\u5207\u6362\u3002",
114
114
  autoThreshold: "auto \u683c\u5f0f\u4ece\u76f8\u5bf9\u65f6\u95f4\u5207\u6362\u5230 date_time \u7684\u9608\u503c\u79d2\u6570\u3002",
115
115
  hasTooltip: '\u60ac\u505c\u65f6\u662f\u5426\u663e\u793a\u5305\u542b\u5b8c\u6574\u65e5\u671f/\u65f6\u95f4\u7684\u5de5\u5177\u63d0\u793a\uff08\u76f8\u5bf9\u65f6\u95f4\u6a21\u5f0f\uff09\u3002',
116
116
  isTimezoneShown: '\u662f\u5426\u9644\u52a0\u65f6\u533a\u7f29\u5199\u3002',
@@ -157,7 +157,7 @@ export const docsDense = {
157
157
  },
158
158
  propDescriptions: {
159
159
  value: 'date/time as unix seconds or ISO string',
160
- format: "display mode: 'relative', 'auto', 'date', 'date_time', 'time', 'system_date', 'system_date_time', 'system_time'",
160
+ format: "display mode: 'relative', 'auto', 'date', 'date_long', 'date_weekday', 'date_time', 'time', 'system_date', 'system_date_time', 'system_time'",
161
161
  autoThreshold: 'seconds threshold for auto relative\u2192date_time switch',
162
162
  hasTooltip: 'show full time tooltip on hover (relative mode)',
163
163
  isTimezoneShown: 'append timezone abbreviation',
@@ -99,6 +99,38 @@ describe('Timestamp', () => {
99
99
  expect(el.textContent).not.toContain(':');
100
100
  });
101
101
 
102
+ it('renders date_weekday format with a weekday prefix', () => {
103
+ render(
104
+ <Timestamp
105
+ value="2026-02-19T17:00:00Z"
106
+ format="date_weekday"
107
+ data-testid="ts"
108
+ />,
109
+ );
110
+ const el = screen.getByTestId('ts');
111
+ // Includes the year and a leading weekday abbreviation, no time portion.
112
+ expect(el.textContent).toContain('2026');
113
+ expect(el.textContent).not.toContain(':');
114
+ // en-US short weekday for 2026-02-19 is "Thu"; assert a weekday word is
115
+ // present without over-fitting the exact locale punctuation.
116
+ expect(el.textContent).toMatch(/Mon|Tue|Wed|Thu|Fri|Sat|Sun/);
117
+ });
118
+
119
+ it('renders date_long format with a full month name', () => {
120
+ render(
121
+ <Timestamp
122
+ value="2026-02-19T17:00:00Z"
123
+ format="date_long"
124
+ data-testid="ts"
125
+ />,
126
+ );
127
+ const el = screen.getByTestId('ts');
128
+ // Long-month shape: full month name, year, no time portion.
129
+ expect(el.textContent).toContain('February');
130
+ expect(el.textContent).toContain('2026');
131
+ expect(el.textContent).not.toContain(':');
132
+ });
133
+
102
134
  it('renders date_time format', () => {
103
135
  render(
104
136
  <Timestamp
@@ -21,9 +21,11 @@ import * as stylex from '@stylexjs/stylex';
21
21
  import {Text} from '../Text';
22
22
  import type {TextType, TextSize, TextColor, TextWeight} from '../theme/types';
23
23
  import {mergeProps, mergeRefs} from '../utils';
24
+ import {useDevWarning} from '../hooks/useDevWarning';
24
25
  import type {BaseProps} from '../BaseProps';
25
26
  import {themeProps} from '../utils/themeProps';
26
27
  import {colorVars} from '../theme/tokens.stylex';
28
+ import {SHARED_DATE_FORMAT_OPTIONS} from '../utils/plainDate';
27
29
 
28
30
  const LazyXDSTooltip = lazy(async () =>
29
31
  import('../Tooltip/Tooltip').then(mod => ({default: mod.Tooltip})),
@@ -37,6 +39,8 @@ export type TimestampFormat =
37
39
  | 'relative'
38
40
  | 'auto'
39
41
  | 'date'
42
+ | 'date_long'
43
+ | 'date_weekday'
40
44
  | 'date_time'
41
45
  | 'time'
42
46
  | 'system_date'
@@ -53,6 +57,8 @@ export interface TimestampProps extends BaseProps<HTMLTimeElement> {
53
57
  * - `'relative'`: "2 hours ago", "yesterday", "now"
54
58
  * - `'auto'`: Relative for recent times, `date_time` for older
55
59
  * - `'date'`: "Mar 21, 2025"
60
+ * - `'date_long'`: "March 21, 2025"
61
+ * - `'date_weekday'`: "Wed, Mar 21, 2025"
56
62
  * - `'date_time'`: "Mar 21, 2025, 2:51 PM"
57
63
  * - `'time'`: "2:51 PM"
58
64
  * - `'system_date'`: "2025-03-21"
@@ -249,11 +255,22 @@ function formatTimestamp(
249
255
  ): string {
250
256
  switch (format) {
251
257
  case 'date':
252
- return new Intl.DateTimeFormat(undefined, {
253
- year: 'numeric',
254
- month: 'short',
255
- day: 'numeric',
256
- }).format(date);
258
+ return new Intl.DateTimeFormat(
259
+ undefined,
260
+ SHARED_DATE_FORMAT_OPTIONS.date,
261
+ ).format(date);
262
+
263
+ case 'date_long':
264
+ return new Intl.DateTimeFormat(
265
+ undefined,
266
+ SHARED_DATE_FORMAT_OPTIONS.date_long,
267
+ ).format(date);
268
+
269
+ case 'date_weekday':
270
+ return new Intl.DateTimeFormat(
271
+ undefined,
272
+ SHARED_DATE_FORMAT_OPTIONS.date_weekday,
273
+ ).format(date);
257
274
 
258
275
  case 'date_time':
259
276
  return new Intl.DateTimeFormat(undefined, {
@@ -415,11 +432,14 @@ export function Timestamp({
415
432
  return () => clearInterval(timer);
416
433
  }, [isLive, isValidDate, effectiveFormat, diffSeconds]);
417
434
 
435
+ useDevWarning(
436
+ 'Timestamp',
437
+ `could not parse value ${JSON.stringify(value)} as a date. Rendering nothing.`,
438
+ !isValidDate,
439
+ );
440
+
418
441
  // Placed after all hooks so the hook order stays stable across renders.
419
442
  if (!isValidDate) {
420
- console.warn(
421
- `Timestamp: could not parse value ${JSON.stringify(value)} as a date. Rendering nothing.`,
422
- );
423
443
  return null;
424
444
  }
425
445
 
@@ -7,6 +7,7 @@ import {createRoot} from 'react-dom/client';
7
7
  import {dataAttr} from '../naming';
8
8
  import {ToastContext, type ToastContextValue} from './ToastContext';
9
9
  import {ToastViewport} from './ToastViewport';
10
+ import {warnOnce} from '../utils/devWarning';
10
11
  import type {
11
12
  ToastOptions,
12
13
  ToastDismissFn,
@@ -17,7 +18,6 @@ import type {
17
18
  // Fallback singleton
18
19
  let fallbackContext: ToastContextValue | null = null;
19
20
  let fallbackRoot: ReturnType<typeof createRoot> | null = null;
20
- let fallbackWarned = false;
21
21
 
22
22
  const ROOT_THEME_ATTRS = ['data-theme', dataAttr('theme')] as const;
23
23
 
@@ -70,13 +70,12 @@ function getFallbackContext(): ToastContextValue {
70
70
  );
71
71
  }
72
72
 
73
- if (!fallbackWarned) {
74
- fallbackWarned = true;
75
- console.warn(
76
- 'useToast: No LayerProvider found. Using fallback viewport. ' +
77
- 'Wrap your app with <LayerProvider> or <AppShell> for full control.',
78
- );
79
- }
73
+ warnOnce(
74
+ 'toast-fallback-viewport',
75
+ 'useToast',
76
+ 'No LayerProvider found. Using fallback viewport. ' +
77
+ 'Wrap your app with <LayerProvider> or <AppShell> for full control.',
78
+ );
80
79
 
81
80
  const container = document.createElement('div');
82
81
  container.setAttribute('data-astryx-toast-fallback', '');
@@ -41,7 +41,7 @@ interface ToggleButtonGroupContextValue {
41
41
  isDisabled?: boolean;
42
42
  }
43
43
 
44
- export const ToggleButtonGroupContext =
44
+ const ToggleButtonGroupContext =
45
45
  createContext<ToggleButtonGroupContextValue | null>(null);
46
46
  ToggleButtonGroupContext.displayName = 'ToggleButtonGroupContext';
47
47
 
@@ -31,7 +31,7 @@ export const docs = {
31
31
  name: 'onChange',
32
32
  type: '(items: T[], change: TokenizerChange<T>) => void',
33
33
  description:
34
- "Called when selection changes. The change argument includes the affected item and type ('add' | 'create' | 'remove' | 'reorder').",
34
+ "Called when selection changes. The change argument includes the affected item and type ('add' | 'create' | 'remove' | 'reorder'). Additions and removals (including Backspace on an empty input) are announced to screen readers via a polite live region.",
35
35
  required: true,
36
36
  },
37
37
  {
@@ -88,6 +88,13 @@ export const docs = {
88
88
  description:
89
89
  'Validation status object with type and message for error/warning/success states.',
90
90
  },
91
+ {
92
+ name: 'statusVariant',
93
+ type: "'attached' | 'detached'",
94
+ description:
95
+ 'How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing.',
96
+ default: "'attached'",
97
+ },
91
98
  {
92
99
  name: 'isLabelHidden',
93
100
  type: 'boolean',
@@ -165,6 +172,13 @@ export const docs = {
165
172
  type: '(query: string) => void',
166
173
  description: 'Callback fired when the search query text changes.',
167
174
  },
175
+ {
176
+ name: 'startIcon',
177
+ type: 'ReactNode | IconType',
178
+ description:
179
+ 'Icon to display at the start of the input, before any tokens. Accepts a semantic icon name, an SVG icon component, or a ReactNode directly.',
180
+ slotElements: [{__element: 'Icon', props: {icon: 'search', size: 'sm'}}],
181
+ },
168
182
  {
169
183
  name: 'endContent',
170
184
  type: 'ReactNode',
@@ -300,6 +314,13 @@ export const docsZh = {
300
314
  description:
301
315
  '\u9a8c\u8bc1\u72b6\u6001\u5bf9\u8c61\uff0c\u5305\u542b\u7c7b\u578b\u548c\u6d88\u606f\uff0c\u7528\u4e8e\u9519\u8bef/\u8b66\u544a/\u6210\u529f\u72b6\u6001\u3002',
302
316
  },
317
+ {
318
+ name: 'statusVariant',
319
+ type: "'attached' | 'detached'",
320
+ description:
321
+ '状态消息相对于输入框的放置方式。attached 直接叠加在输入框下方(带边框处理);detached 作为独立元素浮于下方并留有间距。',
322
+ default: "'attached'",
323
+ },
303
324
  {
304
325
  name: 'isLabelHidden',
305
326
  type: 'boolean',
@@ -370,6 +391,12 @@ export const docsZh = {
370
391
  type: '(query: string) => void',
371
392
  description: '\u641c\u7d22\u67e5\u8be2\u6587\u672c\u53d8\u66f4\u65f6\u89e6\u53d1\u7684\u56de\u8c03\u3002',
372
393
  },
394
+ {
395
+ name: 'startIcon',
396
+ type: 'ReactNode | IconType',
397
+ description:
398
+ '\u5728\u8f93\u5165\u6846\u5f00\u5934\uff08token \u4e4b\u524d\uff09\u663e\u793a\u7684\u56fe\u6807\u3002\u63a5\u53d7\u8bed\u4e49\u56fe\u6807\u540d\u79f0\u3001SVG \u56fe\u6807\u7ec4\u4ef6\u6216\u76f4\u63a5\u4f20\u5165 ReactNode\u3002',
399
+ },
373
400
  {
374
401
  name: 'endContent',
375
402
  type: 'ReactNode',
@@ -448,6 +475,7 @@ export const docsDense = {
448
475
  isDisabled: 'Disables input+all token interactions.',
449
476
  htmlName: 'HTML name attr; one hidden input per selected item id.',
450
477
  status: 'Validation status w/ type+message for error/warning/success.',
478
+ statusVariant: 'How status message is placed: attached overlaps below input; detached floats below w/ spacing.',
451
479
  isLabelHidden: 'Visually hides label; keeps a11y.',
452
480
  description: 'Helper text below label.',
453
481
  isRequired: 'Marks field required.',
@@ -460,6 +488,7 @@ export const docsDense = {
460
488
  size: 'Input+token size.',
461
489
  debounceMs: 'Search debounce delay ms. 0 for sync sources.',
462
490
  onChangeQuery: 'Fired on search query text change.',
491
+ startIcon: 'Icon at input start, before tokens. Icon name, SVG component, or ReactNode.',
463
492
  endContent: 'Content at input row end. For buttons, counts, controls.',
464
493
  handleRef: 'Imperative handle for focus() and blur() control.',
465
494
  xstyle: 'StyleX layout styles (margins, positioning). Must be stylex.create() value.',