@astryxdesign/core 0.1.8 → 0.1.9-canary.02ef052
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 +100 -0
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +6 -2
- package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
- package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
- package/dist/Avatar/Avatar.d.ts +58 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +240 -53
- package/dist/Avatar/AvatarStatusDot.d.ts +35 -5
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +144 -19
- package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +58 -6
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
- package/dist/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +33 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +215 -6
- package/dist/Breadcrumbs/index.d.ts +6 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +10 -1
- package/dist/Button/Button.d.ts +8 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +33 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +30 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +80 -11
- package/dist/Calendar/dayCellUtils.d.ts +4 -4
- package/dist/Calendar/dayCellUtils.js +3 -3
- package/dist/Calendar/styles.d.ts +30 -31
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +30 -31
- package/dist/Card/Card.d.ts +8 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +28 -2
- package/dist/Carousel/Carousel.d.ts +4 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +46 -16
- package/dist/Chat/ChatComposer.d.ts +8 -0
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +46 -7
- package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +11 -1
- package/dist/Chat/ChatComposerInput.d.ts +20 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +36 -4
- package/dist/Chat/ChatContext.d.ts +33 -0
- package/dist/Chat/ChatContext.d.ts.map +1 -1
- package/dist/Chat/ChatContext.js +16 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +4 -2
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +4 -4
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +4 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +7 -1
- package/dist/Chat/ChatToolCalls.d.ts +5 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +27 -11
- package/dist/Chat/index.d.ts +2 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/index.js +1 -1
- package/dist/Chat/useChatStreamScroll.d.ts +2 -1
- package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
- package/dist/Chat/useChatStreamScroll.js +22 -8
- package/dist/Chat/useSpeechRecognition.d.ts +0 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +1 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.js +5 -5
- package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +11 -1
- package/dist/Citation/Citation.d.ts +22 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +20 -6
- package/dist/ClickableCard/ClickableCard.d.ts +9 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +5 -2
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +22 -9
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +3 -1
- package/dist/CommandPalette/CommandPalette.d.ts +2 -2
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +45 -4
- package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
- package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +6 -1
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +14 -5
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +3 -1
- package/dist/DateInput/DateInput.d.ts +56 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +59 -21
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +23 -20
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +33 -19
- package/dist/Dialog/Dialog.d.ts +3 -0
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +57 -6
- package/dist/Dialog/DialogContext.d.ts +7 -0
- package/dist/Dialog/DialogContext.d.ts.map +1 -1
- package/dist/Dialog/DialogContext.js +2 -2
- package/dist/Dialog/DialogHeader.d.ts +5 -2
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +6 -1
- package/dist/Divider/Divider.js +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +22 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +5 -3
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
- package/dist/DropdownMenu/index.d.ts +10 -0
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +13 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemHover.js +33 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemRoles.js +10 -1
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -6
- package/dist/Field/Field.d.ts +3 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +6 -4
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +43 -16
- package/dist/Field/inputStyles.stylex.d.ts +1 -0
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +1 -0
- package/dist/FieldStatus/FieldStatus.d.ts +18 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +60 -6
- package/dist/FileInput/FileInput.d.ts +10 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +54 -35
- package/dist/HoverCard/HoverCard.d.ts +9 -1
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/useHoverCard.d.ts +8 -0
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +17 -6
- package/dist/Icon/Icon.d.ts +22 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +19 -3
- package/dist/Item/Item.d.ts +6 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +22 -1
- package/dist/Layer/useLayer.d.ts +6 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +2 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +19 -13
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +6 -1
- package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
- package/dist/MobileNav/MobileNavToggle.js +4 -0
- package/dist/MultiSelector/MultiSelector.d.ts +9 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +104 -50
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts +10 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +22 -17
- package/dist/Outline/Outline.d.ts +0 -1
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +0 -1
- package/dist/OverflowList/OverflowList.d.ts +20 -3
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +29 -4
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +11 -3
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +3 -9
- package/dist/PowerSearch/PowerSearch.d.ts +9 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +2 -0
- package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/RadioList/RadioList.d.ts +2 -2
- package/dist/RadioList/RadioListItem.js +4 -4
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
- package/dist/SelectableCard/SelectableCard.d.ts +9 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +16 -13
- package/dist/Selector/Selector.d.ts +8 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +65 -19
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +5 -5
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +13 -10
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts +1 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +12 -10
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +106 -36
- package/dist/Stack/stack.stylex.d.ts +9 -9
- package/dist/Switch/Switch.d.ts +8 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +160 -91
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +33 -6
- package/dist/Table/TableCell.js +3 -3
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
- package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/index.js +3 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +7 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +105 -12
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
- package/dist/Table/types.d.ts +32 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- package/dist/TextArea/TextArea.d.ts +10 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +18 -19
- package/dist/TextInput/TextInput.d.ts +10 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +20 -17
- package/dist/Thumbnail/Thumbnail.d.ts +26 -5
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +97 -54
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
- package/dist/TimeInput/TimeInput.d.ts +10 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +32 -21
- package/dist/Timestamp/Timestamp.d.ts +3 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +8 -6
- package/dist/Toast/useToast.d.ts.map +1 -1
- package/dist/Toast/useToast.js +2 -5
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
- package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
- package/dist/Token/Token.d.ts +30 -3
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +17 -2
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts +10 -3
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +20 -6
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +18 -8
- package/dist/TopNav/TopNavMegaMenu.js +10 -4
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
- package/dist/TopNav/TopNavMenu.d.ts +2 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +68 -6
- package/dist/TreeList/TreeList.d.ts +12 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +18 -10
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +59 -21
- package/dist/TreeList/TreeListTypes.d.ts +25 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/TreeList/index.d.ts +2 -2
- package/dist/TreeList/index.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +20 -11
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +3 -1
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +20 -10
- package/dist/astryx.css +61 -39
- package/dist/astryx.umd.js +53 -53
- package/dist/astryx.umd.js.map +4 -4
- package/dist/authoring/doc.d.ts.map +1 -1
- package/dist/docs-types.d.ts +8 -0
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/computeOverflow.d.ts +47 -0
- package/dist/hooks/computeOverflow.d.ts.map +1 -0
- package/dist/hooks/computeOverflow.js +213 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/isRtlElement.d.ts +18 -0
- package/dist/hooks/isRtlElement.d.ts.map +1 -0
- package/dist/hooks/isRtlElement.js +27 -0
- package/dist/hooks/useDevWarning.d.ts +18 -0
- package/dist/hooks/useDevWarning.d.ts.map +1 -0
- package/dist/hooks/useDevWarning.js +49 -0
- package/dist/hooks/useGridFocus.d.ts +6 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +12 -9
- package/dist/hooks/useInputStatusIcon.d.ts +38 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
- package/dist/hooks/useInputStatusIcon.js +158 -0
- package/dist/hooks/useListFocus.d.ts +39 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +54 -9
- package/dist/hooks/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +36 -25
- package/dist/i18n/InternationalizationContext.d.ts +1 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -0
- package/dist/i18n/InternationalizationProvider.d.ts +8 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +5 -1
- package/dist/i18n/getLocaleDirection.d.ts +18 -0
- package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
- package/dist/i18n/getLocaleDirection.js +29 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +7 -1
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- package/dist/i18n/useDirection.d.ts +2 -0
- package/dist/i18n/useDirection.d.ts.map +1 -0
- package/dist/i18n/useDirection.js +27 -0
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +51 -0
- package/dist/theme/hct.d.ts +0 -1
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
- package/dist/utils/devWarning.d.ts +42 -0
- package/dist/utils/devWarning.d.ts.map +1 -0
- package/dist/utils/devWarning.js +88 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +65 -3
- package/dist/utils/rtlStyles.d.ts +24 -0
- package/dist/utils/rtlStyles.d.ts.map +1 -0
- package/dist/utils/rtlStyles.js +27 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +104 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +78 -0
- package/package.json +6 -1
- package/src/AppShell/AppShell.tsx +6 -0
- package/src/AppShell/AppShellMobileContext.tsx +8 -0
- package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
- package/src/Avatar/Avatar.doc.mjs +64 -5
- package/src/Avatar/Avatar.test.tsx +374 -1
- package/src/Avatar/Avatar.tsx +367 -69
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +180 -21
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +141 -1
- package/src/AvatarGroup/AvatarGroup.tsx +58 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +53 -9
- package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +335 -2
- package/src/Breadcrumbs/index.ts +31 -0
- package/src/Button/Button.doc.mjs +9 -4
- package/src/Button/Button.test.tsx +49 -0
- package/src/Button/Button.tsx +27 -3
- package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
- package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
- package/src/ButtonGroup/ButtonGroup.tsx +32 -0
- package/src/Calendar/Calendar.doc.mjs +12 -1
- package/src/Calendar/Calendar.test.tsx +362 -19
- package/src/Calendar/Calendar.tsx +111 -32
- package/src/Calendar/dayCellUtils.test.ts +23 -18
- package/src/Calendar/dayCellUtils.ts +3 -3
- package/src/Calendar/styles.ts +33 -39
- package/src/Card/Card.doc.mjs +9 -0
- package/src/Card/Card.test.tsx +21 -3
- package/src/Card/Card.tsx +35 -2
- package/src/Carousel/Carousel.doc.mjs +1 -0
- package/src/Carousel/Carousel.test.tsx +53 -0
- package/src/Carousel/Carousel.tsx +59 -10
- package/src/Chat/ChatComposer.doc.mjs +12 -3
- package/src/Chat/ChatComposer.test.tsx +115 -0
- package/src/Chat/ChatComposer.tsx +73 -9
- package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
- package/src/Chat/ChatComposerDrawer.tsx +11 -1
- package/src/Chat/ChatComposerInput.doc.mjs +7 -0
- package/src/Chat/ChatComposerInput.test.tsx +103 -0
- package/src/Chat/ChatComposerInput.tsx +51 -5
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +11 -2
- package/src/Chat/ChatLayout.tsx +7 -5
- package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
- package/src/Chat/ChatMessageMetadata.tsx +1 -2
- package/src/Chat/ChatSendButton.tsx +11 -1
- package/src/Chat/ChatToolCalls.test.tsx +64 -0
- package/src/Chat/ChatToolCalls.tsx +33 -5
- package/src/Chat/index.ts +5 -1
- package/src/Chat/useChatStreamScroll.test.tsx +49 -0
- package/src/Chat/useChatStreamScroll.ts +27 -10
- package/src/Chat/useSpeechRecognition.ts +1 -1
- package/src/Chat/useTriggerMenu.tsx +4 -2
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -5
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/CheckboxList/CheckboxList.test.tsx +81 -3
- package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
- package/src/CheckboxList/CheckboxListItem.tsx +41 -5
- package/src/Citation/Citation.doc.mjs +4 -3
- package/src/Citation/Citation.test.tsx +97 -0
- package/src/Citation/Citation.tsx +43 -11
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
- package/src/ClickableCard/ClickableCard.test.tsx +34 -0
- package/src/ClickableCard/ClickableCard.tsx +13 -3
- package/src/CodeBlock/CodeBlock.test.tsx +56 -0
- package/src/CodeBlock/CodeBlock.tsx +45 -10
- package/src/Collapsible/Collapsible.doc.mjs +1 -0
- package/src/Collapsible/Collapsible.test.tsx +7 -0
- package/src/Collapsible/Collapsible.tsx +16 -6
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.test.tsx +95 -1
- package/src/CommandPalette/CommandPalette.tsx +44 -3
- package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
- package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
- package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ContextMenu/ContextMenu.test.tsx +235 -0
- package/src/ContextMenu/ContextMenu.tsx +13 -11
- package/src/ContextMenu/index.ts +5 -0
- package/src/DateInput/DateInput.doc.mjs +41 -0
- package/src/DateInput/DateInput.test.tsx +338 -0
- package/src/DateInput/DateInput.tsx +119 -32
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
- package/src/DateRangeInput/DateRangeInput.tsx +42 -30
- package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
- package/src/DateTimeInput/DateTimeInput.tsx +58 -41
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.test.tsx +77 -4
- package/src/Dialog/Dialog.tsx +89 -5
- package/src/Dialog/DialogContext.ts +9 -2
- package/src/Dialog/DialogHeader.doc.mjs +2 -2
- package/src/Dialog/DialogHeader.tsx +9 -2
- package/src/Divider/Divider.tsx +2 -2
- package/src/DropdownMenu/DropdownMenu.test.tsx +229 -0
- package/src/DropdownMenu/DropdownMenu.tsx +31 -12
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +9 -4
- package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
- package/src/DropdownMenu/index.ts +16 -0
- package/src/DropdownMenu/menuItemHover.ts +39 -0
- package/src/DropdownMenu/menuItemRoles.ts +9 -0
- package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +20 -14
- package/src/Field/FieldLabel.tsx +9 -1
- package/src/Field/inputStyles.stylex.ts +2 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +150 -40
- package/src/FieldStatus/FieldStatus.tsx +69 -5
- package/src/FileInput/FileInput.doc.mjs +23 -2
- package/src/FileInput/FileInput.test.tsx +135 -12
- package/src/FileInput/FileInput.tsx +65 -51
- package/src/HoverCard/HoverCard.doc.mjs +13 -0
- package/src/HoverCard/HoverCard.test.tsx +21 -2
- package/src/HoverCard/HoverCard.tsx +11 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +39 -5
- package/src/Icon/Icon.doc.mjs +16 -2
- package/src/Icon/Icon.test.tsx +89 -0
- package/src/Icon/Icon.tsx +58 -5
- package/src/IconButton/IconButton.doc.mjs +8 -0
- package/src/IconButton/IconButton.test.tsx +15 -18
- package/src/Item/Item.test.tsx +40 -18
- package/src/Item/Item.tsx +38 -2
- package/src/Layer/useLayer.tsx +8 -0
- package/src/Lightbox/Lightbox.tsx +15 -7
- package/src/List/List.test.tsx +9 -8
- package/src/Markdown/Markdown.test.tsx +21 -0
- package/src/Markdown/Markdown.tsx +4 -0
- package/src/MobileNav/MobileNav.tsx +12 -1
- package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
- package/src/MobileNav/MobileNavToggle.tsx +9 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +24 -2
- package/src/MultiSelector/MultiSelector.test.tsx +498 -3
- package/src/MultiSelector/MultiSelector.tsx +149 -65
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +21 -0
- package/src/NumberInput/NumberInput.test.tsx +82 -7
- package/src/NumberInput/NumberInput.tsx +36 -28
- package/src/Outline/Outline.tsx +0 -1
- package/src/OverflowList/OverflowList.doc.mjs +39 -6
- package/src/OverflowList/OverflowList.test.tsx +111 -0
- package/src/OverflowList/OverflowList.tsx +48 -8
- package/src/Pagination/Pagination.tsx +11 -3
- package/src/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
- package/src/PowerSearch/PowerSearch.test.tsx +43 -0
- package/src/PowerSearch/PowerSearch.tsx +10 -1
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
- package/src/PowerSearch/usePowerSearchSource.ts +1 -2
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/RadioList/RadioList.tsx +2 -2
- package/src/RadioList/RadioListItem.tsx +4 -4
- package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
- package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
- package/src/SelectableCard/SelectableCard.test.tsx +46 -4
- package/src/SelectableCard/SelectableCard.tsx +29 -16
- package/src/Selector/Selector.doc.mjs +15 -0
- package/src/Selector/Selector.test.tsx +417 -0
- package/src/Selector/Selector.tsx +86 -21
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNav.tsx +1 -8
- package/src/SideNav/SideNavCollapseButton.tsx +15 -8
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +10 -4
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +314 -13
- package/src/Slider/Slider.tsx +117 -28
- package/src/Switch/Switch.doc.mjs +142 -42
- package/src/Switch/Switch.test.tsx +54 -1
- package/src/Switch/Switch.tsx +90 -33
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +37 -7
- package/src/Table/Table.doc.mjs +11 -0
- package/src/Table/Table.test.tsx +85 -0
- package/src/Table/TableCell.tsx +3 -3
- package/src/Table/TableHeaderCell.tsx +3 -3
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +15 -8
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
- package/src/Table/plugins/rowStatus/index.ts +7 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
- package/src/Table/plugins/selection/useTableSelection.test.tsx +77 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +22 -1
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
- package/src/Table/plugins/tree/useTableTreeData.tsx +139 -8
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- package/src/Table/types.ts +33 -0
- package/src/Table/useBaseTablePlugins.ts +10 -6
- package/src/Table/useTableRowStatus.doc.mjs +30 -0
- package/src/Table/useTableSelection.doc.mjs +65 -14
- package/src/Table/useTableTreeData.doc.mjs +29 -0
- package/src/Table/useTableTreeState.doc.mjs +2 -2
- package/src/TextArea/TextArea.doc.mjs +21 -0
- package/src/TextArea/TextArea.test.tsx +32 -1
- package/src/TextArea/TextArea.tsx +27 -26
- package/src/TextInput/TextInput.doc.mjs +21 -0
- package/src/TextInput/TextInput.test.tsx +150 -0
- package/src/TextInput/TextInput.tsx +28 -25
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +142 -42
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.doc.mjs +21 -0
- package/src/TimeInput/TimeInput.test.tsx +99 -1
- package/src/TimeInput/TimeInput.tsx +43 -31
- package/src/Timestamp/Timestamp.doc.mjs +4 -4
- package/src/Timestamp/Timestamp.test.tsx +32 -0
- package/src/Timestamp/Timestamp.tsx +28 -8
- package/src/Toast/useToast.tsx +7 -8
- package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
- package/src/Token/Token.test.tsx +21 -15
- package/src/Token/Token.tsx +31 -14
- package/src/Token/index.ts +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +38 -2
- package/src/Tokenizer/Tokenizer.test.tsx +206 -2
- package/src/Tokenizer/Tokenizer.tsx +30 -6
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +125 -1
- package/src/TopNav/TopNavHeading.tsx +24 -8
- package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
- package/src/TopNav/TopNavMegaMenu.tsx +10 -4
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
- package/src/TopNav/TopNavMenu.test.tsx +118 -4
- package/src/TopNav/TopNavMenu.tsx +83 -5
- package/src/TreeList/TreeList.doc.mjs +28 -0
- package/src/TreeList/TreeList.test.tsx +272 -0
- package/src/TreeList/TreeList.tsx +23 -2
- package/src/TreeList/TreeListBranches.tsx +24 -8
- package/src/TreeList/TreeListItem.tsx +84 -22
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/Typeahead/BaseTypeahead.tsx +30 -15
- package/src/Typeahead/Typeahead.doc.mjs +13 -0
- package/src/Typeahead/Typeahead.test.tsx +50 -0
- package/src/Typeahead/Typeahead.tsx +11 -1
- package/src/Typeahead/TypeaheadItem.tsx +2 -1
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/authoring/doc.ts +1 -3
- package/src/doc-mjs.d.ts +19 -0
- package/src/docs-types.ts +5 -0
- package/src/hooks/computeOverflow.test.ts +422 -0
- package/src/hooks/computeOverflow.ts +290 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- package/src/hooks/useGridFocus.doc.mjs +3 -3
- package/src/hooks/useGridFocus.test.tsx +41 -0
- package/src/hooks/useGridFocus.ts +21 -10
- package/src/hooks/useInputStatusIcon.test.tsx +162 -0
- package/src/hooks/useInputStatusIcon.tsx +224 -0
- package/src/hooks/useListFocus.doc.mjs +25 -3
- package/src/hooks/useListFocus.test.tsx +153 -1
- package/src/hooks/useListFocus.ts +102 -9
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationContext.ts +4 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- package/src/i18n/InternationalizationProvider.tsx +12 -2
- package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
- package/src/i18n/__tests__/useDirection.test.tsx +66 -0
- package/src/i18n/getLocaleDirection.ts +29 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/resolve.ts +9 -21
- package/src/i18n/useDirection.ts +29 -0
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +107 -0
- package/src/theme/generateThemeRules.ts +56 -0
- package/src/theme/hct.ts +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
- package/src/utils/devWarning.test.ts +56 -0
- package/src/utils/devWarning.ts +102 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/plainDate.test.ts +46 -6
- package/src/utils/plainDate.ts +69 -3
- package/src/utils/rtlStyles.ts +27 -0
- package/src/utils/types.ts +14 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
'use client';
|
|
4
4
|
/**
|
|
5
5
|
* @file CommandPalette.tsx
|
|
6
|
-
* @input Uses React, Dialog, Layout, CommandPaletteContext, SearchSource, useCombobox
|
|
6
|
+
* @input Uses React, Dialog, Layout, CommandPaletteContext, SearchSource, useCombobox, useAnnounce
|
|
7
7
|
* @output Exports CommandPalette root component and props
|
|
8
8
|
* @position Core root component; dialog shell with searchSource-driven items
|
|
9
9
|
*
|
|
@@ -36,6 +36,7 @@ import {CommandPaletteInput} from './CommandPaletteInput';
|
|
|
36
36
|
import {CommandPaletteFooter} from './CommandPaletteFooter';
|
|
37
37
|
import {CommandPaletteEmpty} from './CommandPaletteEmpty';
|
|
38
38
|
import type {BaseProps} from '../BaseProps';
|
|
39
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
39
40
|
import {useTranslator} from '../i18n';
|
|
40
41
|
|
|
41
42
|
export interface CommandPaletteProps<
|
|
@@ -268,6 +269,7 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
268
269
|
label: labelFromProps,
|
|
269
270
|
width = 640,
|
|
270
271
|
maxHeight = 480,
|
|
272
|
+
...rest
|
|
271
273
|
}: CommandPaletteProps<T>) {
|
|
272
274
|
const t = useTranslator();
|
|
273
275
|
const label = labelFromProps ?? t('@astryx.commandPalette.label');
|
|
@@ -290,6 +292,13 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
290
292
|
const isBusy = isPending;
|
|
291
293
|
const searchVersionRef = useRef(0);
|
|
292
294
|
|
|
295
|
+
// Announce search status to screen readers through the shared polite live
|
|
296
|
+
// region (comboboxes-7 announce path, mirroring Selector / BaseTypeahead).
|
|
297
|
+
// The busy spinner and the empty states are otherwise purely visual, so a
|
|
298
|
+
// screen-reader user typing a query would hear nothing when loading starts
|
|
299
|
+
// or results disappear.
|
|
300
|
+
const announce = useAnnounce();
|
|
301
|
+
|
|
293
302
|
const value = controlledValue ?? internalValue;
|
|
294
303
|
|
|
295
304
|
const setValue = useCallback(
|
|
@@ -317,8 +326,12 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
317
326
|
setInternalValue('');
|
|
318
327
|
}
|
|
319
328
|
searchSource.cancel?.();
|
|
329
|
+
// Clear any lingering result / loading announcement when the palette
|
|
330
|
+
// closes so stale status text does not linger in the a11y tree
|
|
331
|
+
// (matching Selector's onHide).
|
|
332
|
+
announce('');
|
|
320
333
|
onOpenChange(false);
|
|
321
|
-
}, [onOpenChange, searchSource, controlledValue]);
|
|
334
|
+
}, [onOpenChange, searchSource, controlledValue, announce]);
|
|
322
335
|
|
|
323
336
|
const selectItem = useCallback(
|
|
324
337
|
(itemValue: string) => {
|
|
@@ -354,6 +367,14 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
354
367
|
startTransition(async () => {
|
|
355
368
|
const isBootstrap = query === '';
|
|
356
369
|
|
|
370
|
+
// Loading started for a user query: tell screen-reader users the
|
|
371
|
+
// spinner appeared. The polite region coalesces rapid updates, so for
|
|
372
|
+
// fast sources the result-count announcement below simply replaces
|
|
373
|
+
// this instead of stacking one "Loading" per keystroke.
|
|
374
|
+
if (!isBootstrap) {
|
|
375
|
+
announce(t('@astryx.commandPalette.loading'));
|
|
376
|
+
}
|
|
377
|
+
|
|
357
378
|
// Client-filter previous results for instant narrowing while fetch is in flight
|
|
358
379
|
if (!isBootstrap && searchResults.length > 0) {
|
|
359
380
|
const lower = query.toLowerCase().trim();
|
|
@@ -376,6 +397,23 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
376
397
|
setOptimisticResults(items);
|
|
377
398
|
setSearchResults(items);
|
|
378
399
|
|
|
400
|
+
// Announce the outcome from the search commit (not a reactive
|
|
401
|
+
// effect), matching Selector / BaseTypeahead: exactly one
|
|
402
|
+
// announcement per committed query, and the version check above
|
|
403
|
+
// already discards stale keystrokes. Bootstrap stays silent — the
|
|
404
|
+
// same role PowerSearch's mount guard plays — so opening the
|
|
405
|
+
// palette announces nothing; clearing the query only clears any
|
|
406
|
+
// lingering status text.
|
|
407
|
+
if (isBootstrap) {
|
|
408
|
+
announce('');
|
|
409
|
+
} else if (items.length === 0) {
|
|
410
|
+
announce(t('@astryx.commandPalette.noResultsFor', {query}));
|
|
411
|
+
} else {
|
|
412
|
+
announce(
|
|
413
|
+
t('@astryx.commandPalette.resultCount', {count: items.length}),
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
379
417
|
// When opening with a preselected value, highlight it once
|
|
380
418
|
// bootstrap results arrive. No value → highlight stays at -1
|
|
381
419
|
// and ArrowDown naturally moves to the first item.
|
|
@@ -395,6 +433,8 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
395
433
|
value,
|
|
396
434
|
combobox,
|
|
397
435
|
setOptimisticResults,
|
|
436
|
+
announce,
|
|
437
|
+
t,
|
|
398
438
|
],
|
|
399
439
|
);
|
|
400
440
|
|
|
@@ -527,7 +567,8 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
527
567
|
width={width}
|
|
528
568
|
maxHeight={maxHeight}
|
|
529
569
|
purpose="info"
|
|
530
|
-
aria-label={label}
|
|
570
|
+
aria-label={label}
|
|
571
|
+
{...rest}>
|
|
531
572
|
<CommandPaletteContext value={contextValue}>
|
|
532
573
|
<Layout
|
|
533
574
|
defaultHasDividers
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import {describe, it, expect} from 'vitest';
|
|
10
10
|
import {render, screen} from '@testing-library/react';
|
|
11
11
|
import {CommandPaletteGroup} from './CommandPaletteGroup';
|
|
12
|
+
import {defineTheme} from '../theme/defineTheme';
|
|
13
|
+
import {generateThemeCSSFlat} from '../theme/generateThemeRules';
|
|
12
14
|
|
|
13
15
|
describe('CommandPaletteGroup', () => {
|
|
14
16
|
it('renders heading', () => {
|
|
@@ -51,4 +53,73 @@ describe('CommandPaletteGroup', () => {
|
|
|
51
53
|
'true',
|
|
52
54
|
);
|
|
53
55
|
});
|
|
56
|
+
|
|
57
|
+
// ===========================================================================
|
|
58
|
+
// Heading theme target
|
|
59
|
+
// ===========================================================================
|
|
60
|
+
|
|
61
|
+
describe('heading theme target', () => {
|
|
62
|
+
it('renders the astryx-command-palette-group-heading target on the heading', () => {
|
|
63
|
+
render(
|
|
64
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
65
|
+
<div>Item</div>
|
|
66
|
+
</CommandPaletteGroup>,
|
|
67
|
+
);
|
|
68
|
+
const heading = screen.getByText('Suggestions');
|
|
69
|
+
|
|
70
|
+
// The root carries `astryx-command-palette-group`; this is the stable
|
|
71
|
+
// handle on the heading itself, so a theme can style just the heading
|
|
72
|
+
// without a fragile structural selector.
|
|
73
|
+
expect(heading).toHaveClass('astryx-command-palette-group-heading');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('keeps the heading target distinct from the group root target', () => {
|
|
77
|
+
render(
|
|
78
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
79
|
+
<div>Item</div>
|
|
80
|
+
</CommandPaletteGroup>,
|
|
81
|
+
);
|
|
82
|
+
const root = screen.getByRole('group');
|
|
83
|
+
const heading = screen.getByText('Suggestions');
|
|
84
|
+
|
|
85
|
+
expect(root).toHaveClass('astryx-command-palette-group');
|
|
86
|
+
expect(root).not.toHaveClass('astryx-command-palette-group-heading');
|
|
87
|
+
expect(heading).not.toHaveClass('astryx-command-palette-group');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('leaves the heading decorative (additive target only)', () => {
|
|
91
|
+
// The target adds a class and nothing else — the heading stays
|
|
92
|
+
// aria-hidden so grouping remains announced via the root's aria-label.
|
|
93
|
+
render(
|
|
94
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
95
|
+
<div>Item</div>
|
|
96
|
+
</CommandPaletteGroup>,
|
|
97
|
+
);
|
|
98
|
+
expect(screen.getByText('Suggestions')).toHaveAttribute(
|
|
99
|
+
'aria-hidden',
|
|
100
|
+
'true',
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('exposes command-palette-group-heading as a themeable defineTheme target', () => {
|
|
105
|
+
// The generated CSS proves the target is reachable by a theme: jsdom
|
|
106
|
+
// cannot resolve the @layer cascade, so the DOM-class assertions above
|
|
107
|
+
// and this generation assertion together cover the seam.
|
|
108
|
+
const theme = defineTheme({
|
|
109
|
+
name: 'command-palette-group-heading-test',
|
|
110
|
+
components: {
|
|
111
|
+
'command-palette-group-heading': {
|
|
112
|
+
base: {
|
|
113
|
+
paddingBlock: 'var(--spacing-2)',
|
|
114
|
+
fontWeight: 'var(--font-weight-bold)',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const css = generateThemeCSSFlat(theme);
|
|
120
|
+
expect(css).toContain('.astryx-command-palette-group-heading {');
|
|
121
|
+
expect(css).toContain('padding-block: var(--spacing-2)');
|
|
122
|
+
expect(css).toContain('font-weight: var(--font-weight-bold)');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
54
125
|
});
|
|
@@ -90,7 +90,18 @@ export function CommandPaletteGroup({
|
|
|
90
90
|
style,
|
|
91
91
|
)}
|
|
92
92
|
{...props}>
|
|
93
|
-
<div
|
|
93
|
+
<div
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
{...mergeProps(
|
|
96
|
+
// Stable theme target for the group heading text. The root carries
|
|
97
|
+
// `astryx-command-palette-group`, but the heading itself had no
|
|
98
|
+
// handle, so a theme could only reach it through a fragile structural
|
|
99
|
+
// selector. This adds an `astryx-command-palette-group-heading` class
|
|
100
|
+
// so `defineTheme` can scope overrides (e.g. heading typography) to
|
|
101
|
+
// the heading alone.
|
|
102
|
+
themeProps('command-palette-group-heading'),
|
|
103
|
+
stylex.props(styles.heading),
|
|
104
|
+
)}>
|
|
94
105
|
{heading}
|
|
95
106
|
</div>
|
|
96
107
|
{children}
|
|
@@ -7,7 +7,8 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'CommandPalette',
|
|
8
8
|
displayName: 'Command Palette Input',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Search input slot. Auto-focuses on mount. Wires to command palette context when used inside CommandPalette.',
|
|
11
12
|
props: [
|
|
12
13
|
{
|
|
13
14
|
name: 'placeholder',
|
|
@@ -15,16 +16,24 @@ export const docs = {
|
|
|
15
16
|
description: 'Placeholder text for the input.',
|
|
16
17
|
default: "'Search...'",
|
|
17
18
|
},
|
|
19
|
+
{
|
|
20
|
+
name: 'label',
|
|
21
|
+
type: 'string',
|
|
22
|
+
description:
|
|
23
|
+
'Accessible label for the combobox input, announced by screen readers. Falls back to the placeholder text when omitted.',
|
|
24
|
+
},
|
|
18
25
|
{
|
|
19
26
|
name: 'hasAutoFocus',
|
|
20
27
|
type: 'boolean',
|
|
21
|
-
description:
|
|
28
|
+
description:
|
|
29
|
+
'Auto-focus the input when mounted. Automatically disabled when inside an inline command palette.',
|
|
22
30
|
default: 'true',
|
|
23
31
|
},
|
|
24
32
|
{
|
|
25
33
|
name: 'endContent',
|
|
26
34
|
type: 'ReactNode',
|
|
27
|
-
description:
|
|
35
|
+
description:
|
|
36
|
+
'Content rendered at the trailing end of the input, after the spinner. Use for clear buttons or keyboard shortcut hints.',
|
|
28
37
|
slotElements: [
|
|
29
38
|
{
|
|
30
39
|
__element: 'Icon',
|
|
@@ -44,17 +53,20 @@ export const docs = {
|
|
|
44
53
|
{
|
|
45
54
|
name: 'value',
|
|
46
55
|
type: 'string',
|
|
47
|
-
description:
|
|
56
|
+
description:
|
|
57
|
+
'Search value. When omitted inside CommandPalette, reads from context.',
|
|
48
58
|
},
|
|
49
59
|
{
|
|
50
60
|
name: 'onValueChange',
|
|
51
61
|
type: '(value: string) => void',
|
|
52
|
-
description:
|
|
62
|
+
description:
|
|
63
|
+
'Called when search value changes. When omitted inside CommandPalette, writes to context.',
|
|
53
64
|
},
|
|
54
65
|
{
|
|
55
66
|
name: 'xstyle',
|
|
56
67
|
type: 'StyleXStyles',
|
|
57
|
-
description:
|
|
68
|
+
description:
|
|
69
|
+
'StyleX styles for layout customization. Must be a stylex.create() value.',
|
|
58
70
|
},
|
|
59
71
|
],
|
|
60
72
|
playground: {
|
|
@@ -69,9 +81,11 @@ export const docsZh = {
|
|
|
69
81
|
name: 'CommandPaletteInput',
|
|
70
82
|
isHiddenFromOverview: true,
|
|
71
83
|
displayName: 'Command Palette Input',
|
|
72
|
-
description:
|
|
84
|
+
description:
|
|
85
|
+
'搜索输入插槽。挂载时自动聚焦。在 CommandPalette 内使用时连接到上下文。',
|
|
73
86
|
propDescriptions: {
|
|
74
87
|
placeholder: '输入框的占位文本。',
|
|
88
|
+
label: '组合框输入的无障碍标签,供屏幕阅读器朗读。省略时回退到占位文本。',
|
|
75
89
|
hasAutoFocus: '挂载时自动聚焦输入框。内联命令面板中自动禁用。',
|
|
76
90
|
endContent: '渲染在输入框末尾的内容,位于加载指示器之后。',
|
|
77
91
|
value: '搜索值。在 CommandPalette 内省略时从上下文读取。',
|
|
@@ -84,13 +98,16 @@ export const docsDense = {
|
|
|
84
98
|
name: 'CommandPaletteInput',
|
|
85
99
|
isHiddenFromOverview: true,
|
|
86
100
|
displayName: 'Command Palette Input',
|
|
87
|
-
description:
|
|
101
|
+
description:
|
|
102
|
+
'search input; auto-focus on mount; wires to context inside CommandPalette',
|
|
88
103
|
propDescriptions: {
|
|
89
104
|
placeholder: 'input placeholder text',
|
|
105
|
+
label: 'accessible label for the combobox; falls back to placeholder',
|
|
90
106
|
hasAutoFocus: 'auto-focus on mount; auto-disabled in inline mode',
|
|
91
107
|
endContent: 'trailing content after spinner',
|
|
92
108
|
value: 'search value; reads context when omitted inside palette',
|
|
93
|
-
onValueChange:
|
|
109
|
+
onValueChange:
|
|
110
|
+
'called on change; writes context when omitted inside palette',
|
|
94
111
|
xstyle: 'StyleX layout styles; must be stylex.create() value',
|
|
95
112
|
},
|
|
96
113
|
};
|
|
@@ -32,6 +32,40 @@ describe('CommandPaletteInput', () => {
|
|
|
32
32
|
expect(screen.getByRole('combobox')).toBeInTheDocument();
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
it('has an accessible name by default', () => {
|
|
36
|
+
render(<CommandPaletteInput />);
|
|
37
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
38
|
+
'aria-label',
|
|
39
|
+
'Search…',
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('uses the label prop as the accessible name', () => {
|
|
44
|
+
render(<CommandPaletteInput label="Search commands" />);
|
|
45
|
+
const input = screen.getByRole('combobox');
|
|
46
|
+
expect(input).toHaveAttribute('aria-label', 'Search commands');
|
|
47
|
+
// The label prop does not affect the visible placeholder
|
|
48
|
+
expect(input).toHaveAttribute('placeholder', 'Search…');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('falls back to a custom placeholder for the accessible name', () => {
|
|
52
|
+
render(<CommandPaletteInput placeholder="Type a command..." />);
|
|
53
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
54
|
+
'aria-label',
|
|
55
|
+
'Type a command...',
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('lets a consumer-passed aria-label override the default', () => {
|
|
60
|
+
render(
|
|
61
|
+
<CommandPaletteInput label="Search commands" aria-label="Custom name" />,
|
|
62
|
+
);
|
|
63
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
64
|
+
'aria-label',
|
|
65
|
+
'Custom name',
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
35
69
|
it('calls onValueChange when typing', () => {
|
|
36
70
|
const handleChange = vi.fn();
|
|
37
71
|
render(<CommandPaletteInput onValueChange={handleChange} />);
|
|
@@ -109,6 +109,13 @@ export interface CommandPaletteInputProps extends Omit<
|
|
|
109
109
|
*/
|
|
110
110
|
placeholder?: string;
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Accessible label for the combobox input, announced by screen readers.
|
|
114
|
+
* Falls back to the placeholder text (`'Search…'` by default), since a
|
|
115
|
+
* placeholder alone is not a reliable accessible name.
|
|
116
|
+
*/
|
|
117
|
+
label?: string;
|
|
118
|
+
|
|
112
119
|
/**
|
|
113
120
|
* Whether to auto-focus the input when mounted.
|
|
114
121
|
* @default true
|
|
@@ -149,6 +156,7 @@ export function CommandPaletteInput({
|
|
|
149
156
|
value: controlledValue,
|
|
150
157
|
onValueChange,
|
|
151
158
|
placeholder: placeholderFromProps,
|
|
159
|
+
label,
|
|
152
160
|
hasAutoFocus = true,
|
|
153
161
|
endContent,
|
|
154
162
|
onChange,
|
|
@@ -215,6 +223,9 @@ export function CommandPaletteInput({
|
|
|
215
223
|
? ctx.getItemId(ctx.highlightedIndex)
|
|
216
224
|
: undefined
|
|
217
225
|
}
|
|
226
|
+
// A placeholder alone is not a reliable accessible name; give the
|
|
227
|
+
// combobox an explicit one (consumer aria-label via rest props wins).
|
|
228
|
+
aria-label={label ?? placeholder}
|
|
218
229
|
placeholder={placeholder}
|
|
219
230
|
value={value}
|
|
220
231
|
data-autofocus={effectiveAutoFocus || undefined}
|
|
@@ -611,3 +611,238 @@ describe('ContextMenu selectable items', () => {
|
|
|
611
611
|
expect(onToggle).toHaveBeenCalledWith(true);
|
|
612
612
|
});
|
|
613
613
|
});
|
|
614
|
+
|
|
615
|
+
describe('ContextMenu keyboard access for menuitemradio/menuitemcheckbox (#3829)', () => {
|
|
616
|
+
it('arrow navigation reaches consumer-rendered menuitemradio and menuitemcheckbox items', () => {
|
|
617
|
+
render(
|
|
618
|
+
<ContextMenu
|
|
619
|
+
menuContent={
|
|
620
|
+
<>
|
|
621
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
622
|
+
<div role="menuitemradio" tabIndex={-1} aria-checked="false">
|
|
623
|
+
Newest
|
|
624
|
+
</div>
|
|
625
|
+
<div role="menuitemcheckbox" tabIndex={-1} aria-checked="false">
|
|
626
|
+
Archived
|
|
627
|
+
</div>
|
|
628
|
+
</>
|
|
629
|
+
}>
|
|
630
|
+
<div>Right-click me</div>
|
|
631
|
+
</ContextMenu>,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
635
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
636
|
+
screen.getByRole('menuitem', {name: 'Cut', hidden: true}).focus();
|
|
637
|
+
|
|
638
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
639
|
+
expect(
|
|
640
|
+
screen.getByRole('menuitemradio', {name: 'Newest', hidden: true}),
|
|
641
|
+
).toHaveFocus();
|
|
642
|
+
|
|
643
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
644
|
+
expect(
|
|
645
|
+
screen.getByRole('menuitemcheckbox', {name: 'Archived', hidden: true}),
|
|
646
|
+
).toHaveFocus();
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
it('activates a focused menuitemradio with Enter and a menuitemcheckbox with Space', () => {
|
|
650
|
+
const onSelect = vi.fn();
|
|
651
|
+
const onToggle = vi.fn();
|
|
652
|
+
render(
|
|
653
|
+
<ContextMenu
|
|
654
|
+
menuContent={
|
|
655
|
+
<>
|
|
656
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
657
|
+
<div
|
|
658
|
+
role="menuitemradio"
|
|
659
|
+
tabIndex={-1}
|
|
660
|
+
aria-checked="false"
|
|
661
|
+
onClick={onSelect}>
|
|
662
|
+
Newest
|
|
663
|
+
</div>
|
|
664
|
+
<div
|
|
665
|
+
role="menuitemcheckbox"
|
|
666
|
+
tabIndex={-1}
|
|
667
|
+
aria-checked="false"
|
|
668
|
+
onClick={onToggle}>
|
|
669
|
+
Archived
|
|
670
|
+
</div>
|
|
671
|
+
</>
|
|
672
|
+
}>
|
|
673
|
+
<div>Right-click me</div>
|
|
674
|
+
</ContextMenu>,
|
|
675
|
+
);
|
|
676
|
+
|
|
677
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
678
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
679
|
+
|
|
680
|
+
screen.getByRole('menuitemradio', {name: 'Newest', hidden: true}).focus();
|
|
681
|
+
fireEvent.keyDown(menu, {key: 'Enter'});
|
|
682
|
+
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
683
|
+
|
|
684
|
+
screen
|
|
685
|
+
.getByRole('menuitemcheckbox', {name: 'Archived', hidden: true})
|
|
686
|
+
.focus();
|
|
687
|
+
fireEvent.keyDown(menu, {key: ' '});
|
|
688
|
+
expect(onToggle).toHaveBeenCalledTimes(1);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
it('typeahead matches a menuitemradio label', () => {
|
|
692
|
+
render(
|
|
693
|
+
<ContextMenu
|
|
694
|
+
menuContent={
|
|
695
|
+
<>
|
|
696
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
697
|
+
<div role="menuitemradio" tabIndex={-1} aria-checked="false">
|
|
698
|
+
Newest
|
|
699
|
+
</div>
|
|
700
|
+
<div role="menuitemcheckbox" tabIndex={-1} aria-checked="false">
|
|
701
|
+
Archived
|
|
702
|
+
</div>
|
|
703
|
+
</>
|
|
704
|
+
}>
|
|
705
|
+
<div>Right-click me</div>
|
|
706
|
+
</ContextMenu>,
|
|
707
|
+
);
|
|
708
|
+
|
|
709
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
710
|
+
fireEvent.keyDown(screen.getByRole('menu', {hidden: true}), {key: 'n'});
|
|
711
|
+
expect(
|
|
712
|
+
screen.getByRole('menuitemradio', {name: 'Newest', hidden: true}),
|
|
713
|
+
).toHaveFocus();
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it('typeahead matches a menuitemcheckbox label', () => {
|
|
717
|
+
render(
|
|
718
|
+
<ContextMenu
|
|
719
|
+
menuContent={
|
|
720
|
+
<>
|
|
721
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
722
|
+
<div role="menuitemradio" tabIndex={-1} aria-checked="false">
|
|
723
|
+
Newest
|
|
724
|
+
</div>
|
|
725
|
+
<div role="menuitemcheckbox" tabIndex={-1} aria-checked="false">
|
|
726
|
+
Archived
|
|
727
|
+
</div>
|
|
728
|
+
</>
|
|
729
|
+
}>
|
|
730
|
+
<div>Right-click me</div>
|
|
731
|
+
</ContextMenu>,
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
735
|
+
fireEvent.keyDown(screen.getByRole('menu', {hidden: true}), {key: 'a'});
|
|
736
|
+
expect(
|
|
737
|
+
screen.getByRole('menuitemcheckbox', {name: 'Archived', hidden: true}),
|
|
738
|
+
).toHaveFocus();
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
it('typeahead skips an aria-disabled item and matches the next enabled label', () => {
|
|
742
|
+
render(
|
|
743
|
+
<ContextMenu
|
|
744
|
+
menuContent={
|
|
745
|
+
<>
|
|
746
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
747
|
+
<div role="menuitemradio" tabIndex={-1} aria-disabled="true">
|
|
748
|
+
Newest
|
|
749
|
+
</div>
|
|
750
|
+
<div role="menuitemcheckbox" tabIndex={-1} aria-checked="false">
|
|
751
|
+
Nightly
|
|
752
|
+
</div>
|
|
753
|
+
</>
|
|
754
|
+
}>
|
|
755
|
+
<div>Right-click me</div>
|
|
756
|
+
</ContextMenu>,
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
760
|
+
// Anchor the search on 'Cut' so typeahead scans forward and meets the
|
|
761
|
+
// disabled 'Newest' (also an 'n' match) before the enabled 'Nightly'.
|
|
762
|
+
// This pins the `:not([aria-disabled="true"])` in MENU_ITEM_SELECTOR: the
|
|
763
|
+
// menus never pass useTypeahead's `isDisabled` option, so that clause is
|
|
764
|
+
// the only thing keeping disabled rows out of the typeahead list. An
|
|
765
|
+
// arrow-key test cannot cover it — useListFocus re-filters disabled items
|
|
766
|
+
// independently, so arrow navigation is guarded twice over.
|
|
767
|
+
// The disabled row keeps tabIndex={-1} on purpose: it stays focusable, so
|
|
768
|
+
// the selector clause is the sole reason focus skips it.
|
|
769
|
+
screen.getByRole('menuitem', {name: 'Cut', hidden: true}).focus();
|
|
770
|
+
fireEvent.keyDown(screen.getByRole('menu', {hidden: true}), {key: 'n'});
|
|
771
|
+
expect(
|
|
772
|
+
screen.getByRole('menuitemcheckbox', {name: 'Nightly', hidden: true}),
|
|
773
|
+
).toHaveFocus();
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
it('skips aria-disabled menuitemradio and menuitemcheckbox items during arrow navigation', () => {
|
|
777
|
+
render(
|
|
778
|
+
<ContextMenu
|
|
779
|
+
menuContent={
|
|
780
|
+
<>
|
|
781
|
+
<DropdownMenuItem label="Cut" onClick={() => {}} />
|
|
782
|
+
<div role="menuitemradio" tabIndex={-1} aria-disabled="true">
|
|
783
|
+
Newest
|
|
784
|
+
</div>
|
|
785
|
+
<div role="menuitemcheckbox" tabIndex={-1} aria-disabled="true">
|
|
786
|
+
Archived
|
|
787
|
+
</div>
|
|
788
|
+
<div role="menuitemradio" tabIndex={-1} aria-checked="false">
|
|
789
|
+
Oldest
|
|
790
|
+
</div>
|
|
791
|
+
</>
|
|
792
|
+
}>
|
|
793
|
+
<div>Right-click me</div>
|
|
794
|
+
</ContextMenu>,
|
|
795
|
+
);
|
|
796
|
+
|
|
797
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
798
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
799
|
+
screen.getByRole('menuitem', {name: 'Cut', hidden: true}).focus();
|
|
800
|
+
|
|
801
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
802
|
+
expect(
|
|
803
|
+
screen.getByRole('menuitemradio', {name: 'Oldest', hidden: true}),
|
|
804
|
+
).toHaveFocus();
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
it('renders a submenu from a nested items array and keyboard-reaches an item after it', () => {
|
|
808
|
+
// Same inline-flyout scoping the DropdownMenu fix covers: the submenu's
|
|
809
|
+
// items must not pollute the ContextMenu's roving order, and an item after
|
|
810
|
+
// the submenu row must stay keyboard-reachable.
|
|
811
|
+
const onDelete = vi.fn();
|
|
812
|
+
render(
|
|
813
|
+
<ContextMenu
|
|
814
|
+
items={[
|
|
815
|
+
{label: 'Cut', onClick: () => {}},
|
|
816
|
+
{
|
|
817
|
+
label: 'Move to',
|
|
818
|
+
items: [
|
|
819
|
+
{label: 'Folder A', onClick: () => {}},
|
|
820
|
+
{label: 'Folder B', onClick: () => {}},
|
|
821
|
+
],
|
|
822
|
+
},
|
|
823
|
+
{type: 'divider'},
|
|
824
|
+
{label: 'Delete', onClick: onDelete},
|
|
825
|
+
]}>
|
|
826
|
+
<div>Right-click me</div>
|
|
827
|
+
</ContextMenu>,
|
|
828
|
+
);
|
|
829
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
830
|
+
// Two role="menu" exist (the context menu + the inline submenu flyout);
|
|
831
|
+
// the context menu is the first in DOM order.
|
|
832
|
+
const menu = screen.getAllByRole('menu', {hidden: true})[0];
|
|
833
|
+
// The submenu trigger renders as a menuitem with aria-haspopup.
|
|
834
|
+
const submenuTrigger = screen.getByRole('menuitem', {
|
|
835
|
+
name: /Move to/,
|
|
836
|
+
hidden: true,
|
|
837
|
+
});
|
|
838
|
+
expect(submenuTrigger).toHaveAttribute('aria-haspopup', 'menu');
|
|
839
|
+
// Cut → Move to → Delete, one step per press (submenu items not swept in).
|
|
840
|
+
screen.getByRole('menuitem', {name: 'Cut', hidden: true}).focus();
|
|
841
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
842
|
+
expect(submenuTrigger).toHaveFocus();
|
|
843
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
844
|
+
expect(
|
|
845
|
+
screen.getByRole('menuitem', {name: 'Delete', hidden: true}),
|
|
846
|
+
).toHaveFocus();
|
|
847
|
+
});
|
|
848
|
+
});
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
import {
|
|
50
50
|
MENU_ITEM_ROLES,
|
|
51
51
|
MENU_ITEM_SELECTOR,
|
|
52
|
+
MENU_BOUNDARY_SELECTOR,
|
|
52
53
|
} from '../DropdownMenu/menuItemRoles';
|
|
53
54
|
import {useListFocus} from '../hooks/useListFocus';
|
|
54
55
|
import {useTypeahead} from '../hooks/useTypeahead';
|
|
@@ -268,22 +269,18 @@ export function ContextMenu({
|
|
|
268
269
|
handleKeyDown: listNavKeyDown,
|
|
269
270
|
focusFirst,
|
|
270
271
|
focusItem,
|
|
272
|
+
ownsEvent,
|
|
273
|
+
getItems: getMenuItems,
|
|
271
274
|
} = useListFocus<HTMLDivElement>({
|
|
272
275
|
itemSelector: MENU_ITEM_SELECTOR,
|
|
276
|
+
boundarySelector: MENU_BOUNDARY_SELECTOR,
|
|
273
277
|
wrap: false,
|
|
274
278
|
onEscape: closeMenu,
|
|
275
279
|
});
|
|
276
280
|
|
|
277
|
-
// First-character typeahead over the enabled menu items (menus-11).
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
listRef.current
|
|
281
|
-
? Array.from(
|
|
282
|
-
listRef.current.querySelectorAll<HTMLElement>(MENU_ITEM_SELECTOR),
|
|
283
|
-
)
|
|
284
|
-
: [],
|
|
285
|
-
[listRef],
|
|
286
|
-
);
|
|
281
|
+
// First-character typeahead over the enabled menu items (menus-11). Reuses
|
|
282
|
+
// the hook's scoped item collection so an inline submenu flyout's items
|
|
283
|
+
// aren't swept in.
|
|
287
284
|
const typeahead = useTypeahead({
|
|
288
285
|
getItemLabels: () => getMenuItems().map(el => el.textContent),
|
|
289
286
|
onMatch: focusItem,
|
|
@@ -340,6 +337,11 @@ export function ContextMenu({
|
|
|
340
337
|
|
|
341
338
|
const listKeyDown = useCallback(
|
|
342
339
|
(e: React.KeyboardEvent) => {
|
|
340
|
+
// A submenu flyout renders inline inside this menu; its key events bubble
|
|
341
|
+
// up here. Let that level own them — only handle events from this level.
|
|
342
|
+
if (!ownsEvent(e)) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
343
345
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
344
346
|
e.preventDefault();
|
|
345
347
|
const focused = document.activeElement as HTMLElement | null;
|
|
@@ -357,7 +359,7 @@ export function ContextMenu({
|
|
|
357
359
|
}
|
|
358
360
|
listNavKeyDown(e);
|
|
359
361
|
},
|
|
360
|
-
[listNavKeyDown, typeahead],
|
|
362
|
+
[listNavKeyDown, typeahead, ownsEvent],
|
|
361
363
|
);
|
|
362
364
|
|
|
363
365
|
// Place the zero-size cursor anchor at a point in the trigger's local
|