@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3
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 +161 -1
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +45 -20
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +3 -2
- package/dist/AspectRatio/AspectRatio.d.ts +24 -0
- package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
- package/dist/AspectRatio/AspectRatio.js +23 -4
- package/dist/Avatar/Avatar.d.ts +25 -1
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +58 -19
- package/dist/Avatar/index.d.ts +2 -2
- package/dist/Avatar/index.d.ts.map +1 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +8 -4
- package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
- package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
- package/dist/Banner/Banner.d.ts +49 -15
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +62 -20
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +17 -4
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -6
- package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +26 -7
- package/dist/Calendar/Calendar.d.ts +7 -3
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -23
- package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
- package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
- package/dist/Calendar/getInitialFocusDate.js +62 -0
- package/dist/Calendar/styles.d.ts +5 -14
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +15 -15
- package/dist/Card/Card.d.ts +12 -12
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +17 -9
- package/dist/Card/index.d.ts +35 -1
- package/dist/Card/index.d.ts.map +1 -1
- package/dist/Card/index.js +21 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +3 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +2 -3
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +3 -3
- package/dist/Chat/ChatMessageList.d.ts +22 -3
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +6 -3
- package/dist/Chat/ChatTokenizedText.d.ts +2 -0
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +11 -6
- package/dist/Chat/useChatComposerTokens.js +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +10 -3
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -3
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +15 -4
- package/dist/CodeBlock/highlightRanges.js +1 -1
- package/dist/CodeBlock/highlightStyles.js +13 -13
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +3 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -2
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/DateInput/DateInput.d.ts +43 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +22 -2
- package/dist/DateInput/NativeDateField.d.ts +10 -0
- package/dist/DateInput/NativeDateField.d.ts.map +1 -0
- package/dist/DateInput/NativeDateField.js +494 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +82 -23
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateInput/nativeDateSegments.d.ts +22 -0
- package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
- package/dist/DateInput/nativeDateSegments.js +111 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +406 -12
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.d.ts +21 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +110 -58
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -13
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +9 -1
- package/dist/Field/InputClearButton.d.ts +9 -3
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +14 -3
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +3 -2
- package/dist/Heading/Heading.d.ts.map +1 -1
- package/dist/Heading/Heading.js +6 -3
- package/dist/HoverCard/HoverCard.d.ts +6 -0
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +104 -3
- package/dist/HoverCard/useHoverCard.d.ts +19 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +74 -26
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +6 -2
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -2
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +2 -19
- package/dist/Layer/LayerDepthContext.d.ts +52 -0
- package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
- package/dist/Layer/LayerDepthContext.js +66 -0
- package/dist/Layer/gestureCounter.d.ts +8 -0
- package/dist/Layer/gestureCounter.d.ts.map +1 -0
- package/dist/Layer/gestureCounter.js +53 -0
- package/dist/Layer/index.d.ts +3 -0
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +4 -0
- package/dist/Layer/layerStack.d.ts +98 -0
- package/dist/Layer/layerStack.d.ts.map +1 -0
- package/dist/Layer/layerStack.js +306 -0
- package/dist/Layer/useLayer.d.ts +23 -13
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +128 -8
- package/dist/Layer/useLayerDismissal.d.ts +93 -0
- package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
- package/dist/Layer/useLayerDismissal.js +91 -0
- package/dist/Lightbox/Lightbox.d.ts +1 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +103 -81
- package/dist/List/List.d.ts +1 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +15 -4
- package/dist/Markdown/Markdown.d.ts +1 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +20 -7
- package/dist/Markdown/index.d.ts +1 -1
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/parser.d.ts +38 -1
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +182 -32
- package/dist/MetadataList/MetadataListItem.d.ts +1 -1
- package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
- package/dist/MetadataList/MetadataListItem.js +4 -1
- package/dist/MobileNav/MobileNav.d.ts +6 -1
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +61 -36
- package/dist/MultiSelector/MultiSelector.d.ts +32 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +73 -15
- package/dist/MultiSelector/hooks.d.ts +7 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -2
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.js +5 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +9 -5
- package/dist/NumberInput/NumberInput.d.ts +6 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +54 -104
- package/dist/NumberInput/numberInputCommit.d.ts +34 -0
- package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
- package/dist/NumberInput/numberInputCommit.js +71 -0
- package/dist/NumberInput/numberParser.d.ts +64 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -0
- package/dist/NumberInput/numberParser.js +350 -0
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -2
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +3 -2
- package/dist/Overlay/Overlay.d.ts.map +1 -1
- package/dist/Overlay/Overlay.js +3 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +1 -9
- package/dist/Popover/usePopover.d.ts +7 -41
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +40 -21
- package/dist/PowerSearch/PowerSearch.d.ts +8 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +19 -6
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
- package/dist/PowerSearch/types.d.ts +2 -0
- package/dist/PowerSearch/types.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.js +14 -5
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +18 -5
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +3 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +3 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +12 -3
- package/dist/Selector/Selector.d.ts +18 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +91 -18
- package/dist/Selector/hooks.d.ts +7 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +3 -2
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +4 -3
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +8 -7
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +4 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +37 -5
- package/dist/Spinner/Spinner.d.ts +3 -3
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +130 -78
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +6 -1
- package/dist/Stepper/Step.d.ts +140 -0
- package/dist/Stepper/Step.d.ts.map +1 -0
- package/dist/Stepper/Step.js +1045 -0
- package/dist/Stepper/StepStatus.d.ts +24 -0
- package/dist/Stepper/StepStatus.d.ts.map +1 -0
- package/dist/Stepper/StepStatus.js +1 -0
- package/dist/Stepper/Stepper.d.ts +93 -0
- package/dist/Stepper/Stepper.d.ts.map +1 -0
- package/dist/Stepper/Stepper.js +184 -0
- package/dist/Stepper/StepperContext.d.ts +41 -0
- package/dist/Stepper/StepperContext.d.ts.map +1 -0
- package/dist/Stepper/StepperContext.js +34 -0
- package/dist/Stepper/index.d.ts +8 -0
- package/dist/Stepper/index.d.ts.map +1 -0
- package/dist/Stepper/index.js +7 -0
- package/dist/Stepper/stepper.stylex.d.ts +15 -0
- package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
- package/dist/Stepper/stepper.stylex.js +20 -0
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +8 -3
- package/dist/TabList/Tab.d.ts +15 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +32 -7
- package/dist/TabList/TabList.d.ts +46 -7
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +353 -23
- package/dist/TabList/TabListContext.d.ts +11 -1
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +11 -2
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -2
- package/dist/TabList/index.d.ts +2 -2
- package/dist/TabList/index.d.ts.map +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +10 -2
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +3 -6
- package/dist/Table/TableRow.d.ts +16 -5
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +16 -5
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
- package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
- package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +43 -5
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
- package/dist/Table/types.d.ts +22 -4
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -0
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +6 -3
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +16 -10
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +3 -2
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +15 -21
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +22 -7
- package/dist/Toast/ToastViewport.d.ts +1 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +71 -18
- package/dist/Token/Token.d.ts +1 -1
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +20 -9
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +7 -4
- package/dist/Tokenizer/Tokenizer.d.ts +14 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +33 -21
- package/dist/Tooltip/Tooltip.d.ts +5 -0
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +5 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +39 -24
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +5 -4
- package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +31 -11
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +22 -7
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +7 -2
- package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +119 -37
- package/dist/Typeahead/Typeahead.d.ts +8 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +5 -2
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +7 -2
- package/dist/astryx.css +113 -11
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +7 -4
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +60 -95
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +3 -18
- package/dist/hooks/useMergedRefs.d.ts +18 -0
- package/dist/hooks/useMergedRefs.d.ts.map +1 -0
- package/dist/hooks/useMergedRefs.js +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +46 -10
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +24 -4
- package/dist/theme/generateThemeRules.d.ts +21 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +26 -0
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +5 -2
- package/dist/utils/groupItems.d.ts +5 -1
- package/dist/utils/groupItems.d.ts.map +1 -1
- package/dist/utils/groupItems.js +9 -9
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/isApplePlatform.d.ts +18 -0
- package/dist/utils/isApplePlatform.d.ts.map +1 -0
- package/dist/utils/isApplePlatform.js +37 -0
- package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
- package/dist/utils/sharedResizeObserver.js +10 -1
- package/dist/utils/timeParser.d.ts +1 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +26 -12
- package/locales/af-ZA.json +6 -6
- package/locales/ar-SA.json +6 -6
- package/locales/ca-ES.json +5 -5
- package/locales/cs-CZ.json +6 -6
- package/locales/da-DK.json +6 -6
- package/locales/de-DE.json +6 -6
- package/locales/el-GR.json +6 -6
- package/locales/en.json +163 -11
- package/locales/es-ES.json +5 -5
- package/locales/fi-FI.json +6 -6
- package/locales/fr-FR.json +6 -6
- package/locales/he-IL.json +6 -6
- package/locales/hu-HU.json +6 -6
- package/locales/it-IT.json +6 -6
- package/locales/ja-JP.json +6 -6
- package/locales/ko-KR.json +6 -6
- package/locales/nl-NL.json +6 -6
- package/locales/no-NO.json +6 -6
- package/locales/pl-PL.json +6 -6
- package/locales/pseudo.json +114 -0
- package/locales/pt-BR.json +6 -6
- package/locales/pt-PT.json +6 -6
- package/locales/ro-RO.json +6 -6
- package/locales/ru-RU.json +6 -6
- package/locales/sr-SP.json +6 -6
- package/locales/sv-SE.json +6 -6
- package/locales/tr-TR.json +6 -6
- package/locales/uk-UA.json +6 -6
- package/locales/vi-VN.json +6 -6
- package/locales/zh-CN.json +6 -6
- package/locales/zh-TW.json +6 -6
- package/package.json +8 -3
- package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
- package/src/AlertDialog/AlertDialog.test.tsx +211 -2
- package/src/AlertDialog/AlertDialog.tsx +62 -20
- package/src/AppShell/AppShell.tsx +3 -2
- package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
- package/src/AspectRatio/AspectRatio.test.tsx +57 -10
- package/src/AspectRatio/AspectRatio.tsx +40 -1
- package/src/Avatar/Avatar.doc.mjs +14 -3
- package/src/Avatar/Avatar.test.tsx +97 -0
- package/src/Avatar/Avatar.tsx +125 -52
- package/src/Avatar/index.ts +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
- package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
- package/src/AvatarGroup/AvatarGroup.tsx +15 -6
- package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
- package/src/Banner/Banner.doc.mjs +22 -11
- package/src/Banner/Banner.test.tsx +177 -25
- package/src/Banner/Banner.tsx +93 -27
- package/src/BottomSheet/BottomSheet.test.tsx +123 -0
- package/src/BottomSheet/BottomSheet.tsx +17 -4
- package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
- package/src/Button/Button.doc.mjs +24 -1
- package/src/Button/Button.test.tsx +32 -4
- package/src/Button/Button.tsx +12 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
- package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
- package/src/ButtonGroup/ButtonGroup.tsx +23 -5
- package/src/Calendar/Calendar.doc.mjs +7 -6
- package/src/Calendar/Calendar.test.tsx +143 -0
- package/src/Calendar/Calendar.tsx +30 -26
- package/src/Calendar/getInitialFocusDate.test.ts +94 -0
- package/src/Calendar/getInitialFocusDate.ts +93 -0
- package/src/Calendar/styles.ts +49 -31
- package/src/Card/Card.doc.mjs +10 -7
- package/src/Card/Card.test.tsx +113 -19
- package/src/Card/Card.tsx +67 -89
- package/src/Card/index.ts +36 -1
- package/src/Carousel/Carousel.tsx +3 -2
- package/src/Chat/ChatComposerInput.tsx +5 -1
- package/src/Chat/ChatLayout.tsx +3 -2
- package/src/Chat/ChatMessageList.doc.mjs +9 -1
- package/src/Chat/ChatMessageList.test.tsx +46 -0
- package/src/Chat/ChatMessageList.tsx +28 -4
- package/src/Chat/ChatTokenizedText.tsx +17 -10
- package/src/Chat/useChatComposerTokens.ts +1 -1
- package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
- package/src/CheckboxInput/CheckboxInput.tsx +8 -2
- package/src/ClickableCard/ClickableCard.tsx +3 -2
- package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
- package/src/CodeBlock/CodeBlock.test.tsx +37 -0
- package/src/CodeBlock/CodeBlock.tsx +20 -4
- package/src/CodeBlock/highlightRanges.ts +1 -1
- package/src/CodeBlock/highlightStyles.ts +13 -13
- package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
- package/src/ComplexSelector/ComplexSelector.test.tsx +32 -0
- package/src/ComplexSelector/ComplexSelector.tsx +1 -3
- package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
- package/src/ContextMenu/ContextMenu.tsx +4 -3
- package/src/DateInput/DateInput.doc.mjs +16 -0
- package/src/DateInput/DateInput.tsx +55 -2
- package/src/DateInput/DateInputTouch.test.tsx +146 -32
- package/src/DateInput/NativeDateField.test.tsx +635 -0
- package/src/DateInput/NativeDateField.tsx +641 -0
- package/src/DateInput/TouchDateField.tsx +108 -24
- package/src/DateInput/index.ts +1 -0
- package/src/DateInput/nativeDateSegments.ts +127 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
- package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
- package/src/DateRangeInput/DateRangeInput.tsx +4 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
- package/src/DateTimeInput/DateTimeInput.tsx +556 -24
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/Dialog.doc.mjs +8 -3
- package/src/Dialog/Dialog.test.tsx +429 -2
- package/src/Dialog/Dialog.tsx +133 -58
- package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
- package/src/DropdownMenu/DropdownMenu.tsx +4 -13
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
- package/src/Field/Field.doc.mjs +13 -2
- package/src/Field/FieldLabel.test.tsx +29 -0
- package/src/Field/FieldLabel.tsx +7 -0
- package/src/Field/InputClearButton.test.tsx +15 -1
- package/src/Field/InputClearButton.tsx +28 -4
- package/src/FileInput/FileInput.tsx +3 -2
- package/src/Heading/Heading.test.tsx +23 -1
- package/src/Heading/Heading.tsx +6 -3
- package/src/HoverCard/HoverCard.doc.mjs +13 -2
- package/src/HoverCard/HoverCard.test.tsx +154 -4
- package/src/HoverCard/HoverCard.tsx +143 -3
- package/src/HoverCard/useHoverCard.tsx +104 -33
- package/src/Indicator/CheckboxIndicator.tsx +14 -8
- package/src/Indicator/Indicator.doc.mjs +2 -0
- package/src/Item/Item.tsx +5 -4
- package/src/Kbd/Kbd.tsx +2 -19
- package/src/Layer/LayerDepthContext.tsx +62 -0
- package/src/Layer/gestureCounter.ts +57 -0
- package/src/Layer/index.ts +9 -0
- package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
- package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
- package/src/Layer/layerStack.ts +362 -0
- package/src/Layer/useLayer.test.tsx +324 -15
- package/src/Layer/useLayer.tsx +164 -8
- package/src/Layer/useLayerDismissal.test.tsx +469 -0
- package/src/Layer/useLayerDismissal.ts +173 -0
- package/src/Layout/Layout.doc.mjs +2 -2
- package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
- package/src/Lightbox/Lightbox.doc.mjs +12 -0
- package/src/Lightbox/Lightbox.tsx +124 -102
- package/src/Link/Link.doc.mjs +39 -0
- package/src/List/List.test.tsx +38 -0
- package/src/List/List.tsx +8 -1
- package/src/Markdown/Markdown.doc.mjs +5 -0
- package/src/Markdown/Markdown.test.tsx +37 -0
- package/src/Markdown/Markdown.tsx +16 -5
- package/src/Markdown/incremental.test.ts +16 -2
- package/src/Markdown/index.ts +1 -0
- package/src/Markdown/parser.perf.test.ts +96 -1
- package/src/Markdown/parser.test.ts +178 -2
- package/src/Markdown/parser.ts +253 -32
- package/src/MetadataList/MetadataList.test.tsx +75 -2
- package/src/MetadataList/MetadataListItem.tsx +5 -2
- package/src/MobileNav/MobileNav.tsx +62 -36
- package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
- package/src/MultiSelector/MultiSelector.test.tsx +311 -0
- package/src/MultiSelector/MultiSelector.tsx +151 -15
- package/src/MultiSelector/hooks.ts +9 -2
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavIcon/NavIcon.doc.mjs +8 -2
- package/src/NavIcon/NavIcon.test.tsx +9 -0
- package/src/NavIcon/NavIcon.tsx +5 -1
- package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
- package/src/NavMenu/NavHeadingMenu.tsx +9 -5
- package/src/NumberInput/NumberInput.doc.mjs +31 -7
- package/src/NumberInput/NumberInput.test.tsx +436 -8
- package/src/NumberInput/NumberInput.tsx +62 -114
- package/src/NumberInput/numberInputCommit.test.ts +72 -0
- package/src/NumberInput/numberInputCommit.ts +103 -0
- package/src/NumberInput/numberParser.docblock.test.ts +234 -0
- package/src/NumberInput/numberParser.test.ts +222 -0
- package/src/NumberInput/numberParser.ts +403 -0
- package/src/Outline/Outline.tsx +3 -2
- package/src/OverflowList/OverflowList.tsx +3 -2
- package/src/Overlay/Overlay.tsx +3 -2
- package/src/Pagination/Pagination.test.tsx +3 -2
- package/src/Popover/Popover.test.tsx +14 -0
- package/src/Popover/Popover.tsx +1 -9
- package/src/Popover/usePopover.tsx +57 -32
- package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
- package/src/PowerSearch/PowerSearch.test.tsx +240 -1
- package/src/PowerSearch/PowerSearch.tsx +34 -5
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
- package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
- package/src/PowerSearch/types.ts +2 -0
- package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
- package/src/PowerSearch/usePowerSearchSource.ts +13 -3
- package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
- package/src/ProgressBar/ProgressBar.test.tsx +24 -0
- package/src/ProgressBar/ProgressBar.tsx +28 -8
- package/src/Resizable/ResizeHandle.tsx +3 -2
- package/src/SegmentedControl/SegmentedControl.tsx +3 -2
- package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
- package/src/SelectableCard/SelectableCard.tsx +19 -2
- package/src/Selector/Selector.doc.mjs +26 -1
- package/src/Selector/Selector.test.tsx +346 -1
- package/src/Selector/Selector.tsx +148 -21
- package/src/Selector/hooks.ts +17 -2
- package/src/SideNav/SideNav.doc.mjs +6 -6
- package/src/SideNav/SideNav.tsx +4 -2
- package/src/SideNav/SideNavHeading.tsx +12 -12
- package/src/SideNav/SideNavItem.tsx +4 -2
- package/src/Slider/Slider.test.tsx +106 -1
- package/src/Slider/Slider.tsx +55 -3
- package/src/Spinner/Spinner.test.tsx +147 -1
- package/src/Spinner/Spinner.tsx +120 -101
- package/src/StatusDot/StatusDot.doc.mjs +8 -2
- package/src/StatusDot/StatusDot.test.tsx +9 -0
- package/src/StatusDot/StatusDot.tsx +7 -1
- package/src/Stepper/Step.doc.mjs +98 -0
- package/src/Stepper/Step.tsx +1638 -0
- package/src/Stepper/StepStatus.ts +26 -0
- package/src/Stepper/Stepper.doc.mjs +370 -0
- package/src/Stepper/Stepper.test.tsx +1024 -0
- package/src/Stepper/Stepper.tsx +258 -0
- package/src/Stepper/StepperContext.ts +71 -0
- package/src/Stepper/index.ts +18 -0
- package/src/Stepper/stepper.stylex.ts +19 -0
- package/src/Switch/Switch.doc.mjs +2 -0
- package/src/Switch/Switch.test.tsx +10 -0
- package/src/Switch/Switch.tsx +6 -2
- package/src/TabList/Tab.doc.mjs +13 -1
- package/src/TabList/Tab.tsx +67 -7
- package/src/TabList/TabList.doc.mjs +22 -6
- package/src/TabList/TabList.test.tsx +559 -0
- package/src/TabList/TabList.tsx +490 -22
- package/src/TabList/TabListContext.ts +13 -2
- package/src/TabList/TabMenu.tsx +3 -2
- package/src/TabList/index.ts +6 -2
- package/src/Table/BaseTable.tsx +12 -4
- package/src/Table/Table.doc.mjs +9 -2
- package/src/Table/Table.test.tsx +132 -14
- package/src/Table/Table.tsx +3 -8
- package/src/Table/TableBody.doc.mjs +40 -0
- package/src/Table/TableFooter.doc.mjs +40 -0
- package/src/Table/TableHeader.doc.mjs +40 -0
- package/src/Table/TableRow.tsx +16 -5
- package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
- package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
- package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +67 -12
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
- package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
- package/src/Table/plugins/selection/useTableSelection.test.tsx +138 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +63 -7
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
- package/src/Table/types.ts +22 -4
- package/src/Table/useBaseTablePlugins.ts +5 -0
- package/src/Table/useTableGroupedRows.doc.mjs +5 -4
- package/src/Table/useTablePagination.doc.mjs +7 -0
- package/src/Table/useTableRowStatus.doc.mjs +1 -1
- package/src/Table/useTableSelection.doc.mjs +31 -0
- package/src/Text/Text.test.tsx +67 -1
- package/src/Text/Text.tsx +6 -3
- package/src/TextArea/TextArea.doc.mjs +12 -2
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +37 -24
- package/src/TextInput/TextInput.doc.mjs +10 -0
- package/src/TextInput/TextInput.tsx +3 -2
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.tsx +2 -2
- package/src/Timestamp/Timestamp.test.tsx +58 -0
- package/src/Timestamp/Timestamp.tsx +12 -10
- package/src/Toast/Toast.doc.mjs +26 -12
- package/src/Toast/Toast.tsx +28 -4
- package/src/Toast/ToastViewport.test.tsx +536 -8
- package/src/Toast/ToastViewport.tsx +81 -12
- package/src/Token/Token.test.tsx +95 -0
- package/src/Token/Token.tsx +15 -10
- package/src/Token/TokenLink.tsx +14 -5
- package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
- package/src/Tokenizer/Tokenizer.test.tsx +161 -0
- package/src/Tokenizer/Tokenizer.tsx +53 -24
- package/src/Toolbar/Toolbar.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.test.tsx +32 -0
- package/src/Tooltip/Tooltip.tsx +5 -0
- package/src/Tooltip/useTooltip.tsx +47 -24
- package/src/TopNav/TopNavHeading.tsx +5 -4
- package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
- package/src/TopNav/TopNavMegaMenu.tsx +47 -5
- package/src/TopNav/TopNavMenu.test.tsx +133 -1
- package/src/TopNav/TopNavMenu.tsx +38 -7
- package/src/TreeList/TreeList.test.tsx +49 -0
- package/src/TreeList/TreeList.tsx +7 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
- package/src/Typeahead/BaseTypeahead.tsx +181 -39
- package/src/Typeahead/Typeahead.doc.mjs +11 -0
- package/src/Typeahead/Typeahead.test.tsx +203 -0
- package/src/Typeahead/Typeahead.tsx +12 -2
- package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
- package/src/Typeahead/TypeaheadItem.tsx +8 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useAnnounce.doc.mjs +96 -0
- package/src/hooks/useContainerReveal.doc.mjs +2 -2
- package/src/hooks/useDevWarning.doc.mjs +96 -0
- package/src/hooks/useFocusTrap.test.tsx +14 -0
- package/src/hooks/useFocusTrap.ts +62 -111
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
- package/src/hooks/useHotkeys.ts +3 -18
- package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
- package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
- package/src/hooks/useInteractiveRole.doc.mjs +119 -0
- package/src/hooks/useLongPress.doc.mjs +123 -0
- package/src/hooks/useMergedRefs.doc.mjs +79 -0
- package/src/hooks/useMergedRefs.test.tsx +62 -0
- package/src/hooks/useMergedRefs.ts +36 -0
- package/src/hooks/useTypeahead.doc.mjs +153 -0
- package/src/index.ts +1 -0
- package/src/raw-import.d.ts +14 -0
- package/src/theme/MediaTheme.doc.mjs +5 -5
- package/src/theme/Theme.test.tsx +104 -2
- package/src/theme/Theme.tsx +49 -14
- package/src/theme/defineTheme.test.ts +23 -0
- package/src/theme/derivedVarRegistry.test.ts +26 -3
- package/src/theme/derivedVarRegistry.ts +23 -4
- package/src/theme/generateThemeRules.test.ts +99 -1
- package/src/theme/generateThemeRules.ts +28 -0
- package/src/theme/syntax/tokens.ts +5 -2
- package/src/utils/groupItems.ts +12 -6
- package/src/utils/index.ts +1 -1
- package/src/utils/isApplePlatform.test.ts +61 -0
- package/src/utils/isApplePlatform.ts +37 -0
- package/src/utils/sharedResizeObserver.ts +10 -2
- package/src/utils/timeParser.test.ts +6 -1
- package/src/utils/timeParser.ts +35 -13
- package/src/__tests__/inputWidthContract.test.tsx +0 -69
|
@@ -20,6 +20,9 @@ import {
|
|
|
20
20
|
useMemo,
|
|
21
21
|
useState,
|
|
22
22
|
useCallback,
|
|
23
|
+
type FocusEvent,
|
|
24
|
+
type FormEvent,
|
|
25
|
+
type KeyboardEvent,
|
|
23
26
|
type ReactNode,
|
|
24
27
|
} from 'react';
|
|
25
28
|
import * as stylex from '@stylexjs/stylex';
|
|
@@ -29,6 +32,10 @@ import {Button} from '../../../Button';
|
|
|
29
32
|
import {Popover} from '../../../Popover';
|
|
30
33
|
import {TextInput} from '../../../TextInput';
|
|
31
34
|
import {NumberInput} from '../../../NumberInput';
|
|
35
|
+
import {
|
|
36
|
+
parseNumberInput,
|
|
37
|
+
resolveNumberInputCommit,
|
|
38
|
+
} from '../../../NumberInput/numberInputCommit';
|
|
32
39
|
import {DateInput} from '../../../DateInput';
|
|
33
40
|
import type {ISODateString} from '../../../utils/dateTypes';
|
|
34
41
|
import {TimeInput} from '../../../TimeInput';
|
|
@@ -42,7 +49,7 @@ import type {
|
|
|
42
49
|
HeaderCellRenderProps,
|
|
43
50
|
} from '../../types';
|
|
44
51
|
import {proportional} from '../../columnUtils';
|
|
45
|
-
import {useTranslator} from '../../../i18n';
|
|
52
|
+
import {useLocale, useTranslator} from '../../../i18n';
|
|
46
53
|
import type {
|
|
47
54
|
PowerSearchConfig,
|
|
48
55
|
PowerSearchField,
|
|
@@ -445,6 +452,80 @@ function TextFilterControl({
|
|
|
445
452
|
);
|
|
446
453
|
}
|
|
447
454
|
|
|
455
|
+
function useLiveNumberFilter({
|
|
456
|
+
value,
|
|
457
|
+
min,
|
|
458
|
+
max,
|
|
459
|
+
hasClear,
|
|
460
|
+
onChange,
|
|
461
|
+
}: {
|
|
462
|
+
value: number | null;
|
|
463
|
+
min?: number | null;
|
|
464
|
+
max?: number | null;
|
|
465
|
+
hasClear: boolean;
|
|
466
|
+
onChange: (value: number | null) => void;
|
|
467
|
+
}) {
|
|
468
|
+
const locale = useLocale();
|
|
469
|
+
const editStartValueRef = useRef(value);
|
|
470
|
+
|
|
471
|
+
const handleChange = useCallback(
|
|
472
|
+
(nextValue: number | null) => {
|
|
473
|
+
editStartValueRef.current = nextValue;
|
|
474
|
+
onChange(nextValue);
|
|
475
|
+
},
|
|
476
|
+
[onChange],
|
|
477
|
+
);
|
|
478
|
+
const handleFocus = useCallback(() => {
|
|
479
|
+
editStartValueRef.current = value;
|
|
480
|
+
}, [value]);
|
|
481
|
+
const handleInput = useCallback(
|
|
482
|
+
(event: FormEvent<HTMLElement>) => {
|
|
483
|
+
const nextValue = parseNumberInput(
|
|
484
|
+
(event.currentTarget as HTMLInputElement).value,
|
|
485
|
+
{
|
|
486
|
+
min,
|
|
487
|
+
max,
|
|
488
|
+
locale,
|
|
489
|
+
},
|
|
490
|
+
);
|
|
491
|
+
if (nextValue !== null && nextValue !== value) {
|
|
492
|
+
onChange(nextValue);
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
[locale, max, min, onChange, value],
|
|
496
|
+
);
|
|
497
|
+
const restoreRejectedDraft = useCallback(
|
|
498
|
+
(input: HTMLInputElement) => {
|
|
499
|
+
const decision = resolveNumberInputCommit(input.value, {
|
|
500
|
+
min,
|
|
501
|
+
max,
|
|
502
|
+
locale,
|
|
503
|
+
hasClear,
|
|
504
|
+
});
|
|
505
|
+
if (decision.type === 'revert' && value !== editStartValueRef.current) {
|
|
506
|
+
onChange(editStartValueRef.current);
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
[hasClear, locale, max, min, onChange, value],
|
|
510
|
+
);
|
|
511
|
+
const handleBlur = useCallback(
|
|
512
|
+
(event: FocusEvent<HTMLInputElement>) => {
|
|
513
|
+
restoreRejectedDraft(event.currentTarget);
|
|
514
|
+
},
|
|
515
|
+
[restoreRejectedDraft],
|
|
516
|
+
);
|
|
517
|
+
const handleKeyDown = useCallback(
|
|
518
|
+
(event: KeyboardEvent<HTMLInputElement>) => {
|
|
519
|
+
if (event.key === 'Enter') {
|
|
520
|
+
restoreRejectedDraft(event.currentTarget);
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
[restoreRejectedDraft],
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
return {handleBlur, handleChange, handleFocus, handleInput, handleKeyDown};
|
|
527
|
+
}
|
|
528
|
+
|
|
448
529
|
function NumberFilterControl({
|
|
449
530
|
columnKey,
|
|
450
531
|
header,
|
|
@@ -466,12 +547,19 @@ function NumberFilterControl({
|
|
|
466
547
|
|
|
467
548
|
const step = operatorValue.type === 'integer' ? 1 : null;
|
|
468
549
|
|
|
469
|
-
const
|
|
550
|
+
const updateFilter = useCallback(
|
|
470
551
|
(newValue: number | null) => {
|
|
471
552
|
store.getConfig().onFilterChange(columnKey, newValue);
|
|
472
553
|
},
|
|
473
554
|
[store, columnKey],
|
|
474
555
|
);
|
|
556
|
+
const liveFilter = useLiveNumberFilter({
|
|
557
|
+
value: numValue,
|
|
558
|
+
min: operatorValue.minValue,
|
|
559
|
+
max: operatorValue.maxValue,
|
|
560
|
+
hasClear: !!hasClear,
|
|
561
|
+
onChange: updateFilter,
|
|
562
|
+
});
|
|
475
563
|
|
|
476
564
|
if (hasClear) {
|
|
477
565
|
return (
|
|
@@ -479,7 +567,11 @@ function NumberFilterControl({
|
|
|
479
567
|
label={t('@astryx.tableFiltering.filterByColumn', {header})}
|
|
480
568
|
isLabelHidden
|
|
481
569
|
value={numValue}
|
|
482
|
-
onChange={handleChange}
|
|
570
|
+
onChange={liveFilter.handleChange}
|
|
571
|
+
onFocus={liveFilter.handleFocus}
|
|
572
|
+
onInput={liveFilter.handleInput}
|
|
573
|
+
onBlur={liveFilter.handleBlur}
|
|
574
|
+
onKeyDown={liveFilter.handleKeyDown}
|
|
483
575
|
placeholder={t('@astryx.tableFiltering.filterByColumn', {header})}
|
|
484
576
|
min={operatorValue.minValue ?? null}
|
|
485
577
|
max={operatorValue.maxValue ?? null}
|
|
@@ -495,7 +587,11 @@ function NumberFilterControl({
|
|
|
495
587
|
label={t('@astryx.tableFiltering.filterByColumn', {header})}
|
|
496
588
|
isLabelHidden
|
|
497
589
|
value={numValue}
|
|
498
|
-
onChange={handleChange}
|
|
590
|
+
onChange={liveFilter.handleChange}
|
|
591
|
+
onFocus={liveFilter.handleFocus}
|
|
592
|
+
onInput={liveFilter.handleInput}
|
|
593
|
+
onBlur={liveFilter.handleBlur}
|
|
594
|
+
onKeyDown={liveFilter.handleKeyDown}
|
|
499
595
|
placeholder={t('@astryx.tableFiltering.filterByColumn', {header})}
|
|
500
596
|
min={operatorValue.minValue ?? null}
|
|
501
597
|
max={operatorValue.maxValue ?? null}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file useTableGroupedRows-perf.test.tsx
|
|
5
|
+
* @input Table, useTableGroupedRows, React testing utilities
|
|
6
|
+
* @output Performance tests for grouped-rows render behavior
|
|
7
|
+
* @position Test file; validates that grouping costs no extra row renders
|
|
8
|
+
*
|
|
9
|
+
* The plugin keeps group headers out of cell renderers per cell, at render
|
|
10
|
+
* time. Doing it by rewriting the columns instead would hand BaseTable a new
|
|
11
|
+
* column object on every render, and its element-by-element check on the
|
|
12
|
+
* resolved column array is what stops every row re-rendering.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {describe, it, expect} from 'vitest';
|
|
16
|
+
import {render, screen, act} from '@testing-library/react';
|
|
17
|
+
import {useCallback, useMemo, useState} from 'react';
|
|
18
|
+
import userEvent from '@testing-library/user-event';
|
|
19
|
+
import {Table} from '../../Table';
|
|
20
|
+
import type {TableColumn} from '../../types';
|
|
21
|
+
import {useTableGroupedRows} from './useTableGroupedRows';
|
|
22
|
+
|
|
23
|
+
interface Person extends Record<string, unknown> {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
team: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const people: Person[] = [
|
|
30
|
+
{id: 'a', name: 'Alice', team: 'Core'},
|
|
31
|
+
{id: 'b', name: 'Bob', team: 'Core'},
|
|
32
|
+
{id: 'c', name: 'Carol', team: 'Infra'},
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const EMPTY = new Set<string>();
|
|
36
|
+
|
|
37
|
+
function GroupedRenderCountTable({
|
|
38
|
+
renderCounts,
|
|
39
|
+
}: {
|
|
40
|
+
renderCounts: Record<string, number>;
|
|
41
|
+
}) {
|
|
42
|
+
const [tick, setTick] = useState(0);
|
|
43
|
+
const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(EMPTY);
|
|
44
|
+
|
|
45
|
+
const columns = useMemo<TableColumn<Person>[]>(
|
|
46
|
+
() => [
|
|
47
|
+
{
|
|
48
|
+
key: 'name',
|
|
49
|
+
header: 'Name',
|
|
50
|
+
renderCell: (item: Person) => {
|
|
51
|
+
renderCounts[item.id] = (renderCounts[item.id] ?? 0) + 1;
|
|
52
|
+
return item.name;
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
[renderCounts],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const grouped = useTableGroupedRows<Person>({
|
|
60
|
+
data: people,
|
|
61
|
+
groupBy: useCallback((p: Person) => p.team, []),
|
|
62
|
+
collapsedGroups,
|
|
63
|
+
onToggleGroup: useCallback(
|
|
64
|
+
(key: string) =>
|
|
65
|
+
setCollapsedGroups(prev => {
|
|
66
|
+
const next = new Set(prev);
|
|
67
|
+
if (!next.delete(key)) {
|
|
68
|
+
next.add(key);
|
|
69
|
+
}
|
|
70
|
+
return next;
|
|
71
|
+
}),
|
|
72
|
+
[],
|
|
73
|
+
),
|
|
74
|
+
getRowKey: useCallback((p: Person) => p.id, []),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<>
|
|
79
|
+
<button type="button" onClick={() => setTick(t => t + 1)}>
|
|
80
|
+
bump {tick}
|
|
81
|
+
</button>
|
|
82
|
+
<Table
|
|
83
|
+
data={grouped.data}
|
|
84
|
+
columns={columns}
|
|
85
|
+
idKey={grouped.idKey}
|
|
86
|
+
plugins={{grouped: grouped.plugin}}
|
|
87
|
+
/>
|
|
88
|
+
</>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
describe('Grouped rows render performance', () => {
|
|
93
|
+
it('renders each real row once and no group header at all', () => {
|
|
94
|
+
const renderCounts: Record<string, number> = {};
|
|
95
|
+
render(<GroupedRenderCountTable renderCounts={renderCounts} />);
|
|
96
|
+
expect(renderCounts).toEqual({a: 1, b: 1, c: 1});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('a re-render of the surrounding component re-renders no rows', async () => {
|
|
100
|
+
const user = userEvent.setup();
|
|
101
|
+
const renderCounts: Record<string, number> = {};
|
|
102
|
+
render(<GroupedRenderCountTable renderCounts={renderCounts} />);
|
|
103
|
+
const before = {...renderCounts};
|
|
104
|
+
|
|
105
|
+
await act(async () => {
|
|
106
|
+
await user.click(screen.getByRole('button', {name: /bump/}));
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(screen.getByRole('button', {name: 'bump 1'})).toBeInTheDocument();
|
|
110
|
+
expect(renderCounts).toEqual(before);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -5,6 +5,7 @@ import {render, screen, fireEvent, within} from '@testing-library/react';
|
|
|
5
5
|
import {useState, useCallback} from 'react';
|
|
6
6
|
import {Table} from '../../Table';
|
|
7
7
|
import type {TableColumn} from '../../types';
|
|
8
|
+
import {useTableRowStatus, type TableRowStatus} from '../rowStatus';
|
|
8
9
|
import {useTableGroupedRows} from './useTableGroupedRows';
|
|
9
10
|
|
|
10
11
|
interface Person extends Record<string, unknown> {
|
|
@@ -175,6 +176,105 @@ describe('useTableGroupedRows', () => {
|
|
|
175
176
|
).not.toBeInTheDocument();
|
|
176
177
|
});
|
|
177
178
|
|
|
179
|
+
it('never runs a column renderCell against a group header row', () => {
|
|
180
|
+
// The renderer that breaks: it keys a lookup off a field rather than
|
|
181
|
+
// printing it, so the header Proxy answering `''` is no better than
|
|
182
|
+
// `undefined`.
|
|
183
|
+
const TEAM_META: Record<string, {dot: string}> = {
|
|
184
|
+
Core: {dot: 'green'},
|
|
185
|
+
Infra: {dot: 'blue'},
|
|
186
|
+
};
|
|
187
|
+
const seen: Person[] = [];
|
|
188
|
+
const lookupColumns: TableColumn<Person>[] = [
|
|
189
|
+
{
|
|
190
|
+
key: 'team',
|
|
191
|
+
header: 'Team',
|
|
192
|
+
renderCell: item => {
|
|
193
|
+
seen.push(item);
|
|
194
|
+
return <span>{TEAM_META[item.team].dot}</span>;
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
function LookupHarness() {
|
|
200
|
+
const [collapsed, setCollapsed] = useState<Set<string>>(EMPTY);
|
|
201
|
+
const grouped = useTableGroupedRows<Person>({
|
|
202
|
+
data: people,
|
|
203
|
+
groupBy: p => p.team,
|
|
204
|
+
collapsedGroups: collapsed,
|
|
205
|
+
onToggleGroup: k => setCollapsed(new Set([k])),
|
|
206
|
+
getRowKey: p => p.id,
|
|
207
|
+
});
|
|
208
|
+
return (
|
|
209
|
+
<Table
|
|
210
|
+
data={grouped.data}
|
|
211
|
+
columns={lookupColumns}
|
|
212
|
+
idKey={grouped.idKey}
|
|
213
|
+
plugins={{grouped: grouped.plugin}}
|
|
214
|
+
/>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
expect(() => render(<LookupHarness />)).not.toThrow();
|
|
219
|
+
expect(seen.map(p => p.name)).toEqual(['Alice', 'Bob', 'Carol']);
|
|
220
|
+
expect(screen.getByText('Core')).toBeInTheDocument();
|
|
221
|
+
expect(screen.getByText('Infra')).toBeInTheDocument();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe.each([
|
|
225
|
+
['grouped first', true],
|
|
226
|
+
['rowStatus first', false],
|
|
227
|
+
])(
|
|
228
|
+
'with a column contributed by another plugin (%s)',
|
|
229
|
+
(_label, groupedFirst) => {
|
|
230
|
+
// `grouped` and `rowStatus` are both absent from PLUGIN_ORDER, so the
|
|
231
|
+
// record's insertion order is the pipeline order. Whichever way round
|
|
232
|
+
// the consumer types it, the status column's renderCell must not see a
|
|
233
|
+
// header row.
|
|
234
|
+
const STATUS_BY_TEAM: Record<string, TableRowStatus> = {
|
|
235
|
+
Core: {color: 'success', label: 'Healthy'},
|
|
236
|
+
Infra: {color: 'error', label: 'Paging'},
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
function StatusHarness() {
|
|
240
|
+
const [collapsed, setCollapsed] = useState<Set<string>>(EMPTY);
|
|
241
|
+
const grouped = useTableGroupedRows<Person>({
|
|
242
|
+
data: people,
|
|
243
|
+
groupBy: p => p.team,
|
|
244
|
+
collapsedGroups: collapsed,
|
|
245
|
+
onToggleGroup: k => setCollapsed(new Set([k])),
|
|
246
|
+
getRowKey: p => p.id,
|
|
247
|
+
});
|
|
248
|
+
const rowStatus = useTableRowStatus<Person>({
|
|
249
|
+
getStatus: useCallback((item: Person) => {
|
|
250
|
+
const {color, label} = STATUS_BY_TEAM[item.team];
|
|
251
|
+
return {color, label};
|
|
252
|
+
}, []),
|
|
253
|
+
});
|
|
254
|
+
return (
|
|
255
|
+
<Table
|
|
256
|
+
data={grouped.data}
|
|
257
|
+
columns={columns}
|
|
258
|
+
idKey={grouped.idKey}
|
|
259
|
+
plugins={
|
|
260
|
+
groupedFirst
|
|
261
|
+
? {grouped: grouped.plugin, rowStatus}
|
|
262
|
+
: {rowStatus, grouped: grouped.plugin}
|
|
263
|
+
}
|
|
264
|
+
/>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
it('renders the group headers without throwing', () => {
|
|
269
|
+
expect(() => render(<StatusHarness />)).not.toThrow();
|
|
270
|
+
expect(screen.getByText('Core')).toBeInTheDocument();
|
|
271
|
+
expect(screen.getByText('Infra')).toBeInTheDocument();
|
|
272
|
+
// One indicator per real row, none on the two headers.
|
|
273
|
+
expect(screen.getAllByRole('img')).toHaveLength(3);
|
|
274
|
+
});
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
|
|
178
278
|
it('keeps a group collapsed across a data change (state keyed by group)', () => {
|
|
179
279
|
function ChangingHarness() {
|
|
180
280
|
const [collapsed, setCollapsed] = useState<Set<string>>(
|
|
@@ -41,8 +41,11 @@ function isGroupHeader(item: unknown): item is GroupHeader {
|
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
// Proxy handler: any field access beyond the marker fields resolves to `''
|
|
45
|
-
//
|
|
44
|
+
// Proxy handler: any field access beyond the marker fields resolves to `''`,
|
|
45
|
+
// which keeps anything that reads a header's data — the sortable and filtering
|
|
46
|
+
// plugins, a consumer's own row handler — off `undefined`. Cell renderers are
|
|
47
|
+
// handled at render time instead (see `transformBodyCell` below); the Proxy
|
|
48
|
+
// never protected them, because `''` fails a lookup exactly as `undefined` does.
|
|
46
49
|
const HEADER_PROXY_HANDLER: ProxyHandler<Record<string | symbol, unknown>> = {
|
|
47
50
|
// eslint-disable-next-line @typescript-eslint/promise-function-async -- Proxy get trap, not a promise-returning fn
|
|
48
51
|
get(t: Record<string | symbol, unknown>, prop: string | symbol): unknown {
|
|
@@ -54,12 +57,9 @@ const HEADER_PROXY_HANDLER: ProxyHandler<Record<string | symbol, unknown>> = {
|
|
|
54
57
|
};
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
|
-
* Build a synthetic header row wrapped in a Proxy so
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* row (including synthetic headers) before `transformBodyRow` can replace the
|
|
61
|
-
* row's cells. `transformBodyRow` then discards those cells and renders a
|
|
62
|
-
* single full-width header cell.
|
|
60
|
+
* Build a synthetic header row wrapped in a Proxy so field access resolves to
|
|
61
|
+
* `''` instead of `undefined`. `transformBodyRow` then discards the row's
|
|
62
|
+
* cells and renders a single full-width header cell.
|
|
63
63
|
*/
|
|
64
64
|
function makeHeader<T extends Record<string, unknown>>(
|
|
65
65
|
groupKey: string,
|
|
@@ -126,15 +126,31 @@ const styles = stylex.create({
|
|
|
126
126
|
},
|
|
127
127
|
headerCell: {
|
|
128
128
|
paddingBlock: spacingVars['--spacing-2'],
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
|
|
129
|
+
// The start gutter lives on headerInner instead, so that it travels with
|
|
130
|
+
// the heading when the heading pins. Left here, the heading would sit one
|
|
131
|
+
// gutter in at rest and jump flush the moment it stuck.
|
|
132
|
+
paddingInlineStart: 0,
|
|
132
133
|
paddingInlineEnd: spacingVars['--spacing-3'],
|
|
133
134
|
},
|
|
135
|
+
// The cell spans every column, so on a table scrolled sideways the heading
|
|
136
|
+
// would slide out of view while the columns it names stay pinned. Sticking
|
|
137
|
+
// the inner span to the start edge keeps the chevron and the label together
|
|
138
|
+
// and on screen.
|
|
134
139
|
headerInner: {
|
|
135
140
|
display: 'flex',
|
|
136
141
|
alignItems: 'center',
|
|
137
142
|
gap: spacingVars['--spacing-1'],
|
|
143
|
+
insetInlineStart: 0,
|
|
144
|
+
position: 'sticky',
|
|
145
|
+
// No inline start padding on the cell, so the chevron aligns with the
|
|
146
|
+
// table's leading edge (Ernest review #1).
|
|
147
|
+
paddingInlineStart: spacingVars['--spacing-1'],
|
|
148
|
+
},
|
|
149
|
+
// Applied alongside headerInner when using the built-in default heading.
|
|
150
|
+
// A custom `renderGroupHeader` may need the full column width, so the
|
|
151
|
+
// shrink-wrap is opt-in rather than unconditional.
|
|
152
|
+
headerInnerFitContent: {
|
|
153
|
+
width: 'fit-content',
|
|
138
154
|
},
|
|
139
155
|
// Standalone chevron button with no heavy chrome (transparent, borderless,
|
|
140
156
|
// zero padding) so the icon sits flush with the start of the table
|
|
@@ -222,6 +238,32 @@ const styles = stylex.create({
|
|
|
222
238
|
* plugins={{grouped: grouped.plugin}}
|
|
223
239
|
* />;
|
|
224
240
|
* ```
|
|
241
|
+
*
|
|
242
|
+
* ## Pairing with pagination
|
|
243
|
+
*
|
|
244
|
+
* Grouping runs on the rows it is handed, so the order is filter, sort, slice,
|
|
245
|
+
* then group. Sort by the group key first and the reader's own keys second —
|
|
246
|
+
* the same `ORDER BY group, sort` a backend would run. That keeps a section's
|
|
247
|
+
* rows contiguous in the result set, so pages fill sections in order and new
|
|
248
|
+
* rows always land at the bottom of the table. Slice a differently-ordered
|
|
249
|
+
* list and every page holds a scatter of sections instead, so loading more
|
|
250
|
+
* splices rows into the middle and new headings appear above the fold.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```
|
|
254
|
+
* const ordered = useMemo(
|
|
255
|
+
* () => [...filtered].sort((a, b) => byTeam(a, b) || bySortKeys(a, b)),
|
|
256
|
+
* [filtered, sortKeys],
|
|
257
|
+
* );
|
|
258
|
+
* const page = ordered.slice(0, loadedCount);
|
|
259
|
+
*
|
|
260
|
+
* const grouped = useTableGroupedRows({
|
|
261
|
+
* data: page,
|
|
262
|
+
* groupBy: r => r.team,
|
|
263
|
+
* collapsedGroups,
|
|
264
|
+
* onToggleGroup,
|
|
265
|
+
* });
|
|
266
|
+
* ```
|
|
225
267
|
*/
|
|
226
268
|
export function useTableGroupedRows<T extends Record<string, unknown>>(
|
|
227
269
|
config: UseTableGroupedRowsConfig<T>,
|
|
@@ -301,6 +343,15 @@ export function useTableGroupedRows<T extends Record<string, unknown>>(
|
|
|
301
343
|
|
|
302
344
|
const plugin = useMemo(
|
|
303
345
|
(): TablePlugin<T> => ({
|
|
346
|
+
// A header row is not one of the caller's rows, so running a cell
|
|
347
|
+
// renderer against it can only misread it or throw — and the cells are
|
|
348
|
+
// discarded by `transformBodyRow` below regardless.
|
|
349
|
+
transformBodyCell(props, _column, item) {
|
|
350
|
+
if (!isGroupHeader(item)) {
|
|
351
|
+
return props;
|
|
352
|
+
}
|
|
353
|
+
return {...props, isContentSuppressed: true};
|
|
354
|
+
},
|
|
304
355
|
// Replace a header row's pre-rendered cells with one full-width cell.
|
|
305
356
|
transformBodyRow(props, item) {
|
|
306
357
|
if (!isGroupHeader(item)) {
|
|
@@ -333,7 +384,11 @@ export function useTableGroupedRows<T extends Record<string, unknown>>(
|
|
|
333
384
|
// to the actual number of columns, so the header always spans the
|
|
334
385
|
// full width without the plugin knowing the column count.
|
|
335
386
|
<td colSpan={999} {...stylex.props(styles.headerCell)}>
|
|
336
|
-
<span
|
|
387
|
+
<span
|
|
388
|
+
{...stylex.props(
|
|
389
|
+
styles.headerInner,
|
|
390
|
+
!renderGroupHeader && styles.headerInnerFitContent,
|
|
391
|
+
)}>
|
|
337
392
|
{/* Standalone chevron button, flush with the table's start
|
|
338
393
|
edge (no heavy button chrome) — the keyboard control. */}
|
|
339
394
|
<button
|
|
@@ -229,7 +229,7 @@ describe('useTablePagination', () => {
|
|
|
229
229
|
).toBeTruthy();
|
|
230
230
|
});
|
|
231
231
|
|
|
232
|
-
it('transformTableContext renders Pagination above and below', () => {
|
|
232
|
+
it('transformTableContext renders distinctly named Pagination above and below', () => {
|
|
233
233
|
render(
|
|
234
234
|
<PaginatedTable
|
|
235
235
|
data={generateItems(30)}
|
|
@@ -237,10 +237,40 @@ describe('useTablePagination', () => {
|
|
|
237
237
|
position="both"
|
|
238
238
|
/>,
|
|
239
239
|
);
|
|
240
|
-
const
|
|
241
|
-
|
|
240
|
+
const table = screen.getByRole('table');
|
|
241
|
+
// Each nav landmark gets a unique accessible name (axe landmark-unique)
|
|
242
|
+
const topNav = screen.getByRole('navigation', {
|
|
243
|
+
name: 'Table pagination (top)',
|
|
244
|
+
});
|
|
245
|
+
const bottomNav = screen.getByRole('navigation', {
|
|
246
|
+
name: 'Table pagination (bottom)',
|
|
242
247
|
});
|
|
243
|
-
|
|
248
|
+
// Top nav comes before the table, bottom nav after it in DOM order
|
|
249
|
+
expect(
|
|
250
|
+
table.compareDocumentPosition(topNav) &
|
|
251
|
+
Node.DOCUMENT_POSITION_PRECEDING,
|
|
252
|
+
).toBeTruthy();
|
|
253
|
+
expect(
|
|
254
|
+
table.compareDocumentPosition(bottomNav) &
|
|
255
|
+
Node.DOCUMENT_POSITION_FOLLOWING,
|
|
256
|
+
).toBeTruthy();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('position="both" interpolates a consumer label into distinct nav names', () => {
|
|
260
|
+
render(
|
|
261
|
+
<PaginatedTable
|
|
262
|
+
data={generateItems(30)}
|
|
263
|
+
pageSize={10}
|
|
264
|
+
position="both"
|
|
265
|
+
label="Users table"
|
|
266
|
+
/>,
|
|
267
|
+
);
|
|
268
|
+
expect(
|
|
269
|
+
screen.getByRole('navigation', {name: 'Users table (top)'}),
|
|
270
|
+
).toBeInTheDocument();
|
|
271
|
+
expect(
|
|
272
|
+
screen.getByRole('navigation', {name: 'Users table (bottom)'}),
|
|
273
|
+
).toBeInTheDocument();
|
|
244
274
|
});
|
|
245
275
|
|
|
246
276
|
it('transformTableContext does not render Pagination when position is none', () => {
|
|
@@ -164,6 +164,9 @@ export interface UseTablePaginationConfig {
|
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* Accessible label for the pagination nav landmark.
|
|
167
|
+
* When `position` is 'both', the two navs get distinct names by suffixing
|
|
168
|
+
* this label — "{label} (top)" above and "{label} (bottom)" below — so
|
|
169
|
+
* same-type landmarks stay distinguishable to assistive technology.
|
|
167
170
|
* @default 'Table pagination'
|
|
168
171
|
*/
|
|
169
172
|
label?: string;
|
|
@@ -211,6 +214,10 @@ export function useTablePagination<T extends Record<string, unknown>>(
|
|
|
211
214
|
label: labelFromProps,
|
|
212
215
|
} = config;
|
|
213
216
|
const label = labelFromProps ?? t('@astryx.table.pagination.label');
|
|
217
|
+
// position='both' renders two nav landmarks; suffix the base label so each
|
|
218
|
+
// gets a unique accessible name (axe landmark-unique).
|
|
219
|
+
const labelAbove = t('@astryx.table.pagination.labelAbove', {label});
|
|
220
|
+
const labelBelow = t('@astryx.table.pagination.labelBelow', {label});
|
|
214
221
|
|
|
215
222
|
// Same guard as Pagination itself: 0/NaN/negative pageSize would produce an
|
|
216
223
|
// Infinity/NaN totalPages here, which bypasses Pagination's own coercion
|
|
@@ -240,8 +247,20 @@ export function useTablePagination<T extends Record<string, unknown>>(
|
|
|
240
247
|
|
|
241
248
|
// Keep current config in a ref so the plugin can read the latest values
|
|
242
249
|
// without needing to recreate the plugin object on every change.
|
|
243
|
-
const configRef = useRef({
|
|
244
|
-
|
|
250
|
+
const configRef = useRef({
|
|
251
|
+
paginationProps,
|
|
252
|
+
position,
|
|
253
|
+
align,
|
|
254
|
+
labelAbove,
|
|
255
|
+
labelBelow,
|
|
256
|
+
});
|
|
257
|
+
configRef.current = {
|
|
258
|
+
paginationProps,
|
|
259
|
+
position,
|
|
260
|
+
align,
|
|
261
|
+
labelAbove,
|
|
262
|
+
labelBelow,
|
|
263
|
+
};
|
|
245
264
|
|
|
246
265
|
// Stable plugin object \u2014 created once, reads config via ref.
|
|
247
266
|
return useMemo(
|
|
@@ -251,6 +270,8 @@ export function useTablePagination<T extends Record<string, unknown>>(
|
|
|
251
270
|
position: pos,
|
|
252
271
|
paginationProps: props,
|
|
253
272
|
align: a,
|
|
273
|
+
labelAbove: above,
|
|
274
|
+
labelBelow: below,
|
|
254
275
|
} = configRef.current;
|
|
255
276
|
if (pos === 'none') {
|
|
256
277
|
return children;
|
|
@@ -277,7 +298,18 @@ export function useTablePagination<T extends Record<string, unknown>>(
|
|
|
277
298
|
a === 'end' && styles.alignEnd,
|
|
278
299
|
a === 'start' && styles.alignStart,
|
|
279
300
|
)}>
|
|
280
|
-
<Pagination
|
|
301
|
+
<Pagination
|
|
302
|
+
{...props}
|
|
303
|
+
// Two navs with the same name are indistinguishable landmarks;
|
|
304
|
+
// give each side a unique name when both render.
|
|
305
|
+
label={
|
|
306
|
+
pos === 'both'
|
|
307
|
+
? side === 'above'
|
|
308
|
+
? above
|
|
309
|
+
: below
|
|
310
|
+
: props.label
|
|
311
|
+
}
|
|
312
|
+
/>
|
|
281
313
|
</div>
|
|
282
314
|
);
|
|
283
315
|
|
|
@@ -21,6 +21,7 @@ import {useMemo, useRef, type ReactNode} from 'react';
|
|
|
21
21
|
import * as stylex from '@stylexjs/stylex';
|
|
22
22
|
import {spacingVars, colorVars, radiusVars} from '../../../theme/tokens.stylex';
|
|
23
23
|
import {Icon} from '../../../Icon';
|
|
24
|
+
import {VisuallyHidden} from '../../../VisuallyHidden';
|
|
24
25
|
import {resolveContextActions} from '../../tableContextMenu';
|
|
25
26
|
import {useTranslator} from '../../../i18n';
|
|
26
27
|
import {rtlStyles} from '../../../utils';
|
|
@@ -207,7 +208,13 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
|
|
|
207
208
|
const expansionColumn = useMemo(
|
|
208
209
|
(): TableColumn<T> => ({
|
|
209
210
|
key: '__expansion',
|
|
210
|
-
|
|
211
|
+
// A `<th>` with no discernible text is announced as an unlabelled
|
|
212
|
+
// column; the label is hidden because the column shows only chevrons.
|
|
213
|
+
header: (
|
|
214
|
+
<VisuallyHidden>
|
|
215
|
+
{t('@astryx.tableRowExpansion.columnHeader')}
|
|
216
|
+
</VisuallyHidden>
|
|
217
|
+
),
|
|
211
218
|
width: EXPANSION_COLUMN_WIDTH,
|
|
212
219
|
resizable: false,
|
|
213
220
|
renderCell: (item: T) => {
|
|
@@ -226,7 +233,7 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
|
|
|
226
233
|
);
|
|
227
234
|
},
|
|
228
235
|
}),
|
|
229
|
-
[expandedKeys, onToggle, getRowKey, getIsItemExpandable],
|
|
236
|
+
[expandedKeys, onToggle, getRowKey, getIsItemExpandable, t],
|
|
230
237
|
);
|
|
231
238
|
|
|
232
239
|
return useMemo(
|