@astryxdesign/core 0.1.2 → 0.1.3-canary.6d57c8d
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.
- package/CHANGELOG.md +165 -0
- package/README.md +12 -12
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +11 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +2 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +0 -1
- package/dist/Calendar/Calendar.d.ts +5 -4
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +82 -43
- package/dist/Calendar/hooks/index.d.ts +0 -2
- package/dist/Calendar/hooks/index.d.ts.map +1 -1
- package/dist/Calendar/hooks/index.js +1 -2
- package/dist/Calendar/index.d.ts +3 -3
- package/dist/Calendar/index.d.ts.map +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/Calendar/styles.d.ts +3 -9
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +3 -11
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +17 -3
- package/dist/Center/Center.d.ts +11 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +9 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +0 -1
- package/dist/Chat/ChatMessageList.d.ts +14 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +2 -0
- package/dist/Chat/useTriggerMenu.d.ts +8 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -3
- package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +51 -9
- package/dist/CheckboxList/CheckboxList.d.ts +13 -1
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +39 -9
- package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +0 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +9 -5
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +51 -37
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +5 -5
- package/dist/ContextMenu/ContextMenu.d.ts +4 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +93 -11
- package/dist/DateInput/DateInput.d.ts +23 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +167 -99
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +42 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +78 -15
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +12 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +42 -14
- package/dist/Field/Field.d.ts +19 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -0
- package/dist/Field/FieldLabel.d.ts +21 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +41 -26
- package/dist/FileInput/FileInput.d.ts +22 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +56 -10
- package/dist/Grid/Grid.d.ts +11 -1
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +32 -6
- package/dist/InputGroup/InputGroup.d.ts +4 -3
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +16 -6
- package/dist/InputGroup/InputGroupContext.d.ts +4 -0
- package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
- package/dist/InputGroup/InputGroupContext.js +2 -2
- package/dist/InputGroup/groupStyles.d.ts +1 -1
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +3 -3
- package/dist/InputGroup/index.d.ts +1 -0
- package/dist/InputGroup/index.d.ts.map +1 -1
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +33 -1
- package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +8 -4
- package/dist/Layer/useLayer.d.ts +10 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +64 -9
- package/dist/Layout/Layout.d.ts +4 -11
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +10 -11
- package/dist/Layout/LayoutFooter.d.ts +2 -2
- package/dist/Layout/LayoutFooter.d.ts.map +1 -1
- package/dist/Layout/LayoutHeader.d.ts +2 -2
- package/dist/Layout/LayoutHeader.d.ts.map +1 -1
- package/dist/Layout/LayoutPanel.d.ts +2 -2
- package/dist/Layout/LayoutPanel.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.d.ts +51 -0
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +63 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +4 -2
- package/dist/Link/Link.d.ts +16 -1
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +18 -7
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MoreMenu/MoreMenu.d.ts +1 -7
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +0 -2
- package/dist/MultiSelector/MultiSelector.d.ts +27 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +141 -42
- package/dist/MultiSelector/hooks.d.ts +12 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +14 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +34 -3
- package/dist/NumberInput/NumberInput.d.ts +23 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +62 -12
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +15 -1
- package/dist/Popover/Popover.d.ts +18 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +5 -2
- package/dist/Popover/usePopover.d.ts +38 -3
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +24 -9
- package/dist/PowerSearch/PowerSearch.d.ts +11 -1
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +6 -1
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +3 -5
- package/dist/RadioList/RadioList.d.ts +20 -2
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +105 -9
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +78 -44
- package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
- package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
- package/dist/Selector/Selector.d.ts +24 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +122 -43
- package/dist/Selector/hooks.d.ts +8 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +14 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +2 -0
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +8 -2
- package/dist/Slider/Slider.d.ts +21 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +36 -9
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +1 -1
- package/dist/Stack/Stack.d.ts +38 -23
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +25 -1
- package/dist/Stack/StackItem.d.ts +12 -23
- package/dist/Stack/StackItem.d.ts.map +1 -1
- package/dist/Stack/StackItem.js +8 -1
- package/dist/Switch/Switch.d.ts +23 -2
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -11
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +6 -0
- package/dist/TabList/TabList.d.ts +16 -4
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +87 -10
- package/dist/TabList/TabListContext.d.ts +5 -0
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +5 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +6 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +11 -8
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +10 -1
- package/dist/Table/TableCell.d.ts +8 -1
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +10 -10
- package/dist/Table/TableHeaderCell.d.ts +8 -1
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.js +16 -16
- package/dist/Table/index.d.ts +2 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +2 -2
- package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +8 -3
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
- package/dist/Table/tableContextMenu.d.ts +33 -0
- package/dist/Table/tableContextMenu.d.ts.map +1 -0
- package/dist/Table/tableContextMenu.js +133 -0
- package/dist/Table/types.d.ts +66 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/TextArea/TextArea.d.ts +22 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +41 -9
- package/dist/TextInput/TextInput.d.ts +23 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +55 -10
- package/dist/TimeInput/TimeInput.d.ts +23 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +147 -76
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +14 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +131 -3
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +26 -4
- package/dist/Toolbar/Toolbar.d.ts +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +51 -7
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +56 -9
- package/dist/TopNav/TopNavHeading.d.ts +7 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +8 -0
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +72 -2
- package/dist/TreeList/TreeListItem.d.ts +11 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +51 -12
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
- package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
- package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +69 -6
- package/dist/Typeahead/Typeahead.d.ts +26 -3
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +65 -29
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
- package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
- package/dist/VisuallyHidden/index.d.ts +11 -0
- package/dist/VisuallyHidden/index.d.ts.map +1 -0
- package/dist/VisuallyHidden/index.js +13 -0
- package/dist/astryx.css +18 -0
- package/dist/astryx.umd.js +55 -55
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/focusableSelector.d.ts +22 -0
- package/dist/hooks/focusableSelector.d.ts.map +1 -0
- package/dist/hooks/focusableSelector.js +24 -0
- package/dist/hooks/index.d.ts +12 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -2
- package/dist/hooks/useAnnounce.d.ts +40 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -0
- package/dist/hooks/useAnnounce.js +142 -0
- package/dist/hooks/useClickableContainer.d.ts +16 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +16 -4
- package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
- package/dist/hooks/useEntryAnimation.js +4 -4
- package/dist/hooks/useFocusTrap.d.ts +18 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +87 -3
- package/dist/hooks/useGridFocus.d.ts +88 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +261 -62
- package/dist/hooks/useKeyboardHint.d.ts +82 -0
- package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
- package/dist/hooks/useKeyboardHint.js +220 -0
- package/dist/hooks/useListFocus.d.ts +78 -7
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +305 -52
- package/dist/hooks/useLongPress.d.ts +21 -0
- package/dist/hooks/useLongPress.d.ts.map +1 -0
- package/dist/hooks/useLongPress.js +89 -0
- package/dist/hooks/useTreeFocus.d.ts +157 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -0
- package/dist/hooks/useTreeFocus.js +337 -0
- package/dist/hooks/useTypeahead.d.ts +63 -0
- package/dist/hooks/useTypeahead.d.ts.map +1 -0
- package/dist/hooks/useTypeahead.js +117 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/utils/dateTypes.d.ts +12 -0
- package/dist/utils/dateTypes.d.ts.map +1 -1
- package/dist/utils/dateTypes.js +41 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/inputAria.d.ts +29 -0
- package/dist/utils/inputAria.d.ts.map +1 -0
- package/dist/utils/inputAria.js +30 -0
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +5 -2
- package/docs.mjs +2 -2
- package/package.json +12 -8
- package/src/Avatar/Avatar.test.tsx +37 -0
- package/src/Avatar/Avatar.tsx +10 -5
- package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
- package/src/Button/Button.tsx +3 -16
- package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
- package/src/ButtonGroup/ButtonGroup.tsx +0 -1
- package/src/Calendar/Calendar.doc.mjs +4 -4
- package/src/Calendar/Calendar.test.tsx +168 -30
- package/src/Calendar/Calendar.tsx +121 -66
- package/src/Calendar/hooks/index.ts +0 -6
- package/src/Calendar/index.ts +1 -3
- package/src/Calendar/styles.ts +4 -9
- package/src/Carousel/Carousel.doc.mjs +7 -1
- package/src/Carousel/Carousel.test.tsx +20 -0
- package/src/Carousel/Carousel.tsx +16 -1
- package/src/Center/Center.doc.mjs +12 -2
- package/src/Center/Center.tsx +28 -3
- package/src/Chat/ChatComposerInput.test.tsx +26 -7
- package/src/Chat/ChatComposerInput.tsx +0 -1
- package/src/Chat/ChatDictationButton.doc.mjs +1 -1
- package/src/Chat/ChatMessageList.doc.mjs +8 -0
- package/src/Chat/ChatMessageList.test.tsx +18 -0
- package/src/Chat/ChatMessageList.tsx +16 -0
- package/src/Chat/useTriggerMenu.tsx +22 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
- package/src/CheckboxInput/CheckboxInput.tsx +78 -6
- package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
- package/src/CheckboxList/CheckboxList.test.tsx +192 -26
- package/src/CheckboxList/CheckboxList.tsx +56 -3
- package/src/CheckboxList/CheckboxListContext.tsx +7 -0
- package/src/CheckboxList/CheckboxListItem.tsx +0 -3
- package/src/Citation/Citation.doc.mjs +10 -0
- package/src/Citation/Citation.test.tsx +121 -0
- package/src/Citation/Citation.tsx +15 -3
- package/src/CodeBlock/CodeBlock.test.tsx +115 -0
- package/src/CodeBlock/CodeBlock.tsx +63 -33
- package/src/CommandPalette/CommandPalette.test.tsx +47 -1
- package/src/CommandPalette/CommandPalette.tsx +9 -21
- package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
- package/src/ContextMenu/ContextMenu.test.tsx +155 -1
- package/src/ContextMenu/ContextMenu.tsx +113 -16
- package/src/DateInput/DateInput.doc.mjs +286 -56
- package/src/DateInput/DateInput.test.tsx +248 -2
- package/src/DateInput/DateInput.tsx +196 -100
- package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
- package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
- package/src/DateRangeInput/DateRangeInput.tsx +63 -5
- package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
- package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
- package/src/DateTimeInput/DateTimeInput.tsx +125 -17
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.tsx +12 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
- package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
- package/src/DropdownMenu/DropdownMenu.tsx +52 -18
- package/src/Field/Field.doc.mjs +59 -18
- package/src/Field/Field.test.tsx +32 -0
- package/src/Field/Field.tsx +23 -5
- package/src/Field/FieldLabel.tsx +55 -17
- package/src/FileInput/FileInput.doc.mjs +17 -0
- package/src/FileInput/FileInput.test.tsx +283 -49
- package/src/FileInput/FileInput.tsx +76 -4
- package/src/Grid/Grid.doc.mjs +17 -4
- package/src/Grid/Grid.test.tsx +43 -30
- package/src/Grid/Grid.tsx +38 -3
- package/src/Icon/Icon.doc.mjs +3 -3
- package/src/InputGroup/InputGroup.doc.mjs +111 -23
- package/src/InputGroup/InputGroup.test.tsx +257 -60
- package/src/InputGroup/InputGroup.tsx +23 -5
- package/src/InputGroup/InputGroupContext.ts +9 -4
- package/src/InputGroup/groupStyles.ts +7 -1
- package/src/InputGroup/index.ts +1 -0
- package/src/Kbd/Kbd.test.tsx +22 -4
- package/src/Kbd/Kbd.tsx +35 -3
- package/src/Layer/layerAnimations.stylex.ts +20 -4
- package/src/Layer/useLayer.doc.mjs +5 -0
- package/src/Layer/useLayer.test.tsx +111 -0
- package/src/Layer/useLayer.tsx +90 -9
- package/src/Layout/Layout.tsx +8 -16
- package/src/Layout/LayoutFooter.doc.mjs +4 -4
- package/src/Layout/LayoutFooter.tsx +3 -3
- package/src/Layout/LayoutHeader.doc.mjs +4 -4
- package/src/Layout/LayoutHeader.tsx +3 -3
- package/src/Layout/LayoutPanel.tsx +3 -3
- package/src/Layout/padding.stylex.ts +52 -0
- package/src/Lightbox/Lightbox.doc.mjs +9 -0
- package/src/Lightbox/Lightbox.test.tsx +53 -5
- package/src/Lightbox/Lightbox.tsx +9 -4
- package/src/Link/Link.doc.mjs +14 -0
- package/src/Link/Link.test.tsx +50 -0
- package/src/Link/Link.tsx +39 -4
- package/src/Markdown/Markdown.test.tsx +11 -0
- package/src/Markdown/Markdown.tsx +7 -0
- package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
- package/src/MoreMenu/MoreMenu.tsx +0 -9
- package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
- package/src/MultiSelector/MultiSelector.test.tsx +375 -8
- package/src/MultiSelector/MultiSelector.tsx +194 -48
- package/src/MultiSelector/hooks.ts +27 -0
- package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
- package/src/NavMenu/NavHeadingMenu.tsx +50 -3
- package/src/NumberInput/NumberInput.doc.mjs +17 -0
- package/src/NumberInput/NumberInput.test.tsx +242 -40
- package/src/NumberInput/NumberInput.tsx +89 -11
- package/src/Pagination/Pagination.doc.mjs +3 -3
- package/src/Pagination/Pagination.test.tsx +117 -5
- package/src/Pagination/Pagination.tsx +21 -1
- package/src/Popover/Popover.doc.mjs +26 -0
- package/src/Popover/Popover.test.tsx +121 -0
- package/src/Popover/Popover.tsx +23 -2
- package/src/Popover/usePopover.doc.mjs +9 -3
- package/src/Popover/usePopover.tsx +70 -12
- package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
- package/src/PowerSearch/PowerSearch.test.tsx +97 -1
- package/src/PowerSearch/PowerSearch.tsx +16 -3
- package/src/ProgressBar/ProgressBar.test.tsx +34 -26
- package/src/ProgressBar/ProgressBar.tsx +3 -4
- package/src/RadioList/RadioList.doc.mjs +9 -0
- package/src/RadioList/RadioList.test.tsx +252 -16
- package/src/RadioList/RadioList.tsx +166 -10
- package/src/RadioList/RadioListItem.tsx +14 -2
- package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
- package/src/SegmentedControl/SegmentedControl.tsx +102 -54
- package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +26 -0
- package/src/Selector/Selector.test.tsx +387 -15
- package/src/Selector/Selector.tsx +175 -67
- package/src/Selector/hooks.ts +23 -0
- package/src/SideNav/SideNav.test.tsx +48 -0
- package/src/SideNav/SideNavHeading.tsx +8 -2
- package/src/SideNav/SideNavItem.tsx +2 -4
- package/src/Skeleton/Skeleton.test.tsx +25 -0
- package/src/Skeleton/Skeleton.tsx +11 -1
- package/src/Slider/Slider.doc.mjs +15 -0
- package/src/Slider/Slider.test.tsx +155 -2
- package/src/Slider/Slider.tsx +53 -5
- package/src/Spinner/Spinner.tsx +7 -1
- package/src/Stack/Stack.doc.mjs +77 -0
- package/src/Stack/Stack.test.tsx +55 -5
- package/src/Stack/Stack.tsx +73 -24
- package/src/Stack/StackItem.test.tsx +23 -0
- package/src/Stack/StackItem.tsx +20 -23
- package/src/Switch/Switch.doc.mjs +15 -0
- package/src/Switch/Switch.test.tsx +162 -27
- package/src/Switch/Switch.tsx +61 -21
- package/src/TabList/Tab.tsx +6 -0
- package/src/TabList/TabList.doc.mjs +6 -0
- package/src/TabList/TabList.test.tsx +251 -0
- package/src/TabList/TabList.tsx +103 -12
- package/src/TabList/TabListContext.ts +7 -3
- package/src/TabList/TabMenu.tsx +6 -3
- package/src/Table/BaseTable.tsx +21 -17
- package/src/Table/Table.doc.mjs +2 -0
- package/src/Table/Table.test.tsx +10 -0
- package/src/Table/Table.tsx +8 -0
- package/src/Table/TableCell.tsx +25 -23
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/index.ts +3 -2
- package/src/Table/plugins/pagination/paginateData.ts +10 -3
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
- package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
- package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
- package/src/Table/tableContextMenu.test.tsx +157 -0
- package/src/Table/tableContextMenu.tsx +142 -0
- package/src/Table/types.ts +74 -0
- package/src/Table/useTableColumnResize.doc.mjs +3 -3
- package/src/Table/useTableStickyColumns.doc.mjs +2 -2
- package/src/Text/Text.doc.mjs +18 -18
- package/src/TextArea/TextArea.doc.mjs +17 -0
- package/src/TextArea/TextArea.test.tsx +167 -35
- package/src/TextArea/TextArea.tsx +62 -15
- package/src/TextInput/TextInput.doc.mjs +17 -0
- package/src/TextInput/TextInput.test.tsx +168 -34
- package/src/TextInput/TextInput.tsx +77 -9
- package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
- package/src/TimeInput/TimeInput.doc.mjs +340 -60
- package/src/TimeInput/TimeInput.test.tsx +255 -7
- package/src/TimeInput/TimeInput.tsx +176 -70
- package/src/Timestamp/Timestamp.doc.mjs +19 -19
- package/src/Toast/Toast.tsx +14 -0
- package/src/Toast/ToastViewport.test.tsx +214 -0
- package/src/Toast/ToastViewport.tsx +167 -21
- package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
- package/src/Tokenizer/Tokenizer.test.tsx +105 -1
- package/src/Tokenizer/Tokenizer.tsx +37 -1
- package/src/Toolbar/Toolbar.test.tsx +109 -6
- package/src/Toolbar/Toolbar.tsx +59 -5
- package/src/Tooltip/Tooltip.test.tsx +68 -0
- package/src/Tooltip/useTooltip.tsx +55 -8
- package/src/TopNav/TopNav.test.tsx +50 -0
- package/src/TopNav/TopNavHeading.tsx +17 -1
- package/src/TreeList/TreeList.test.tsx +295 -6
- package/src/TreeList/TreeList.tsx +73 -1
- package/src/TreeList/TreeListItem.tsx +51 -5
- package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
- package/src/Typeahead/BaseTypeahead.tsx +93 -9
- package/src/Typeahead/Typeahead.doc.mjs +141 -30
- package/src/Typeahead/Typeahead.test.tsx +331 -1
- package/src/Typeahead/Typeahead.tsx +105 -33
- package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
- package/src/VisuallyHidden/index.ts +15 -0
- package/src/docs-script.test.mjs +50 -0
- package/src/hooks/focusableSelector.ts +25 -0
- package/src/hooks/index.ts +28 -2
- package/src/hooks/useAnnounce.test.tsx +101 -0
- package/src/hooks/useAnnounce.ts +168 -0
- package/src/hooks/useClickableContainer.ts +16 -4
- package/src/hooks/useEntryAnimation.ts +16 -4
- package/src/hooks/useFocusTrap.test.tsx +132 -0
- package/src/hooks/useFocusTrap.ts +98 -4
- package/src/hooks/useGridFocus.doc.mjs +40 -2
- package/src/hooks/useGridFocus.test.tsx +132 -0
- package/src/hooks/useGridFocus.ts +343 -67
- package/src/hooks/useKeyboardHint.doc.mjs +101 -0
- package/src/hooks/useKeyboardHint.test.tsx +70 -0
- package/src/hooks/useKeyboardHint.tsx +332 -0
- package/src/hooks/useListFocus.doc.mjs +50 -10
- package/src/hooks/useListFocus.test.tsx +375 -0
- package/src/hooks/useListFocus.ts +395 -57
- package/src/hooks/useLongPress.test.tsx +134 -0
- package/src/hooks/useLongPress.ts +119 -0
- package/src/hooks/useTreeFocus.doc.mjs +140 -0
- package/src/hooks/useTreeFocus.test.tsx +214 -0
- package/src/hooks/useTreeFocus.ts +559 -0
- package/src/hooks/useTypeahead.test.tsx +109 -0
- package/src/hooks/useTypeahead.ts +183 -0
- package/src/index.ts +1 -0
- package/src/theme/derivedVarRegistry.test.ts +10 -5
- package/src/utils/dateTypes.test.ts +40 -0
- package/src/utils/dateTypes.ts +40 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/inputAria.test.ts +39 -0
- package/src/utils/inputAria.ts +58 -0
- package/src/utils/timeParser.test.ts +10 -0
- package/src/utils/timeParser.ts +5 -2
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
- package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
- package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
package/src/Table/BaseTable.tsx
CHANGED
|
@@ -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>
|
|
@@ -409,29 +410,32 @@ function BaseTableInner<T extends Record<string, unknown>>({
|
|
|
409
410
|
const hasSlots =
|
|
410
411
|
before != null || after != null || overlay != null || below != null;
|
|
411
412
|
|
|
413
|
+
const headerInner = hasSlots ? (
|
|
414
|
+
<>
|
|
415
|
+
{before}
|
|
416
|
+
{after != null ? (
|
|
417
|
+
<div {...stylex.props(styles.headerLabelRow)}>
|
|
418
|
+
{resolvedContent}
|
|
419
|
+
{after}
|
|
420
|
+
</div>
|
|
421
|
+
) : (
|
|
422
|
+
resolvedContent
|
|
423
|
+
)}
|
|
424
|
+
{overlay}
|
|
425
|
+
{below}
|
|
426
|
+
</>
|
|
427
|
+
) : (
|
|
428
|
+
resolvedContent
|
|
429
|
+
);
|
|
430
|
+
|
|
412
431
|
return (
|
|
413
432
|
<HeaderCellComponent
|
|
414
433
|
key={col.key}
|
|
415
434
|
{...mergedHtmlProps}
|
|
416
435
|
{...headerTitleProp}
|
|
436
|
+
contextMenuActions={cellRenderProps.contextMenuActions}
|
|
417
437
|
xstyle={cellRenderProps.styles}>
|
|
418
|
-
{
|
|
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
|
-
)}
|
|
438
|
+
{headerInner}
|
|
435
439
|
</HeaderCellComponent>
|
|
436
440
|
);
|
|
437
441
|
});
|
package/src/Table/Table.doc.mjs
CHANGED
|
@@ -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.' },
|
package/src/Table/Table.test.tsx
CHANGED
|
@@ -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">
|
package/src/Table/Table.tsx
CHANGED
|
@@ -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'),
|
package/src/Table/TableCell.tsx
CHANGED
|
@@ -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({
|
|
@@ -138,33 +146,27 @@ export function TableCell({
|
|
|
138
146
|
ref,
|
|
139
147
|
className: incomingClassName,
|
|
140
148
|
style: incomingStyle,
|
|
149
|
+
contextMenuActions,
|
|
141
150
|
...props
|
|
142
151
|
}: TableCellProps) {
|
|
143
152
|
const ctx = useTableContext();
|
|
144
153
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
</td>
|
|
158
|
-
);
|
|
159
|
-
}
|
|
154
|
+
// Standalone (no table context) renders plain, with no density/divider styles.
|
|
155
|
+
const cellStyles: StyleXStyles[] = ctx
|
|
156
|
+
? [
|
|
157
|
+
densityStyles[ctx.density],
|
|
158
|
+
ctx.textOverflow === 'truncate'
|
|
159
|
+
? overflowStyles.cell
|
|
160
|
+
: wrapStyles.cell,
|
|
161
|
+
containerEdgeStyles[ctx.density],
|
|
162
|
+
verticalAlignStyles[ctx.verticalAlign],
|
|
163
|
+
...buildDividerStyles(ctx, dividerRowStyles.cell, dividerColumnStyles.cell),
|
|
164
|
+
]
|
|
165
|
+
: [];
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
containerEdgeStyles[ctx.density],
|
|
165
|
-
verticalAlignStyles[ctx.verticalAlign],
|
|
166
|
-
...buildDividerStyles(ctx, dividerRowStyles.cell, dividerColumnStyles.cell),
|
|
167
|
-
];
|
|
167
|
+
// The cell owns the context-menu wrapper so it controls how the menu
|
|
168
|
+
// interacts with its padding / content. No-op when no actions.
|
|
169
|
+
const content = wrapInTableContextMenu(children, contextMenuActions);
|
|
168
170
|
|
|
169
171
|
return (
|
|
170
172
|
<td
|
|
@@ -176,7 +178,7 @@ export function TableCell({
|
|
|
176
178
|
incomingClassName,
|
|
177
179
|
incomingStyle,
|
|
178
180
|
)}>
|
|
179
|
-
{
|
|
181
|
+
{content}
|
|
180
182
|
</td>
|
|
181
183
|
);
|
|
182
184
|
}
|
|
@@ -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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
//
|
|
141
|
-
//
|
|
142
|
-
|
|
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
|
-
{
|
|
165
|
+
{content}
|
|
167
166
|
</th>
|
|
168
167
|
);
|
|
169
168
|
}
|
package/src/Table/index.ts
CHANGED
|
@@ -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,7 @@ 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 {resolveContextActions} from './tableContextMenu';
|
|
31
30
|
export {
|
|
32
31
|
useTableFiltering,
|
|
33
32
|
useTableFilterState,
|
|
@@ -49,6 +48,8 @@ export type {
|
|
|
49
48
|
ProportionalWidth,
|
|
50
49
|
PixelWidth,
|
|
51
50
|
TablePlugin,
|
|
51
|
+
TableContextAction,
|
|
52
|
+
TableContextActions,
|
|
52
53
|
TableRenderProps,
|
|
53
54
|
HeaderRowRenderProps,
|
|
54
55
|
HeaderCellRenderProps,
|
|
@@ -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
|
-
|
|
35
|
-
|
|
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);
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* @position Testing; validates sortable plugin implementation
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
11
|
-
import {render, screen} from '@testing-library/react';
|
|
10
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
11
|
+
import {render, screen, fireEvent} from '@testing-library/react';
|
|
12
12
|
import userEvent from '@testing-library/user-event';
|
|
13
13
|
import {useState} from 'react';
|
|
14
14
|
import {Table} from '../../Table';
|
|
@@ -620,3 +620,92 @@ describe('useTableSortable', () => {
|
|
|
620
620
|
});
|
|
621
621
|
});
|
|
622
622
|
});
|
|
623
|
+
|
|
624
|
+
// =============================================================================
|
|
625
|
+
// Context-menu actions (colocated with the sortable plugin)
|
|
626
|
+
// =============================================================================
|
|
627
|
+
|
|
628
|
+
describe('useTableSortable — context menu actions', () => {
|
|
629
|
+
// jsdom doesn't implement the Popover API; mock it so the menu can "open"
|
|
630
|
+
// and its items become queryable (as hidden).
|
|
631
|
+
beforeEach(() => {
|
|
632
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
633
|
+
this.setAttribute('popover-open', '');
|
|
634
|
+
const event = new Event('toggle', {bubbles: false});
|
|
635
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
636
|
+
this.dispatchEvent(event);
|
|
637
|
+
});
|
|
638
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
639
|
+
this.removeAttribute('popover-open');
|
|
640
|
+
const event = new Event('toggle', {bubbles: false});
|
|
641
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
642
|
+
this.dispatchEvent(event);
|
|
643
|
+
});
|
|
644
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
645
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
646
|
+
(HTMLElement.prototype as any).matches = function (
|
|
647
|
+
selector: string,
|
|
648
|
+
): boolean {
|
|
649
|
+
if (selector === ':popover-open') {
|
|
650
|
+
return this.hasAttribute('popover-open');
|
|
651
|
+
}
|
|
652
|
+
return originalMatches.call(this, selector);
|
|
653
|
+
};
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
it('offers Sort ascending/descending on a sortable header, and Clear sort once sorted', () => {
|
|
657
|
+
render(<SortableTable allowUnsortedState />);
|
|
658
|
+
|
|
659
|
+
// Unsorted: asc + desc, no "Clear sort".
|
|
660
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
661
|
+
expect(
|
|
662
|
+
screen.getAllByRole('menuitem', {name: 'Sort ascending', hidden: true})
|
|
663
|
+
.length,
|
|
664
|
+
).toBeGreaterThan(0);
|
|
665
|
+
expect(
|
|
666
|
+
screen.getAllByRole('menuitem', {name: 'Sort descending', hidden: true})
|
|
667
|
+
.length,
|
|
668
|
+
).toBeGreaterThan(0);
|
|
669
|
+
expect(
|
|
670
|
+
screen.queryByRole('menuitem', {name: 'Clear sort', hidden: true}),
|
|
671
|
+
).not.toBeInTheDocument();
|
|
672
|
+
|
|
673
|
+
// Apply ascending → "Clear sort" now appears.
|
|
674
|
+
fireEvent.click(
|
|
675
|
+
screen.getAllByRole('menuitem', {name: 'Sort ascending', hidden: true})[0],
|
|
676
|
+
);
|
|
677
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
678
|
+
expect(
|
|
679
|
+
screen.getAllByRole('menuitem', {name: 'Clear sort', hidden: true}).length,
|
|
680
|
+
).toBeGreaterThan(0);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
it('resolves fresh actions on each open as sort state changes (lazy getter)', () => {
|
|
684
|
+
const onSortChange = vi.fn();
|
|
685
|
+
render(<SortableTable allowUnsortedState onSortChange={onSortChange} />);
|
|
686
|
+
|
|
687
|
+
// Open (unsorted) and pick descending.
|
|
688
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
689
|
+
fireEvent.click(
|
|
690
|
+
screen.getAllByRole('menuitem', {
|
|
691
|
+
name: 'Sort descending',
|
|
692
|
+
hidden: true,
|
|
693
|
+
})[0],
|
|
694
|
+
);
|
|
695
|
+
expect(onSortChange).toHaveBeenLastCalledWith([
|
|
696
|
+
{sortKey: 'name', direction: 'descending'},
|
|
697
|
+
]);
|
|
698
|
+
|
|
699
|
+
// Re-open: the getter recomputes against the now-descending state, so
|
|
700
|
+
// "Clear sort" is present and clicking it clears — proving the actions are
|
|
701
|
+
// freshly derived on each open, not memoized from the first render.
|
|
702
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
703
|
+
const clear = screen.getAllByRole('menuitem', {
|
|
704
|
+
name: 'Clear sort',
|
|
705
|
+
hidden: true,
|
|
706
|
+
});
|
|
707
|
+
expect(clear.length).toBeGreaterThan(0);
|
|
708
|
+
fireEvent.click(clear[0]);
|
|
709
|
+
expect(onSortChange).toHaveBeenLastCalledWith([]);
|
|
710
|
+
});
|
|
711
|
+
});
|
|
@@ -17,10 +17,12 @@ import {useRef, useMemo, type ReactNode} from 'react';
|
|
|
17
17
|
import * as stylex from '@stylexjs/stylex';
|
|
18
18
|
import {colorVars, spacingVars, radiusVars} from '../../../theme/tokens.stylex';
|
|
19
19
|
import {Icon} from '../../../Icon';
|
|
20
|
+
import {resolveContextActions} from '../../tableContextMenu';
|
|
20
21
|
import type {
|
|
21
22
|
TablePlugin,
|
|
22
23
|
HeaderCellRenderProps,
|
|
23
24
|
TableColumn,
|
|
25
|
+
TableContextAction,
|
|
24
26
|
} from '../../types';
|
|
25
27
|
|
|
26
28
|
// =============================================================================
|
|
@@ -356,10 +358,56 @@ export function useTableSortable<
|
|
|
356
358
|
return props;
|
|
357
359
|
}
|
|
358
360
|
|
|
359
|
-
// Find sort entry for this column
|
|
360
361
|
const cfg = configRef.current;
|
|
361
362
|
const entry = cfg.sort.find(e => e.sortKey === sortKey);
|
|
362
363
|
|
|
364
|
+
// Context-menu actions are built lazily (only when the menu opens) via
|
|
365
|
+
// a getter, reading the current sort state at call time — so we don't
|
|
366
|
+
// build an action array for every header on every render, and the
|
|
367
|
+
// checked/clear state always reflects the latest sort.
|
|
368
|
+
const getSortActions = (): TableContextAction[] => {
|
|
369
|
+
const c = configRef.current;
|
|
370
|
+
const dir = c.sort.find(e => e.sortKey === sortKey)?.direction ?? null;
|
|
371
|
+
const actions: TableContextAction[] = [
|
|
372
|
+
{
|
|
373
|
+
id: 'sort-asc',
|
|
374
|
+
group: 'sort',
|
|
375
|
+
label: 'Sort ascending',
|
|
376
|
+
icon: <Icon icon="arrowUp" size="xsm" aria-hidden />,
|
|
377
|
+
checked: dir === 'ascending',
|
|
378
|
+
onSelect: () =>
|
|
379
|
+
c.onSortChange([
|
|
380
|
+
{sortKey: sortKey as TSortKey, direction: 'ascending'},
|
|
381
|
+
]),
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: 'sort-desc',
|
|
385
|
+
group: 'sort',
|
|
386
|
+
label: 'Sort descending',
|
|
387
|
+
icon: <Icon icon="arrowDown" size="xsm" aria-hidden />,
|
|
388
|
+
checked: dir === 'descending',
|
|
389
|
+
onSelect: () =>
|
|
390
|
+
c.onSortChange([
|
|
391
|
+
{sortKey: sortKey as TSortKey, direction: 'descending'},
|
|
392
|
+
]),
|
|
393
|
+
},
|
|
394
|
+
];
|
|
395
|
+
if (dir != null) {
|
|
396
|
+
actions.push({
|
|
397
|
+
id: 'sort-clear',
|
|
398
|
+
group: 'sort-clear',
|
|
399
|
+
label: 'Clear sort',
|
|
400
|
+
icon: <Icon icon="close" size="xsm" aria-hidden />,
|
|
401
|
+
onSelect: () =>
|
|
402
|
+
c.onSortChange(c.sort.filter(e => e.sortKey !== sortKey)),
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
return actions;
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// Merge with any actions a prior plugin contributed (array or getter),
|
|
409
|
+
// resolving both lazily at open time.
|
|
410
|
+
const priorActions = props.contextMenuActions;
|
|
363
411
|
return {
|
|
364
412
|
...props,
|
|
365
413
|
htmlProps: {
|
|
@@ -375,6 +423,10 @@ export function useTableSortable<
|
|
|
375
423
|
{props.content}
|
|
376
424
|
</SortHeaderButton>
|
|
377
425
|
),
|
|
426
|
+
contextMenuActions: () => [
|
|
427
|
+
...resolveContextActions(priorActions),
|
|
428
|
+
...getSortActions(),
|
|
429
|
+
],
|
|
378
430
|
};
|
|
379
431
|
},
|
|
380
432
|
}),
|