@astryxdesign/core 0.1.8 → 0.1.9-canary.09e9ddd
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/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 +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.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 +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 -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 +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/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 +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 +30 -15
- package/src/Typeahead/Typeahead.doc.mjs +7 -0
- package/src/Typeahead/Typeahead.test.tsx +50 -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
|
@@ -9,11 +9,17 @@
|
|
|
9
9
|
* SYNC: When Tokenizer.tsx changes, update tests to match
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest';
|
|
12
|
+
import {describe, it, expect, vi, beforeAll, afterAll, afterEach} from 'vitest';
|
|
13
13
|
import {render, screen, fireEvent, act, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {Tokenizer} from './Tokenizer';
|
|
16
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
16
17
|
import type {SearchSource, SearchableItem} from '../Typeahead/types';
|
|
18
|
+
import {TestIcon} from '../__tests__/TestIcon';
|
|
19
|
+
|
|
20
|
+
function politeRegion(): HTMLElement | null {
|
|
21
|
+
return document.querySelector('[data-astryx-live-region="polite"]');
|
|
22
|
+
}
|
|
17
23
|
|
|
18
24
|
// Store original matches to restore later
|
|
19
25
|
const originalMatches = HTMLElement.prototype.matches;
|
|
@@ -60,6 +66,10 @@ afterAll(() => {
|
|
|
60
66
|
(HTMLElement.prototype as any).matches = originalMatches;
|
|
61
67
|
});
|
|
62
68
|
|
|
69
|
+
afterEach(() => {
|
|
70
|
+
__resetLiveRegionsForTest();
|
|
71
|
+
});
|
|
72
|
+
|
|
63
73
|
// Test data
|
|
64
74
|
const users: SearchableItem[] = [
|
|
65
75
|
{id: '1', label: 'Alice'},
|
|
@@ -818,6 +828,51 @@ describe('Tokenizer', () => {
|
|
|
818
828
|
});
|
|
819
829
|
});
|
|
820
830
|
|
|
831
|
+
describe('startIcon', () => {
|
|
832
|
+
it('does not render a start icon when omitted', () => {
|
|
833
|
+
render(
|
|
834
|
+
<Tokenizer
|
|
835
|
+
label="Members"
|
|
836
|
+
searchSource={userSource}
|
|
837
|
+
value={[]}
|
|
838
|
+
onChange={() => {}}
|
|
839
|
+
/>,
|
|
840
|
+
);
|
|
841
|
+
expect(document.querySelector('svg')).not.toBeInTheDocument();
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
it('renders a ReactNode start icon before the tokens', () => {
|
|
845
|
+
render(
|
|
846
|
+
<Tokenizer
|
|
847
|
+
label="Members"
|
|
848
|
+
searchSource={userSource}
|
|
849
|
+
value={[{id: '1', label: 'Alice'}]}
|
|
850
|
+
onChange={() => {}}
|
|
851
|
+
startIcon={<TestIcon data-testid="start-icon" />}
|
|
852
|
+
/>,
|
|
853
|
+
);
|
|
854
|
+
const icon = screen.getByTestId('start-icon');
|
|
855
|
+
const token = screen.getByText('Alice');
|
|
856
|
+
expect(icon).toBeInTheDocument();
|
|
857
|
+
expect(
|
|
858
|
+
icon.compareDocumentPosition(token) & Node.DOCUMENT_POSITION_FOLLOWING,
|
|
859
|
+
).toBeTruthy();
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
it('renders an IconType (SVG component) start icon', () => {
|
|
863
|
+
render(
|
|
864
|
+
<Tokenizer
|
|
865
|
+
label="Members"
|
|
866
|
+
searchSource={userSource}
|
|
867
|
+
value={[]}
|
|
868
|
+
onChange={() => {}}
|
|
869
|
+
startIcon={TestIcon}
|
|
870
|
+
/>,
|
|
871
|
+
);
|
|
872
|
+
expect(document.querySelector('svg')).toBeInTheDocument();
|
|
873
|
+
});
|
|
874
|
+
});
|
|
875
|
+
|
|
821
876
|
describe('disabledMessage', () => {
|
|
822
877
|
const h = {hidden: true} as const;
|
|
823
878
|
const isOpen = (el: Element) => el.matches(':popover-open');
|
|
@@ -921,6 +976,130 @@ describe('Tokenizer', () => {
|
|
|
921
976
|
expect(screen.getByRole('combobox')).toBeDisabled();
|
|
922
977
|
});
|
|
923
978
|
});
|
|
979
|
+
describe('announcements', () => {
|
|
980
|
+
it('announces removal politely on Backspace with an empty input', async () => {
|
|
981
|
+
const onChange = vi.fn();
|
|
982
|
+
render(
|
|
983
|
+
<Tokenizer
|
|
984
|
+
label="Members"
|
|
985
|
+
searchSource={userSource}
|
|
986
|
+
value={[users[0], users[1]]}
|
|
987
|
+
onChange={onChange}
|
|
988
|
+
/>,
|
|
989
|
+
);
|
|
990
|
+
const input = screen.getByRole('combobox');
|
|
991
|
+
fireEvent.keyDown(input, {key: 'Backspace'});
|
|
992
|
+
expect(onChange).toHaveBeenCalledWith([users[0]], {
|
|
993
|
+
item: users[1],
|
|
994
|
+
type: 'remove',
|
|
995
|
+
});
|
|
996
|
+
await waitFor(() => {
|
|
997
|
+
expect(politeRegion()).toHaveTextContent('Removed Bob');
|
|
998
|
+
});
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
it("announces removal politely when clicking a token's remove button", async () => {
|
|
1002
|
+
render(
|
|
1003
|
+
<Tokenizer
|
|
1004
|
+
label="Members"
|
|
1005
|
+
searchSource={userSource}
|
|
1006
|
+
value={[users[0], users[1]]}
|
|
1007
|
+
onChange={() => {}}
|
|
1008
|
+
/>,
|
|
1009
|
+
);
|
|
1010
|
+
fireEvent.click(screen.getByRole('button', {name: 'Remove Alice'}));
|
|
1011
|
+
await waitFor(() => {
|
|
1012
|
+
expect(politeRegion()).toHaveTextContent('Removed Alice');
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
it('announces addition politely when selecting a search result', async () => {
|
|
1017
|
+
render(
|
|
1018
|
+
<Tokenizer
|
|
1019
|
+
label="Members"
|
|
1020
|
+
searchSource={userSource}
|
|
1021
|
+
value={[]}
|
|
1022
|
+
onChange={() => {}}
|
|
1023
|
+
hasEntriesOnFocus
|
|
1024
|
+
debounceMs={0}
|
|
1025
|
+
/>,
|
|
1026
|
+
);
|
|
1027
|
+
const input = screen.getByRole('combobox');
|
|
1028
|
+
fireEvent.focus(input);
|
|
1029
|
+
await act(async () => {
|
|
1030
|
+
await new Promise(r => setTimeout(r, 50));
|
|
1031
|
+
});
|
|
1032
|
+
fireEvent.click(screen.getByText('Alice'));
|
|
1033
|
+
await waitFor(() => {
|
|
1034
|
+
expect(politeRegion()).toHaveTextContent('Added Alice');
|
|
1035
|
+
});
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
it('announces addition politely when creating a token with hasCreate', async () => {
|
|
1039
|
+
const emptySource: SearchSource = {
|
|
1040
|
+
search: () => [],
|
|
1041
|
+
bootstrap: () => [],
|
|
1042
|
+
};
|
|
1043
|
+
render(
|
|
1044
|
+
<Tokenizer
|
|
1045
|
+
label="Tags"
|
|
1046
|
+
searchSource={emptySource}
|
|
1047
|
+
value={[]}
|
|
1048
|
+
onChange={() => {}}
|
|
1049
|
+
hasCreate
|
|
1050
|
+
debounceMs={0}
|
|
1051
|
+
/>,
|
|
1052
|
+
);
|
|
1053
|
+
const input = screen.getByRole('combobox');
|
|
1054
|
+
await act(async () => {
|
|
1055
|
+
fireEvent.change(input, {target: {value: 'new-tag'}});
|
|
1056
|
+
});
|
|
1057
|
+
await act(async () => {
|
|
1058
|
+
await new Promise(r => setTimeout(r, 50));
|
|
1059
|
+
});
|
|
1060
|
+
fireEvent.click(screen.getByText('Create "new-tag"'));
|
|
1061
|
+
await waitFor(() => {
|
|
1062
|
+
expect(politeRegion()).toHaveTextContent('Added new-tag');
|
|
1063
|
+
});
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
it('does not announce on mount', () => {
|
|
1067
|
+
render(
|
|
1068
|
+
<Tokenizer
|
|
1069
|
+
label="Members"
|
|
1070
|
+
searchSource={userSource}
|
|
1071
|
+
value={[users[0]]}
|
|
1072
|
+
onChange={() => {}}
|
|
1073
|
+
/>,
|
|
1074
|
+
);
|
|
1075
|
+
// The live regions are created lazily on first announce, so a mount
|
|
1076
|
+
// with pre-selected tokens must not create (or speak through) one.
|
|
1077
|
+
expect(politeRegion()).toBeNull();
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
it('does not announce add/remove while typing', async () => {
|
|
1081
|
+
render(
|
|
1082
|
+
<Tokenizer
|
|
1083
|
+
label="Members"
|
|
1084
|
+
searchSource={userSource}
|
|
1085
|
+
value={[]}
|
|
1086
|
+
onChange={() => {}}
|
|
1087
|
+
debounceMs={0}
|
|
1088
|
+
/>,
|
|
1089
|
+
);
|
|
1090
|
+
const input = screen.getByRole('combobox');
|
|
1091
|
+
await act(async () => {
|
|
1092
|
+
fireEvent.change(input, {target: {value: 'Ali'}});
|
|
1093
|
+
});
|
|
1094
|
+
await act(async () => {
|
|
1095
|
+
await new Promise(r => setTimeout(r, 50));
|
|
1096
|
+
});
|
|
1097
|
+
// BaseTypeahead announces result counts while typing (existing
|
|
1098
|
+
// behavior); typing alone must not produce add/remove announcements.
|
|
1099
|
+
expect(politeRegion()?.textContent ?? '').not.toMatch(/Added|Removed/);
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
|
|
924
1103
|
describe('form participation', () => {
|
|
925
1104
|
it('submits one entry per token id under htmlName', () => {
|
|
926
1105
|
const {container} = render(
|
|
@@ -951,7 +1130,32 @@ describe('Tokenizer', () => {
|
|
|
951
1130
|
/>
|
|
952
1131
|
</form>,
|
|
953
1132
|
);
|
|
954
|
-
expect([
|
|
1133
|
+
expect([
|
|
1134
|
+
...new FormData(container.querySelector('form')!).keys(),
|
|
1135
|
+
]).toEqual([]);
|
|
955
1136
|
});
|
|
956
1137
|
});
|
|
957
1138
|
});
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
describe('Tokenizer statusVariant forwarding', () => {
|
|
1142
|
+
it('defaults to attached (status renders with data-variant="attached")', () => {
|
|
1143
|
+
const {container} = render(
|
|
1144
|
+
<Tokenizer label="Members" searchSource={userSource} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
|
|
1145
|
+
);
|
|
1146
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1147
|
+
'data-variant',
|
|
1148
|
+
'attached',
|
|
1149
|
+
);
|
|
1150
|
+
});
|
|
1151
|
+
|
|
1152
|
+
it('forwards statusVariant="detached" to the underlying Field status', () => {
|
|
1153
|
+
const {container} = render(
|
|
1154
|
+
<Tokenizer label="Members" searchSource={userSource} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
|
|
1155
|
+
);
|
|
1156
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1157
|
+
'data-variant',
|
|
1158
|
+
'detached',
|
|
1159
|
+
);
|
|
1160
|
+
});
|
|
1161
|
+
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Tokenizer.tsx
|
|
7
|
-
* @input Uses React, BaseTypeahead, Field, Token
|
|
7
|
+
* @input Uses React, BaseTypeahead, Field, Token, useAnnounce
|
|
8
8
|
* @output Exports Tokenizer multi-select typeahead component
|
|
9
9
|
* @position Composed component; forwards DOM ref and exposes focus control via
|
|
10
10
|
* handleRef
|
|
@@ -37,12 +37,14 @@ import {
|
|
|
37
37
|
inputStatusBorderStyles,
|
|
38
38
|
inputStatusHoverShadowStyles,
|
|
39
39
|
inputStatusFocusWithinStyles,
|
|
40
|
+
type FieldStatusVariant,
|
|
40
41
|
} from '../Field';
|
|
41
42
|
import {Token} from '../Token';
|
|
42
43
|
import {renderIconSlot, type IconType} from '../Icon';
|
|
43
44
|
import {OverflowList} from '../OverflowList';
|
|
44
45
|
import {useLayer} from '../Layer/useLayer';
|
|
45
46
|
import {useTooltip} from '../Tooltip';
|
|
47
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
46
48
|
import {
|
|
47
49
|
colorVars,
|
|
48
50
|
spacingVars,
|
|
@@ -110,6 +112,13 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
|
|
|
110
112
|
isOptional?: boolean;
|
|
111
113
|
/** Validation status. */
|
|
112
114
|
status?: InputStatus;
|
|
115
|
+
/**
|
|
116
|
+
* How the status message is placed relative to the input.
|
|
117
|
+
* - 'attached': message overlaps directly below the input (bordered treatment)
|
|
118
|
+
* - 'detached': message floats below as a separate element with spacing
|
|
119
|
+
* @default 'attached'
|
|
120
|
+
*/
|
|
121
|
+
statusVariant?: FieldStatusVariant;
|
|
113
122
|
/**
|
|
114
123
|
* Icon to display at the start of the input.
|
|
115
124
|
* Accepts a ReactNode (e.g. `<Icon icon={SearchIcon} />`) or an SVG icon component directly.
|
|
@@ -369,6 +378,7 @@ export function Tokenizer<T extends SearchableItem>({
|
|
|
369
378
|
isRequired = false,
|
|
370
379
|
isOptional = false,
|
|
371
380
|
status,
|
|
381
|
+
statusVariant = 'attached',
|
|
372
382
|
startIcon,
|
|
373
383
|
labelTooltip,
|
|
374
384
|
searchSource,
|
|
@@ -560,6 +570,12 @@ export function Tokenizer<T extends SearchableItem>({
|
|
|
560
570
|
[],
|
|
561
571
|
);
|
|
562
572
|
|
|
573
|
+
// Announce token add/remove politely via the persistent live region.
|
|
574
|
+
// Tokens previously appeared and disappeared silently — Backspace on an
|
|
575
|
+
// empty input removes the trailing token, and the per-token remove buttons
|
|
576
|
+
// gave no audible feedback either.
|
|
577
|
+
const announce = useAnnounce();
|
|
578
|
+
|
|
563
579
|
// Handle adding an item — detect creatable synthetic items
|
|
564
580
|
const handleAdd = useCallback(
|
|
565
581
|
(item: T | null) => {
|
|
@@ -584,6 +600,7 @@ export function Tokenizer<T extends SearchableItem>({
|
|
|
584
600
|
const realItem = base as T;
|
|
585
601
|
const newItems = [...value, realItem];
|
|
586
602
|
onChange(newItems, {item: realItem, type: 'create'});
|
|
603
|
+
announce(`Added ${createdValue}`);
|
|
587
604
|
return;
|
|
588
605
|
}
|
|
589
606
|
|
|
@@ -592,18 +609,22 @@ export function Tokenizer<T extends SearchableItem>({
|
|
|
592
609
|
}
|
|
593
610
|
const newItems = [...value, item];
|
|
594
611
|
onChange(newItems, {item, type: 'add'});
|
|
612
|
+
announce(`Added ${item.label}`);
|
|
595
613
|
},
|
|
596
|
-
[value, onChange, isAtMax, selectedIds, hasCreate],
|
|
614
|
+
[value, onChange, isAtMax, selectedIds, hasCreate, announce],
|
|
597
615
|
);
|
|
598
616
|
|
|
599
|
-
// Handle removing an item
|
|
617
|
+
// Handle removing an item. Single removal path: both Backspace on an empty
|
|
618
|
+
// input and the per-token remove buttons route through here, so the
|
|
619
|
+
// announcement covers both.
|
|
600
620
|
const handleRemove = useCallback(
|
|
601
621
|
(item: T) => {
|
|
602
622
|
const newItems = value.filter(v => v.id !== item.id);
|
|
603
623
|
onChange(newItems, {item, type: 'remove'});
|
|
624
|
+
announce(`Removed ${item.label}`);
|
|
604
625
|
inputRef.current?.focus();
|
|
605
626
|
},
|
|
606
|
-
[value, onChange],
|
|
627
|
+
[value, onChange, announce],
|
|
607
628
|
);
|
|
608
629
|
|
|
609
630
|
// Handle clearing all items
|
|
@@ -879,6 +900,7 @@ export function Tokenizer<T extends SearchableItem>({
|
|
|
879
900
|
}
|
|
880
901
|
: undefined
|
|
881
902
|
}
|
|
903
|
+
statusVariant={statusVariant}
|
|
882
904
|
labelTooltip={labelTooltip}
|
|
883
905
|
width={width}
|
|
884
906
|
xstyle={xstyle}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {describe, it, expect, vi} from 'vitest';
|
|
13
|
-
import {render, screen} from '@testing-library/react';
|
|
13
|
+
import {fireEvent, render, screen} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {TopNav} from './TopNav';
|
|
16
16
|
import {TopNavRenderContext} from './TopNavRenderContext';
|
|
@@ -297,6 +297,85 @@ describe('TopNavHeading', () => {
|
|
|
297
297
|
render(<TopNavHeading heading="Test" ref={ref} />);
|
|
298
298
|
expect(ref).toHaveBeenCalledWith(expect.any(HTMLElement));
|
|
299
299
|
});
|
|
300
|
+
|
|
301
|
+
// ===========================================================================
|
|
302
|
+
// Menu popover semantics — the popup must not be announced as a modal
|
|
303
|
+
// dialog, and role="menu" must be scoped to the actual menu items so the
|
|
304
|
+
// heading button is not an invalid child of the menu.
|
|
305
|
+
// ===========================================================================
|
|
306
|
+
|
|
307
|
+
// The popover layer keeps `popover` content display:none in jsdom even
|
|
308
|
+
// when open, hiding it from role queries — so these tests assert the
|
|
309
|
+
// popup's ARIA semantics at the DOM level instead.
|
|
310
|
+
describe('menu popover semantics', () => {
|
|
311
|
+
const menuItems = (
|
|
312
|
+
<>
|
|
313
|
+
<div role="menuitem">Alpha</div>
|
|
314
|
+
<div role="menuitem">Beta</div>
|
|
315
|
+
</>
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
it('does not wrap the heading menu popup in a modal dialog', async () => {
|
|
319
|
+
const user = userEvent.setup();
|
|
320
|
+
render(<TopNavHeading heading="My App" menu={menuItems} />);
|
|
321
|
+
await user.click(screen.getByRole('button', {name: 'Open menu'}));
|
|
322
|
+
expect(document.querySelector('[role="dialog"]')).toBeNull();
|
|
323
|
+
expect(document.querySelector('[aria-modal="true"]')).toBeNull();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('scopes role="menu" to only menuitem children with an accessible name', async () => {
|
|
327
|
+
const user = userEvent.setup();
|
|
328
|
+
render(<TopNavHeading heading="My App" menu={menuItems} />);
|
|
329
|
+
await user.click(screen.getByRole('button', {name: 'Open menu'}));
|
|
330
|
+
const menu = document.querySelector('[role="menu"]');
|
|
331
|
+
expect(menu).not.toBeNull();
|
|
332
|
+
expect(menu).toHaveAttribute('aria-label', 'My App');
|
|
333
|
+
const children = Array.from(menu!.children);
|
|
334
|
+
expect(children.length).toBeGreaterThan(0);
|
|
335
|
+
for (const child of children) {
|
|
336
|
+
expect(child).toHaveAttribute('role', 'menuitem');
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('keeps the popup heading button outside the menu and closes on click', async () => {
|
|
341
|
+
const user = userEvent.setup();
|
|
342
|
+
render(<TopNavHeading heading="My App" menu={menuItems} />);
|
|
343
|
+
const trigger = screen.getByRole('button', {name: 'Open menu'});
|
|
344
|
+
await user.click(trigger);
|
|
345
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
346
|
+
const menu = document.querySelector('[role="menu"]');
|
|
347
|
+
expect(menu).not.toBeNull();
|
|
348
|
+
// The heading replica button in the popup is a sibling of the menu,
|
|
349
|
+
// not an invalid menu child.
|
|
350
|
+
const headingButton = Array.from(
|
|
351
|
+
document.querySelectorAll('button'),
|
|
352
|
+
).find(b => b !== trigger && b.textContent?.includes('My App'));
|
|
353
|
+
expect(headingButton).toBeDefined();
|
|
354
|
+
expect(menu!.contains(headingButton!)).toBe(false);
|
|
355
|
+
// Clicking it still closes the popup.
|
|
356
|
+
fireEvent.click(headingButton!);
|
|
357
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it('applies the same semantics in mixed mode (menu + hrefs)', async () => {
|
|
361
|
+
const user = userEvent.setup();
|
|
362
|
+
render(
|
|
363
|
+
<TopNavHeading
|
|
364
|
+
heading="Product"
|
|
365
|
+
headingHref="/product"
|
|
366
|
+
menu={menuItems}
|
|
367
|
+
/>,
|
|
368
|
+
);
|
|
369
|
+
await user.click(screen.getByRole('button', {name: 'Open menu'}));
|
|
370
|
+
expect(document.querySelector('[role="dialog"]')).toBeNull();
|
|
371
|
+
const menu = document.querySelector('[role="menu"]');
|
|
372
|
+
expect(menu).not.toBeNull();
|
|
373
|
+
expect(menu).toHaveAttribute('aria-label', 'Product');
|
|
374
|
+
for (const child of Array.from(menu!.children)) {
|
|
375
|
+
expect(child).toHaveAttribute('role', 'menuitem');
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
});
|
|
300
379
|
});
|
|
301
380
|
|
|
302
381
|
describe('NavIcon', () => {
|
|
@@ -444,4 +523,49 @@ describe('TopNavItem', () => {
|
|
|
444
523
|
expect(card).toHaveAttribute('aria-label', 'Featured');
|
|
445
524
|
});
|
|
446
525
|
});
|
|
526
|
+
|
|
527
|
+
describe('TopNavMegaMenuFeaturedCard image alt handling', () => {
|
|
528
|
+
it('marks the image as explicitly decorative when imageAlt is omitted', () => {
|
|
529
|
+
render(
|
|
530
|
+
<TopNavMegaMenuFeaturedCard
|
|
531
|
+
title="What's new"
|
|
532
|
+
image="/promo.jpg"
|
|
533
|
+
data-testid="featured-card"
|
|
534
|
+
/>,
|
|
535
|
+
);
|
|
536
|
+
const img = screen.getByTestId('featured-card').querySelector('img');
|
|
537
|
+
expect(img).toHaveAttribute('alt', '');
|
|
538
|
+
expect(img).toHaveAttribute('role', 'presentation');
|
|
539
|
+
expect(img).toHaveAttribute('aria-hidden', 'true');
|
|
540
|
+
// The image must not be exposed to assistive technology as a nameless img.
|
|
541
|
+
expect(screen.queryByRole('img')).toBeNull();
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('exposes the image with normal img semantics when imageAlt is provided', () => {
|
|
545
|
+
render(
|
|
546
|
+
<TopNavMegaMenuFeaturedCard
|
|
547
|
+
title="What's new"
|
|
548
|
+
image="/promo.jpg"
|
|
549
|
+
imageAlt="Team collaboration"
|
|
550
|
+
/>,
|
|
551
|
+
);
|
|
552
|
+
const img = screen.getByRole('img', {name: 'Team collaboration'});
|
|
553
|
+
expect(img).not.toHaveAttribute('role');
|
|
554
|
+
expect(img).not.toHaveAttribute('aria-hidden');
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('keeps title and link semantics unchanged with a decorative image', () => {
|
|
558
|
+
render(
|
|
559
|
+
<TopNavMegaMenuFeaturedCard
|
|
560
|
+
title="What's new"
|
|
561
|
+
image="/promo.jpg"
|
|
562
|
+
linkLabel="Read the announcement"
|
|
563
|
+
linkHref="/blog/v4"
|
|
564
|
+
/>,
|
|
565
|
+
);
|
|
566
|
+
expect(screen.getByText("What's new")).toBeInTheDocument();
|
|
567
|
+
const link = screen.getByRole('link', {name: /Read the announcement/});
|
|
568
|
+
expect(link).toHaveAttribute('href', '/blog/v4');
|
|
569
|
+
});
|
|
570
|
+
});
|
|
447
571
|
});
|
|
@@ -332,6 +332,10 @@ export function TopNavHeading({
|
|
|
332
332
|
|
|
333
333
|
const popover = usePopover({
|
|
334
334
|
dialogLabel: t('@astryx.topNav.heading.dialogLabel'),
|
|
335
|
+
// The popup exposes its own role="menu" semantics; a role="dialog"
|
|
336
|
+
// aria-modal wrapper would announce "dialog, Navigation menu" around a
|
|
337
|
+
// menu (the anti-pattern removed in a478a3dcf).
|
|
338
|
+
role: 'none',
|
|
335
339
|
hasCloseButton: false,
|
|
336
340
|
});
|
|
337
341
|
|
|
@@ -511,13 +515,19 @@ export function TopNavHeading({
|
|
|
511
515
|
{popover.render(
|
|
512
516
|
<div
|
|
513
517
|
ref={menuRef}
|
|
514
|
-
role="menu"
|
|
515
518
|
{...stylex.props(styles.popoverContent)}
|
|
516
519
|
{...contentProps}>
|
|
517
520
|
{popoverHeadingContent}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
+
{/* The menu role is scoped to the actual menu items so the
|
|
522
|
+
heading button above stays a valid sibling, not an invalid
|
|
523
|
+
child of a role="menu" element. */}
|
|
524
|
+
<div
|
|
525
|
+
role="menu"
|
|
526
|
+
aria-label={heading ?? t('@astryx.topNav.heading.dialogLabel')}>
|
|
527
|
+
<NavHeadingCloseContext value={closeMenuCtx}>
|
|
528
|
+
{menu}
|
|
529
|
+
</NavHeadingCloseContext>
|
|
530
|
+
</div>
|
|
521
531
|
</div>,
|
|
522
532
|
{
|
|
523
533
|
placement: 'below',
|
|
@@ -575,13 +585,19 @@ export function TopNavHeading({
|
|
|
575
585
|
{popover.render(
|
|
576
586
|
<div
|
|
577
587
|
ref={menuRef}
|
|
578
|
-
role="menu"
|
|
579
588
|
{...stylex.props(styles.popoverContent)}
|
|
580
589
|
{...contentProps}>
|
|
581
590
|
{popoverHeadingContent}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
591
|
+
{/* The menu role is scoped to the actual menu items so the
|
|
592
|
+
heading button above stays a valid sibling, not an invalid
|
|
593
|
+
child of a role="menu" element. */}
|
|
594
|
+
<div
|
|
595
|
+
role="menu"
|
|
596
|
+
aria-label={heading ?? t('@astryx.topNav.heading.dialogLabel')}>
|
|
597
|
+
<NavHeadingCloseContext value={closeMenuCtx}>
|
|
598
|
+
{menu}
|
|
599
|
+
</NavHeadingCloseContext>
|
|
600
|
+
</div>
|
|
585
601
|
</div>,
|
|
586
602
|
{
|
|
587
603
|
placement: 'below',
|