@astryxdesign/core 0.1.5 → 0.1.6-canary.02f2602

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 (564) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +2 -0
  3. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  4. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  5. package/dist/AlertDialog/AlertDialog.js +21 -18
  6. package/dist/AlertDialog/useImperativeAlertDialog.d.ts +0 -2
  7. package/dist/AlertDialog/useImperativeAlertDialog.d.ts.map +1 -1
  8. package/dist/AlertDialog/useImperativeAlertDialog.js +3 -5
  9. package/dist/AppShell/AppShell.d.ts.map +1 -1
  10. package/dist/AppShell/AppShell.js +55 -53
  11. package/dist/AspectRatio/AspectRatio.js +5 -5
  12. package/dist/Avatar/Avatar.js +19 -19
  13. package/dist/Avatar/AvatarStatusDot.js +5 -5
  14. package/dist/AvatarGroup/AvatarGroup.d.ts +1 -1
  15. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.js +9 -6
  17. package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -5
  18. package/dist/Badge/Badge.js +3 -3
  19. package/dist/Banner/Banner.d.ts.map +1 -1
  20. package/dist/Banner/Banner.js +32 -30
  21. package/dist/Blockquote/Blockquote.js +7 -7
  22. package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
  23. package/dist/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  24. package/dist/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  25. package/dist/Breadcrumbs/Breadcrumbs.js +11 -8
  26. package/dist/Button/Button.d.ts.map +1 -1
  27. package/dist/Button/Button.js +53 -23
  28. package/dist/ButtonGroup/ButtonGroup.d.ts +20 -5
  29. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  30. package/dist/ButtonGroup/ButtonGroup.js +34 -18
  31. package/dist/Calendar/Calendar.d.ts.map +1 -1
  32. package/dist/Calendar/Calendar.js +51 -48
  33. package/dist/Card/Card.js +3 -3
  34. package/dist/Carousel/Carousel.d.ts +1 -1
  35. package/dist/Carousel/Carousel.d.ts.map +1 -1
  36. package/dist/Carousel/Carousel.js +27 -24
  37. package/dist/Center/Center.js +3 -3
  38. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  39. package/dist/Chat/ChatComposer.js +27 -24
  40. package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
  41. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  42. package/dist/Chat/ChatComposerDrawer.js +23 -16
  43. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  44. package/dist/Chat/ChatComposerInput.js +20 -16
  45. package/dist/Chat/ChatDictationButton.js +10 -10
  46. package/dist/Chat/ChatLayout.d.ts +1 -11
  47. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  48. package/dist/Chat/ChatLayout.js +23 -21
  49. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  50. package/dist/Chat/ChatLayoutScrollButton.js +13 -11
  51. package/dist/Chat/ChatMessage.d.ts +1 -1
  52. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  53. package/dist/Chat/ChatMessage.js +20 -14
  54. package/dist/Chat/ChatMessageBubble.d.ts +1 -1
  55. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  56. package/dist/Chat/ChatMessageBubble.js +10 -8
  57. package/dist/Chat/ChatMessageList.d.ts +1 -1
  58. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  59. package/dist/Chat/ChatMessageList.js +17 -15
  60. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  61. package/dist/Chat/ChatMessageMetadata.js +24 -19
  62. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  63. package/dist/Chat/ChatPastedTextToken.js +16 -14
  64. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  65. package/dist/Chat/ChatSendButton.js +6 -4
  66. package/dist/Chat/ChatSystemMessage.js +11 -11
  67. package/dist/Chat/ChatTokenizedText.js +8 -8
  68. package/dist/Chat/ChatToolCalls.js +73 -73
  69. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  70. package/dist/Chat/useSpeechRecognition.js +4 -2
  71. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  72. package/dist/Chat/useTriggerMenu.js +19 -17
  73. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  74. package/dist/CheckboxInput/CheckboxInput.js +26 -24
  75. package/dist/CheckboxList/CheckboxList.d.ts +1 -1
  76. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  77. package/dist/CheckboxList/CheckboxList.js +12 -10
  78. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  79. package/dist/CheckboxList/CheckboxListItem.js +8 -6
  80. package/dist/Citation/Citation.d.ts.map +1 -1
  81. package/dist/Citation/Citation.js +20 -12
  82. package/dist/ClickableCard/ClickableCard.js +6 -6
  83. package/dist/Code/Code.js +3 -3
  84. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  85. package/dist/CodeBlock/CodeBlock.js +114 -96
  86. package/dist/Collapsible/Collapsible.js +11 -11
  87. package/dist/Collapsible/CollapsibleGroup.js +7 -7
  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 +39 -34
  91. package/dist/CommandPalette/CommandPaletteEmpty.js +3 -3
  92. package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
  93. package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
  94. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  95. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  96. package/dist/CommandPalette/CommandPaletteInput.js +17 -14
  97. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  98. package/dist/CommandPalette/CommandPaletteList.d.ts +1 -1
  99. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  100. package/dist/CommandPalette/CommandPaletteList.js +7 -4
  101. package/dist/ContextMenu/ContextMenu.d.ts +1 -1
  102. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  103. package/dist/ContextMenu/ContextMenu.js +14 -11
  104. package/dist/DateInput/DateInput.d.ts +1 -1
  105. package/dist/DateInput/DateInput.d.ts.map +1 -1
  106. package/dist/DateInput/DateInput.js +28 -23
  107. package/dist/DateRangeInput/DateRangeInput.d.ts +1 -1
  108. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  109. package/dist/DateRangeInput/DateRangeInput.js +32 -27
  110. package/dist/DateTimeInput/DateTimeInput.d.ts +1 -1
  111. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  112. package/dist/DateTimeInput/DateTimeInput.js +41 -33
  113. package/dist/Dialog/Dialog.js +9 -9
  114. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  115. package/dist/Dialog/DialogHeader.js +20 -18
  116. package/dist/Dialog/useImperativeDialog.js +3 -3
  117. package/dist/Divider/Divider.js +7 -7
  118. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
  119. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  120. package/dist/DropdownMenu/DropdownMenu.js +21 -15
  121. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  122. package/dist/DropdownMenu/renderDropdownItems.js +10 -10
  123. package/dist/EmptyState/EmptyState.d.ts +4 -1
  124. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  125. package/dist/EmptyState/EmptyState.js +9 -9
  126. package/dist/Field/Field.js +17 -17
  127. package/dist/Field/FieldLabel.js +15 -15
  128. package/dist/Field/InputClearButton.js +5 -5
  129. package/dist/FieldStatus/FieldStatus.js +3 -3
  130. package/dist/FileInput/FileInput.d.ts.map +1 -1
  131. package/dist/FileInput/FileInput.js +34 -30
  132. package/dist/FormLayout/FormLayout.js +5 -5
  133. package/dist/Grid/Grid.js +3 -3
  134. package/dist/Grid/GridSpan.js +3 -3
  135. package/dist/HStack/HStack.js +3 -3
  136. package/dist/Heading/Heading.js +10 -10
  137. package/dist/HoverCard/HoverCard.js +9 -9
  138. package/dist/HoverCard/useHoverCard.js +3 -3
  139. package/dist/Icon/Icon.js +11 -11
  140. package/dist/Icon/defaultIcons.js +116 -116
  141. package/dist/IconButton/IconButton.js +3 -3
  142. package/dist/InputGroup/InputGroup.js +9 -9
  143. package/dist/InputGroup/InputGroupText.js +3 -3
  144. package/dist/Item/Item.js +17 -17
  145. package/dist/Kbd/Kbd.js +5 -5
  146. package/dist/Layer/LayerProvider.js +7 -7
  147. package/dist/Layer/useLayer.js +5 -5
  148. package/dist/Layout/Layout.js +21 -21
  149. package/dist/Layout/LayoutContent.js +3 -3
  150. package/dist/Layout/LayoutFooter.js +5 -5
  151. package/dist/Layout/LayoutHeader.js +5 -5
  152. package/dist/Layout/LayoutPanel.js +3 -3
  153. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  154. package/dist/Lightbox/Lightbox.js +35 -33
  155. package/dist/Lightbox/useLightbox.d.ts +0 -1
  156. package/dist/Lightbox/useLightbox.d.ts.map +1 -1
  157. package/dist/Lightbox/useLightbox.js +3 -4
  158. package/dist/Link/Link.d.ts +5 -3
  159. package/dist/Link/Link.d.ts.map +1 -1
  160. package/dist/Link/Link.js +47 -18
  161. package/dist/Link/LinkProvider.js +3 -3
  162. package/dist/Link/useLinkify.js +3 -3
  163. package/dist/List/List.js +11 -11
  164. package/dist/List/ListItem.js +11 -11
  165. package/dist/Markdown/Markdown.d.ts.map +1 -1
  166. package/dist/Markdown/Markdown.js +111 -109
  167. package/dist/MetadataList/MetadataList.js +10 -10
  168. package/dist/MetadataList/MetadataListItem.js +15 -15
  169. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  170. package/dist/MobileNav/MobileNav.js +19 -17
  171. package/dist/MobileNav/MobileNavToggle.d.ts +1 -1
  172. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  173. package/dist/MobileNav/MobileNavToggle.js +9 -6
  174. package/dist/MoreMenu/MoreMenu.d.ts +1 -1
  175. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  176. package/dist/MoreMenu/MoreMenu.js +7 -4
  177. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  178. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  179. package/dist/MultiSelector/MultiSelector.js +69 -62
  180. package/dist/NavIcon/NavIcon.js +3 -3
  181. package/dist/NavMenu/NavHeadingMenu.js +5 -5
  182. package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
  183. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  184. package/dist/NumberInput/NumberInput.js +21 -17
  185. package/dist/Outline/Outline.d.ts +1 -1
  186. package/dist/Outline/Outline.d.ts.map +1 -1
  187. package/dist/Outline/Outline.js +19 -16
  188. package/dist/OverflowList/OverflowList.js +8 -8
  189. package/dist/Overlay/Overlay.js +3 -3
  190. package/dist/Overlay/OverlayScrim.js +5 -5
  191. package/dist/Overlay/useOverlay.d.ts +0 -3
  192. package/dist/Overlay/useOverlay.d.ts.map +1 -1
  193. package/dist/Overlay/useOverlay.js +3 -6
  194. package/dist/Pagination/Pagination.d.ts +1 -1
  195. package/dist/Pagination/Pagination.d.ts.map +1 -1
  196. package/dist/Pagination/Pagination.js +73 -46
  197. package/dist/Popover/Popover.js +16 -16
  198. package/dist/Popover/usePopover.d.ts.map +1 -1
  199. package/dist/Popover/usePopover.js +11 -8
  200. package/dist/PowerSearch/PowerSearch.d.ts +1 -1
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +95 -85
  203. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +1 -1
  204. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  205. package/dist/PowerSearch/PowerSearchEditPopover.js +109 -103
  206. package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
  207. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  208. package/dist/PowerSearch/PowerSearchToken.js +12 -8
  209. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  210. package/dist/PowerSearch/PowerSearchValueEditor.js +88 -75
  211. package/dist/PowerSearch/formatFilterValue.d.ts +2 -1
  212. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  213. package/dist/PowerSearch/formatFilterValue.js +19 -9
  214. package/dist/PowerSearch/index.d.ts +2 -1
  215. package/dist/PowerSearch/index.d.ts.map +1 -1
  216. package/dist/PowerSearch/index.js +1 -0
  217. package/dist/PowerSearch/resolveOperatorLabel.d.ts +23 -0
  218. package/dist/PowerSearch/resolveOperatorLabel.d.ts.map +1 -0
  219. package/dist/PowerSearch/resolveOperatorLabel.js +28 -0
  220. package/dist/PowerSearch/types.d.ts +28 -2
  221. package/dist/PowerSearch/types.d.ts.map +1 -1
  222. package/dist/PowerSearch/usePowerSearchConfig.d.ts.map +1 -1
  223. package/dist/PowerSearch/usePowerSearchConfig.js +27 -27
  224. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  225. package/dist/PowerSearch/usePowerSearchSource.js +15 -8
  226. package/dist/ProgressBar/ProgressBar.js +13 -13
  227. package/dist/RadioList/RadioList.js +7 -7
  228. package/dist/RadioList/RadioListItem.js +18 -18
  229. package/dist/Resizable/ResizeHandle.d.ts +1 -1
  230. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  231. package/dist/Resizable/ResizeHandle.js +10 -7
  232. package/dist/Section/Section.js +5 -5
  233. package/dist/SegmentedControl/SegmentedControl.js +5 -5
  234. package/dist/SegmentedControl/SegmentedControlItem.js +7 -7
  235. package/dist/SelectableCard/SelectableCard.js +5 -5
  236. package/dist/Selector/Selector.d.ts.map +1 -1
  237. package/dist/Selector/Selector.js +57 -51
  238. package/dist/Selector/SelectorOption.js +3 -3
  239. package/dist/SideNav/SideNav.d.ts.map +1 -1
  240. package/dist/SideNav/SideNav.js +38 -36
  241. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  242. package/dist/SideNav/SideNavCollapseButton.js +8 -6
  243. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  244. package/dist/SideNav/SideNavHeading.js +92 -90
  245. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  246. package/dist/SideNav/SideNavItem.js +49 -43
  247. package/dist/SideNav/SideNavSection.js +14 -14
  248. package/dist/Skeleton/Skeleton.js +3 -3
  249. package/dist/Slider/Slider.js +23 -23
  250. package/dist/Spinner/Spinner.js +9 -9
  251. package/dist/StatusDot/StatusDot.js +5 -5
  252. package/dist/Switch/Switch.d.ts.map +1 -1
  253. package/dist/Switch/Switch.js +29 -27
  254. package/dist/TabList/Tab.js +18 -18
  255. package/dist/TabList/TabList.d.ts +1 -1
  256. package/dist/TabList/TabList.d.ts.map +1 -1
  257. package/dist/TabList/TabList.js +9 -6
  258. package/dist/TabList/TabMenu.js +23 -23
  259. package/dist/Table/BaseTable.d.ts.map +1 -1
  260. package/dist/Table/BaseTable.js +39 -37
  261. package/dist/Table/Table.d.ts.map +1 -1
  262. package/dist/Table/Table.js +10 -8
  263. package/dist/Table/TableBody.js +3 -3
  264. package/dist/Table/TableCell.js +3 -3
  265. package/dist/Table/TableFooter.js +3 -3
  266. package/dist/Table/TableHeader.js +3 -3
  267. package/dist/Table/TableHeaderCell.js +3 -3
  268. package/dist/Table/TableRow.js +5 -5
  269. package/dist/Table/index.d.ts +4 -0
  270. package/dist/Table/index.d.ts.map +1 -1
  271. package/dist/Table/index.js +2 -0
  272. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -9
  273. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  274. package/dist/Table/plugins/filtering/useTableFiltering.js +127 -90
  275. package/dist/Table/plugins/groupedRows/index.d.ts +3 -0
  276. package/dist/Table/plugins/groupedRows/index.d.ts.map +1 -0
  277. package/dist/Table/plugins/groupedRows/index.js +3 -0
  278. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +78 -0
  279. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -0
  280. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +257 -0
  281. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  282. package/dist/Table/plugins/pagination/useTablePagination.js +12 -9
  283. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  284. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  285. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +30 -28
  286. package/dist/Table/plugins/rowIndex/index.d.ts +3 -0
  287. package/dist/Table/plugins/rowIndex/index.d.ts.map +1 -0
  288. package/dist/Table/plugins/rowIndex/index.js +3 -0
  289. package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts +50 -0
  290. package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts.map +1 -0
  291. package/dist/Table/plugins/rowIndex/useTableRowIndex.js +91 -0
  292. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  293. package/dist/Table/plugins/selection/useTableSelection.js +23 -20
  294. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  295. package/dist/Table/plugins/sortable/useTableSortable.js +23 -21
  296. package/dist/Table/tableContextMenu.js +9 -9
  297. package/dist/Text/Text.js +10 -10
  298. package/dist/TextArea/TextArea.js +14 -14
  299. package/dist/TextInput/TextInput.d.ts.map +1 -1
  300. package/dist/TextInput/TextInput.js +20 -16
  301. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  302. package/dist/Thumbnail/Thumbnail.js +37 -31
  303. package/dist/TimeInput/TimeInput.d.ts +1 -1
  304. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  305. package/dist/TimeInput/TimeInput.js +28 -23
  306. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  307. package/dist/Timestamp/Timestamp.js +29 -14
  308. package/dist/Toast/Toast.d.ts.map +1 -1
  309. package/dist/Toast/Toast.js +17 -15
  310. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  311. package/dist/Toast/ToastViewport.js +14 -12
  312. package/dist/Toast/useToast.js +4 -4
  313. package/dist/ToggleButton/ToggleButton.js +12 -12
  314. package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
  315. package/dist/Token/Token.d.ts.map +1 -1
  316. package/dist/Token/Token.js +29 -23
  317. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  318. package/dist/Tokenizer/Tokenizer.js +33 -31
  319. package/dist/Toolbar/Toolbar.js +18 -18
  320. package/dist/Tooltip/Tooltip.js +11 -11
  321. package/dist/Tooltip/useTooltip.js +3 -3
  322. package/dist/TopNav/TopNav.d.ts +2 -1
  323. package/dist/TopNav/TopNav.d.ts.map +1 -1
  324. package/dist/TopNav/TopNav.js +36 -33
  325. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  326. package/dist/TopNav/TopNavHeading.js +72 -70
  327. package/dist/TopNav/TopNavItem.js +5 -5
  328. package/dist/TopNav/TopNavMegaMenu.js +30 -30
  329. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +10 -10
  330. package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
  331. package/dist/TopNav/TopNavMenu.js +32 -32
  332. package/dist/TreeList/TreeList.d.ts.map +1 -1
  333. package/dist/TreeList/TreeList.js +13 -9
  334. package/dist/TreeList/TreeListBranches.js +11 -11
  335. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  336. package/dist/TreeList/TreeListItem.js +37 -31
  337. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  338. package/dist/Typeahead/BaseTypeahead.js +26 -22
  339. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  340. package/dist/Typeahead/Typeahead.js +15 -13
  341. package/dist/Typeahead/TypeaheadItem.js +10 -10
  342. package/dist/VStack/VStack.js +3 -3
  343. package/dist/VisuallyHidden/VisuallyHidden.d.ts +1 -3
  344. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  345. package/dist/VisuallyHidden/VisuallyHidden.js +1 -3
  346. package/dist/astryx.css +20 -2
  347. package/dist/astryx.umd.js +66 -64
  348. package/dist/astryx.umd.js.map +4 -4
  349. package/dist/authoring/doc.d.ts +145 -0
  350. package/dist/authoring/doc.d.ts.map +1 -0
  351. package/dist/authoring/doc.js +100 -0
  352. package/dist/authoring/index.d.ts +29 -0
  353. package/dist/authoring/index.d.ts.map +1 -0
  354. package/dist/authoring/index.js +28 -0
  355. package/dist/authoring/integration.d.ts +35 -0
  356. package/dist/authoring/integration.d.ts.map +1 -0
  357. package/dist/authoring/integration.js +30 -0
  358. package/dist/authoring/template.d.ts +66 -0
  359. package/dist/authoring/template.d.ts.map +1 -0
  360. package/dist/authoring/template.js +55 -0
  361. package/dist/config.d.ts +80 -0
  362. package/dist/config.d.ts.map +1 -0
  363. package/dist/config.js +40 -0
  364. package/dist/hooks/useKeyboardHint.js +9 -9
  365. package/dist/i18n/InternationalizationContext.d.ts +12 -0
  366. package/dist/i18n/InternationalizationContext.d.ts.map +1 -0
  367. package/dist/i18n/InternationalizationContext.js +29 -0
  368. package/dist/i18n/InternationalizationProvider.d.ts +62 -0
  369. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -0
  370. package/dist/i18n/InternationalizationProvider.js +44 -0
  371. package/dist/i18n/index.d.ts +24 -0
  372. package/dist/i18n/index.d.ts.map +1 -0
  373. package/dist/i18n/index.js +21 -0
  374. package/dist/i18n/resolve.d.ts +22 -0
  375. package/dist/i18n/resolve.d.ts.map +1 -0
  376. package/dist/i18n/resolve.js +141 -0
  377. package/dist/i18n/translator.d.ts +25 -0
  378. package/dist/i18n/translator.d.ts.map +1 -0
  379. package/dist/i18n/translator.js +1 -0
  380. package/dist/i18n/types.d.ts +47 -0
  381. package/dist/i18n/types.d.ts.map +1 -0
  382. package/dist/i18n/types.js +1 -0
  383. package/dist/i18n/useTranslator.d.ts +15 -0
  384. package/dist/i18n/useTranslator.d.ts.map +1 -0
  385. package/dist/i18n/useTranslator.js +39 -0
  386. package/dist/index.d.ts +1 -0
  387. package/dist/index.d.ts.map +1 -1
  388. package/dist/index.js +3 -0
  389. package/dist/theme/MediaTheme.js +3 -3
  390. package/dist/theme/Theme.js +7 -7
  391. package/dist/theme/syntax/SyntaxTheme.js +5 -5
  392. package/locales/en.json +746 -0
  393. package/locales/pseudo.json +560 -0
  394. package/package.json +24 -3
  395. package/src/AlertDialog/AlertDialog.doc.mjs +5 -0
  396. package/src/AlertDialog/AlertDialog.tsx +4 -1
  397. package/src/AlertDialog/useImperativeAlertDialog.tsx +0 -2
  398. package/src/AppShell/AppShell.doc.mjs +8 -2
  399. package/src/AppShell/AppShell.tsx +3 -1
  400. package/src/AvatarGroup/AvatarGroup.tsx +4 -1
  401. package/src/Banner/Banner.tsx +10 -5
  402. package/src/Breadcrumbs/Breadcrumbs.tsx +4 -1
  403. package/src/Button/Button.tsx +34 -4
  404. package/src/ButtonGroup/ButtonGroup.test.tsx +386 -2
  405. package/src/ButtonGroup/ButtonGroup.tsx +27 -11
  406. package/src/Calendar/Calendar.tsx +8 -5
  407. package/src/Card/Card.doc.mjs +3 -3
  408. package/src/Carousel/Carousel.tsx +10 -7
  409. package/src/Chat/ChatComposer.tsx +5 -1
  410. package/src/Chat/ChatComposerDrawer.tsx +9 -2
  411. package/src/Chat/ChatComposerInput.tsx +10 -4
  412. package/src/Chat/ChatLayout.tsx +5 -12
  413. package/src/Chat/ChatLayoutScrollButton.tsx +4 -2
  414. package/src/Chat/ChatMessage.tsx +5 -1
  415. package/src/Chat/ChatMessageBubble.tsx +2 -0
  416. package/src/Chat/ChatMessageList.doc.mjs +1 -1
  417. package/src/Chat/ChatMessageList.tsx +2 -0
  418. package/src/Chat/ChatMessageMetadata.tsx +15 -9
  419. package/src/Chat/ChatPastedTextToken.tsx +3 -1
  420. package/src/Chat/ChatSendButton.tsx +3 -1
  421. package/src/Chat/ChatToolCalls.doc.mjs +1 -1
  422. package/src/Chat/useSpeechRecognition.ts +11 -2
  423. package/src/Chat/useTriggerMenu.tsx +4 -2
  424. package/src/CheckboxInput/CheckboxInput.test.tsx +16 -0
  425. package/src/CheckboxInput/CheckboxInput.tsx +4 -2
  426. package/src/CheckboxList/CheckboxList.doc.mjs +6 -1
  427. package/src/CheckboxList/CheckboxList.tsx +2 -0
  428. package/src/CheckboxList/CheckboxListItem.tsx +7 -1
  429. package/src/Citation/Citation.tsx +4 -2
  430. package/src/ClickableCard/ClickableCard.doc.mjs +1 -1
  431. package/src/CodeBlock/CodeBlock.tsx +91 -40
  432. package/src/Collapsible/Collapsible.doc.mjs +3 -3
  433. package/src/CommandPalette/CommandPalette.tsx +10 -3
  434. package/src/CommandPalette/CommandPaletteInput.test.tsx +1 -1
  435. package/src/CommandPalette/CommandPaletteInput.tsx +5 -1
  436. package/src/CommandPalette/CommandPaletteList.tsx +4 -1
  437. package/src/ContextMenu/ContextMenu.tsx +4 -1
  438. package/src/DateInput/DateInput.doc.mjs +2 -2
  439. package/src/DateInput/DateInput.tsx +13 -5
  440. package/src/DateRangeInput/DateRangeInput.doc.mjs +7 -7
  441. package/src/DateRangeInput/DateRangeInput.tsx +14 -6
  442. package/src/DateTimeInput/DateTimeInput.doc.mjs +2 -2
  443. package/src/DateTimeInput/DateTimeInput.tsx +17 -7
  444. package/src/Dialog/DialogHeader.tsx +4 -2
  445. package/src/DropdownMenu/DropdownMenu.tsx +12 -8
  446. package/src/EmptyState/EmptyState.doc.mjs +3 -3
  447. package/src/EmptyState/EmptyState.tsx +4 -1
  448. package/src/Field/Field.doc.mjs +2 -2
  449. package/src/FileInput/FileInput.tsx +3 -1
  450. package/src/Grid/Grid.doc.mjs +5 -5
  451. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  452. package/src/Layer/useLayer.doc.mjs +2 -2
  453. package/src/Lightbox/Lightbox.doc.mjs +7 -2
  454. package/src/Lightbox/Lightbox.tsx +6 -4
  455. package/src/Lightbox/useLightbox.tsx +0 -1
  456. package/src/Link/Link.test.tsx +74 -2
  457. package/src/Link/Link.tsx +48 -3
  458. package/src/Markdown/Markdown.tsx +12 -4
  459. package/src/MobileNav/MobileNav.tsx +4 -2
  460. package/src/MobileNav/MobileNavToggle.tsx +5 -3
  461. package/src/MoreMenu/MoreMenu.tsx +4 -1
  462. package/src/MultiSelector/MultiSelector.tsx +14 -5
  463. package/src/NumberInput/NumberInput.tsx +3 -1
  464. package/src/Outline/Outline.tsx +4 -1
  465. package/src/OverflowList/OverflowList.doc.mjs +2 -2
  466. package/src/Overlay/useOverlay.tsx +0 -3
  467. package/src/Pagination/Pagination.tsx +35 -12
  468. package/src/Popover/usePopover.tsx +6 -1
  469. package/src/PowerSearch/PowerSearch.doc.mjs +9 -4
  470. package/src/PowerSearch/PowerSearch.tsx +22 -10
  471. package/src/PowerSearch/PowerSearchEditPopover.tsx +27 -20
  472. package/src/PowerSearch/PowerSearchToken.tsx +17 -6
  473. package/src/PowerSearch/PowerSearchValueEditor.tsx +34 -21
  474. package/src/PowerSearch/formatFilterValue.test.ts +282 -0
  475. package/src/PowerSearch/formatFilterValue.ts +21 -8
  476. package/src/PowerSearch/index.ts +5 -0
  477. package/src/PowerSearch/resolveOperatorLabel.ts +34 -0
  478. package/src/PowerSearch/types.ts +33 -9
  479. package/src/PowerSearch/usePowerSearchConfig.ts +59 -27
  480. package/src/PowerSearch/usePowerSearchSource.ts +17 -8
  481. package/src/RadioList/RadioList.doc.mjs +1 -1
  482. package/src/Resizable/ResizeHandle.tsx +4 -1
  483. package/src/Section/Section.doc.mjs +4 -4
  484. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  485. package/src/Selector/Selector.tsx +11 -6
  486. package/src/SideNav/SideNav.tsx +4 -2
  487. package/src/SideNav/SideNavCollapseButton.tsx +3 -1
  488. package/src/SideNav/SideNavHeading.tsx +5 -3
  489. package/src/SideNav/SideNavItem.tsx +3 -1
  490. package/src/Slider/Slider.doc.mjs +2 -2
  491. package/src/Stack/Stack.doc.mjs +10 -10
  492. package/src/Switch/Switch.doc.mjs +2 -2
  493. package/src/Switch/Switch.test.tsx +16 -0
  494. package/src/Switch/Switch.tsx +4 -2
  495. package/src/TabList/TabList.tsx +4 -1
  496. package/src/Table/BaseTable.tsx +8 -1
  497. package/src/Table/Table.doc.mjs +1 -1
  498. package/src/Table/Table.tsx +3 -1
  499. package/src/Table/index.ts +7 -0
  500. package/src/Table/plugins/filtering/useTableFiltering.tsx +31 -30
  501. package/src/Table/plugins/groupedRows/index.ts +7 -0
  502. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +231 -0
  503. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +351 -0
  504. package/src/Table/plugins/pagination/useTablePagination.tsx +4 -1
  505. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +8 -4
  506. package/src/Table/plugins/rowIndex/index.ts +4 -0
  507. package/src/Table/plugins/rowIndex/useTableRowIndex.test.tsx +132 -0
  508. package/src/Table/plugins/rowIndex/useTableRowIndex.tsx +114 -0
  509. package/src/Table/plugins/selection/useTableSelection.tsx +6 -7
  510. package/src/Table/plugins/sortable/useTableSortable.tsx +8 -5
  511. package/src/Table/useTableFiltering.doc.mjs +2 -2
  512. package/src/Table/useTableGroupedRows.doc.mjs +71 -0
  513. package/src/Table/useTableRowIndex.doc.mjs +50 -0
  514. package/src/Table/useTableSortable.doc.mjs +11 -11
  515. package/src/Text/Text.doc.mjs +2 -2
  516. package/src/TextInput/TextInput.tsx +3 -1
  517. package/src/Thumbnail/Thumbnail.tsx +4 -2
  518. package/src/TimeInput/TimeInput.doc.mjs +2 -2
  519. package/src/TimeInput/TimeInput.tsx +6 -2
  520. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  521. package/src/Timestamp/Timestamp.test.tsx +120 -7
  522. package/src/Timestamp/Timestamp.tsx +21 -1
  523. package/src/Toast/Toast.tsx +3 -1
  524. package/src/Toast/ToastViewport.tsx +3 -1
  525. package/src/Token/Token.tsx +4 -2
  526. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  527. package/src/Tokenizer/Tokenizer.tsx +4 -4
  528. package/src/Toolbar/Toolbar.doc.mjs +1 -1
  529. package/src/TopNav/TopNav.doc.mjs +1 -0
  530. package/src/TopNav/TopNav.test.tsx +30 -0
  531. package/src/TopNav/TopNav.tsx +6 -4
  532. package/src/TopNav/TopNavHeading.tsx +5 -3
  533. package/src/TreeList/TreeList.tsx +5 -1
  534. package/src/TreeList/TreeListItem.tsx +6 -1
  535. package/src/Typeahead/BaseTypeahead.tsx +11 -4
  536. package/src/Typeahead/Typeahead.doc.mjs +1 -1
  537. package/src/Typeahead/Typeahead.tsx +3 -1
  538. package/src/VisuallyHidden/VisuallyHidden.tsx +1 -3
  539. package/src/authoring/doc.ts +166 -0
  540. package/src/authoring/index.test.ts +52 -0
  541. package/src/authoring/index.ts +50 -0
  542. package/src/authoring/integration.ts +42 -0
  543. package/src/authoring/template.ts +74 -0
  544. package/src/config.test.ts +16 -0
  545. package/src/config.ts +92 -0
  546. package/src/docPropLiterals.test.ts +902 -0
  547. package/src/hooks/useHotkeys.doc.mjs +5 -5
  548. package/src/i18n/InternationalizationContext.ts +39 -0
  549. package/src/i18n/InternationalizationProvider.doc.mjs +72 -0
  550. package/src/i18n/InternationalizationProvider.tsx +83 -0
  551. package/src/i18n/__tests__/e2e-pagination.test.tsx +172 -0
  552. package/src/i18n/__tests__/e2e-powersearch.test.tsx +130 -0
  553. package/src/i18n/__tests__/resolve.test.ts +284 -0
  554. package/src/i18n/index.ts +32 -0
  555. package/src/i18n/resolve.ts +165 -0
  556. package/src/i18n/translator.ts +31 -0
  557. package/src/i18n/types.ts +53 -0
  558. package/src/i18n/useTranslator.doc.mjs +46 -0
  559. package/src/i18n/useTranslator.ts +50 -0
  560. package/src/index.ts +3 -0
  561. package/dist/NavItem/index.d.ts +0 -9
  562. package/dist/NavItem/index.d.ts.map +0 -1
  563. package/dist/NavItem/index.js +0 -10
  564. package/src/NavItem/index.ts +0 -11
@@ -0,0 +1,351 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useTableGroupedRows.tsx
7
+ * @input React, StyleX, Icon, Table types + the flat data array
8
+ * @output Exports useTableGroupedRows hook + config/result types
9
+ * @position Grouped-rows plugin; consumed by Table via plugins prop
10
+ *
11
+ * SYNC: When modified, update these files to stay in sync:
12
+ * - /packages/core/src/Table/index.ts (exports)
13
+ */
14
+
15
+ import {useCallback, useMemo, type ReactNode} from 'react';
16
+ import * as stylex from '@stylexjs/stylex';
17
+ import {
18
+ spacingVars,
19
+ colorVars,
20
+ fontWeightVars,
21
+ } from '../../../theme/tokens.stylex';
22
+ import {Icon} from '../../../Icon';
23
+ import type {TablePlugin} from '../../types';
24
+ import {useTranslator} from '../../../i18n';
25
+
26
+ // A synthetic group-header row injected into the flattened data. Real rows
27
+ // never carry this marker.
28
+ const GROUP_HEADER = Symbol('tableGroupHeader');
29
+
30
+ interface GroupHeader {
31
+ [GROUP_HEADER]: true;
32
+ groupKey: string;
33
+ count: number;
34
+ }
35
+
36
+ function isGroupHeader(item: unknown): item is GroupHeader {
37
+ return (
38
+ typeof item === 'object' &&
39
+ item !== null &&
40
+ (item as Record<symbol, unknown>)[GROUP_HEADER] === true
41
+ );
42
+ }
43
+
44
+ // Proxy handler: any field access beyond the marker fields resolves to `''`
45
+ // so user cell renderers (`item.name.toUpperCase()`) never throw on a header.
46
+ const HEADER_PROXY_HANDLER: ProxyHandler<Record<string | symbol, unknown>> = {
47
+ // eslint-disable-next-line @typescript-eslint/promise-function-async -- Proxy get trap, not a promise-returning fn
48
+ get(t: Record<string | symbol, unknown>, prop: string | symbol): unknown {
49
+ if (prop === GROUP_HEADER || prop === 'groupKey' || prop === 'count') {
50
+ return t[prop];
51
+ }
52
+ return prop in t ? t[prop] : '';
53
+ },
54
+ };
55
+
56
+ /**
57
+ * Build a synthetic header row wrapped in a Proxy so arbitrary field access
58
+ * from user cell renderers (e.g. `item.name.toUpperCase()`) resolves to `''`
59
+ * instead of throwing — BaseTable evaluates `col.renderCell(item)` on every
60
+ * row (including synthetic headers) before `transformBodyRow` can replace the
61
+ * row's cells. `transformBodyRow` then discards those cells and renders a
62
+ * single full-width header cell.
63
+ */
64
+ function makeHeader<T extends Record<string, unknown>>(
65
+ groupKey: string,
66
+ count: number,
67
+ ): T {
68
+ const target: Record<string | symbol, unknown> = {
69
+ [GROUP_HEADER]: true,
70
+ groupKey,
71
+ count,
72
+ };
73
+ return new Proxy(target, HEADER_PROXY_HANDLER) as unknown as T;
74
+ }
75
+
76
+ /** Configuration for {@link useTableGroupedRows}. */
77
+ export interface UseTableGroupedRowsConfig<T extends Record<string, unknown>> {
78
+ /** The flat data to group. */
79
+ data: T[];
80
+ /** Derive the group key for a row. Rows with the same key share a section. */
81
+ groupBy: (item: T) => string;
82
+ /** Set of currently-collapsed group keys. */
83
+ collapsedGroups: Set<string>;
84
+ /** Called with a group key when its header is toggled. */
85
+ onToggleGroup: (groupKey: string) => void;
86
+ /**
87
+ * Custom renderer for a group header's content (right of the chevron).
88
+ * Defaults to `<groupKey> (<count>)`.
89
+ */
90
+ renderGroupHeader?: (
91
+ groupKey: string,
92
+ count: number,
93
+ collapsed: boolean,
94
+ ) => ReactNode;
95
+ /** Stable key for a real row. Falls back to a positional key when omitted. */
96
+ getRowKey?: (item: T) => string;
97
+ /** Explicit group ordering; groups not listed keep first-seen order after these. */
98
+ groupOrder?: string[];
99
+ }
100
+
101
+ export interface UseTableGroupedRowsResult<T extends Record<string, unknown>> {
102
+ /** Ready-to-use plugin for `<Table plugins>`. */
103
+ plugin: TablePlugin<T>;
104
+ /** Flattened rows: `[header, ...visibleRows, header, ...visibleRows]`. */
105
+ data: T[];
106
+ /**
107
+ * Row-key resolver (also keys synthetic headers as `__group_<key>`). Pass to
108
+ * `<Table idKey>` — named for parallelism with the Table prop:
109
+ * `<Table idKey={grouped.idKey} />`.
110
+ */
111
+ idKey: (item: T) => string;
112
+ }
113
+
114
+ const styles = stylex.create({
115
+ headerRow: {
116
+ cursor: 'pointer',
117
+ userSelect: 'none',
118
+ backgroundColor: colorVars['--color-background-muted'],
119
+ // Divider beneath each group header row (Ernest review #2).
120
+ borderBottomWidth: '1px',
121
+ borderBottomStyle: 'solid',
122
+ borderBottomColor: colorVars['--color-border'],
123
+ },
124
+ headerCell: {
125
+ paddingBlock: spacingVars['--spacing-2'],
126
+ // No inline start padding so the chevron aligns with the table's leading
127
+ // edge (Ernest review #1).
128
+ paddingInlineStart: spacingVars['--spacing-1'],
129
+ paddingInlineEnd: spacingVars['--spacing-3'],
130
+ },
131
+ headerInner: {
132
+ display: 'flex',
133
+ alignItems: 'center',
134
+ gap: spacingVars['--spacing-1'],
135
+ },
136
+ // Standalone chevron button with no heavy chrome (transparent, borderless,
137
+ // zero padding) so the icon sits flush with the start of the table
138
+ // (Ernest review #1) while staying keyboard-operable.
139
+ chevron: {
140
+ display: 'inline-flex',
141
+ alignItems: 'center',
142
+ justifyContent: 'center',
143
+ flexShrink: '0',
144
+ padding: 0,
145
+ margin: 0,
146
+ background: 'transparent',
147
+ border: 'none',
148
+ cursor: 'pointer',
149
+ color: {
150
+ default: colorVars['--color-icon-secondary'],
151
+ ':hover': colorVars['--color-icon-primary'],
152
+ },
153
+ },
154
+ chevronIcon: {
155
+ display: 'inline-flex',
156
+ transitionProperty: 'transform',
157
+ transitionDuration: '150ms',
158
+ },
159
+ chevronExpanded: {
160
+ transform: 'rotate(90deg)',
161
+ },
162
+ // Emphasized body text — same size as body, heavier weight (Ernest #3).
163
+ label: {
164
+ fontWeight: fontWeightVars['--font-weight-semibold'],
165
+ color: colorVars['--color-text-primary'],
166
+ },
167
+ count: {
168
+ fontWeight: fontWeightVars['--font-weight-normal'],
169
+ color: colorVars['--color-text-secondary'],
170
+ },
171
+ });
172
+
173
+ /**
174
+ * Groups a flat data array into collapsible section rows. Each distinct
175
+ * `groupBy` value becomes a full-width section-header row with a chevron
176
+ * toggle, the group label, and a member count; collapsing hides that group's
177
+ * data rows while keeping the header visible.
178
+ *
179
+ * Mirrors {@link useTableRowExpansionState}: the consumer owns the
180
+ * `collapsedGroups` set and this hook returns `{data, plugin, idKey}` —
181
+ * pass all three to `<Table>`.
182
+ *
183
+ * @example
184
+ * ```
185
+ * const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
186
+ * const grouped = useTableGroupedRows({
187
+ * data: rows,
188
+ * groupBy: r => r.team,
189
+ * collapsedGroups: collapsed,
190
+ * onToggleGroup: key =>
191
+ * setCollapsed(prev => {
192
+ * const next = new Set(prev);
193
+ * next.has(key) ? next.delete(key) : next.add(key);
194
+ * return next;
195
+ * }),
196
+ * getRowKey: r => r.id,
197
+ * });
198
+ * <Table
199
+ * data={grouped.data}
200
+ * columns={columns}
201
+ * idKey={grouped.idKey}
202
+ * plugins={{grouped: grouped.plugin}}
203
+ * />;
204
+ * ```
205
+ */
206
+ export function useTableGroupedRows<T extends Record<string, unknown>>(
207
+ config: UseTableGroupedRowsConfig<T>,
208
+ ): UseTableGroupedRowsResult<T> {
209
+ const t = useTranslator();
210
+ const {
211
+ data,
212
+ groupBy,
213
+ collapsedGroups,
214
+ onToggleGroup,
215
+ renderGroupHeader,
216
+ getRowKey: getRowKeyProp,
217
+ groupOrder,
218
+ } = config;
219
+
220
+ const flattened = useMemo((): T[] => {
221
+ if (data.length === 0) {
222
+ return [];
223
+ }
224
+
225
+ // Group preserving first-seen order.
226
+ const groups = new Map<string, T[]>();
227
+ for (const item of data) {
228
+ const key = groupBy(item);
229
+ const bucket = groups.get(key);
230
+ if (bucket) {
231
+ bucket.push(item);
232
+ } else {
233
+ groups.set(key, [item]);
234
+ }
235
+ }
236
+
237
+ // Determine iteration order.
238
+ let keys = [...groups.keys()];
239
+ if (groupOrder && groupOrder.length > 0) {
240
+ const ordered = groupOrder.filter(k => groups.has(k));
241
+ const rest = keys.filter(k => !groupOrder.includes(k));
242
+ keys = [...ordered, ...rest];
243
+ }
244
+
245
+ const out: T[] = [];
246
+ for (const key of keys) {
247
+ const rows = groups.get(key) ?? [];
248
+ out.push(makeHeader<T>(key, rows.length));
249
+ if (!collapsedGroups.has(key)) {
250
+ out.push(...rows);
251
+ }
252
+ }
253
+ return out;
254
+ }, [data, groupBy, collapsedGroups, groupOrder]);
255
+
256
+ // Positional fallback index, built once per flattened array so key lookup
257
+ // stays O(1) instead of O(n) per row (which would make table keying O(n²)).
258
+ const positionByItem = useMemo(() => {
259
+ if (getRowKeyProp) {
260
+ return null;
261
+ }
262
+ const map = new Map<T, number>();
263
+ for (let i = 0; i < flattened.length; i++) {
264
+ map.set(flattened[i], i);
265
+ }
266
+ return map;
267
+ }, [flattened, getRowKeyProp]);
268
+
269
+ const idKey = useCallback(
270
+ (item: T): string => {
271
+ if (isGroupHeader(item)) {
272
+ return `__group_${item.groupKey}`;
273
+ }
274
+ if (getRowKeyProp) {
275
+ return getRowKeyProp(item);
276
+ }
277
+ return String(positionByItem?.get(item) ?? -1);
278
+ },
279
+ [getRowKeyProp, positionByItem],
280
+ );
281
+
282
+ const plugin = useMemo(
283
+ (): TablePlugin<T> => ({
284
+ // Replace a header row's pre-rendered cells with one full-width cell.
285
+ transformBodyRow(props, item) {
286
+ if (!isGroupHeader(item)) {
287
+ return props;
288
+ }
289
+ const header = item as unknown as GroupHeader;
290
+ const collapsed = collapsedGroups.has(header.groupKey);
291
+ const toggle = () => onToggleGroup(header.groupKey);
292
+ const content: ReactNode = renderGroupHeader ? (
293
+ renderGroupHeader(header.groupKey, header.count, collapsed)
294
+ ) : (
295
+ <span {...stylex.props(styles.label)}>
296
+ {header.groupKey}{' '}
297
+ <span {...stylex.props(styles.count)}>({header.count})</span>
298
+ </span>
299
+ );
300
+ return {
301
+ ...props,
302
+ htmlProps: {
303
+ ...props.htmlProps,
304
+ // Convenience: clicking anywhere on the row toggles it. The chevron
305
+ // button below is the accessible, keyboard-operable control, so the
306
+ // row keeps its implicit `row` role (no role override here).
307
+ onClick: toggle,
308
+ 'aria-expanded': !collapsed,
309
+ },
310
+ styles: [...props.styles, styles.headerRow],
311
+ children: (
312
+ // colSpan larger than the column count is clamped by the browser
313
+ // to the actual number of columns, so the header always spans the
314
+ // full width without the plugin knowing the column count.
315
+ <td colSpan={999} {...stylex.props(styles.headerCell)}>
316
+ <span {...stylex.props(styles.headerInner)}>
317
+ {/* Standalone chevron button, flush with the table's start
318
+ edge (no heavy button chrome) — the keyboard control. */}
319
+ <button
320
+ type="button"
321
+ {...stylex.props(styles.chevron)}
322
+ onClick={e => {
323
+ e.stopPropagation();
324
+ toggle();
325
+ }}
326
+ aria-label={
327
+ collapsed
328
+ ? t('@astryx.tableGroupedRows.expandGroup', {groupKey: header.groupKey})
329
+ : t('@astryx.tableGroupedRows.collapseGroup', {groupKey: header.groupKey})
330
+ }
331
+ aria-expanded={!collapsed}>
332
+ <span
333
+ {...stylex.props(
334
+ styles.chevronIcon,
335
+ !collapsed && styles.chevronExpanded,
336
+ )}>
337
+ <Icon icon="chevronRight" size="xsm" />
338
+ </span>
339
+ </button>
340
+ {content}
341
+ </span>
342
+ </td>
343
+ ),
344
+ };
345
+ },
346
+ }),
347
+ [collapsedGroups, onToggleGroup, renderGroupHeader, t],
348
+ );
349
+
350
+ return {plugin, data: flattened, idKey};
351
+ }
@@ -22,6 +22,7 @@ import {spacingVars} from '../../../theme/tokens.stylex';
22
22
  import {Pagination} from '../../../Pagination';
23
23
  import type {PaginationProps} from '../../../Pagination';
24
24
  import type {TablePlugin} from '../../types';
25
+ import {useTranslator} from '../../../i18n';
25
26
 
26
27
  // =============================================================================
27
28
  // Styles
@@ -193,6 +194,7 @@ export interface UseTablePaginationConfig {
193
194
  export function useTablePagination<T extends Record<string, unknown>>(
194
195
  config: UseTablePaginationConfig,
195
196
  ): TablePlugin<T> {
197
+ const t = useTranslator();
196
198
  const {
197
199
  page,
198
200
  onPageChange,
@@ -206,8 +208,9 @@ export function useTablePagination<T extends Record<string, unknown>>(
206
208
  size = 'md',
207
209
  position = 'below',
208
210
  align = 'center',
209
- label = 'Table pagination',
211
+ label: labelFromProps,
210
212
  } = config;
213
+ const label = labelFromProps ?? t('@astryx.table.pagination.label');
211
214
 
212
215
  // Same guard as Pagination itself: 0/NaN/negative pageSize would produce an
213
216
  // Infinity/NaN totalPages here, which bypasses Pagination's own coercion
@@ -17,6 +17,7 @@ import * as stylex from '@stylexjs/stylex';
17
17
  import {spacingVars, colorVars, radiusVars} from '../../../theme/tokens.stylex';
18
18
  import {Icon} from '../../../Icon';
19
19
  import {resolveContextActions} from '../../tableContextMenu';
20
+ import {useTranslator} from '../../../i18n';
20
21
  import type {
21
22
  TablePlugin,
22
23
  TableColumn,
@@ -109,7 +110,7 @@ export interface UseTableRowExpansionStateResult<
109
110
  * computing the expand-all state.
110
111
  *
111
112
  * @example
112
- * ```tsx
113
+ * ```
113
114
  * const [expandedKeys, setExpandedKeys] = useState<Set<string>>(new Set());
114
115
  * const {data, expansionConfig} = useTableRowExpansionState({
115
116
  * baseData: tree,
@@ -356,6 +357,7 @@ function ExpansionChevron({
356
357
  export function useTableRowExpansion<T extends Record<string, unknown>>(
357
358
  config: UseTableRowExpansionConfig<T>,
358
359
  ): TablePlugin<T> {
360
+ const t = useTranslator();
359
361
  const {
360
362
  expandedKeys,
361
363
  onToggle,
@@ -397,7 +399,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
397
399
  <ExpansionChevron
398
400
  isExpanded={isExpanded}
399
401
  onToggle={() => onToggle(key)}
400
- ariaLabel={isExpanded ? 'Collapse row' : 'Expand row'}
402
+ ariaLabel={isExpanded ? t('@astryx.tableRowExpansion.collapseRow') : t('@astryx.tableRowExpansion.expandRow')}
401
403
  />
402
404
  );
403
405
  },
@@ -409,6 +411,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
409
411
  getChildren,
410
412
  getIsItemExpandable,
411
413
  getDepth,
414
+ t,
412
415
  ],
413
416
  );
414
417
 
@@ -457,7 +460,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
457
460
  <ExpansionChevron
458
461
  isExpanded={isExpanded}
459
462
  onToggle={() => onToggle(key)}
460
- ariaLabel={isExpanded ? 'Collapse row' : 'Expand row'}
463
+ ariaLabel={isExpanded ? t('@astryx.tableRowExpansion.collapseRow') : t('@astryx.tableRowExpansion.expandRow')}
461
464
  />
462
465
  ) : (
463
466
  <span {...stylex.props(expansionStyles.placeholder)} />
@@ -499,7 +502,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
499
502
  {...stylex.props(expansionStyles.chevronButton)}
500
503
  onClick={() => onToggleExpandAll(!allExpanded)}
501
504
  aria-label={
502
- allExpanded ? 'Collapse all rows' : 'Expand all rows'
505
+ allExpanded ? t('@astryx.tableRowExpansion.collapseAllRows') : t('@astryx.tableRowExpansion.expandAllRows')
503
506
  }>
504
507
  <span
505
508
  {...stylex.props(
@@ -585,6 +588,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
585
588
  isAllExpanded,
586
589
  onToggleExpandAll,
587
590
  expansionColumn,
591
+ t,
588
592
  ],
589
593
  );
590
594
  }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ export {useTableRowIndex} from './useTableRowIndex';
4
+ export type {UseTableRowIndexConfig} from './useTableRowIndex';
@@ -0,0 +1,132 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, it, expect} from 'vitest';
4
+ import {render, screen, within} from '@testing-library/react';
5
+ import {Table} from '../../Table';
6
+ import type {TableColumn} from '../../types';
7
+ import {useTableRowIndex} from './useTableRowIndex';
8
+
9
+ interface Row extends Record<string, unknown> {
10
+ id: string;
11
+ name: string;
12
+ }
13
+
14
+ const data: Row[] = [
15
+ {id: 'a', name: 'Alice'},
16
+ {id: 'b', name: 'Bob'},
17
+ {id: 'c', name: 'Carol'},
18
+ ];
19
+
20
+ const columns: TableColumn<Row>[] = [{key: 'name', header: 'Name'}];
21
+
22
+ function Harness({
23
+ rows = data,
24
+ label,
25
+ startFrom,
26
+ useKey = false,
27
+ }: {
28
+ rows?: Row[];
29
+ label?: string;
30
+ startFrom?: number;
31
+ useKey?: boolean;
32
+ }) {
33
+ const rowIndex = useTableRowIndex<Row>({
34
+ data: rows,
35
+ label,
36
+ startFrom,
37
+ getRowKey: useKey ? item => item.id : undefined,
38
+ });
39
+ return (
40
+ <Table data={rows} columns={columns} idKey="id" plugins={{rowIndex}} />
41
+ );
42
+ }
43
+
44
+ describe('useTableRowIndex', () => {
45
+ it('prepends a header cell with the default label', () => {
46
+ render(<Harness />);
47
+ const headers = screen.getAllByRole('columnheader');
48
+ // First column is the index column.
49
+ expect(within(headers[0]).getByText('#')).toBeInTheDocument();
50
+ });
51
+
52
+ it('numbers rows 1..n by default', () => {
53
+ render(<Harness />);
54
+ expect(screen.getByText('1')).toBeInTheDocument();
55
+ expect(screen.getByText('2')).toBeInTheDocument();
56
+ expect(screen.getByText('3')).toBeInTheDocument();
57
+ });
58
+
59
+ it('respects startFrom', () => {
60
+ render(<Harness startFrom={0} />);
61
+ expect(screen.getByText('0')).toBeInTheDocument();
62
+ expect(screen.getByText('2')).toBeInTheDocument();
63
+ expect(screen.queryByText('3')).not.toBeInTheDocument();
64
+ });
65
+
66
+ it('supports a custom label', () => {
67
+ render(<Harness label="Row" />);
68
+ const headers = screen.getAllByRole('columnheader');
69
+ expect(within(headers[0]).getByText('Row')).toBeInTheDocument();
70
+ });
71
+
72
+ it('numbers a single row', () => {
73
+ render(<Harness rows={[{id: 'a', name: 'Alice'}]} />);
74
+ const rows = screen.getAllByRole('row');
75
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
76
+ expect(within(rows[1]).getByText('Alice')).toBeInTheDocument();
77
+ });
78
+
79
+ it('renders the index header with empty data and no row numbers', () => {
80
+ render(<Harness rows={[]} />);
81
+ const headers = screen.getAllByRole('columnheader');
82
+ expect(within(headers[0]).getByText('#')).toBeInTheDocument();
83
+ // No body rows → no ordinals.
84
+ expect(screen.queryByText('1')).not.toBeInTheDocument();
85
+ });
86
+
87
+ it('renumbers when the data order changes (reference path)', () => {
88
+ const {rerender} = render(<Harness rows={data} />);
89
+ let rows = screen.getAllByRole('row');
90
+ // rows[0] is the header row.
91
+ expect(within(rows[1]).getByText('Alice')).toBeInTheDocument();
92
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
93
+
94
+ // Reorder: Carol, Alice, Bob (same object identities, new order).
95
+ rerender(<Harness rows={[data[2], data[0], data[1]]} />);
96
+ rows = screen.getAllByRole('row');
97
+ expect(within(rows[1]).getByText('Carol')).toBeInTheDocument();
98
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
99
+ expect(within(rows[2]).getByText('Alice')).toBeInTheDocument();
100
+ expect(within(rows[2]).getByText('2')).toBeInTheDocument();
101
+ });
102
+
103
+ it('renumbers when the data order changes (keyed path)', () => {
104
+ // With getRowKey provided, the keyed lookup must still produce ordinals in
105
+ // the new order. If the keyed branch were broken it would return undefined
106
+ // and render no numbers — so this fails for the right reason.
107
+ const {rerender} = render(<Harness rows={data} useKey />);
108
+ let rows = screen.getAllByRole('row');
109
+ expect(within(rows[1]).getByText('Alice')).toBeInTheDocument();
110
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
111
+
112
+ rerender(<Harness rows={[data[1], data[2], data[0]]} useKey />);
113
+ rows = screen.getAllByRole('row');
114
+ expect(within(rows[1]).getByText('Bob')).toBeInTheDocument();
115
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
116
+ expect(within(rows[3]).getByText('Alice')).toBeInTheDocument();
117
+ expect(within(rows[3]).getByText('3')).toBeInTheDocument();
118
+ });
119
+
120
+ it('keyed path resolves ordinals across fresh object identities', () => {
121
+ // Simulates a re-fetch: brand-new objects with the same ids. Keyed lookup
122
+ // must map them correctly.
123
+ const fresh: Row[] = [
124
+ {id: 'a', name: 'Alice'},
125
+ {id: 'b', name: 'Bob'},
126
+ ];
127
+ render(<Harness rows={fresh} useKey />);
128
+ const rows = screen.getAllByRole('row');
129
+ expect(within(rows[1]).getByText('1')).toBeInTheDocument();
130
+ expect(within(rows[2]).getByText('2')).toBeInTheDocument();
131
+ });
132
+ });
@@ -0,0 +1,114 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useTableRowIndex.tsx
7
+ * @input React, StyleX, Table types + the rendered data array
8
+ * @output Exports useTableRowIndex hook + config type
9
+ * @position Row-index plugin; consumed by Table via plugins prop
10
+ *
11
+ * SYNC: When modified, update these files to stay in sync:
12
+ * - /packages/core/src/Table/index.ts (exports)
13
+ */
14
+
15
+ import {useMemo, type ReactNode} from 'react';
16
+ import * as stylex from '@stylexjs/stylex';
17
+ import {colorVars, typeScaleVars} from '../../../theme/tokens.stylex';
18
+
19
+ import type {TableColumn, TablePlugin} from '../../types';
20
+
21
+ /**
22
+ * Configuration for {@link useTableRowIndex}.
23
+ *
24
+ * Astryx's `renderCell` receives only the row item (not its position), so the
25
+ * plugin needs the rendered `data` array — the same array passed to
26
+ * `<Table data>` — to derive each row's 1-based ordinal. Pass `getRowKey` when
27
+ * items don't have a stable identity by reference (e.g. new objects each
28
+ * render); it must return a **unique** string per row (duplicate keys collapse
29
+ * to a single ordinal).
30
+ */
31
+ export interface UseTableRowIndexConfig<T extends Record<string, unknown>> {
32
+ /** The data array currently rendered by the table (post sort/filter/page). */
33
+ data: T[];
34
+ /**
35
+ * Optional key extractor returning a **unique** string per row. When
36
+ * provided, index lookup is keyed by the returned string (stable across new
37
+ * object identities); otherwise items are matched by reference identity.
38
+ * For a stable plugin identity across renders, memoize this with
39
+ * `useCallback`.
40
+ */
41
+ getRowKey?: (item: T) => string;
42
+ /** Header label for the index column. @default '#' */
43
+ label?: ReactNode;
44
+ /** First index value. @default 1 */
45
+ startFrom?: number;
46
+ }
47
+
48
+ const INDEX_COLUMN_WIDTH = {type: 'pixel' as const, value: 48};
49
+
50
+ const styles = stylex.create({
51
+ index: {
52
+ fontFamily: 'var(--font-family-code)',
53
+ fontSize: typeScaleVars['--text-supporting-size'],
54
+ fontVariantNumeric: 'tabular-nums',
55
+ color: colorVars['--color-text-secondary'],
56
+ },
57
+ });
58
+
59
+ /**
60
+ * Returns a {@link TablePlugin} that prepends a right-aligned, monospaced
61
+ * row-number column. Numbering follows the order of the rendered `data` array,
62
+ * so it reflects the current sort / filter / pagination view.
63
+ *
64
+ * @example
65
+ * ```
66
+ * const rowIndex = useTableRowIndex({data});
67
+ * <Table data={data} columns={columns} idKey="id" plugins={{rowIndex}} />;
68
+ * ```
69
+ */
70
+ export function useTableRowIndex<T extends Record<string, unknown>>(
71
+ config: UseTableRowIndexConfig<T>,
72
+ ): TablePlugin<T> {
73
+ const {data, getRowKey, label = '#', startFrom = 1} = config;
74
+
75
+ // Single item → ordinal lookup, built in one pass and rebuilt only when the
76
+ // data array or key extractor changes. Keyed by getRowKey when provided
77
+ // (stable across new object identities), otherwise by object reference.
78
+ const lookup = useMemo(() => {
79
+ const map = new Map<unknown, number>();
80
+ for (let i = 0; i < data.length; i++) {
81
+ const item = data[i];
82
+ map.set(getRowKey ? getRowKey(item) : item, i);
83
+ }
84
+ return (item: T): number | undefined =>
85
+ map.get(getRowKey ? getRowKey(item) : item);
86
+ }, [data, getRowKey]);
87
+
88
+ // The plugin object depends only on the stable lookup and the presentational
89
+ // props — not on data directly — so it stays as stable as its inputs allow.
90
+ return useMemo(
91
+ (): TablePlugin<T> => ({
92
+ transformColumns(columns) {
93
+ const indexColumn: TableColumn<T> = {
94
+ key: '__rowIndex',
95
+ header: label,
96
+ width: INDEX_COLUMN_WIDTH,
97
+ align: 'end',
98
+ resizable: false,
99
+ renderCell: (item: T) => {
100
+ const idx = lookup(item);
101
+ if (idx == null) {
102
+ return null;
103
+ }
104
+ return (
105
+ <span {...stylex.props(styles.index)}>{idx + startFrom}</span>
106
+ );
107
+ },
108
+ };
109
+ return [indexColumn, ...columns];
110
+ },
111
+ }),
112
+ [label, startFrom, lookup],
113
+ );
114
+ }