@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3

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 (730) hide show
  1. package/CHANGELOG.md +161 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +3 -2
  7. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  8. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  9. package/dist/AspectRatio/AspectRatio.js +23 -4
  10. package/dist/Avatar/Avatar.d.ts +25 -1
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +58 -19
  13. package/dist/Avatar/index.d.ts +2 -2
  14. package/dist/Avatar/index.d.ts.map +1 -1
  15. package/dist/Avatar/index.js +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  17. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  19. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  20. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  21. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  22. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  23. package/dist/Banner/Banner.d.ts +49 -15
  24. package/dist/Banner/Banner.d.ts.map +1 -1
  25. package/dist/Banner/Banner.js +62 -20
  26. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  27. package/dist/BottomSheet/BottomSheet.js +17 -4
  28. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  29. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  30. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  31. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  32. package/dist/Button/Button.d.ts.map +1 -1
  33. package/dist/Button/Button.js +11 -6
  34. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  35. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  36. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  37. package/dist/Calendar/Calendar.d.ts +7 -3
  38. package/dist/Calendar/Calendar.d.ts.map +1 -1
  39. package/dist/Calendar/Calendar.js +21 -23
  40. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  41. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  42. package/dist/Calendar/getInitialFocusDate.js +62 -0
  43. package/dist/Calendar/styles.d.ts +5 -14
  44. package/dist/Calendar/styles.d.ts.map +1 -1
  45. package/dist/Calendar/styles.js +15 -15
  46. package/dist/Card/Card.d.ts +12 -12
  47. package/dist/Card/Card.d.ts.map +1 -1
  48. package/dist/Card/Card.js +17 -9
  49. package/dist/Card/index.d.ts +35 -1
  50. package/dist/Card/index.d.ts.map +1 -1
  51. package/dist/Card/index.js +21 -1
  52. package/dist/Carousel/Carousel.d.ts.map +1 -1
  53. package/dist/Carousel/Carousel.js +3 -3
  54. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  55. package/dist/Chat/ChatComposerInput.js +2 -3
  56. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  57. package/dist/Chat/ChatLayout.js +3 -3
  58. package/dist/Chat/ChatMessageList.d.ts +22 -3
  59. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  60. package/dist/Chat/ChatMessageList.js +6 -3
  61. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  62. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  63. package/dist/Chat/ChatTokenizedText.js +11 -6
  64. package/dist/Chat/useChatComposerTokens.js +1 -1
  65. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  66. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  67. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  68. package/dist/ClickableCard/ClickableCard.js +3 -3
  69. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  70. package/dist/CodeBlock/CodeBlock.js +15 -4
  71. package/dist/CodeBlock/highlightRanges.js +1 -1
  72. package/dist/CodeBlock/highlightStyles.js +13 -13
  73. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  74. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  75. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  76. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  77. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  78. package/dist/ComplexSelector/ComplexSelector.js +1 -3
  79. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  80. package/dist/ContextMenu/ContextMenu.js +4 -3
  81. package/dist/DateInput/DateInput.d.ts +43 -0
  82. package/dist/DateInput/DateInput.d.ts.map +1 -1
  83. package/dist/DateInput/DateInput.js +22 -2
  84. package/dist/DateInput/NativeDateField.d.ts +10 -0
  85. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  86. package/dist/DateInput/NativeDateField.js +494 -0
  87. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  88. package/dist/DateInput/TouchDateField.js +82 -23
  89. package/dist/DateInput/index.d.ts +1 -1
  90. package/dist/DateInput/index.d.ts.map +1 -1
  91. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  92. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  93. package/dist/DateInput/nativeDateSegments.js +111 -0
  94. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  95. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  96. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  97. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  98. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  99. package/dist/DateTimeInput/index.d.ts +1 -1
  100. package/dist/DateTimeInput/index.d.ts.map +1 -1
  101. package/dist/Dialog/Dialog.d.ts +21 -1
  102. package/dist/Dialog/Dialog.d.ts.map +1 -1
  103. package/dist/Dialog/Dialog.js +110 -58
  104. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  105. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  106. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  107. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  108. package/dist/Field/FieldLabel.d.ts.map +1 -1
  109. package/dist/Field/FieldLabel.js +9 -1
  110. package/dist/Field/InputClearButton.d.ts +9 -3
  111. package/dist/Field/InputClearButton.d.ts.map +1 -1
  112. package/dist/Field/InputClearButton.js +14 -3
  113. package/dist/FileInput/FileInput.d.ts.map +1 -1
  114. package/dist/FileInput/FileInput.js +3 -2
  115. package/dist/Heading/Heading.d.ts.map +1 -1
  116. package/dist/Heading/Heading.js +6 -3
  117. package/dist/HoverCard/HoverCard.d.ts +6 -0
  118. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  119. package/dist/HoverCard/HoverCard.js +104 -3
  120. package/dist/HoverCard/useHoverCard.d.ts +19 -2
  121. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  122. package/dist/HoverCard/useHoverCard.js +74 -26
  123. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  124. package/dist/Indicator/CheckboxIndicator.js +6 -2
  125. package/dist/Item/Item.d.ts.map +1 -1
  126. package/dist/Item/Item.js +4 -2
  127. package/dist/Kbd/Kbd.d.ts.map +1 -1
  128. package/dist/Kbd/Kbd.js +2 -19
  129. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  130. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  131. package/dist/Layer/LayerDepthContext.js +66 -0
  132. package/dist/Layer/gestureCounter.d.ts +8 -0
  133. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  134. package/dist/Layer/gestureCounter.js +53 -0
  135. package/dist/Layer/index.d.ts +3 -0
  136. package/dist/Layer/index.d.ts.map +1 -1
  137. package/dist/Layer/index.js +4 -0
  138. package/dist/Layer/layerStack.d.ts +98 -0
  139. package/dist/Layer/layerStack.d.ts.map +1 -0
  140. package/dist/Layer/layerStack.js +306 -0
  141. package/dist/Layer/useLayer.d.ts +23 -13
  142. package/dist/Layer/useLayer.d.ts.map +1 -1
  143. package/dist/Layer/useLayer.js +128 -8
  144. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  145. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  146. package/dist/Layer/useLayerDismissal.js +91 -0
  147. package/dist/Lightbox/Lightbox.d.ts +1 -0
  148. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  149. package/dist/Lightbox/Lightbox.js +103 -81
  150. package/dist/List/List.d.ts +1 -1
  151. package/dist/List/List.d.ts.map +1 -1
  152. package/dist/List/List.js +15 -4
  153. package/dist/Markdown/Markdown.d.ts +1 -1
  154. package/dist/Markdown/Markdown.d.ts.map +1 -1
  155. package/dist/Markdown/Markdown.js +20 -7
  156. package/dist/Markdown/index.d.ts +1 -1
  157. package/dist/Markdown/index.d.ts.map +1 -1
  158. package/dist/Markdown/parser.d.ts +38 -1
  159. package/dist/Markdown/parser.d.ts.map +1 -1
  160. package/dist/Markdown/parser.js +182 -32
  161. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  162. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  163. package/dist/MetadataList/MetadataListItem.js +4 -1
  164. package/dist/MobileNav/MobileNav.d.ts +6 -1
  165. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  166. package/dist/MobileNav/MobileNav.js +61 -36
  167. package/dist/MultiSelector/MultiSelector.d.ts +32 -1
  168. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  169. package/dist/MultiSelector/MultiSelector.js +73 -15
  170. package/dist/MultiSelector/hooks.d.ts +7 -1
  171. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  172. package/dist/MultiSelector/hooks.js +3 -2
  173. package/dist/MultiSelector/index.d.ts +1 -1
  174. package/dist/MultiSelector/index.d.ts.map +1 -1
  175. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  176. package/dist/NavIcon/NavIcon.js +5 -1
  177. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  178. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  179. package/dist/NavMenu/NavHeadingMenu.js +9 -5
  180. package/dist/NumberInput/NumberInput.d.ts +6 -1
  181. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  182. package/dist/NumberInput/NumberInput.js +54 -104
  183. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  184. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  185. package/dist/NumberInput/numberInputCommit.js +71 -0
  186. package/dist/NumberInput/numberParser.d.ts +64 -0
  187. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  188. package/dist/NumberInput/numberParser.js +350 -0
  189. package/dist/Outline/Outline.d.ts.map +1 -1
  190. package/dist/Outline/Outline.js +3 -2
  191. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  192. package/dist/OverflowList/OverflowList.js +3 -2
  193. package/dist/Overlay/Overlay.d.ts.map +1 -1
  194. package/dist/Overlay/Overlay.js +3 -2
  195. package/dist/Popover/Popover.d.ts.map +1 -1
  196. package/dist/Popover/Popover.js +1 -9
  197. package/dist/Popover/usePopover.d.ts +7 -41
  198. package/dist/Popover/usePopover.d.ts.map +1 -1
  199. package/dist/Popover/usePopover.js +40 -21
  200. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +19 -6
  203. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  204. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  205. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  206. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  207. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  208. package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
  209. package/dist/PowerSearch/types.d.ts +2 -0
  210. package/dist/PowerSearch/types.d.ts.map +1 -1
  211. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  212. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  213. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  214. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  215. package/dist/ProgressBar/ProgressBar.js +18 -5
  216. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  217. package/dist/Resizable/ResizeHandle.js +3 -2
  218. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  219. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  220. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  221. package/dist/SelectableCard/SelectableCard.js +12 -3
  222. package/dist/Selector/Selector.d.ts +18 -1
  223. package/dist/Selector/Selector.d.ts.map +1 -1
  224. package/dist/Selector/Selector.js +91 -18
  225. package/dist/Selector/hooks.d.ts +7 -1
  226. package/dist/Selector/hooks.d.ts.map +1 -1
  227. package/dist/Selector/hooks.js +3 -2
  228. package/dist/SideNav/SideNav.d.ts.map +1 -1
  229. package/dist/SideNav/SideNav.js +4 -3
  230. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  231. package/dist/SideNav/SideNavHeading.js +8 -7
  232. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  233. package/dist/SideNav/SideNavItem.js +4 -3
  234. package/dist/Slider/Slider.d.ts.map +1 -1
  235. package/dist/Slider/Slider.js +37 -5
  236. package/dist/Spinner/Spinner.d.ts +3 -3
  237. package/dist/Spinner/Spinner.d.ts.map +1 -1
  238. package/dist/Spinner/Spinner.js +130 -78
  239. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  240. package/dist/StatusDot/StatusDot.js +6 -1
  241. package/dist/Stepper/Step.d.ts +140 -0
  242. package/dist/Stepper/Step.d.ts.map +1 -0
  243. package/dist/Stepper/Step.js +1045 -0
  244. package/dist/Stepper/StepStatus.d.ts +24 -0
  245. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  246. package/dist/Stepper/StepStatus.js +1 -0
  247. package/dist/Stepper/Stepper.d.ts +93 -0
  248. package/dist/Stepper/Stepper.d.ts.map +1 -0
  249. package/dist/Stepper/Stepper.js +184 -0
  250. package/dist/Stepper/StepperContext.d.ts +41 -0
  251. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  252. package/dist/Stepper/StepperContext.js +34 -0
  253. package/dist/Stepper/index.d.ts +8 -0
  254. package/dist/Stepper/index.d.ts.map +1 -0
  255. package/dist/Stepper/index.js +7 -0
  256. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  257. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  258. package/dist/Stepper/stepper.stylex.js +20 -0
  259. package/dist/Switch/Switch.d.ts.map +1 -1
  260. package/dist/Switch/Switch.js +8 -3
  261. package/dist/TabList/Tab.d.ts +15 -2
  262. package/dist/TabList/Tab.d.ts.map +1 -1
  263. package/dist/TabList/Tab.js +32 -7
  264. package/dist/TabList/TabList.d.ts +46 -7
  265. package/dist/TabList/TabList.d.ts.map +1 -1
  266. package/dist/TabList/TabList.js +353 -23
  267. package/dist/TabList/TabListContext.d.ts +11 -1
  268. package/dist/TabList/TabListContext.d.ts.map +1 -1
  269. package/dist/TabList/TabListContext.js +11 -2
  270. package/dist/TabList/TabMenu.d.ts.map +1 -1
  271. package/dist/TabList/TabMenu.js +3 -2
  272. package/dist/TabList/index.d.ts +2 -2
  273. package/dist/TabList/index.d.ts.map +1 -1
  274. package/dist/Table/BaseTable.d.ts.map +1 -1
  275. package/dist/Table/BaseTable.js +10 -2
  276. package/dist/Table/Table.d.ts.map +1 -1
  277. package/dist/Table/Table.js +3 -6
  278. package/dist/Table/TableRow.d.ts +16 -5
  279. package/dist/Table/TableRow.d.ts.map +1 -1
  280. package/dist/Table/TableRow.js +16 -5
  281. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  282. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  283. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  284. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  285. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
  286. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  287. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  288. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  289. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  290. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  291. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  292. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  293. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  294. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  295. package/dist/Table/plugins/selection/useTableSelection.js +43 -5
  296. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  297. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  298. package/dist/Table/types.d.ts +22 -4
  299. package/dist/Table/types.d.ts.map +1 -1
  300. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  301. package/dist/Table/useBaseTablePlugins.js +5 -0
  302. package/dist/Text/Text.d.ts.map +1 -1
  303. package/dist/Text/Text.js +6 -3
  304. package/dist/TextArea/TextArea.d.ts.map +1 -1
  305. package/dist/TextArea/TextArea.js +16 -10
  306. package/dist/TextInput/TextInput.d.ts.map +1 -1
  307. package/dist/TextInput/TextInput.js +3 -2
  308. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  309. package/dist/TimeInput/TimeInput.js +3 -2
  310. package/dist/Timestamp/Timestamp.d.ts +1 -1
  311. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  312. package/dist/Timestamp/Timestamp.js +15 -21
  313. package/dist/Toast/Toast.d.ts.map +1 -1
  314. package/dist/Toast/Toast.js +22 -7
  315. package/dist/Toast/ToastViewport.d.ts +1 -0
  316. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  317. package/dist/Toast/ToastViewport.js +71 -18
  318. package/dist/Token/Token.d.ts +1 -1
  319. package/dist/Token/Token.d.ts.map +1 -1
  320. package/dist/Token/Token.js +20 -9
  321. package/dist/Token/TokenLink.d.ts +1 -1
  322. package/dist/Token/TokenLink.d.ts.map +1 -1
  323. package/dist/Token/TokenLink.js +7 -4
  324. package/dist/Tokenizer/Tokenizer.d.ts +14 -1
  325. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  326. package/dist/Tokenizer/Tokenizer.js +33 -21
  327. package/dist/Tooltip/Tooltip.d.ts +5 -0
  328. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  329. package/dist/Tooltip/useTooltip.d.ts +5 -0
  330. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  331. package/dist/Tooltip/useTooltip.js +39 -24
  332. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  333. package/dist/TopNav/TopNavHeading.js +5 -4
  334. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  335. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  336. package/dist/TopNav/TopNavMegaMenu.js +31 -11
  337. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  338. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  339. package/dist/TopNav/TopNavMenu.js +22 -7
  340. package/dist/TreeList/TreeList.d.ts +1 -1
  341. package/dist/TreeList/TreeList.d.ts.map +1 -1
  342. package/dist/TreeList/TreeList.js +7 -2
  343. package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
  344. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  345. package/dist/Typeahead/BaseTypeahead.js +119 -37
  346. package/dist/Typeahead/Typeahead.d.ts +8 -1
  347. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  348. package/dist/Typeahead/Typeahead.js +5 -2
  349. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  350. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  351. package/dist/Typeahead/TypeaheadItem.js +7 -2
  352. package/dist/astryx.css +113 -11
  353. package/dist/hooks/index.d.ts +1 -0
  354. package/dist/hooks/index.d.ts.map +1 -1
  355. package/dist/hooks/index.js +1 -0
  356. package/dist/hooks/useFocusTrap.d.ts +7 -4
  357. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  358. package/dist/hooks/useFocusTrap.js +60 -95
  359. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  360. package/dist/hooks/useHotkeys.js +3 -18
  361. package/dist/hooks/useMergedRefs.d.ts +18 -0
  362. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  363. package/dist/hooks/useMergedRefs.js +25 -0
  364. package/dist/index.d.ts +1 -0
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +1 -0
  367. package/dist/theme/Theme.d.ts.map +1 -1
  368. package/dist/theme/Theme.js +46 -10
  369. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  370. package/dist/theme/derivedVarRegistry.js +24 -4
  371. package/dist/theme/generateThemeRules.d.ts +21 -0
  372. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  373. package/dist/theme/generateThemeRules.js +26 -0
  374. package/dist/theme/syntax/tokens.d.ts +1 -1
  375. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  376. package/dist/theme/syntax/tokens.js +5 -2
  377. package/dist/utils/groupItems.d.ts +5 -1
  378. package/dist/utils/groupItems.d.ts.map +1 -1
  379. package/dist/utils/groupItems.js +9 -9
  380. package/dist/utils/index.d.ts +1 -1
  381. package/dist/utils/index.d.ts.map +1 -1
  382. package/dist/utils/isApplePlatform.d.ts +18 -0
  383. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  384. package/dist/utils/isApplePlatform.js +37 -0
  385. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  386. package/dist/utils/sharedResizeObserver.js +10 -1
  387. package/dist/utils/timeParser.d.ts +1 -1
  388. package/dist/utils/timeParser.d.ts.map +1 -1
  389. package/dist/utils/timeParser.js +26 -12
  390. package/locales/af-ZA.json +6 -6
  391. package/locales/ar-SA.json +6 -6
  392. package/locales/ca-ES.json +5 -5
  393. package/locales/cs-CZ.json +6 -6
  394. package/locales/da-DK.json +6 -6
  395. package/locales/de-DE.json +6 -6
  396. package/locales/el-GR.json +6 -6
  397. package/locales/en.json +163 -11
  398. package/locales/es-ES.json +5 -5
  399. package/locales/fi-FI.json +6 -6
  400. package/locales/fr-FR.json +6 -6
  401. package/locales/he-IL.json +6 -6
  402. package/locales/hu-HU.json +6 -6
  403. package/locales/it-IT.json +6 -6
  404. package/locales/ja-JP.json +6 -6
  405. package/locales/ko-KR.json +6 -6
  406. package/locales/nl-NL.json +6 -6
  407. package/locales/no-NO.json +6 -6
  408. package/locales/pl-PL.json +6 -6
  409. package/locales/pseudo.json +114 -0
  410. package/locales/pt-BR.json +6 -6
  411. package/locales/pt-PT.json +6 -6
  412. package/locales/ro-RO.json +6 -6
  413. package/locales/ru-RU.json +6 -6
  414. package/locales/sr-SP.json +6 -6
  415. package/locales/sv-SE.json +6 -6
  416. package/locales/tr-TR.json +6 -6
  417. package/locales/uk-UA.json +6 -6
  418. package/locales/vi-VN.json +6 -6
  419. package/locales/zh-CN.json +6 -6
  420. package/locales/zh-TW.json +6 -6
  421. package/package.json +8 -3
  422. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  423. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  424. package/src/AlertDialog/AlertDialog.tsx +62 -20
  425. package/src/AppShell/AppShell.tsx +3 -2
  426. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  427. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  428. package/src/AspectRatio/AspectRatio.tsx +40 -1
  429. package/src/Avatar/Avatar.doc.mjs +14 -3
  430. package/src/Avatar/Avatar.test.tsx +97 -0
  431. package/src/Avatar/Avatar.tsx +125 -52
  432. package/src/Avatar/index.ts +2 -2
  433. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  434. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  435. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  436. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  437. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  438. package/src/Banner/Banner.doc.mjs +22 -11
  439. package/src/Banner/Banner.test.tsx +177 -25
  440. package/src/Banner/Banner.tsx +93 -27
  441. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  442. package/src/BottomSheet/BottomSheet.tsx +17 -4
  443. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  444. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  445. package/src/Button/Button.doc.mjs +24 -1
  446. package/src/Button/Button.test.tsx +32 -4
  447. package/src/Button/Button.tsx +12 -5
  448. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  449. package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
  450. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  451. package/src/Calendar/Calendar.doc.mjs +7 -6
  452. package/src/Calendar/Calendar.test.tsx +143 -0
  453. package/src/Calendar/Calendar.tsx +30 -26
  454. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  455. package/src/Calendar/getInitialFocusDate.ts +93 -0
  456. package/src/Calendar/styles.ts +49 -31
  457. package/src/Card/Card.doc.mjs +10 -7
  458. package/src/Card/Card.test.tsx +113 -19
  459. package/src/Card/Card.tsx +67 -89
  460. package/src/Card/index.ts +36 -1
  461. package/src/Carousel/Carousel.tsx +3 -2
  462. package/src/Chat/ChatComposerInput.tsx +5 -1
  463. package/src/Chat/ChatLayout.tsx +3 -2
  464. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  465. package/src/Chat/ChatMessageList.test.tsx +46 -0
  466. package/src/Chat/ChatMessageList.tsx +28 -4
  467. package/src/Chat/ChatTokenizedText.tsx +17 -10
  468. package/src/Chat/useChatComposerTokens.ts +1 -1
  469. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  470. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  471. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  472. package/src/ClickableCard/ClickableCard.tsx +3 -2
  473. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  474. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  475. package/src/CodeBlock/CodeBlock.tsx +20 -4
  476. package/src/CodeBlock/highlightRanges.ts +1 -1
  477. package/src/CodeBlock/highlightStyles.ts +13 -13
  478. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  479. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  480. package/src/ComplexSelector/ComplexSelector.test.tsx +32 -0
  481. package/src/ComplexSelector/ComplexSelector.tsx +1 -3
  482. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  483. package/src/ContextMenu/ContextMenu.tsx +4 -3
  484. package/src/DateInput/DateInput.doc.mjs +16 -0
  485. package/src/DateInput/DateInput.tsx +55 -2
  486. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  487. package/src/DateInput/NativeDateField.test.tsx +635 -0
  488. package/src/DateInput/NativeDateField.tsx +641 -0
  489. package/src/DateInput/TouchDateField.tsx +108 -24
  490. package/src/DateInput/index.ts +1 -0
  491. package/src/DateInput/nativeDateSegments.ts +127 -0
  492. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  493. package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
  494. package/src/DateRangeInput/DateRangeInput.tsx +4 -2
  495. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  496. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  497. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  498. package/src/DateTimeInput/index.ts +1 -0
  499. package/src/Dialog/Dialog.doc.mjs +8 -3
  500. package/src/Dialog/Dialog.test.tsx +429 -2
  501. package/src/Dialog/Dialog.tsx +133 -58
  502. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  503. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  504. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  505. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  506. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  507. package/src/Field/Field.doc.mjs +13 -2
  508. package/src/Field/FieldLabel.test.tsx +29 -0
  509. package/src/Field/FieldLabel.tsx +7 -0
  510. package/src/Field/InputClearButton.test.tsx +15 -1
  511. package/src/Field/InputClearButton.tsx +28 -4
  512. package/src/FileInput/FileInput.tsx +3 -2
  513. package/src/Heading/Heading.test.tsx +23 -1
  514. package/src/Heading/Heading.tsx +6 -3
  515. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  516. package/src/HoverCard/HoverCard.test.tsx +154 -4
  517. package/src/HoverCard/HoverCard.tsx +143 -3
  518. package/src/HoverCard/useHoverCard.tsx +104 -33
  519. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  520. package/src/Indicator/Indicator.doc.mjs +2 -0
  521. package/src/Item/Item.tsx +5 -4
  522. package/src/Kbd/Kbd.tsx +2 -19
  523. package/src/Layer/LayerDepthContext.tsx +62 -0
  524. package/src/Layer/gestureCounter.ts +57 -0
  525. package/src/Layer/index.ts +9 -0
  526. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  527. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  528. package/src/Layer/layerStack.ts +362 -0
  529. package/src/Layer/useLayer.test.tsx +324 -15
  530. package/src/Layer/useLayer.tsx +164 -8
  531. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  532. package/src/Layer/useLayerDismissal.ts +173 -0
  533. package/src/Layout/Layout.doc.mjs +2 -2
  534. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  535. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  536. package/src/Lightbox/Lightbox.tsx +124 -102
  537. package/src/Link/Link.doc.mjs +39 -0
  538. package/src/List/List.test.tsx +38 -0
  539. package/src/List/List.tsx +8 -1
  540. package/src/Markdown/Markdown.doc.mjs +5 -0
  541. package/src/Markdown/Markdown.test.tsx +37 -0
  542. package/src/Markdown/Markdown.tsx +16 -5
  543. package/src/Markdown/incremental.test.ts +16 -2
  544. package/src/Markdown/index.ts +1 -0
  545. package/src/Markdown/parser.perf.test.ts +96 -1
  546. package/src/Markdown/parser.test.ts +178 -2
  547. package/src/Markdown/parser.ts +253 -32
  548. package/src/MetadataList/MetadataList.test.tsx +75 -2
  549. package/src/MetadataList/MetadataListItem.tsx +5 -2
  550. package/src/MobileNav/MobileNav.tsx +62 -36
  551. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  552. package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
  553. package/src/MultiSelector/MultiSelector.test.tsx +311 -0
  554. package/src/MultiSelector/MultiSelector.tsx +151 -15
  555. package/src/MultiSelector/hooks.ts +9 -2
  556. package/src/MultiSelector/index.ts +1 -0
  557. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  558. package/src/NavIcon/NavIcon.test.tsx +9 -0
  559. package/src/NavIcon/NavIcon.tsx +5 -1
  560. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  561. package/src/NavMenu/NavHeadingMenu.tsx +9 -5
  562. package/src/NumberInput/NumberInput.doc.mjs +31 -7
  563. package/src/NumberInput/NumberInput.test.tsx +436 -8
  564. package/src/NumberInput/NumberInput.tsx +62 -114
  565. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  566. package/src/NumberInput/numberInputCommit.ts +103 -0
  567. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  568. package/src/NumberInput/numberParser.test.ts +222 -0
  569. package/src/NumberInput/numberParser.ts +403 -0
  570. package/src/Outline/Outline.tsx +3 -2
  571. package/src/OverflowList/OverflowList.tsx +3 -2
  572. package/src/Overlay/Overlay.tsx +3 -2
  573. package/src/Pagination/Pagination.test.tsx +3 -2
  574. package/src/Popover/Popover.test.tsx +14 -0
  575. package/src/Popover/Popover.tsx +1 -9
  576. package/src/Popover/usePopover.tsx +57 -32
  577. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  578. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  579. package/src/PowerSearch/PowerSearch.tsx +34 -5
  580. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
  581. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  582. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
  583. package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
  584. package/src/PowerSearch/types.ts +2 -0
  585. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  586. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  587. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  588. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  589. package/src/ProgressBar/ProgressBar.tsx +28 -8
  590. package/src/Resizable/ResizeHandle.tsx +3 -2
  591. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  592. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  593. package/src/SelectableCard/SelectableCard.tsx +19 -2
  594. package/src/Selector/Selector.doc.mjs +26 -1
  595. package/src/Selector/Selector.test.tsx +346 -1
  596. package/src/Selector/Selector.tsx +148 -21
  597. package/src/Selector/hooks.ts +17 -2
  598. package/src/SideNav/SideNav.doc.mjs +6 -6
  599. package/src/SideNav/SideNav.tsx +4 -2
  600. package/src/SideNav/SideNavHeading.tsx +12 -12
  601. package/src/SideNav/SideNavItem.tsx +4 -2
  602. package/src/Slider/Slider.test.tsx +106 -1
  603. package/src/Slider/Slider.tsx +55 -3
  604. package/src/Spinner/Spinner.test.tsx +147 -1
  605. package/src/Spinner/Spinner.tsx +120 -101
  606. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  607. package/src/StatusDot/StatusDot.test.tsx +9 -0
  608. package/src/StatusDot/StatusDot.tsx +7 -1
  609. package/src/Stepper/Step.doc.mjs +98 -0
  610. package/src/Stepper/Step.tsx +1638 -0
  611. package/src/Stepper/StepStatus.ts +26 -0
  612. package/src/Stepper/Stepper.doc.mjs +370 -0
  613. package/src/Stepper/Stepper.test.tsx +1024 -0
  614. package/src/Stepper/Stepper.tsx +258 -0
  615. package/src/Stepper/StepperContext.ts +71 -0
  616. package/src/Stepper/index.ts +18 -0
  617. package/src/Stepper/stepper.stylex.ts +19 -0
  618. package/src/Switch/Switch.doc.mjs +2 -0
  619. package/src/Switch/Switch.test.tsx +10 -0
  620. package/src/Switch/Switch.tsx +6 -2
  621. package/src/TabList/Tab.doc.mjs +13 -1
  622. package/src/TabList/Tab.tsx +67 -7
  623. package/src/TabList/TabList.doc.mjs +22 -6
  624. package/src/TabList/TabList.test.tsx +559 -0
  625. package/src/TabList/TabList.tsx +490 -22
  626. package/src/TabList/TabListContext.ts +13 -2
  627. package/src/TabList/TabMenu.tsx +3 -2
  628. package/src/TabList/index.ts +6 -2
  629. package/src/Table/BaseTable.tsx +12 -4
  630. package/src/Table/Table.doc.mjs +9 -2
  631. package/src/Table/Table.test.tsx +132 -14
  632. package/src/Table/Table.tsx +3 -8
  633. package/src/Table/TableBody.doc.mjs +40 -0
  634. package/src/Table/TableFooter.doc.mjs +40 -0
  635. package/src/Table/TableHeader.doc.mjs +40 -0
  636. package/src/Table/TableRow.tsx +16 -5
  637. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  638. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  639. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  640. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  641. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +67 -12
  642. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  643. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  644. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  645. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  646. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  647. package/src/Table/plugins/selection/useTableSelection.test.tsx +138 -0
  648. package/src/Table/plugins/selection/useTableSelection.tsx +63 -7
  649. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  650. package/src/Table/types.ts +22 -4
  651. package/src/Table/useBaseTablePlugins.ts +5 -0
  652. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  653. package/src/Table/useTablePagination.doc.mjs +7 -0
  654. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  655. package/src/Table/useTableSelection.doc.mjs +31 -0
  656. package/src/Text/Text.test.tsx +67 -1
  657. package/src/Text/Text.tsx +6 -3
  658. package/src/TextArea/TextArea.doc.mjs +12 -2
  659. package/src/TextArea/TextArea.test.tsx +11 -0
  660. package/src/TextArea/TextArea.tsx +37 -24
  661. package/src/TextInput/TextInput.doc.mjs +10 -0
  662. package/src/TextInput/TextInput.tsx +3 -2
  663. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  664. package/src/TimeInput/TimeInput.tsx +2 -2
  665. package/src/Timestamp/Timestamp.test.tsx +58 -0
  666. package/src/Timestamp/Timestamp.tsx +12 -10
  667. package/src/Toast/Toast.doc.mjs +26 -12
  668. package/src/Toast/Toast.tsx +28 -4
  669. package/src/Toast/ToastViewport.test.tsx +536 -8
  670. package/src/Toast/ToastViewport.tsx +81 -12
  671. package/src/Token/Token.test.tsx +95 -0
  672. package/src/Token/Token.tsx +15 -10
  673. package/src/Token/TokenLink.tsx +14 -5
  674. package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
  675. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  676. package/src/Tokenizer/Tokenizer.tsx +53 -24
  677. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  678. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  679. package/src/Tooltip/Tooltip.test.tsx +32 -0
  680. package/src/Tooltip/Tooltip.tsx +5 -0
  681. package/src/Tooltip/useTooltip.tsx +47 -24
  682. package/src/TopNav/TopNavHeading.tsx +5 -4
  683. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  684. package/src/TopNav/TopNavMegaMenu.tsx +47 -5
  685. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  686. package/src/TopNav/TopNavMenu.tsx +38 -7
  687. package/src/TreeList/TreeList.test.tsx +49 -0
  688. package/src/TreeList/TreeList.tsx +7 -2
  689. package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
  690. package/src/Typeahead/BaseTypeahead.tsx +181 -39
  691. package/src/Typeahead/Typeahead.doc.mjs +11 -0
  692. package/src/Typeahead/Typeahead.test.tsx +203 -0
  693. package/src/Typeahead/Typeahead.tsx +12 -2
  694. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  695. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  696. package/src/hooks/index.ts +2 -0
  697. package/src/hooks/useAnnounce.doc.mjs +96 -0
  698. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  699. package/src/hooks/useDevWarning.doc.mjs +96 -0
  700. package/src/hooks/useFocusTrap.test.tsx +14 -0
  701. package/src/hooks/useFocusTrap.ts +62 -111
  702. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  703. package/src/hooks/useHotkeys.ts +3 -18
  704. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  705. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  706. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  707. package/src/hooks/useLongPress.doc.mjs +123 -0
  708. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  709. package/src/hooks/useMergedRefs.test.tsx +62 -0
  710. package/src/hooks/useMergedRefs.ts +36 -0
  711. package/src/hooks/useTypeahead.doc.mjs +153 -0
  712. package/src/index.ts +1 -0
  713. package/src/raw-import.d.ts +14 -0
  714. package/src/theme/MediaTheme.doc.mjs +5 -5
  715. package/src/theme/Theme.test.tsx +104 -2
  716. package/src/theme/Theme.tsx +49 -14
  717. package/src/theme/defineTheme.test.ts +23 -0
  718. package/src/theme/derivedVarRegistry.test.ts +26 -3
  719. package/src/theme/derivedVarRegistry.ts +23 -4
  720. package/src/theme/generateThemeRules.test.ts +99 -1
  721. package/src/theme/generateThemeRules.ts +28 -0
  722. package/src/theme/syntax/tokens.ts +5 -2
  723. package/src/utils/groupItems.ts +12 -6
  724. package/src/utils/index.ts +1 -1
  725. package/src/utils/isApplePlatform.test.ts +61 -0
  726. package/src/utils/isApplePlatform.ts +37 -0
  727. package/src/utils/sharedResizeObserver.ts +10 -2
  728. package/src/utils/timeParser.test.ts +6 -1
  729. package/src/utils/timeParser.ts +35 -13
  730. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -2,6 +2,18 @@
2
2
 
3
3
  'use client';
4
4
 
5
+ /**
6
+ * @file ToastViewport.tsx
7
+ * @input Uses React state/effects, ToastContext, useAnnounce, viewport tokens,
8
+ * and placement-derived motion variables
9
+ * @output Exports the ToastViewport provider, stack, live announcement dispatch,
10
+ * focus handoff, safe-area-aware edge gutters, and motion context
11
+ * @position Core provider/imperative viewport for useToast()
12
+ *
13
+ * SYNC: When placement, stacking, focus, announcement, or safe-area behavior
14
+ * changes, update ToastViewport.test.tsx, Toast.doc.mjs, and Toast.stories.tsx.
15
+ */
16
+
5
17
  import {
6
18
  isValidElement,
7
19
  useCallback,
@@ -22,13 +34,30 @@ import {ToastContext, type ToastContextValue} from './ToastContext';
22
34
  import type {ToastEntry, ToastPosition, ToastDismissReason} from './types';
23
35
  import {useTranslator} from '../i18n';
24
36
 
37
+ const SAFE_AREA_INLINE_START = `max(${spacingVars['--spacing-4']}, env(safe-area-inset-left, 0px))`;
38
+ const SAFE_AREA_INLINE_END = `max(${spacingVars['--spacing-4']}, env(safe-area-inset-right, 0px))`;
39
+ const SAFE_AREA_BLOCK_START = `max(${spacingVars['--spacing-4']}, env(safe-area-inset-top, 0px))`;
40
+ const SAFE_AREA_BLOCK_END = `max(${spacingVars['--spacing-4']}, env(safe-area-inset-bottom, 0px))`;
41
+ const TOAST_EDGE_DRIFT = spacingVars['--spacing-2'];
42
+ const TOAST_EDGE_DRIFT_NEGATIVE = `calc(-1 * ${TOAST_EDGE_DRIFT})`;
43
+
25
44
  const styles = stylex.create({
26
45
  viewport: {
27
46
  position: 'fixed',
28
47
  zIndex: 500,
29
48
  display: 'flex',
49
+ boxSizing: 'border-box',
30
50
  flexDirection: 'column',
31
- padding: spacingVars['--spacing-4'],
51
+ paddingBlockStart: SAFE_AREA_BLOCK_START,
52
+ paddingBlockEnd: SAFE_AREA_BLOCK_END,
53
+ paddingInlineStart: {
54
+ default: SAFE_AREA_INLINE_START,
55
+ ':is([dir="rtl"] *)': SAFE_AREA_INLINE_END,
56
+ },
57
+ paddingInlineEnd: {
58
+ default: SAFE_AREA_INLINE_END,
59
+ ':is([dir="rtl"] *)': SAFE_AREA_INLINE_START,
60
+ },
32
61
  pointerEvents: 'none',
33
62
  // Reset popover styles — the popover attribute puts us in the top
34
63
  // layer (above dialogs), but we don't want its default styles.
@@ -40,25 +69,29 @@ const styles = stylex.create({
40
69
  backgroundColor: 'transparent',
41
70
  overflow: 'visible',
42
71
  },
43
- bottomEnd: {bottom: 0, insetInlineEnd: 0, alignItems: 'flex-end'},
44
- bottomStart: {bottom: 0, insetInlineStart: 0, alignItems: 'flex-start'},
72
+ viewportInlineSpan: {
73
+ insetInlineStart: 0,
74
+ insetInlineEnd: 0,
75
+ },
76
+ bottomEnd: {bottom: 0, alignItems: 'flex-end'},
77
+ bottomStart: {bottom: 0, alignItems: 'flex-start'},
45
78
  topEnd: {
46
79
  top: 0,
47
- insetInlineEnd: 0,
48
80
  alignItems: 'flex-end',
49
81
  flexDirection: 'column-reverse',
50
82
  },
51
83
  topStart: {
52
84
  top: 0,
53
- insetInlineStart: 0,
54
85
  alignItems: 'flex-start',
55
86
  flexDirection: 'column-reverse',
56
87
  },
57
88
  toastWrapper: {
58
89
  pointerEvents: 'auto',
59
90
  display: 'grid',
91
+ width: '100%',
92
+ maxWidth: 400,
93
+ minWidth: 0,
60
94
  gridTemplateRows: '1fr',
61
- paddingBlockEnd: spacingVars['--spacing-3'],
62
95
  transitionProperty: 'grid-template-rows, padding',
63
96
  transitionDuration: {
64
97
  default: durationVars['--duration-fast'],
@@ -70,11 +103,33 @@ const styles = stylex.create({
70
103
  paddingBlockEnd: 0,
71
104
  },
72
105
  },
106
+ toastWrapperFromBottom: {
107
+ '--_toast-slide-y': TOAST_EDGE_DRIFT,
108
+ },
109
+ toastWrapperFromTop: {
110
+ '--_toast-slide-y': TOAST_EDGE_DRIFT_NEGATIVE,
111
+ },
112
+ // The inter-toast gap is padding on each wrapper so it collapses with the
113
+ // grid track. The wrapper nearest the viewport edge drops that padding; the
114
+ // child flips because top stacks use column-reverse.
115
+ toastWrapperGap: {
116
+ paddingBlockEnd: {default: spacingVars['--spacing-2'], ':last-child': 0},
117
+ },
118
+ toastWrapperGapReversed: {
119
+ paddingBlockEnd: {default: spacingVars['--spacing-2'], ':first-child': 0},
120
+ },
73
121
  toastWrapperExiting: {
74
122
  gridTemplateRows: '0fr',
75
123
  paddingBlockEnd: 0,
76
124
  },
77
125
  toastWrapperInner: {
126
+ width: '100%',
127
+ maxWidth: '100%',
128
+ minWidth: 0,
129
+ minHeight: 0,
130
+ // Required for the 1fr -> 0fr exit collapse to hide the shrinking Toast.
131
+ // This preserves main's paint containment; browser-chrome behavior is not
132
+ // changed or claimed by this responsive-layout fix.
78
133
  overflow: 'hidden',
79
134
  },
80
135
  });
@@ -104,6 +159,7 @@ function getNodeText(node: ReactNode): string {
104
159
 
105
160
  export interface ToastViewportProps {
106
161
  position?: ToastPosition;
162
+ /** Maximum number of visible toasts. @default 5 */
107
163
  maxVisible?: number;
108
164
  inset?: {top?: number; bottom?: number; start?: number; end?: number};
109
165
  /**
@@ -341,6 +397,7 @@ export function ToastViewport({
341
397
  );
342
398
 
343
399
  const visibleToasts = toasts.slice(-maxVisible);
400
+
344
401
  const insetStyle: React.CSSProperties = {};
345
402
  if (inset?.top) {
346
403
  insetStyle.top = inset.top;
@@ -417,21 +474,31 @@ export function ToastViewport({
417
474
  : position === 'bottomStart'
418
475
  ? styles.bottomStart
419
476
  : styles.bottomEnd;
477
+ const isReversed = position === 'topEnd' || position === 'topStart';
478
+ const toastWrapperPositionStyle = isReversed
479
+ ? styles.toastWrapperFromTop
480
+ : styles.toastWrapperFromBottom;
481
+ const gapStyle = isReversed
482
+ ? styles.toastWrapperGapReversed
483
+ : styles.toastWrapperGap;
420
484
 
421
485
  return (
422
486
  <ToastContext value={contextValue}>
423
487
  {children}
424
488
  <div
425
489
  ref={viewportRef}
426
- role="region"
427
- aria-label={t('@astryx.toast.viewport')}
428
- tabIndex={-1}
490
+ role={hasToasts ? 'region' : undefined}
491
+ aria-label={hasToasts ? t('@astryx.toast.viewport') : undefined}
492
+ tabIndex={hasToasts ? -1 : undefined}
429
493
  // popover="manual" promotes to the top layer (above dialogs).
430
494
  // Omitted inside dialogs where the viewport is already in a top layer.
431
495
  popover={isTopLayer ? 'manual' : undefined}
432
- {...mergeProps(stylex.props(styles.viewport, posStyle), {
433
- style: Object.keys(insetStyle).length > 0 ? insetStyle : undefined,
434
- })}>
496
+ {...mergeProps(
497
+ stylex.props(styles.viewport, styles.viewportInlineSpan, posStyle),
498
+ {
499
+ style: Object.keys(insetStyle).length > 0 ? insetStyle : undefined,
500
+ },
501
+ )}>
435
502
  {visibleToasts.map(entry => {
436
503
  const o = entry.options;
437
504
  const type = o.type ?? 'info';
@@ -444,6 +511,8 @@ export function ToastViewport({
444
511
  data-toast-id={entry.id}
445
512
  {...stylex.props(
446
513
  styles.toastWrapper,
514
+ toastWrapperPositionStyle,
515
+ gapStyle,
447
516
  isExiting && styles.toastWrapperExiting,
448
517
  )}
449
518
  onTransitionEnd={
@@ -521,3 +521,98 @@ describe('Token focus outline', () => {
521
521
  expect(container.tagName).toBe('SPAN');
522
522
  });
523
523
  });
524
+
525
+ describe('Token pass-through props', () => {
526
+ it('forwards pass-through props to the token element', () => {
527
+ render(
528
+ <Token
529
+ label="Design"
530
+ aria-label="Design tag"
531
+ id="design-token"
532
+ data-source="filters"
533
+ data-testid="token"
534
+ />,
535
+ );
536
+ const token = screen.getByTestId('token');
537
+ expect(token).toHaveAttribute('aria-label', 'Design tag');
538
+ expect(token).toHaveAttribute('id', 'design-token');
539
+ expect(token).toHaveAttribute('data-source', 'filters');
540
+ });
541
+
542
+ it('forwards pass-through props on the clickable and link variants', () => {
543
+ const {rerender} = render(
544
+ <Token
545
+ label="Design"
546
+ onClick={() => {}}
547
+ id="clickable"
548
+ data-testid="token"
549
+ />,
550
+ );
551
+ expect(screen.getByTestId('token')).toHaveAttribute('id', 'clickable');
552
+
553
+ rerender(
554
+ <Token label="Design" href="/tags" id="link" data-testid="token" />,
555
+ );
556
+ expect(screen.getByTestId('token')).toHaveAttribute('id', 'link');
557
+ });
558
+
559
+ it('keeps its own label when the label is visually hidden', () => {
560
+ render(
561
+ <Token
562
+ label="Design"
563
+ isLabelHidden
564
+ aria-label="Caller label"
565
+ data-source="filters"
566
+ data-testid="token"
567
+ />,
568
+ );
569
+ const token = screen.getByTestId('token');
570
+ expect({
571
+ ariaLabel: token.getAttribute('aria-label'),
572
+ dataSource: token.getAttribute('data-source'),
573
+ }).toEqual({ariaLabel: 'Design', dataSource: 'filters'});
574
+ });
575
+ });
576
+
577
+ describe('Token — owned handlers on the link+remove container', () => {
578
+ it("composes a caller's onMouseUp with the container's link delegation", () => {
579
+ const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null);
580
+ const handleMouseUp = vi.fn();
581
+ render(
582
+ <Token
583
+ label="Tag"
584
+ href="/test"
585
+ onRemove={() => {}}
586
+ onMouseUp={handleMouseUp}
587
+ icon={<span data-testid="icon">★</span>}
588
+ />,
589
+ );
590
+
591
+ fireEvent.mouseUp(screen.getByTestId('icon'), {button: 1});
592
+
593
+ expect(handleMouseUp).toHaveBeenCalledOnce();
594
+ expect(openSpy).toHaveBeenCalledWith('/test', '_blank', 'noopener');
595
+ openSpy.mockRestore();
596
+ });
597
+
598
+ it("does not fire the container's delegation when disabled, but still forwards the caller's onMouseUp", () => {
599
+ const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null);
600
+ const handleMouseUp = vi.fn();
601
+ render(
602
+ <Token
603
+ label="Tag"
604
+ href="/test"
605
+ onRemove={() => {}}
606
+ onMouseUp={handleMouseUp}
607
+ isDisabled
608
+ icon={<span data-testid="icon">★</span>}
609
+ />,
610
+ );
611
+
612
+ fireEvent.mouseUp(screen.getByTestId('icon'), {button: 1});
613
+
614
+ expect(handleMouseUp).toHaveBeenCalledOnce();
615
+ expect(openSpy).not.toHaveBeenCalled();
616
+ openSpy.mockRestore();
617
+ });
618
+ });
@@ -307,6 +307,7 @@ export function Token({
307
307
  style,
308
308
  'data-testid': testId,
309
309
  ref,
310
+ ...rest
310
311
  }: TokenProps) {
311
312
  const t = useTranslator();
312
313
  const LinkComponent = useLinkComponent();
@@ -344,8 +345,8 @@ export function Token({
344
345
 
345
346
  const sharedProps = {
346
347
  'data-testid': testId,
347
- 'aria-label': isLabelHidden ? label : undefined,
348
- 'aria-description': description,
348
+ ...(isLabelHidden ? {'aria-label': label} : {}),
349
+ ...(description != null ? {'aria-description': description} : {}),
349
350
  };
350
351
 
351
352
  if (role === 'link') {
@@ -354,8 +355,6 @@ export function Token({
354
355
  <LinkComponent
355
356
  ref={ref as React.Ref<HTMLAnchorElement>}
356
357
  href={href as string}
357
- aria-disabled={isDisabled || undefined}
358
- {...sharedProps}
359
358
  {...mergeProps(
360
359
  themeProps('token', {color, size}),
361
360
  focusOutlineProps.focusVisible(
@@ -368,7 +367,10 @@ export function Token({
368
367
  ),
369
368
  className,
370
369
  style,
371
- )}>
370
+ )}
371
+ {...rest}
372
+ {...(isDisabled ? {'aria-disabled': true} : {})}
373
+ {...sharedProps}>
372
374
  {content}
373
375
  </LinkComponent>
374
376
  );
@@ -400,7 +402,6 @@ export function Token({
400
402
  {label}
401
403
  </span>
402
404
  }
403
- {...sharedProps}
404
405
  {...mergeProps(
405
406
  themeProps('token', {color, size}),
406
407
  focusOutlineProps.focusWithin(
@@ -414,6 +415,8 @@ export function Token({
414
415
  className,
415
416
  style,
416
417
  )}
418
+ {...rest}
419
+ {...sharedProps}
417
420
  />
418
421
  );
419
422
  }
@@ -431,7 +434,6 @@ export function Token({
431
434
  <span
432
435
  ref={ref}
433
436
  onClick={isDisabled ? undefined : handleContainerClick}
434
- {...sharedProps}
435
437
  {...mergeProps(
436
438
  themeProps('token', {color, size}),
437
439
  focusOutlineProps.focusWithin(
@@ -444,7 +446,9 @@ export function Token({
444
446
  ),
445
447
  className,
446
448
  style,
447
- )}>
449
+ )}
450
+ {...rest}
451
+ {...sharedProps}>
448
452
  {icon}
449
453
  <button
450
454
  type="button"
@@ -468,7 +472,6 @@ export function Token({
468
472
  return (
469
473
  <span
470
474
  ref={ref}
471
- {...sharedProps}
472
475
  {...mergeProps(
473
476
  themeProps('token', {color, size}),
474
477
  stylex.props(
@@ -480,7 +483,9 @@ export function Token({
480
483
  ),
481
484
  className,
482
485
  style,
483
- )}>
486
+ )}
487
+ {...rest}
488
+ {...sharedProps}>
484
489
  {content}
485
490
  </span>
486
491
  );
@@ -27,10 +27,11 @@
27
27
 
28
28
  import type {ReactNode, CSSProperties, Ref, HTMLAttributes} from 'react';
29
29
  import {useRef} from 'react';
30
- import {mergeRefs} from '../utils';
31
30
  import {useClickableContainer} from '../hooks/useClickableContainer';
32
31
  import type {LinkComponentType} from '../Link/types';
32
+ import {composeEventHandlers} from '../utils';
33
33
 
34
+ import {useMergedRefs} from '../hooks/useMergedRefs';
34
35
  export interface TokenLinkProps extends HTMLAttributes<HTMLElement> {
35
36
  /** Ref forwarded to the container element. */
36
37
  ref?: Ref<HTMLElement>;
@@ -72,6 +73,8 @@ export function TokenLink({
72
73
  icon,
73
74
  endContent,
74
75
  removeButton,
76
+ onClick: onClickProp,
77
+ onMouseUp: onMouseUpProp,
75
78
  ...containerProps
76
79
  }: TokenLinkProps) {
77
80
  const containerRef = useRef<HTMLElement | null>(null);
@@ -86,10 +89,16 @@ export function TokenLink({
86
89
 
87
90
  return (
88
91
  <span
89
- ref={mergeRefs(ref, containerRef)}
90
- onClick={isDisabled ? undefined : onClick}
91
- onMouseUp={isDisabled ? undefined : onMouseUp}
92
- {...containerProps}>
92
+ ref={useMergedRefs(ref, containerRef)}
93
+ {...containerProps}
94
+ onClick={
95
+ isDisabled ? onClickProp : composeEventHandlers(onClickProp, onClick)
96
+ }
97
+ onMouseUp={
98
+ isDisabled
99
+ ? onMouseUpProp
100
+ : composeEventHandlers(onMouseUpProp, onMouseUp)
101
+ }>
93
102
  {icon}
94
103
  <LinkComponent
95
104
  ref={linkRef as Ref<HTMLAnchorElement>}
@@ -132,9 +132,20 @@ export const docs = {
132
132
  {
133
133
  name: 'maxMenuItems',
134
134
  type: 'number',
135
- description: 'Maximum number of dropdown items to display.',
135
+ description: 'Maximum number of search results to display. The hasCreate entry is offered on top of them, so a menu can show one more than this.',
136
136
  default: '10',
137
137
  },
138
+ {
139
+ name: 'menuWidth',
140
+ type: 'number',
141
+ description: 'Fixed dropdown width in pixels. The menu never shrinks below its anchor width.',
142
+ },
143
+ {
144
+ name: 'minQueryLength',
145
+ type: 'number',
146
+ description: 'Minimum query length before the search source is queried. Below it no search runs, and the menu stays closed — unless hasCreate is set, in which case the "Create ..." entry is still offered, being derived from the typed text rather than fetched for it.',
147
+ default: '1',
148
+ },
138
149
  {
139
150
  name: 'emptySearchResultsText',
140
151
  type: 'string',
@@ -201,6 +212,22 @@ export const docs = {
201
212
  description:
202
213
  'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
203
214
  },
215
+ {
216
+ name: 'tokenOverflowBehavior',
217
+ type: "'none' | 'unfocusedInline' | 'unfocusedLayer'",
218
+ description: 'Controls how tokens overflow when the container is too narrow.',
219
+ default: "'none'",
220
+ },
221
+ {
222
+ name: 'onFocus',
223
+ type: '(e: FocusEvent<HTMLInputElement>) => void',
224
+ description: 'Fires when focus enters the tokenizer input.',
225
+ },
226
+ {
227
+ name: 'onBlur',
228
+ type: '(e: FocusEvent<HTMLInputElement>) => void',
229
+ description: 'Fires when focus leaves the tokenizer input.',
230
+ },
204
231
  {
205
232
  name: 'xstyle',
206
233
  type: 'StyleXStyles',
@@ -365,9 +392,20 @@ export const docsZh = {
365
392
  {
366
393
  name: 'maxMenuItems',
367
394
  type: 'number',
368
- description: '\u4e0b\u62c9\u5217\u8868\u663e\u793a\u7684\u6700\u5927\u9879\u76ee\u6570\u3002',
395
+ description: '下拉列表显示的最大搜索结果数。“创建 ...”条目会在此之外额外提供,因此菜单可能比该数量多显示一项。',
369
396
  default: '10',
370
397
  },
398
+ {
399
+ name: 'menuWidth',
400
+ type: 'number',
401
+ description: '下拉菜单的固定像素宽度。菜单不会小于其锚点宽度。',
402
+ },
403
+ {
404
+ name: 'minQueryLength',
405
+ type: 'number',
406
+ description: '查询搜索源前的最小查询长度。低于该长度不会发起搜索,菜单保持关闭;但设置 hasCreate 时仍会提供“创建 ...”条目——该条目由输入的文本推导而来,并非通过搜索获取。',
407
+ default: '1',
408
+ },
371
409
  {
372
410
  name: 'emptySearchResultsText',
373
411
  type: 'string',
@@ -489,7 +527,9 @@ export const docsDense = {
489
527
  isOptional: 'Shows optional indicator on label.',
490
528
  labelTooltip: 'Tooltip on label.',
491
529
  hasEntriesOnFocus: 'Show bootstrap results on focus before typing.',
492
- maxMenuItems: 'Max dropdown items to display.',
530
+ maxMenuItems: 'Max search results shown; the hasCreate entry sits on top of them.',
531
+ menuWidth: 'Fixed dropdown width in pixels.',
532
+ minQueryLength: 'Min query length before searching. Menu stays closed below it, except the hasCreate entry.',
493
533
  emptySearchResultsText: 'Text when search returns no results.',
494
534
  hasAutoFocus: 'Auto-focus input on mount.',
495
535
  size: 'Input+token size.',
@@ -94,6 +94,37 @@ const userSource: SearchSource = {
94
94
  bootstrap: () => users.slice(0, 3),
95
95
  };
96
96
 
97
+ describe('Tokenizer minQueryLength', () => {
98
+ it('forwards the threshold to the typeahead engine', async () => {
99
+ const search = vi.fn((query: string) =>
100
+ users.filter(u => u.label.toLowerCase().includes(query.toLowerCase())),
101
+ );
102
+ render(
103
+ <Tokenizer
104
+ label="People"
105
+ searchSource={{search, bootstrap: () => []}}
106
+ value={[]}
107
+ onChange={() => {}}
108
+ minQueryLength={3}
109
+ debounceMs={0}
110
+ />,
111
+ );
112
+ const input = screen.getByRole('combobox');
113
+
114
+ fireEvent.change(input, {target: {value: 'Al'}});
115
+ await act(async () => {
116
+ await Promise.resolve();
117
+ });
118
+ expect(search).not.toHaveBeenCalled();
119
+ expect(input).toHaveAttribute('aria-expanded', 'false');
120
+
121
+ fireEvent.change(input, {target: {value: 'Ali'}});
122
+ await waitFor(() => {
123
+ expect(input).toHaveAttribute('aria-expanded', 'true');
124
+ });
125
+ });
126
+ });
127
+
97
128
  describe('Tokenizer', () => {
98
129
  it('forwards ref to the root field element', () => {
99
130
  let root: HTMLDivElement | null = null;
@@ -606,6 +637,136 @@ describe('Tokenizer', () => {
606
637
  bootstrap: () => [],
607
638
  };
608
639
 
640
+ it('still offers Create below minQueryLength, and does not search', async () => {
641
+ // The threshold exists to avoid a fetch too broad to be worth making.
642
+ // Creating costs no fetch, so a field that can create `QA` should not
643
+ // stop being able to just because a search for `QA` would match too
644
+ // much. Reported on #5385.
645
+ const search = vi.fn(() => []);
646
+ const onChange = vi.fn();
647
+ render(
648
+ <Tokenizer
649
+ label="Tags"
650
+ searchSource={{search, bootstrap: () => []}}
651
+ value={[]}
652
+ onChange={onChange}
653
+ hasCreate
654
+ minQueryLength={3}
655
+ debounceMs={0}
656
+ />,
657
+ );
658
+
659
+ const input = screen.getByRole('combobox');
660
+ await act(async () => {
661
+ fireEvent.change(input, {target: {value: 'QA'}});
662
+ });
663
+ await act(async () => {
664
+ await new Promise(r => setTimeout(r, 50));
665
+ });
666
+
667
+ // Offered...
668
+ expect(screen.queryByText('Create "QA"')).toBeInTheDocument();
669
+ // ...without the source ever being asked.
670
+ expect(search).not.toHaveBeenCalled();
671
+ // ...and it commits.
672
+ fireEvent.click(screen.getByText('Create "QA"'));
673
+ expect(onChange).toHaveBeenCalledWith(
674
+ [expect.objectContaining({id: 'QA', label: 'QA'})],
675
+ expect.objectContaining({type: 'create'}),
676
+ );
677
+ });
678
+
679
+ it('offers no menu below the threshold without hasCreate', async () => {
680
+ // The negative control for the case above: with nothing to derive from
681
+ // the text, a below-threshold query still opens nothing, and never
682
+ // reports "no results" for a query that was not searched.
683
+ const search = vi.fn(() => []);
684
+ render(
685
+ <Tokenizer
686
+ label="Tags"
687
+ searchSource={{search, bootstrap: () => []}}
688
+ value={[]}
689
+ onChange={() => {}}
690
+ minQueryLength={3}
691
+ debounceMs={0}
692
+ />,
693
+ );
694
+
695
+ const input = screen.getByRole('combobox');
696
+ await act(async () => {
697
+ fireEvent.change(input, {target: {value: 'QA'}});
698
+ });
699
+ await act(async () => {
700
+ await new Promise(r => setTimeout(r, 50));
701
+ });
702
+
703
+ expect(search).not.toHaveBeenCalled();
704
+ expect(input).toHaveAttribute('aria-expanded', 'false');
705
+ expect(screen.queryByText('No results found')).not.toBeInTheDocument();
706
+ });
707
+
708
+ it('does not offer Create below the threshold for a token already held', async () => {
709
+ render(
710
+ <Tokenizer
711
+ label="Tags"
712
+ searchSource={{search: () => [], bootstrap: () => []}}
713
+ value={[{id: 'QA', label: 'QA'}]}
714
+ onChange={() => {}}
715
+ hasCreate
716
+ minQueryLength={3}
717
+ debounceMs={0}
718
+ />,
719
+ );
720
+
721
+ const input = screen.getByRole('combobox');
722
+ await act(async () => {
723
+ fireEvent.change(input, {target: {value: 'QA'}});
724
+ });
725
+ await act(async () => {
726
+ await new Promise(r => setTimeout(r, 50));
727
+ });
728
+
729
+ expect(screen.queryByText('Create "QA"')).not.toBeInTheDocument();
730
+ });
731
+
732
+ it('offers Create on top of a full menu, not in place of a result', async () => {
733
+ // The Create entry is appended after the results are cut to
734
+ // `maxMenuItems`, so a full menu shows one more option rather than
735
+ // dropping its last result to make room. Deliberate: creating is a
736
+ // different capability from searching, and the cap exists to bound how
737
+ // many *results* a menu shows.
738
+ const many = Array.from({length: 20}, (_, i) => ({
739
+ id: `qa-${i}`,
740
+ label: `QA ${i}`,
741
+ }));
742
+ render(
743
+ <Tokenizer
744
+ label="Tags"
745
+ searchSource={{search: () => many, bootstrap: () => []}}
746
+ value={[]}
747
+ onChange={() => {}}
748
+ hasCreate
749
+ maxMenuItems={3}
750
+ debounceMs={0}
751
+ />,
752
+ );
753
+
754
+ const input = screen.getByRole('combobox');
755
+ await act(async () => {
756
+ fireEvent.change(input, {target: {value: 'QA'}});
757
+ });
758
+ await act(async () => {
759
+ await new Promise(r => setTimeout(r, 50));
760
+ });
761
+
762
+ // Queried off the document rather than by role: the popover renders
763
+ // into a layer that jsdom keeps out of the accessibility tree, which is
764
+ // why the tests around this one reach for text too.
765
+ const options = document.querySelectorAll('[role="option"]');
766
+ expect(options).toHaveLength(4);
767
+ expect(options[3]).toHaveTextContent('Create "QA"');
768
+ });
769
+
609
770
  it('shows a "Create" option when typing with hasCreate', async () => {
610
771
  render(
611
772
  <Tokenizer