@astryxdesign/core 0.5.0 → 0.5.1-canary.70169cd

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 (622) hide show
  1. package/CHANGELOG.md +222 -0
  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/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  278. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  279. package/dist/i18n/InternationalizationContext.js +3 -1
  280. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  281. package/dist/i18n/InternationalizationProvider.js +3 -1
  282. package/dist/i18n/resolve.d.ts +1 -1
  283. package/dist/i18n/resolve.d.ts.map +1 -1
  284. package/dist/i18n/resolve.js +37 -38
  285. package/dist/i18n/useTranslator.d.ts.map +1 -1
  286. package/dist/i18n/useTranslator.js +2 -3
  287. package/dist/index.d.ts +1 -1
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/theme/Theme.d.ts.map +1 -1
  290. package/dist/theme/Theme.js +46 -10
  291. package/dist/theme/defineTheme.d.ts +9 -3
  292. package/dist/theme/defineTheme.d.ts.map +1 -1
  293. package/dist/theme/defineTheme.js +5 -0
  294. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  295. package/dist/theme/derivedVarRegistry.js +24 -4
  296. package/dist/theme/generateThemeRules.d.ts +21 -0
  297. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  298. package/dist/theme/generateThemeRules.js +26 -0
  299. package/dist/theme/syntax/tokens.d.ts +1 -1
  300. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  301. package/dist/theme/syntax/tokens.js +5 -2
  302. package/dist/theme/useTheme.d.ts.map +1 -1
  303. package/dist/theme/useTheme.js +6 -7
  304. package/dist/utils/dateParser.d.ts +5 -8
  305. package/dist/utils/dateParser.d.ts.map +1 -1
  306. package/dist/utils/dateParser.js +10 -11
  307. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  308. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  309. package/dist/utils/focusOutline.stylex.js +15 -0
  310. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  311. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  312. package/dist/utils/interactionOverlay.stylex.js +42 -0
  313. package/dist/utils/isApplePlatform.d.ts +18 -0
  314. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  315. package/dist/utils/isApplePlatform.js +37 -0
  316. package/dist/utils/plainDate.d.ts +11 -0
  317. package/dist/utils/plainDate.d.ts.map +1 -1
  318. package/dist/utils/plainDate.js +20 -4
  319. package/locales/af-ZA.json +7 -7
  320. package/locales/ar-SA.json +7 -7
  321. package/locales/ca-ES.json +6 -6
  322. package/locales/cs-CZ.json +7 -7
  323. package/locales/da-DK.json +7 -7
  324. package/locales/de-DE.json +7 -7
  325. package/locales/el-GR.json +7 -7
  326. package/locales/en.json +178 -6
  327. package/locales/es-ES.json +6 -6
  328. package/locales/fi-FI.json +7 -7
  329. package/locales/fr-FR.json +7 -7
  330. package/locales/he-IL.json +7 -7
  331. package/locales/hu-HU.json +7 -7
  332. package/locales/it-IT.json +7 -7
  333. package/locales/ja-JP.json +7 -7
  334. package/locales/ko-KR.json +7 -7
  335. package/locales/nl-NL.json +7 -7
  336. package/locales/no-NO.json +7 -7
  337. package/locales/pl-PL.json +7 -7
  338. package/locales/pseudo.json +130 -1
  339. package/locales/pt-BR.json +7 -7
  340. package/locales/pt-PT.json +7 -7
  341. package/locales/ro-RO.json +7 -7
  342. package/locales/ru-RU.json +7 -7
  343. package/locales/sr-SP.json +7 -7
  344. package/locales/sv-SE.json +7 -7
  345. package/locales/tr-TR.json +7 -7
  346. package/locales/uk-UA.json +7 -7
  347. package/locales/vi-VN.json +7 -7
  348. package/locales/zh-CN.json +7 -7
  349. package/locales/zh-TW.json +7 -7
  350. package/package.json +4 -5
  351. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  352. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  353. package/src/AlertDialog/AlertDialog.tsx +62 -20
  354. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  355. package/src/AspectRatio/AspectRatio.tsx +6 -6
  356. package/src/Avatar/Avatar.doc.mjs +12 -2
  357. package/src/Avatar/Avatar.test.tsx +80 -0
  358. package/src/Avatar/Avatar.tsx +64 -14
  359. package/src/Avatar/index.ts +2 -2
  360. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  361. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  362. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  363. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  364. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  365. package/src/Badge/Badge.doc.mjs +3 -2
  366. package/src/Badge/Badge.test.tsx +32 -3
  367. package/src/Badge/Badge.tsx +42 -1
  368. package/src/Banner/Banner.doc.mjs +9 -0
  369. package/src/Banner/Banner.test.tsx +76 -11
  370. package/src/Banner/Banner.tsx +21 -2
  371. package/src/Button/Button.doc.mjs +2 -1
  372. package/src/Button/Button.test.tsx +19 -4
  373. package/src/Button/Button.tsx +9 -29
  374. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  375. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  376. package/src/Calendar/Calendar.doc.mjs +4 -4
  377. package/src/Calendar/Calendar.test.tsx +112 -0
  378. package/src/Calendar/Calendar.tsx +18 -16
  379. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  380. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  381. package/src/Calendar/styles.ts +48 -42
  382. package/src/Card/Card.doc.mjs +10 -7
  383. package/src/Card/Card.test.tsx +113 -19
  384. package/src/Card/Card.tsx +67 -89
  385. package/src/Card/index.ts +36 -1
  386. package/src/Carousel/Carousel.doc.mjs +3 -0
  387. package/src/Carousel/Carousel.test.tsx +360 -0
  388. package/src/Carousel/Carousel.tsx +116 -15
  389. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -1
  390. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  391. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  392. package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
  393. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  394. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  395. package/src/CodeBlock/CodeBlock.tsx +20 -4
  396. package/src/CodeBlock/highlightRanges.ts +1 -1
  397. package/src/CodeBlock/highlightStyles.ts +13 -13
  398. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  399. package/src/ComplexSelector/ComplexSelector.doc.mjs +9 -2
  400. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  401. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  402. package/src/DateInput/DateInput.doc.mjs +17 -1
  403. package/src/DateInput/DateInput.test.tsx +9 -4
  404. package/src/DateInput/DateInput.tsx +54 -3
  405. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  406. package/src/DateInput/MonthScroller.tsx +5 -1
  407. package/src/DateInput/MonthYearWheels.tsx +7 -4
  408. package/src/DateInput/NativeDateField.test.tsx +635 -0
  409. package/src/DateInput/NativeDateField.tsx +641 -0
  410. package/src/DateInput/TouchDateField.tsx +83 -33
  411. package/src/DateInput/Wheel.tsx +1 -0
  412. package/src/DateInput/index.ts +1 -0
  413. package/src/DateInput/nativeDateSegments.ts +127 -0
  414. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -3
  415. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  416. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  417. package/src/DateTimeInput/DateTimeInput.doc.mjs +39 -22
  418. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  419. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  420. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  421. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  422. package/src/Dialog/Dialog.test.tsx +185 -18
  423. package/src/Dialog/Dialog.tsx +35 -11
  424. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  425. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  426. package/src/Field/Field.doc.mjs +1 -1
  427. package/src/Field/FieldLabel.test.tsx +29 -0
  428. package/src/Field/FieldLabel.tsx +7 -0
  429. package/src/Field/InputClearButton.test.tsx +15 -1
  430. package/src/Field/InputClearButton.tsx +28 -4
  431. package/src/FieldStatus/FieldStatus.doc.mjs +1 -1
  432. package/src/FileInput/FileInput.doc.mjs +1 -1
  433. package/src/Heading/Heading.tsx +0 -1
  434. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  435. package/src/HoverCard/HoverCard.test.tsx +154 -4
  436. package/src/HoverCard/HoverCard.tsx +137 -3
  437. package/src/HoverCard/useHoverCard.tsx +23 -3
  438. package/src/Icon/Icon.test.tsx +55 -1
  439. package/src/Icon/Icon.tsx +5 -3
  440. package/src/Icon/defaultIcons.tsx +11 -2
  441. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  442. package/src/Icon/globalIconRegistry.tsx +37 -6
  443. package/src/Icon/index.ts +1 -0
  444. package/src/Icon/useIcon.ts +9 -2
  445. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  446. package/src/Indicator/Indicator.doc.mjs +3 -1
  447. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  448. package/src/Item/Item.tsx +2 -7
  449. package/src/Kbd/Kbd.test.tsx +0 -17
  450. package/src/Kbd/Kbd.tsx +2 -26
  451. package/src/Layer/gestureCounter.ts +57 -0
  452. package/src/Layer/useLayer.test.tsx +368 -16
  453. package/src/Layer/useLayer.tsx +208 -35
  454. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  455. package/src/List/List.test.tsx +38 -0
  456. package/src/List/List.tsx +8 -1
  457. package/src/Markdown/Markdown.test.tsx +37 -0
  458. package/src/Markdown/Markdown.tsx +16 -5
  459. package/src/Markdown/parser.test.ts +33 -0
  460. package/src/Markdown/parser.ts +9 -3
  461. package/src/MetadataList/MetadataList.test.tsx +75 -2
  462. package/src/MetadataList/MetadataListItem.tsx +5 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +23 -2
  464. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  465. package/src/MultiSelector/MultiSelector.tsx +103 -16
  466. package/src/MultiSelector/hooks.ts +9 -2
  467. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  468. package/src/NavIcon/NavIcon.test.tsx +9 -0
  469. package/src/NavIcon/NavIcon.tsx +5 -1
  470. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  471. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  472. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  473. package/src/NumberInput/NumberInput.doc.mjs +27 -8
  474. package/src/NumberInput/NumberInput.test.tsx +563 -8
  475. package/src/NumberInput/NumberInput.tsx +77 -131
  476. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  477. package/src/NumberInput/numberInputCommit.ts +103 -0
  478. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  479. package/src/NumberInput/numberParser.test.ts +222 -0
  480. package/src/NumberInput/numberParser.ts +403 -0
  481. package/src/Outline/Outline.tsx +2 -4
  482. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  483. package/src/OverflowList/OverflowList.test.tsx +550 -4
  484. package/src/OverflowList/OverflowList.tsx +100 -2
  485. package/src/Pagination/Pagination.test.tsx +3 -2
  486. package/src/Popover/Popover.doc.mjs +2 -2
  487. package/src/Popover/Popover.test.tsx +38 -0
  488. package/src/Popover/Popover.tsx +28 -66
  489. package/src/Popover/usePopover.tsx +44 -5
  490. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  491. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  492. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  493. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  494. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  495. package/src/PowerSearch/formatFilterValue.ts +2 -0
  496. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  497. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  498. package/src/ProgressBar/ProgressBar.tsx +28 -8
  499. package/src/RadioList/RadioList.doc.mjs +1 -1
  500. package/src/Resizable/Resizable.doc.mjs +2 -2
  501. package/src/Resizable/useResizable.doc.mjs +21 -2
  502. package/src/Resizable/useResizable.test.ts +421 -0
  503. package/src/Resizable/useResizable.ts +133 -48
  504. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  505. package/src/SelectableCard/SelectableCard.tsx +16 -0
  506. package/src/Selector/Selector.doc.mjs +15 -1
  507. package/src/Selector/Selector.source-build.test.mjs +65 -0
  508. package/src/Selector/Selector.test.tsx +301 -0
  509. package/src/Selector/Selector.tsx +145 -32
  510. package/src/Selector/hooks.ts +17 -2
  511. package/src/SideNav/SideNav.doc.mjs +2 -2
  512. package/src/SideNav/SideNav.test.tsx +1069 -6
  513. package/src/SideNav/SideNav.tsx +109 -38
  514. package/src/SideNav/SideNavHeading.tsx +5 -2
  515. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  516. package/src/SideNav/SideNavItem.tsx +134 -44
  517. package/src/Slider/Slider.doc.mjs +2 -2
  518. package/src/Slider/Slider.test.tsx +106 -1
  519. package/src/Slider/Slider.tsx +52 -1
  520. package/src/Spinner/Spinner.doc.mjs +17 -5
  521. package/src/Spinner/Spinner.test.tsx +164 -0
  522. package/src/Spinner/Spinner.tsx +252 -22
  523. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  524. package/src/StatusDot/StatusDot.test.tsx +9 -0
  525. package/src/StatusDot/StatusDot.tsx +7 -1
  526. package/src/Stepper/Step.doc.mjs +1 -1
  527. package/src/Stepper/Step.tsx +7 -14
  528. package/src/Switch/Switch.doc.mjs +3 -1
  529. package/src/Switch/Switch.test.tsx +10 -0
  530. package/src/Switch/Switch.tsx +3 -0
  531. package/src/Table/BaseTable.tsx +6 -1
  532. package/src/Table/Table.doc.mjs +5 -3
  533. package/src/Table/Table.tsx +3 -8
  534. package/src/Table/TableBody.doc.mjs +2 -2
  535. package/src/Table/TableFooter.doc.mjs +1 -1
  536. package/src/Table/TableHeader.doc.mjs +1 -1
  537. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  538. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  539. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  540. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  541. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  542. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  543. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  544. package/src/Table/useTablePagination.doc.mjs +1 -1
  545. package/src/Table/useTableSelection.doc.mjs +1 -1
  546. package/src/Text/Text.test.tsx +44 -0
  547. package/src/Text/Text.tsx +0 -1
  548. package/src/TextArea/TextArea.doc.mjs +13 -3
  549. package/src/TextArea/TextArea.test.tsx +11 -0
  550. package/src/TextArea/TextArea.tsx +34 -22
  551. package/src/TextInput/TextInput.doc.mjs +1 -1
  552. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  553. package/src/Timestamp/Timestamp.test.tsx +89 -0
  554. package/src/Timestamp/Timestamp.tsx +8 -8
  555. package/src/Timestamp/formatInstant.ts +5 -0
  556. package/src/Toast/Toast.doc.mjs +213 -44
  557. package/src/Toast/Toast.tsx +118 -23
  558. package/src/Toast/ToastViewport.test.tsx +1434 -8
  559. package/src/Toast/ToastViewport.tsx +85 -14
  560. package/src/Toast/index.ts +2 -0
  561. package/src/Toast/types.ts +43 -5
  562. package/src/Toast/useToastGesture.ts +361 -0
  563. package/src/Token/Token.test.tsx +95 -0
  564. package/src/Token/Token.tsx +19 -17
  565. package/src/Token/TokenLink.tsx +12 -3
  566. package/src/Tokenizer/Tokenizer.doc.mjs +17 -4
  567. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  568. package/src/Tokenizer/Tokenizer.tsx +49 -24
  569. package/src/TopNav/TopNavHeading.tsx +2 -2
  570. package/src/TopNav/TopNavItem.tsx +3 -7
  571. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  572. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  573. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  574. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  575. package/src/TopNav/TopNavMenu.tsx +38 -5
  576. package/src/TreeList/TreeList.test.tsx +49 -0
  577. package/src/TreeList/TreeList.tsx +7 -2
  578. package/src/TreeList/TreeListItem.tsx +2 -7
  579. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  580. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  581. package/src/Typeahead/Typeahead.doc.mjs +7 -1
  582. package/src/Typeahead/Typeahead.test.tsx +154 -0
  583. package/src/Typeahead/Typeahead.tsx +9 -0
  584. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  585. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  586. package/src/hooks/useAnnounce.doc.mjs +96 -0
  587. package/src/hooks/useDevWarning.doc.mjs +96 -0
  588. package/src/hooks/useHotkeys.test.ts +0 -18
  589. package/src/hooks/useHotkeys.ts +3 -25
  590. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  591. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  592. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  593. package/src/hooks/useLongPress.doc.mjs +123 -0
  594. package/src/hooks/useOverflow.doc.mjs +58 -17
  595. package/src/hooks/useOverflow.ts +16 -4
  596. package/src/hooks/useTypeahead.doc.mjs +153 -0
  597. package/src/i18n/InternationalizationContext.ts +3 -0
  598. package/src/i18n/InternationalizationProvider.tsx +8 -1
  599. package/src/i18n/__tests__/resolve.test.ts +23 -1
  600. package/src/i18n/resolve.ts +46 -49
  601. package/src/i18n/useTranslator.ts +2 -7
  602. package/src/index.ts +2 -0
  603. package/src/raw-import.d.ts +14 -0
  604. package/src/theme/Theme.test.tsx +104 -2
  605. package/src/theme/Theme.tsx +49 -14
  606. package/src/theme/defineTheme.test.ts +23 -0
  607. package/src/theme/defineTheme.ts +12 -3
  608. package/src/theme/derivedVarRegistry.test.ts +87 -3
  609. package/src/theme/derivedVarRegistry.ts +23 -4
  610. package/src/theme/generateThemeRules.test.ts +99 -1
  611. package/src/theme/generateThemeRules.ts +28 -0
  612. package/src/theme/syntax/tokens.ts +5 -2
  613. package/src/theme/useTheme.test.tsx +10 -0
  614. package/src/theme/useTheme.ts +16 -10
  615. package/src/utils/dateParser.test.ts +34 -2
  616. package/src/utils/dateParser.ts +11 -14
  617. package/src/utils/focusOutline.stylex.ts +50 -0
  618. package/src/utils/interactionOverlay.stylex.ts +74 -0
  619. package/src/utils/isApplePlatform.test.ts +61 -0
  620. package/src/utils/isApplePlatform.ts +37 -0
  621. package/src/utils/plainDate.test.ts +46 -0
  622. package/src/utils/plainDate.ts +18 -3
@@ -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
+ });
@@ -37,6 +37,7 @@ import {TokenLink} from './TokenLink';
37
37
  import type {BaseProps} from '../BaseProps';
38
38
  import {themeProps} from '../utils/themeProps';
39
39
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
40
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
40
41
  import {useTranslator} from '../i18n';
41
42
  import type {TokenColorMap} from './index';
42
43
 
@@ -143,13 +144,6 @@ const styles = stylex.create({
143
144
  transitionProperty: 'background-image',
144
145
  transitionDuration: durationVars['--duration-fast'],
145
146
  transitionTimingFunction: easeVars['--ease-standard'],
146
- backgroundImage: {
147
- default: null,
148
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
149
- '@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
150
- },
151
- ':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
152
- },
153
147
  },
154
148
  disabled: {
155
149
  cursor: 'default',
@@ -307,6 +301,7 @@ export function Token({
307
301
  style,
308
302
  'data-testid': testId,
309
303
  ref,
304
+ ...rest
310
305
  }: TokenProps) {
311
306
  const t = useTranslator();
312
307
  const LinkComponent = useLinkComponent();
@@ -344,8 +339,8 @@ export function Token({
344
339
 
345
340
  const sharedProps = {
346
341
  'data-testid': testId,
347
- 'aria-label': isLabelHidden ? label : undefined,
348
- 'aria-description': description,
342
+ ...(isLabelHidden ? {'aria-label': label} : {}),
343
+ ...(description != null ? {'aria-description': description} : {}),
349
344
  };
350
345
 
351
346
  if (role === 'link') {
@@ -354,8 +349,6 @@ export function Token({
354
349
  <LinkComponent
355
350
  ref={ref as React.Ref<HTMLAnchorElement>}
356
351
  href={href as string}
357
- aria-disabled={isDisabled || undefined}
358
- {...sharedProps}
359
352
  {...mergeProps(
360
353
  themeProps('token', {color, size}),
361
354
  focusOutlineProps.focusVisible(
@@ -363,12 +356,16 @@ export function Token({
363
356
  sizeStyles[size],
364
357
  colorStyles[color],
365
358
  styles.interactive,
359
+ interactionOverlayStyles.backgroundImage,
366
360
  isDisabled && styles.disabled,
367
361
  xstyle,
368
362
  ),
369
363
  className,
370
364
  style,
371
- )}>
365
+ )}
366
+ {...rest}
367
+ {...(isDisabled ? {'aria-disabled': true} : {})}
368
+ {...sharedProps}>
372
369
  {content}
373
370
  </LinkComponent>
374
371
  );
@@ -400,7 +397,6 @@ export function Token({
400
397
  {label}
401
398
  </span>
402
399
  }
403
- {...sharedProps}
404
400
  {...mergeProps(
405
401
  themeProps('token', {color, size}),
406
402
  focusOutlineProps.focusWithin(
@@ -408,12 +404,15 @@ export function Token({
408
404
  sizeStyles[size],
409
405
  colorStyles[color],
410
406
  styles.interactive,
407
+ interactionOverlayStyles.backgroundImage,
411
408
  isDisabled && styles.disabled,
412
409
  xstyle,
413
410
  ),
414
411
  className,
415
412
  style,
416
413
  )}
414
+ {...rest}
415
+ {...sharedProps}
417
416
  />
418
417
  );
419
418
  }
@@ -431,7 +430,6 @@ export function Token({
431
430
  <span
432
431
  ref={ref}
433
432
  onClick={isDisabled ? undefined : handleContainerClick}
434
- {...sharedProps}
435
433
  {...mergeProps(
436
434
  themeProps('token', {color, size}),
437
435
  focusOutlineProps.focusWithin(
@@ -439,12 +437,15 @@ export function Token({
439
437
  sizeStyles[size],
440
438
  colorStyles[color],
441
439
  styles.interactive,
440
+ interactionOverlayStyles.backgroundImage,
442
441
  isDisabled && styles.disabled,
443
442
  xstyle,
444
443
  ),
445
444
  className,
446
445
  style,
447
- )}>
446
+ )}
447
+ {...rest}
448
+ {...sharedProps}>
448
449
  {icon}
449
450
  <button
450
451
  type="button"
@@ -468,7 +469,6 @@ export function Token({
468
469
  return (
469
470
  <span
470
471
  ref={ref}
471
- {...sharedProps}
472
472
  {...mergeProps(
473
473
  themeProps('token', {color, size}),
474
474
  stylex.props(
@@ -480,7 +480,9 @@ export function Token({
480
480
  ),
481
481
  className,
482
482
  style,
483
- )}>
483
+ )}
484
+ {...rest}
485
+ {...sharedProps}>
484
486
  {content}
485
487
  </span>
486
488
  );
@@ -29,6 +29,7 @@ import type {ReactNode, CSSProperties, Ref, HTMLAttributes} from 'react';
29
29
  import {useRef} from 'react';
30
30
  import {useClickableContainer} from '../hooks/useClickableContainer';
31
31
  import type {LinkComponentType} from '../Link/types';
32
+ import {composeEventHandlers} from '../utils';
32
33
 
33
34
  import {useMergedRefs} from '../hooks/useMergedRefs';
34
35
  export interface TokenLinkProps extends HTMLAttributes<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);
@@ -87,9 +90,15 @@ export function TokenLink({
87
90
  return (
88
91
  <span
89
92
  ref={useMergedRefs(ref, containerRef)}
90
- onClick={isDisabled ? undefined : onClick}
91
- onMouseUp={isDisabled ? undefined : onMouseUp}
92
- {...containerProps}>
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>}
@@ -5,7 +5,7 @@
5
5
  export const docs = {
6
6
  name: 'Tokenizer',
7
7
  displayName: 'Tokenizer',
8
- category: 'Data Input',
8
+ category: 'Form Controls',
9
9
  keywords: ["tokenizer","multiselect","multi-select","chips","tags","combobox","autocomplete","taginput","chipinput"],
10
10
  props: [
11
11
  {
@@ -132,7 +132,7 @@ 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
138
  {
@@ -140,6 +140,12 @@ export const docs = {
140
140
  type: 'number',
141
141
  description: 'Fixed dropdown width in pixels. The menu never shrinks below its anchor width.',
142
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
+ },
143
149
  {
144
150
  name: 'emptySearchResultsText',
145
151
  type: 'string',
@@ -386,7 +392,7 @@ export const docsZh = {
386
392
  {
387
393
  name: 'maxMenuItems',
388
394
  type: 'number',
389
- description: '\u4e0b\u62c9\u5217\u8868\u663e\u793a\u7684\u6700\u5927\u9879\u76ee\u6570\u3002',
395
+ description: '下拉列表显示的最大搜索结果数。“创建 ...”条目会在此之外额外提供,因此菜单可能比该数量多显示一项。',
390
396
  default: '10',
391
397
  },
392
398
  {
@@ -394,6 +400,12 @@ export const docsZh = {
394
400
  type: 'number',
395
401
  description: '下拉菜单的固定像素宽度。菜单不会小于其锚点宽度。',
396
402
  },
403
+ {
404
+ name: 'minQueryLength',
405
+ type: 'number',
406
+ description: '查询搜索源前的最小查询长度。低于该长度不会发起搜索,菜单保持关闭;但设置 hasCreate 时仍会提供“创建 ...”条目——该条目由输入的文本推导而来,并非通过搜索获取。',
407
+ default: '1',
408
+ },
397
409
  {
398
410
  name: 'emptySearchResultsText',
399
411
  type: 'string',
@@ -515,8 +527,9 @@ export const docsDense = {
515
527
  isOptional: 'Shows optional indicator on label.',
516
528
  labelTooltip: 'Tooltip on label.',
517
529
  hasEntriesOnFocus: 'Show bootstrap results on focus before typing.',
518
- maxMenuItems: 'Max dropdown items to display.',
530
+ maxMenuItems: 'Max search results shown; the hasCreate entry sits on top of them.',
519
531
  menuWidth: 'Fixed dropdown width in pixels.',
532
+ minQueryLength: 'Min query length before searching. Menu stays closed below it, except the hasCreate entry.',
520
533
  emptySearchResultsText: 'Text when search returns no results.',
521
534
  hasAutoFocus: 'Auto-focus input on mount.',
522
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
@@ -158,6 +158,17 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
158
158
  maxMenuItems?: number;
159
159
  /** Fixed dropdown width in pixels. Never shrinks below the input width. */
160
160
  menuWidth?: number;
161
+ /**
162
+ * Minimum query length before the search source is queried. Below it no
163
+ * search runs and the menu stays closed — useful for remote sources where
164
+ * one or two characters match too much to be worth fetching.
165
+ *
166
+ * With `hasCreate`, the "Create" entry rides on the search results, so it
167
+ * also waits for the threshold.
168
+ *
169
+ * @default 1
170
+ */
171
+ minQueryLength?: number;
161
172
  /** Text shown when no results found. @default 'No results found' */
162
173
  emptySearchResultsText?: string;
163
174
  /** Whether the input is disabled. @default false */
@@ -396,6 +407,7 @@ export function Tokenizer<T extends SearchableItem>({
396
407
  hasEntriesOnFocus,
397
408
  maxMenuItems,
398
409
  menuWidth,
410
+ minQueryLength,
399
411
  emptySearchResultsText,
400
412
  isDisabled = false,
401
413
  htmlName,
@@ -536,36 +548,47 @@ export function Tokenizer<T extends SearchableItem>({
536
548
  () => ({
537
549
  search: async (query: string) => {
538
550
  const results = await searchSource.search(query);
539
- const filtered = results.filter(item => !selectedIds.has(item.id));
540
-
541
- // Append a "Create: X" synthetic item when hasCreate is true,
542
- // the user has typed something, and it doesn't exactly match an
543
- // existing result.
544
- if (hasCreate && query.trim()) {
545
- const trimmed = query.trim();
546
- const alreadyExists =
547
- selectedIds.has(trimmed) ||
548
- filtered.some(
549
- item => item.label.toLowerCase() === trimmed.toLowerCase(),
550
- );
551
- if (!alreadyExists) {
552
- const creatableItem = {
553
- id: `${CREATABLE_ID_PREFIX}${trimmed}`,
554
- label: `Create "${trimmed}"`,
555
- auxiliaryData: {__createdValue: trimmed},
556
- } as unknown as T;
557
- filtered.push(creatableItem);
558
- }
559
- }
560
-
561
- return filtered;
551
+ return results.filter(item => !selectedIds.has(item.id));
562
552
  },
563
553
  bootstrap: async () => {
564
554
  const results = await searchSource.bootstrap();
565
555
  return results.filter(item => !selectedIds.has(item.id));
566
556
  },
567
557
  }),
568
- [searchSource, selectedIds, hasCreate],
558
+ [searchSource, selectedIds],
559
+ );
560
+
561
+ /**
562
+ * The "Create X" entry. It is derived from the typed text, not fetched for
563
+ * it, so it is offered through `__queryEntries` rather than appended to the
564
+ * search results — which is what keeps it available when the query is too
565
+ * short to search. `minQueryLength` is there to avoid a fetch too broad to
566
+ * be worth making; creating `QA` costs no fetch, and a field that can
567
+ * create it should not stop being able to.
568
+ */
569
+ const createEntries = useCallback(
570
+ (query: string, results: T[]): T[] => {
571
+ const trimmed = query.trim();
572
+ if (!hasCreate || trimmed === '') {
573
+ return [];
574
+ }
575
+ const alreadyExists =
576
+ selectedIds.has(trimmed) ||
577
+ results.some(
578
+ item => item.label.toLowerCase() === trimmed.toLowerCase(),
579
+ );
580
+ if (alreadyExists) {
581
+ return [];
582
+ }
583
+ return [
584
+ {
585
+ id: `${CREATABLE_ID_PREFIX}${trimmed}`,
586
+ label: `Create "${trimmed}"`,
587
+ auxiliaryData: {__createdValue: trimmed},
588
+ } as unknown as T,
589
+ ];
590
+ },
591
+ [hasCreate, selectedIds],
569
592
  );
570
593
 
571
594
  const emptySource: SearchSource<T> = useMemo(
@@ -782,6 +805,7 @@ export function Tokenizer<T extends SearchableItem>({
782
805
  hasEntriesOnFocus={isAtMax ? false : hasEntriesOnFocus}
783
806
  maxMenuItems={maxMenuItems}
784
807
  menuWidth={menuWidth}
808
+ minQueryLength={minQueryLength}
785
809
  emptySearchResultsText={emptySearchResultsText}
786
810
  isDisabled={isDisabled}
787
811
  isFocusableDisabled={showsDisabledMessage}
@@ -789,6 +813,7 @@ export function Tokenizer<T extends SearchableItem>({
789
813
  inputId={inputId}
790
814
  ariaDescribedBy={ariaDescribedBy}
791
815
  onChangeQuery={onChangeQuery}
816
+ __queryEntries={createEntries}
792
817
  debounceMs={debounceMs}
793
818
  onKeyDown={handleKeyDown}
794
819
  anchorRef={wrapperRef}
@@ -54,7 +54,7 @@ const styles = stylex.create({
54
54
  minHeight: spacingVars['--spacing-8'],
55
55
  paddingInlineStart: {
56
56
  default: spacingVars['--spacing-2'],
57
- ':has(.astryx-navicon)': 0,
57
+ ':has(.astryx-nav-icon)': 0,
58
58
  },
59
59
  paddingInlineEnd: spacingVars['--spacing-2'],
60
60
  paddingBlock: 0,
@@ -190,7 +190,7 @@ const styles = stylex.create({
190
190
  minHeight: spacingVars['--spacing-8'],
191
191
  paddingInlineStart: {
192
192
  default: spacingVars['--spacing-2'],
193
- ':has(.astryx-navicon)': 0,
193
+ ':has(.astryx-nav-icon)': 0,
194
194
  },
195
195
  paddingInlineEnd: spacingVars['--spacing-2'],
196
196
  paddingBlock: 0,
@@ -36,6 +36,7 @@ import {mergeProps} from '../utils';
36
36
  import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
37
37
  import {themeProps} from '../utils/themeProps';
38
38
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
39
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
39
40
 
40
41
  /**
41
42
  * NavItem styles with hover/selected states
@@ -60,13 +61,6 @@ const styles = stylex.create({
60
61
  transitionProperty: 'background-color, color',
61
62
  transitionDuration: durationVars['--duration-fast'],
62
63
  transitionTimingFunction: easeVars['--ease-standard'],
63
- backgroundColor: {
64
- default: 'transparent',
65
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
66
- '@media (hover: hover)': colorVars['--color-overlay-hover'],
67
- },
68
- ':active': colorVars['--color-overlay-pressed'],
69
- },
70
64
  },
71
65
  selected: {
72
66
  color: colorVars['--color-text-primary'],
@@ -234,6 +228,7 @@ export function TopNavItem({
234
228
  }),
235
229
  focusOutlineProps.focusVisible(
236
230
  navItemStyles.item,
231
+ interactionOverlayStyles.backgroundColor,
237
232
  navItemStyles[size],
238
233
  isSelected && navItemStyles.selected,
239
234
  isDisabled && navItemStyles.disabled,
@@ -270,6 +265,7 @@ export function TopNavItem({
270
265
  }),
271
266
  focusOutlineProps.focusVisible(
272
267
  styles.base,
268
+ interactionOverlayStyles.backgroundColor,
273
269
  isSelected && styles.selected,
274
270
  isDisabled && navItemStyles.disabled,
275
271
  isIconOnly && styles.iconOnly,