@astryxdesign/core 0.1.2 → 0.1.3-canary.102854d

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 (586) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +12 -12
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +11 -5
  5. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  7. package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +31 -12
  10. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  11. package/dist/ButtonGroup/ButtonGroup.js +0 -1
  12. package/dist/Calendar/Calendar.d.ts +5 -4
  13. package/dist/Calendar/Calendar.d.ts.map +1 -1
  14. package/dist/Calendar/Calendar.js +124 -61
  15. package/dist/Calendar/dayCellUtils.d.ts +67 -5
  16. package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
  17. package/dist/Calendar/dayCellUtils.js +139 -18
  18. package/dist/Calendar/hooks/index.d.ts +0 -2
  19. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  20. package/dist/Calendar/hooks/index.js +1 -2
  21. package/dist/Calendar/index.d.ts +3 -3
  22. package/dist/Calendar/index.d.ts.map +1 -1
  23. package/dist/Calendar/index.js +1 -1
  24. package/dist/Calendar/styles.d.ts +3 -9
  25. package/dist/Calendar/styles.d.ts.map +1 -1
  26. package/dist/Calendar/styles.js +3 -11
  27. package/dist/Carousel/Carousel.d.ts.map +1 -1
  28. package/dist/Carousel/Carousel.js +17 -3
  29. package/dist/Center/Center.d.ts +11 -1
  30. package/dist/Center/Center.d.ts.map +1 -1
  31. package/dist/Center/Center.js +9 -3
  32. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  33. package/dist/Chat/ChatComposerInput.js +0 -1
  34. package/dist/Chat/ChatMessageList.d.ts +14 -1
  35. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  36. package/dist/Chat/ChatMessageList.js +2 -0
  37. package/dist/Chat/useTriggerMenu.d.ts +8 -1
  38. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  39. package/dist/Chat/useTriggerMenu.js +15 -3
  40. package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
  41. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  42. package/dist/CheckboxInput/CheckboxInput.js +51 -9
  43. package/dist/CheckboxList/CheckboxList.d.ts +13 -1
  44. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  45. package/dist/CheckboxList/CheckboxList.js +39 -9
  46. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  47. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  48. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  49. package/dist/CheckboxList/CheckboxListItem.js +0 -1
  50. package/dist/Citation/Citation.d.ts.map +1 -1
  51. package/dist/Citation/Citation.js +9 -5
  52. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  53. package/dist/CodeBlock/CodeBlock.js +51 -37
  54. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  55. package/dist/CommandPalette/CommandPalette.js +5 -5
  56. package/dist/ContextMenu/ContextMenu.d.ts +12 -5
  57. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  58. package/dist/ContextMenu/ContextMenu.js +96 -11
  59. package/dist/DateInput/DateInput.d.ts +23 -1
  60. package/dist/DateInput/DateInput.d.ts.map +1 -1
  61. package/dist/DateInput/DateInput.js +167 -99
  62. package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
  63. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  64. package/dist/DateRangeInput/DateRangeInput.js +42 -9
  65. package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
  66. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  67. package/dist/DateTimeInput/DateTimeInput.js +78 -15
  68. package/dist/Dialog/Dialog.d.ts.map +1 -1
  69. package/dist/Dialog/Dialog.js +12 -0
  70. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
  71. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  72. package/dist/DropdownMenu/DropdownMenu.js +42 -14
  73. package/dist/Field/Field.d.ts +19 -2
  74. package/dist/Field/Field.d.ts.map +1 -1
  75. package/dist/Field/Field.js +4 -0
  76. package/dist/Field/FieldLabel.d.ts +21 -2
  77. package/dist/Field/FieldLabel.d.ts.map +1 -1
  78. package/dist/Field/FieldLabel.js +41 -26
  79. package/dist/FileInput/FileInput.d.ts +22 -1
  80. package/dist/FileInput/FileInput.d.ts.map +1 -1
  81. package/dist/FileInput/FileInput.js +56 -10
  82. package/dist/Grid/Grid.d.ts +11 -1
  83. package/dist/Grid/Grid.d.ts.map +1 -1
  84. package/dist/Grid/Grid.js +32 -6
  85. package/dist/InputGroup/InputGroup.d.ts +4 -3
  86. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  87. package/dist/InputGroup/InputGroup.js +16 -6
  88. package/dist/InputGroup/InputGroupContext.d.ts +4 -0
  89. package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
  90. package/dist/InputGroup/InputGroupContext.js +2 -2
  91. package/dist/InputGroup/groupStyles.d.ts +1 -1
  92. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  93. package/dist/InputGroup/groupStyles.js +3 -3
  94. package/dist/InputGroup/index.d.ts +1 -0
  95. package/dist/InputGroup/index.d.ts.map +1 -1
  96. package/dist/Kbd/Kbd.d.ts.map +1 -1
  97. package/dist/Kbd/Kbd.js +33 -1
  98. package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
  99. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  100. package/dist/Layer/layerAnimations.stylex.js +8 -4
  101. package/dist/Layer/useLayer.d.ts +10 -0
  102. package/dist/Layer/useLayer.d.ts.map +1 -1
  103. package/dist/Layer/useLayer.js +64 -9
  104. package/dist/Layout/Layout.d.ts +4 -11
  105. package/dist/Layout/Layout.d.ts.map +1 -1
  106. package/dist/Layout/Layout.js +10 -11
  107. package/dist/Layout/LayoutFooter.d.ts +2 -2
  108. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  109. package/dist/Layout/LayoutHeader.d.ts +2 -2
  110. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  111. package/dist/Layout/LayoutPanel.d.ts +2 -2
  112. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  113. package/dist/Layout/padding.stylex.d.ts +51 -0
  114. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  115. package/dist/Layout/padding.stylex.js +63 -0
  116. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  117. package/dist/Lightbox/Lightbox.js +4 -2
  118. package/dist/Link/Link.d.ts +16 -1
  119. package/dist/Link/Link.d.ts.map +1 -1
  120. package/dist/Link/Link.js +18 -7
  121. package/dist/Markdown/Markdown.d.ts.map +1 -1
  122. package/dist/Markdown/Markdown.js +7 -0
  123. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  124. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  125. package/dist/MoreMenu/MoreMenu.js +0 -2
  126. package/dist/MultiSelector/MultiSelector.d.ts +27 -2
  127. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  128. package/dist/MultiSelector/MultiSelector.js +141 -42
  129. package/dist/MultiSelector/hooks.d.ts +12 -1
  130. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  131. package/dist/MultiSelector/hooks.js +14 -1
  132. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  133. package/dist/NavMenu/NavHeadingMenu.js +34 -3
  134. package/dist/NumberInput/NumberInput.d.ts +23 -2
  135. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  136. package/dist/NumberInput/NumberInput.js +62 -12
  137. package/dist/Pagination/Pagination.d.ts +1 -1
  138. package/dist/Pagination/Pagination.d.ts.map +1 -1
  139. package/dist/Pagination/Pagination.js +15 -1
  140. package/dist/Popover/Popover.d.ts +18 -2
  141. package/dist/Popover/Popover.d.ts.map +1 -1
  142. package/dist/Popover/Popover.js +5 -2
  143. package/dist/Popover/usePopover.d.ts +38 -3
  144. package/dist/Popover/usePopover.d.ts.map +1 -1
  145. package/dist/Popover/usePopover.js +24 -9
  146. package/dist/PowerSearch/PowerSearch.d.ts +11 -1
  147. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  148. package/dist/PowerSearch/PowerSearch.js +6 -1
  149. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  150. package/dist/ProgressBar/ProgressBar.js +3 -5
  151. package/dist/RadioList/RadioList.d.ts +20 -2
  152. package/dist/RadioList/RadioList.d.ts.map +1 -1
  153. package/dist/RadioList/RadioList.js +105 -9
  154. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  155. package/dist/RadioList/RadioListItem.js +13 -2
  156. package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
  157. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  158. package/dist/SegmentedControl/SegmentedControl.js +78 -44
  159. package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
  160. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  161. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  162. package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
  163. package/dist/Selector/Selector.d.ts +24 -1
  164. package/dist/Selector/Selector.d.ts.map +1 -1
  165. package/dist/Selector/Selector.js +122 -43
  166. package/dist/Selector/hooks.d.ts +8 -1
  167. package/dist/Selector/hooks.d.ts.map +1 -1
  168. package/dist/Selector/hooks.js +14 -1
  169. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  170. package/dist/SideNav/SideNavHeading.js +2 -0
  171. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  172. package/dist/SideNav/SideNavItem.js +1 -1
  173. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  174. package/dist/Skeleton/Skeleton.js +8 -2
  175. package/dist/Slider/Slider.d.ts +21 -0
  176. package/dist/Slider/Slider.d.ts.map +1 -1
  177. package/dist/Slider/Slider.js +36 -9
  178. package/dist/Spinner/Spinner.d.ts.map +1 -1
  179. package/dist/Spinner/Spinner.js +1 -1
  180. package/dist/Stack/Stack.d.ts +38 -23
  181. package/dist/Stack/Stack.d.ts.map +1 -1
  182. package/dist/Stack/Stack.js +25 -1
  183. package/dist/Stack/StackItem.d.ts +12 -23
  184. package/dist/Stack/StackItem.d.ts.map +1 -1
  185. package/dist/Stack/StackItem.js +8 -1
  186. package/dist/Switch/Switch.d.ts +23 -2
  187. package/dist/Switch/Switch.d.ts.map +1 -1
  188. package/dist/Switch/Switch.js +41 -11
  189. package/dist/TabList/Tab.d.ts.map +1 -1
  190. package/dist/TabList/Tab.js +6 -0
  191. package/dist/TabList/TabList.d.ts +16 -4
  192. package/dist/TabList/TabList.d.ts.map +1 -1
  193. package/dist/TabList/TabList.js +87 -10
  194. package/dist/TabList/TabListContext.d.ts +5 -0
  195. package/dist/TabList/TabListContext.d.ts.map +1 -1
  196. package/dist/TabList/TabListContext.js +5 -0
  197. package/dist/TabList/TabMenu.d.ts.map +1 -1
  198. package/dist/TabList/TabMenu.js +6 -1
  199. package/dist/Table/BaseTable.d.ts.map +1 -1
  200. package/dist/Table/BaseTable.js +13 -9
  201. package/dist/Table/Table.d.ts.map +1 -1
  202. package/dist/Table/Table.js +10 -1
  203. package/dist/Table/TableCell.d.ts +8 -1
  204. package/dist/Table/TableCell.d.ts.map +1 -1
  205. package/dist/Table/TableCell.js +79 -10
  206. package/dist/Table/TableHeaderCell.d.ts +8 -1
  207. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  208. package/dist/Table/TableHeaderCell.js +16 -16
  209. package/dist/Table/index.d.ts +4 -1
  210. package/dist/Table/index.d.ts.map +1 -1
  211. package/dist/Table/index.js +3 -2
  212. package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
  213. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  214. package/dist/Table/plugins/pagination/paginateData.js +8 -3
  215. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  216. package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
  217. package/dist/Table/plugins/rowExpansion/index.d.ts +3 -0
  218. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
  219. package/dist/Table/plugins/rowExpansion/index.js +3 -0
  220. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
  221. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
  222. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
  223. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  224. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  225. package/dist/Table/tableContextMenu.d.ts +37 -0
  226. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  227. package/dist/Table/tableContextMenu.js +140 -0
  228. package/dist/Table/types.d.ts +66 -0
  229. package/dist/Table/types.d.ts.map +1 -1
  230. package/dist/TextArea/TextArea.d.ts +22 -1
  231. package/dist/TextArea/TextArea.d.ts.map +1 -1
  232. package/dist/TextArea/TextArea.js +41 -9
  233. package/dist/TextInput/TextInput.d.ts +23 -2
  234. package/dist/TextInput/TextInput.d.ts.map +1 -1
  235. package/dist/TextInput/TextInput.js +55 -10
  236. package/dist/TimeInput/TimeInput.d.ts +23 -1
  237. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  238. package/dist/TimeInput/TimeInput.js +147 -76
  239. package/dist/Toast/Toast.d.ts.map +1 -1
  240. package/dist/Toast/Toast.js +14 -0
  241. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  242. package/dist/Toast/ToastViewport.js +131 -3
  243. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  244. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  245. package/dist/Tokenizer/Tokenizer.js +26 -4
  246. package/dist/Toolbar/Toolbar.d.ts +3 -3
  247. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  248. package/dist/Toolbar/Toolbar.js +51 -7
  249. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  250. package/dist/Tooltip/useTooltip.js +56 -9
  251. package/dist/TopNav/TopNavHeading.d.ts +7 -1
  252. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  253. package/dist/TopNav/TopNavHeading.js +8 -0
  254. package/dist/TreeList/TreeList.d.ts +1 -1
  255. package/dist/TreeList/TreeList.d.ts.map +1 -1
  256. package/dist/TreeList/TreeList.js +72 -2
  257. package/dist/TreeList/TreeListItem.d.ts +11 -1
  258. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  259. package/dist/TreeList/TreeListItem.js +51 -12
  260. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  261. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  262. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  263. package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +69 -6
  266. package/dist/Typeahead/Typeahead.d.ts +26 -3
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +65 -29
  269. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  270. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  271. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  272. package/dist/VisuallyHidden/index.d.ts +11 -0
  273. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  274. package/dist/VisuallyHidden/index.js +13 -0
  275. package/dist/astryx.css +22 -0
  276. package/dist/astryx.umd.js +55 -55
  277. package/dist/astryx.umd.js.map +4 -4
  278. package/dist/hooks/focusableSelector.d.ts +22 -0
  279. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  280. package/dist/hooks/focusableSelector.js +24 -0
  281. package/dist/hooks/index.d.ts +12 -2
  282. package/dist/hooks/index.d.ts.map +1 -1
  283. package/dist/hooks/index.js +7 -2
  284. package/dist/hooks/useAnnounce.d.ts +40 -0
  285. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  286. package/dist/hooks/useAnnounce.js +142 -0
  287. package/dist/hooks/useClickableContainer.d.ts +16 -1
  288. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  289. package/dist/hooks/useClickableContainer.js +16 -4
  290. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  291. package/dist/hooks/useEntryAnimation.js +4 -4
  292. package/dist/hooks/useFocusTrap.d.ts +18 -0
  293. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  294. package/dist/hooks/useFocusTrap.js +87 -3
  295. package/dist/hooks/useGridFocus.d.ts +88 -1
  296. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  297. package/dist/hooks/useGridFocus.js +261 -62
  298. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  299. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  300. package/dist/hooks/useKeyboardHint.js +220 -0
  301. package/dist/hooks/useListFocus.d.ts +78 -7
  302. package/dist/hooks/useListFocus.d.ts.map +1 -1
  303. package/dist/hooks/useListFocus.js +305 -52
  304. package/dist/hooks/useLongPress.d.ts +21 -0
  305. package/dist/hooks/useLongPress.d.ts.map +1 -0
  306. package/dist/hooks/useLongPress.js +89 -0
  307. package/dist/hooks/useTreeFocus.d.ts +157 -0
  308. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  309. package/dist/hooks/useTreeFocus.js +337 -0
  310. package/dist/hooks/useTypeahead.d.ts +63 -0
  311. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  312. package/dist/hooks/useTypeahead.js +117 -0
  313. package/dist/index.d.ts +1 -0
  314. package/dist/index.d.ts.map +1 -1
  315. package/dist/index.js +1 -0
  316. package/dist/utils/dateTypes.d.ts +12 -0
  317. package/dist/utils/dateTypes.d.ts.map +1 -1
  318. package/dist/utils/dateTypes.js +41 -1
  319. package/dist/utils/index.d.ts +4 -0
  320. package/dist/utils/index.d.ts.map +1 -1
  321. package/dist/utils/index.js +3 -1
  322. package/dist/utils/inputAria.d.ts +29 -0
  323. package/dist/utils/inputAria.d.ts.map +1 -0
  324. package/dist/utils/inputAria.js +30 -0
  325. package/dist/utils/timeParser.d.ts.map +1 -1
  326. package/dist/utils/timeParser.js +5 -2
  327. package/docs.mjs +2 -2
  328. package/package.json +12 -8
  329. package/src/Avatar/Avatar.doc.mjs +2 -2
  330. package/src/Avatar/Avatar.test.tsx +37 -0
  331. package/src/Avatar/Avatar.tsx +10 -5
  332. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  333. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  334. package/src/Button/Button.tsx +42 -22
  335. package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
  336. package/src/ButtonGroup/ButtonGroup.tsx +0 -1
  337. package/src/Calendar/Calendar.doc.mjs +4 -4
  338. package/src/Calendar/Calendar.test.tsx +247 -30
  339. package/src/Calendar/Calendar.tsx +173 -86
  340. package/src/Calendar/dayCellUtils.test.ts +306 -1
  341. package/src/Calendar/dayCellUtils.ts +206 -13
  342. package/src/Calendar/hooks/index.ts +0 -6
  343. package/src/Calendar/index.ts +1 -3
  344. package/src/Calendar/styles.ts +4 -9
  345. package/src/Carousel/Carousel.doc.mjs +7 -1
  346. package/src/Carousel/Carousel.test.tsx +20 -0
  347. package/src/Carousel/Carousel.tsx +16 -1
  348. package/src/Center/Center.doc.mjs +12 -2
  349. package/src/Center/Center.tsx +28 -3
  350. package/src/Chat/ChatComposerInput.test.tsx +26 -7
  351. package/src/Chat/ChatComposerInput.tsx +0 -1
  352. package/src/Chat/ChatDictationButton.doc.mjs +1 -1
  353. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  354. package/src/Chat/ChatMessageList.test.tsx +18 -0
  355. package/src/Chat/ChatMessageList.tsx +16 -0
  356. package/src/Chat/useTriggerMenu.tsx +22 -4
  357. package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
  358. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  359. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  360. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  361. package/src/CheckboxList/CheckboxList.test.tsx +192 -26
  362. package/src/CheckboxList/CheckboxList.tsx +56 -3
  363. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  364. package/src/CheckboxList/CheckboxListItem.tsx +0 -3
  365. package/src/Citation/Citation.doc.mjs +10 -0
  366. package/src/Citation/Citation.test.tsx +121 -0
  367. package/src/Citation/Citation.tsx +15 -3
  368. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  369. package/src/CodeBlock/CodeBlock.tsx +63 -33
  370. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  371. package/src/CommandPalette/CommandPalette.tsx +9 -21
  372. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  373. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  374. package/src/ContextMenu/ContextMenu.tsx +129 -16
  375. package/src/DateInput/DateInput.doc.mjs +291 -56
  376. package/src/DateInput/DateInput.test.tsx +248 -2
  377. package/src/DateInput/DateInput.tsx +196 -100
  378. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  379. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  380. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  381. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  382. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  383. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  384. package/src/Dialog/Dialog.doc.mjs +2 -2
  385. package/src/Dialog/Dialog.tsx +12 -0
  386. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  387. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  388. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  389. package/src/Field/Field.doc.mjs +59 -18
  390. package/src/Field/Field.test.tsx +32 -0
  391. package/src/Field/Field.tsx +23 -5
  392. package/src/Field/FieldLabel.tsx +55 -17
  393. package/src/FileInput/FileInput.doc.mjs +17 -0
  394. package/src/FileInput/FileInput.test.tsx +283 -49
  395. package/src/FileInput/FileInput.tsx +76 -4
  396. package/src/Grid/Grid.doc.mjs +17 -4
  397. package/src/Grid/Grid.test.tsx +43 -30
  398. package/src/Grid/Grid.tsx +38 -3
  399. package/src/Icon/Icon.doc.mjs +3 -3
  400. package/src/InputGroup/InputGroup.doc.mjs +111 -23
  401. package/src/InputGroup/InputGroup.test.tsx +257 -60
  402. package/src/InputGroup/InputGroup.tsx +23 -5
  403. package/src/InputGroup/InputGroupContext.ts +9 -4
  404. package/src/InputGroup/groupStyles.ts +7 -1
  405. package/src/InputGroup/index.ts +1 -0
  406. package/src/Kbd/Kbd.test.tsx +22 -4
  407. package/src/Kbd/Kbd.tsx +35 -3
  408. package/src/Layer/layerAnimations.stylex.ts +20 -4
  409. package/src/Layer/useLayer.doc.mjs +5 -0
  410. package/src/Layer/useLayer.test.tsx +111 -0
  411. package/src/Layer/useLayer.tsx +90 -9
  412. package/src/Layout/Layout.tsx +8 -16
  413. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  414. package/src/Layout/LayoutFooter.tsx +3 -3
  415. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  416. package/src/Layout/LayoutHeader.tsx +3 -3
  417. package/src/Layout/LayoutPanel.tsx +3 -3
  418. package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
  419. package/src/Layout/padding.stylex.ts +52 -0
  420. package/src/Lightbox/Lightbox.doc.mjs +9 -0
  421. package/src/Lightbox/Lightbox.test.tsx +53 -5
  422. package/src/Lightbox/Lightbox.tsx +9 -4
  423. package/src/Link/Link.doc.mjs +14 -0
  424. package/src/Link/Link.test.tsx +50 -0
  425. package/src/Link/Link.tsx +39 -4
  426. package/src/Markdown/Markdown.test.tsx +11 -0
  427. package/src/Markdown/Markdown.tsx +7 -0
  428. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  429. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  430. package/src/MoreMenu/MoreMenu.tsx +0 -9
  431. package/src/MultiSelector/MultiSelector.doc.mjs +35 -0
  432. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  433. package/src/MultiSelector/MultiSelector.tsx +194 -48
  434. package/src/MultiSelector/hooks.ts +27 -0
  435. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  436. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  437. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  438. package/src/NumberInput/NumberInput.test.tsx +242 -40
  439. package/src/NumberInput/NumberInput.tsx +89 -11
  440. package/src/Pagination/Pagination.doc.mjs +3 -3
  441. package/src/Pagination/Pagination.test.tsx +117 -5
  442. package/src/Pagination/Pagination.tsx +21 -1
  443. package/src/Popover/Popover.doc.mjs +26 -0
  444. package/src/Popover/Popover.test.tsx +121 -0
  445. package/src/Popover/Popover.tsx +23 -2
  446. package/src/Popover/usePopover.doc.mjs +9 -3
  447. package/src/Popover/usePopover.tsx +70 -12
  448. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  449. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  450. package/src/PowerSearch/PowerSearch.tsx +16 -3
  451. package/src/ProgressBar/ProgressBar.test.tsx +34 -26
  452. package/src/ProgressBar/ProgressBar.tsx +3 -4
  453. package/src/RadioList/RadioList.doc.mjs +9 -0
  454. package/src/RadioList/RadioList.test.tsx +252 -16
  455. package/src/RadioList/RadioList.tsx +166 -10
  456. package/src/RadioList/RadioListItem.tsx +14 -2
  457. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  458. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  459. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  460. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  461. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  462. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  463. package/src/Selector/Selector.doc.mjs +31 -0
  464. package/src/Selector/Selector.test.tsx +387 -15
  465. package/src/Selector/Selector.tsx +175 -67
  466. package/src/Selector/hooks.ts +23 -0
  467. package/src/SideNav/SideNav.test.tsx +48 -0
  468. package/src/SideNav/SideNavHeading.tsx +8 -2
  469. package/src/SideNav/SideNavItem.tsx +2 -4
  470. package/src/Skeleton/Skeleton.test.tsx +25 -0
  471. package/src/Skeleton/Skeleton.tsx +11 -1
  472. package/src/Slider/Slider.doc.mjs +15 -0
  473. package/src/Slider/Slider.test.tsx +155 -2
  474. package/src/Slider/Slider.tsx +53 -5
  475. package/src/Spinner/Spinner.tsx +7 -1
  476. package/src/Stack/Stack.doc.mjs +77 -0
  477. package/src/Stack/Stack.test.tsx +55 -5
  478. package/src/Stack/Stack.tsx +73 -24
  479. package/src/Stack/StackItem.test.tsx +23 -0
  480. package/src/Stack/StackItem.tsx +20 -23
  481. package/src/Switch/Switch.doc.mjs +15 -0
  482. package/src/Switch/Switch.test.tsx +162 -27
  483. package/src/Switch/Switch.tsx +61 -21
  484. package/src/TabList/Tab.tsx +6 -0
  485. package/src/TabList/TabList.doc.mjs +9 -3
  486. package/src/TabList/TabList.test.tsx +251 -0
  487. package/src/TabList/TabList.tsx +103 -12
  488. package/src/TabList/TabListContext.ts +7 -3
  489. package/src/TabList/TabMenu.tsx +6 -3
  490. package/src/Table/BaseTable.tsx +24 -18
  491. package/src/Table/Table.doc.mjs +2 -0
  492. package/src/Table/Table.test.tsx +10 -0
  493. package/src/Table/Table.tsx +8 -0
  494. package/src/Table/TableCell.tsx +105 -24
  495. package/src/Table/TableHeaderCell.tsx +28 -29
  496. package/src/Table/index.ts +8 -2
  497. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  498. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  499. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  500. package/src/Table/plugins/rowExpansion/index.ts +7 -0
  501. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
  502. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
  503. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  504. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  505. package/src/Table/tableContextMenu.test.tsx +181 -0
  506. package/src/Table/tableContextMenu.tsx +160 -0
  507. package/src/Table/types.ts +74 -0
  508. package/src/Table/useTableColumnResize.doc.mjs +3 -3
  509. package/src/Table/useTablePagination.doc.mjs +4 -1
  510. package/src/Table/useTableRowExpansion.doc.mjs +63 -0
  511. package/src/Table/useTableSortable.doc.mjs +4 -1
  512. package/src/Table/useTableStickyColumns.doc.mjs +2 -2
  513. package/src/Text/Text.doc.mjs +18 -18
  514. package/src/TextArea/TextArea.doc.mjs +17 -0
  515. package/src/TextArea/TextArea.test.tsx +167 -35
  516. package/src/TextArea/TextArea.tsx +62 -15
  517. package/src/TextInput/TextInput.doc.mjs +17 -0
  518. package/src/TextInput/TextInput.test.tsx +168 -34
  519. package/src/TextInput/TextInput.tsx +77 -9
  520. package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
  521. package/src/TimeInput/TimeInput.doc.mjs +345 -60
  522. package/src/TimeInput/TimeInput.test.tsx +255 -7
  523. package/src/TimeInput/TimeInput.tsx +176 -70
  524. package/src/Timestamp/Timestamp.doc.mjs +19 -19
  525. package/src/Toast/Toast.tsx +14 -0
  526. package/src/Toast/ToastViewport.test.tsx +214 -0
  527. package/src/Toast/ToastViewport.tsx +167 -21
  528. package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
  529. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  530. package/src/Tokenizer/Tokenizer.tsx +37 -1
  531. package/src/Toolbar/Toolbar.test.tsx +109 -6
  532. package/src/Toolbar/Toolbar.tsx +59 -5
  533. package/src/Tooltip/Tooltip.test.tsx +68 -0
  534. package/src/Tooltip/useTooltip.tsx +55 -8
  535. package/src/TopNav/TopNav.test.tsx +50 -0
  536. package/src/TopNav/TopNavHeading.tsx +17 -1
  537. package/src/TreeList/TreeList.test.tsx +295 -6
  538. package/src/TreeList/TreeList.tsx +73 -1
  539. package/src/TreeList/TreeListItem.tsx +51 -5
  540. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  541. package/src/Typeahead/BaseTypeahead.tsx +93 -9
  542. package/src/Typeahead/Typeahead.doc.mjs +146 -30
  543. package/src/Typeahead/Typeahead.test.tsx +331 -1
  544. package/src/Typeahead/Typeahead.tsx +105 -33
  545. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  546. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  547. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  548. package/src/VisuallyHidden/index.ts +15 -0
  549. package/src/docs-script.test.mjs +50 -0
  550. package/src/hooks/focusableSelector.ts +25 -0
  551. package/src/hooks/index.ts +28 -2
  552. package/src/hooks/useAnnounce.test.tsx +101 -0
  553. package/src/hooks/useAnnounce.ts +168 -0
  554. package/src/hooks/useClickableContainer.ts +16 -4
  555. package/src/hooks/useEntryAnimation.ts +16 -4
  556. package/src/hooks/useFocusTrap.test.tsx +132 -0
  557. package/src/hooks/useFocusTrap.ts +98 -4
  558. package/src/hooks/useGridFocus.doc.mjs +40 -2
  559. package/src/hooks/useGridFocus.test.tsx +132 -0
  560. package/src/hooks/useGridFocus.ts +343 -67
  561. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  562. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  563. package/src/hooks/useKeyboardHint.tsx +332 -0
  564. package/src/hooks/useListFocus.doc.mjs +50 -10
  565. package/src/hooks/useListFocus.test.tsx +375 -0
  566. package/src/hooks/useListFocus.ts +395 -57
  567. package/src/hooks/useLongPress.test.tsx +134 -0
  568. package/src/hooks/useLongPress.ts +119 -0
  569. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  570. package/src/hooks/useTreeFocus.test.tsx +214 -0
  571. package/src/hooks/useTreeFocus.ts +559 -0
  572. package/src/hooks/useTypeahead.test.tsx +109 -0
  573. package/src/hooks/useTypeahead.ts +183 -0
  574. package/src/index.ts +1 -0
  575. package/src/theme/derivedVarRegistry.test.ts +10 -5
  576. package/src/utils/dateTypes.test.ts +40 -0
  577. package/src/utils/dateTypes.ts +40 -0
  578. package/src/utils/index.ts +9 -0
  579. package/src/utils/inputAria.test.ts +39 -0
  580. package/src/utils/inputAria.ts +58 -0
  581. package/src/utils/timeParser.test.ts +10 -0
  582. package/src/utils/timeParser.ts +5 -2
  583. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  584. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  585. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  586. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -267,6 +267,9 @@ export function TabMenu({
267
267
  hasLightDismiss: true,
268
268
  hasCloseButton: false,
269
269
  hasAutoFocus: false,
270
+ // The popup's own role="menu" is the exposed semantics; a modal dialog
271
+ // wrapper would announce an unnamed dialog around the menu.
272
+ role: 'none',
270
273
  });
271
274
 
272
275
  const {listRef, handleKeyDown: handleListKeyDown} =
@@ -306,6 +309,8 @@ export function TabMenu({
306
309
  aria-haspopup="menu"
307
310
  aria-expanded={popover.isOpen}
308
311
  aria-controls={menuId}
312
+ data-tab-menu=""
313
+ tabIndex={hasSelectedOption ? 0 : -1}
309
314
  onClick={handleToggle}
310
315
  {...mergeProps(
311
316
  themeProps('tab-menu'),
@@ -390,9 +395,7 @@ export function TabMenu({
390
395
  })}
391
396
  {option.label}
392
397
  </span>
393
- {isSelected && (
394
- <Icon icon="check" size="sm" color="accent" />
395
- )}
398
+ {isSelected && <Icon icon="check" size="sm" color="accent" />}
396
399
  </div>
397
400
  );
398
401
  })}
@@ -205,6 +205,7 @@ function TableRowInner<T extends Record<string, unknown>>({
205
205
  <CellComponent
206
206
  key={col.key}
207
207
  {...cellRenderProps.htmlProps}
208
+ contextMenuActions={cellRenderProps.contextMenuActions}
208
209
  xstyle={cellRenderProps.styles}>
209
210
  {content}
210
211
  </CellComponent>
@@ -224,7 +225,7 @@ function TableRowInner<T extends Record<string, unknown>>({
224
225
  rowIndex,
225
226
  );
226
227
 
227
- return (
228
+ const row = (
228
229
  <RowComponent
229
230
  key={rowKey}
230
231
  ref={rowRenderProps.ref}
@@ -233,6 +234,8 @@ function TableRowInner<T extends Record<string, unknown>>({
233
234
  {rowRenderProps.children}
234
235
  </RowComponent>
235
236
  );
237
+
238
+ return row;
236
239
  }
237
240
 
238
241
  /**
@@ -409,29 +412,32 @@ function BaseTableInner<T extends Record<string, unknown>>({
409
412
  const hasSlots =
410
413
  before != null || after != null || overlay != null || below != null;
411
414
 
415
+ const headerInner = hasSlots ? (
416
+ <>
417
+ {before}
418
+ {after != null ? (
419
+ <div {...stylex.props(styles.headerLabelRow)}>
420
+ {resolvedContent}
421
+ {after}
422
+ </div>
423
+ ) : (
424
+ resolvedContent
425
+ )}
426
+ {overlay}
427
+ {below}
428
+ </>
429
+ ) : (
430
+ resolvedContent
431
+ );
432
+
412
433
  return (
413
434
  <HeaderCellComponent
414
435
  key={col.key}
415
436
  {...mergedHtmlProps}
416
437
  {...headerTitleProp}
438
+ contextMenuActions={cellRenderProps.contextMenuActions}
417
439
  xstyle={cellRenderProps.styles}>
418
- {hasSlots ? (
419
- <>
420
- {before}
421
- {after != null ? (
422
- <div {...stylex.props(styles.headerLabelRow)}>
423
- {resolvedContent}
424
- {after}
425
- </div>
426
- ) : (
427
- resolvedContent
428
- )}
429
- {overlay}
430
- {below}
431
- </>
432
- ) : (
433
- resolvedContent
434
- )}
440
+ {headerInner}
435
441
  </HeaderCellComponent>
436
442
  );
437
443
  });
@@ -118,6 +118,7 @@ export const docs = {
118
118
  { guidance: true, description: 'Use density and divider variants to match the information density and scanning needs of your data.' },
119
119
  { guidance: true, description: 'Compose rich cell content with Astryx components like Badge, StatusDot, and Avatar via renderCell.' },
120
120
  { guidance: true, description: 'Set explicit width on every column using proportional() or pixel(). proportional(1) gives equal flex distribution with a 120px minimum that prevents columns from collapsing on narrow viewports. Omitting width skips the minimum.' },
121
+ { guidance: true, description: 'Use the data-driven API from React Server Components: proportional(), pixel(), and column definitions without function props are server-safe. Columns using renderCell (or any function prop) need the table wrapped in a "use client" component, since functions cannot cross the server-client boundary.' },
121
122
  { guidance: false, description: 'Use a table for data without consistent columns. Use a list or card layout for heterogeneous content.' },
122
123
  { guidance: false, description: 'Enable every plugin at once. Add only the features your use case requires to keep the interface focused.' },
123
124
  { guidance: false, description: 'Omit width on text-heavy columns; without an explicit proportional() width they have no minimum and can squish to near-zero on mobile.' },
@@ -165,6 +166,7 @@ export const docsDense = {
165
166
  { guidance: true, description: 'Use density and divider variants to match the information density and scanning needs of your data.' },
166
167
  { guidance: true, description: 'Compose rich cell content with Astryx components like Badge, StatusDot, and Avatar via renderCell.' },
167
168
  { guidance: true, description: 'Set explicit width on every column via proportional() or pixel(). proportional(1) = equal flex w/ 120px min preventing collapse on narrow viewports. Omitting width skips the minimum.' },
169
+ { guidance: true, description: 'Data-driven API is RSC-safe: proportional(), pixel(), column defs w/o function props work in Server Components. renderCell (any function prop) requires a "use client" wrapper.' },
168
170
  { guidance: false, description: 'Use a table for data without consistent columns. Use a list or card layout for heterogeneous content.' },
169
171
  { guidance: false, description: 'Enable every plugin at once. Add only the features your use case requires to keep the interface focused.' },
170
172
  { guidance: false, description: 'Omit width on text-heavy columns; w/o explicit proportional() width they have no minimum and can squish to near-zero on mobile.' },
@@ -633,6 +633,16 @@ describe('Table', () => {
633
633
  expect(wrapper!.className).toContain('astryx-table-scroll-wrapper');
634
634
  });
635
635
 
636
+ it('makes the scroll container keyboard-focusable', () => {
637
+ render(<Table data={users} columns={columns} />);
638
+ const table = screen.getByRole('table');
639
+ const wrapper = table.parentElement;
640
+ expect(wrapper).toBeTruthy();
641
+ expect(wrapper!).toHaveAttribute('tabindex', '0');
642
+ expect(wrapper!).toHaveAttribute('role', 'group');
643
+ expect(wrapper!).toHaveAttribute('aria-label', 'Table');
644
+ });
645
+
636
646
  it('uses table-layout: auto in children mode', () => {
637
647
  const {container} = render(
638
648
  <Table dividers="rows">
@@ -151,6 +151,14 @@ function TableScrollWrapper({
151
151
  return (
152
152
  <div
153
153
  ref={ref}
154
+ // Keyboard-focusable so keyboard users can scroll a horizontally
155
+ // overflowing table. Uses role="group" (not "region") so multiple
156
+ // tables on a page don't create duplicate same-named landmarks
157
+ // (axe: landmark-unique). Callers may override role/aria-label via
158
+ // htmlProps.
159
+ tabIndex={0}
160
+ role="group"
161
+ aria-label="Table"
154
162
  {...restHtmlProps}
155
163
  {...mergeProps(
156
164
  themeProps('table-scroll-wrapper'),
@@ -24,6 +24,8 @@ import {
24
24
  typeScaleVars,
25
25
  } from '../theme/tokens.stylex';
26
26
  import type {StyleXStyles} from '../theme/types';
27
+ import type {TableContextActions} from './types';
28
+ import {wrapInTableContextMenu} from './tableContextMenu';
27
29
  import {
28
30
  overflowStyles,
29
31
  wrapStyles,
@@ -56,6 +58,12 @@ export interface TableCellProps extends BaseProps<HTMLTableCellElement> {
56
58
  * Must be a `stylex.create()` value — not an inline style object.
57
59
  */
58
60
  xstyle?: StyleXStyles | StyleXStyles[];
61
+ /**
62
+ * Right-click actions rendered as a context menu around the cell content.
63
+ * The cell owns the wrapper so it controls how the menu interacts with its
64
+ * padding / content. Empty or undefined renders no menu.
65
+ */
66
+ contextMenuActions?: TableContextActions;
59
67
  }
60
68
 
61
69
  const densityStyles = stylex.create({
@@ -79,6 +87,62 @@ const densityStyles = stylex.create({
79
87
  },
80
88
  });
81
89
 
90
+ // When a cell owns a context menu, its padding moves from the `<td>` onto the
91
+ // right-click trigger wrapper so the *entire* cell (padding included) opens the
92
+ // menu. Without this, right-clicking the padding ring near a cell edge falls
93
+ // through to the browser's native menu. Paired with `contextMenuCellStyles` on
94
+ // the `<td>` (font/box-sizing only — no padding).
95
+ const densityTextStyles = stylex.create({
96
+ compact: {
97
+ fontSize: typeScaleVars['--text-body-size'],
98
+ boxSizing: 'border-box',
99
+ },
100
+ balanced: {
101
+ fontSize: typeScaleVars['--text-body-size'],
102
+ boxSizing: 'border-box',
103
+ },
104
+ spacious: {
105
+ fontSize: typeScaleVars['--text-body-size'],
106
+ boxSizing: 'border-box',
107
+ },
108
+ });
109
+
110
+ const densityPaddingStyles = stylex.create({
111
+ compact: {
112
+ paddingBlock: spacingVars['--spacing-1'],
113
+ paddingInline: spacingVars['--spacing-2'],
114
+ },
115
+ balanced: {
116
+ paddingBlock: spacingVars['--spacing-2'],
117
+ paddingInline: spacingVars['--spacing-3'],
118
+ },
119
+ spacious: {
120
+ paddingBlock: spacingVars['--spacing-3'],
121
+ paddingInline: spacingVars['--spacing-4'],
122
+ },
123
+ });
124
+
125
+ // The trigger wrapper fills the whole cell (a `<td>` child with height:100%
126
+ // stretches to the row height) so a right-click anywhere in the cell opens the
127
+ // menu. It carries the density padding relocated off the `<td>`.
128
+ const triggerFillStyles = stylex.create({
129
+ fill: {
130
+ display: 'block',
131
+ boxSizing: 'border-box',
132
+ blockSize: '100%',
133
+ inlineSize: '100%',
134
+ },
135
+ });
136
+
137
+ // `height:100%` on the `<td>` is the CSS trick that lets a block child resolve
138
+ // its own `height:100%` against the row height — so the trigger fills the cell
139
+ // vertically (top/bottom padding included) and is fully right-clickable.
140
+ const contextMenuCellStyles = stylex.create({
141
+ cell: {
142
+ blockSize: '100%',
143
+ },
144
+ });
145
+
82
146
  const dividerRowStyles = stylex.create({
83
147
  cell: {
84
148
  borderBottomWidth: {
@@ -138,33 +202,50 @@ export function TableCell({
138
202
  ref,
139
203
  className: incomingClassName,
140
204
  style: incomingStyle,
205
+ contextMenuActions,
141
206
  ...props
142
207
  }: TableCellProps) {
143
208
  const ctx = useTableContext();
144
209
 
145
- if (!ctx) {
146
- return (
147
- <td
148
- ref={ref}
149
- {...props}
150
- {...mergeProps(
151
- themeProps('table-cell'),
152
- stylex.props(xstyle),
153
- incomingClassName,
154
- incomingStyle,
155
- )}>
156
- {children}
157
- </td>
158
- );
159
- }
160
-
161
- const cellStyles: StyleXStyles[] = [
162
- densityStyles[ctx.density],
163
- ctx.textOverflow === 'truncate' ? overflowStyles.cell : wrapStyles.cell,
164
- containerEdgeStyles[ctx.density],
165
- verticalAlignStyles[ctx.verticalAlign],
166
- ...buildDividerStyles(ctx, dividerRowStyles.cell, dividerColumnStyles.cell),
167
- ];
210
+ const hasContextMenu =
211
+ typeof contextMenuActions === 'function' ||
212
+ (Array.isArray(contextMenuActions) && contextMenuActions.length > 0);
213
+
214
+ // When the cell owns a context menu, its density padding is relocated onto
215
+ // the right-click trigger wrapper (see `content` below) so the entire cell —
216
+ // padding included — opens the menu. Otherwise padding lives on the `<td>`.
217
+ const cellStyles: StyleXStyles[] = ctx
218
+ ? [
219
+ hasContextMenu
220
+ ? densityTextStyles[ctx.density]
221
+ : densityStyles[ctx.density],
222
+ ctx.textOverflow === 'truncate' ? overflowStyles.cell : wrapStyles.cell,
223
+ containerEdgeStyles[ctx.density],
224
+ verticalAlignStyles[ctx.verticalAlign],
225
+ ...buildDividerStyles(
226
+ ctx,
227
+ dividerRowStyles.cell,
228
+ dividerColumnStyles.cell,
229
+ ),
230
+ ...(hasContextMenu ? [contextMenuCellStyles.cell] : []),
231
+ ]
232
+ : [];
233
+
234
+ // The cell owns the context-menu wrapper so it controls how the menu
235
+ // interacts with its padding / content. No-op when no actions. When actions
236
+ // exist we make the trigger fill the cell and carry the density padding so a
237
+ // right-click anywhere in the cell (including the padding ring) opens it.
238
+ const triggerXstyle =
239
+ hasContextMenu && ctx
240
+ ? [triggerFillStyles.fill, densityPaddingStyles[ctx.density]]
241
+ : hasContextMenu
242
+ ? triggerFillStyles.fill
243
+ : undefined;
244
+ const content = wrapInTableContextMenu(
245
+ children,
246
+ contextMenuActions,
247
+ triggerXstyle,
248
+ );
168
249
 
169
250
  return (
170
251
  <td
@@ -176,7 +257,7 @@ export function TableCell({
176
257
  incomingClassName,
177
258
  incomingStyle,
178
259
  )}>
179
- {children}
260
+ {content}
180
261
  </td>
181
262
  );
182
263
  }
@@ -25,8 +25,10 @@ import {
25
25
  borderVars,
26
26
  } from '../theme/tokens.stylex';
27
27
  import type {StyleXStyles} from '../theme/types';
28
+ import type {TableContextActions} from './types';
28
29
  import {overflowStyles, containerEdgeStyles} from './table.stylex';
29
30
  import {useTableContext, mergeXStyle} from './useTableCellStyles';
31
+ import {wrapInTableContextMenu} from './tableContextMenu';
30
32
  import {mergeProps} from '../utils';
31
33
  import {themeProps} from '../utils/themeProps';
32
34
 
@@ -42,6 +44,12 @@ export interface TableHeaderCellProps extends BaseProps<HTMLTableCellElement> {
42
44
  * Must be a `stylex.create()` value — not an inline style object.
43
45
  */
44
46
  xstyle?: StyleXStyles | StyleXStyles[];
47
+ /**
48
+ * Right-click actions rendered as a context menu around the cell content.
49
+ * The cell owns the wrapper so it controls how the menu interacts with its
50
+ * padding / content. Empty or undefined renders no menu.
51
+ */
52
+ contextMenuActions?: TableContextActions;
45
53
  }
46
54
 
47
55
  const densityStyles = stylex.create({
@@ -117,41 +125,32 @@ export function TableHeaderCell({
117
125
  ref,
118
126
  className: incomingClassName,
119
127
  style: incomingStyle,
128
+ contextMenuActions,
120
129
  ...props
121
130
  }: TableHeaderCellProps) {
122
131
  const ctx = useTableContext();
123
132
 
124
- if (!ctx) {
125
- return (
126
- <th
127
- ref={ref}
128
- {...props}
129
- {...mergeProps(
130
- themeProps('table-header-cell'),
131
- stylex.props(xstyle),
132
- incomingClassName,
133
- incomingStyle,
134
- )}>
135
- {children}
136
- </th>
133
+ // Header cells always get the bottom divider (separates header from body).
134
+ // When used standalone (no table context) the cell renders plain, with no
135
+ // density/divider styles.
136
+ const cellStyles: StyleXStyles[] = [];
137
+ if (ctx) {
138
+ cellStyles.push(
139
+ headerStyles.cell,
140
+ densityStyles[ctx.density],
141
+ headerDividerStyles.cell,
142
+ overflowStyles.cell,
143
+ containerEdgeStyles[ctx.density],
137
144
  );
145
+ // Column dividers come from the shared builder (column axis only).
146
+ if (ctx.dividers === 'columns' || ctx.dividers === 'grid') {
147
+ cellStyles.push(dividerColumnStyles.cell);
148
+ }
138
149
  }
139
150
 
140
- // Header cells always get the bottom divider (separates header from body).
141
- // Column dividers use the shared buildDividerStyles but only for
142
- // the column axis, since the row divider is the headerDividerStyles.
143
- const cellStyles: StyleXStyles[] = [
144
- headerStyles.cell,
145
- densityStyles[ctx.density],
146
- headerDividerStyles.cell,
147
- overflowStyles.cell,
148
- containerEdgeStyles[ctx.density],
149
- ];
150
-
151
- // Only add column dividers from the shared builder
152
- if (ctx.dividers === 'columns' || ctx.dividers === 'grid') {
153
- cellStyles.push(dividerColumnStyles.cell);
154
- }
151
+ // The cell owns the context-menu wrapper so it controls how the menu
152
+ // interacts with its padding / content. No-op when no actions.
153
+ const content = wrapInTableContextMenu(children, contextMenuActions);
155
154
 
156
155
  return (
157
156
  <th
@@ -163,7 +162,7 @@ export function TableHeaderCell({
163
162
  incomingClassName,
164
163
  incomingStyle,
165
164
  )}>
166
- {children}
165
+ {content}
167
166
  </th>
168
167
  );
169
168
  }
@@ -1,7 +1,5 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- 'use client';
4
-
5
3
  /**
6
4
  * @file index.ts
7
5
  * @input Imports from Table component files
@@ -28,6 +26,11 @@ export {useTableColumnSettings} from './plugins/columnSettings';
28
26
  export {useTableColumnSettingsState} from './plugins/columnSettings';
29
27
  export {useTableColumnResize} from './plugins/columnResize';
30
28
  export {useTableStickyColumns} from './plugins/stickyColumns';
29
+ export {
30
+ useTableRowExpansion,
31
+ useTableRowExpansionState,
32
+ } from './plugins/rowExpansion';
33
+ export {resolveContextActions} from './tableContextMenu';
31
34
  export {
32
35
  useTableFiltering,
33
36
  useTableFilterState,
@@ -49,6 +52,8 @@ export type {
49
52
  ProportionalWidth,
50
53
  PixelWidth,
51
54
  TablePlugin,
55
+ TableContextAction,
56
+ TableContextActions,
52
57
  TableRenderProps,
53
58
  HeaderRowRenderProps,
54
59
  HeaderCellRenderProps,
@@ -96,6 +101,7 @@ export type {
96
101
  } from './plugins/columnSettings';
97
102
  export type {UseTableColumnResizeConfig} from './plugins/columnResize';
98
103
  export type {UseTableStickyColumnsConfig} from './plugins/stickyColumns';
104
+ export type {UseTableRowExpansionConfig} from './plugins/rowExpansion';
99
105
  export type {
100
106
  UseTableFilteringConfig,
101
107
  TableFilterState,
@@ -15,7 +15,8 @@
15
15
  *
16
16
  * @param data - Full data array
17
17
  * @param page - Current page number (1-based)
18
- * @param pageSize - Number of items per page
18
+ * @param pageSize - Number of items per page; coerced to a positive integer,
19
+ * non-finite values fall back to 10
19
20
  * @returns Slice of data for the current page
20
21
  *
21
22
  * @example
@@ -31,6 +32,12 @@ export function paginateData<T>(
31
32
  page: number,
32
33
  pageSize: number,
33
34
  ): T[] {
34
- const start = (page - 1) * pageSize;
35
- return data.slice(start, start + pageSize);
35
+ // Same coercion as Pagination and useTablePagination: a 0/NaN/negative
36
+ // pageSize would slice every page empty while the pagination chrome still
37
+ // renders page buttons.
38
+ const size = Number.isFinite(pageSize)
39
+ ? Math.max(1, Math.floor(pageSize))
40
+ : 10;
41
+ const start = (page - 1) * size;
42
+ return data.slice(start, start + size);
36
43
  }
@@ -184,6 +184,22 @@ describe('useTablePagination', () => {
184
184
  ).toBeTruthy();
185
185
  });
186
186
 
187
+ it('guards pageSize 0 against Infinity page counts', () => {
188
+ render(<PaginatedTable data={generateItems(5)} pageSize={0} />);
189
+ expect(
190
+ screen.getByRole('navigation', {name: 'Table pagination'}),
191
+ ).toBeInTheDocument();
192
+ // pageSize is coerced to 1, so 5 items produce 5 pages, not Infinity,
193
+ // and page 1 shows the first item instead of an empty slice
194
+ expect(
195
+ screen.queryByRole('button', {name: 'Go to page Infinity'}),
196
+ ).toBeNull();
197
+ expect(
198
+ screen.getByRole('button', {name: 'Go to page 5'}),
199
+ ).toBeInTheDocument();
200
+ expect(screen.getByText('Item 1')).toBeInTheDocument();
201
+ });
202
+
187
203
  it('transformTableContext renders Pagination above table', () => {
188
204
  render(
189
205
  <PaginatedTable
@@ -199,7 +199,7 @@ export function useTablePagination<T extends Record<string, unknown>>(
199
199
  totalItems,
200
200
  totalPages: totalPagesProp,
201
201
  hasMore,
202
- pageSize = 10,
202
+ pageSize: pageSizeConfig = 10,
203
203
  onPageSizeChange,
204
204
  pageSizeOptions,
205
205
  variant = 'pages',
@@ -209,6 +209,13 @@ export function useTablePagination<T extends Record<string, unknown>>(
209
209
  label = 'Table pagination',
210
210
  } = config;
211
211
 
212
+ // Same guard as Pagination itself: 0/NaN/negative pageSize would produce an
213
+ // Infinity/NaN totalPages here, which bypasses Pagination's own coercion
214
+ // because it is passed down as the explicit totalPages prop.
215
+ const pageSize = Number.isFinite(pageSizeConfig)
216
+ ? Math.max(1, Math.floor(pageSizeConfig))
217
+ : 10;
218
+
212
219
  const computedTotalPages =
213
220
  totalPagesProp ??
214
221
  (totalItems != null ? Math.ceil(totalItems / pageSize) : undefined);
@@ -0,0 +1,7 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ export {
4
+ useTableRowExpansion,
5
+ useTableRowExpansionState,
6
+ } from './useTableRowExpansion';
7
+ export type {UseTableRowExpansionConfig} from './useTableRowExpansion';