@astryxdesign/core 0.4.7 → 0.5.0-canary.055e75f

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 +161 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +3 -2
  7. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  8. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  9. package/dist/AspectRatio/AspectRatio.js +23 -4
  10. package/dist/Avatar/Avatar.d.ts +25 -1
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +58 -19
  13. package/dist/Avatar/index.d.ts +2 -2
  14. package/dist/Avatar/index.d.ts.map +1 -1
  15. package/dist/Avatar/index.js +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  17. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  19. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  20. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  21. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  22. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  23. package/dist/Banner/Banner.d.ts +40 -15
  24. package/dist/Banner/Banner.d.ts.map +1 -1
  25. package/dist/Banner/Banner.js +51 -18
  26. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  27. package/dist/BottomSheet/BottomSheet.js +17 -4
  28. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  29. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  30. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  31. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  32. package/dist/Button/Button.d.ts.map +1 -1
  33. package/dist/Button/Button.js +11 -6
  34. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  35. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  36. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  37. package/dist/Calendar/Calendar.d.ts +3 -1
  38. package/dist/Calendar/Calendar.d.ts.map +1 -1
  39. package/dist/Calendar/Calendar.js +14 -15
  40. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  41. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  42. package/dist/Calendar/getInitialFocusDate.js +62 -0
  43. package/dist/Calendar/styles.d.ts +5 -14
  44. package/dist/Calendar/styles.d.ts.map +1 -1
  45. package/dist/Calendar/styles.js +15 -15
  46. package/dist/Card/Card.d.ts +6 -9
  47. package/dist/Card/Card.d.ts.map +1 -1
  48. package/dist/Card/Card.js +6 -6
  49. package/dist/Carousel/Carousel.d.ts.map +1 -1
  50. package/dist/Carousel/Carousel.js +3 -3
  51. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  52. package/dist/Chat/ChatComposerInput.js +2 -3
  53. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  54. package/dist/Chat/ChatLayout.js +3 -3
  55. package/dist/Chat/ChatMessageList.d.ts +22 -3
  56. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  57. package/dist/Chat/ChatMessageList.js +6 -3
  58. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  59. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  60. package/dist/Chat/ChatTokenizedText.js +11 -6
  61. package/dist/Chat/useChatComposerTokens.js +1 -1
  62. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  63. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  64. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  65. package/dist/ClickableCard/ClickableCard.js +3 -3
  66. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  67. package/dist/CodeBlock/CodeBlock.js +15 -4
  68. package/dist/CodeBlock/highlightRanges.js +1 -1
  69. package/dist/CodeBlock/highlightStyles.js +13 -13
  70. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  71. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  72. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  73. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  74. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  75. package/dist/ContextMenu/ContextMenu.js +4 -3
  76. package/dist/DateInput/DateInput.d.ts +43 -0
  77. package/dist/DateInput/DateInput.d.ts.map +1 -1
  78. package/dist/DateInput/DateInput.js +22 -2
  79. package/dist/DateInput/NativeDateField.d.ts +10 -0
  80. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  81. package/dist/DateInput/NativeDateField.js +494 -0
  82. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  83. package/dist/DateInput/TouchDateField.js +82 -23
  84. package/dist/DateInput/index.d.ts +1 -1
  85. package/dist/DateInput/index.d.ts.map +1 -1
  86. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  87. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  88. package/dist/DateInput/nativeDateSegments.js +111 -0
  89. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  90. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  91. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  92. package/dist/DateTimeInput/index.d.ts +1 -1
  93. package/dist/DateTimeInput/index.d.ts.map +1 -1
  94. package/dist/Dialog/Dialog.d.ts +21 -1
  95. package/dist/Dialog/Dialog.d.ts.map +1 -1
  96. package/dist/Dialog/Dialog.js +110 -58
  97. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  98. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  99. package/dist/Field/FieldLabel.d.ts.map +1 -1
  100. package/dist/Field/FieldLabel.js +9 -1
  101. package/dist/FileInput/FileInput.d.ts.map +1 -1
  102. package/dist/FileInput/FileInput.js +3 -2
  103. package/dist/Heading/Heading.d.ts.map +1 -1
  104. package/dist/Heading/Heading.js +6 -2
  105. package/dist/HoverCard/HoverCard.d.ts +6 -0
  106. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  107. package/dist/HoverCard/HoverCard.js +104 -3
  108. package/dist/HoverCard/useHoverCard.d.ts +19 -2
  109. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  110. package/dist/HoverCard/useHoverCard.js +74 -26
  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 +4 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -19
  117. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  118. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  119. package/dist/Layer/LayerDepthContext.js +66 -0
  120. package/dist/Layer/index.d.ts +3 -0
  121. package/dist/Layer/index.d.ts.map +1 -1
  122. package/dist/Layer/index.js +4 -0
  123. package/dist/Layer/layerStack.d.ts +98 -0
  124. package/dist/Layer/layerStack.d.ts.map +1 -0
  125. package/dist/Layer/layerStack.js +306 -0
  126. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  127. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  128. package/dist/Layer/useLayerDismissal.js +91 -0
  129. package/dist/Lightbox/Lightbox.d.ts +1 -0
  130. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  131. package/dist/Lightbox/Lightbox.js +103 -81
  132. package/dist/Markdown/Markdown.d.ts.map +1 -1
  133. package/dist/Markdown/Markdown.js +9 -4
  134. package/dist/Markdown/index.d.ts +1 -1
  135. package/dist/Markdown/index.d.ts.map +1 -1
  136. package/dist/Markdown/parser.d.ts +38 -1
  137. package/dist/Markdown/parser.d.ts.map +1 -1
  138. package/dist/Markdown/parser.js +182 -32
  139. package/dist/MobileNav/MobileNav.d.ts +6 -1
  140. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  141. package/dist/MobileNav/MobileNav.js +61 -36
  142. package/dist/MultiSelector/MultiSelector.d.ts +32 -1
  143. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  144. package/dist/MultiSelector/MultiSelector.js +63 -11
  145. package/dist/MultiSelector/index.d.ts +1 -1
  146. package/dist/MultiSelector/index.d.ts.map +1 -1
  147. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  148. package/dist/NavIcon/NavIcon.js +5 -1
  149. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  150. package/dist/NavMenu/NavHeadingMenu.js +3 -2
  151. package/dist/NumberInput/NumberInput.d.ts +6 -1
  152. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  153. package/dist/NumberInput/NumberInput.js +54 -104
  154. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  155. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  156. package/dist/NumberInput/numberInputCommit.js +71 -0
  157. package/dist/NumberInput/numberParser.d.ts +64 -0
  158. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  159. package/dist/NumberInput/numberParser.js +350 -0
  160. package/dist/Outline/Outline.d.ts.map +1 -1
  161. package/dist/Outline/Outline.js +3 -2
  162. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  163. package/dist/OverflowList/OverflowList.js +3 -2
  164. package/dist/Overlay/Overlay.d.ts.map +1 -1
  165. package/dist/Overlay/Overlay.js +3 -2
  166. package/dist/Popover/usePopover.d.ts.map +1 -1
  167. package/dist/Popover/usePopover.js +20 -17
  168. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  169. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearch.js +19 -6
  171. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  172. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  173. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  174. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  175. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  176. package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
  177. package/dist/PowerSearch/types.d.ts +2 -0
  178. package/dist/PowerSearch/types.d.ts.map +1 -1
  179. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  180. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  181. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  182. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  183. package/dist/ProgressBar/ProgressBar.js +18 -5
  184. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  185. package/dist/Resizable/ResizeHandle.js +3 -2
  186. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  187. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  188. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  189. package/dist/SelectableCard/SelectableCard.js +3 -3
  190. package/dist/Selector/Selector.d.ts +17 -0
  191. package/dist/Selector/Selector.d.ts.map +1 -1
  192. package/dist/Selector/Selector.js +81 -14
  193. package/dist/SideNav/SideNav.d.ts.map +1 -1
  194. package/dist/SideNav/SideNav.js +4 -3
  195. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  196. package/dist/SideNav/SideNavHeading.js +8 -7
  197. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  198. package/dist/SideNav/SideNavItem.js +4 -3
  199. package/dist/Slider/Slider.d.ts.map +1 -1
  200. package/dist/Slider/Slider.js +37 -5
  201. package/dist/Spinner/Spinner.d.ts +3 -3
  202. package/dist/Spinner/Spinner.d.ts.map +1 -1
  203. package/dist/Spinner/Spinner.js +130 -78
  204. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  205. package/dist/StatusDot/StatusDot.js +6 -1
  206. package/dist/Stepper/Step.d.ts +140 -0
  207. package/dist/Stepper/Step.d.ts.map +1 -0
  208. package/dist/Stepper/Step.js +1045 -0
  209. package/dist/Stepper/StepStatus.d.ts +24 -0
  210. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  211. package/dist/Stepper/StepStatus.js +1 -0
  212. package/dist/Stepper/Stepper.d.ts +93 -0
  213. package/dist/Stepper/Stepper.d.ts.map +1 -0
  214. package/dist/Stepper/Stepper.js +184 -0
  215. package/dist/Stepper/StepperContext.d.ts +41 -0
  216. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  217. package/dist/Stepper/StepperContext.js +34 -0
  218. package/dist/Stepper/index.d.ts +8 -0
  219. package/dist/Stepper/index.d.ts.map +1 -0
  220. package/dist/Stepper/index.js +7 -0
  221. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  222. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  223. package/dist/Stepper/stepper.stylex.js +20 -0
  224. package/dist/Switch/Switch.d.ts.map +1 -1
  225. package/dist/Switch/Switch.js +8 -3
  226. package/dist/TabList/Tab.d.ts +15 -2
  227. package/dist/TabList/Tab.d.ts.map +1 -1
  228. package/dist/TabList/Tab.js +32 -7
  229. package/dist/TabList/TabList.d.ts +46 -7
  230. package/dist/TabList/TabList.d.ts.map +1 -1
  231. package/dist/TabList/TabList.js +353 -23
  232. package/dist/TabList/TabListContext.d.ts +11 -1
  233. package/dist/TabList/TabListContext.d.ts.map +1 -1
  234. package/dist/TabList/TabListContext.js +11 -2
  235. package/dist/TabList/TabMenu.d.ts.map +1 -1
  236. package/dist/TabList/TabMenu.js +3 -2
  237. package/dist/TabList/index.d.ts +2 -2
  238. package/dist/TabList/index.d.ts.map +1 -1
  239. package/dist/Table/BaseTable.d.ts.map +1 -1
  240. package/dist/Table/BaseTable.js +10 -2
  241. package/dist/Table/Table.d.ts.map +1 -1
  242. package/dist/Table/Table.js +3 -6
  243. package/dist/Table/TableRow.d.ts +16 -5
  244. package/dist/Table/TableRow.d.ts.map +1 -1
  245. package/dist/Table/TableRow.js +16 -5
  246. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  247. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  248. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  249. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  250. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  251. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  252. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  253. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  254. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  255. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  256. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  257. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  258. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  259. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  260. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  261. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  262. package/dist/Table/types.d.ts +22 -4
  263. package/dist/Table/types.d.ts.map +1 -1
  264. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  265. package/dist/Table/useBaseTablePlugins.js +5 -0
  266. package/dist/Text/Text.d.ts.map +1 -1
  267. package/dist/Text/Text.js +6 -2
  268. package/dist/TextArea/TextArea.d.ts.map +1 -1
  269. package/dist/TextArea/TextArea.js +9 -3
  270. package/dist/TextInput/TextInput.d.ts.map +1 -1
  271. package/dist/TextInput/TextInput.js +3 -2
  272. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  273. package/dist/TimeInput/TimeInput.js +3 -2
  274. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  275. package/dist/Timestamp/Timestamp.js +5 -3
  276. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  277. package/dist/Toast/ToastViewport.js +27 -8
  278. package/dist/Token/TokenLink.d.ts.map +1 -1
  279. package/dist/Token/TokenLink.js +2 -2
  280. package/dist/Tokenizer/Tokenizer.d.ts +3 -1
  281. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  282. package/dist/Tokenizer/Tokenizer.js +2 -0
  283. package/dist/Tooltip/Tooltip.d.ts +5 -0
  284. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  285. package/dist/Tooltip/useTooltip.d.ts +5 -0
  286. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  287. package/dist/Tooltip/useTooltip.js +39 -24
  288. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  289. package/dist/TopNav/TopNavHeading.js +5 -4
  290. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  291. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  292. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  293. package/dist/TopNav/TopNavMenu.js +4 -3
  294. package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
  295. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  296. package/dist/Typeahead/BaseTypeahead.js +68 -29
  297. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  298. package/dist/Typeahead/Typeahead.js +3 -2
  299. package/dist/astryx.css +98 -7
  300. package/dist/hooks/index.d.ts +1 -0
  301. package/dist/hooks/index.d.ts.map +1 -1
  302. package/dist/hooks/index.js +1 -0
  303. package/dist/hooks/useFocusTrap.d.ts +7 -4
  304. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  305. package/dist/hooks/useFocusTrap.js +60 -95
  306. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  307. package/dist/hooks/useHotkeys.js +3 -18
  308. package/dist/hooks/useMergedRefs.d.ts +18 -0
  309. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  310. package/dist/hooks/useMergedRefs.js +25 -0
  311. package/dist/index.d.ts +1 -0
  312. package/dist/index.d.ts.map +1 -1
  313. package/dist/index.js +1 -0
  314. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  315. package/dist/theme/derivedVarRegistry.js +24 -4
  316. package/dist/theme/syntax/tokens.d.ts +1 -1
  317. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  318. package/dist/theme/syntax/tokens.js +5 -2
  319. package/dist/utils/groupItems.d.ts +5 -1
  320. package/dist/utils/groupItems.d.ts.map +1 -1
  321. package/dist/utils/groupItems.js +9 -9
  322. package/dist/utils/index.d.ts +1 -1
  323. package/dist/utils/index.d.ts.map +1 -1
  324. package/dist/utils/isApplePlatform.d.ts +18 -0
  325. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  326. package/dist/utils/isApplePlatform.js +37 -0
  327. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  328. package/dist/utils/sharedResizeObserver.js +10 -1
  329. package/dist/utils/timeParser.d.ts +1 -1
  330. package/dist/utils/timeParser.d.ts.map +1 -1
  331. package/dist/utils/timeParser.js +26 -12
  332. package/locales/en.json +154 -10
  333. package/locales/pseudo.json +108 -0
  334. package/package.json +8 -3
  335. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  336. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  337. package/src/AlertDialog/AlertDialog.tsx +62 -20
  338. package/src/AppShell/AppShell.tsx +3 -2
  339. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  340. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  341. package/src/AspectRatio/AspectRatio.tsx +40 -1
  342. package/src/Avatar/Avatar.doc.mjs +14 -3
  343. package/src/Avatar/Avatar.test.tsx +97 -0
  344. package/src/Avatar/Avatar.tsx +125 -52
  345. package/src/Avatar/index.ts +2 -2
  346. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  347. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  348. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  349. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  350. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  351. package/src/Banner/Banner.doc.mjs +13 -11
  352. package/src/Banner/Banner.test.tsx +102 -15
  353. package/src/Banner/Banner.tsx +72 -25
  354. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  355. package/src/BottomSheet/BottomSheet.tsx +17 -4
  356. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  357. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  358. package/src/Button/Button.doc.mjs +24 -1
  359. package/src/Button/Button.test.tsx +32 -4
  360. package/src/Button/Button.tsx +12 -5
  361. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  362. package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
  363. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  364. package/src/Calendar/Calendar.doc.mjs +4 -3
  365. package/src/Calendar/Calendar.test.tsx +103 -0
  366. package/src/Calendar/Calendar.tsx +19 -16
  367. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  368. package/src/Calendar/getInitialFocusDate.ts +93 -0
  369. package/src/Calendar/styles.ts +49 -31
  370. package/src/Card/Card.doc.mjs +10 -7
  371. package/src/Card/Card.test.tsx +44 -19
  372. package/src/Card/Card.tsx +12 -32
  373. package/src/Carousel/Carousel.tsx +3 -2
  374. package/src/Chat/ChatComposerInput.tsx +5 -1
  375. package/src/Chat/ChatLayout.tsx +3 -2
  376. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  377. package/src/Chat/ChatMessageList.test.tsx +46 -0
  378. package/src/Chat/ChatMessageList.tsx +28 -4
  379. package/src/Chat/ChatTokenizedText.tsx +17 -10
  380. package/src/Chat/useChatComposerTokens.ts +1 -1
  381. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  382. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  383. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  384. package/src/ClickableCard/ClickableCard.tsx +3 -2
  385. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  386. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  387. package/src/CodeBlock/CodeBlock.tsx +20 -4
  388. package/src/CodeBlock/highlightRanges.ts +1 -1
  389. package/src/CodeBlock/highlightStyles.ts +13 -13
  390. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  391. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  392. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  393. package/src/ContextMenu/ContextMenu.tsx +4 -3
  394. package/src/DateInput/DateInput.doc.mjs +16 -0
  395. package/src/DateInput/DateInput.tsx +55 -2
  396. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +108 -24
  400. package/src/DateInput/index.ts +1 -0
  401. package/src/DateInput/nativeDateSegments.ts +127 -0
  402. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  403. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  404. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  405. package/src/DateTimeInput/index.ts +1 -0
  406. package/src/Dialog/Dialog.doc.mjs +8 -3
  407. package/src/Dialog/Dialog.test.tsx +429 -2
  408. package/src/Dialog/Dialog.tsx +133 -58
  409. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  410. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  411. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  412. package/src/Field/Field.doc.mjs +13 -2
  413. package/src/Field/FieldLabel.test.tsx +29 -0
  414. package/src/Field/FieldLabel.tsx +7 -0
  415. package/src/FileInput/FileInput.tsx +3 -2
  416. package/src/Heading/Heading.test.tsx +23 -1
  417. package/src/Heading/Heading.tsx +6 -2
  418. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  419. package/src/HoverCard/HoverCard.test.tsx +154 -4
  420. package/src/HoverCard/HoverCard.tsx +143 -3
  421. package/src/HoverCard/useHoverCard.tsx +104 -33
  422. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  423. package/src/Indicator/Indicator.doc.mjs +2 -0
  424. package/src/Item/Item.tsx +5 -4
  425. package/src/Kbd/Kbd.tsx +2 -19
  426. package/src/Layer/LayerDepthContext.tsx +62 -0
  427. package/src/Layer/index.ts +9 -0
  428. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  429. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  430. package/src/Layer/layerStack.ts +362 -0
  431. package/src/Layer/useLayer.test.tsx +62 -14
  432. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  433. package/src/Layer/useLayerDismissal.ts +173 -0
  434. package/src/Layout/Layout.doc.mjs +2 -2
  435. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  436. package/src/Lightbox/Lightbox.tsx +124 -102
  437. package/src/Link/Link.doc.mjs +39 -0
  438. package/src/Markdown/Markdown.doc.mjs +5 -0
  439. package/src/Markdown/Markdown.tsx +9 -4
  440. package/src/Markdown/incremental.test.ts +16 -2
  441. package/src/Markdown/index.ts +1 -0
  442. package/src/Markdown/parser.perf.test.ts +96 -1
  443. package/src/Markdown/parser.test.ts +178 -2
  444. package/src/Markdown/parser.ts +253 -32
  445. package/src/MobileNav/MobileNav.tsx +62 -36
  446. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  447. package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
  448. package/src/MultiSelector/MultiSelector.test.tsx +277 -0
  449. package/src/MultiSelector/MultiSelector.tsx +142 -11
  450. package/src/MultiSelector/index.ts +1 -0
  451. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  452. package/src/NavIcon/NavIcon.test.tsx +9 -0
  453. package/src/NavIcon/NavIcon.tsx +5 -1
  454. package/src/NavMenu/NavHeadingMenu.tsx +3 -2
  455. package/src/NumberInput/NumberInput.doc.mjs +31 -7
  456. package/src/NumberInput/NumberInput.test.tsx +436 -8
  457. package/src/NumberInput/NumberInput.tsx +62 -114
  458. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  459. package/src/NumberInput/numberInputCommit.ts +103 -0
  460. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  461. package/src/NumberInput/numberParser.test.ts +222 -0
  462. package/src/NumberInput/numberParser.ts +403 -0
  463. package/src/Outline/Outline.tsx +3 -2
  464. package/src/OverflowList/OverflowList.tsx +3 -2
  465. package/src/Overlay/Overlay.tsx +3 -2
  466. package/src/Pagination/Pagination.test.tsx +3 -2
  467. package/src/Popover/usePopover.tsx +31 -28
  468. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  469. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  470. package/src/PowerSearch/PowerSearch.tsx +34 -5
  471. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
  472. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  473. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
  474. package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
  475. package/src/PowerSearch/types.ts +2 -0
  476. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  477. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  478. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  479. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  480. package/src/ProgressBar/ProgressBar.tsx +28 -8
  481. package/src/Resizable/ResizeHandle.tsx +3 -2
  482. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  483. package/src/SelectableCard/SelectableCard.tsx +3 -2
  484. package/src/Selector/Selector.doc.mjs +26 -1
  485. package/src/Selector/Selector.test.tsx +311 -1
  486. package/src/Selector/Selector.tsx +139 -16
  487. package/src/SideNav/SideNav.doc.mjs +6 -6
  488. package/src/SideNav/SideNav.tsx +4 -2
  489. package/src/SideNav/SideNavHeading.tsx +12 -12
  490. package/src/SideNav/SideNavItem.tsx +4 -2
  491. package/src/Slider/Slider.test.tsx +106 -1
  492. package/src/Slider/Slider.tsx +55 -3
  493. package/src/Spinner/Spinner.test.tsx +147 -1
  494. package/src/Spinner/Spinner.tsx +120 -101
  495. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  496. package/src/StatusDot/StatusDot.test.tsx +9 -0
  497. package/src/StatusDot/StatusDot.tsx +7 -1
  498. package/src/Stepper/Step.doc.mjs +98 -0
  499. package/src/Stepper/Step.tsx +1638 -0
  500. package/src/Stepper/StepStatus.ts +26 -0
  501. package/src/Stepper/Stepper.doc.mjs +370 -0
  502. package/src/Stepper/Stepper.test.tsx +1024 -0
  503. package/src/Stepper/Stepper.tsx +258 -0
  504. package/src/Stepper/StepperContext.ts +71 -0
  505. package/src/Stepper/index.ts +18 -0
  506. package/src/Stepper/stepper.stylex.ts +19 -0
  507. package/src/Switch/Switch.doc.mjs +2 -0
  508. package/src/Switch/Switch.test.tsx +10 -0
  509. package/src/Switch/Switch.tsx +6 -2
  510. package/src/TabList/Tab.doc.mjs +13 -1
  511. package/src/TabList/Tab.tsx +67 -7
  512. package/src/TabList/TabList.doc.mjs +22 -6
  513. package/src/TabList/TabList.test.tsx +559 -0
  514. package/src/TabList/TabList.tsx +490 -22
  515. package/src/TabList/TabListContext.ts +13 -2
  516. package/src/TabList/TabMenu.tsx +3 -2
  517. package/src/TabList/index.ts +6 -2
  518. package/src/Table/BaseTable.tsx +12 -4
  519. package/src/Table/Table.doc.mjs +9 -2
  520. package/src/Table/Table.test.tsx +132 -14
  521. package/src/Table/Table.tsx +3 -8
  522. package/src/Table/TableBody.doc.mjs +40 -0
  523. package/src/Table/TableFooter.doc.mjs +40 -0
  524. package/src/Table/TableHeader.doc.mjs +40 -0
  525. package/src/Table/TableRow.tsx +16 -5
  526. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  527. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  528. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  529. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  530. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  531. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  532. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  533. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  534. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  535. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  536. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  537. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  538. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  539. package/src/Table/types.ts +22 -4
  540. package/src/Table/useBaseTablePlugins.ts +5 -0
  541. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  542. package/src/Table/useTablePagination.doc.mjs +7 -0
  543. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  544. package/src/Table/useTableSelection.doc.mjs +31 -0
  545. package/src/Text/Text.test.tsx +23 -1
  546. package/src/Text/Text.tsx +6 -2
  547. package/src/TextArea/TextArea.doc.mjs +8 -2
  548. package/src/TextArea/TextArea.test.tsx +11 -0
  549. package/src/TextArea/TextArea.tsx +15 -8
  550. package/src/TextInput/TextInput.doc.mjs +10 -0
  551. package/src/TextInput/TextInput.tsx +3 -2
  552. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  553. package/src/TimeInput/TimeInput.tsx +2 -2
  554. package/src/Timestamp/Timestamp.test.tsx +18 -0
  555. package/src/Timestamp/Timestamp.tsx +4 -2
  556. package/src/Toast/Toast.doc.mjs +6 -0
  557. package/src/Toast/ToastViewport.tsx +17 -1
  558. package/src/Token/TokenLink.tsx +2 -2
  559. package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
  560. package/src/Tokenizer/Tokenizer.tsx +4 -0
  561. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  562. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  563. package/src/Tooltip/Tooltip.test.tsx +32 -0
  564. package/src/Tooltip/Tooltip.tsx +5 -0
  565. package/src/Tooltip/useTooltip.tsx +47 -24
  566. package/src/TopNav/TopNavHeading.tsx +5 -4
  567. package/src/TopNav/TopNavMegaMenu.tsx +3 -2
  568. package/src/TopNav/TopNavMenu.tsx +4 -3
  569. package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
  570. package/src/Typeahead/BaseTypeahead.tsx +85 -33
  571. package/src/Typeahead/Typeahead.doc.mjs +5 -0
  572. package/src/Typeahead/Typeahead.test.tsx +49 -0
  573. package/src/Typeahead/Typeahead.tsx +3 -2
  574. package/src/hooks/index.ts +2 -0
  575. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  576. package/src/hooks/useFocusTrap.test.tsx +14 -0
  577. package/src/hooks/useFocusTrap.ts +62 -111
  578. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  579. package/src/hooks/useHotkeys.ts +3 -18
  580. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  581. package/src/hooks/useMergedRefs.test.tsx +62 -0
  582. package/src/hooks/useMergedRefs.ts +36 -0
  583. package/src/index.ts +1 -0
  584. package/src/raw-import.d.ts +14 -0
  585. package/src/theme/MediaTheme.doc.mjs +5 -5
  586. package/src/theme/derivedVarRegistry.test.ts +19 -3
  587. package/src/theme/derivedVarRegistry.ts +23 -4
  588. package/src/theme/generateThemeRules.test.ts +37 -0
  589. package/src/theme/syntax/tokens.ts +5 -2
  590. package/src/utils/groupItems.ts +12 -6
  591. package/src/utils/index.ts +1 -1
  592. package/src/utils/isApplePlatform.test.ts +61 -0
  593. package/src/utils/isApplePlatform.ts +37 -0
  594. package/src/utils/sharedResizeObserver.ts +10 -2
  595. package/src/utils/timeParser.test.ts +6 -1
  596. package/src/utils/timeParser.ts +35 -13
  597. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -46,7 +46,6 @@ import {
46
46
  typeScaleVars,
47
47
  fontWeightVars,
48
48
  } from '../theme/tokens.stylex';
49
- import {mergeRefs} from '../utils';
50
49
  import {useSize} from '../SizeContext/SizeContext';
51
50
  import {useInternalConfig} from './useInternalConfig';
52
51
  import {usePowerSearchSource} from './usePowerSearchSource';
@@ -75,10 +74,19 @@ import type {
75
74
  PowerSearchComponents,
76
75
  } from './types';
77
76
 
77
+ import {useMergedRefs} from '../hooks/useMergedRefs';
78
78
  // =============================================================================
79
79
  // Icon mapping for typeahead entries
80
80
  // =============================================================================
81
81
 
82
+ // Ranked suggestions shown for a non-empty query. The field list itself is
83
+ // never capped -- see the maxSearchResults prop.
84
+ const DEFAULT_MAX_SEARCH_RESULTS = 10;
85
+
86
+ // Empty-query browsing gets a high safety ceiling, matching XDS. This shows
87
+ // every practical field list without allowing an accidental unbounded DOM.
88
+ const MAX_BROWSE_MENU_ITEMS = 1000;
89
+
82
90
  const OPERATOR_VALUE_TYPE_TO_ICON: Record<string, IconName> = {
83
91
  string: 'search',
84
92
  string_list: 'search',
@@ -109,7 +117,12 @@ const tokenValueStyles = stylex.create({
109
117
  const popoverLayerStyles = stylex.create({
110
118
  layer: {
111
119
  width: 'anchor-size(width)',
112
- minWidth: 400,
120
+ // Floor for comfortable editing, yielding when the available inline
121
+ // space cannot fit it, so the editor stays on-screen at narrow viewport
122
+ // widths (#4761). Percentages resolve against the position-area region
123
+ // (anchor start edge to viewport end), falling back to the viewport
124
+ // where area sizing is not honored.
125
+ minWidth: `min(400px, calc(100% - ${spacingVars['--spacing-4']}))`,
113
126
  },
114
127
  });
115
128
 
@@ -401,8 +414,14 @@ export interface PowerSearchProps extends Omit<
401
414
  menuWidth?: number;
402
415
  /** Max display length for filter token values. @default 40 */
403
416
  maxTokenLength?: number;
404
- /** Max items in operator dropdown. */
417
+ /** Max suggestions in string and entity value typeaheads. @default 10 */
405
418
  maxOperatorMenuItems?: number;
419
+ /**
420
+ * Max ranked results shown for a non-empty query. This does not affect the
421
+ * value editor shown after selecting a field. Browsing the field list with
422
+ * an empty query shows up to 1,000 fields. @default 10
423
+ */
424
+ maxSearchResults?: number;
406
425
  /** Label for the save button in edit popover. @default 'Apply' */
407
426
  popoverSaveButtonLabel?: string;
408
427
  /** Timezone ID for date formatting. */
@@ -542,7 +561,10 @@ export function PowerSearch({
542
561
  onBlur,
543
562
  status,
544
563
  statusVariant = 'attached',
564
+ menuWidth,
545
565
  maxTokenLength = 40,
566
+ maxOperatorMenuItems,
567
+ maxSearchResults = DEFAULT_MAX_SEARCH_RESULTS,
546
568
  popoverSaveButtonLabel: popoverSaveButtonLabelFromProps,
547
569
  timezoneID,
548
570
  tokenOverflowBehavior,
@@ -559,7 +581,7 @@ export function PowerSearch({
559
581
  }: PowerSearchProps) {
560
582
  const size = useSize(sizeProp, 'md');
561
583
  const config = useInternalConfig(configProp);
562
- const searchSource = usePowerSearchSource(config);
584
+ const searchSource = usePowerSearchSource(config, maxSearchResults);
563
585
  const t = useTranslator();
564
586
  const locale = useLocale();
565
587
  const label = labelFromProps ?? t('@astryx.powersearch.label');
@@ -962,6 +984,7 @@ export function PowerSearch({
962
984
  onSave={handlePopoverSave}
963
985
  onCancel={handlePopoverCancel}
964
986
  saveButtonLabel={popoverSaveButtonLabel}
987
+ maxMenuItems={maxOperatorMenuItems}
965
988
  isReadOnly={isReadOnly}
966
989
  />
967
990
  );
@@ -974,6 +997,7 @@ export function PowerSearch({
974
997
  handlePopoverSave,
975
998
  handlePopoverCancel,
976
999
  popoverSaveButtonLabel,
1000
+ maxOperatorMenuItems,
977
1001
  isReadOnly,
978
1002
  ]);
979
1003
 
@@ -1029,7 +1053,10 @@ export function PowerSearch({
1029
1053
  return (
1030
1054
  <>
1031
1055
  <div
1032
- ref={mergeRefs(ref, popover.triggerRef as React.Ref<HTMLDivElement>)}
1056
+ ref={useMergedRefs(
1057
+ ref,
1058
+ popover.triggerRef as React.Ref<HTMLDivElement>,
1059
+ )}
1033
1060
  {...themeProps('power-search')}>
1034
1061
  <Tokenizer
1035
1062
  handleRef={tokenizerRef}
@@ -1040,6 +1067,8 @@ export function PowerSearch({
1040
1067
  onChange={handleTokenizerChange}
1041
1068
  renderToken={renderToken}
1042
1069
  renderItem={renderItem}
1070
+ maxMenuItems={MAX_BROWSE_MENU_ITEMS}
1071
+ menuWidth={menuWidth}
1043
1072
  placeholder={filters.length === 0 ? placeholder : ''}
1044
1073
  hasAutoFocus={hasAutoFocus}
1045
1074
  hasClear={hasClear && !isReadOnly}
@@ -12,6 +12,8 @@ import {
12
12
  } from 'vitest';
13
13
  import {render, screen, fireEvent, act} from '@testing-library/react';
14
14
  import React, {useState} from 'react';
15
+ import * as stylex from '@stylexjs/stylex';
16
+ import {spacingVars} from '../theme/tokens.stylex';
15
17
  import {PowerSearch} from './PowerSearch';
16
18
  import {PowerSearchEditPopover} from './PowerSearchEditPopover';
17
19
  import {useInternalConfig} from './useInternalConfig';
@@ -284,6 +286,93 @@ describe('PowerSearch', () => {
284
286
  expect(onSave).not.toHaveBeenCalled();
285
287
  });
286
288
 
289
+ it('saves the freshly committed numeric value on Enter', () => {
290
+ const numericConfig: PowerSearchConfig = {
291
+ name: 'test-number',
292
+ fields: [
293
+ {
294
+ key: 'level',
295
+ label: 'Level',
296
+ operators: [
297
+ {key: 'equals', label: 'equals', value: {type: 'integer'}},
298
+ ],
299
+ },
300
+ ],
301
+ };
302
+ const onSave = vi.fn();
303
+
304
+ function NumericValueHarness() {
305
+ const internalConfig = useInternalConfig(numericConfig);
306
+ return (
307
+ <PowerSearchEditPopover
308
+ config={internalConfig}
309
+ filter={{
310
+ field: 'level',
311
+ operator: 'equals',
312
+ value: {type: 'integer', value: 5},
313
+ }}
314
+ mode="edit"
315
+ onSave={onSave}
316
+ onCancel={() => {}}
317
+ />
318
+ );
319
+ }
320
+
321
+ render(<NumericValueHarness />);
322
+ const input = screen.getByRole('spinbutton');
323
+ fireEvent.focus(input);
324
+ fireEvent.input(input, {target: {value: '42'}});
325
+ fireEvent.keyDown(input, {key: 'Enter'});
326
+
327
+ expect(onSave).toHaveBeenCalledWith({
328
+ field: 'level',
329
+ operator: 'equals',
330
+ value: {type: 'integer', value: 42},
331
+ });
332
+ });
333
+
334
+ it('does not save an invalid numeric draft on Enter', () => {
335
+ const numericConfig: PowerSearchConfig = {
336
+ name: 'test-number',
337
+ fields: [
338
+ {
339
+ key: 'level',
340
+ label: 'Level',
341
+ operators: [
342
+ {key: 'equals', label: 'equals', value: {type: 'integer'}},
343
+ ],
344
+ },
345
+ ],
346
+ };
347
+ const onSave = vi.fn();
348
+
349
+ function NumericValueHarness() {
350
+ const internalConfig = useInternalConfig(numericConfig);
351
+ return (
352
+ <PowerSearchEditPopover
353
+ config={internalConfig}
354
+ filter={{
355
+ field: 'level',
356
+ operator: 'equals',
357
+ value: {type: 'integer', value: 5},
358
+ }}
359
+ mode="edit"
360
+ onSave={onSave}
361
+ onCancel={() => {}}
362
+ />
363
+ );
364
+ }
365
+
366
+ render(<NumericValueHarness />);
367
+ const input = screen.getByRole('spinbutton');
368
+ fireEvent.focus(input);
369
+ fireEvent.input(input, {target: {value: '1·234'}});
370
+ fireEvent.keyDown(input, {key: 'Enter'});
371
+
372
+ expect(onSave).not.toHaveBeenCalled();
373
+ expect(input).toHaveValue('1·234');
374
+ });
375
+
287
376
  it('does not save/close on a composing Enter while typing a filter value (#4828)', () => {
288
377
  const onSave = vi.fn();
289
378
  const onCancel = vi.fn();
@@ -326,3 +415,202 @@ describe('PowerSearch', () => {
326
415
  expect(onSave).toHaveBeenCalledTimes(1);
327
416
  });
328
417
  });
418
+
419
+ // =============================================================================
420
+ // Narrow-width layout (#4761)
421
+ // =============================================================================
422
+
423
+ // jsdom performs no real layout (and never matches @container conditions), so
424
+ // these tests assert the declarations that produce the narrow-width behavior
425
+ // rather than measured geometry, via StyleX probe classes: one deterministic
426
+ // atomic class per property/value/condition, so an element carries a probe's
427
+ // classes exactly when it has the same declaration. The dev debug class
428
+ // (contains "__") is excluded.
429
+ const CHIP_ROW_COLLAPSE = '@container (max-width: 399px)';
430
+
431
+ const probe = stylex.create({
432
+ responsiveLayerMinWidth: {
433
+ minWidth: `min(400px, calc(100% - ${spacingVars['--spacing-4']}))`,
434
+ },
435
+ fixedLayerMinWidth: {minWidth: 400},
436
+ queryContainer: {containerType: 'inline-size'},
437
+ responsiveWrap: {
438
+ flexWrap: {default: 'nowrap', [CHIP_ROW_COLLAPSE]: 'wrap'},
439
+ },
440
+ cellMaxWidth: {maxWidth: '100%'},
441
+ nestedFieldCellWidth: {width: 200},
442
+ });
443
+
444
+ function atomicClasses(style: (typeof probe)[keyof typeof probe]): string[] {
445
+ const {className = ''} = stylex.props(style);
446
+ const classes = className
447
+ .split(' ')
448
+ .filter(c => c !== '' && !c.includes('__'));
449
+ // A probe resolving to no atomic classes would make every assertion built
450
+ // on it vacuous, including the not-toHaveClass loops; fail loudly instead.
451
+ expect(classes.length).toBeGreaterThan(0);
452
+ return classes;
453
+ }
454
+
455
+ function expectProbeClasses(
456
+ el: HTMLElement,
457
+ style: (typeof probe)[keyof typeof probe],
458
+ ) {
459
+ for (const cls of atomicClasses(style)) {
460
+ expect(el).toHaveClass(cls);
461
+ }
462
+ }
463
+
464
+ describe('narrow-width layout (#4761)', () => {
465
+ function EditHarness() {
466
+ const internalConfig = useInternalConfig(testConfig);
467
+ return (
468
+ <PowerSearchEditPopover
469
+ config={internalConfig}
470
+ filter={{
471
+ field: 'status',
472
+ operator: 'is',
473
+ value: {type: 'string', value: 'open'},
474
+ }}
475
+ mode="edit"
476
+ onSave={() => {}}
477
+ onCancel={() => {}}
478
+ />
479
+ );
480
+ }
481
+
482
+ function getChipRow(container: HTMLElement): HTMLElement {
483
+ // Locate the chip row by its collapse declaration, then sanity-check it
484
+ // really is the row holding the field / operator / value cells.
485
+ const [rowCls] = atomicClasses(probe.responsiveWrap);
486
+ const row = container.querySelector(`.${rowCls}`) as HTMLElement;
487
+ expect(row).not.toBeNull();
488
+ expect(row).toHaveClass('astryx-stack');
489
+ expect(row.children).toHaveLength(3);
490
+ return row;
491
+ }
492
+
493
+ it('popover root establishes the container the collapse query measures', () => {
494
+ const {container} = render(<EditHarness />);
495
+
496
+ // Without inline-size containment on the root, no @container condition
497
+ // in this file can match and the chip rows would never wrap.
498
+ const root = container.firstElementChild as HTMLElement;
499
+ expect(root).not.toBeNull();
500
+ expectProbeClasses(root, probe.queryContainer);
501
+ });
502
+
503
+ it('filter chip row wraps below the collapse width instead of overflowing', () => {
504
+ const {container} = render(<EditHarness />);
505
+
506
+ const row = getChipRow(container);
507
+ expectProbeClasses(row, probe.responsiveWrap);
508
+ });
509
+
510
+ it('operator cell is capped at the row width', () => {
511
+ const {container} = render(<EditHarness />);
512
+
513
+ // Capped so a long translated operator label truncates inside the
514
+ // Selector trigger instead of pushing the row wider than the popover.
515
+ const operatorCell = getChipRow(container).children[1] as HTMLElement;
516
+ expectProbeClasses(operatorCell, probe.cellMaxWidth);
517
+ });
518
+
519
+ it('nested sub-filter rows wrap instead of overflowing on one line', () => {
520
+ const nestedConfig: PowerSearchConfig = {
521
+ name: 'test-nested',
522
+ fields: [
523
+ {
524
+ key: 'group',
525
+ label: 'Group',
526
+ operators: [
527
+ {key: 'all_of', label: 'all of', value: {type: 'nested'}},
528
+ ],
529
+ },
530
+ {
531
+ key: 'status',
532
+ label: 'Status',
533
+ operators: [{key: 'is', label: 'is', value: {type: 'string'}}],
534
+ },
535
+ ],
536
+ };
537
+
538
+ function NestedHarness() {
539
+ const internalConfig = useInternalConfig(nestedConfig);
540
+ return (
541
+ <PowerSearchEditPopover
542
+ config={internalConfig}
543
+ filter={{
544
+ field: 'group',
545
+ operator: 'all_of',
546
+ value: {
547
+ type: 'nested',
548
+ value: [
549
+ {
550
+ field: 'status',
551
+ operator: 'is',
552
+ value: {type: 'string', value: 'open'},
553
+ },
554
+ ],
555
+ },
556
+ }}
557
+ mode="edit"
558
+ onSave={() => {}}
559
+ onCancel={() => {}}
560
+ />
561
+ );
562
+ }
563
+
564
+ const {container} = render(<NestedHarness />);
565
+
566
+ // Locate the sub-filter row through its fixed-width field cell.
567
+ const [cellCls] = atomicClasses(probe.nestedFieldCellWidth);
568
+ const fieldCell = container.querySelector(`.${cellCls}`) as HTMLElement;
569
+ expect(fieldCell).not.toBeNull();
570
+ const row = fieldCell.parentElement as HTMLElement;
571
+ expect(row).toHaveClass('astryx-stack');
572
+ expectProbeClasses(row, probe.responsiveWrap);
573
+
574
+ // The fixed-width cells are capped so they cannot clip in containers
575
+ // narrower than their design width (or under deep TreeList indentation).
576
+ expectProbeClasses(fieldCell, probe.cellMaxWidth);
577
+ const operatorCell = row.children[1] as HTMLElement;
578
+ expectProbeClasses(operatorCell, probe.cellMaxWidth);
579
+ });
580
+
581
+ it('edit popover layer yields to viewports narrower than its 400px floor', () => {
582
+ const filters: PowerSearchFilter[] = [
583
+ {field: 'status', operator: 'is', value: {type: 'string', value: 'open'}},
584
+ ];
585
+
586
+ function Harness() {
587
+ const [currentFilters, setCurrentFilters] = useState(filters);
588
+ return (
589
+ <PowerSearch
590
+ config={testConfig}
591
+ filters={currentFilters}
592
+ onChange={newFilters => setCurrentFilters([...newFilters])}
593
+ />
594
+ );
595
+ }
596
+
597
+ render(<Harness />);
598
+
599
+ act(() => {
600
+ fireEvent.click(screen.getByText('Status: is'));
601
+ flushRAF();
602
+ });
603
+
604
+ const layer = screen
605
+ .getByText('Cancel')
606
+ .closest('[popover]') as HTMLElement;
607
+ expect(layer).not.toBeNull();
608
+
609
+ // The fixed 400px floor is replaced by one clamped to the available
610
+ // inline space, so the popover never opens wider than the screen.
611
+ expectProbeClasses(layer, probe.responsiveLayerMinWidth);
612
+ for (const cls of atomicClasses(probe.fixedLayerMinWidth)) {
613
+ expect(layer).not.toHaveClass(cls);
614
+ }
615
+ });
616
+ });
@@ -32,13 +32,23 @@ import type {
32
32
  OperatorValue,
33
33
  } from './types';
34
34
 
35
+ // Below the popover layer's 400px floor (see popoverLayerStyles in
36
+ // PowerSearch.tsx) the chip rows collapse from one line to wrapped lines.
37
+ // A container query, not a viewport one, so the rows track the width the
38
+ // popover actually got (#4761).
39
+ const CHIP_ROW_COLLAPSE = '@container (max-width: 399px)';
40
+
35
41
  const styles = stylex.create({
36
42
  container: {
37
43
  overflow: 'hidden',
44
+ containerType: 'inline-size',
38
45
  },
39
46
  content: {
40
47
  padding: spacingVars['--spacing-4'],
41
48
  },
49
+ chipRow: {
50
+ flexWrap: {default: 'nowrap', [CHIP_ROW_COLLAPSE]: 'wrap'},
51
+ },
42
52
  footer: {
43
53
  padding: spacingVars['--spacing-3'],
44
54
  paddingTop: 0,
@@ -51,6 +61,9 @@ const styles = stylex.create({
51
61
  operatorSelector: {
52
62
  flexGrow: 1,
53
63
  flexShrink: 0,
64
+ // Long translated operator labels truncate in the Selector trigger
65
+ // instead of pushing the row wider than the popover (#4761).
66
+ maxWidth: '100%',
54
67
  },
55
68
  valueEditor: {
56
69
  flexGrow: 2,
@@ -63,10 +76,12 @@ const styles = stylex.create({
63
76
  nestedFieldSelector: {
64
77
  flexShrink: 0,
65
78
  width: 200,
79
+ maxWidth: '100%',
66
80
  },
67
81
  nestedOperatorSelector: {
68
82
  flexShrink: 0,
69
83
  width: 180,
84
+ maxWidth: '100%',
70
85
  },
71
86
  nestedRow: {
72
87
  width: '100%',
@@ -90,6 +105,8 @@ export interface PowerSearchEditPopoverProps {
90
105
  onCancel: () => void;
91
106
  /** Label for the save button. @default 'Apply' */
92
107
  saveButtonLabel?: string;
108
+ /** Max suggestions in string and entity value typeaheads. */
109
+ maxMenuItems?: number;
93
110
  /** Whether the filter is read-only. */
94
111
  isReadOnly?: boolean;
95
112
  }
@@ -232,6 +249,7 @@ interface NestedSubFilterRowProps {
232
249
  config: InternalConfig;
233
250
  subFilter: EditablePartialFilter;
234
251
  onChange: (subFilter: EditablePartialFilter) => void;
252
+ maxMenuItems?: number;
235
253
  isReadOnly: boolean;
236
254
  }
237
255
 
@@ -239,6 +257,7 @@ function NestedSubFilterRow({
239
257
  config,
240
258
  subFilter,
241
259
  onChange,
260
+ maxMenuItems,
242
261
  isReadOnly,
243
262
  }: NestedSubFilterRowProps) {
244
263
  const t = useTranslator();
@@ -309,7 +328,7 @@ function NestedSubFilterRow({
309
328
  );
310
329
 
311
330
  return (
312
- <HStack gap={2} vAlign="center">
331
+ <HStack gap={2} vAlign="center" xstyle={styles.chipRow}>
313
332
  <div {...stylex.props(styles.nestedFieldSelector)}>
314
333
  <Selector
315
334
  label={t('@astryx.powersearch.editor.field')}
@@ -341,6 +360,7 @@ function NestedSubFilterRow({
341
360
  filterValue={subFilter.value}
342
361
  onChange={handleValueChange}
343
362
  config={config}
363
+ maxMenuItems={maxMenuItems}
344
364
  isDisabled={isReadOnly}
345
365
  />
346
366
  </div>
@@ -359,6 +379,7 @@ interface NestedEditorProps {
359
379
  operatorOptions: {value: string; label: string}[];
360
380
  onOperatorChange: (operatorKey: string) => void;
361
381
  onPartialFilterChange: (filter: PartialFilter) => void;
382
+ maxMenuItems?: number;
362
383
  isReadOnly: boolean;
363
384
  }
364
385
 
@@ -368,6 +389,7 @@ function NestedEditor({
368
389
  operatorOptions,
369
390
  onOperatorChange,
370
391
  onPartialFilterChange,
392
+ maxMenuItems,
371
393
  isReadOnly,
372
394
  }: NestedEditorProps) {
373
395
  const t = useTranslator();
@@ -489,6 +511,7 @@ function NestedEditor({
489
511
  config={config}
490
512
  subFilter={sf}
491
513
  onChange={updated => handleUpdate(itemPath, updated)}
514
+ maxMenuItems={maxMenuItems}
492
515
  isReadOnly={isReadOnly}
493
516
  />
494
517
  ),
@@ -515,6 +538,7 @@ function NestedEditor({
515
538
  config={config}
516
539
  subFilter={sf}
517
540
  onChange={updated => handleUpdate(itemPath, updated)}
541
+ maxMenuItems={maxMenuItems}
518
542
  isReadOnly={isReadOnly}
519
543
  />
520
544
  ),
@@ -593,6 +617,7 @@ export function PowerSearchEditPopover({
593
617
  onSave,
594
618
  onCancel,
595
619
  saveButtonLabel: saveButtonLabelFromProps,
620
+ maxMenuItems,
596
621
  isReadOnly = false,
597
622
  }: PowerSearchEditPopoverProps) {
598
623
  const t = useTranslator();
@@ -762,6 +787,7 @@ export function PowerSearchEditPopover({
762
787
  operatorOptions={operatorOptions}
763
788
  onOperatorChange={handleOperatorChange}
764
789
  onPartialFilterChange={setPartialFilter}
790
+ maxMenuItems={maxMenuItems}
765
791
  isReadOnly={isReadOnly}
766
792
  />
767
793
  </VStack>
@@ -802,7 +828,7 @@ export function PowerSearchEditPopover({
802
828
  return (
803
829
  <div {...stylex.props(styles.container)} onKeyDown={handleKeyDown}>
804
830
  <div {...stylex.props(styles.content)}>
805
- <HStack gap={2}>
831
+ <HStack gap={2} xstyle={styles.chipRow}>
806
832
  <div {...stylex.props(styles.fieldSelector)}>
807
833
  <Selector
808
834
  label={t('@astryx.powersearch.editor.field')}
@@ -835,6 +861,7 @@ export function PowerSearchEditPopover({
835
861
  onChange={handleValueChange}
836
862
  onEnter={handleSave}
837
863
  config={config}
864
+ maxMenuItems={maxMenuItems}
838
865
  isDisabled={isReadOnly}
839
866
  />
840
867
  </div>
@@ -10,7 +10,11 @@
10
10
  import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest';
11
11
  import {render, screen, fireEvent, act} from '@testing-library/react';
12
12
  import {PowerSearchValueEditor} from './PowerSearchValueEditor';
13
- import type {FilterValueEntityList, PowerSearchEntity} from './types';
13
+ import type {
14
+ FilterValueEntityList,
15
+ OperatorValue,
16
+ PowerSearchEntity,
17
+ } from './types';
14
18
  import type {InternalConfig} from './useInternalConfig';
15
19
  import type {SearchableItem, SearchSource} from '../Typeahead/types';
16
20
 
@@ -178,6 +182,70 @@ describe('StringEditor (#1103)', () => {
178
182
  });
179
183
  });
180
184
 
185
+ describe('numeric editor commit timing', () => {
186
+ it('saves the committed number when Enter finishes the edit', () => {
187
+ const onChange = vi.fn();
188
+ const onEnter = vi.fn();
189
+ render(
190
+ <PowerSearchValueEditor
191
+ operatorValue={{type: 'integer'}}
192
+ filterValue={{type: 'integer', value: 5}}
193
+ onChange={onChange}
194
+ onEnter={onEnter}
195
+ config={stubConfig}
196
+ />,
197
+ );
198
+ const input = screen.getByRole('spinbutton');
199
+ fireEvent.focus(input);
200
+ fireEvent.input(input, {target: {value: '42'}});
201
+ fireEvent.keyDown(input, {key: 'Enter'});
202
+
203
+ expect(onChange).toHaveBeenLastCalledWith(
204
+ {type: 'integer', value: 42},
205
+ true,
206
+ );
207
+ expect(onEnter).not.toHaveBeenCalled();
208
+ });
209
+
210
+ it('does not save an invalid numeric draft on Enter', () => {
211
+ const onChange = vi.fn();
212
+ const onEnter = vi.fn();
213
+ render(
214
+ <PowerSearchValueEditor
215
+ operatorValue={{type: 'integer'}}
216
+ filterValue={{type: 'integer', value: 5}}
217
+ onChange={onChange}
218
+ onEnter={onEnter}
219
+ config={stubConfig}
220
+ />,
221
+ );
222
+ const input = screen.getByRole('spinbutton');
223
+ fireEvent.focus(input);
224
+ fireEvent.input(input, {target: {value: '1·234'}});
225
+ fireEvent.keyDown(input, {key: 'Enter'});
226
+
227
+ expect(onChange).not.toHaveBeenCalled();
228
+ expect(onEnter).not.toHaveBeenCalled();
229
+ expect(input).toHaveValue('1·234');
230
+ });
231
+
232
+ it('keeps the existing Enter callback when there is no pending edit', () => {
233
+ const onEnter = vi.fn();
234
+ render(
235
+ <PowerSearchValueEditor
236
+ operatorValue={{type: 'float'}}
237
+ filterValue={{type: 'float', value: 1.5}}
238
+ onChange={() => {}}
239
+ onEnter={onEnter}
240
+ config={stubConfig}
241
+ />,
242
+ );
243
+
244
+ fireEvent.keyDown(screen.getByRole('spinbutton'), {key: 'Enter'});
245
+ expect(onEnter).toHaveBeenCalledTimes(1);
246
+ });
247
+ });
248
+
181
249
  // =============================================================================
182
250
  // #1106 — EntityListEditor drops photo, no renderItem
183
251
  // =============================================================================
@@ -404,3 +472,45 @@ describe('StringListEditor (#1107)', () => {
404
472
  expect(screen.getByRole('combobox')).toBeInTheDocument();
405
473
  });
406
474
  });
475
+
476
+ describe('maxMenuItems', () => {
477
+ const source = createSearchSource(
478
+ Array.from({length: 6}, (_, index) => ({
479
+ id: `option-${index}`,
480
+ label: `Option ${index}`,
481
+ })),
482
+ );
483
+
484
+ async function expectCapped(operatorValue: OperatorValue) {
485
+ render(
486
+ <PowerSearchValueEditor
487
+ operatorValue={operatorValue}
488
+ filterValue={undefined}
489
+ onChange={vi.fn()}
490
+ config={stubConfig}
491
+ maxMenuItems={2}
492
+ />,
493
+ );
494
+
495
+ await act(async () => {
496
+ fireEvent.change(screen.getByRole('combobox'), {
497
+ target: {value: 'Option'},
498
+ });
499
+ await new Promise(resolve => setTimeout(resolve, 200));
500
+ });
501
+
502
+ expect(screen.getAllByRole('option', {hidden: true})).toHaveLength(2);
503
+ }
504
+
505
+ it('caps string suggestions', async () => {
506
+ await expectCapped({type: 'string', searchSource: source});
507
+ });
508
+
509
+ it('caps string-list suggestions', async () => {
510
+ await expectCapped({type: 'string_list', searchSource: source});
511
+ });
512
+
513
+ it('caps entity-list suggestions', async () => {
514
+ await expectCapped({type: 'entity_list', searchSource: source});
515
+ });
516
+ });