@astryxdesign/core 0.1.8 → 0.1.9-canary.08c278e
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 +53 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +203 -49
- package/dist/Avatar/AvatarStatusDot.d.ts +33 -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 +208 -6
- package/dist/Breadcrumbs/index.d.ts +5 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +9 -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 +30 -2
- package/dist/Calendar/dayCellUtils.js +1 -1
- 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 +24 -4
- 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 +1 -1
- 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 +18 -9
- 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 +1 -1
- 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/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 +9 -2
- package/dist/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +3 -1
- 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/DateInput/DateInput.d.ts +55 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +28 -2
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +3 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +18 -3
- 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/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -2
- package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
- 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/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +2 -3
- 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/FieldStatus/FieldStatus.d.ts +15 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +58 -6
- package/dist/FileInput/FileInput.d.ts +9 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +42 -20
- 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 +7 -2
- package/dist/Icon/Icon.d.ts +7 -2
- package/dist/Icon/Icon.d.ts.map +1 -1
- 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.js +4 -4
- 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 +41 -12
- 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 +9 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +8 -1
- 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/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 +7 -3
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +19 -2
- package/dist/Stack/stack.stylex.d.ts +9 -9
- 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 +3 -2
- 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/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 +4 -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 +87 -0
- 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/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- package/dist/TextArea/TextArea.d.ts +9 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +2 -0
- package/dist/TextInput/TextInput.d.ts +9 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +6 -1
- 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 +9 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +17 -4
- 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/Tokenizer/Tokenizer.d.ts +10 -3
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +18 -4
- 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 +2 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +10 -4
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +28 -8
- 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.js +1 -1
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +2 -0
- package/dist/astryx.css +41 -31
- package/dist/astryx.umd.js +51 -51
- 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 +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -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/useListFocus.d.ts +6 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +12 -4
- 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 +3 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +53 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +32 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +24 -0
- package/package.json +1 -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 +60 -3
- package/src/Avatar/Avatar.test.tsx +281 -1
- package/src/Avatar/Avatar.tsx +324 -64
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +178 -21
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +125 -0
- 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 +284 -2
- package/src/Breadcrumbs/index.ts +27 -0
- package/src/Button/Button.doc.mjs +9 -0
- 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 +193 -0
- package/src/Calendar/Calendar.tsx +38 -16
- package/src/Calendar/dayCellUtils.test.ts +5 -0
- package/src/Calendar/dayCellUtils.ts +1 -1
- 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 +34 -4
- 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 +4 -1
- 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 +25 -4
- 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.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +1 -1
- 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/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 +10 -2
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.tsx +3 -1
- 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 +193 -0
- package/src/DateInput/DateInput.doc.mjs +31 -0
- package/src/DateInput/DateInput.test.tsx +131 -0
- package/src/DateInput/DateInput.tsx +78 -3
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +8 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +23 -0
- package/src/DateRangeInput/DateRangeInput.tsx +13 -3
- package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
- package/src/DateTimeInput/DateTimeInput.tsx +42 -18
- 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 +169 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +1 -1
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +6 -5
- package/src/Field/FieldLabel.tsx +9 -1
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +150 -40
- package/src/FieldStatus/FieldStatus.tsx +63 -5
- package/src/FileInput/FileInput.doc.mjs +17 -2
- package/src/FileInput/FileInput.test.tsx +135 -12
- package/src/FileInput/FileInput.tsx +53 -28
- 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 +24 -2
- package/src/Icon/Icon.doc.mjs +3 -2
- package/src/Icon/Icon.tsx +7 -2
- 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 +4 -4
- package/src/List/List.test.tsx +9 -8
- 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 +13 -2
- package/src/MultiSelector/MultiSelector.test.tsx +195 -3
- package/src/MultiSelector/MultiSelector.tsx +65 -12
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +15 -0
- package/src/NumberInput/NumberInput.test.tsx +82 -7
- package/src/NumberInput/NumberInput.tsx +21 -4
- 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/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 +7 -0
- package/src/Selector/Selector.test.tsx +92 -0
- package/src/Selector/Selector.tsx +16 -2
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNavCollapseButton.tsx +6 -1
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +5 -1
- package/src/Slider/Slider.test.tsx +75 -2
- package/src/Slider/Slider.tsx +21 -5
- package/src/Switch/Switch.test.tsx +32 -1
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +3 -5
- 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 +6 -2
- 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 +16 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +19 -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 +128 -1
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- 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 +15 -0
- package/src/TextArea/TextArea.test.tsx +32 -1
- package/src/TextArea/TextArea.tsx +10 -0
- package/src/TextInput/TextInput.doc.mjs +15 -0
- package/src/TextInput/TextInput.test.tsx +44 -0
- package/src/TextInput/TextInput.tsx +13 -1
- 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 +15 -0
- package/src/TimeInput/TimeInput.test.tsx +99 -1
- package/src/TimeInput/TimeInput.tsx +29 -6
- 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/Tokenizer/Tokenizer.doc.mjs +30 -1
- package/src/Tokenizer/Tokenizer.test.tsx +206 -2
- package/src/Tokenizer/Tokenizer.tsx +26 -4
- 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 +22 -0
- package/src/TreeList/TreeList.test.tsx +232 -0
- package/src/TreeList/TreeList.tsx +18 -2
- package/src/TreeList/TreeListBranches.tsx +16 -2
- package/src/TreeList/TreeListItem.tsx +52 -12
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/Typeahead/BaseTypeahead.tsx +1 -1
- package/src/Typeahead/Typeahead.doc.mjs +7 -0
- package/src/Typeahead/Typeahead.test.tsx +23 -0
- package/src/Typeahead/Typeahead.tsx +10 -0
- package/src/authoring/doc.ts +1 -3
- 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 +2 -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/useListFocus.doc.mjs +3 -3
- package/src/hooks/useListFocus.test.tsx +67 -1
- package/src/hooks/useListFocus.ts +21 -5
- 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 +6 -0
- package/src/utils/plainDate.test.ts +22 -0
- package/src/utils/plainDate.ts +61 -0
- package/src/utils/types.ts +14 -0
package/src/Layer/useLayer.tsx
CHANGED
|
@@ -100,6 +100,12 @@ export interface ContextRenderProps {
|
|
|
100
100
|
* non-hashed selector for the layer.
|
|
101
101
|
*/
|
|
102
102
|
role?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Accessible name applied to the popover container via `aria-label`.
|
|
105
|
+
* Pair with `role` so layers with a named role (e.g. `'dialog'`) expose a
|
|
106
|
+
* proper name to assistive technology.
|
|
107
|
+
*/
|
|
108
|
+
'aria-label'?: string;
|
|
103
109
|
/**
|
|
104
110
|
* StyleX styles for the popover container.
|
|
105
111
|
*/
|
|
@@ -525,6 +531,7 @@ export function useLayer(
|
|
|
525
531
|
alignment = 'center',
|
|
526
532
|
positioning = 'anchor',
|
|
527
533
|
role,
|
|
534
|
+
'aria-label': ariaLabel,
|
|
528
535
|
xstyle,
|
|
529
536
|
className: extraClassName,
|
|
530
537
|
style: extraStyle,
|
|
@@ -561,6 +568,7 @@ export function useLayer(
|
|
|
561
568
|
ref={popoverRefCallback}
|
|
562
569
|
id={id}
|
|
563
570
|
role={role}
|
|
571
|
+
aria-label={ariaLabel}
|
|
564
572
|
popover={lightDismiss ? 'auto' : 'manual'}
|
|
565
573
|
className={combinedClassName}
|
|
566
574
|
style={{...stylexResult.style, ...anchorStyle, ...extraStyle}}
|
|
@@ -199,7 +199,7 @@ const styles = stylex.create({
|
|
|
199
199
|
closeButton: {
|
|
200
200
|
position: 'absolute',
|
|
201
201
|
top: spacingVars['--spacing-3'],
|
|
202
|
-
|
|
202
|
+
insetInlineEnd: spacingVars['--spacing-3'],
|
|
203
203
|
zIndex: 1,
|
|
204
204
|
},
|
|
205
205
|
navButton: {
|
|
@@ -209,15 +209,15 @@ const styles = stylex.create({
|
|
|
209
209
|
zIndex: 1,
|
|
210
210
|
},
|
|
211
211
|
navPrev: {
|
|
212
|
-
|
|
212
|
+
insetInlineStart: spacingVars['--spacing-3'],
|
|
213
213
|
},
|
|
214
214
|
navNext: {
|
|
215
|
-
|
|
215
|
+
insetInlineEnd: spacingVars['--spacing-3'],
|
|
216
216
|
},
|
|
217
217
|
counter: {
|
|
218
218
|
position: 'absolute',
|
|
219
219
|
top: spacingVars['--spacing-3'],
|
|
220
|
-
|
|
220
|
+
insetInlineStart: spacingVars['--spacing-3'],
|
|
221
221
|
color: colorVars['--color-on-dark'],
|
|
222
222
|
fontSize: typeScaleVars['--text-body-size'],
|
|
223
223
|
lineHeight: typeScaleVars['--text-body-leading'],
|
package/src/List/List.test.tsx
CHANGED
|
@@ -436,11 +436,7 @@ describe('List', () => {
|
|
|
436
436
|
it('sets target on anchor when provided', () => {
|
|
437
437
|
const {container} = render(
|
|
438
438
|
<List>
|
|
439
|
-
<ListItem
|
|
440
|
-
label="External"
|
|
441
|
-
href="https://example.com"
|
|
442
|
-
target="_blank"
|
|
443
|
-
/>
|
|
439
|
+
<ListItem label="External" href="https://example.com" target="_blank" />
|
|
444
440
|
</List>,
|
|
445
441
|
);
|
|
446
442
|
const anchor = container.querySelector('a');
|
|
@@ -500,17 +496,21 @@ describe('List', () => {
|
|
|
500
496
|
// Selected state
|
|
501
497
|
// ===========================================================================
|
|
502
498
|
|
|
503
|
-
it('
|
|
499
|
+
it('conveys selection via aria-current when isSelected', () => {
|
|
500
|
+
// aria-selected is not permitted on an li (role listitem, axe:
|
|
501
|
+
// aria-allowed-attr), so selection is exposed via aria-current — valid on
|
|
502
|
+
// any element — so screen-reader users are still told which item is chosen.
|
|
504
503
|
const {container} = render(
|
|
505
504
|
<List>
|
|
506
505
|
<ListItem label="Selected" isSelected onClick={() => {}} />
|
|
507
506
|
</List>,
|
|
508
507
|
);
|
|
509
508
|
const item = container.querySelector('.astryx-item');
|
|
510
|
-
expect(item).toHaveAttribute('aria-selected'
|
|
509
|
+
expect(item).not.toHaveAttribute('aria-selected');
|
|
510
|
+
expect(item).toHaveAttribute('aria-current', 'true');
|
|
511
511
|
});
|
|
512
512
|
|
|
513
|
-
it('
|
|
513
|
+
it('applies neither aria-selected nor aria-current when not selected', () => {
|
|
514
514
|
const {container} = render(
|
|
515
515
|
<List>
|
|
516
516
|
<ListItem label="Not Selected" />
|
|
@@ -518,6 +518,7 @@ describe('List', () => {
|
|
|
518
518
|
);
|
|
519
519
|
const li = container.querySelector('li');
|
|
520
520
|
expect(li).not.toHaveAttribute('aria-selected');
|
|
521
|
+
expect(li).not.toHaveAttribute('aria-current');
|
|
521
522
|
});
|
|
522
523
|
|
|
523
524
|
// ===========================================================================
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import {
|
|
30
30
|
useCallback,
|
|
31
31
|
useEffect,
|
|
32
|
+
useId,
|
|
32
33
|
useMemo,
|
|
33
34
|
useRef,
|
|
34
35
|
useState,
|
|
@@ -295,6 +296,10 @@ export function MobileNav({
|
|
|
295
296
|
// Read from AppShell context as fallback
|
|
296
297
|
const appShellMobile = useAppShellMobile();
|
|
297
298
|
const isOpen = isOpenProp ?? appShellMobile.isMobileNavOpen;
|
|
299
|
+
// Share the id from AppShell context so the toggle's aria-controls resolves to
|
|
300
|
+
// this drawer; fall back to a locally generated id when used standalone.
|
|
301
|
+
const fallbackId = useId();
|
|
302
|
+
const dialogId = appShellMobile.mobileNavId || fallbackId;
|
|
298
303
|
const onOpenChange = useMemo(
|
|
299
304
|
() =>
|
|
300
305
|
onOpenChangeProp ??
|
|
@@ -411,6 +416,7 @@ export function MobileNav({
|
|
|
411
416
|
return (
|
|
412
417
|
<dialog
|
|
413
418
|
ref={mergeRefs(ref, dialogRef)}
|
|
419
|
+
id={dialogId}
|
|
414
420
|
{...mergeProps(
|
|
415
421
|
themeProps('mobile-nav', {side: resolvedSide}),
|
|
416
422
|
stylex.props(
|
|
@@ -425,7 +431,12 @@ export function MobileNav({
|
|
|
425
431
|
)}
|
|
426
432
|
{...rest}
|
|
427
433
|
data-testid={testId}
|
|
428
|
-
aria-label={
|
|
434
|
+
aria-label={
|
|
435
|
+
label ??
|
|
436
|
+
(typeof header === 'string'
|
|
437
|
+
? header
|
|
438
|
+
: t('@astryx.mobileNav.navigation'))
|
|
439
|
+
}
|
|
429
440
|
onClick={composeEventHandlers(onClickProp, handleDialogClick)}
|
|
430
441
|
onCancel={handleCancel}>
|
|
431
442
|
{/* Drawer panel — tabIndex so showModal() focuses the drawer, not the close button */}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file MobileNavToggle.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, AppShell + SideNav
|
|
6
|
+
* @output Unit tests for MobileNavToggle ARIA wiring
|
|
7
|
+
* @position Testing; validates MobileNavToggle.tsx exposes aria-expanded and
|
|
8
|
+
* aria-controls so screen-reader users know the drawer state and target.
|
|
9
|
+
*
|
|
10
|
+
* SYNC: When MobileNavToggle.tsx changes, update tests to match new behavior
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
describe,
|
|
15
|
+
it,
|
|
16
|
+
expect,
|
|
17
|
+
vi,
|
|
18
|
+
beforeAll,
|
|
19
|
+
beforeEach,
|
|
20
|
+
afterEach,
|
|
21
|
+
} from 'vitest';
|
|
22
|
+
import {render, screen, fireEvent} from '@testing-library/react';
|
|
23
|
+
import {AppShell} from '../AppShell/AppShell';
|
|
24
|
+
import {SideNav, SideNavItem, SideNavSection} from '../SideNav';
|
|
25
|
+
|
|
26
|
+
// jsdom doesn't implement showModal/close on <dialog>, so we mock them
|
|
27
|
+
beforeAll(() => {
|
|
28
|
+
HTMLDialogElement.prototype.showModal =
|
|
29
|
+
HTMLDialogElement.prototype.showModal ||
|
|
30
|
+
function (this: HTMLDialogElement) {
|
|
31
|
+
this.setAttribute('open', '');
|
|
32
|
+
};
|
|
33
|
+
HTMLDialogElement.prototype.close =
|
|
34
|
+
HTMLDialogElement.prototype.close ||
|
|
35
|
+
function (this: HTMLDialogElement) {
|
|
36
|
+
this.removeAttribute('open');
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
class MockResizeObserver {
|
|
41
|
+
observe() {}
|
|
42
|
+
unobserve() {}
|
|
43
|
+
disconnect() {}
|
|
44
|
+
}
|
|
45
|
+
vi.stubGlobal('ResizeObserver', MockResizeObserver);
|
|
46
|
+
|
|
47
|
+
function createMockMatchMedia(matches: boolean) {
|
|
48
|
+
return {
|
|
49
|
+
matches,
|
|
50
|
+
media: '',
|
|
51
|
+
onchange: null,
|
|
52
|
+
addEventListener: vi.fn(),
|
|
53
|
+
removeEventListener: vi.fn(),
|
|
54
|
+
addListener: vi.fn(),
|
|
55
|
+
removeListener: vi.fn(),
|
|
56
|
+
dispatchEvent: vi.fn(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
// Below the breakpoint so the mobile nav (and its toggle) render.
|
|
62
|
+
vi.stubGlobal(
|
|
63
|
+
'matchMedia',
|
|
64
|
+
vi.fn().mockReturnValue(createMockMatchMedia(true)),
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
afterEach(() => {
|
|
69
|
+
vi.restoreAllMocks();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
function TestShell() {
|
|
73
|
+
return (
|
|
74
|
+
<AppShell
|
|
75
|
+
sideNav={
|
|
76
|
+
<SideNav>
|
|
77
|
+
<SideNavSection title="Test" isHeaderHidden>
|
|
78
|
+
<SideNavItem label="Home" />
|
|
79
|
+
</SideNavSection>
|
|
80
|
+
</SideNav>
|
|
81
|
+
}
|
|
82
|
+
mobileNav={{breakpoint: 'md'}}>
|
|
83
|
+
<div>Content</div>
|
|
84
|
+
</AppShell>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
describe('MobileNavToggle ARIA wiring', () => {
|
|
89
|
+
it('exposes aria-expanded="false" when the drawer is closed', () => {
|
|
90
|
+
render(<TestShell />);
|
|
91
|
+
|
|
92
|
+
const toggle = screen.getByRole('button', {name: /open navigation/i});
|
|
93
|
+
expect(toggle).toHaveAttribute('aria-expanded', 'false');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('exposes aria-expanded="true" after opening the drawer', () => {
|
|
97
|
+
render(<TestShell />);
|
|
98
|
+
|
|
99
|
+
const toggle = screen.getByRole('button', {name: /open navigation/i});
|
|
100
|
+
fireEvent.click(toggle);
|
|
101
|
+
expect(toggle).toHaveAttribute('aria-expanded', 'true');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('references the nav drawer via aria-controls that resolves to the dialog', () => {
|
|
105
|
+
render(<TestShell />);
|
|
106
|
+
|
|
107
|
+
const toggle = screen.getByRole('button', {name: /open navigation/i});
|
|
108
|
+
const controls = toggle.getAttribute('aria-controls');
|
|
109
|
+
expect(controls).toBeTruthy();
|
|
110
|
+
|
|
111
|
+
const target = document.getElementById(controls!);
|
|
112
|
+
expect(target).not.toBeNull();
|
|
113
|
+
expect(target).toBe(screen.getAllByRole('dialog', {hidden: true})[0]);
|
|
114
|
+
expect(target?.tagName).toBe('DIALOG');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -69,7 +69,13 @@ export function MobileNavToggle({
|
|
|
69
69
|
}: MobileNavToggleProps) {
|
|
70
70
|
const t = useTranslator();
|
|
71
71
|
const label = labelFromProps ?? t('@astryx.mobileNav.toggle.open');
|
|
72
|
-
const {
|
|
72
|
+
const {
|
|
73
|
+
isMobile,
|
|
74
|
+
isMobileNavEnabled,
|
|
75
|
+
isMobileNavOpen,
|
|
76
|
+
mobileNavId,
|
|
77
|
+
toggleMobileNav,
|
|
78
|
+
} = useAppShellMobile();
|
|
73
79
|
|
|
74
80
|
// Don't render above the breakpoint or when mobile nav is disabled
|
|
75
81
|
if (!isMobile || !isMobileNavEnabled) {
|
|
@@ -83,6 +89,8 @@ export function MobileNavToggle({
|
|
|
83
89
|
label={label}
|
|
84
90
|
icon={children ?? <Icon icon="menu" color="inherit" />}
|
|
85
91
|
onClick={toggleMobileNav}
|
|
92
|
+
aria-expanded={isMobileNavOpen}
|
|
93
|
+
aria-controls={mobileNavId || undefined}
|
|
86
94
|
data-testid={testId ?? 'mobile-nav-toggle'}
|
|
87
95
|
xstyle={xstyle}
|
|
88
96
|
className={className}
|
|
@@ -99,7 +99,8 @@ export const docs = {
|
|
|
99
99
|
{
|
|
100
100
|
name: 'hasSearch',
|
|
101
101
|
type: 'boolean',
|
|
102
|
-
description:
|
|
102
|
+
description:
|
|
103
|
+
'Whether to show a search input for filtering options. As the user types, the match count (or "No results found") is announced to screen readers via a polite live region.',
|
|
103
104
|
},
|
|
104
105
|
{
|
|
105
106
|
name: 'searchPlaceholder',
|
|
@@ -154,6 +155,13 @@ export const docs = {
|
|
|
154
155
|
type: "{type: 'error' | 'warning' | 'success', message?: string}",
|
|
155
156
|
description: 'Validation status with an optional message.',
|
|
156
157
|
},
|
|
158
|
+
{
|
|
159
|
+
name: 'statusVariant',
|
|
160
|
+
type: "'attached' | 'detached'",
|
|
161
|
+
description:
|
|
162
|
+
'How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing.',
|
|
163
|
+
default: "'attached'",
|
|
164
|
+
},
|
|
157
165
|
{
|
|
158
166
|
name: 'renderOption',
|
|
159
167
|
type: '(option: MultiSelectorOptionData) => ReactNode',
|
|
@@ -239,7 +247,8 @@ export const docsZh = {
|
|
|
239
247
|
hasSearch: '是否显示用于过滤选项的搜索输入。',
|
|
240
248
|
searchPlaceholder: '搜索输入的占位文本。',
|
|
241
249
|
isDisabled: '禁用选择器。',
|
|
242
|
-
htmlName:
|
|
250
|
+
htmlName:
|
|
251
|
+
'用于表单提交的 HTML name 属性。为每个已选值渲染一个隐藏输入,类似原生多选。',
|
|
243
252
|
disabledMessage:
|
|
244
253
|
'解释选择器被禁用的原因。与 isDisabled 一起使用时,悬停/键盘聚焦时显示工具提示,并通过 aria-disabled 保持触发器可聚焦(仍无法激活)。请使用此属性,而不是用 Tooltip 包裹被禁用的选择器。',
|
|
245
254
|
isLabelHidden: '视觉上隐藏标签同时保持其可访问性。',
|
|
@@ -248,6 +257,7 @@ export const docsZh = {
|
|
|
248
257
|
isRequired: '将字段标记为必填。',
|
|
249
258
|
isLoading: '在触发器中显示加载旋转器。',
|
|
250
259
|
status: '带可选消息的验证状态。',
|
|
260
|
+
statusVariant: '状态消息的放置方式:attached 直接叠加在输入框下方;detached 作为独立元素浮于下方并留有间距。',
|
|
251
261
|
renderOption:
|
|
252
262
|
'每个可选选项的自定义渲染函数。不会用于分隔线、分组或全选行。',
|
|
253
263
|
xstyle: '布局自定义的 StyleX 样式,必须是 stylex.create() 值。',
|
|
@@ -373,6 +383,7 @@ export const docsDense = {
|
|
|
373
383
|
isRequired: 'marks required',
|
|
374
384
|
isLoading: 'spinner in trigger',
|
|
375
385
|
status: 'validation status w/ optional message',
|
|
386
|
+
statusVariant: 'How status message is placed: attached overlaps below input; detached floats below w/ spacing.',
|
|
376
387
|
renderOption:
|
|
377
388
|
'custom render fn per selectable option; not dividers/sections/select-all',
|
|
378
389
|
xstyle: 'StyleX layout styles; stylex.create() only',
|
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
render,
|
|
15
|
+
screen,
|
|
16
|
+
fireEvent,
|
|
17
|
+
waitFor,
|
|
18
|
+
within,
|
|
19
|
+
} from '@testing-library/react';
|
|
14
20
|
import userEvent from '@testing-library/user-event';
|
|
15
21
|
import {MultiSelector} from './MultiSelector';
|
|
16
22
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
@@ -360,6 +366,30 @@ describe('MultiSelector', () => {
|
|
|
360
366
|
expect(activeId).toBeTruthy();
|
|
361
367
|
});
|
|
362
368
|
|
|
369
|
+
it('End/Home jump the highlight to the last/first option (non-search)', async () => {
|
|
370
|
+
const user = userEvent.setup();
|
|
371
|
+
render(
|
|
372
|
+
<MultiSelector
|
|
373
|
+
label="Fruit"
|
|
374
|
+
options={defaultOptions}
|
|
375
|
+
value={[]}
|
|
376
|
+
onChange={() => {}}
|
|
377
|
+
/>,
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
const trigger = screen.getByRole('combobox');
|
|
381
|
+
await user.click(trigger);
|
|
382
|
+
const options = screen.getAllByRole('option', h);
|
|
383
|
+
|
|
384
|
+
await user.keyboard('{End}');
|
|
385
|
+
expect(trigger).toHaveAttribute(
|
|
386
|
+
'aria-activedescendant',
|
|
387
|
+
options[options.length - 1].id,
|
|
388
|
+
);
|
|
389
|
+
await user.keyboard('{Home}');
|
|
390
|
+
expect(trigger).toHaveAttribute('aria-activedescendant', options[0].id);
|
|
391
|
+
});
|
|
392
|
+
|
|
363
393
|
it('toggles item with Enter key', async () => {
|
|
364
394
|
const user = userEvent.setup();
|
|
365
395
|
const onChange = vi.fn();
|
|
@@ -535,6 +565,65 @@ describe('MultiSelector', () => {
|
|
|
535
565
|
expect(options).toHaveLength(1);
|
|
536
566
|
});
|
|
537
567
|
|
|
568
|
+
it('PageDown/PageUp jump the highlight to the last/first filtered option', async () => {
|
|
569
|
+
const user = userEvent.setup();
|
|
570
|
+
render(
|
|
571
|
+
<MultiSelector
|
|
572
|
+
label="Fruit"
|
|
573
|
+
options={defaultOptions}
|
|
574
|
+
value={[]}
|
|
575
|
+
onChange={() => {}}
|
|
576
|
+
hasSearch
|
|
577
|
+
/>,
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
581
|
+
const searchInput = screen.getByRole('combobox', h);
|
|
582
|
+
// Filter to Banana and Orange so "last" means last *visible* option.
|
|
583
|
+
await user.type(searchInput, 'an');
|
|
584
|
+
const options = screen.getAllByRole('option', h);
|
|
585
|
+
expect(options).toHaveLength(2);
|
|
586
|
+
|
|
587
|
+
await user.keyboard('{PageDown}');
|
|
588
|
+
expect(searchInput).toHaveAttribute(
|
|
589
|
+
'aria-activedescendant',
|
|
590
|
+
options[options.length - 1].id,
|
|
591
|
+
);
|
|
592
|
+
await user.keyboard('{PageUp}');
|
|
593
|
+
expect(searchInput).toHaveAttribute('aria-activedescendant', options[0].id);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('Home/End move the search caret, not the option highlight', async () => {
|
|
597
|
+
const user = userEvent.setup();
|
|
598
|
+
render(
|
|
599
|
+
<MultiSelector
|
|
600
|
+
label="Fruit"
|
|
601
|
+
options={defaultOptions}
|
|
602
|
+
value={[]}
|
|
603
|
+
onChange={() => {}}
|
|
604
|
+
hasSearch
|
|
605
|
+
/>,
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
609
|
+
const searchInput = screen.getByRole<HTMLInputElement>('combobox', h);
|
|
610
|
+
await user.type(searchInput, 'an');
|
|
611
|
+
expect(searchInput.selectionStart).toBe(2);
|
|
612
|
+
const activeBefore = searchInput.getAttribute('aria-activedescendant');
|
|
613
|
+
// Home/End stay on the input for caret movement (APG editable combobox);
|
|
614
|
+
// the option highlight must not move.
|
|
615
|
+
await user.keyboard('{Home}');
|
|
616
|
+
expect(searchInput.selectionStart).toBe(0);
|
|
617
|
+
expect(searchInput.getAttribute('aria-activedescendant')).toBe(
|
|
618
|
+
activeBefore,
|
|
619
|
+
);
|
|
620
|
+
await user.keyboard('{End}');
|
|
621
|
+
expect(searchInput.selectionStart).toBe(2);
|
|
622
|
+
expect(searchInput.getAttribute('aria-activedescendant')).toBe(
|
|
623
|
+
activeBefore,
|
|
624
|
+
);
|
|
625
|
+
});
|
|
626
|
+
|
|
538
627
|
it('shows empty state when search has no results', async () => {
|
|
539
628
|
const user = userEvent.setup();
|
|
540
629
|
render(
|
|
@@ -551,7 +640,85 @@ describe('MultiSelector', () => {
|
|
|
551
640
|
const searchInput = screen.getByRole('combobox', h);
|
|
552
641
|
await user.type(searchInput, 'xyz');
|
|
553
642
|
|
|
554
|
-
expect(
|
|
643
|
+
expect(
|
|
644
|
+
within(screen.getByRole('listbox', h)).getByText('No results found'),
|
|
645
|
+
).toBeInTheDocument();
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
describe('result announcements', () => {
|
|
649
|
+
it('announces the match count politely while searching', async () => {
|
|
650
|
+
const user = userEvent.setup();
|
|
651
|
+
render(
|
|
652
|
+
<MultiSelector
|
|
653
|
+
label="Fruit"
|
|
654
|
+
options={defaultOptions}
|
|
655
|
+
value={EMPTY_VALUE}
|
|
656
|
+
onChange={() => {}}
|
|
657
|
+
hasSearch
|
|
658
|
+
/>,
|
|
659
|
+
);
|
|
660
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
661
|
+
// "an" matches Banana and Orange.
|
|
662
|
+
await user.type(screen.getByRole('combobox', h), 'an');
|
|
663
|
+
await waitFor(() => {
|
|
664
|
+
expect(politeRegion()).toHaveTextContent('2 results');
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it('announces the singular form when one option matches', async () => {
|
|
669
|
+
const user = userEvent.setup();
|
|
670
|
+
render(
|
|
671
|
+
<MultiSelector
|
|
672
|
+
label="Fruit"
|
|
673
|
+
options={defaultOptions}
|
|
674
|
+
value={EMPTY_VALUE}
|
|
675
|
+
onChange={() => {}}
|
|
676
|
+
hasSearch
|
|
677
|
+
/>,
|
|
678
|
+
);
|
|
679
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
680
|
+
// "app" matches only Apple. Anchored so it cannot pass on "1 results".
|
|
681
|
+
await user.type(screen.getByRole('combobox', h), 'app');
|
|
682
|
+
await waitFor(() => {
|
|
683
|
+
expect(politeRegion()).toHaveTextContent(/^1 result$/);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('announces "No results found" when nothing matches', async () => {
|
|
688
|
+
const user = userEvent.setup();
|
|
689
|
+
render(
|
|
690
|
+
<MultiSelector
|
|
691
|
+
label="Fruit"
|
|
692
|
+
options={defaultOptions}
|
|
693
|
+
value={EMPTY_VALUE}
|
|
694
|
+
onChange={() => {}}
|
|
695
|
+
hasSearch
|
|
696
|
+
/>,
|
|
697
|
+
);
|
|
698
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
699
|
+
await user.type(screen.getByRole('combobox', h), 'xyz');
|
|
700
|
+
await waitFor(() => {
|
|
701
|
+
expect(politeRegion()).toHaveTextContent('No results found');
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('does not announce results until the user searches', async () => {
|
|
706
|
+
const user = userEvent.setup();
|
|
707
|
+
render(
|
|
708
|
+
<MultiSelector
|
|
709
|
+
label="Fruit"
|
|
710
|
+
options={defaultOptions}
|
|
711
|
+
value={EMPTY_VALUE}
|
|
712
|
+
onChange={() => {}}
|
|
713
|
+
hasSearch
|
|
714
|
+
/>,
|
|
715
|
+
);
|
|
716
|
+
// Popover closed: nothing announced.
|
|
717
|
+
expect(politeRegion()?.textContent ?? '').toBe('');
|
|
718
|
+
// Open with an empty query: still nothing announced.
|
|
719
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
720
|
+
expect(politeRegion()?.textContent ?? '').toBe('');
|
|
721
|
+
});
|
|
555
722
|
});
|
|
556
723
|
|
|
557
724
|
it('renders with description', () => {
|
|
@@ -1072,7 +1239,32 @@ describe('MultiSelector', () => {
|
|
|
1072
1239
|
/>
|
|
1073
1240
|
</form>,
|
|
1074
1241
|
);
|
|
1075
|
-
expect([
|
|
1242
|
+
expect([
|
|
1243
|
+
...new FormData(container.querySelector('form')!).keys(),
|
|
1244
|
+
]).toEqual([]);
|
|
1076
1245
|
});
|
|
1077
1246
|
});
|
|
1078
1247
|
});
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
describe('MultiSelector statusVariant forwarding', () => {
|
|
1251
|
+
it('defaults to attached (status renders with data-variant="attached")', () => {
|
|
1252
|
+
const {container} = render(
|
|
1253
|
+
<MultiSelector label="Fruit" options={['Apple', 'Banana']} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
|
|
1254
|
+
);
|
|
1255
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1256
|
+
'data-variant',
|
|
1257
|
+
'attached',
|
|
1258
|
+
);
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
it('forwards statusVariant="detached" to the underlying Field status', () => {
|
|
1262
|
+
const {container} = render(
|
|
1263
|
+
<MultiSelector label="Fruit" options={['Apple', 'Banana']} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
|
|
1264
|
+
);
|
|
1265
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1266
|
+
'data-variant',
|
|
1267
|
+
'detached',
|
|
1268
|
+
);
|
|
1269
|
+
});
|
|
1270
|
+
});
|