@astryxdesign/core 0.5.0 → 0.5.1-canary.f64186a

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 (597) 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/index.d.ts +1 -1
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/theme/Theme.d.ts.map +1 -1
  280. package/dist/theme/Theme.js +46 -10
  281. package/dist/theme/defineTheme.d.ts +9 -3
  282. package/dist/theme/defineTheme.d.ts.map +1 -1
  283. package/dist/theme/defineTheme.js +5 -0
  284. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  285. package/dist/theme/derivedVarRegistry.js +24 -4
  286. package/dist/theme/generateThemeRules.d.ts +21 -0
  287. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  288. package/dist/theme/generateThemeRules.js +26 -0
  289. package/dist/theme/syntax/tokens.d.ts +1 -1
  290. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  291. package/dist/theme/syntax/tokens.js +5 -2
  292. package/dist/theme/useTheme.d.ts.map +1 -1
  293. package/dist/theme/useTheme.js +6 -7
  294. package/dist/utils/dateParser.d.ts +5 -8
  295. package/dist/utils/dateParser.d.ts.map +1 -1
  296. package/dist/utils/dateParser.js +10 -11
  297. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  298. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  299. package/dist/utils/focusOutline.stylex.js +15 -0
  300. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  301. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  302. package/dist/utils/interactionOverlay.stylex.js +42 -0
  303. package/dist/utils/isApplePlatform.d.ts +18 -0
  304. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  305. package/dist/utils/isApplePlatform.js +37 -0
  306. package/dist/utils/plainDate.d.ts +11 -0
  307. package/dist/utils/plainDate.d.ts.map +1 -1
  308. package/dist/utils/plainDate.js +20 -4
  309. package/locales/af-ZA.json +7 -7
  310. package/locales/ar-SA.json +7 -7
  311. package/locales/ca-ES.json +6 -6
  312. package/locales/cs-CZ.json +7 -7
  313. package/locales/da-DK.json +7 -7
  314. package/locales/de-DE.json +7 -7
  315. package/locales/el-GR.json +7 -7
  316. package/locales/en.json +178 -6
  317. package/locales/es-ES.json +6 -6
  318. package/locales/fi-FI.json +7 -7
  319. package/locales/fr-FR.json +7 -7
  320. package/locales/he-IL.json +7 -7
  321. package/locales/hu-HU.json +7 -7
  322. package/locales/it-IT.json +7 -7
  323. package/locales/ja-JP.json +7 -7
  324. package/locales/ko-KR.json +7 -7
  325. package/locales/nl-NL.json +7 -7
  326. package/locales/no-NO.json +7 -7
  327. package/locales/pl-PL.json +7 -7
  328. package/locales/pseudo.json +130 -1
  329. package/locales/pt-BR.json +7 -7
  330. package/locales/pt-PT.json +7 -7
  331. package/locales/ro-RO.json +7 -7
  332. package/locales/ru-RU.json +7 -7
  333. package/locales/sr-SP.json +7 -7
  334. package/locales/sv-SE.json +7 -7
  335. package/locales/tr-TR.json +7 -7
  336. package/locales/uk-UA.json +7 -7
  337. package/locales/vi-VN.json +7 -7
  338. package/locales/zh-CN.json +7 -7
  339. package/locales/zh-TW.json +7 -7
  340. package/package.json +4 -5
  341. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  342. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  343. package/src/AlertDialog/AlertDialog.tsx +62 -20
  344. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  345. package/src/AspectRatio/AspectRatio.tsx +6 -6
  346. package/src/Avatar/Avatar.doc.mjs +12 -2
  347. package/src/Avatar/Avatar.test.tsx +80 -0
  348. package/src/Avatar/Avatar.tsx +64 -14
  349. package/src/Avatar/index.ts +2 -2
  350. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  351. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  352. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  353. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  354. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  355. package/src/Badge/Badge.doc.mjs +3 -2
  356. package/src/Badge/Badge.test.tsx +32 -3
  357. package/src/Badge/Badge.tsx +42 -1
  358. package/src/Banner/Banner.doc.mjs +9 -0
  359. package/src/Banner/Banner.test.tsx +76 -11
  360. package/src/Banner/Banner.tsx +21 -2
  361. package/src/Button/Button.doc.mjs +2 -1
  362. package/src/Button/Button.test.tsx +19 -4
  363. package/src/Button/Button.tsx +9 -29
  364. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  365. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  366. package/src/Calendar/Calendar.doc.mjs +3 -3
  367. package/src/Calendar/Calendar.test.tsx +112 -0
  368. package/src/Calendar/Calendar.tsx +18 -16
  369. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  370. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  371. package/src/Calendar/styles.ts +48 -42
  372. package/src/Card/Card.doc.mjs +10 -7
  373. package/src/Card/Card.test.tsx +113 -19
  374. package/src/Card/Card.tsx +67 -89
  375. package/src/Card/index.ts +36 -1
  376. package/src/Carousel/Carousel.doc.mjs +3 -0
  377. package/src/Carousel/Carousel.test.tsx +360 -0
  378. package/src/Carousel/Carousel.tsx +116 -15
  379. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  380. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  381. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  382. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  383. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  384. package/src/CodeBlock/CodeBlock.tsx +20 -4
  385. package/src/CodeBlock/highlightRanges.ts +1 -1
  386. package/src/CodeBlock/highlightStyles.ts +13 -13
  387. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  388. package/src/ComplexSelector/ComplexSelector.doc.mjs +7 -0
  389. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  390. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  391. package/src/DateInput/DateInput.doc.mjs +16 -0
  392. package/src/DateInput/DateInput.test.tsx +9 -4
  393. package/src/DateInput/DateInput.tsx +54 -3
  394. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  395. package/src/DateInput/MonthScroller.tsx +5 -1
  396. package/src/DateInput/MonthYearWheels.tsx +7 -4
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +83 -33
  400. package/src/DateInput/Wheel.tsx +1 -0
  401. package/src/DateInput/index.ts +1 -0
  402. package/src/DateInput/nativeDateSegments.ts +127 -0
  403. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  404. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  405. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  406. package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
  407. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  408. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  409. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  410. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  411. package/src/Dialog/Dialog.test.tsx +185 -18
  412. package/src/Dialog/Dialog.tsx +35 -11
  413. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  414. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  415. package/src/Field/FieldLabel.test.tsx +29 -0
  416. package/src/Field/FieldLabel.tsx +7 -0
  417. package/src/Field/InputClearButton.test.tsx +15 -1
  418. package/src/Field/InputClearButton.tsx +28 -4
  419. package/src/Heading/Heading.tsx +0 -1
  420. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  421. package/src/HoverCard/HoverCard.test.tsx +154 -4
  422. package/src/HoverCard/HoverCard.tsx +137 -3
  423. package/src/HoverCard/useHoverCard.tsx +23 -3
  424. package/src/Icon/Icon.test.tsx +55 -1
  425. package/src/Icon/Icon.tsx +5 -3
  426. package/src/Icon/defaultIcons.tsx +11 -2
  427. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  428. package/src/Icon/globalIconRegistry.tsx +37 -6
  429. package/src/Icon/index.ts +1 -0
  430. package/src/Icon/useIcon.ts +9 -2
  431. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  432. package/src/Indicator/Indicator.doc.mjs +2 -0
  433. package/src/Item/Item.tsx +2 -7
  434. package/src/Kbd/Kbd.test.tsx +0 -17
  435. package/src/Kbd/Kbd.tsx +2 -26
  436. package/src/Layer/gestureCounter.ts +57 -0
  437. package/src/Layer/useLayer.test.tsx +368 -16
  438. package/src/Layer/useLayer.tsx +208 -35
  439. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  440. package/src/List/List.test.tsx +38 -0
  441. package/src/List/List.tsx +8 -1
  442. package/src/Markdown/Markdown.test.tsx +37 -0
  443. package/src/Markdown/Markdown.tsx +16 -5
  444. package/src/Markdown/parser.test.ts +33 -0
  445. package/src/Markdown/parser.ts +9 -3
  446. package/src/MetadataList/MetadataList.test.tsx +75 -2
  447. package/src/MetadataList/MetadataListItem.tsx +5 -2
  448. package/src/MultiSelector/MultiSelector.doc.mjs +22 -1
  449. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  450. package/src/MultiSelector/MultiSelector.tsx +103 -16
  451. package/src/MultiSelector/hooks.ts +9 -2
  452. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  453. package/src/NavIcon/NavIcon.test.tsx +9 -0
  454. package/src/NavIcon/NavIcon.tsx +5 -1
  455. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  456. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  457. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  458. package/src/NumberInput/NumberInput.doc.mjs +26 -7
  459. package/src/NumberInput/NumberInput.test.tsx +563 -8
  460. package/src/NumberInput/NumberInput.tsx +77 -131
  461. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  462. package/src/NumberInput/numberInputCommit.ts +103 -0
  463. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  464. package/src/NumberInput/numberParser.test.ts +222 -0
  465. package/src/NumberInput/numberParser.ts +403 -0
  466. package/src/Outline/Outline.tsx +2 -4
  467. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  468. package/src/OverflowList/OverflowList.test.tsx +550 -4
  469. package/src/OverflowList/OverflowList.tsx +100 -2
  470. package/src/Pagination/Pagination.test.tsx +3 -2
  471. package/src/Popover/Popover.doc.mjs +2 -2
  472. package/src/Popover/Popover.test.tsx +38 -0
  473. package/src/Popover/Popover.tsx +28 -66
  474. package/src/Popover/usePopover.tsx +44 -5
  475. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  476. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  477. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  478. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  479. package/src/PowerSearch/formatFilterValue.ts +2 -0
  480. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  481. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  482. package/src/ProgressBar/ProgressBar.tsx +28 -8
  483. package/src/Resizable/Resizable.doc.mjs +2 -2
  484. package/src/Resizable/useResizable.doc.mjs +21 -2
  485. package/src/Resizable/useResizable.test.ts +421 -0
  486. package/src/Resizable/useResizable.ts +133 -48
  487. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  488. package/src/SelectableCard/SelectableCard.tsx +16 -0
  489. package/src/Selector/Selector.doc.mjs +14 -0
  490. package/src/Selector/Selector.source-build.test.mjs +65 -0
  491. package/src/Selector/Selector.test.tsx +301 -0
  492. package/src/Selector/Selector.tsx +145 -32
  493. package/src/Selector/hooks.ts +17 -2
  494. package/src/SideNav/SideNav.doc.mjs +2 -2
  495. package/src/SideNav/SideNav.test.tsx +1069 -6
  496. package/src/SideNav/SideNav.tsx +109 -38
  497. package/src/SideNav/SideNavHeading.tsx +5 -2
  498. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  499. package/src/SideNav/SideNavItem.tsx +134 -44
  500. package/src/Slider/Slider.test.tsx +106 -1
  501. package/src/Slider/Slider.tsx +52 -1
  502. package/src/Spinner/Spinner.doc.mjs +17 -5
  503. package/src/Spinner/Spinner.test.tsx +164 -0
  504. package/src/Spinner/Spinner.tsx +252 -22
  505. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  506. package/src/StatusDot/StatusDot.test.tsx +9 -0
  507. package/src/StatusDot/StatusDot.tsx +7 -1
  508. package/src/Stepper/Step.doc.mjs +1 -1
  509. package/src/Stepper/Step.tsx +7 -14
  510. package/src/Switch/Switch.doc.mjs +2 -0
  511. package/src/Switch/Switch.test.tsx +10 -0
  512. package/src/Switch/Switch.tsx +3 -0
  513. package/src/Table/BaseTable.tsx +6 -1
  514. package/src/Table/Table.doc.mjs +5 -3
  515. package/src/Table/Table.tsx +3 -8
  516. package/src/Table/TableBody.doc.mjs +2 -2
  517. package/src/Table/TableFooter.doc.mjs +1 -1
  518. package/src/Table/TableHeader.doc.mjs +1 -1
  519. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  520. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  521. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  522. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  523. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  524. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  525. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  526. package/src/Table/useTablePagination.doc.mjs +1 -1
  527. package/src/Table/useTableSelection.doc.mjs +1 -1
  528. package/src/Text/Text.test.tsx +44 -0
  529. package/src/Text/Text.tsx +0 -1
  530. package/src/TextArea/TextArea.doc.mjs +12 -2
  531. package/src/TextArea/TextArea.test.tsx +11 -0
  532. package/src/TextArea/TextArea.tsx +34 -22
  533. package/src/Timestamp/Timestamp.test.tsx +89 -0
  534. package/src/Timestamp/Timestamp.tsx +8 -8
  535. package/src/Timestamp/formatInstant.ts +5 -0
  536. package/src/Toast/Toast.doc.mjs +213 -44
  537. package/src/Toast/Toast.tsx +118 -23
  538. package/src/Toast/ToastViewport.test.tsx +1434 -8
  539. package/src/Toast/ToastViewport.tsx +85 -14
  540. package/src/Toast/index.ts +2 -0
  541. package/src/Toast/types.ts +43 -5
  542. package/src/Toast/useToastGesture.ts +361 -0
  543. package/src/Token/Token.test.tsx +95 -0
  544. package/src/Token/Token.tsx +19 -17
  545. package/src/Token/TokenLink.tsx +12 -3
  546. package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
  547. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  548. package/src/Tokenizer/Tokenizer.tsx +49 -24
  549. package/src/TopNav/TopNavHeading.tsx +2 -2
  550. package/src/TopNav/TopNavItem.tsx +3 -7
  551. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  552. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  553. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  554. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  555. package/src/TopNav/TopNavMenu.tsx +38 -5
  556. package/src/TreeList/TreeList.test.tsx +49 -0
  557. package/src/TreeList/TreeList.tsx +7 -2
  558. package/src/TreeList/TreeListItem.tsx +2 -7
  559. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  560. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  561. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  562. package/src/Typeahead/Typeahead.test.tsx +154 -0
  563. package/src/Typeahead/Typeahead.tsx +9 -0
  564. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  565. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  566. package/src/hooks/useAnnounce.doc.mjs +96 -0
  567. package/src/hooks/useDevWarning.doc.mjs +96 -0
  568. package/src/hooks/useHotkeys.test.ts +0 -18
  569. package/src/hooks/useHotkeys.ts +3 -25
  570. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  571. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  572. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  573. package/src/hooks/useLongPress.doc.mjs +123 -0
  574. package/src/hooks/useOverflow.doc.mjs +58 -17
  575. package/src/hooks/useOverflow.ts +16 -4
  576. package/src/hooks/useTypeahead.doc.mjs +153 -0
  577. package/src/index.ts +2 -0
  578. package/src/raw-import.d.ts +14 -0
  579. package/src/theme/Theme.test.tsx +104 -2
  580. package/src/theme/Theme.tsx +49 -14
  581. package/src/theme/defineTheme.test.ts +23 -0
  582. package/src/theme/defineTheme.ts +12 -3
  583. package/src/theme/derivedVarRegistry.test.ts +87 -3
  584. package/src/theme/derivedVarRegistry.ts +23 -4
  585. package/src/theme/generateThemeRules.test.ts +99 -1
  586. package/src/theme/generateThemeRules.ts +28 -0
  587. package/src/theme/syntax/tokens.ts +5 -2
  588. package/src/theme/useTheme.test.tsx +10 -0
  589. package/src/theme/useTheme.ts +16 -10
  590. package/src/utils/dateParser.test.ts +34 -2
  591. package/src/utils/dateParser.ts +11 -14
  592. package/src/utils/focusOutline.stylex.ts +50 -0
  593. package/src/utils/interactionOverlay.stylex.ts +74 -0
  594. package/src/utils/isApplePlatform.test.ts +61 -0
  595. package/src/utils/isApplePlatform.ts +37 -0
  596. package/src/utils/plainDate.test.ts +46 -0
  597. package/src/utils/plainDate.ts +18 -3
@@ -29,7 +29,7 @@ import React, {
29
29
  type ReactNode,
30
30
  } from 'react';
31
31
  import * as stylex from '@stylexjs/stylex';
32
- import {usePopover} from '../Popover/usePopover';
32
+ import {usePopoverInternal} from '../Popover/usePopover';
33
33
  import {useTooltip} from '../Tooltip';
34
34
  import {Icon, renderIconSlot, type IconType} from '../Icon';
35
35
  import {useIndicator} from '../Indicator';
@@ -37,7 +37,6 @@ import type {IndicatorPosition} from '../Indicator';
37
37
  import type {IconName} from '../Icon';
38
38
  import {
39
39
  Field,
40
- InputClearButton,
41
40
  inputStatusBorderStyles,
42
41
  inputStatusHoverShadowStyles,
43
42
  inputWrapperStyles,
@@ -45,7 +44,8 @@ import {
45
44
  } from '../Field';
46
45
  import {Divider} from '../Divider';
47
46
  import {layerAnimations} from '../Layer/layerAnimations.stylex';
48
- import type {LayerPlacement} from '../Layer/useLayer';
47
+ import {useKeepLayerOpenProps, type LayerPlacement} from '../Layer/useLayer';
48
+ import {InternalInputClearButton} from '../Field/InputClearButton';
49
49
  import {Spinner} from '../Spinner';
50
50
  import {PanelSearchInput} from '../Field/PanelSearchInput';
51
51
  import {useAnnounce} from '../hooks/useAnnounce';
@@ -80,6 +80,7 @@ import type {BaseProps} from '../BaseProps';
80
80
  import type {SizeValue} from '../utils/types';
81
81
  import {themeProps} from '../utils/themeProps';
82
82
  import {focusOutlineStyles} from '../utils/focusOutline.stylex';
83
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
83
84
  import {stableClassName} from '../naming';
84
85
  import {groupStyles} from '../InputGroup/groupStyles';
85
86
  import {useInputGroup} from '../InputGroup/InputGroupContext';
@@ -217,13 +218,6 @@ const styles = stylex.create({
217
218
  width: 'auto',
218
219
  borderWidth: 0,
219
220
  backgroundColor: 'transparent',
220
- backgroundImage: {
221
- default: null,
222
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
223
- '@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
224
- },
225
- ':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
226
- },
227
221
  boxShadow: {
228
222
  default: 'none',
229
223
  ':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
@@ -395,21 +389,22 @@ const styles = stylex.create({
395
389
  // `--spacing-5` is one line here because `triggerContainer` pins its
396
390
  // line-height to exactly that; the two must stay in step, which is why both
397
391
  // read the same token rather than one hardcoding 20px.
398
- const linePad = (token: string) =>
399
- `calc((${token} - ${spacingVars['--spacing-5']} - 2 * ${borderVars['--border-width']}) / 2)`;
392
+ // Keep these calculations inline: a consumer's Babel preset can lower a
393
+ // module-scope helper to a function expression before StyleX evaluates this
394
+ // object, and StyleX cannot constant-evaluate that transformed helper.
400
395
 
401
396
  const sizeStyles = stylex.create({
402
397
  sm: {
403
398
  minHeight: sizeVars['--size-element-sm'],
404
- paddingBlock: linePad(sizeVars['--size-element-sm']),
399
+ paddingBlock: `calc((${sizeVars['--size-element-sm']} - ${spacingVars['--spacing-5']} - 2 * ${borderVars['--border-width']}) / 2)`,
405
400
  },
406
401
  md: {
407
402
  minHeight: sizeVars['--size-element-md'],
408
- paddingBlock: linePad(sizeVars['--size-element-md']),
403
+ paddingBlock: `calc((${sizeVars['--size-element-md']} - ${spacingVars['--spacing-5']} - 2 * ${borderVars['--border-width']}) / 2)`,
409
404
  },
410
405
  lg: {
411
406
  minHeight: sizeVars['--size-element-lg'],
412
- paddingBlock: linePad(sizeVars['--size-element-lg']),
407
+ paddingBlock: `calc((${sizeVars['--size-element-lg']} - ${spacingVars['--spacing-5']} - 2 * ${borderVars['--border-width']}) / 2)`,
413
408
  },
414
409
  });
415
410
 
@@ -648,6 +643,25 @@ interface SelectorPropsBase<
648
643
  */
649
644
  searchPlaceholder?: string;
650
645
 
646
+ /**
647
+ * Content shown in the panel when there are no options to show, and
648
+ * announced in a polite live region when the panel opens. Not shown while
649
+ * `isLoading` — the options have not arrived yet.
650
+ * @default 'No options'
651
+ */
652
+ emptyText?: ReactNode;
653
+
654
+ /**
655
+ * Content shown in the panel when a search query matches no options, and
656
+ * announced in a polite live region at the same time.
657
+ *
658
+ * The panel message is `role="presentation"`, so the live region is the only
659
+ * route to assistive tech: a string is announced verbatim, a richer node
660
+ * falls back to the default text since it cannot be spoken.
661
+ * @default 'No results found'
662
+ */
663
+ emptySearchText?: ReactNode;
664
+
651
665
  /**
652
666
  * Position placement relative to the trigger.
653
667
  *
@@ -794,6 +808,8 @@ export function Selector<T extends SelectorOptionType>(
794
808
  indicatorPosition = 'end',
795
809
  hasSearch = false,
796
810
  searchPlaceholder: searchPlaceholderFromProps,
811
+ emptyText: emptyTextFromProps,
812
+ emptySearchText: emptySearchTextFromProps,
797
813
  placement,
798
814
  isDefaultOpen = false,
799
815
  'data-testid': testId,
@@ -802,12 +818,16 @@ export function Selector<T extends SelectorOptionType>(
802
818
  className,
803
819
  style,
804
820
  hasClear: hasClearProp,
821
+ id,
805
822
  ...rest
806
823
  } = props as SelectorPropsClearable<T>;
807
824
  const isEffectivelyRequired = useResolvedRequired({isRequired, isOptional});
808
825
  const placeholder = placeholderFromProps ?? t('@astryx.selector.placeholder');
809
826
  const searchPlaceholder =
810
827
  searchPlaceholderFromProps ?? t('@astryx.selector.searchPlaceholder');
828
+ const emptyText = emptyTextFromProps ?? t('@astryx.selector.empty');
829
+ const emptySearchText =
830
+ emptySearchTextFromProps ?? t('@astryx.selector.emptySearchResults');
811
831
  const hasClear = hasClearProp === true;
812
832
  const size = useSize(sizeProp, 'md');
813
833
  const effectiveStatusVariant =
@@ -817,7 +837,10 @@ export function Selector<T extends SelectorOptionType>(
817
837
 
818
838
  // Normalize null to undefined for internal use (null is the clear sentinel)
819
839
  const normalizedValue = value === null ? undefined : value;
820
- const triggerId = useId();
840
+ const generatedTriggerId = useId();
841
+ // A caller's `id` lands on the trigger either way, so the internal identity
842
+ // has to be that same value or the label and listbox point at nothing.
843
+ const triggerId = id ?? generatedTriggerId;
821
844
  const listboxId = useId();
822
845
  const descriptionId = useId();
823
846
  const statusMessageId = useId();
@@ -831,6 +854,9 @@ export function Selector<T extends SelectorOptionType>(
831
854
  const inputGroup = useInputGroup();
832
855
 
833
856
  const [searchQuery, setSearchQuery] = useState('');
857
+ // Mirrors searchQuery for the seed path, which runs before focus reaches the
858
+ // input and so cannot read the rendered state.
859
+ const searchQueryRef = useRef('');
834
860
  // A typed query shows the search row's clear (✕) button, which becomes
835
861
  // the next tab stop after the search input.
836
862
  const hasQuery = searchQuery.length > 0;
@@ -840,6 +866,17 @@ export function Selector<T extends SelectorOptionType>(
840
866
  const isBusy = isLoading || optimisticValue !== normalizedValue;
841
867
  const announce = useAnnounce();
842
868
 
869
+ // The panel's empty message is role="presentation" and reaches assistive tech
870
+ // only through this live region, so the region has to speak whatever the
871
+ // panel shows. A ReactNode override cannot be spoken; fall back to the
872
+ // catalog copy for that case rather than announcing nothing.
873
+ const emptyAnnouncement =
874
+ typeof emptyText === 'string' ? emptyText : t('@astryx.selector.empty');
875
+ const emptySearchAnnouncement =
876
+ typeof emptySearchText === 'string'
877
+ ? emptySearchText
878
+ : t('@astryx.selector.emptySearchResults');
879
+
843
880
  // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
844
881
  // tooltip listeners attach to the trigger container (which already exists)
845
882
  // and the trigger button stays perceivable via aria-disabled instead of the
@@ -907,6 +944,7 @@ export function Selector<T extends SelectorOptionType>(
907
944
  // Layer for dropdown positioning
908
945
  const handleLayerHide = useCallback(() => {
909
946
  setSearchQuery('');
947
+ searchQueryRef.current = '';
910
948
  resetTypeaheadRef.current();
911
949
  // Clear any lingering result count when the popover closes so stale status
912
950
  // text does not linger in the a11y tree.
@@ -914,7 +952,7 @@ export function Selector<T extends SelectorOptionType>(
914
952
  triggerRef.current?.focus();
915
953
  }, [announce]);
916
954
 
917
- const popover = usePopover({
955
+ const popover = usePopoverInternal({
918
956
  onHide: handleLayerHide,
919
957
  hasLightDismiss: true,
920
958
  hasCloseButton: false,
@@ -926,6 +964,7 @@ export function Selector<T extends SelectorOptionType>(
926
964
  // `usePopover` owns — not on the scrolling list inside it.
927
965
  surfaceTarget: 'selector-popup',
928
966
  });
967
+ const keepOpenProps = useKeepLayerOpenProps(popover.id, popover.isOpen);
929
968
 
930
969
  // Open dropdown on mount when isDefaultOpen is true
931
970
  useEffect(() => {
@@ -935,28 +974,76 @@ export function Selector<T extends SelectorOptionType>(
935
974
  // eslint-disable-next-line @eslint-react/exhaustive-deps -- mount-only: isDefaultOpen is not reactive
936
975
  }, []);
937
976
 
938
- // Announce the filtered result count from the query-change handler (matching
977
+ // Announce the filtered result count from the query-change handlers (matching
939
978
  // BaseTypeahead) rather than a reactive effect: computing the count for the
940
979
  // next query here fires the announcement exactly once per keystroke and does
941
- // not re-speak on unrelated re-renders.
942
- const handleSearchChange = useCallback(
980
+ // not re-speak on unrelated re-renders. Split out from handleSearchChange so
981
+ // the type-to-open seed below reaches the same live region — a query the user
982
+ // typed is a query however it arrived.
983
+ const announceSearchResults = useCallback(
943
984
  (nextQuery: string) => {
944
- setSearchQuery(nextQuery);
945
985
  if (nextQuery.length === 0) {
946
986
  // Emptying the query clears the region rather than announcing a count.
947
987
  announce('');
948
988
  return;
949
989
  }
990
+ // While isLoading the panel deliberately shows nothing, so announcing a
991
+ // result would put a claim in the one channel the screen has gone quiet
992
+ // for.
993
+ if (isLoading) {
994
+ announce('');
995
+ return;
996
+ }
950
997
  const count = filterOptionsByQuery(selectableItems, nextQuery).length;
951
998
  announce(
952
999
  count === 0
953
- ? t('@astryx.selector.emptySearchResults')
1000
+ ? emptySearchAnnouncement
954
1001
  : t('@astryx.selector.resultCount', {count}),
955
1002
  );
956
1003
  },
957
- [announce, selectableItems, t],
1004
+ [announce, isLoading, selectableItems, emptySearchAnnouncement, t],
1005
+ );
1006
+
1007
+ const handleSearchChange = useCallback(
1008
+ (nextQuery: string) => {
1009
+ setSearchQuery(nextQuery);
1010
+ searchQueryRef.current = nextQuery;
1011
+ announceSearchResults(nextQuery);
1012
+ },
1013
+ [announceSearchResults],
958
1014
  );
959
1015
 
1016
+ // The panel's empty message is role="presentation", so this region is the
1017
+ // only route to assistive tech. It has to watch the STATE rather than the
1018
+ // open event: the panel can become empty either on open or when a fetch
1019
+ // lands with nothing in it, and an open-only announcement leaves the second
1020
+ // case silent while the message sits on screen. The ref makes it fire once
1021
+ // per arrival at that state rather than on every re-render.
1022
+ const announcedEmptyRef = useRef<string | null>(null);
1023
+ useEffect(() => {
1024
+ const isPanelEmpty =
1025
+ popover.isOpen &&
1026
+ !isLoading &&
1027
+ searchQuery === '' &&
1028
+ selectableItems.length === 0;
1029
+ if (!isPanelEmpty) {
1030
+ announcedEmptyRef.current = null;
1031
+ return;
1032
+ }
1033
+ if (announcedEmptyRef.current === emptyAnnouncement) {
1034
+ return;
1035
+ }
1036
+ announcedEmptyRef.current = emptyAnnouncement;
1037
+ announce(emptyAnnouncement);
1038
+ }, [
1039
+ popover.isOpen,
1040
+ isLoading,
1041
+ searchQuery,
1042
+ selectableItems.length,
1043
+ emptyAnnouncement,
1044
+ announce,
1045
+ ]);
1046
+
960
1047
  // Calculate offset to position selected item over trigger. Explicit
961
1048
  // placement opts out of the selector-specific overlay behavior and uses the
962
1049
  // standard layer positioning API instead.
@@ -992,10 +1079,20 @@ export function Selector<T extends SelectorOptionType>(
992
1079
  }, [onChange, changeAction, startTransition, setOptimisticValue]);
993
1080
 
994
1081
  // Type-to-find appends to the query rather than replacing it: characters
995
- // typed before focus reaches the search input must not be dropped.
996
- const appendSearchQuery = useCallback((char: string) => {
997
- setSearchQuery(query => query + char);
998
- }, []);
1082
+ // typed before focus reaches the search input must not be dropped. The ref
1083
+ // is what makes that safe without a state updater — it advances
1084
+ // synchronously, so a second character seeded in the same tick still sees
1085
+ // the first, and the announcement can be computed here rather than inside a
1086
+ // setState callback.
1087
+ const appendSearchQuery = useCallback(
1088
+ (char: string) => {
1089
+ const nextQuery = searchQueryRef.current + char;
1090
+ searchQueryRef.current = nextQuery;
1091
+ setSearchQuery(nextQuery);
1092
+ announceSearchResults(nextQuery);
1093
+ },
1094
+ [announceSearchResults],
1095
+ );
999
1096
 
1000
1097
  const commitValue = useCallback(
1001
1098
  (newValue: string) => {
@@ -1021,6 +1118,7 @@ export function Selector<T extends SelectorOptionType>(
1021
1118
  onItemMouseEnter,
1022
1119
  } = useCombobox({
1023
1120
  selectableItems: filteredItems,
1121
+ wasJustDismissed: popover.wasJustDismissed,
1024
1122
  // The optimistic value, not the raw prop: with a pending changeAction the
1025
1123
  // prop still holds the old selection, so the popup would open with the
1026
1124
  // highlight on it and Delete/Backspace could clear a value the action has
@@ -1313,8 +1411,11 @@ export function Selector<T extends SelectorOptionType>(
1313
1411
  const renderOptions = useCallback(() => {
1314
1412
  const isSearching = hasSearch && Boolean(searchQuery);
1315
1413
 
1316
- // Nothing matched across every group/option: show the empty state.
1317
- if (isSearching && filteredItems.length === 0) {
1414
+ // Nothing to show — either the query matched nothing, or no options were
1415
+ // given at all. Both render the same slot with different copy. While
1416
+ // isLoading the options have not arrived yet, so asserting either would be
1417
+ // a claim the component cannot make; the trigger's spinner covers it.
1418
+ if (filteredItems.length === 0 && !isLoading) {
1318
1419
  // role="presentation" keeps the message out of the listbox's
1319
1420
  // accessibility tree (role="listbox" only permits option/group
1320
1421
  // children); the no-results outcome is announced via the
@@ -1327,7 +1428,7 @@ export function Selector<T extends SelectorOptionType>(
1327
1428
  themeProps('selector-empty-state'),
1328
1429
  stylex.props(styles.emptyState),
1329
1430
  )}>
1330
- No results found
1431
+ {isSearching ? emptySearchText : emptyText}
1331
1432
  </div>,
1332
1433
  ];
1333
1434
  }
@@ -1401,7 +1502,16 @@ export function Selector<T extends SelectorOptionType>(
1401
1502
  }
1402
1503
 
1403
1504
  return elements;
1404
- }, [options, renderItem, hasSearch, searchQuery, filteredItems]);
1505
+ }, [
1506
+ options,
1507
+ renderItem,
1508
+ hasSearch,
1509
+ searchQuery,
1510
+ filteredItems,
1511
+ isLoading,
1512
+ emptyText,
1513
+ emptySearchText,
1514
+ ]);
1405
1515
 
1406
1516
  // The detached message box renders its own leading status icon, so the
1407
1517
  // on-field icon would duplicate it — keep the chevron indicator instead.
@@ -1469,6 +1579,7 @@ export function Selector<T extends SelectorOptionType>(
1469
1579
  styles.triggerContainer,
1470
1580
  sizeStyles[size],
1471
1581
  variant === 'ghost' && styles.triggerGhost,
1582
+ variant === 'ghost' && interactionOverlayStyles.backgroundImage,
1472
1583
  variant === 'ghost' && focusOutlineStyles.focusWithin,
1473
1584
  isDisabled && inputWrapperStyles.disabled,
1474
1585
  variant === 'ghost' && isDisabled && styles.triggerGhostDisabled,
@@ -1539,7 +1650,8 @@ export function Selector<T extends SelectorOptionType>(
1539
1650
  )}
1540
1651
  {isBusy && <Spinner size="sm" />}
1541
1652
  {hasClear && value != null && !isDisabled && (
1542
- <InputClearButton
1653
+ <InternalInputClearButton
1654
+ {...keepOpenProps}
1543
1655
  label={t('@astryx.selector.clearLabel', {label})}
1544
1656
  onClick={handleClear}
1545
1657
  iconClassName={stableClassName('selector-clear-icon')}
@@ -1558,6 +1670,7 @@ export function Selector<T extends SelectorOptionType>(
1558
1670
  type="button"
1559
1671
  aria-label={t(STATUS_BUTTON_LABEL_KEY[status.type])}
1560
1672
  aria-describedby={statusTooltip.describedBy}
1673
+ {...keepOpenProps}
1561
1674
  onClick={e => e.stopPropagation()}
1562
1675
  {...stylex.props(
1563
1676
  focusOutlineStyles.focusVisible,
@@ -176,6 +176,12 @@ interface UseComboboxOptions {
176
176
  * lands in the search input, which then owns its own typing.
177
177
  */
178
178
  onSearchSeed?: (char: string) => void;
179
+ /**
180
+ * Whether the browser's light dismiss just closed the popup. The trigger
181
+ * click that follows belongs to that same press, so acting on it would
182
+ * reopen the popup the user just closed.
183
+ */
184
+ wasJustDismissed?: () => boolean;
179
185
  listboxId: string;
180
186
  }
181
187
 
@@ -208,6 +214,7 @@ export function useCombobox({
208
214
  onSelect,
209
215
  onClear,
210
216
  onSearchSeed,
217
+ wasJustDismissed,
211
218
  listboxId,
212
219
  }: UseComboboxOptions): UseComboboxResult {
213
220
  const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
@@ -244,7 +251,7 @@ export function useCombobox({
244
251
  );
245
252
 
246
253
  const onTriggerClick = useCallback(() => {
247
- if (isDisabled) {
254
+ if (isDisabled || wasJustDismissed?.()) {
248
255
  return;
249
256
  }
250
257
  if (isOpen) {
@@ -256,7 +263,15 @@ export function useCombobox({
256
263
  setHighlightedIndex(selectedIndex >= 0 ? selectedIndex : 0);
257
264
  }
258
265
  }
259
- }, [isDisabled, isOpen, onOpen, closeAndReset, findSelectedIndex, hasSearch]);
266
+ }, [
267
+ isDisabled,
268
+ wasJustDismissed,
269
+ isOpen,
270
+ onOpen,
271
+ closeAndReset,
272
+ findSelectedIndex,
273
+ hasSearch,
274
+ ]);
260
275
 
261
276
  const onItemMouseEnter = useCallback(
262
277
  (item: SelectorOptionData, index: number) => {
@@ -104,8 +104,8 @@ export const docs = {
104
104
  },
105
105
  {
106
106
  name: 'resizable',
107
- type: 'boolean | { defaultWidth?: number; minWidth?: number; maxWidth?: number; autoSaveId?: string; onWidthChange?: (width: number) => void }',
108
- description: 'Enables a resize handle at the inline-end edge. true for defaults (260px initial, 180-480px range), or a ResizableConfig object (defaultWidth, minWidth, maxWidth, autoSaveId for localStorage persistence, onWidthChange). The handle is hidden while collapsed.',
107
+ type: 'boolean | { defaultWidth?: number; minWidth?: number; maxWidth?: number; autoSaveId?: string; onWidthChange?: (width: number) => void; defaultIsCollapsed?: boolean; isCollapsed?: boolean; onCollapseChange?: (isCollapsed: boolean) => void }',
108
+ description: 'Enables a resize handle at the inline-end edge. true for defaults (260px initial, 180-480px range), or a ResizableConfig object (defaultWidth, minWidth, maxWidth, autoSaveId for localStorage persistence of width and collapse state, onWidthChange). It can also own collapse state (defaultIsCollapsed, isCollapsed + onCollapseChange); when both props carry collapse state, resizable wins and a dev warning names the conflicting keys. The handle is hidden while collapsed.',
109
109
  default: 'false',
110
110
  },
111
111
  {