@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
|
@@ -7,14 +7,22 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'CheckboxList',
|
|
8
8
|
displayName: 'Checkbox List Item',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Individual checkbox item with label, description, and end content slot. Works in collection mode (inside CheckboxList) or standalone mode (inside List).',
|
|
11
12
|
props: [
|
|
12
13
|
{
|
|
13
14
|
name: 'label',
|
|
14
|
-
type: '
|
|
15
|
-
description:
|
|
15
|
+
type: 'ReactNode',
|
|
16
|
+
description:
|
|
17
|
+
'Primary text label for the item. A plain string names the checkbox automatically; a rich (ReactNode) label should be paired with aria-label so screen readers get a concise name.',
|
|
16
18
|
required: true,
|
|
17
19
|
},
|
|
20
|
+
{
|
|
21
|
+
name: 'aria-label',
|
|
22
|
+
type: 'string',
|
|
23
|
+
description:
|
|
24
|
+
'Plain-text accessible name for the checkbox when label is a ReactNode. Applied to the checkbox control. Without it, rich-label items all announce as the generic "Checkbox" to screen readers.',
|
|
25
|
+
},
|
|
18
26
|
{
|
|
19
27
|
name: 'value',
|
|
20
28
|
type: 'string',
|
|
@@ -69,13 +77,24 @@ export const docs = {
|
|
|
69
77
|
description: 'Direct check handler (standalone mode only).',
|
|
70
78
|
},
|
|
71
79
|
],
|
|
80
|
+
examples: [
|
|
81
|
+
{
|
|
82
|
+
label: 'Rich label with an accessible name',
|
|
83
|
+
code: `<CheckboxListItem
|
|
84
|
+
label={<span>Pro plan <Badge label="Recommended" /></span>}
|
|
85
|
+
aria-label="Pro plan"
|
|
86
|
+
value="pro"
|
|
87
|
+
/>`,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
72
90
|
};
|
|
73
91
|
|
|
74
92
|
export const docsZh = {
|
|
75
93
|
name: 'CheckboxListItem',
|
|
76
94
|
isHiddenFromOverview: true,
|
|
77
95
|
displayName: 'Checkbox List Item',
|
|
78
|
-
description:
|
|
96
|
+
description:
|
|
97
|
+
'单个复选框选项,包含标签、描述和尾部内容插槽。可在集合模式或独立模式下使用。',
|
|
79
98
|
props: [
|
|
80
99
|
{
|
|
81
100
|
name: 'label',
|
|
@@ -83,6 +102,12 @@ export const docsZh = {
|
|
|
83
102
|
description: '选项的主要文本标签。',
|
|
84
103
|
required: true,
|
|
85
104
|
},
|
|
105
|
+
{
|
|
106
|
+
name: 'aria-label',
|
|
107
|
+
type: 'string',
|
|
108
|
+
description:
|
|
109
|
+
'当 label 是 ReactNode 时,复选框的纯文本无障碍名称。缺少它时,富标签选项都会向屏幕阅读器播报为通用的 "Checkbox"。',
|
|
110
|
+
},
|
|
86
111
|
{
|
|
87
112
|
name: 'value',
|
|
88
113
|
type: 'string',
|
|
@@ -128,9 +153,12 @@ export const docsDense = {
|
|
|
128
153
|
name: 'CheckboxListItem',
|
|
129
154
|
isHiddenFromOverview: true,
|
|
130
155
|
displayName: 'Checkbox List Item',
|
|
131
|
-
description:
|
|
156
|
+
description:
|
|
157
|
+
'Individual checkbox item w/ label, description, end content slot.',
|
|
132
158
|
propDescriptions: {
|
|
133
159
|
label: 'Primary text label for item.',
|
|
160
|
+
'aria-label':
|
|
161
|
+
'Plain-text checkbox name when label is a ReactNode. Without it, rich-label items all announce as "Checkbox".',
|
|
134
162
|
value: 'Identity key (required inside CheckboxList).',
|
|
135
163
|
description: 'Secondary text below label.',
|
|
136
164
|
endContent: 'Content rendered after label area.',
|
|
@@ -22,6 +22,7 @@ import type {StyleXStyles} from '@stylexjs/stylex';
|
|
|
22
22
|
import {colorVars} from '../theme/tokens.stylex';
|
|
23
23
|
import type {BaseProps} from '../BaseProps';
|
|
24
24
|
import {composeEventHandlers} from '../utils';
|
|
25
|
+
import {useDevWarning} from '../hooks/useDevWarning';
|
|
25
26
|
import {CheckboxInput} from '../CheckboxInput/CheckboxInput';
|
|
26
27
|
import {ListItem} from '../List/ListItem';
|
|
27
28
|
import {ListContext} from '../List/ListContext';
|
|
@@ -51,6 +52,25 @@ export interface CheckboxListItemProps extends BaseProps<HTMLLIElement> {
|
|
|
51
52
|
* child components control their own text behavior).
|
|
52
53
|
*/
|
|
53
54
|
label: ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* Plain-text accessible name for the checkbox when `label` is a ReactNode.
|
|
57
|
+
*
|
|
58
|
+
* A string `label` names the checkbox automatically. A rich (ReactNode)
|
|
59
|
+
* `label` cannot, so pass a concise string equivalent via the standard
|
|
60
|
+
* `aria-label` — otherwise the checkbox falls back to the generic name
|
|
61
|
+
* "Checkbox" and every rich-label item in a list announces identically to
|
|
62
|
+
* screen readers. Applied to the checkbox control, not the row.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```
|
|
66
|
+
* <CheckboxListItem
|
|
67
|
+
* label={<span>Pro plan <Badge label="Recommended" /></span>}
|
|
68
|
+
* aria-label="Pro plan"
|
|
69
|
+
* value="pro"
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
'aria-label'?: string;
|
|
54
74
|
/**
|
|
55
75
|
* Identity key for collection mode (REQUIRED inside CheckboxList).
|
|
56
76
|
* Throws a runtime error if missing when used inside CheckboxList.
|
|
@@ -119,6 +139,7 @@ export interface CheckboxListItemProps extends BaseProps<HTMLLIElement> {
|
|
|
119
139
|
*/
|
|
120
140
|
export function CheckboxListItem({
|
|
121
141
|
label,
|
|
142
|
+
'aria-label': ariaLabel,
|
|
122
143
|
value,
|
|
123
144
|
description,
|
|
124
145
|
endContent,
|
|
@@ -142,6 +163,25 @@ export function CheckboxListItem({
|
|
|
142
163
|
);
|
|
143
164
|
}
|
|
144
165
|
|
|
166
|
+
// Accessible name for the (visually hidden) checkbox label. A string
|
|
167
|
+
// `label` names it directly; a rich label needs `aria-label`.
|
|
168
|
+
const checkboxLabel =
|
|
169
|
+
ariaLabel ??
|
|
170
|
+
(typeof label === 'string'
|
|
171
|
+
? label
|
|
172
|
+
: t('@astryx.checkboxList.item.checkbox'));
|
|
173
|
+
|
|
174
|
+
// Dev-time guardrail: a rich label without `aria-label` leaves the
|
|
175
|
+
// checkbox with the generic name "Checkbox".
|
|
176
|
+
useDevWarning(
|
|
177
|
+
'CheckboxListItem',
|
|
178
|
+
'`label` is a ReactNode, so the checkbox falls ' +
|
|
179
|
+
'back to the generic accessible name "Checkbox". Pass ' +
|
|
180
|
+
'`aria-label` with a concise string equivalent of the visible ' +
|
|
181
|
+
'label so screen readers can tell items apart.',
|
|
182
|
+
typeof label !== 'string' && ariaLabel == null,
|
|
183
|
+
);
|
|
184
|
+
|
|
145
185
|
// Density from list context for checkbox sizing
|
|
146
186
|
const listCtx = use(ListContext);
|
|
147
187
|
const density = listCtx?.density ?? 'balanced';
|
|
@@ -226,11 +266,7 @@ export function CheckboxListItem({
|
|
|
226
266
|
style={style}
|
|
227
267
|
startContent={
|
|
228
268
|
<CheckboxInput
|
|
229
|
-
label={
|
|
230
|
-
typeof label === 'string'
|
|
231
|
-
? label
|
|
232
|
-
: t('@astryx.checkboxList.item.checkbox')
|
|
233
|
-
}
|
|
269
|
+
label={checkboxLabel}
|
|
234
270
|
isLabelHidden
|
|
235
271
|
value={resolvedChecked}
|
|
236
272
|
onChange={() => handleToggle()}
|
|
@@ -28,6 +28,7 @@ export const docs = {
|
|
|
28
28
|
{name: 'children', type: 'ReactNode', description: 'Card content.'},
|
|
29
29
|
{name: 'padding', type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10', description: 'Inner padding.', default: '4'},
|
|
30
30
|
{name: 'variant', type: "'default' | 'transparent' | 'muted' | 'blue' | 'cyan' | 'gray' | 'green' | 'orange' | 'pink' | 'purple' | 'red' | 'teal' | 'yellow'", description: 'Background color variant.', default: "'default'"},
|
|
31
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: 'Resting shadow depth. Often raised to signal the whole card is clickable.', default: "'none'"},
|
|
31
32
|
{name: 'width', type: 'SizeValue', description: 'Card width.'},
|
|
32
33
|
{name: 'height', type: 'SizeValue', description: 'Card height.'},
|
|
33
34
|
{name: 'maxWidth', type: 'SizeValue', description: 'Maximum card width.'},
|
|
@@ -73,6 +74,7 @@ export const docsDense = {
|
|
|
73
74
|
isDisabled: 'disables card',
|
|
74
75
|
padding: 'inner padding',
|
|
75
76
|
variant: 'background color variant',
|
|
77
|
+
elevation: 'resting shadow depth: none|low|med|high; often raised to signal clickability',
|
|
76
78
|
width: 'card width',
|
|
77
79
|
height: 'card height',
|
|
78
80
|
maxWidth: 'max card width',
|
|
@@ -106,4 +106,38 @@ describe('ClickableCard', () => {
|
|
|
106
106
|
const link = screen.getByRole('link', {name: 'Disabled link'});
|
|
107
107
|
expect(link).toHaveAttribute('aria-disabled', 'true');
|
|
108
108
|
});
|
|
109
|
+
|
|
110
|
+
describe('elevation', () => {
|
|
111
|
+
it('forwards a distinct elevation class to the card for each level', () => {
|
|
112
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
113
|
+
const {container} = render(
|
|
114
|
+
<ClickableCard label="Card" elevation={elevation}>
|
|
115
|
+
Content
|
|
116
|
+
</ClickableCard>,
|
|
117
|
+
);
|
|
118
|
+
return container.firstElementChild!.className;
|
|
119
|
+
};
|
|
120
|
+
const classes = new Set([
|
|
121
|
+
classFor('none'),
|
|
122
|
+
classFor('low'),
|
|
123
|
+
classFor('med'),
|
|
124
|
+
classFor('high'),
|
|
125
|
+
]);
|
|
126
|
+
expect(classes.size).toBe(4);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('defaults to flat (elevation none)', () => {
|
|
130
|
+
const {container: def} = render(
|
|
131
|
+
<ClickableCard label="Card">Content</ClickableCard>,
|
|
132
|
+
);
|
|
133
|
+
const {container: none} = render(
|
|
134
|
+
<ClickableCard label="Card" elevation="none">
|
|
135
|
+
Content
|
|
136
|
+
</ClickableCard>,
|
|
137
|
+
);
|
|
138
|
+
expect(def.firstElementChild!.className).toBe(
|
|
139
|
+
none.firstElementChild!.className,
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
109
143
|
});
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - /apps/storybook/stories/ClickableCard.stories.tsx (storybook stories)
|
|
15
15
|
* - /packages/cli/templates/blocks/components/Card/ClickableCardShowcase.tsx (showcase block)
|
|
16
16
|
* - /packages/cli/templates/blocks/components/Card/ClickableCardWithNestedButton.tsx (block)
|
|
17
|
+
* - /packages/cli/templates/blocks/components/Card/ClickableCardElevated.tsx (block)
|
|
17
18
|
*
|
|
18
19
|
* Composes Card for all visual styling (radius, padding, variants,
|
|
19
20
|
* container tokens, theming). Adds an interactive wrapper with
|
|
@@ -37,7 +38,7 @@ import {
|
|
|
37
38
|
durationVars,
|
|
38
39
|
easeVars,
|
|
39
40
|
} from '../theme/tokens.stylex';
|
|
40
|
-
import type {SizeValue, SpacingStep} from '../utils/types';
|
|
41
|
+
import type {SizeValue, SpacingStep, Elevation} from '../utils/types';
|
|
41
42
|
import {mergeProps, mergeRefs} from '../utils';
|
|
42
43
|
import {Card} from '../Card/Card';
|
|
43
44
|
import type {CardVariant} from '../Card/Card';
|
|
@@ -78,13 +79,13 @@ const styles = stylex.create({
|
|
|
78
79
|
backgroundColor: 'transparent',
|
|
79
80
|
},
|
|
80
81
|
':active::after': {
|
|
81
|
-
backgroundColor: 'color-
|
|
82
|
+
backgroundColor: colorVars['--color-overlay-pressed'],
|
|
82
83
|
},
|
|
83
84
|
},
|
|
84
85
|
hoverOnPointer: {
|
|
85
86
|
'@media (hover: hover)': {
|
|
86
87
|
':hover::after': {
|
|
87
|
-
backgroundColor: 'color-
|
|
88
|
+
backgroundColor: colorVars['--color-overlay-hover'],
|
|
88
89
|
},
|
|
89
90
|
},
|
|
90
91
|
},
|
|
@@ -197,6 +198,13 @@ export interface ClickableCardProps extends BaseProps {
|
|
|
197
198
|
*/
|
|
198
199
|
variant?: CardVariant;
|
|
199
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Resting elevation — the shadow depth the card sits at. Often raised to
|
|
203
|
+
* signal that the whole card is clickable.
|
|
204
|
+
* @default 'none'
|
|
205
|
+
*/
|
|
206
|
+
elevation?: Elevation;
|
|
207
|
+
|
|
200
208
|
/** Width of the card. */
|
|
201
209
|
width?: SizeValue;
|
|
202
210
|
|
|
@@ -253,6 +261,7 @@ export function ClickableCard({
|
|
|
253
261
|
children,
|
|
254
262
|
padding,
|
|
255
263
|
variant = 'default',
|
|
264
|
+
elevation = 'none',
|
|
256
265
|
width,
|
|
257
266
|
height,
|
|
258
267
|
maxWidth,
|
|
@@ -297,6 +306,7 @@ export function ClickableCard({
|
|
|
297
306
|
maxWidth={maxWidth}
|
|
298
307
|
padding={padding}
|
|
299
308
|
variant={variant}
|
|
309
|
+
elevation={elevation}
|
|
300
310
|
{...mergeProps(themeProps('clickable-card', {variant}), {
|
|
301
311
|
className: classNameProp,
|
|
302
312
|
style,
|
|
@@ -210,6 +210,62 @@ describe('CodeBlock', () => {
|
|
|
210
210
|
expect(document.getElementById(controlsId as string)).not.toBeNull();
|
|
211
211
|
});
|
|
212
212
|
|
|
213
|
+
it('makes the collapsed region inert so the scroll container is unreachable', () => {
|
|
214
|
+
render(
|
|
215
|
+
<CodeBlock
|
|
216
|
+
code={LONG_CODE}
|
|
217
|
+
language="javascript"
|
|
218
|
+
title="example"
|
|
219
|
+
isCollapsible
|
|
220
|
+
/>,
|
|
221
|
+
);
|
|
222
|
+
const header = screen
|
|
223
|
+
.getAllByRole('button')
|
|
224
|
+
.find(el => el.hasAttribute('aria-expanded'))!;
|
|
225
|
+
const region = document.getElementById(
|
|
226
|
+
header.getAttribute('aria-controls') as string,
|
|
227
|
+
)!;
|
|
228
|
+
// Expanded: the region is not inert and the scroll container is reachable.
|
|
229
|
+
expect(region).not.toHaveAttribute('inert');
|
|
230
|
+
|
|
231
|
+
fireEvent.click(header);
|
|
232
|
+
expect(header).toHaveAttribute('aria-expanded', 'false');
|
|
233
|
+
// Collapsed: the wrapper is inert, so the keyboard-focusable scroll
|
|
234
|
+
// container (tabIndex=0) inside it drops out of the tab order and the
|
|
235
|
+
// accessibility tree instead of remaining an invisible tab stop.
|
|
236
|
+
expect(region).toHaveAttribute('inert');
|
|
237
|
+
const scrollContainer = screen.getByRole('group');
|
|
238
|
+
expect(scrollContainer.closest('[inert]')).toBe(region);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('restores focusability of the scroll container after expanding again', () => {
|
|
242
|
+
render(
|
|
243
|
+
<CodeBlock
|
|
244
|
+
code={LONG_CODE}
|
|
245
|
+
language="javascript"
|
|
246
|
+
title="example"
|
|
247
|
+
isCollapsible
|
|
248
|
+
/>,
|
|
249
|
+
);
|
|
250
|
+
const header = screen
|
|
251
|
+
.getAllByRole('button')
|
|
252
|
+
.find(el => el.hasAttribute('aria-expanded'))!;
|
|
253
|
+
const region = document.getElementById(
|
|
254
|
+
header.getAttribute('aria-controls') as string,
|
|
255
|
+
)!;
|
|
256
|
+
// Collapse, then expand again.
|
|
257
|
+
fireEvent.click(header);
|
|
258
|
+
expect(region).toHaveAttribute('inert');
|
|
259
|
+
fireEvent.click(header);
|
|
260
|
+
expect(header).toHaveAttribute('aria-expanded', 'true');
|
|
261
|
+
// Expanded again: inert is removed and the scroll container is a
|
|
262
|
+
// keyboard-focusable group once more.
|
|
263
|
+
expect(region).not.toHaveAttribute('inert');
|
|
264
|
+
const scrollContainer = screen.getByRole('group');
|
|
265
|
+
expect(scrollContainer.closest('[inert]')).toBeNull();
|
|
266
|
+
expect(scrollContainer).toHaveAttribute('tabindex', '0');
|
|
267
|
+
});
|
|
268
|
+
|
|
213
269
|
it('applies a per-instance syntax theme via the syntaxTheme prop', () => {
|
|
214
270
|
const {container} = render(
|
|
215
271
|
<CodeBlock
|
|
@@ -807,7 +807,9 @@ export function CodeBlock({
|
|
|
807
807
|
e.stopPropagation();
|
|
808
808
|
void handleCopy();
|
|
809
809
|
}}
|
|
810
|
-
aria-label={
|
|
810
|
+
aria-label={
|
|
811
|
+
copied ? t('@astryx.codeBlock.copied') : t('@astryx.codeBlock.copyCode')
|
|
812
|
+
}
|
|
811
813
|
{...stylex.props(
|
|
812
814
|
styles.copyButton,
|
|
813
815
|
!showHeader && styles.copyButtonAbsolute,
|
|
@@ -923,6 +925,12 @@ export function CodeBlock({
|
|
|
923
925
|
{canCollapse ? (
|
|
924
926
|
<div
|
|
925
927
|
id={regionId}
|
|
928
|
+
// While collapsed, the region is only hidden visually (0fr grid
|
|
929
|
+
// row); inert also removes it from the tab order and accessibility
|
|
930
|
+
// tree so keyboard users cannot Tab into the invisible scroll
|
|
931
|
+
// container (tabIndex=0). aria-controls pointing at an inert
|
|
932
|
+
// element remains a valid, resolvable reference.
|
|
933
|
+
inert={isCollapsed ? true : undefined}
|
|
926
934
|
{...stylex.props(
|
|
927
935
|
styles.collapseGrid,
|
|
928
936
|
isCollapsed && styles.collapseGridCollapsed,
|
|
@@ -145,6 +145,7 @@ export const docs = {
|
|
|
145
145
|
{className: 'astryx-command-palette-empty'},
|
|
146
146
|
{className: 'astryx-command-palette-footer'},
|
|
147
147
|
{className: 'astryx-command-palette-group'},
|
|
148
|
+
{className: 'astryx-command-palette-group-heading'},
|
|
148
149
|
{className: 'astryx-command-palette-input'},
|
|
149
150
|
{className: 'astryx-command-palette-item'},
|
|
150
151
|
{className: 'astryx-command-palette-list'},
|
|
@@ -268,6 +268,7 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
268
268
|
label: labelFromProps,
|
|
269
269
|
width = 640,
|
|
270
270
|
maxHeight = 480,
|
|
271
|
+
...rest
|
|
271
272
|
}: CommandPaletteProps<T>) {
|
|
272
273
|
const t = useTranslator();
|
|
273
274
|
const label = labelFromProps ?? t('@astryx.commandPalette.label');
|
|
@@ -527,7 +528,8 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
527
528
|
width={width}
|
|
528
529
|
maxHeight={maxHeight}
|
|
529
530
|
purpose="info"
|
|
530
|
-
aria-label={label}
|
|
531
|
+
aria-label={label}
|
|
532
|
+
{...rest}>
|
|
531
533
|
<CommandPaletteContext value={contextValue}>
|
|
532
534
|
<Layout
|
|
533
535
|
defaultHasDividers
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import {describe, it, expect} from 'vitest';
|
|
10
10
|
import {render, screen} from '@testing-library/react';
|
|
11
11
|
import {CommandPaletteGroup} from './CommandPaletteGroup';
|
|
12
|
+
import {defineTheme} from '../theme/defineTheme';
|
|
13
|
+
import {generateThemeCSSFlat} from '../theme/generateThemeRules';
|
|
12
14
|
|
|
13
15
|
describe('CommandPaletteGroup', () => {
|
|
14
16
|
it('renders heading', () => {
|
|
@@ -51,4 +53,73 @@ describe('CommandPaletteGroup', () => {
|
|
|
51
53
|
'true',
|
|
52
54
|
);
|
|
53
55
|
});
|
|
56
|
+
|
|
57
|
+
// ===========================================================================
|
|
58
|
+
// Heading theme target
|
|
59
|
+
// ===========================================================================
|
|
60
|
+
|
|
61
|
+
describe('heading theme target', () => {
|
|
62
|
+
it('renders the astryx-command-palette-group-heading target on the heading', () => {
|
|
63
|
+
render(
|
|
64
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
65
|
+
<div>Item</div>
|
|
66
|
+
</CommandPaletteGroup>,
|
|
67
|
+
);
|
|
68
|
+
const heading = screen.getByText('Suggestions');
|
|
69
|
+
|
|
70
|
+
// The root carries `astryx-command-palette-group`; this is the stable
|
|
71
|
+
// handle on the heading itself, so a theme can style just the heading
|
|
72
|
+
// without a fragile structural selector.
|
|
73
|
+
expect(heading).toHaveClass('astryx-command-palette-group-heading');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('keeps the heading target distinct from the group root target', () => {
|
|
77
|
+
render(
|
|
78
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
79
|
+
<div>Item</div>
|
|
80
|
+
</CommandPaletteGroup>,
|
|
81
|
+
);
|
|
82
|
+
const root = screen.getByRole('group');
|
|
83
|
+
const heading = screen.getByText('Suggestions');
|
|
84
|
+
|
|
85
|
+
expect(root).toHaveClass('astryx-command-palette-group');
|
|
86
|
+
expect(root).not.toHaveClass('astryx-command-palette-group-heading');
|
|
87
|
+
expect(heading).not.toHaveClass('astryx-command-palette-group');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('leaves the heading decorative (additive target only)', () => {
|
|
91
|
+
// The target adds a class and nothing else — the heading stays
|
|
92
|
+
// aria-hidden so grouping remains announced via the root's aria-label.
|
|
93
|
+
render(
|
|
94
|
+
<CommandPaletteGroup heading="Suggestions">
|
|
95
|
+
<div>Item</div>
|
|
96
|
+
</CommandPaletteGroup>,
|
|
97
|
+
);
|
|
98
|
+
expect(screen.getByText('Suggestions')).toHaveAttribute(
|
|
99
|
+
'aria-hidden',
|
|
100
|
+
'true',
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('exposes command-palette-group-heading as a themeable defineTheme target', () => {
|
|
105
|
+
// The generated CSS proves the target is reachable by a theme: jsdom
|
|
106
|
+
// cannot resolve the @layer cascade, so the DOM-class assertions above
|
|
107
|
+
// and this generation assertion together cover the seam.
|
|
108
|
+
const theme = defineTheme({
|
|
109
|
+
name: 'command-palette-group-heading-test',
|
|
110
|
+
components: {
|
|
111
|
+
'command-palette-group-heading': {
|
|
112
|
+
base: {
|
|
113
|
+
paddingBlock: 'var(--spacing-2)',
|
|
114
|
+
fontWeight: 'var(--font-weight-bold)',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const css = generateThemeCSSFlat(theme);
|
|
120
|
+
expect(css).toContain('.astryx-command-palette-group-heading {');
|
|
121
|
+
expect(css).toContain('padding-block: var(--spacing-2)');
|
|
122
|
+
expect(css).toContain('font-weight: var(--font-weight-bold)');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
54
125
|
});
|
|
@@ -90,7 +90,18 @@ export function CommandPaletteGroup({
|
|
|
90
90
|
style,
|
|
91
91
|
)}
|
|
92
92
|
{...props}>
|
|
93
|
-
<div
|
|
93
|
+
<div
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
{...mergeProps(
|
|
96
|
+
// Stable theme target for the group heading text. The root carries
|
|
97
|
+
// `astryx-command-palette-group`, but the heading itself had no
|
|
98
|
+
// handle, so a theme could only reach it through a fragile structural
|
|
99
|
+
// selector. This adds an `astryx-command-palette-group-heading` class
|
|
100
|
+
// so `defineTheme` can scope overrides (e.g. heading typography) to
|
|
101
|
+
// the heading alone.
|
|
102
|
+
themeProps('command-palette-group-heading'),
|
|
103
|
+
stylex.props(styles.heading),
|
|
104
|
+
)}>
|
|
94
105
|
{heading}
|
|
95
106
|
</div>
|
|
96
107
|
{children}
|
|
@@ -7,7 +7,8 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'CommandPalette',
|
|
8
8
|
displayName: 'Command Palette Input',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Search input slot. Auto-focuses on mount. Wires to command palette context when used inside CommandPalette.',
|
|
11
12
|
props: [
|
|
12
13
|
{
|
|
13
14
|
name: 'placeholder',
|
|
@@ -15,16 +16,24 @@ export const docs = {
|
|
|
15
16
|
description: 'Placeholder text for the input.',
|
|
16
17
|
default: "'Search...'",
|
|
17
18
|
},
|
|
19
|
+
{
|
|
20
|
+
name: 'label',
|
|
21
|
+
type: 'string',
|
|
22
|
+
description:
|
|
23
|
+
'Accessible label for the combobox input, announced by screen readers. Falls back to the placeholder text when omitted.',
|
|
24
|
+
},
|
|
18
25
|
{
|
|
19
26
|
name: 'hasAutoFocus',
|
|
20
27
|
type: 'boolean',
|
|
21
|
-
description:
|
|
28
|
+
description:
|
|
29
|
+
'Auto-focus the input when mounted. Automatically disabled when inside an inline command palette.',
|
|
22
30
|
default: 'true',
|
|
23
31
|
},
|
|
24
32
|
{
|
|
25
33
|
name: 'endContent',
|
|
26
34
|
type: 'ReactNode',
|
|
27
|
-
description:
|
|
35
|
+
description:
|
|
36
|
+
'Content rendered at the trailing end of the input, after the spinner. Use for clear buttons or keyboard shortcut hints.',
|
|
28
37
|
slotElements: [
|
|
29
38
|
{
|
|
30
39
|
__element: 'Icon',
|
|
@@ -44,17 +53,20 @@ export const docs = {
|
|
|
44
53
|
{
|
|
45
54
|
name: 'value',
|
|
46
55
|
type: 'string',
|
|
47
|
-
description:
|
|
56
|
+
description:
|
|
57
|
+
'Search value. When omitted inside CommandPalette, reads from context.',
|
|
48
58
|
},
|
|
49
59
|
{
|
|
50
60
|
name: 'onValueChange',
|
|
51
61
|
type: '(value: string) => void',
|
|
52
|
-
description:
|
|
62
|
+
description:
|
|
63
|
+
'Called when search value changes. When omitted inside CommandPalette, writes to context.',
|
|
53
64
|
},
|
|
54
65
|
{
|
|
55
66
|
name: 'xstyle',
|
|
56
67
|
type: 'StyleXStyles',
|
|
57
|
-
description:
|
|
68
|
+
description:
|
|
69
|
+
'StyleX styles for layout customization. Must be a stylex.create() value.',
|
|
58
70
|
},
|
|
59
71
|
],
|
|
60
72
|
playground: {
|
|
@@ -69,9 +81,11 @@ export const docsZh = {
|
|
|
69
81
|
name: 'CommandPaletteInput',
|
|
70
82
|
isHiddenFromOverview: true,
|
|
71
83
|
displayName: 'Command Palette Input',
|
|
72
|
-
description:
|
|
84
|
+
description:
|
|
85
|
+
'搜索输入插槽。挂载时自动聚焦。在 CommandPalette 内使用时连接到上下文。',
|
|
73
86
|
propDescriptions: {
|
|
74
87
|
placeholder: '输入框的占位文本。',
|
|
88
|
+
label: '组合框输入的无障碍标签,供屏幕阅读器朗读。省略时回退到占位文本。',
|
|
75
89
|
hasAutoFocus: '挂载时自动聚焦输入框。内联命令面板中自动禁用。',
|
|
76
90
|
endContent: '渲染在输入框末尾的内容,位于加载指示器之后。',
|
|
77
91
|
value: '搜索值。在 CommandPalette 内省略时从上下文读取。',
|
|
@@ -84,13 +98,16 @@ export const docsDense = {
|
|
|
84
98
|
name: 'CommandPaletteInput',
|
|
85
99
|
isHiddenFromOverview: true,
|
|
86
100
|
displayName: 'Command Palette Input',
|
|
87
|
-
description:
|
|
101
|
+
description:
|
|
102
|
+
'search input; auto-focus on mount; wires to context inside CommandPalette',
|
|
88
103
|
propDescriptions: {
|
|
89
104
|
placeholder: 'input placeholder text',
|
|
105
|
+
label: 'accessible label for the combobox; falls back to placeholder',
|
|
90
106
|
hasAutoFocus: 'auto-focus on mount; auto-disabled in inline mode',
|
|
91
107
|
endContent: 'trailing content after spinner',
|
|
92
108
|
value: 'search value; reads context when omitted inside palette',
|
|
93
|
-
onValueChange:
|
|
109
|
+
onValueChange:
|
|
110
|
+
'called on change; writes context when omitted inside palette',
|
|
94
111
|
xstyle: 'StyleX layout styles; must be stylex.create() value',
|
|
95
112
|
},
|
|
96
113
|
};
|
|
@@ -32,6 +32,40 @@ describe('CommandPaletteInput', () => {
|
|
|
32
32
|
expect(screen.getByRole('combobox')).toBeInTheDocument();
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
it('has an accessible name by default', () => {
|
|
36
|
+
render(<CommandPaletteInput />);
|
|
37
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
38
|
+
'aria-label',
|
|
39
|
+
'Search…',
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('uses the label prop as the accessible name', () => {
|
|
44
|
+
render(<CommandPaletteInput label="Search commands" />);
|
|
45
|
+
const input = screen.getByRole('combobox');
|
|
46
|
+
expect(input).toHaveAttribute('aria-label', 'Search commands');
|
|
47
|
+
// The label prop does not affect the visible placeholder
|
|
48
|
+
expect(input).toHaveAttribute('placeholder', 'Search…');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('falls back to a custom placeholder for the accessible name', () => {
|
|
52
|
+
render(<CommandPaletteInput placeholder="Type a command..." />);
|
|
53
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
54
|
+
'aria-label',
|
|
55
|
+
'Type a command...',
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('lets a consumer-passed aria-label override the default', () => {
|
|
60
|
+
render(
|
|
61
|
+
<CommandPaletteInput label="Search commands" aria-label="Custom name" />,
|
|
62
|
+
);
|
|
63
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
64
|
+
'aria-label',
|
|
65
|
+
'Custom name',
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
35
69
|
it('calls onValueChange when typing', () => {
|
|
36
70
|
const handleChange = vi.fn();
|
|
37
71
|
render(<CommandPaletteInput onValueChange={handleChange} />);
|
|
@@ -109,6 +109,13 @@ export interface CommandPaletteInputProps extends Omit<
|
|
|
109
109
|
*/
|
|
110
110
|
placeholder?: string;
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Accessible label for the combobox input, announced by screen readers.
|
|
114
|
+
* Falls back to the placeholder text (`'Search…'` by default), since a
|
|
115
|
+
* placeholder alone is not a reliable accessible name.
|
|
116
|
+
*/
|
|
117
|
+
label?: string;
|
|
118
|
+
|
|
112
119
|
/**
|
|
113
120
|
* Whether to auto-focus the input when mounted.
|
|
114
121
|
* @default true
|
|
@@ -149,6 +156,7 @@ export function CommandPaletteInput({
|
|
|
149
156
|
value: controlledValue,
|
|
150
157
|
onValueChange,
|
|
151
158
|
placeholder: placeholderFromProps,
|
|
159
|
+
label,
|
|
152
160
|
hasAutoFocus = true,
|
|
153
161
|
endContent,
|
|
154
162
|
onChange,
|
|
@@ -215,6 +223,9 @@ export function CommandPaletteInput({
|
|
|
215
223
|
? ctx.getItemId(ctx.highlightedIndex)
|
|
216
224
|
: undefined
|
|
217
225
|
}
|
|
226
|
+
// A placeholder alone is not a reliable accessible name; give the
|
|
227
|
+
// combobox an explicit one (consumer aria-label via rest props wins).
|
|
228
|
+
aria-label={label ?? placeholder}
|
|
218
229
|
placeholder={placeholder}
|
|
219
230
|
value={value}
|
|
220
231
|
data-autofocus={effectiveAutoFocus || undefined}
|