@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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file tableContextMenu.test.tsx
|
|
5
|
+
* @output Tests for the Table context-menu system
|
|
6
|
+
* @position Validates contextMenuActions aggregation + header context menus
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
10
|
+
import {render, screen, fireEvent} from '@testing-library/react';
|
|
11
|
+
import {Table} from './Table';
|
|
12
|
+
import type {TablePlugin, TableColumn} from './types';
|
|
13
|
+
import {resolveContextActions} from './tableContextMenu';
|
|
14
|
+
|
|
15
|
+
// jsdom doesn't implement the Popover API; mirror the ContextMenu test's mock
|
|
16
|
+
// so the menu can "open" and its items become queryable (as hidden).
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
19
|
+
this.setAttribute('popover-open', '');
|
|
20
|
+
const event = new Event('toggle', {bubbles: false});
|
|
21
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
22
|
+
this.dispatchEvent(event);
|
|
23
|
+
});
|
|
24
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
25
|
+
this.removeAttribute('popover-open');
|
|
26
|
+
const event = new Event('toggle', {bubbles: false});
|
|
27
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
28
|
+
this.dispatchEvent(event);
|
|
29
|
+
});
|
|
30
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
(HTMLElement.prototype as any).matches = function (
|
|
33
|
+
selector: string,
|
|
34
|
+
): boolean {
|
|
35
|
+
if (selector === ':popover-open') {
|
|
36
|
+
return this.hasAttribute('popover-open');
|
|
37
|
+
}
|
|
38
|
+
return originalMatches.call(this, selector);
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
interface Row extends Record<string, unknown> {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const data: Row[] = [
|
|
48
|
+
{id: '1', name: 'Alice'},
|
|
49
|
+
{id: '2', name: 'Bob'},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const columns: TableColumn<Row>[] = [
|
|
53
|
+
{key: 'name', header: 'Name'},
|
|
54
|
+
{key: 'id', header: 'ID'},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// contextMenuActions via transformHeaderCell
|
|
59
|
+
// =============================================================================
|
|
60
|
+
|
|
61
|
+
describe('Table header context menu', () => {
|
|
62
|
+
it('renders a menu from a plugin that sets contextMenuActions', () => {
|
|
63
|
+
const onSelect = vi.fn();
|
|
64
|
+
const plugin: TablePlugin<Row> = {
|
|
65
|
+
transformHeaderCell: props => ({
|
|
66
|
+
...props,
|
|
67
|
+
contextMenuActions: [{id: 'pin', label: 'Pin column', onSelect}],
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
render(
|
|
71
|
+
<Table data={data} columns={columns} idKey="id" plugins={{plugin}} />,
|
|
72
|
+
);
|
|
73
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
74
|
+
const items = screen.getAllByRole('menuitem', {
|
|
75
|
+
name: 'Pin column',
|
|
76
|
+
hidden: true,
|
|
77
|
+
});
|
|
78
|
+
expect(items.length).toBeGreaterThan(0);
|
|
79
|
+
fireEvent.click(items[0]);
|
|
80
|
+
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('concatenates actions from multiple plugins (never overridden)', () => {
|
|
84
|
+
const a: TablePlugin<Row> = {
|
|
85
|
+
transformHeaderCell: props => ({
|
|
86
|
+
...props,
|
|
87
|
+
contextMenuActions: [
|
|
88
|
+
...resolveContextActions(props.contextMenuActions),
|
|
89
|
+
{id: 'a', label: 'Action A', onSelect: () => {}},
|
|
90
|
+
],
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
const b: TablePlugin<Row> = {
|
|
94
|
+
transformHeaderCell: props => ({
|
|
95
|
+
...props,
|
|
96
|
+
contextMenuActions: [
|
|
97
|
+
...resolveContextActions(props.contextMenuActions),
|
|
98
|
+
{id: 'b', label: 'Action B', onSelect: () => {}},
|
|
99
|
+
],
|
|
100
|
+
}),
|
|
101
|
+
};
|
|
102
|
+
render(
|
|
103
|
+
<Table data={data} columns={columns} idKey="id" plugins={{a, b}} />,
|
|
104
|
+
);
|
|
105
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
106
|
+
expect(
|
|
107
|
+
screen.getAllByRole('menuitem', {name: 'Action A', hidden: true}).length,
|
|
108
|
+
).toBeGreaterThan(0);
|
|
109
|
+
expect(
|
|
110
|
+
screen.getAllByRole('menuitem', {name: 'Action B', hidden: true}).length,
|
|
111
|
+
).toBeGreaterThan(0);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('does not render a menu when no plugin contributes actions', () => {
|
|
115
|
+
render(<Table data={data} columns={columns} idKey="id" />);
|
|
116
|
+
fireEvent.contextMenu(screen.getByText('Name'));
|
|
117
|
+
expect(
|
|
118
|
+
screen.queryByRole('menuitem', {hidden: true}),
|
|
119
|
+
).not.toBeInTheDocument();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// =============================================================================
|
|
124
|
+
// Body / row context menu
|
|
125
|
+
// =============================================================================
|
|
126
|
+
|
|
127
|
+
describe('Table body context menu', () => {
|
|
128
|
+
it('renders row actions from a plugin that sets contextMenuActions in transformBodyCell', () => {
|
|
129
|
+
const onSelect = vi.fn();
|
|
130
|
+
const plugin: TablePlugin<Row> = {
|
|
131
|
+
transformBodyCell: (props, _column, item) => ({
|
|
132
|
+
...props,
|
|
133
|
+
contextMenuActions: [
|
|
134
|
+
{
|
|
135
|
+
id: `delete-${item.id}`,
|
|
136
|
+
label: 'Delete row',
|
|
137
|
+
onSelect: () => {
|
|
138
|
+
onSelect(item.id);
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
}),
|
|
143
|
+
};
|
|
144
|
+
render(
|
|
145
|
+
<Table data={data} columns={columns} idKey="id" plugins={{plugin}} />,
|
|
146
|
+
);
|
|
147
|
+
// Right-click the first body cell (Alice).
|
|
148
|
+
fireEvent.contextMenu(screen.getByText('Alice'));
|
|
149
|
+
const items = screen.getAllByRole('menuitem', {
|
|
150
|
+
name: 'Delete row',
|
|
151
|
+
hidden: true,
|
|
152
|
+
});
|
|
153
|
+
expect(items.length).toBeGreaterThan(0);
|
|
154
|
+
fireEvent.click(items[0]);
|
|
155
|
+
expect(onSelect).toHaveBeenCalledWith('1');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file tableContextMenu.tsx
|
|
7
|
+
* @input React, ContextMenu, Icon, types
|
|
8
|
+
* @output wrapInTableContextMenu helper
|
|
9
|
+
* @position Renders the aggregated `contextMenuActions` for a header cell / row
|
|
10
|
+
*
|
|
11
|
+
* SYNC: When modified, update these files to stay in sync:
|
|
12
|
+
* - /packages/core/src/Table/BaseTable.tsx (call sites)
|
|
13
|
+
* - /packages/core/src/Table/types.ts (TableContextAction)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {useState, type ReactNode} from 'react';
|
|
17
|
+
import {ContextMenu, type ContextMenuOption} from '../ContextMenu';
|
|
18
|
+
import {Icon} from '../Icon';
|
|
19
|
+
import type {TableContextAction, TableContextActions} from './types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a `contextMenuActions` value (array or getter) to a plain array.
|
|
23
|
+
* Use this when composing actions from a prior plugin's render props so you
|
|
24
|
+
* don't have to branch on the array-vs-getter form:
|
|
25
|
+
*
|
|
26
|
+
* ```
|
|
27
|
+
* contextMenuActions: () => [
|
|
28
|
+
* ...resolveContextActions(props.contextMenuActions),
|
|
29
|
+
* ...myActions,
|
|
30
|
+
* ]
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function resolveContextActions(
|
|
34
|
+
actions: TableContextActions | undefined,
|
|
35
|
+
): TableContextAction[] {
|
|
36
|
+
if (typeof actions === 'function') {
|
|
37
|
+
return actions();
|
|
38
|
+
}
|
|
39
|
+
return actions ?? [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Convert the flat action list into ContextMenu options, inserting a divider
|
|
44
|
+
* between groups (first-seen group order). Ungrouped actions form a trailing
|
|
45
|
+
* group. A `checked` action shows a trailing check icon.
|
|
46
|
+
*/
|
|
47
|
+
function toContextMenuOptions(
|
|
48
|
+
actions: TableContextAction[],
|
|
49
|
+
): ContextMenuOption[] {
|
|
50
|
+
const order: string[] = [];
|
|
51
|
+
const buckets = new Map<string, TableContextAction[]>();
|
|
52
|
+
for (const action of actions) {
|
|
53
|
+
const key = action.group ?? '__ungrouped__';
|
|
54
|
+
let bucket = buckets.get(key);
|
|
55
|
+
if (!bucket) {
|
|
56
|
+
bucket = [];
|
|
57
|
+
buckets.set(key, bucket);
|
|
58
|
+
order.push(key);
|
|
59
|
+
}
|
|
60
|
+
bucket.push(action);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const options: ContextMenuOption[] = [];
|
|
64
|
+
order.forEach((key, groupIndex) => {
|
|
65
|
+
if (groupIndex > 0) {
|
|
66
|
+
options.push({type: 'divider'});
|
|
67
|
+
}
|
|
68
|
+
for (const action of buckets.get(key) ?? []) {
|
|
69
|
+
options.push({
|
|
70
|
+
label: typeof action.label === 'string' ? action.label : action.id,
|
|
71
|
+
// A checked action (e.g. the active sort direction) shows a checkmark;
|
|
72
|
+
// otherwise the action's own icon. ContextMenu's data form takes a
|
|
73
|
+
// single leading icon, so checked state replaces the icon.
|
|
74
|
+
icon: action.checked ? (
|
|
75
|
+
<Icon icon="check" size="xsm" aria-hidden />
|
|
76
|
+
) : (
|
|
77
|
+
action.icon
|
|
78
|
+
),
|
|
79
|
+
isDisabled: action.disabled,
|
|
80
|
+
onClick: action.onSelect,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return options;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Wrap a table element (a header cell's content or a row) in a right-click
|
|
89
|
+
* context menu rendering the aggregated `actions`. When no plugin contributes
|
|
90
|
+
* actions the element is returned untouched so the native browser menu passes
|
|
91
|
+
* through.
|
|
92
|
+
*/
|
|
93
|
+
/**
|
|
94
|
+
* A context menu whose actions are resolved lazily — only when the user opens
|
|
95
|
+
* the menu (right-click). Deferring the work means plugins that pass a getter
|
|
96
|
+
* don't build an action array (with its closures) for every cell on every
|
|
97
|
+
* render; it's computed on demand and memoized until the menu closes.
|
|
98
|
+
*/
|
|
99
|
+
function LazyTableContextMenu({
|
|
100
|
+
element,
|
|
101
|
+
getActions,
|
|
102
|
+
}: {
|
|
103
|
+
element: ReactNode;
|
|
104
|
+
getActions: () => TableContextAction[];
|
|
105
|
+
}): ReactNode {
|
|
106
|
+
const [options, setOptions] = useState<ContextMenuOption[] | null>(null);
|
|
107
|
+
return (
|
|
108
|
+
<ContextMenu
|
|
109
|
+
items={options ?? []}
|
|
110
|
+
onOpenChange={open => {
|
|
111
|
+
// Resolve actions when opening; clear on close so state derived later
|
|
112
|
+
// (e.g. current sort direction) is always fresh next open.
|
|
113
|
+
setOptions(open ? toContextMenuOptions(getActions()) : null);
|
|
114
|
+
}}>
|
|
115
|
+
{element}
|
|
116
|
+
</ContextMenu>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Wrap a table element (a header cell's content or a body cell) in a right-click
|
|
122
|
+
* context menu rendering the aggregated `actions`. Accepts a static array or a
|
|
123
|
+
* getter (resolved lazily on open). When there are no actions the element is
|
|
124
|
+
* returned untouched so the native browser menu passes through.
|
|
125
|
+
*/
|
|
126
|
+
export function wrapInTableContextMenu(
|
|
127
|
+
element: ReactNode,
|
|
128
|
+
actions: TableContextActions | undefined,
|
|
129
|
+
): ReactNode {
|
|
130
|
+
// Getter form → resolve lazily on open.
|
|
131
|
+
if (typeof actions === 'function') {
|
|
132
|
+
return <LazyTableContextMenu element={element} getActions={actions} />;
|
|
133
|
+
}
|
|
134
|
+
if (!actions || actions.length === 0) {
|
|
135
|
+
return element;
|
|
136
|
+
}
|
|
137
|
+
// item (it looked like "ascending" was always selected). Focus moves only
|
|
138
|
+
// when the user arrow-keys into the menu.
|
|
139
|
+
return (
|
|
140
|
+
<ContextMenu items={toContextMenuOptions(actions)}>{element}</ContextMenu>
|
|
141
|
+
);
|
|
142
|
+
}
|
package/src/Table/types.ts
CHANGED
|
@@ -261,6 +261,12 @@ export interface HeaderCellRenderProps {
|
|
|
261
261
|
overlay?: ReactNode;
|
|
262
262
|
/** Content rendered below the header label row (e.g. inline filter controls). */
|
|
263
263
|
below?: ReactNode;
|
|
264
|
+
/**
|
|
265
|
+
* Right-click context-menu actions for this header cell. Plugins append
|
|
266
|
+
* their actions in `transformHeaderCell`; BaseTable concatenates the arrays
|
|
267
|
+
* across plugins (never overridden) and renders one menu per header cell.
|
|
268
|
+
*/
|
|
269
|
+
contextMenuActions?: TableContextActions;
|
|
264
270
|
/**
|
|
265
271
|
* Index of this column within the final, ordered list of rendered columns
|
|
266
272
|
* (after column injection/reordering by other plugins). Populated by
|
|
@@ -290,6 +296,13 @@ export interface BodyRowRenderProps {
|
|
|
290
296
|
export interface BodyCellRenderProps {
|
|
291
297
|
htmlProps: TdHTMLAttributes<HTMLTableCellElement>;
|
|
292
298
|
styles: StyleXStyles[];
|
|
299
|
+
/**
|
|
300
|
+
* Right-click context-menu actions for this body cell. Plugins append their
|
|
301
|
+
* actions in `transformBodyCell`; BaseTable concatenates the arrays across
|
|
302
|
+
* plugins and across the row's cells (never overridden) and renders one menu
|
|
303
|
+
* per row.
|
|
304
|
+
*/
|
|
305
|
+
contextMenuActions?: TableContextActions;
|
|
293
306
|
/**
|
|
294
307
|
* Index of this cell's column within the final ordered column list.
|
|
295
308
|
* Mirrors the `columnIndex` passed to `transformHeaderCell`. Populated by
|
|
@@ -335,6 +348,50 @@ export interface ScrollWrapperRenderProps {
|
|
|
335
348
|
afterTable?: ReactNode;
|
|
336
349
|
}
|
|
337
350
|
|
|
351
|
+
// =============================================================================
|
|
352
|
+
// Context-menu actions
|
|
353
|
+
// =============================================================================
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* A single right-click context-menu action contributed by a plugin.
|
|
357
|
+
*
|
|
358
|
+
* Plugins contribute actions via the `contextMenuActions` field on
|
|
359
|
+
* `HeaderCellRenderProps` / `BodyCellRenderProps` (set in
|
|
360
|
+
* `transformHeaderCell` / `transformBodyCell`); the table aggregates actions
|
|
361
|
+
* from every enabled plugin into a single menu per header cell / row.
|
|
362
|
+
*/
|
|
363
|
+
export interface TableContextAction {
|
|
364
|
+
/** Stable identifier, unique within a single menu. */
|
|
365
|
+
id: string;
|
|
366
|
+
/** Visible label for the menu item. */
|
|
367
|
+
label: ReactNode;
|
|
368
|
+
/** Optional leading icon. */
|
|
369
|
+
icon?: ReactNode;
|
|
370
|
+
/** Invoked when the item is selected. */
|
|
371
|
+
onSelect: () => void;
|
|
372
|
+
/** When true, the item is rendered but not selectable. */
|
|
373
|
+
disabled?: boolean;
|
|
374
|
+
/**
|
|
375
|
+
* Group key used to cluster related actions and insert a divider between
|
|
376
|
+
* groups (e.g. 'sort', 'selection'). Actions without a group form a trailing
|
|
377
|
+
* group. Group order follows first-seen order across the aggregated list.
|
|
378
|
+
*/
|
|
379
|
+
group?: string;
|
|
380
|
+
/** When true, the item renders as checked (e.g. the active sort direction). */
|
|
381
|
+
checked?: boolean;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Context-menu actions for a cell — either a static array, or a getter that
|
|
386
|
+
* returns the actions lazily. Prefer the getter for actions derived from state
|
|
387
|
+
* (e.g. the active sort direction): it's only invoked when the menu is opened,
|
|
388
|
+
* so the plugin doesn't build an action array (with closures) for every cell on
|
|
389
|
+
* every render.
|
|
390
|
+
*/
|
|
391
|
+
export type TableContextActions =
|
|
392
|
+
| TableContextAction[]
|
|
393
|
+
| (() => TableContextAction[]);
|
|
394
|
+
|
|
338
395
|
// =============================================================================
|
|
339
396
|
// Plugin Interface
|
|
340
397
|
// =============================================================================
|
|
@@ -353,6 +410,10 @@ export interface ScrollWrapperRenderProps {
|
|
|
353
410
|
* 6. `transformBodyCell` — transform each body `<td>` props
|
|
354
411
|
* 7. `transformScrollWrapper` — transform the scroll-container wrapper around the table
|
|
355
412
|
* 8. `transformTableContext` — wrap the table output in context providers
|
|
413
|
+
*
|
|
414
|
+
* Plugins may also contribute right-click menu actions by appending to
|
|
415
|
+
* `contextMenuActions` in `transformHeaderCell` / `transformBodyCell`
|
|
416
|
+
* (aggregated into one menu per header cell / row).
|
|
356
417
|
*/
|
|
357
418
|
export interface TablePlugin<
|
|
358
419
|
T extends Record<string, unknown> = Record<string, unknown>,
|
|
@@ -432,12 +493,25 @@ export interface TableRowComponentProps extends HTMLAttributes<HTMLTableRowEleme
|
|
|
432
493
|
export interface TableCellComponentProps extends TdHTMLAttributes<HTMLTableCellElement> {
|
|
433
494
|
children?: ReactNode;
|
|
434
495
|
xstyle?: StyleXStyles | StyleXStyles[];
|
|
496
|
+
/**
|
|
497
|
+
* Right-click actions to render as a context menu around the cell content.
|
|
498
|
+
* The cell owns the menu wrapper so it can control how it interacts with
|
|
499
|
+
* padding / content sizing. Empty/undefined renders no menu (native passes
|
|
500
|
+
* through).
|
|
501
|
+
*/
|
|
502
|
+
contextMenuActions?: TableContextActions;
|
|
435
503
|
}
|
|
436
504
|
|
|
437
505
|
/** Props for header cell components used in the components prop */
|
|
438
506
|
export interface TableHeaderCellComponentProps extends ThHTMLAttributes<HTMLTableCellElement> {
|
|
439
507
|
children?: ReactNode;
|
|
440
508
|
xstyle?: StyleXStyles | StyleXStyles[];
|
|
509
|
+
/**
|
|
510
|
+
* Right-click actions to render as a context menu around the header content.
|
|
511
|
+
* The cell owns the menu wrapper so it can control how it interacts with
|
|
512
|
+
* padding / content sizing. Empty/undefined renders no menu.
|
|
513
|
+
*/
|
|
514
|
+
contextMenuActions?: TableContextActions;
|
|
441
515
|
}
|
|
442
516
|
|
|
443
517
|
// =============================================================================
|
|
@@ -19,7 +19,7 @@ export const docs = {
|
|
|
19
19
|
name: 'onColumnResizeEnd',
|
|
20
20
|
type: '(updates: Record<string, number>) => void',
|
|
21
21
|
description:
|
|
22
|
-
'Called when a resize completes (pointerup / Enter). Receives a map of every column key whose width changed
|
|
22
|
+
'Called when a resize completes (pointerup / Enter). Receives a map of every column key whose width changed; merge it into your columnWidths state.',
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
name: 'minWidth',
|
|
@@ -37,7 +37,7 @@ export const docs = {
|
|
|
37
37
|
name: 'columns',
|
|
38
38
|
type: 'TableColumn<T>[]',
|
|
39
39
|
description:
|
|
40
|
-
'Column definitions
|
|
40
|
+
'Column definitions, needed to derive per-column min widths and detect proportional vs pixel columns for neighbor/last-column resize behavior.',
|
|
41
41
|
},
|
|
42
42
|
],
|
|
43
43
|
};
|
|
@@ -91,6 +91,6 @@ export const docsDense = {
|
|
|
91
91
|
minWidth: 'Global min column width (px) during resize.',
|
|
92
92
|
maxWidth: 'Global max column width (px) during resize. Default Infinity.',
|
|
93
93
|
columns:
|
|
94
|
-
'Column defs
|
|
94
|
+
'Column defs: derive per-column mins + proportional/pixel detection for neighbor/last-column behavior.',
|
|
95
95
|
},
|
|
96
96
|
};
|
|
@@ -13,13 +13,13 @@ export const docs = {
|
|
|
13
13
|
name: 'startKeys',
|
|
14
14
|
type: 'string[]',
|
|
15
15
|
description:
|
|
16
|
-
'Column keys pinned to the start (inline-start / left in LTR) edge
|
|
16
|
+
'Column keys pinned to the start (inline-start / left in LTR) edge: the contiguous run from the first column through the last listed key.',
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
name: 'endKeys',
|
|
20
20
|
type: 'string[]',
|
|
21
21
|
description:
|
|
22
|
-
'Column keys pinned to the end (inline-end / right in LTR) edge
|
|
22
|
+
'Column keys pinned to the end (inline-end / right in LTR) edge: the contiguous run from the first listed key through the last column.',
|
|
23
23
|
},
|
|
24
24
|
],
|
|
25
25
|
};
|
package/src/Text/Text.doc.mjs
CHANGED
|
@@ -124,15 +124,15 @@ export const docs = {
|
|
|
124
124
|
description:
|
|
125
125
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
126
126
|
bestPractices: [
|
|
127
|
-
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight
|
|
127
|
+
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
|
|
128
128
|
{ guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
|
|
129
|
-
{ guidance: true, description: 'Use maxLines with a number to truncate long content
|
|
129
|
+
{ guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
|
|
130
130
|
{ guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
|
|
131
|
-
{ guidance: false, description: 'Override size and weight when a semantic type already matches
|
|
132
|
-
{ guidance: false, description: 'Skip heading levels in the document outline
|
|
133
|
-
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text
|
|
134
|
-
{ guidance: false, description: 'Pass a `variant` prop
|
|
135
|
-
{ guidance: false, description: 'Use Text for headings
|
|
131
|
+
{ guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
|
|
132
|
+
{ guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
|
|
133
|
+
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
|
|
134
|
+
{ guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
|
|
135
|
+
{ guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
|
|
136
136
|
],
|
|
137
137
|
},
|
|
138
138
|
};
|
|
@@ -143,15 +143,15 @@ export const docsZh = {
|
|
|
143
143
|
description:
|
|
144
144
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
145
145
|
bestPractices: [
|
|
146
|
-
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight
|
|
146
|
+
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
|
|
147
147
|
{ guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
|
|
148
|
-
{ guidance: true, description: 'Use maxLines with a number to truncate long content
|
|
148
|
+
{ guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
|
|
149
149
|
{ guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
|
|
150
|
-
{ guidance: false, description: 'Override size and weight when a semantic type already matches
|
|
151
|
-
{ guidance: false, description: 'Skip heading levels in the document outline
|
|
152
|
-
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text
|
|
153
|
-
{ guidance: false, description: 'Pass a `variant` prop
|
|
154
|
-
{ guidance: false, description: 'Use Text for headings
|
|
150
|
+
{ guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
|
|
151
|
+
{ guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
|
|
152
|
+
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
|
|
153
|
+
{ guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
|
|
154
|
+
{ guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
|
|
155
155
|
],
|
|
156
156
|
},
|
|
157
157
|
};
|
|
@@ -165,12 +165,12 @@ export const docsDense = {
|
|
|
165
165
|
bestPractices: [
|
|
166
166
|
{ guidance: true, description: 'Semantic type (body, label, supporting, large, code) instead of manual size/weight.' },
|
|
167
167
|
{ guidance: true, description: 'accessibilityLevel on Heading when visual level differs from document outline.' },
|
|
168
|
-
{ guidance: true, description: 'maxLines for truncation
|
|
168
|
+
{ guidance: true, description: 'maxLines for truncation; tooltip shows full text on hover.' },
|
|
169
169
|
{ guidance: true, description: 'hasTabularNumbers for aligned numeric columns.' },
|
|
170
170
|
{ guidance: false, description: 'Override size/weight when a semantic type already matches.' },
|
|
171
|
-
{ guidance: false, description: 'Skip heading levels
|
|
172
|
-
{ guidance: false, description: 'Raw <p>/<h1>/<span
|
|
173
|
-
{ guidance: false, description: '`variant` prop
|
|
171
|
+
{ guidance: false, description: 'Skip heading levels; sequential h1 \u2192 h2 \u2192 h3.' },
|
|
172
|
+
{ guidance: false, description: 'Raw <p>/<h1>/<span>; use Text/Heading for theme tokens.' },
|
|
173
|
+
{ guidance: false, description: '`variant` prop, which does not exist. Use `type` for text styling or Heading for headings.' },
|
|
174
174
|
{ guidance: false, description: 'Text for headings: use Heading with level (1\u20136).' },
|
|
175
175
|
],
|
|
176
176
|
},
|
|
@@ -70,6 +70,12 @@ export const docs = {
|
|
|
70
70
|
description: 'Disables the textarea, preventing interaction.',
|
|
71
71
|
default: 'false',
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: 'disabledMessage',
|
|
75
|
+
type: 'string',
|
|
76
|
+
description:
|
|
77
|
+
'Explains why the textarea is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the textarea focusable via aria-disabled (the field becomes read-only). Use this instead of wrapping a disabled TextArea in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
|
|
78
|
+
},
|
|
73
79
|
{
|
|
74
80
|
name: 'isLoading',
|
|
75
81
|
type: 'boolean',
|
|
@@ -174,6 +180,7 @@ export const docs = {
|
|
|
174
180
|
{ guidance: false, description: 'Avoid using TextArea for short, single-line values like names or emails; use TextInput instead.' },
|
|
175
181
|
{ guidance: false, description: 'Don\'t rely solely on placeholder text to communicate the purpose of the field; placeholders disappear on focus and are not accessible labels.' },
|
|
176
182
|
{ guidance: false, description: 'Don\'t show a status message without also setting the status type; the colored border and icon are what draw the user\'s attention to the message.' },
|
|
183
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain why it\'s disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
177
184
|
],
|
|
178
185
|
},
|
|
179
186
|
};
|
|
@@ -239,6 +246,12 @@ export const docsZh = {
|
|
|
239
246
|
description: '禁用文本域,阻止交互。',
|
|
240
247
|
default: 'false',
|
|
241
248
|
},
|
|
249
|
+
{
|
|
250
|
+
name: 'disabledMessage',
|
|
251
|
+
type: 'string',
|
|
252
|
+
description:
|
|
253
|
+
'说明文本域被禁用的原因。与 isDisabled 一起使用时,在悬停/键盘聚焦时显示工具提示,并通过 aria-disabled 保持文本域可聚焦(字段变为只读)。请使用此属性,而不是用 Tooltip 包裹已禁用的 TextArea。',
|
|
254
|
+
},
|
|
242
255
|
{
|
|
243
256
|
name: 'isLoading',
|
|
244
257
|
type: 'boolean',
|
|
@@ -336,6 +349,7 @@ export const docsZh = {
|
|
|
336
349
|
{ guidance: false, description: 'Avoid using TextArea for short, single-line values like names or emails; use TextInput instead.' },
|
|
337
350
|
{ guidance: false, description: 'Don\'t rely solely on placeholder text to communicate the purpose of the field; placeholders disappear on focus and are not accessible labels.' },
|
|
338
351
|
{ guidance: false, description: 'Don\'t show a status message without also setting the status type; the colored border and icon are what draw the user\'s attention to the message.' },
|
|
352
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain why it\'s disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
339
353
|
],
|
|
340
354
|
},
|
|
341
355
|
};
|
|
@@ -354,6 +368,7 @@ export const docsDense = {
|
|
|
354
368
|
{ guidance: false, description: 'Avoid TextArea for single-line values; use TextInput.' },
|
|
355
369
|
{ guidance: false, description: 'Don\'t use placeholder as only label; disappears on focus, not accessible.' },
|
|
356
370
|
{ guidance: false, description: 'Don\'t show status message without status type; border and icon draw attention.' },
|
|
371
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain the disabled state; use the disabledMessage prop instead.' },
|
|
357
372
|
],
|
|
358
373
|
},
|
|
359
374
|
propDescriptions: {
|
|
@@ -367,6 +382,8 @@ export const docsDense = {
|
|
|
367
382
|
isOptional: 'Shows "Optional" indicator. Mutually exclusive w/ isRequired.',
|
|
368
383
|
isRequired: 'Shows "Required" indicator+sets aria-required. Mutually exclusive w/ isOptional.',
|
|
369
384
|
isDisabled: 'Disables textarea, prevents interaction.',
|
|
385
|
+
disabledMessage:
|
|
386
|
+
'Explains why textarea is disabled. With isDisabled, shows tooltip on hover/focus + keeps textarea focusable via aria-disabled (field becomes read-only). Use instead of wrapping a disabled TextArea in Tooltip.',
|
|
370
387
|
isLoading: 'Loading state w/ spinner inside input.',
|
|
371
388
|
placeholder: 'Placeholder when textarea empty.',
|
|
372
389
|
rows: 'Visible text rows.',
|