@astryxdesign/core 0.1.8 → 0.1.9
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 +18 -2
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +63 -7
- 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/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +31 -2
- 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 +31 -2
- 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 +35 -3
- 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/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/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 +8 -1
- 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/DateInput/DateInput.d.ts +47 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +26 -2
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +10 -1
- 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/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 +42 -15
- package/dist/FieldStatus/FieldStatus.d.ts +8 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +22 -4
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +10 -2
- 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/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.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +39 -12
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NumberInput/NumberInput.d.ts.map +1 -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/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/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.map +1 -1
- package/dist/Selector/Selector.js +4 -2
- 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/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +3 -2
- 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/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/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.map +1 -1
- package/dist/TimeInput/TimeInput.js +15 -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 +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +16 -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 +27 -7
- 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/astryx.css +28 -18
- 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/useDevWarning.d.ts +18 -0
- package/dist/hooks/useDevWarning.d.ts.map +1 -0
- package/dist/hooks/useDevWarning.js +49 -0
- 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/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- 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 +24 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +18 -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 +15 -3
- package/src/Avatar/Avatar.test.tsx +156 -1
- package/src/Avatar/Avatar.tsx +96 -4
- 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/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +47 -3
- 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 +25 -1
- 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 +49 -3
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +4 -1
- package/src/Chat/ChatLayout.tsx +3 -1
- 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 +3 -1
- 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 +9 -1
- 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/ContextMenu/ContextMenu.test.tsx +193 -0
- package/src/DateInput/DateInput.doc.mjs +16 -0
- package/src/DateInput/DateInput.test.tsx +108 -0
- package/src/DateInput/DateInput.tsx +68 -3
- package/src/DateInput/index.ts +1 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +35 -0
- package/src/DateTimeInput/DateTimeInput.tsx +14 -2
- 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/DropdownMenuRadioGroup.tsx +1 -2
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +6 -5
- package/src/Field/FieldLabel.tsx +8 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +78 -40
- package/src/FieldStatus/FieldStatus.tsx +22 -4
- package/src/FileInput/FileInput.test.tsx +52 -3
- package/src/FileInput/FileInput.tsx +13 -2
- 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/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 +4 -2
- package/src/MultiSelector/MultiSelector.test.tsx +172 -3
- package/src/MultiSelector/MultiSelector.tsx +55 -12
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NumberInput/NumberInput.test.tsx +11 -7
- package/src/NumberInput/NumberInput.tsx +1 -2
- 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/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +14 -0
- package/src/PowerSearch/PowerSearch.test.tsx +20 -0
- 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.test.tsx +69 -0
- package/src/Selector/Selector.tsx +5 -1
- 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/Table/BaseTable.tsx +3 -5
- 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/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.test.tsx +9 -1
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +141 -41
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.test.tsx +76 -1
- package/src/TimeInput/TimeInput.tsx +19 -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 +15 -1
- package/src/Tokenizer/Tokenizer.test.tsx +183 -2
- package/src/Tokenizer/Tokenizer.tsx +16 -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 +51 -11
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- 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/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- package/src/i18n/resolve.ts +9 -21
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/generateThemeRules.test.ts +65 -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
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
4
|
-
import {render, screen, waitFor} from '@testing-library/react';
|
|
3
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
4
|
+
import {render, screen, waitFor, fireEvent} from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
import {Breadcrumbs} from './Breadcrumbs';
|
|
7
7
|
import {BreadcrumbItem} from './BreadcrumbItem';
|
|
8
|
+
import {
|
|
9
|
+
BreadcrumbMenuItem,
|
|
10
|
+
BreadcrumbMenuCheckboxItem,
|
|
11
|
+
BreadcrumbMenuRadioGroup,
|
|
12
|
+
BreadcrumbMenuRadioItem,
|
|
13
|
+
} from './index';
|
|
14
|
+
import type {BreadcrumbMenuOption} from './index';
|
|
8
15
|
import {LinkProvider} from '../Link/LinkProvider';
|
|
9
16
|
|
|
10
17
|
function CustomLink({
|
|
@@ -359,3 +366,278 @@ describe('BreadcrumbItem', () => {
|
|
|
359
366
|
expect(current.tagName).toBe('SPAN');
|
|
360
367
|
});
|
|
361
368
|
});
|
|
369
|
+
|
|
370
|
+
describe('BreadcrumbItem menu', () => {
|
|
371
|
+
// Mock the native Popover API — jsdom doesn't implement showPopover/
|
|
372
|
+
// hidePopover or the :popover-open match. Mirrors DropdownMenu's test setup.
|
|
373
|
+
beforeEach(() => {
|
|
374
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
375
|
+
this.setAttribute('popover-open', '');
|
|
376
|
+
const event = new Event('toggle', {bubbles: false});
|
|
377
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
378
|
+
this.dispatchEvent(event);
|
|
379
|
+
});
|
|
380
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
381
|
+
this.removeAttribute('popover-open');
|
|
382
|
+
const event = new Event('toggle', {bubbles: false});
|
|
383
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
384
|
+
this.dispatchEvent(event);
|
|
385
|
+
});
|
|
386
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
387
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
388
|
+
(HTMLElement.prototype as any).matches = function (
|
|
389
|
+
selector: string,
|
|
390
|
+
): boolean {
|
|
391
|
+
if (selector === ':popover-open') {
|
|
392
|
+
return this.hasAttribute('popover-open');
|
|
393
|
+
}
|
|
394
|
+
return originalMatches.call(this, selector);
|
|
395
|
+
};
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
const items: BreadcrumbMenuOption[] = [
|
|
399
|
+
{label: 'Design', onClick: vi.fn()},
|
|
400
|
+
{label: 'Engineering', onClick: vi.fn()},
|
|
401
|
+
{type: 'divider'},
|
|
402
|
+
{label: 'Data', onClick: vi.fn()},
|
|
403
|
+
];
|
|
404
|
+
|
|
405
|
+
it('renders as a menu trigger button with aria-haspopup="menu"', () => {
|
|
406
|
+
render(
|
|
407
|
+
<Breadcrumbs>
|
|
408
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
409
|
+
<BreadcrumbItem menu={items}>Teams</BreadcrumbItem>
|
|
410
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
411
|
+
</Breadcrumbs>,
|
|
412
|
+
);
|
|
413
|
+
const trigger = screen.getByRole('button', {name: 'Teams'});
|
|
414
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'menu');
|
|
415
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('portability: a DropdownMenuOption[] renders its items on open', async () => {
|
|
419
|
+
const user = userEvent.setup();
|
|
420
|
+
render(
|
|
421
|
+
<Breadcrumbs>
|
|
422
|
+
<BreadcrumbItem menu={items}>Teams</BreadcrumbItem>
|
|
423
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
424
|
+
</Breadcrumbs>,
|
|
425
|
+
);
|
|
426
|
+
await user.click(screen.getByRole('button', {name: 'Teams'}));
|
|
427
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
428
|
+
expect(menu).toHaveAttribute('aria-label', 'Teams');
|
|
429
|
+
expect(
|
|
430
|
+
screen.getByRole('menuitem', {name: 'Design', hidden: true}),
|
|
431
|
+
).toBeInTheDocument();
|
|
432
|
+
expect(
|
|
433
|
+
screen.getByRole('menuitem', {name: 'Engineering', hidden: true}),
|
|
434
|
+
).toBeInTheDocument();
|
|
435
|
+
expect(
|
|
436
|
+
screen.getByRole('menuitem', {name: 'Data', hidden: true}),
|
|
437
|
+
).toBeInTheDocument();
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('fires the item onClick and closes the menu on select', async () => {
|
|
441
|
+
const user = userEvent.setup();
|
|
442
|
+
const onDesign = vi.fn();
|
|
443
|
+
render(
|
|
444
|
+
<Breadcrumbs>
|
|
445
|
+
<BreadcrumbItem menu={[{label: 'Design', onClick: onDesign}]}>
|
|
446
|
+
Teams
|
|
447
|
+
</BreadcrumbItem>
|
|
448
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
449
|
+
</Breadcrumbs>,
|
|
450
|
+
);
|
|
451
|
+
await user.click(screen.getByRole('button', {name: 'Teams'}));
|
|
452
|
+
await user.click(
|
|
453
|
+
screen.getByRole('menuitem', {name: 'Design', hidden: true}),
|
|
454
|
+
);
|
|
455
|
+
expect(onDesign).toHaveBeenCalledTimes(1);
|
|
456
|
+
expect(HTMLElement.prototype.hidePopover).toHaveBeenCalled();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('supports the composed children form', async () => {
|
|
460
|
+
const user = userEvent.setup();
|
|
461
|
+
const onOverview = vi.fn();
|
|
462
|
+
render(
|
|
463
|
+
<Breadcrumbs>
|
|
464
|
+
<BreadcrumbItem
|
|
465
|
+
menu={
|
|
466
|
+
<>
|
|
467
|
+
<BreadcrumbMenuItem label="Overview" onClick={onOverview} />
|
|
468
|
+
<BreadcrumbMenuItem label="Settings" />
|
|
469
|
+
</>
|
|
470
|
+
}>
|
|
471
|
+
Project
|
|
472
|
+
</BreadcrumbItem>
|
|
473
|
+
<BreadcrumbItem isCurrent>Current</BreadcrumbItem>
|
|
474
|
+
</Breadcrumbs>,
|
|
475
|
+
);
|
|
476
|
+
await user.click(screen.getByRole('button', {name: 'Project'}));
|
|
477
|
+
expect(
|
|
478
|
+
screen.getByRole('menuitem', {name: 'Overview', hidden: true}),
|
|
479
|
+
).toBeInTheDocument();
|
|
480
|
+
await user.click(
|
|
481
|
+
screen.getByRole('menuitem', {name: 'Overview', hidden: true}),
|
|
482
|
+
);
|
|
483
|
+
expect(onOverview).toHaveBeenCalledTimes(1);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('supports a selectable checkbox item', async () => {
|
|
487
|
+
const user = userEvent.setup();
|
|
488
|
+
const onChange = vi.fn();
|
|
489
|
+
render(
|
|
490
|
+
<Breadcrumbs>
|
|
491
|
+
<BreadcrumbItem
|
|
492
|
+
menu={
|
|
493
|
+
<BreadcrumbMenuCheckboxItem
|
|
494
|
+
label="Show archived"
|
|
495
|
+
value={false}
|
|
496
|
+
onChange={onChange}
|
|
497
|
+
/>
|
|
498
|
+
}>
|
|
499
|
+
Filters
|
|
500
|
+
</BreadcrumbItem>
|
|
501
|
+
<BreadcrumbItem isCurrent>Current</BreadcrumbItem>
|
|
502
|
+
</Breadcrumbs>,
|
|
503
|
+
);
|
|
504
|
+
await user.click(screen.getByRole('button', {name: 'Filters'}));
|
|
505
|
+
const checkbox = screen.getByRole('menuitemcheckbox', {
|
|
506
|
+
name: 'Show archived',
|
|
507
|
+
hidden: true,
|
|
508
|
+
});
|
|
509
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'false');
|
|
510
|
+
await user.click(checkbox);
|
|
511
|
+
expect(onChange).toHaveBeenCalledWith(true);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it('supports a selectable radio group', async () => {
|
|
515
|
+
const user = userEvent.setup();
|
|
516
|
+
const onChange = vi.fn();
|
|
517
|
+
render(
|
|
518
|
+
<Breadcrumbs>
|
|
519
|
+
<BreadcrumbItem
|
|
520
|
+
menu={
|
|
521
|
+
<BreadcrumbMenuRadioGroup
|
|
522
|
+
aria-label="Sort by"
|
|
523
|
+
value="name"
|
|
524
|
+
onChange={onChange}>
|
|
525
|
+
<BreadcrumbMenuRadioItem value="name" label="Name" />
|
|
526
|
+
<BreadcrumbMenuRadioItem value="date" label="Date" />
|
|
527
|
+
</BreadcrumbMenuRadioGroup>
|
|
528
|
+
}>
|
|
529
|
+
Sort
|
|
530
|
+
</BreadcrumbItem>
|
|
531
|
+
<BreadcrumbItem isCurrent>Current</BreadcrumbItem>
|
|
532
|
+
</Breadcrumbs>,
|
|
533
|
+
);
|
|
534
|
+
await user.click(screen.getByRole('button', {name: 'Sort'}));
|
|
535
|
+
const nameOption = screen.getByRole('menuitemradio', {
|
|
536
|
+
name: 'Name',
|
|
537
|
+
hidden: true,
|
|
538
|
+
});
|
|
539
|
+
expect(nameOption).toHaveAttribute('aria-checked', 'true');
|
|
540
|
+
await user.click(
|
|
541
|
+
screen.getByRole('menuitemradio', {name: 'Date', hidden: true}),
|
|
542
|
+
);
|
|
543
|
+
expect(onChange).toHaveBeenCalledWith('date');
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('opens with ArrowDown and closes with Escape, returning focus to trigger', async () => {
|
|
547
|
+
render(
|
|
548
|
+
<Breadcrumbs>
|
|
549
|
+
<BreadcrumbItem menu={items}>Teams</BreadcrumbItem>
|
|
550
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
551
|
+
</Breadcrumbs>,
|
|
552
|
+
);
|
|
553
|
+
const trigger = screen.getByRole('button', {name: 'Teams'});
|
|
554
|
+
trigger.focus();
|
|
555
|
+
fireEvent.keyDown(trigger, {key: 'ArrowDown'});
|
|
556
|
+
expect(HTMLElement.prototype.showPopover).toHaveBeenCalled();
|
|
557
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
558
|
+
await waitFor(() => {
|
|
559
|
+
expect(menu).toContainElement(
|
|
560
|
+
document.activeElement as HTMLElement | null,
|
|
561
|
+
);
|
|
562
|
+
});
|
|
563
|
+
fireEvent.keyDown(menu, {key: 'Escape'});
|
|
564
|
+
expect(HTMLElement.prototype.hidePopover).toHaveBeenCalled();
|
|
565
|
+
await waitFor(() => {
|
|
566
|
+
expect(trigger).toHaveFocus();
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it('roves focus with ArrowDown across items', async () => {
|
|
571
|
+
render(
|
|
572
|
+
<Breadcrumbs>
|
|
573
|
+
<BreadcrumbItem menu={items}>Teams</BreadcrumbItem>
|
|
574
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
575
|
+
</Breadcrumbs>,
|
|
576
|
+
);
|
|
577
|
+
const trigger = screen.getByRole('button', {name: 'Teams'});
|
|
578
|
+
trigger.focus();
|
|
579
|
+
fireEvent.keyDown(trigger, {key: 'ArrowDown'});
|
|
580
|
+
const menu = screen.getByRole('menu', {hidden: true});
|
|
581
|
+
await waitFor(() => {
|
|
582
|
+
expect(
|
|
583
|
+
screen.getByRole('menuitem', {name: 'Design', hidden: true}),
|
|
584
|
+
).toHaveFocus();
|
|
585
|
+
});
|
|
586
|
+
fireEvent.keyDown(menu, {key: 'ArrowDown'});
|
|
587
|
+
expect(
|
|
588
|
+
screen.getByRole('menuitem', {name: 'Engineering', hidden: true}),
|
|
589
|
+
).toHaveFocus();
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
it('allows menu together with isCurrent (both aria-current and aria-haspopup)', () => {
|
|
593
|
+
render(
|
|
594
|
+
<Breadcrumbs>
|
|
595
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
596
|
+
<BreadcrumbItem isCurrent menu={items}>
|
|
597
|
+
Teams
|
|
598
|
+
</BreadcrumbItem>
|
|
599
|
+
</Breadcrumbs>,
|
|
600
|
+
);
|
|
601
|
+
const trigger = screen.getByRole('button', {name: 'Teams'});
|
|
602
|
+
expect(trigger).toHaveAttribute('aria-current', 'page');
|
|
603
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'menu');
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
it('warns and lets menu win when href is also provided', () => {
|
|
607
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
608
|
+
render(
|
|
609
|
+
<Breadcrumbs>
|
|
610
|
+
<BreadcrumbItem href="/teams" menu={items}>
|
|
611
|
+
Teams
|
|
612
|
+
</BreadcrumbItem>
|
|
613
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
614
|
+
</Breadcrumbs>,
|
|
615
|
+
);
|
|
616
|
+
// menu wins: it's a button trigger, not a link.
|
|
617
|
+
expect(screen.getByRole('button', {name: 'Teams'})).toHaveAttribute(
|
|
618
|
+
'aria-haspopup',
|
|
619
|
+
'menu',
|
|
620
|
+
);
|
|
621
|
+
expect(screen.queryByRole('link', {name: 'Teams'})).not.toBeInTheDocument();
|
|
622
|
+
expect(warn).toHaveBeenCalledWith(
|
|
623
|
+
expect.stringContaining('`menu` and `href` are mutually exclusive'),
|
|
624
|
+
);
|
|
625
|
+
warn.mockRestore();
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it('keeps mid-trail separators intact around a menu crumb', () => {
|
|
629
|
+
const {container} = render(
|
|
630
|
+
<Breadcrumbs>
|
|
631
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
632
|
+
<BreadcrumbItem menu={items}>Teams</BreadcrumbItem>
|
|
633
|
+
<BreadcrumbItem isCurrent>Overview</BreadcrumbItem>
|
|
634
|
+
</Breadcrumbs>,
|
|
635
|
+
);
|
|
636
|
+
// One separator per item (first hidden via CSS); the menu crumb does not
|
|
637
|
+
// add or drop any.
|
|
638
|
+
const separators = container.querySelectorAll(
|
|
639
|
+
'ol > li > span[aria-hidden="true"]',
|
|
640
|
+
);
|
|
641
|
+
expect(separators).toHaveLength(3);
|
|
642
|
+
});
|
|
643
|
+
});
|
package/src/Breadcrumbs/index.ts
CHANGED
|
@@ -14,3 +14,30 @@ export type {
|
|
|
14
14
|
} from './Breadcrumbs';
|
|
15
15
|
export {BreadcrumbItem} from './BreadcrumbItem';
|
|
16
16
|
export type {BreadcrumbItemProps} from './BreadcrumbItem';
|
|
17
|
+
|
|
18
|
+
// The breadcrumb `menu` prop reuses the DropdownMenu item API, so the item
|
|
19
|
+
// components are re-exported under `Breadcrumb*` aliases for family coherence
|
|
20
|
+
// and discoverability (mirroring ContextMenu). A consumer's existing
|
|
21
|
+
// DropdownMenu item definitions are portable into a breadcrumb menu verbatim.
|
|
22
|
+
export {
|
|
23
|
+
DropdownMenuItem as BreadcrumbMenuItem,
|
|
24
|
+
type DropdownMenuItemProps as BreadcrumbMenuItemProps,
|
|
25
|
+
} from '../DropdownMenu/DropdownMenuItem';
|
|
26
|
+
export {
|
|
27
|
+
DropdownMenuCheckboxItem as BreadcrumbMenuCheckboxItem,
|
|
28
|
+
type DropdownMenuCheckboxItemProps as BreadcrumbMenuCheckboxItemProps,
|
|
29
|
+
} from '../DropdownMenu/DropdownMenuCheckboxItem';
|
|
30
|
+
export {
|
|
31
|
+
DropdownMenuRadioGroup as BreadcrumbMenuRadioGroup,
|
|
32
|
+
type DropdownMenuRadioGroupProps as BreadcrumbMenuRadioGroupProps,
|
|
33
|
+
} from '../DropdownMenu/DropdownMenuRadioGroup';
|
|
34
|
+
export {
|
|
35
|
+
DropdownMenuRadioItem as BreadcrumbMenuRadioItem,
|
|
36
|
+
type DropdownMenuRadioItemProps as BreadcrumbMenuRadioItemProps,
|
|
37
|
+
} from '../DropdownMenu/DropdownMenuRadioItem';
|
|
38
|
+
export type {
|
|
39
|
+
DropdownMenuOption as BreadcrumbMenuOption,
|
|
40
|
+
DropdownMenuItemData as BreadcrumbMenuItemData,
|
|
41
|
+
DropdownMenuDivider as BreadcrumbMenuDivider,
|
|
42
|
+
DropdownMenuSection as BreadcrumbMenuSection,
|
|
43
|
+
} from '../DropdownMenu/DropdownMenu';
|
|
@@ -51,6 +51,13 @@ export const docs = {
|
|
|
51
51
|
description: 'Size variant.',
|
|
52
52
|
default: "'md'",
|
|
53
53
|
},
|
|
54
|
+
{
|
|
55
|
+
name: 'elevation',
|
|
56
|
+
type: "'none' | 'low' | 'med' | 'high'",
|
|
57
|
+
description:
|
|
58
|
+
'Resting shadow depth for floating buttons (e.g. a FAB). `none` is the default flat button; `low`/`med`/`high` map to the shadow token scale. Ignored inside a ButtonGroup, where elevation is owned by the group.',
|
|
59
|
+
default: "'none'",
|
|
60
|
+
},
|
|
54
61
|
{
|
|
55
62
|
name: 'type',
|
|
56
63
|
type: "'button' | 'submit' | 'reset'",
|
|
@@ -199,6 +206,7 @@ export const docsZh = {
|
|
|
199
206
|
default: "'secondary'",
|
|
200
207
|
},
|
|
201
208
|
{name: 'size', type: "'sm' | 'md' | 'lg'", description: '尺寸变体。', default: "'md'"},
|
|
209
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '浮动按钮(如 FAB)的静止阴影深度。`none` 为默认扁平按钮;在 ButtonGroup 内忽略。', default: "'none'"},
|
|
202
210
|
{name: 'type', type: "'button' | 'submit' | 'reset'", description: 'HTML 按钮类型属性。', default: "'button'"},
|
|
203
211
|
{name: 'name', type: 'string', description: '表单提交的 HTML name 属性。'},
|
|
204
212
|
{name: 'value', type: 'string | number | readonly string[]', description: '表单提交的 HTML value 属性。'},
|
|
@@ -271,6 +279,7 @@ export const docsDense = {
|
|
|
271
279
|
label: 'accessible label; visible text by default, aria-label when isIconOnly',
|
|
272
280
|
variant: 'visual style variant',
|
|
273
281
|
size: 'size variant',
|
|
282
|
+
elevation: 'resting shadow depth for floating buttons/FABs: none|low|med|high; ignored inside ButtonGroup',
|
|
274
283
|
type: 'HTML button type; defaults to "button"',
|
|
275
284
|
name: 'HTML name for form submission',
|
|
276
285
|
displayName: 'HTML name for form submission',
|
|
@@ -445,4 +445,53 @@ describe('Button', () => {
|
|
|
445
445
|
rerender(<Button label="Submit" isLoading />);
|
|
446
446
|
expect(liveRegion).toHaveTextContent('Loading');
|
|
447
447
|
});
|
|
448
|
+
|
|
449
|
+
describe('elevation', () => {
|
|
450
|
+
it('renders a distinct class for each elevation level', () => {
|
|
451
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
452
|
+
const {container} = render(
|
|
453
|
+
<Button label="Save" elevation={elevation} />,
|
|
454
|
+
);
|
|
455
|
+
return container.querySelector('button')!.className;
|
|
456
|
+
};
|
|
457
|
+
const classes = new Set([
|
|
458
|
+
classFor('none'),
|
|
459
|
+
classFor('low'),
|
|
460
|
+
classFor('med'),
|
|
461
|
+
classFor('high'),
|
|
462
|
+
]);
|
|
463
|
+
expect(classes.size).toBe(4);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it('defaults to flat (elevation none)', () => {
|
|
467
|
+
const {container: def} = render(<Button label="Save" />);
|
|
468
|
+
const {container: none} = render(
|
|
469
|
+
<Button label="Save" elevation="none" />,
|
|
470
|
+
);
|
|
471
|
+
expect(def.querySelector('button')!.className).toBe(
|
|
472
|
+
none.querySelector('button')!.className,
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('exposes aria-busy on the link-rendered button while loading', () => {
|
|
478
|
+
// Non-interruptible loading disables the button, which falls back to
|
|
479
|
+
// <button> rendering — so an anchor only shows loading when interruptible.
|
|
480
|
+
render(
|
|
481
|
+
<Button
|
|
482
|
+
label="Docs"
|
|
483
|
+
href="https://example.com"
|
|
484
|
+
isLoading
|
|
485
|
+
isInterruptible
|
|
486
|
+
/>,
|
|
487
|
+
);
|
|
488
|
+
const link = screen.getByRole('link');
|
|
489
|
+
expect(link).toHaveAttribute('aria-busy', 'true');
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('does not set aria-busy on the link-rendered button when not loading', () => {
|
|
493
|
+
render(<Button label="Docs" href="https://example.com" />);
|
|
494
|
+
const link = screen.getByRole('link');
|
|
495
|
+
expect(link).not.toHaveAttribute('aria-busy');
|
|
496
|
+
});
|
|
448
497
|
});
|
package/src/Button/Button.tsx
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import {useRef, useTransition, type ReactNode} from 'react';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
|
-
import type {SizeValue} from '../utils/types';
|
|
23
|
+
import type {Elevation, SizeValue} from '../utils/types';
|
|
24
24
|
import * as stylex from '@stylexjs/stylex';
|
|
25
25
|
import {useTooltip} from '../Tooltip/useTooltip';
|
|
26
26
|
import {
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
easeVars,
|
|
34
34
|
fontWeightVars,
|
|
35
35
|
typeScaleVars,
|
|
36
|
+
shadowVars,
|
|
36
37
|
} from '../theme/tokens.stylex';
|
|
37
38
|
import {Spinner} from '../Spinner';
|
|
38
39
|
import {VisuallyHidden} from '../VisuallyHidden';
|
|
@@ -160,6 +161,18 @@ const iconSizeStyles = stylex.create({
|
|
|
160
161
|
lg: {width: 20, height: 20, fontSize: 20},
|
|
161
162
|
});
|
|
162
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Resting elevation for floating buttons (e.g. a FAB). `none` is the default
|
|
166
|
+
* flat button; `low`/`med`/`high` map to the shadow token scale. 'none' stays
|
|
167
|
+
* a literal so it never conflicts with a variant's background layering.
|
|
168
|
+
*/
|
|
169
|
+
const elevationStyles = stylex.create({
|
|
170
|
+
none: {boxShadow: 'none'},
|
|
171
|
+
low: {boxShadow: shadowVars['--shadow-low']},
|
|
172
|
+
med: {boxShadow: shadowVars['--shadow-med']},
|
|
173
|
+
high: {boxShadow: shadowVars['--shadow-high']},
|
|
174
|
+
});
|
|
175
|
+
|
|
163
176
|
/**
|
|
164
177
|
* Variant styles using backgroundImage for layered colors
|
|
165
178
|
* Pseudo-classes are nested within properties per StyleX recommendation
|
|
@@ -307,6 +320,12 @@ export interface ButtonProps extends BaseProps<HTMLButtonElement> {
|
|
|
307
320
|
* @default 'md'
|
|
308
321
|
*/
|
|
309
322
|
size?: ButtonSize;
|
|
323
|
+
/**
|
|
324
|
+
* Resting elevation — the shadow depth the button sits at. Use for floating
|
|
325
|
+
* buttons (FABs) that hover above content. `none` is the default flat button.
|
|
326
|
+
* @default 'none'
|
|
327
|
+
*/
|
|
328
|
+
elevation?: Elevation;
|
|
310
329
|
/**
|
|
311
330
|
* Whether the button is disabled.
|
|
312
331
|
* @default false
|
|
@@ -578,6 +597,7 @@ export function Button({
|
|
|
578
597
|
icon,
|
|
579
598
|
isIconOnly = false,
|
|
580
599
|
width,
|
|
600
|
+
elevation = 'none',
|
|
581
601
|
children,
|
|
582
602
|
endContent,
|
|
583
603
|
tooltip,
|
|
@@ -691,6 +711,9 @@ export function Button({
|
|
|
691
711
|
(buttonGroup.orientation === 'horizontal'
|
|
692
712
|
? groupStyles.onSolidHorizontal
|
|
693
713
|
: groupStyles.onSolidVertical),
|
|
714
|
+
// Standalone floating buttons only — a grouped button's elevation is owned
|
|
715
|
+
// by the ButtonGroup so the shared surface lifts as one unit.
|
|
716
|
+
!buttonGroup && elevationStyles[elevation],
|
|
694
717
|
width != null && dynamicStyles.width(width),
|
|
695
718
|
xstyle,
|
|
696
719
|
);
|
|
@@ -786,6 +809,7 @@ export function Button({
|
|
|
786
809
|
{...ariaLabelProp}
|
|
787
810
|
{...describedByProp}
|
|
788
811
|
{...edgeCompAttr}
|
|
812
|
+
aria-busy={isLoadingState || undefined}
|
|
789
813
|
onClick={handleClick}>
|
|
790
814
|
{buttonContent}
|
|
791
815
|
</LinkComponent>
|
|
@@ -29,6 +29,7 @@ export const docs = {
|
|
|
29
29
|
{name: 'orientation', type: "'horizontal' | 'vertical'", description: 'Layout direction of the button group.', default: "'horizontal'"},
|
|
30
30
|
{name: 'size', type: "'sm' | 'md' | 'lg'", description: 'Default size for buttons in the group. Individual buttons can override.', default: "'md'"},
|
|
31
31
|
{name: 'isDisabled', type: 'boolean', description: 'Whether all buttons in the group are disabled.', default: 'false'},
|
|
32
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: 'Resting shadow depth for the whole group. The connected buttons share one surface, so the shadow lifts them as a unit. Use for a group that floats above content.', default: "'none'"},
|
|
32
33
|
{name: 'ref', type: 'React.Ref<HTMLDivElement>', description: 'Ref forwarded to the root element.'},
|
|
33
34
|
{name: 'xstyle', type: 'StyleXStyles', description: 'StyleX styles for layout customization. Must be a stylex.create() value.'},
|
|
34
35
|
{name: 'data-testid', type: 'string', description: 'Test selector for automated testing frameworks.'},
|
|
@@ -66,6 +67,7 @@ export const docsZh = {
|
|
|
66
67
|
orientation: '按钮组的布局方向。',
|
|
67
68
|
size: '组内按钮的默认尺寸。单个按钮可覆盖。',
|
|
68
69
|
isDisabled: '组内所有按钮是否禁用。',
|
|
70
|
+
elevation: '整个组的静止阴影深度。连接的按钮共享一个表面,阴影将它们作为整体抬起。',
|
|
69
71
|
ref: '转发到根元素的引用。',
|
|
70
72
|
xstyle: 'StyleX 样式,用于布局自定义。必须是 stylex.create() 的值。',
|
|
71
73
|
'data-testid': '自动化测试的选择器。',
|
|
@@ -116,6 +118,7 @@ export const docsDense = {
|
|
|
116
118
|
orientation: 'layout direction',
|
|
117
119
|
size: 'default btn size; individual btns override',
|
|
118
120
|
isDisabled: 'all btns disabled',
|
|
121
|
+
elevation: 'resting shadow depth for whole group: none|low|med|high',
|
|
119
122
|
xstyle: 'StyleX layout styles; must be stylex.create() value',
|
|
120
123
|
'data-testid': 'test selector',
|
|
121
124
|
},
|
|
@@ -572,4 +572,41 @@ describe('ButtonGroup', () => {
|
|
|
572
572
|
expect(hasRoundedTrailingCorners(save)).toBe(false);
|
|
573
573
|
});
|
|
574
574
|
});
|
|
575
|
+
|
|
576
|
+
describe('elevation', () => {
|
|
577
|
+
it('renders a distinct class on the group for each elevation level', () => {
|
|
578
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
579
|
+
const {container} = render(
|
|
580
|
+
<ButtonGroup label="Actions" elevation={elevation}>
|
|
581
|
+
<Button label="One" />
|
|
582
|
+
<Button label="Two" />
|
|
583
|
+
</ButtonGroup>,
|
|
584
|
+
);
|
|
585
|
+
return container.querySelector('[role="group"]')!.className;
|
|
586
|
+
};
|
|
587
|
+
const classes = new Set([
|
|
588
|
+
classFor('none'),
|
|
589
|
+
classFor('low'),
|
|
590
|
+
classFor('med'),
|
|
591
|
+
classFor('high'),
|
|
592
|
+
]);
|
|
593
|
+
expect(classes.size).toBe(4);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('defaults to flat (elevation none)', () => {
|
|
597
|
+
const {container: def} = render(
|
|
598
|
+
<ButtonGroup label="Actions">
|
|
599
|
+
<Button label="One" />
|
|
600
|
+
</ButtonGroup>,
|
|
601
|
+
);
|
|
602
|
+
const {container: none} = render(
|
|
603
|
+
<ButtonGroup label="Actions" elevation="none">
|
|
604
|
+
<Button label="One" />
|
|
605
|
+
</ButtonGroup>,
|
|
606
|
+
);
|
|
607
|
+
expect(def.querySelector('[role="group"]')!.className).toBe(
|
|
608
|
+
none.querySelector('[role="group"]')!.className,
|
|
609
|
+
);
|
|
610
|
+
});
|
|
611
|
+
});
|
|
575
612
|
});
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
import {useMemo, type ReactNode} from 'react';
|
|
25
25
|
import * as stylex from '@stylexjs/stylex';
|
|
26
26
|
import type {ButtonSize} from '../Button';
|
|
27
|
+
import {radiusVars, shadowVars} from '../theme/tokens.stylex';
|
|
28
|
+
import type {Elevation} from '../utils/types';
|
|
27
29
|
import {SizeProvider, useSize} from '../SizeContext/SizeContext';
|
|
28
30
|
import {useListFocus} from '../hooks/useListFocus';
|
|
29
31
|
import {mergeProps, mergeRefs, composeEventHandlers} from '../utils';
|
|
@@ -63,6 +65,14 @@ export interface ButtonGroupProps extends BaseProps<HTMLDivElement> {
|
|
|
63
65
|
*/
|
|
64
66
|
size?: ButtonSize;
|
|
65
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Resting elevation for the group. The connected buttons share one surface,
|
|
70
|
+
* so the shadow sits on the group and lifts them together. Use for a floating
|
|
71
|
+
* group of actions above content.
|
|
72
|
+
* @default 'none'
|
|
73
|
+
*/
|
|
74
|
+
elevation?: Elevation;
|
|
75
|
+
|
|
66
76
|
/**
|
|
67
77
|
* Whether all buttons in the group are disabled.
|
|
68
78
|
* @default false
|
|
@@ -89,6 +99,26 @@ const styles = stylex.create({
|
|
|
89
99
|
},
|
|
90
100
|
});
|
|
91
101
|
|
|
102
|
+
// Resting elevation for the whole group — the connected buttons share one
|
|
103
|
+
// surface, so the shadow sits on the group wrapper and lifts them as a unit.
|
|
104
|
+
// The wrapper takes the element radius so the shadow follows the group's
|
|
105
|
+
// rounded outer corners rather than a bare rectangle. 'none' is the default.
|
|
106
|
+
const elevationStyles = stylex.create({
|
|
107
|
+
none: {boxShadow: 'none'},
|
|
108
|
+
low: {
|
|
109
|
+
boxShadow: shadowVars['--shadow-low'],
|
|
110
|
+
borderRadius: radiusVars['--radius-element'],
|
|
111
|
+
},
|
|
112
|
+
med: {
|
|
113
|
+
boxShadow: shadowVars['--shadow-med'],
|
|
114
|
+
borderRadius: radiusVars['--radius-element'],
|
|
115
|
+
},
|
|
116
|
+
high: {
|
|
117
|
+
boxShadow: shadowVars['--shadow-high'],
|
|
118
|
+
borderRadius: radiusVars['--radius-element'],
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
92
122
|
// =============================================================================
|
|
93
123
|
// Component
|
|
94
124
|
// =============================================================================
|
|
@@ -129,6 +159,7 @@ export function ButtonGroup({
|
|
|
129
159
|
orientation = 'horizontal',
|
|
130
160
|
size: sizeProp,
|
|
131
161
|
isDisabled = false,
|
|
162
|
+
elevation = 'none',
|
|
132
163
|
xstyle,
|
|
133
164
|
className,
|
|
134
165
|
style,
|
|
@@ -160,6 +191,7 @@ export function ButtonGroup({
|
|
|
160
191
|
stylex.props(
|
|
161
192
|
styles.group,
|
|
162
193
|
orientation === 'vertical' && styles.vertical,
|
|
194
|
+
elevationStyles[elevation],
|
|
163
195
|
xstyle,
|
|
164
196
|
),
|
|
165
197
|
className,
|
|
@@ -111,7 +111,8 @@ export const docs = {
|
|
|
111
111
|
theming: {
|
|
112
112
|
targets: [
|
|
113
113
|
{className: 'astryx-calendar', visualProps: ['mode']},
|
|
114
|
-
{className: 'astryx-calendar-
|
|
114
|
+
{className: 'astryx-calendar-nav', visualProps: ['nav'], states: ['disabled']},
|
|
115
|
+
{className: 'astryx-calendar-day', states: ['selected', 'today', 'disabled', 'in-range', 'marker']},
|
|
115
116
|
],
|
|
116
117
|
},
|
|
117
118
|
};
|
|
@@ -157,6 +158,15 @@ export const docsZh = {
|
|
|
157
158
|
'mode',
|
|
158
159
|
],
|
|
159
160
|
},
|
|
161
|
+
{
|
|
162
|
+
className: 'astryx-calendar-nav',
|
|
163
|
+
visualProps: [
|
|
164
|
+
'nav',
|
|
165
|
+
],
|
|
166
|
+
states: [
|
|
167
|
+
'disabled',
|
|
168
|
+
],
|
|
169
|
+
},
|
|
160
170
|
{
|
|
161
171
|
className: 'astryx-calendar-day',
|
|
162
172
|
states: [
|
|
@@ -164,6 +174,7 @@ export const docsZh = {
|
|
|
164
174
|
'today',
|
|
165
175
|
'disabled',
|
|
166
176
|
'in-range',
|
|
177
|
+
'marker',
|
|
167
178
|
],
|
|
168
179
|
},
|
|
169
180
|
],
|