@astryxdesign/core 0.1.8 → 0.1.9-canary.1887ee2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (610) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +6 -2
  4. package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
  5. package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
  6. package/dist/Avatar/Avatar.d.ts +53 -3
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +203 -49
  9. package/dist/Avatar/AvatarStatusDot.d.ts +33 -5
  10. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  11. package/dist/Avatar/AvatarStatusDot.js +144 -19
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  15. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  16. package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
  17. package/dist/Banner/Banner.d.ts +9 -1
  18. package/dist/Banner/Banner.d.ts.map +1 -1
  19. package/dist/Banner/Banner.js +33 -4
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
  21. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  22. package/dist/Breadcrumbs/BreadcrumbItem.js +208 -6
  23. package/dist/Breadcrumbs/index.d.ts +5 -0
  24. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  25. package/dist/Breadcrumbs/index.js +9 -1
  26. package/dist/Button/Button.d.ts +8 -2
  27. package/dist/Button/Button.d.ts.map +1 -1
  28. package/dist/Button/Button.js +33 -4
  29. package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
  30. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  31. package/dist/ButtonGroup/ButtonGroup.js +30 -1
  32. package/dist/Calendar/Calendar.d.ts.map +1 -1
  33. package/dist/Calendar/Calendar.js +30 -2
  34. package/dist/Calendar/dayCellUtils.js +1 -1
  35. package/dist/Card/Card.d.ts +8 -2
  36. package/dist/Card/Card.d.ts.map +1 -1
  37. package/dist/Card/Card.js +28 -2
  38. package/dist/Carousel/Carousel.d.ts +4 -1
  39. package/dist/Carousel/Carousel.d.ts.map +1 -1
  40. package/dist/Carousel/Carousel.js +24 -4
  41. package/dist/Chat/ChatComposer.d.ts +8 -0
  42. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposer.js +46 -7
  44. package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
  45. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  46. package/dist/Chat/ChatComposerDrawer.js +11 -1
  47. package/dist/Chat/ChatComposerInput.d.ts +20 -3
  48. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  49. package/dist/Chat/ChatComposerInput.js +36 -4
  50. package/dist/Chat/ChatContext.d.ts +33 -0
  51. package/dist/Chat/ChatContext.d.ts.map +1 -1
  52. package/dist/Chat/ChatContext.js +16 -2
  53. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  54. package/dist/Chat/ChatDictationButton.js +1 -1
  55. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  56. package/dist/Chat/ChatLayout.js +4 -4
  57. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  58. package/dist/Chat/ChatLayoutScrollButton.js +4 -4
  59. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  60. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  61. package/dist/Chat/ChatSendButton.js +7 -1
  62. package/dist/Chat/ChatToolCalls.d.ts +5 -1
  63. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  64. package/dist/Chat/ChatToolCalls.js +18 -9
  65. package/dist/Chat/index.d.ts +2 -1
  66. package/dist/Chat/index.d.ts.map +1 -1
  67. package/dist/Chat/index.js +1 -1
  68. package/dist/Chat/useChatStreamScroll.d.ts +2 -1
  69. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  70. package/dist/Chat/useChatStreamScroll.js +22 -8
  71. package/dist/Chat/useSpeechRecognition.d.ts +0 -1
  72. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  73. package/dist/Chat/useSpeechRecognition.js +1 -1
  74. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  75. package/dist/Chat/useTriggerMenu.js +2 -2
  76. package/dist/CheckboxInput/CheckboxInput.js +1 -1
  77. package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
  78. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  79. package/dist/CheckboxList/CheckboxListItem.js +11 -1
  80. package/dist/Citation/Citation.d.ts +22 -1
  81. package/dist/Citation/Citation.d.ts.map +1 -1
  82. package/dist/Citation/Citation.js +20 -6
  83. package/dist/ClickableCard/ClickableCard.d.ts +9 -2
  84. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  85. package/dist/ClickableCard/ClickableCard.js +5 -2
  86. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  87. package/dist/CodeBlock/CodeBlock.js +9 -2
  88. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  89. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  90. package/dist/CommandPalette/CommandPalette.js +3 -1
  91. package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
  92. package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
  93. package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
  94. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  95. package/dist/CommandPalette/CommandPaletteInput.js +6 -1
  96. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  97. package/dist/DateInput/DateInput.d.ts +55 -2
  98. package/dist/DateInput/DateInput.d.ts.map +1 -1
  99. package/dist/DateInput/DateInput.js +28 -2
  100. package/dist/DateInput/index.d.ts +1 -1
  101. package/dist/DateInput/index.d.ts.map +1 -1
  102. package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
  103. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  104. package/dist/DateRangeInput/DateRangeInput.js +3 -1
  105. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  106. package/dist/DateTimeInput/DateTimeInput.js +18 -3
  107. package/dist/Dialog/Dialog.d.ts +3 -0
  108. package/dist/Dialog/Dialog.d.ts.map +1 -1
  109. package/dist/Dialog/Dialog.js +57 -6
  110. package/dist/Dialog/DialogContext.d.ts +7 -0
  111. package/dist/Dialog/DialogContext.d.ts.map +1 -1
  112. package/dist/Dialog/DialogContext.js +2 -2
  113. package/dist/Dialog/DialogHeader.d.ts +5 -2
  114. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  115. package/dist/Dialog/DialogHeader.js +6 -1
  116. package/dist/Divider/Divider.js +1 -1
  117. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
  118. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  119. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -2
  120. package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
  121. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
  122. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  123. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
  124. package/dist/Field/Field.d.ts.map +1 -1
  125. package/dist/Field/Field.js +2 -3
  126. package/dist/Field/FieldLabel.d.ts +1 -1
  127. package/dist/Field/FieldLabel.d.ts.map +1 -1
  128. package/dist/Field/FieldLabel.js +43 -16
  129. package/dist/FieldStatus/FieldStatus.d.ts +15 -0
  130. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  131. package/dist/FieldStatus/FieldStatus.js +58 -6
  132. package/dist/FileInput/FileInput.d.ts +9 -2
  133. package/dist/FileInput/FileInput.d.ts.map +1 -1
  134. package/dist/FileInput/FileInput.js +42 -20
  135. package/dist/HoverCard/HoverCard.d.ts +9 -1
  136. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  137. package/dist/HoverCard/HoverCard.js +2 -0
  138. package/dist/HoverCard/useHoverCard.d.ts +8 -0
  139. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  140. package/dist/HoverCard/useHoverCard.js +7 -2
  141. package/dist/Icon/Icon.d.ts +7 -2
  142. package/dist/Icon/Icon.d.ts.map +1 -1
  143. package/dist/Item/Item.d.ts +6 -1
  144. package/dist/Item/Item.d.ts.map +1 -1
  145. package/dist/Item/Item.js +22 -1
  146. package/dist/Layer/useLayer.d.ts +6 -0
  147. package/dist/Layer/useLayer.d.ts.map +1 -1
  148. package/dist/Layer/useLayer.js +2 -0
  149. package/dist/Lightbox/Lightbox.js +4 -4
  150. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  151. package/dist/MobileNav/MobileNav.js +6 -1
  152. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  153. package/dist/MobileNav/MobileNavToggle.js +4 -0
  154. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  155. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  156. package/dist/MultiSelector/MultiSelector.js +41 -12
  157. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  158. package/dist/MultiSelector/hooks.js +16 -0
  159. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  160. package/dist/NumberInput/NumberInput.d.ts +9 -2
  161. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  162. package/dist/NumberInput/NumberInput.js +8 -1
  163. package/dist/Outline/Outline.d.ts +0 -1
  164. package/dist/Outline/Outline.d.ts.map +1 -1
  165. package/dist/Outline/Outline.js +0 -1
  166. package/dist/OverflowList/OverflowList.d.ts +20 -3
  167. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  168. package/dist/OverflowList/OverflowList.js +29 -4
  169. package/dist/Pagination/Pagination.d.ts.map +1 -1
  170. package/dist/Pagination/Pagination.js +11 -3
  171. package/dist/Popover/Popover.d.ts.map +1 -1
  172. package/dist/Popover/Popover.js +3 -2
  173. package/dist/Popover/usePopover.d.ts.map +1 -1
  174. package/dist/Popover/usePopover.js +3 -9
  175. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  176. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  177. package/dist/PowerSearch/PowerSearch.js +2 -0
  178. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  179. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  180. package/dist/SelectableCard/SelectableCard.d.ts +9 -2
  181. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  182. package/dist/SelectableCard/SelectableCard.js +16 -13
  183. package/dist/Selector/Selector.d.ts +8 -0
  184. package/dist/Selector/Selector.d.ts.map +1 -1
  185. package/dist/Selector/Selector.js +7 -3
  186. package/dist/Selector/hooks.d.ts.map +1 -1
  187. package/dist/Selector/hooks.js +16 -0
  188. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  189. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  190. package/dist/SideNav/SideNavHeading.js +21 -8
  191. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +19 -2
  194. package/dist/Stack/stack.stylex.d.ts +9 -9
  195. package/dist/TabList/Tab.js +2 -2
  196. package/dist/TabList/TabMenu.js +1 -1
  197. package/dist/Table/BaseTable.d.ts.map +1 -1
  198. package/dist/Table/BaseTable.js +3 -2
  199. package/dist/Table/TableCell.js +3 -3
  200. package/dist/Table/TableHeaderCell.js +3 -3
  201. package/dist/Table/index.d.ts +2 -0
  202. package/dist/Table/index.d.ts.map +1 -1
  203. package/dist/Table/index.js +1 -0
  204. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  205. package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
  206. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
  207. package/dist/Table/plugins/rowStatus/index.js +3 -0
  208. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
  209. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
  210. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
  211. package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +4 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
  215. package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
  216. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  217. package/dist/Table/plugins/tree/useTableTreeData.js +87 -0
  218. package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
  219. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
  220. package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
  221. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  222. package/dist/Table/useBaseTablePlugins.js +5 -3
  223. package/dist/TextArea/TextArea.d.ts +9 -1
  224. package/dist/TextArea/TextArea.d.ts.map +1 -1
  225. package/dist/TextArea/TextArea.js +2 -0
  226. package/dist/TextInput/TextInput.d.ts +9 -2
  227. package/dist/TextInput/TextInput.d.ts.map +1 -1
  228. package/dist/TextInput/TextInput.js +6 -1
  229. package/dist/Thumbnail/Thumbnail.d.ts +26 -5
  230. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  231. package/dist/Thumbnail/Thumbnail.js +97 -54
  232. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
  233. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
  234. package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
  235. package/dist/TimeInput/TimeInput.d.ts +9 -2
  236. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  237. package/dist/TimeInput/TimeInput.js +17 -4
  238. package/dist/Timestamp/Timestamp.d.ts +3 -1
  239. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  240. package/dist/Timestamp/Timestamp.js +8 -6
  241. package/dist/Toast/useToast.d.ts.map +1 -1
  242. package/dist/Toast/useToast.js +2 -5
  243. package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
  244. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  245. package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
  246. package/dist/Tokenizer/Tokenizer.d.ts +10 -3
  247. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  248. package/dist/Tokenizer/Tokenizer.js +18 -4
  249. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  250. package/dist/TopNav/TopNavHeading.js +18 -8
  251. package/dist/TopNav/TopNavMegaMenu.js +10 -4
  252. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
  253. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
  255. package/dist/TopNav/TopNavMenu.d.ts +2 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +68 -6
  258. package/dist/TreeList/TreeList.d.ts +12 -3
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +2 -0
  261. package/dist/TreeList/TreeListBranches.d.ts +5 -0
  262. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  263. package/dist/TreeList/TreeListBranches.js +10 -4
  264. package/dist/TreeList/TreeListItem.d.ts +8 -2
  265. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  266. package/dist/TreeList/TreeListItem.js +28 -8
  267. package/dist/TreeList/TreeListTypes.d.ts +25 -1
  268. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  269. package/dist/TreeList/index.d.ts +2 -2
  270. package/dist/TreeList/index.d.ts.map +1 -1
  271. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  272. package/dist/Typeahead/BaseTypeahead.js +20 -11
  273. package/dist/Typeahead/Typeahead.d.ts +9 -2
  274. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  275. package/dist/Typeahead/Typeahead.js +2 -0
  276. package/dist/astryx.css +41 -31
  277. package/dist/astryx.umd.js +51 -51
  278. package/dist/astryx.umd.js.map +4 -4
  279. package/dist/authoring/doc.d.ts.map +1 -1
  280. package/dist/docs-types.d.ts +8 -0
  281. package/dist/docs-types.d.ts.map +1 -1
  282. package/dist/hooks/computeOverflow.d.ts +47 -0
  283. package/dist/hooks/computeOverflow.d.ts.map +1 -0
  284. package/dist/hooks/computeOverflow.js +213 -0
  285. package/dist/hooks/index.d.ts +1 -0
  286. package/dist/hooks/index.d.ts.map +1 -1
  287. package/dist/hooks/index.js +2 -1
  288. package/dist/hooks/isRtlElement.d.ts +18 -0
  289. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  290. package/dist/hooks/isRtlElement.js +27 -0
  291. package/dist/hooks/useDevWarning.d.ts +18 -0
  292. package/dist/hooks/useDevWarning.d.ts.map +1 -0
  293. package/dist/hooks/useDevWarning.js +49 -0
  294. package/dist/hooks/useGridFocus.d.ts +6 -1
  295. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  296. package/dist/hooks/useGridFocus.js +12 -9
  297. package/dist/hooks/useListFocus.d.ts +6 -1
  298. package/dist/hooks/useListFocus.d.ts.map +1 -1
  299. package/dist/hooks/useListFocus.js +12 -4
  300. package/dist/hooks/useOverflow.d.ts +19 -0
  301. package/dist/hooks/useOverflow.d.ts.map +1 -1
  302. package/dist/hooks/useOverflow.js +36 -25
  303. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  304. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  305. package/dist/i18n/InternationalizationContext.js +3 -0
  306. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  307. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  308. package/dist/i18n/InternationalizationProvider.js +5 -1
  309. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  310. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  311. package/dist/i18n/getLocaleDirection.js +29 -0
  312. package/dist/i18n/index.d.ts +6 -0
  313. package/dist/i18n/index.d.ts.map +1 -1
  314. package/dist/i18n/index.js +7 -1
  315. package/dist/i18n/resolve.d.ts.map +1 -1
  316. package/dist/i18n/resolve.js +7 -18
  317. package/dist/i18n/useDirection.d.ts +2 -0
  318. package/dist/i18n/useDirection.d.ts.map +1 -0
  319. package/dist/i18n/useDirection.js +27 -0
  320. package/dist/theme/Theme.d.ts.map +1 -1
  321. package/dist/theme/Theme.js +2 -7
  322. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  323. package/dist/theme/derivedVarRegistry.js +13 -0
  324. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  325. package/dist/theme/generateThemeRules.js +51 -0
  326. package/dist/theme/hct.d.ts +0 -1
  327. package/dist/theme/hct.d.ts.map +1 -1
  328. package/dist/theme/hct.js +1 -1
  329. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  330. package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
  331. package/dist/utils/devWarning.d.ts +42 -0
  332. package/dist/utils/devWarning.d.ts.map +1 -0
  333. package/dist/utils/devWarning.js +88 -0
  334. package/dist/utils/index.d.ts +3 -1
  335. package/dist/utils/index.d.ts.map +1 -1
  336. package/dist/utils/index.js +3 -2
  337. package/dist/utils/plainDate.d.ts +30 -0
  338. package/dist/utils/plainDate.d.ts.map +1 -1
  339. package/dist/utils/plainDate.js +53 -0
  340. package/dist/utils/types.d.ts +13 -0
  341. package/dist/utils/types.d.ts.map +1 -1
  342. package/locales/en.json +32 -0
  343. package/locales/fr-FR.json +14 -0
  344. package/locales/pseudo.json +24 -0
  345. package/package.json +1 -1
  346. package/src/AppShell/AppShell.tsx +6 -0
  347. package/src/AppShell/AppShellMobileContext.tsx +8 -0
  348. package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
  349. package/src/Avatar/Avatar.doc.mjs +60 -3
  350. package/src/Avatar/Avatar.test.tsx +281 -1
  351. package/src/Avatar/Avatar.tsx +324 -64
  352. package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
  353. package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
  354. package/src/Avatar/AvatarStatusDot.tsx +178 -21
  355. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  356. package/src/AvatarGroup/AvatarGroup.test.tsx +125 -0
  357. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  358. package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
  359. package/src/Banner/Banner.doc.mjs +9 -0
  360. package/src/Banner/Banner.test.tsx +30 -0
  361. package/src/Banner/Banner.tsx +53 -9
  362. package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
  363. package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
  364. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
  365. package/src/Breadcrumbs/Breadcrumbs.test.tsx +284 -2
  366. package/src/Breadcrumbs/index.ts +27 -0
  367. package/src/Button/Button.doc.mjs +9 -0
  368. package/src/Button/Button.test.tsx +49 -0
  369. package/src/Button/Button.tsx +27 -3
  370. package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
  371. package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
  372. package/src/ButtonGroup/ButtonGroup.tsx +32 -0
  373. package/src/Calendar/Calendar.doc.mjs +12 -1
  374. package/src/Calendar/Calendar.test.tsx +193 -0
  375. package/src/Calendar/Calendar.tsx +38 -16
  376. package/src/Calendar/dayCellUtils.test.ts +5 -0
  377. package/src/Calendar/dayCellUtils.ts +1 -1
  378. package/src/Card/Card.doc.mjs +9 -0
  379. package/src/Card/Card.test.tsx +21 -3
  380. package/src/Card/Card.tsx +35 -2
  381. package/src/Carousel/Carousel.doc.mjs +1 -0
  382. package/src/Carousel/Carousel.test.tsx +53 -0
  383. package/src/Carousel/Carousel.tsx +34 -4
  384. package/src/Chat/ChatComposer.doc.mjs +12 -3
  385. package/src/Chat/ChatComposer.test.tsx +115 -0
  386. package/src/Chat/ChatComposer.tsx +73 -9
  387. package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
  388. package/src/Chat/ChatComposerDrawer.tsx +11 -1
  389. package/src/Chat/ChatComposerInput.doc.mjs +7 -0
  390. package/src/Chat/ChatComposerInput.test.tsx +103 -0
  391. package/src/Chat/ChatComposerInput.tsx +51 -5
  392. package/src/Chat/ChatContext.tsx +37 -10
  393. package/src/Chat/ChatDictationButton.tsx +4 -1
  394. package/src/Chat/ChatLayout.tsx +7 -5
  395. package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
  396. package/src/Chat/ChatMessageMetadata.tsx +1 -2
  397. package/src/Chat/ChatSendButton.tsx +11 -1
  398. package/src/Chat/ChatToolCalls.test.tsx +64 -0
  399. package/src/Chat/ChatToolCalls.tsx +25 -4
  400. package/src/Chat/index.ts +5 -1
  401. package/src/Chat/useChatStreamScroll.test.tsx +49 -0
  402. package/src/Chat/useChatStreamScroll.ts +27 -10
  403. package/src/Chat/useSpeechRecognition.ts +1 -1
  404. package/src/Chat/useTriggerMenu.tsx +4 -2
  405. package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
  406. package/src/CheckboxInput/CheckboxInput.tsx +1 -1
  407. package/src/CheckboxList/CheckboxList.test.tsx +81 -3
  408. package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
  409. package/src/CheckboxList/CheckboxListItem.tsx +41 -5
  410. package/src/Citation/Citation.doc.mjs +4 -3
  411. package/src/Citation/Citation.test.tsx +97 -0
  412. package/src/Citation/Citation.tsx +43 -11
  413. package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
  414. package/src/ClickableCard/ClickableCard.test.tsx +34 -0
  415. package/src/ClickableCard/ClickableCard.tsx +13 -3
  416. package/src/CodeBlock/CodeBlock.test.tsx +56 -0
  417. package/src/CodeBlock/CodeBlock.tsx +10 -2
  418. package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
  419. package/src/CommandPalette/CommandPalette.tsx +3 -1
  420. package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
  421. package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
  422. package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
  423. package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
  424. package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
  425. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  426. package/src/ContextMenu/ContextMenu.test.tsx +193 -0
  427. package/src/DateInput/DateInput.doc.mjs +31 -0
  428. package/src/DateInput/DateInput.test.tsx +131 -0
  429. package/src/DateInput/DateInput.tsx +78 -3
  430. package/src/DateInput/index.ts +1 -0
  431. package/src/DateRangeInput/DateRangeInput.doc.mjs +8 -0
  432. package/src/DateRangeInput/DateRangeInput.test.tsx +23 -0
  433. package/src/DateRangeInput/DateRangeInput.tsx +13 -3
  434. package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -1
  435. package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
  436. package/src/DateTimeInput/DateTimeInput.tsx +42 -18
  437. package/src/Dialog/Dialog.doc.mjs +2 -2
  438. package/src/Dialog/Dialog.test.tsx +77 -4
  439. package/src/Dialog/Dialog.tsx +89 -5
  440. package/src/Dialog/DialogContext.ts +9 -2
  441. package/src/Dialog/DialogHeader.doc.mjs +2 -2
  442. package/src/Dialog/DialogHeader.tsx +9 -2
  443. package/src/Divider/Divider.tsx +2 -2
  444. package/src/DropdownMenu/DropdownMenu.test.tsx +169 -0
  445. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
  446. package/src/DropdownMenu/DropdownMenuItem.tsx +1 -1
  447. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
  448. package/src/Field/Field.test.tsx +57 -12
  449. package/src/Field/Field.tsx +6 -5
  450. package/src/Field/FieldLabel.tsx +9 -1
  451. package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
  452. package/src/FieldStatus/FieldStatus.test.tsx +150 -40
  453. package/src/FieldStatus/FieldStatus.tsx +63 -5
  454. package/src/FileInput/FileInput.doc.mjs +17 -2
  455. package/src/FileInput/FileInput.test.tsx +135 -12
  456. package/src/FileInput/FileInput.tsx +53 -28
  457. package/src/HoverCard/HoverCard.doc.mjs +13 -0
  458. package/src/HoverCard/HoverCard.test.tsx +21 -2
  459. package/src/HoverCard/HoverCard.tsx +11 -0
  460. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  461. package/src/HoverCard/useHoverCard.tsx +24 -2
  462. package/src/Icon/Icon.doc.mjs +3 -2
  463. package/src/Icon/Icon.tsx +7 -2
  464. package/src/IconButton/IconButton.doc.mjs +8 -0
  465. package/src/IconButton/IconButton.test.tsx +15 -18
  466. package/src/Item/Item.test.tsx +40 -18
  467. package/src/Item/Item.tsx +38 -2
  468. package/src/Layer/useLayer.tsx +8 -0
  469. package/src/Lightbox/Lightbox.tsx +4 -4
  470. package/src/List/List.test.tsx +9 -8
  471. package/src/MobileNav/MobileNav.tsx +12 -1
  472. package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
  473. package/src/MobileNav/MobileNavToggle.tsx +9 -1
  474. package/src/MultiSelector/MultiSelector.doc.mjs +13 -2
  475. package/src/MultiSelector/MultiSelector.test.tsx +195 -3
  476. package/src/MultiSelector/MultiSelector.tsx +65 -12
  477. package/src/MultiSelector/hooks.ts +17 -0
  478. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  479. package/src/NumberInput/NumberInput.doc.mjs +15 -0
  480. package/src/NumberInput/NumberInput.test.tsx +82 -7
  481. package/src/NumberInput/NumberInput.tsx +21 -4
  482. package/src/Outline/Outline.tsx +0 -1
  483. package/src/OverflowList/OverflowList.doc.mjs +39 -6
  484. package/src/OverflowList/OverflowList.test.tsx +111 -0
  485. package/src/OverflowList/OverflowList.tsx +48 -8
  486. package/src/Pagination/Pagination.tsx +11 -3
  487. package/src/Popover/Popover.tsx +7 -4
  488. package/src/Popover/usePopover.tsx +9 -13
  489. package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
  490. package/src/PowerSearch/PowerSearch.test.tsx +43 -0
  491. package/src/PowerSearch/PowerSearch.tsx +10 -1
  492. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
  493. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  494. package/src/PowerSearch/usePowerSearchSource.ts +1 -2
  495. package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
  496. package/src/SelectableCard/SelectableCard.test.tsx +46 -4
  497. package/src/SelectableCard/SelectableCard.tsx +29 -16
  498. package/src/Selector/Selector.doc.mjs +7 -0
  499. package/src/Selector/Selector.test.tsx +92 -0
  500. package/src/Selector/Selector.tsx +16 -2
  501. package/src/Selector/hooks.ts +17 -0
  502. package/src/SideNav/SideNav.test.tsx +119 -3
  503. package/src/SideNav/SideNavCollapseButton.tsx +6 -1
  504. package/src/SideNav/SideNavHeading.tsx +24 -8
  505. package/src/SideNav/SideNavItem.tsx +5 -1
  506. package/src/Slider/Slider.test.tsx +75 -2
  507. package/src/Slider/Slider.tsx +21 -5
  508. package/src/Switch/Switch.test.tsx +32 -1
  509. package/src/TabList/Tab.tsx +2 -2
  510. package/src/TabList/TabMenu.tsx +2 -2
  511. package/src/Table/BaseTable.tsx +3 -5
  512. package/src/Table/TableCell.tsx +3 -3
  513. package/src/Table/TableHeaderCell.tsx +3 -3
  514. package/src/Table/index.ts +5 -0
  515. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
  516. package/src/Table/plugins/rowStatus/index.ts +7 -0
  517. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
  518. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
  519. package/src/Table/plugins/selection/useTableSelection.test.tsx +16 -0
  520. package/src/Table/plugins/selection/useTableSelection.tsx +19 -1
  521. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
  522. package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
  523. package/src/Table/plugins/tree/useTableTreeData.tsx +128 -1
  524. package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
  525. package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
  526. package/src/Table/useBaseTablePlugins.ts +10 -6
  527. package/src/Table/useTableRowStatus.doc.mjs +30 -0
  528. package/src/Table/useTableSelection.doc.mjs +65 -14
  529. package/src/Table/useTableTreeData.doc.mjs +29 -0
  530. package/src/Table/useTableTreeState.doc.mjs +2 -2
  531. package/src/TextArea/TextArea.doc.mjs +15 -0
  532. package/src/TextArea/TextArea.test.tsx +32 -1
  533. package/src/TextArea/TextArea.tsx +10 -0
  534. package/src/TextInput/TextInput.doc.mjs +15 -0
  535. package/src/TextInput/TextInput.test.tsx +44 -0
  536. package/src/TextInput/TextInput.tsx +13 -1
  537. package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
  538. package/src/Thumbnail/Thumbnail.test.tsx +98 -7
  539. package/src/Thumbnail/Thumbnail.tsx +142 -42
  540. package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
  541. package/src/TimeInput/TimeInput.doc.mjs +15 -0
  542. package/src/TimeInput/TimeInput.test.tsx +99 -1
  543. package/src/TimeInput/TimeInput.tsx +29 -6
  544. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  545. package/src/Timestamp/Timestamp.test.tsx +32 -0
  546. package/src/Timestamp/Timestamp.tsx +28 -8
  547. package/src/Toast/useToast.tsx +7 -8
  548. package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
  549. package/src/Tokenizer/Tokenizer.doc.mjs +30 -1
  550. package/src/Tokenizer/Tokenizer.test.tsx +206 -2
  551. package/src/Tokenizer/Tokenizer.tsx +26 -4
  552. package/src/TopNav/TopNav.test.tsx +125 -1
  553. package/src/TopNav/TopNavHeading.tsx +24 -8
  554. package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
  555. package/src/TopNav/TopNavMegaMenu.tsx +10 -4
  556. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
  557. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
  558. package/src/TopNav/TopNavMenu.test.tsx +118 -4
  559. package/src/TopNav/TopNavMenu.tsx +83 -5
  560. package/src/TreeList/TreeList.doc.mjs +22 -0
  561. package/src/TreeList/TreeList.test.tsx +232 -0
  562. package/src/TreeList/TreeList.tsx +18 -2
  563. package/src/TreeList/TreeListBranches.tsx +16 -2
  564. package/src/TreeList/TreeListItem.tsx +52 -12
  565. package/src/TreeList/TreeListTypes.ts +27 -1
  566. package/src/TreeList/index.ts +2 -2
  567. package/src/Typeahead/BaseTypeahead.tsx +30 -15
  568. package/src/Typeahead/Typeahead.doc.mjs +7 -0
  569. package/src/Typeahead/Typeahead.test.tsx +50 -0
  570. package/src/Typeahead/Typeahead.tsx +10 -0
  571. package/src/authoring/doc.ts +1 -3
  572. package/src/docs-types.ts +5 -0
  573. package/src/hooks/computeOverflow.test.ts +422 -0
  574. package/src/hooks/computeOverflow.ts +290 -0
  575. package/src/hooks/index.ts +2 -0
  576. package/src/hooks/isRtlElement.ts +27 -0
  577. package/src/hooks/useDevWarning.test.tsx +45 -0
  578. package/src/hooks/useDevWarning.ts +54 -0
  579. package/src/hooks/useGridFocus.doc.mjs +3 -3
  580. package/src/hooks/useGridFocus.test.tsx +41 -0
  581. package/src/hooks/useGridFocus.ts +21 -10
  582. package/src/hooks/useListFocus.doc.mjs +3 -3
  583. package/src/hooks/useListFocus.test.tsx +67 -1
  584. package/src/hooks/useListFocus.ts +21 -5
  585. package/src/hooks/useOverflow.test.ts +96 -4
  586. package/src/hooks/useOverflow.ts +74 -33
  587. package/src/i18n/InternationalizationContext.ts +4 -0
  588. package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
  589. package/src/i18n/InternationalizationProvider.tsx +12 -2
  590. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  591. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  592. package/src/i18n/getLocaleDirection.ts +29 -0
  593. package/src/i18n/index.ts +6 -0
  594. package/src/i18n/resolve.ts +9 -21
  595. package/src/i18n/useDirection.ts +29 -0
  596. package/src/reset.css +0 -26
  597. package/src/reset.test.ts +60 -0
  598. package/src/theme/Theme.tsx +11 -14
  599. package/src/theme/derivedVarRegistry.test.ts +1 -0
  600. package/src/theme/derivedVarRegistry.ts +6 -0
  601. package/src/theme/generateThemeRules.test.ts +107 -0
  602. package/src/theme/generateThemeRules.ts +56 -0
  603. package/src/theme/hct.ts +1 -1
  604. package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
  605. package/src/utils/devWarning.test.ts +56 -0
  606. package/src/utils/devWarning.ts +102 -0
  607. package/src/utils/index.ts +6 -0
  608. package/src/utils/plainDate.test.ts +22 -0
  609. package/src/utils/plainDate.ts +61 -0
  610. package/src/utils/types.ts +14 -0
@@ -61,6 +61,20 @@ export const docs = {
61
61
  description: 'Minimum number of items to always show, even when overflowing.',
62
62
  default: '0',
63
63
  },
64
+ {
65
+ name: 'maxVisibleItems',
66
+ type: 'number',
67
+ description:
68
+ 'Maximum number of items to ever show, even when they all fit. The ceiling partner to minVisibleItems; extra items collapse into the overflow indicator. If less than minVisibleItems, the floor wins.',
69
+ default: 'undefined (no cap)',
70
+ },
71
+ {
72
+ name: 'maxRows',
73
+ type: 'number',
74
+ description:
75
+ 'Wrap items across up to this many rows before collapsing the rest into the overflow indicator. A number, not a boolean. Leave undefined (or set 1) for single-line behavior. Assumes uniform row height.',
76
+ default: 'undefined (single line)',
77
+ },
64
78
  {
65
79
  name: 'collapseFrom',
66
80
  type: "'start' | 'end'",
@@ -91,8 +105,9 @@ export const docs = {
91
105
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
92
106
  bestPractices: [
93
107
  { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
94
- { guidance: true, description: 'Set minVisibleItems to keep key items visible regardless of container size.' },
95
- { guidance: false, description: 'Use OverflowList for vertical layouts; it only works with horizontal rows.' },
108
+ { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
109
+ { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
110
+ { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
96
111
  ],
97
112
  },
98
113
  };
@@ -127,6 +142,20 @@ export const docsZh = {
127
142
  description: '溢出时始终显示的最小项目数。',
128
143
  default: '0',
129
144
  },
145
+ {
146
+ name: 'maxVisibleItems',
147
+ type: 'number',
148
+ description:
149
+ '始终显示的最大项目数(即使全部都能放下)。它是 minVisibleItems 的上限伙伴;多余项目会折叠进溢出指示器。若小于 minVisibleItems,则以下限为准。',
150
+ default: 'undefined(无上限)',
151
+ },
152
+ {
153
+ name: 'maxRows',
154
+ type: 'number',
155
+ description:
156
+ '在将其余项目折叠进溢出指示器之前,允许项目换行到的最大行数。是数字而非布尔值。留空(或设为 1)表示单行。假定行高一致。',
157
+ default: 'undefined(单行)',
158
+ },
130
159
  {
131
160
  name: 'collapseFrom',
132
161
  type: "'start' | 'end'",
@@ -152,8 +181,9 @@ export const docsZh = {
152
181
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
153
182
  bestPractices: [
154
183
  { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
155
- { guidance: true, description: 'Set minVisibleItems to keep key items visible regardless of container size.' },
156
- { guidance: false, description: 'Use OverflowList for vertical layouts; it only works with horizontal rows.' },
184
+ { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
185
+ { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
186
+ { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
157
187
  ],
158
188
  },
159
189
  };
@@ -166,8 +196,9 @@ export const docsDense = {
166
196
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
167
197
  bestPractices: [
168
198
  { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
169
- { guidance: true, description: 'Set minVisibleItems to keep key items visible regardless of container size.' },
170
- { guidance: false, description: 'Use OverflowList for vertical layouts; it only works with horizontal rows.' },
199
+ { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
200
+ { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
201
+ { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
171
202
  ],
172
203
  },
173
204
  propDescriptions: {
@@ -175,6 +206,8 @@ export const docsDense = {
175
206
  overflowRenderer: 'renders overflow indicator, receives hidden items w/ index',
176
207
  gap: 'item gap as spacing step',
177
208
  minVisibleItems: 'min items always shown even when overflowing',
209
+ maxVisibleItems: 'max items ever shown (cap); extra items collapse to indicator; min wins if smaller',
210
+ maxRows: 'wrap items across up to N rows then collapse rest (number, not boolean); undefined = single line',
178
211
  collapseFrom: 'which end to collapse from',
179
212
  behavior: 'observeSelf (default) or observeParent for content-sized containers',
180
213
  xstyle: 'StyleX styles, use stylex.create() values only',
@@ -413,4 +413,115 @@ describe('OverflowList', () => {
413
413
  expect(OverflowList.displayName).toBe('OverflowList');
414
414
  });
415
415
  });
416
+
417
+ describe('maxVisibleItems (cap)', () => {
418
+ it('caps visible items even when they all fit', () => {
419
+ render(
420
+ <OverflowList
421
+ gap={0}
422
+ data-w="1000"
423
+ data-testid="ov"
424
+ maxVisibleItems={2}
425
+ overflowRenderer={indicator('more:')}>
426
+ <button type="button" data-w="40">
427
+ A
428
+ </button>
429
+ <button type="button" data-w="40">
430
+ B
431
+ </button>
432
+ <button type="button" data-w="40">
433
+ C
434
+ </button>
435
+ <button type="button" data-w="40">
436
+ D
437
+ </button>
438
+ </OverflowList>,
439
+ );
440
+ const vis = visibleContainer();
441
+ expect(within(vis).getByText('A')).toBeInTheDocument();
442
+ expect(within(vis).getByText('B')).toBeInTheDocument();
443
+ expect(within(vis).queryByText('C')).not.toBeInTheDocument();
444
+ expect(within(vis).getByText('more:2,3')).toBeInTheDocument();
445
+ });
446
+
447
+ it('min wins over a smaller cap (D1)', () => {
448
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
449
+ render(
450
+ <OverflowList
451
+ gap={0}
452
+ data-w="1000"
453
+ data-testid="ov"
454
+ minVisibleItems={3}
455
+ maxVisibleItems={1}
456
+ overflowRenderer={indicator('more:')}>
457
+ <button type="button" data-w="40">
458
+ A
459
+ </button>
460
+ <button type="button" data-w="40">
461
+ B
462
+ </button>
463
+ <button type="button" data-w="40">
464
+ C
465
+ </button>
466
+ <button type="button" data-w="40">
467
+ D
468
+ </button>
469
+ </OverflowList>,
470
+ );
471
+ const vis = visibleContainer();
472
+ expect(within(vis).getByText('A')).toBeInTheDocument();
473
+ expect(within(vis).getByText('B')).toBeInTheDocument();
474
+ expect(within(vis).getByText('C')).toBeInTheDocument();
475
+ expect(within(vis).queryByText('D')).not.toBeInTheDocument();
476
+ expect(warn).toHaveBeenCalled();
477
+ warn.mockRestore();
478
+ });
479
+ });
480
+
481
+ describe('maxRows (multi-row)', () => {
482
+ it('applies a different container class when maxRows enables wrapping', () => {
483
+ const {rerender} = render(
484
+ <OverflowList gap={0} data-w="1000" data-testid="ov">
485
+ <button type="button" data-w="40">
486
+ A
487
+ </button>
488
+ </OverflowList>,
489
+ );
490
+ const singleLine = visibleContainer().getAttribute('class');
491
+
492
+ rerender(
493
+ <OverflowList gap={0} data-w="1000" data-testid="ov" maxRows={2}>
494
+ <button type="button" data-w="40">
495
+ A
496
+ </button>
497
+ </OverflowList>,
498
+ );
499
+ const multiRow = visibleContainer().getAttribute('class');
500
+ expect(multiRow).not.toEqual(singleLine);
501
+ });
502
+
503
+ it('keeps single-line behavior with maxRows={1}', () => {
504
+ render(
505
+ <OverflowList
506
+ gap={0}
507
+ data-w="100"
508
+ data-testid="ov"
509
+ maxRows={1}
510
+ overflowRenderer={indicator('more:')}>
511
+ <button type="button" data-w="40">
512
+ A
513
+ </button>
514
+ <button type="button" data-w="40">
515
+ B
516
+ </button>
517
+ <button type="button" data-w="40">
518
+ C
519
+ </button>
520
+ </OverflowList>,
521
+ );
522
+ const vis = visibleContainer();
523
+ expect(within(vis).getByText('A')).toBeInTheDocument();
524
+ expect(within(vis).queryByText('B')).not.toBeInTheDocument();
525
+ });
526
+ });
416
527
  });
@@ -9,8 +9,9 @@
9
9
  * @position Core implementation; consumed by index.ts
10
10
  *
11
11
  * Renders a horizontal list of items, hiding those that don't fit in the
12
- * available width and optionally showing an overflow indicator.
13
- * Uses a hidden measurement container to avoid flickering.
12
+ * available width and optionally showing an overflow indicator. Supports an
13
+ * optional item cap (`maxVisibleItems`) and bounded multi-row wrapping
14
+ * (`maxRows`). Uses a hidden measurement container to avoid flickering.
14
15
  *
15
16
  * SYNC: When modified, update these files to stay in sync:
16
17
  * - /packages/core/src/OverflowList/index.ts (exports if types change)
@@ -34,6 +35,14 @@ const styles = stylex.create({
34
35
  whiteSpace: 'nowrap',
35
36
  minWidth: 0,
36
37
  },
38
+ containerMultiRow: {
39
+ display: 'flex',
40
+ flexWrap: 'wrap',
41
+ alignContent: 'flex-start',
42
+ overflow: 'hidden',
43
+ whiteSpace: 'normal',
44
+ minWidth: 0,
45
+ },
37
46
  fillParent: {
38
47
  width: '100%',
39
48
  },
@@ -52,6 +61,12 @@ const styles = stylex.create({
52
61
  },
53
62
  });
54
63
 
64
+ const multiRowHeight = stylex.create({
65
+ height: (maxRows: number, rowHeight: number, gapPx: number) => ({
66
+ maxHeight: `calc(${rowHeight}px * ${maxRows} + ${gapPx}px * ${maxRows - 1})`,
67
+ }),
68
+ });
69
+
55
70
  const gapStyles = stylex.create({
56
71
  0: {gap: spacingVars['--spacing-0']},
57
72
  0.5: {gap: spacingVars['--spacing-0-5']},
@@ -112,6 +127,24 @@ export interface OverflowListProps extends BaseProps<HTMLDivElement> {
112
127
  */
113
128
  minVisibleItems?: number;
114
129
 
130
+ /**
131
+ * Maximum number of items to ever show, even when they all fit. The ceiling
132
+ * partner to `minVisibleItems`; extra items collapse into the overflow
133
+ * indicator. Leave undefined for no cap. If it is less than
134
+ * `minVisibleItems`, the floor wins (and a dev-only warning is logged).
135
+ * @default undefined
136
+ */
137
+ maxVisibleItems?: number;
138
+
139
+ /**
140
+ * Wrap items across up to this many rows before collapsing the remainder
141
+ * into the overflow indicator. Leave undefined (or set `1`) for the default
142
+ * single-line behavior. A number, not a boolean — unbounded wrapping is a
143
+ * plain flex-wrap layout, not overflow collapse. Assumes uniform row height.
144
+ * @default undefined
145
+ */
146
+ maxRows?: number;
147
+
115
148
  /**
116
149
  * Which end to collapse items from.
117
150
  * @default 'end'
@@ -180,6 +213,8 @@ export function OverflowList({
180
213
  children,
181
214
  gap = 2,
182
215
  minVisibleItems = 0,
216
+ maxVisibleItems,
217
+ maxRows,
183
218
  collapseFrom = 'end',
184
219
  behavior = 'observeSelf',
185
220
  overflowRenderer,
@@ -195,16 +230,17 @@ export function OverflowList({
195
230
  const gapPx = spacingToPx[gap];
196
231
 
197
232
  const observeParent = behavior === 'observeParent';
233
+ const isMultiRow = maxRows != null && maxRows > 1;
198
234
 
199
- const {containerRef, measureRef, visibleCount, hasOverflow} = useOverflow(
200
- itemCount,
201
- {
235
+ const {containerRef, measureRef, visibleCount, hasOverflow, rowHeight} =
236
+ useOverflow(itemCount, {
202
237
  gap: gapPx,
203
238
  minVisibleItems,
239
+ maxVisibleItems,
240
+ maxRows,
204
241
  collapseFrom,
205
242
  behavior,
206
- },
207
- );
243
+ });
208
244
 
209
245
  const allItems: OverflowItem[] = childArray.map((child, index) => ({
210
246
  child,
@@ -248,8 +284,12 @@ export function OverflowList({
248
284
  {...mergeProps(
249
285
  themeProps('overflow-list'),
250
286
  stylex.props(
251
- styles.container,
287
+ isMultiRow ? styles.containerMultiRow : styles.container,
252
288
  gapStyles[gap],
289
+ isMultiRow &&
290
+ rowHeight > 0 &&
291
+ maxRows != null &&
292
+ multiRowHeight.height(maxRows, rowHeight, gapPx),
253
293
  observeParent && hasOverflow && styles.fillParent,
254
294
  xstyle,
255
295
  ),
@@ -4,7 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file Pagination.tsx
7
- * @input Uses React, StyleX, Button, Icon, Selector, Text; page number buttons delegate to Button
7
+ * @input Uses React, StyleX, Button, Icon, Selector, Text; page number buttons delegate to Button.
8
+ * Reads i18n direction via useDirection() to flip the prev/next chevrons under RTL.
8
9
  * @output Exports Pagination component, PaginationProps, PaginationVariant, PaginationSize types
9
10
  * @position Core implementation; consumed by index.ts, tested by Pagination.test.tsx
10
11
  *
@@ -40,6 +41,7 @@ import {mergeProps} from '../utils';
40
41
  import type {BaseProps} from '../BaseProps';
41
42
  import {themeProps} from '../utils/themeProps';
42
43
  import {useTranslator} from '../i18n/useTranslator';
44
+ import {useDirection} from '../i18n/useDirection';
43
45
 
44
46
  // =============================================================================
45
47
  // Types
@@ -360,6 +362,12 @@ export function Pagination({
360
362
  const label = labelFromProps ?? t('@astryx.pagination.label');
361
363
  const previousLabel = t('@astryx.pagination.previous');
362
364
  const nextLabel = t('@astryx.pagination.next');
365
+
366
+ // Directional icons: under RTL, the "previous" control points right and the
367
+ // "next" control points left. aria-labels stay semantic (unchanged).
368
+ const direction = useDirection();
369
+ const previousIcon = direction === 'rtl' ? 'chevronRight' : 'chevronLeft';
370
+ const nextIcon = direction === 'rtl' ? 'chevronLeft' : 'chevronRight';
363
371
  const pageIndicatorsLabel = t('@astryx.pagination.pageIndicators');
364
372
  const itemsPerPageLabel = t('@astryx.pagination.itemsPerPage');
365
373
 
@@ -663,7 +671,7 @@ export function Pagination({
663
671
  label={previousLabel}
664
672
  variant="ghost"
665
673
  size={buttonSize}
666
- icon={<Icon icon="chevronLeft" size={isSm ? 'sm' : 'md'} />}
674
+ icon={<Icon icon={previousIcon} size={isSm ? 'sm' : 'md'} />}
667
675
  onClick={handlePrevious}
668
676
  isDisabled={isDisabled || !hasPrevious}
669
677
  isIconOnly
@@ -675,7 +683,7 @@ export function Pagination({
675
683
  label={nextLabel}
676
684
  variant="ghost"
677
685
  size={buttonSize}
678
- icon={<Icon icon="chevronRight" size={isSm ? 'sm' : 'md'} />}
686
+ icon={<Icon icon={nextIcon} size={isSm ? 'sm' : 'md'} />}
679
687
  onClick={handleNext}
680
688
  isDisabled={isDisabled || !hasNext}
681
689
  isIconOnly
@@ -26,6 +26,7 @@ import React, {
26
26
  import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
27
27
  import * as stylex from '@stylexjs/stylex';
28
28
  import {mergeProps} from '../utils';
29
+ import {devWarn} from '../utils/devWarning';
29
30
  import type {BaseProps} from '../BaseProps';
30
31
  import {usePopover} from './usePopover';
31
32
  import type {LayerAlignment, LayerPlacement} from '../Layer/useLayer';
@@ -410,8 +411,9 @@ export function Popover({
410
411
 
411
412
  const button = findTriggerButton(el);
412
413
  if (!button) {
413
- console.warn(
414
- 'Popover: anchorRef must reference a <button> or [role="button"] element. ' +
414
+ devWarn(
415
+ 'Popover',
416
+ 'anchorRef must reference a <button> or [role="button"] element. ' +
415
417
  'The popover trigger implements the button + dialog ARIA pattern.',
416
418
  );
417
419
  }
@@ -453,8 +455,9 @@ export function Popover({
453
455
  // Find the button inside the wrapper
454
456
  const button = findTriggerButton(wrapper);
455
457
  if (!button) {
456
- console.warn(
457
- 'Popover: children must contain a <button> or [role="button"] element. ' +
458
+ devWarn(
459
+ 'Popover',
460
+ 'children must contain a <button> or [role="button"] element. ' +
458
461
  'The popover trigger implements the button + dialog ARIA pattern.',
459
462
  );
460
463
  }
@@ -28,6 +28,7 @@ import {
28
28
  } from '../theme/tokens.stylex';
29
29
  import {Button} from '../Button';
30
30
  import {useTranslator} from '../i18n';
31
+ import {useDevWarning} from '../hooks/useDevWarning';
31
32
 
32
33
  const styles = stylex.create({
33
34
  // Default popover surface — background, radius, shadow.
@@ -391,19 +392,14 @@ export function usePopover(options: UsePopoverOptions = {}): UsePopoverReturn {
391
392
  'aria-controls': layer.id,
392
393
  };
393
394
 
394
- // Dev-time guardrail: a dialog popover should always be labeled. Warn once
395
- // per hook instance (in an effect) rather than on every render.
396
- const warnedUnnamedDialogRef = useRef(false);
397
- useEffect(() => {
398
- if (role === 'dialog' && !dialogLabel && !warnedUnnamedDialogRef.current) {
399
- warnedUnnamedDialogRef.current = true;
400
- console.warn(
401
- 'usePopover: role="dialog" without a `dialogLabel` renders an unnamed ' +
402
- 'dialog. Pass `dialogLabel`, or use `role: "none"` for listbox/menu ' +
403
- 'popups whose content already carries its own role.',
404
- );
405
- }
406
- }, [role, dialogLabel]);
395
+ // Dev-time guardrail: a dialog popover should always be labeled.
396
+ useDevWarning(
397
+ 'usePopover',
398
+ 'role="dialog" without a `dialogLabel` renders an unnamed ' +
399
+ 'dialog. Pass `dialogLabel`, or use `role: "none"` for listbox/menu ' +
400
+ 'popups whose content already carries its own role.',
401
+ role === 'dialog' && !dialogLabel,
402
+ );
407
403
 
408
404
  // Wrapped render function that includes surface styles and optional hidden close button
409
405
  const render = useCallback(
@@ -83,6 +83,20 @@ export const docs = {
83
83
  description:
84
84
  'Validation status object with type and optional message.',
85
85
  },
86
+ {
87
+ name: 'startIcon',
88
+ type: 'ReactNode | IconType',
89
+ description:
90
+ 'Icon to display at the start of the input, before any filter tokens. Forwarded to the internal Tokenizer. Accepts a semantic icon name, an SVG icon component, or a ReactNode directly.',
91
+ slotElements: [{__element: 'Icon', props: {icon: 'search', size: 'sm'}}],
92
+ },
93
+ {
94
+ name: 'statusVariant',
95
+ type: "'attached' | 'detached'",
96
+ description:
97
+ 'How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing.',
98
+ default: "'attached'",
99
+ },
86
100
  {
87
101
  name: 'maxTokenLength',
88
102
  type: 'number',
@@ -235,6 +249,19 @@ export const docsZh = {
235
249
  type: "{type: 'warning' | 'error' | 'success', message?: string}",
236
250
  description: '带有类型和可选消息的验证状态对象。',
237
251
  },
252
+ {
253
+ name: 'startIcon',
254
+ type: 'ReactNode | IconType',
255
+ description:
256
+ '在输入框开头(筛选 token 之前)显示的图标,转发给内部的 Tokenizer。接受语义图标名称、SVG 图标组件或直接传入 ReactNode。',
257
+ },
258
+ {
259
+ name: 'statusVariant',
260
+ type: "'attached' | 'detached'",
261
+ description:
262
+ '状态消息相对于输入框的放置方式。attached 直接叠加在输入框下方(带边框处理);detached 作为独立元素浮于下方并留有间距。',
263
+ default: "'attached'",
264
+ },
238
265
  {
239
266
  name: 'maxTokenLength',
240
267
  type: 'number',
@@ -318,6 +345,8 @@ export const docsDense = {
318
345
  isReadOnly: 'Prevent adding, editing, or removing filters.',
319
346
  isDisabled: 'Disables entire component.',
320
347
  status: 'Validation status object w/ type + optional message.',
348
+ startIcon: 'Icon at input start, before filter tokens. Forwarded to internal Tokenizer.',
349
+ statusVariant: 'How status message is placed: attached overlaps below input; detached floats below w/ spacing.',
321
350
  maxTokenLength: 'Max char length for filter value display in tokens.',
322
351
  popoverSaveButtonLabel: 'Label for save button in edit popover.',
323
352
  timezoneID: 'Timezone ID for date formatting (e.g. "America/New_York").',
@@ -16,6 +16,7 @@ import userEvent from '@testing-library/user-event';
16
16
  import {PowerSearch} from './PowerSearch';
17
17
  import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
18
18
  import type {PowerSearchConfig, PowerSearchFilter} from './types';
19
+ import {TestIcon} from '../__tests__/TestIcon';
19
20
 
20
21
  // =============================================================================
21
22
  // Test infrastructure
@@ -157,6 +158,25 @@ describe('PowerSearch', () => {
157
158
  expect(screen.getByRole('combobox')).toHaveFocus();
158
159
  });
159
160
 
161
+ describe('startIcon', () => {
162
+ it('does not render a start icon when omitted', () => {
163
+ render(<PowerSearch config={config} filters={[]} onChange={() => {}} />);
164
+ expect(document.querySelector('svg')).not.toBeInTheDocument();
165
+ });
166
+
167
+ it('forwards startIcon to the internal Tokenizer', () => {
168
+ render(
169
+ <PowerSearch
170
+ config={config}
171
+ filters={[]}
172
+ onChange={() => {}}
173
+ startIcon={<TestIcon data-testid="start-icon" />}
174
+ />,
175
+ );
176
+ expect(screen.getByTestId('start-icon')).toBeInTheDocument();
177
+ });
178
+ });
179
+
160
180
  describe('paste behavior', () => {
161
181
  it('pasting a field name shows matching field suggestions', async () => {
162
182
  const user = userEvent.setup();
@@ -404,3 +424,26 @@ describe('PowerSearch', () => {
404
424
  });
405
425
  });
406
426
  });
427
+
428
+
429
+ describe('PowerSearch statusVariant forwarding', () => {
430
+ it('defaults to attached (status renders with data-variant="attached")', () => {
431
+ const {container} = render(
432
+ <PowerSearch config={config} filters={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
433
+ );
434
+ expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
435
+ 'data-variant',
436
+ 'attached',
437
+ );
438
+ });
439
+
440
+ it('forwards statusVariant="detached" to the underlying Field status', () => {
441
+ const {container} = render(
442
+ <PowerSearch config={config} filters={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
443
+ );
444
+ expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
445
+ 'data-variant',
446
+ 'detached',
447
+ );
448
+ });
449
+ });
@@ -37,7 +37,7 @@ import {layerAnimations} from '../Layer/layerAnimations.stylex';
37
37
  import {Icon} from '../Icon';
38
38
  import type {IconType} from '../Icon';
39
39
  import type {IconName} from '../Icon/globalIconRegistry';
40
- import type {InputStatus} from '../Field';
40
+ import type {InputStatus, FieldStatusVariant} from '../Field';
41
41
  import {usePopover} from '../Popover/usePopover';
42
42
  import {useAnnounce} from '../hooks/useAnnounce';
43
43
  import {
@@ -383,6 +383,13 @@ export interface PowerSearchProps extends Omit<
383
383
  onBlur?: (e: React.FocusEvent) => void;
384
384
  /** Validation status. */
385
385
  status?: InputStatus;
386
+ /**
387
+ * How the status message is placed relative to the input.
388
+ * - 'attached': message overlaps directly below the input (bordered treatment)
389
+ * - 'detached': message floats below as a separate element with spacing
390
+ * @default 'attached'
391
+ */
392
+ statusVariant?: FieldStatusVariant;
386
393
  /** Max width for dropdown menu. */
387
394
  menuWidth?: number;
388
395
  /** Max display length for filter token values. @default 40 */
@@ -527,6 +534,7 @@ export function PowerSearch({
527
534
  onFocus,
528
535
  onBlur,
529
536
  status,
537
+ statusVariant = 'attached',
530
538
  maxTokenLength = 40,
531
539
  popoverSaveButtonLabel: popoverSaveButtonLabelFromProps,
532
540
  timezoneID,
@@ -1033,6 +1041,7 @@ export function PowerSearch({
1033
1041
  hasEntriesOnFocus
1034
1042
  debounceMs={0}
1035
1043
  status={status}
1044
+ statusVariant={statusVariant}
1036
1045
  onFocus={onFocus}
1037
1046
  onBlur={onBlur}
1038
1047
  xstyle={xstyle}
@@ -13,6 +13,8 @@ import {
13
13
  import {render, screen, fireEvent, act} from '@testing-library/react';
14
14
  import React, {useState} from 'react';
15
15
  import {PowerSearch} from './PowerSearch';
16
+ import {PowerSearchEditPopover} from './PowerSearchEditPopover';
17
+ import {useInternalConfig} from './useInternalConfig';
16
18
  import type {PowerSearchConfig, PowerSearchFilter} from './types';
17
19
 
18
20
  // =============================================================================
@@ -216,4 +218,69 @@ describe('PowerSearch', () => {
216
218
  expect(popoverText).toContain('Priority');
217
219
  expect(popoverText).toContain('equals');
218
220
  });
221
+
222
+ it('does not save/close edit popover when Enter is consumed by child listbox option selection', () => {
223
+ const multiConfig: PowerSearchConfig = {
224
+ name: 'test-multi',
225
+ fields: [
226
+ {
227
+ key: 'status',
228
+ label: 'Status',
229
+ operators: [
230
+ {
231
+ key: 'any_of',
232
+ label: 'is any of',
233
+ value: {
234
+ type: 'enum_list',
235
+ values: [
236
+ {value: 'open', label: 'Open'},
237
+ {value: 'closed', label: 'Closed'},
238
+ ],
239
+ },
240
+ },
241
+ ],
242
+ },
243
+ ],
244
+ };
245
+
246
+ const onSave = vi.fn();
247
+ const onCancel = vi.fn();
248
+
249
+ function MultiSelectHarness() {
250
+ const internalConfig = useInternalConfig(multiConfig);
251
+ return (
252
+ <PowerSearchEditPopover
253
+ config={internalConfig}
254
+ filter={{
255
+ field: 'status',
256
+ operator: 'any_of',
257
+ value: {type: 'enum_list', value: ['open']},
258
+ }}
259
+ mode="edit"
260
+ onSave={onSave}
261
+ onCancel={onCancel}
262
+ />
263
+ );
264
+ }
265
+
266
+ const {container} = render(<MultiSelectHarness />);
267
+
268
+ const input = container.querySelector('input');
269
+ expect(input).not.toBeNull();
270
+
271
+ // Fire an Enter event that has been defaultPrevented (e.g. child typeahead option selection)
272
+ const enterEvent = new KeyboardEvent('keydown', {
273
+ key: 'Enter',
274
+ bubbles: true,
275
+ cancelable: true,
276
+ });
277
+ enterEvent.preventDefault();
278
+
279
+ act(() => {
280
+ input?.dispatchEvent(enterEvent);
281
+ });
282
+
283
+ // onSave should NOT be called because the event was already consumed (defaultPrevented)
284
+ expect(onSave).not.toHaveBeenCalled();
285
+ });
219
286
  });
@@ -702,7 +702,7 @@ export function PowerSearchEditPopover({
702
702
  // Handle Enter to save, Escape to cancel
703
703
  const handleKeyDown = useCallback(
704
704
  (e: React.KeyboardEvent) => {
705
- if (e.key === 'Enter' && !isSaveDisabled) {
705
+ if (e.key === 'Enter' && !isSaveDisabled && !e.defaultPrevented) {
706
706
  e.preventDefault();
707
707
  handleSave();
708
708
  } else if (e.key === 'Escape' && !e.defaultPrevented) {