@astryxdesign/core 0.1.7 → 0.1.8-canary.0c4d8d7
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 +65 -0
- package/README.md +30 -19
- 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 +10 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +12 -8
- package/dist/Avatar/AvatarSizeContext.d.ts +1 -1
- package/dist/Avatar/AvatarSizeContext.js +1 -1
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
- package/dist/Avatar/AvatarStatusDot.js +2 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +2 -2
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +16 -14
- 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/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/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 +6 -2
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +55 -5
- package/dist/Chat/ChatComposer.d.ts +8 -0
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +31 -6
- 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 +19 -3
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatMessage.d.ts +1 -1
- package/dist/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/Chat/ChatMessage.js +1 -1
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.d.ts +5 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +12 -3
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +10 -4
- package/dist/ClickableCard/ClickableCard.d.ts +9 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -0
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +8 -1
- package/dist/Collapsible/Collapsible.d.ts +11 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +36 -4
- 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/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/ContextMenu/index.d.ts +3 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +7 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +10 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +2 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +8 -4
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +88 -0
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +169 -0
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.js +18 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +68 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +69 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +69 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +178 -0
- package/dist/DropdownMenu/index.d.ts +5 -1
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +10 -1
- package/dist/DropdownMenu/menuItemRoles.d.ts +13 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemRoles.js +15 -0
- 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 +43 -13
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +62 -27
- 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 +68 -3
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +128 -26
- package/dist/Outline/useScrollSpy.d.ts +27 -7
- package/dist/Outline/useScrollSpy.d.ts.map +1 -1
- package/dist/Outline/useScrollSpy.js +202 -70
- 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/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 +14 -11
- 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 +15 -1
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +2 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/Table.d.ts +1 -1
- package/dist/Table/Table.js +1 -1
- package/dist/Table/index.d.ts +4 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +2 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +24 -2
- 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 +12 -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/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +18 -7
- package/dist/Table/plugins/tree/index.d.ts +5 -0
- package/dist/Table/plugins/tree/index.d.ts.map +1 -0
- package/dist/Table/plugins/tree/index.js +4 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +38 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -0
- package/dist/Table/plugins/tree/useTableTreeData.js +358 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +51 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -0
- package/dist/Table/plugins/tree/useTableTreeState.js +175 -0
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +6 -3
- package/dist/Thumbnail/Thumbnail.d.ts +8 -1
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +46 -8
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +15 -4
- 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/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +8 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +18 -8
- package/dist/TopNav/TopNavMegaMenu.js +10 -4
- package/dist/TopNav/TopNavMenu.d.ts +2 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +68 -6
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +5 -14
- package/dist/astryx.css +51 -16
- package/dist/astryx.umd.js +56 -56
- package/dist/astryx.umd.js.map +4 -4
- package/dist/authoring/doc.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/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +37 -25
- package/dist/theme/Theme.js +1 -1
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.js +1 -1
- 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 +0 -3
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/docs.mjs +32 -461
- package/locales/en.json +212 -172
- package/locales/fr-FR.json +10 -0
- package/locales/pseudo.json +30 -0
- package/package.json +3 -1
- package/scripts/postinstall.mjs +93 -0
- 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 +6 -6
- package/src/Avatar/Avatar.tsx +16 -11
- package/src/Avatar/AvatarSizeContext.ts +1 -1
- package/src/Avatar/AvatarStatusDot.tsx +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -1
- package/src/AvatarGroup/AvatarGroup.test.tsx +17 -3
- package/src/AvatarGroup/AvatarGroup.tsx +3 -3
- package/src/AvatarGroup/AvatarGroupOverflow.doc.mjs +4 -4
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +21 -5
- 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/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/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 +149 -1
- package/src/Carousel/Carousel.tsx +62 -5
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatComposer.doc.mjs +9 -0
- package/src/Chat/ChatComposer.test.tsx +35 -0
- package/src/Chat/ChatComposer.tsx +58 -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 +87 -0
- package/src/Chat/ChatComposerInput.tsx +35 -3
- package/src/Chat/ChatLayout.tsx +3 -1
- package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
- package/src/Chat/ChatMessage.tsx +4 -2
- package/src/Chat/ChatMessageMetadata.tsx +1 -2
- package/src/Chat/ChatSendButton.tsx +5 -1
- package/src/Chat/ChatToolCalls.test.tsx +64 -0
- package/src/Chat/ChatToolCalls.tsx +13 -1
- package/src/Chat/useTriggerMenu.tsx +3 -1
- package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxList/CheckboxList.test.tsx +9 -1
- package/src/Citation/Citation.test.tsx +51 -0
- package/src/Citation/Citation.tsx +8 -2
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
- package/src/ClickableCard/ClickableCard.test.tsx +34 -0
- package/src/ClickableCard/ClickableCard.tsx +11 -1
- package/src/CodeBlock/CodeBlock.test.tsx +56 -0
- package/src/CodeBlock/CodeBlock.tsx +9 -1
- package/src/Collapsible/Collapsible.doc.mjs +7 -0
- package/src/Collapsible/Collapsible.test.tsx +80 -0
- package/src/Collapsible/Collapsible.tsx +58 -5
- 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 +75 -1
- package/src/ContextMenu/ContextMenu.tsx +10 -5
- package/src/ContextMenu/index.ts +15 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +35 -0
- package/src/DateTimeInput/DateTimeInput.tsx +14 -2
- package/src/Dialog/Dialog.tsx +12 -2
- package/src/DropdownMenu/DropdownMenu.doc.mjs +23 -0
- package/src/DropdownMenu/DropdownMenu.tsx +11 -6
- package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +95 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +236 -0
- package/src/DropdownMenu/DropdownMenuContext.tsx +29 -1
- package/src/DropdownMenu/DropdownMenuItem.doc.mjs +7 -1
- package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +80 -0
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +118 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +80 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +232 -0
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +163 -0
- package/src/DropdownMenu/index.ts +23 -3
- package/src/DropdownMenu/menuItemRoles.ts +22 -0
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/FieldLabel.doc.mjs +1 -1
- 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 +12 -0
- package/src/Icon/Icon.test.tsx +142 -0
- package/src/Icon/Icon.tsx +98 -30
- package/src/IconButton/IconButton.doc.mjs +8 -0
- package/src/IconButton/IconButton.test.tsx +15 -18
- package/src/Item/Item.doc.mjs +1 -1
- package/src/Layer/useLayer.tsx +8 -0
- package/src/MobileNav/MobileNav.tsx +12 -1
- package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
- package/src/MobileNav/MobileNavToggle.tsx +9 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +4 -2
- package/src/MultiSelector/MultiSelector.test.tsx +162 -1
- package/src/MultiSelector/MultiSelector.tsx +55 -12
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NumberInput/NumberInput.doc.mjs +2 -2
- package/src/NumberInput/NumberInput.test.tsx +11 -7
- package/src/NumberInput/NumberInput.tsx +1 -2
- package/src/Outline/Outline.doc.mjs +123 -3
- package/src/Outline/Outline.test.tsx +735 -0
- package/src/Outline/Outline.tsx +183 -33
- package/src/Outline/useScrollSpy.ts +248 -72
- 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/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 +27 -14
- package/src/Selector/Selector.test.tsx +69 -0
- package/src/Selector/Selector.tsx +5 -1
- package/src/Selector/SelectorOption.doc.mjs +1 -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.doc.mjs +2 -2
- package/src/SideNav/SideNavItem.tsx +5 -1
- package/src/Slider/Slider.test.tsx +62 -2
- package/src/Slider/Slider.tsx +15 -1
- package/src/Switch/Switch.doc.mjs +1 -1
- package/src/Switch/Switch.test.tsx +32 -1
- package/src/TabList/Tab.tsx +5 -1
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +66 -0
- package/src/TabList/TabList.tsx +8 -0
- package/src/TabList/TabMenu.tsx +4 -1
- package/src/Table/Table.doc.mjs +2 -0
- package/src/Table/Table.tsx +1 -1
- package/src/Table/index.ts +12 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +90 -1
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +37 -5
- 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 +18 -1
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +95 -9
- package/src/Table/plugins/sortable/useTableSortable.tsx +23 -7
- package/src/Table/plugins/tree/index.ts +12 -0
- package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +163 -0
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +594 -0
- package/src/Table/plugins/tree/useTableTreeData.tsx +495 -0
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +636 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +253 -0
- package/src/Table/useBaseTablePlugins.ts +6 -2
- package/src/Table/useTableRowStatus.doc.mjs +30 -0
- package/src/Table/useTableSelection.doc.mjs +65 -14
- package/src/Table/useTableTreeData.doc.mjs +75 -0
- package/src/Table/useTableTreeState.doc.mjs +98 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.test.tsx +9 -1
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/Thumbnail/Thumbnail.doc.mjs +9 -0
- package/src/Thumbnail/Thumbnail.test.tsx +38 -8
- package/src/Thumbnail/Thumbnail.tsx +28 -1
- package/src/TimeInput/TimeInput.test.tsx +76 -1
- package/src/TimeInput/TimeInput.tsx +19 -6
- package/src/Tokenizer/Tokenizer.doc.mjs +1 -1
- package/src/Tokenizer/Tokenizer.test.tsx +137 -2
- package/src/Tokenizer/Tokenizer.tsx +16 -4
- package/src/Toolbar/Toolbar.tsx +10 -3
- package/src/TopNav/TopNav.test.tsx +80 -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/TopNavMenu.test.tsx +118 -4
- package/src/TopNav/TopNavMenu.tsx +83 -5
- package/src/TreeList/TreeList.test.tsx +32 -1
- package/src/TreeList/TreeListItem.tsx +19 -10
- package/src/authoring/doc.ts +1 -3
- package/src/docs-script.test.mjs +18 -13
- package/src/hooks/computeOverflow.test.ts +422 -0
- package/src/hooks/computeOverflow.ts +290 -0
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +77 -33
- package/src/postinstall.test.mjs +71 -0
- package/src/theme/Theme.doc.mjs +4 -4
- package/src/theme/Theme.tsx +1 -1
- package/src/theme/defineTheme.ts +1 -1
- package/src/theme/generateThemeRules.test.ts +65 -0
- package/src/theme/generateThemeRules.ts +56 -0
- package/src/theme/hct.ts +0 -4
- package/src/utils/types.ts +14 -0
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +0 -16
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +0 -1
- package/dist/TreeList/treeListItem.markers.stylex.js +0 -22
- package/src/TreeList/treeListItem.markers.stylex.ts +0 -20
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* @position Core implementation; consumed by index.ts
|
|
10
10
|
*
|
|
11
11
|
* Renders a horizontal list of items, hiding those that don't fit in the
|
|
12
|
-
* available width and optionally showing an overflow indicator.
|
|
13
|
-
*
|
|
12
|
+
* available width and optionally showing an overflow indicator. Supports an
|
|
13
|
+
* optional item cap (`maxVisibleItems`) and bounded multi-row wrapping
|
|
14
|
+
* (`maxRows`). Uses a hidden measurement container to avoid flickering.
|
|
14
15
|
*
|
|
15
16
|
* SYNC: When modified, update these files to stay in sync:
|
|
16
17
|
* - /packages/core/src/OverflowList/index.ts (exports if types change)
|
|
@@ -34,6 +35,14 @@ const styles = stylex.create({
|
|
|
34
35
|
whiteSpace: 'nowrap',
|
|
35
36
|
minWidth: 0,
|
|
36
37
|
},
|
|
38
|
+
containerMultiRow: {
|
|
39
|
+
display: 'flex',
|
|
40
|
+
flexWrap: 'wrap',
|
|
41
|
+
alignContent: 'flex-start',
|
|
42
|
+
overflow: 'hidden',
|
|
43
|
+
whiteSpace: 'normal',
|
|
44
|
+
minWidth: 0,
|
|
45
|
+
},
|
|
37
46
|
fillParent: {
|
|
38
47
|
width: '100%',
|
|
39
48
|
},
|
|
@@ -52,6 +61,12 @@ const styles = stylex.create({
|
|
|
52
61
|
},
|
|
53
62
|
});
|
|
54
63
|
|
|
64
|
+
const multiRowHeight = stylex.create({
|
|
65
|
+
height: (maxRows: number, rowHeight: number, gapPx: number) => ({
|
|
66
|
+
maxHeight: `calc(${rowHeight}px * ${maxRows} + ${gapPx}px * ${maxRows - 1})`,
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
69
|
+
|
|
55
70
|
const gapStyles = stylex.create({
|
|
56
71
|
0: {gap: spacingVars['--spacing-0']},
|
|
57
72
|
0.5: {gap: spacingVars['--spacing-0-5']},
|
|
@@ -112,6 +127,24 @@ export interface OverflowListProps extends BaseProps<HTMLDivElement> {
|
|
|
112
127
|
*/
|
|
113
128
|
minVisibleItems?: number;
|
|
114
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Maximum number of items to ever show, even when they all fit. The ceiling
|
|
132
|
+
* partner to `minVisibleItems`; extra items collapse into the overflow
|
|
133
|
+
* indicator. Leave undefined for no cap. If it is less than
|
|
134
|
+
* `minVisibleItems`, the floor wins (and a dev-only warning is logged).
|
|
135
|
+
* @default undefined
|
|
136
|
+
*/
|
|
137
|
+
maxVisibleItems?: number;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Wrap items across up to this many rows before collapsing the remainder
|
|
141
|
+
* into the overflow indicator. Leave undefined (or set `1`) for the default
|
|
142
|
+
* single-line behavior. A number, not a boolean — unbounded wrapping is a
|
|
143
|
+
* plain flex-wrap layout, not overflow collapse. Assumes uniform row height.
|
|
144
|
+
* @default undefined
|
|
145
|
+
*/
|
|
146
|
+
maxRows?: number;
|
|
147
|
+
|
|
115
148
|
/**
|
|
116
149
|
* Which end to collapse items from.
|
|
117
150
|
* @default 'end'
|
|
@@ -180,6 +213,8 @@ export function OverflowList({
|
|
|
180
213
|
children,
|
|
181
214
|
gap = 2,
|
|
182
215
|
minVisibleItems = 0,
|
|
216
|
+
maxVisibleItems,
|
|
217
|
+
maxRows,
|
|
183
218
|
collapseFrom = 'end',
|
|
184
219
|
behavior = 'observeSelf',
|
|
185
220
|
overflowRenderer,
|
|
@@ -195,16 +230,17 @@ export function OverflowList({
|
|
|
195
230
|
const gapPx = spacingToPx[gap];
|
|
196
231
|
|
|
197
232
|
const observeParent = behavior === 'observeParent';
|
|
233
|
+
const isMultiRow = maxRows != null && maxRows > 1;
|
|
198
234
|
|
|
199
|
-
const {containerRef, measureRef, visibleCount, hasOverflow} =
|
|
200
|
-
itemCount,
|
|
201
|
-
{
|
|
235
|
+
const {containerRef, measureRef, visibleCount, hasOverflow, rowHeight} =
|
|
236
|
+
useOverflow(itemCount, {
|
|
202
237
|
gap: gapPx,
|
|
203
238
|
minVisibleItems,
|
|
239
|
+
maxVisibleItems,
|
|
240
|
+
maxRows,
|
|
204
241
|
collapseFrom,
|
|
205
242
|
behavior,
|
|
206
|
-
}
|
|
207
|
-
);
|
|
243
|
+
});
|
|
208
244
|
|
|
209
245
|
const allItems: OverflowItem[] = childArray.map((child, index) => ({
|
|
210
246
|
child,
|
|
@@ -248,8 +284,12 @@ export function OverflowList({
|
|
|
248
284
|
{...mergeProps(
|
|
249
285
|
themeProps('overflow-list'),
|
|
250
286
|
stylex.props(
|
|
251
|
-
styles.container,
|
|
287
|
+
isMultiRow ? styles.containerMultiRow : styles.container,
|
|
252
288
|
gapStyles[gap],
|
|
289
|
+
isMultiRow &&
|
|
290
|
+
rowHeight > 0 &&
|
|
291
|
+
maxRows != null &&
|
|
292
|
+
multiRowHeight.height(maxRows, rowHeight, gapPx),
|
|
253
293
|
observeParent && hasOverflow && styles.fillParent,
|
|
254
294
|
xstyle,
|
|
255
295
|
),
|
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
import {render, screen, fireEvent, act} from '@testing-library/react';
|
|
14
14
|
import React, {useState} from 'react';
|
|
15
15
|
import {PowerSearch} from './PowerSearch';
|
|
16
|
+
import {PowerSearchEditPopover} from './PowerSearchEditPopover';
|
|
17
|
+
import {useInternalConfig} from './useInternalConfig';
|
|
16
18
|
import type {PowerSearchConfig, PowerSearchFilter} from './types';
|
|
17
19
|
|
|
18
20
|
// =============================================================================
|
|
@@ -216,4 +218,69 @@ describe('PowerSearch', () => {
|
|
|
216
218
|
expect(popoverText).toContain('Priority');
|
|
217
219
|
expect(popoverText).toContain('equals');
|
|
218
220
|
});
|
|
221
|
+
|
|
222
|
+
it('does not save/close edit popover when Enter is consumed by child listbox option selection', () => {
|
|
223
|
+
const multiConfig: PowerSearchConfig = {
|
|
224
|
+
name: 'test-multi',
|
|
225
|
+
fields: [
|
|
226
|
+
{
|
|
227
|
+
key: 'status',
|
|
228
|
+
label: 'Status',
|
|
229
|
+
operators: [
|
|
230
|
+
{
|
|
231
|
+
key: 'any_of',
|
|
232
|
+
label: 'is any of',
|
|
233
|
+
value: {
|
|
234
|
+
type: 'enum_list',
|
|
235
|
+
values: [
|
|
236
|
+
{value: 'open', label: 'Open'},
|
|
237
|
+
{value: 'closed', label: 'Closed'},
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const onSave = vi.fn();
|
|
247
|
+
const onCancel = vi.fn();
|
|
248
|
+
|
|
249
|
+
function MultiSelectHarness() {
|
|
250
|
+
const internalConfig = useInternalConfig(multiConfig);
|
|
251
|
+
return (
|
|
252
|
+
<PowerSearchEditPopover
|
|
253
|
+
config={internalConfig}
|
|
254
|
+
filter={{
|
|
255
|
+
field: 'status',
|
|
256
|
+
operator: 'any_of',
|
|
257
|
+
value: {type: 'enum_list', value: ['open']},
|
|
258
|
+
}}
|
|
259
|
+
mode="edit"
|
|
260
|
+
onSave={onSave}
|
|
261
|
+
onCancel={onCancel}
|
|
262
|
+
/>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const {container} = render(<MultiSelectHarness />);
|
|
267
|
+
|
|
268
|
+
const input = container.querySelector('input');
|
|
269
|
+
expect(input).not.toBeNull();
|
|
270
|
+
|
|
271
|
+
// Fire an Enter event that has been defaultPrevented (e.g. child typeahead option selection)
|
|
272
|
+
const enterEvent = new KeyboardEvent('keydown', {
|
|
273
|
+
key: 'Enter',
|
|
274
|
+
bubbles: true,
|
|
275
|
+
cancelable: true,
|
|
276
|
+
});
|
|
277
|
+
enterEvent.preventDefault();
|
|
278
|
+
|
|
279
|
+
act(() => {
|
|
280
|
+
input?.dispatchEvent(enterEvent);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// onSave should NOT be called because the event was already consumed (defaultPrevented)
|
|
284
|
+
expect(onSave).not.toHaveBeenCalled();
|
|
285
|
+
});
|
|
219
286
|
});
|
|
@@ -702,7 +702,7 @@ export function PowerSearchEditPopover({
|
|
|
702
702
|
// Handle Enter to save, Escape to cancel
|
|
703
703
|
const handleKeyDown = useCallback(
|
|
704
704
|
(e: React.KeyboardEvent) => {
|
|
705
|
-
if (e.key === 'Enter' && !isSaveDisabled) {
|
|
705
|
+
if (e.key === 'Enter' && !isSaveDisabled && !e.defaultPrevented) {
|
|
706
706
|
e.preventDefault();
|
|
707
707
|
handleSave();
|
|
708
708
|
} else if (e.key === 'Escape' && !e.defaultPrevented) {
|
|
@@ -76,8 +76,7 @@ export function usePowerSearchSource(
|
|
|
76
76
|
|
|
77
77
|
// Check each field+operator combo against the query
|
|
78
78
|
for (const op of field.operators) {
|
|
79
|
-
const combinedLabel =
|
|
80
|
-
`${field.label} ${opLabel(op)}`.toLowerCase();
|
|
79
|
+
const combinedLabel = `${field.label} ${opLabel(op)}`.toLowerCase();
|
|
81
80
|
if (combinedLabel.includes(lower)) {
|
|
82
81
|
const id = `${field.key}:${op.key}`;
|
|
83
82
|
if (!seen.has(id)) {
|
|
@@ -27,6 +27,7 @@ export const docs = {
|
|
|
27
27
|
{name: 'children', type: 'ReactNode', description: 'Card content.'},
|
|
28
28
|
{name: 'padding', type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10', description: 'Inner padding.', default: '4'},
|
|
29
29
|
{name: 'variant', type: "'default' | 'transparent' | 'muted' | 'blue' | 'cyan' | 'gray' | 'green' | 'orange' | 'pink' | 'purple' | 'red' | 'teal' | 'yellow'", description: 'Background color variant.', default: "'default'"},
|
|
30
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: 'Resting shadow depth. The selection ring composes on top, so a selected card keeps its shadow.', default: "'none'"},
|
|
30
31
|
{name: 'width', type: 'SizeValue', description: 'Card width.'},
|
|
31
32
|
{name: 'height', type: 'SizeValue', description: 'Card height.'},
|
|
32
33
|
{name: 'maxWidth', type: 'SizeValue', description: 'Maximum card width.'},
|
|
@@ -71,6 +72,7 @@ export const docsDense = {
|
|
|
71
72
|
isDisabled: 'disables card',
|
|
72
73
|
padding: 'inner padding',
|
|
73
74
|
variant: 'background color variant',
|
|
75
|
+
elevation: 'resting shadow depth: none|low|med|high; selection ring composes on top',
|
|
74
76
|
width: 'card width',
|
|
75
77
|
height: 'card height',
|
|
76
78
|
maxWidth: 'max card width',
|
|
@@ -85,8 +85,7 @@ describe('SelectableCard', () => {
|
|
|
85
85
|
label="Disabled"
|
|
86
86
|
isSelected={false}
|
|
87
87
|
onChange={handleChange}
|
|
88
|
-
isDisabled
|
|
89
|
-
>
|
|
88
|
+
isDisabled>
|
|
90
89
|
Content
|
|
91
90
|
</SelectableCard>,
|
|
92
91
|
);
|
|
@@ -101,12 +100,55 @@ describe('SelectableCard', () => {
|
|
|
101
100
|
label="Disabled"
|
|
102
101
|
isSelected={false}
|
|
103
102
|
onChange={handleChange}
|
|
104
|
-
isDisabled
|
|
105
|
-
>
|
|
103
|
+
isDisabled>
|
|
106
104
|
<span>Content</span>
|
|
107
105
|
</SelectableCard>,
|
|
108
106
|
);
|
|
109
107
|
fireEvent.click(screen.getByText('Content'));
|
|
110
108
|
expect(handleChange).not.toHaveBeenCalled();
|
|
111
109
|
});
|
|
110
|
+
|
|
111
|
+
describe('elevation', () => {
|
|
112
|
+
const noop = () => {};
|
|
113
|
+
|
|
114
|
+
it('forwards a distinct elevation class to the card for each level', () => {
|
|
115
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
116
|
+
const {container} = render(
|
|
117
|
+
<SelectableCard
|
|
118
|
+
label="Card"
|
|
119
|
+
isSelected={false}
|
|
120
|
+
onChange={noop}
|
|
121
|
+
elevation={elevation}>
|
|
122
|
+
Content
|
|
123
|
+
</SelectableCard>,
|
|
124
|
+
);
|
|
125
|
+
return container.firstElementChild!.className;
|
|
126
|
+
};
|
|
127
|
+
const classes = new Set([
|
|
128
|
+
classFor('none'),
|
|
129
|
+
classFor('low'),
|
|
130
|
+
classFor('med'),
|
|
131
|
+
classFor('high'),
|
|
132
|
+
]);
|
|
133
|
+
expect(classes.size).toBe(4);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('still varies elevation while selected (ring composes with elevation)', () => {
|
|
137
|
+
const selectedClassFor = (elevation: 'none' | 'med') => {
|
|
138
|
+
const {container} = render(
|
|
139
|
+
<SelectableCard
|
|
140
|
+
label="Card"
|
|
141
|
+
isSelected
|
|
142
|
+
onChange={noop}
|
|
143
|
+
elevation={elevation}>
|
|
144
|
+
Content
|
|
145
|
+
</SelectableCard>,
|
|
146
|
+
);
|
|
147
|
+
return container.firstElementChild!.className;
|
|
148
|
+
};
|
|
149
|
+
// A selected card at 'med' must differ from a selected card at 'none' —
|
|
150
|
+
// proving the selection ring does not clobber the elevation shadow.
|
|
151
|
+
expect(selectedClassFor('med')).not.toBe(selectedClassFor('none'));
|
|
152
|
+
});
|
|
153
|
+
});
|
|
112
154
|
});
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - /apps/storybook/stories/SelectableCard.stories.tsx (storybook stories)
|
|
15
15
|
* - /packages/cli/templates/blocks/components/Card/SelectableCardShowcase.tsx (showcase block)
|
|
16
16
|
* - /packages/cli/templates/blocks/components/Card/SelectableCardMulti.tsx (block)
|
|
17
|
+
* - /packages/cli/templates/blocks/components/Card/SelectableCardElevated.tsx (block)
|
|
17
18
|
*
|
|
18
19
|
* Composes Card for all visual styling. Adds selection state with
|
|
19
20
|
* an inset box-shadow (zero layout jitter) and useClickableContainer
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
import * as stylex from '@stylexjs/stylex';
|
|
37
38
|
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
38
39
|
import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
|
|
39
|
-
import type {SizeValue, SpacingStep} from '../utils/types';
|
|
40
|
+
import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
|
|
40
41
|
import {mergeProps, mergeRefs} from '../utils';
|
|
41
42
|
import {Card} from '../Card/Card';
|
|
42
43
|
import type {CardVariant} from '../Card/Card';
|
|
@@ -103,51 +104,54 @@ const styles = stylex.create({
|
|
|
103
104
|
whiteSpace: 'nowrap',
|
|
104
105
|
borderWidth: 0,
|
|
105
106
|
},
|
|
106
|
-
// Selection indicator — inset
|
|
107
|
-
// jitter) plus borderColor change on the card's
|
|
107
|
+
// Selection indicator — an inset ring drawn via the card's --_card-ring
|
|
108
|
+
// shadow slot (zero layout jitter) plus a borderColor change on the card's
|
|
109
|
+
// own border for a cohesive look. Routing the ring through --_card-ring
|
|
110
|
+
// (rather than box-shadow directly) lets it compose with the card's
|
|
111
|
+
// elevation instead of clobbering it.
|
|
108
112
|
selected: {
|
|
109
113
|
borderColor: colorVars['--color-accent'],
|
|
110
|
-
|
|
114
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-accent']}`,
|
|
111
115
|
},
|
|
112
116
|
selectedBlue: {
|
|
113
117
|
borderColor: colorVars['--color-border-blue'],
|
|
114
|
-
|
|
118
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-blue']}`,
|
|
115
119
|
},
|
|
116
120
|
selectedCyan: {
|
|
117
121
|
borderColor: colorVars['--color-border-cyan'],
|
|
118
|
-
|
|
122
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-cyan']}`,
|
|
119
123
|
},
|
|
120
124
|
selectedGray: {
|
|
121
125
|
borderColor: colorVars['--color-border-gray'],
|
|
122
|
-
|
|
126
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-gray']}`,
|
|
123
127
|
},
|
|
124
128
|
selectedGreen: {
|
|
125
129
|
borderColor: colorVars['--color-border-green'],
|
|
126
|
-
|
|
130
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-green']}`,
|
|
127
131
|
},
|
|
128
132
|
selectedOrange: {
|
|
129
133
|
borderColor: colorVars['--color-border-orange'],
|
|
130
|
-
|
|
134
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-orange']}`,
|
|
131
135
|
},
|
|
132
136
|
selectedPink: {
|
|
133
137
|
borderColor: colorVars['--color-border-pink'],
|
|
134
|
-
|
|
138
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-pink']}`,
|
|
135
139
|
},
|
|
136
140
|
selectedPurple: {
|
|
137
141
|
borderColor: colorVars['--color-border-purple'],
|
|
138
|
-
|
|
142
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-purple']}`,
|
|
139
143
|
},
|
|
140
144
|
selectedRed: {
|
|
141
145
|
borderColor: colorVars['--color-border-red'],
|
|
142
|
-
|
|
146
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-red']}`,
|
|
143
147
|
},
|
|
144
148
|
selectedTeal: {
|
|
145
149
|
borderColor: colorVars['--color-border-teal'],
|
|
146
|
-
|
|
150
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-teal']}`,
|
|
147
151
|
},
|
|
148
152
|
selectedYellow: {
|
|
149
153
|
borderColor: colorVars['--color-border-yellow'],
|
|
150
|
-
|
|
154
|
+
'--_card-ring': `inset 0 0 0 2px ${colorVars['--color-border-yellow']}`,
|
|
151
155
|
},
|
|
152
156
|
});
|
|
153
157
|
|
|
@@ -228,6 +232,13 @@ export interface SelectableCardProps extends Omit<BaseProps, 'onChange'> {
|
|
|
228
232
|
*/
|
|
229
233
|
variant?: CardVariant;
|
|
230
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Resting elevation — the shadow depth the card sits at.
|
|
237
|
+
* The selection ring composes on top, so a selected card keeps its shadow.
|
|
238
|
+
* @default 'none'
|
|
239
|
+
*/
|
|
240
|
+
elevation?: Elevation;
|
|
241
|
+
|
|
231
242
|
/** Width of the card. */
|
|
232
243
|
width?: SizeValue;
|
|
233
244
|
|
|
@@ -278,6 +289,7 @@ export function SelectableCard({
|
|
|
278
289
|
children,
|
|
279
290
|
padding,
|
|
280
291
|
variant = 'default',
|
|
292
|
+
elevation = 'none',
|
|
281
293
|
width,
|
|
282
294
|
height,
|
|
283
295
|
maxWidth,
|
|
@@ -328,6 +340,7 @@ export function SelectableCard({
|
|
|
328
340
|
maxWidth={maxWidth}
|
|
329
341
|
padding={padding}
|
|
330
342
|
variant={variant}
|
|
343
|
+
elevation={elevation}
|
|
331
344
|
{...mergeProps(
|
|
332
345
|
themeProps('selectable-card', {
|
|
333
346
|
variant,
|
|
@@ -503,6 +503,58 @@ describe('Selector', () => {
|
|
|
503
503
|
expect(search).toHaveAttribute('aria-activedescendant');
|
|
504
504
|
});
|
|
505
505
|
|
|
506
|
+
it('PageDown/PageUp jump the highlight to the last/first filtered option', async () => {
|
|
507
|
+
const user = userEvent.setup();
|
|
508
|
+
render(
|
|
509
|
+
<Selector
|
|
510
|
+
label="Fruit"
|
|
511
|
+
options={OPTIONS}
|
|
512
|
+
value="Apple"
|
|
513
|
+
onChange={() => {}}
|
|
514
|
+
hasSearch
|
|
515
|
+
/>,
|
|
516
|
+
);
|
|
517
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
518
|
+
const search = screen.getByRole('combobox', h);
|
|
519
|
+
// Filter to Apple and Banana so "last" means last *visible* option.
|
|
520
|
+
await user.type(search, 'a');
|
|
521
|
+
const options = screen.getAllByRole('option', h);
|
|
522
|
+
expect(options).toHaveLength(2);
|
|
523
|
+
await user.keyboard('{PageDown}');
|
|
524
|
+
expect(search).toHaveAttribute(
|
|
525
|
+
'aria-activedescendant',
|
|
526
|
+
options[options.length - 1].id,
|
|
527
|
+
);
|
|
528
|
+
await user.keyboard('{PageUp}');
|
|
529
|
+
expect(search).toHaveAttribute('aria-activedescendant', options[0].id);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('Home/End move the search caret, not the option highlight', async () => {
|
|
533
|
+
const user = userEvent.setup();
|
|
534
|
+
render(
|
|
535
|
+
<Selector
|
|
536
|
+
label="Fruit"
|
|
537
|
+
options={OPTIONS}
|
|
538
|
+
value="Apple"
|
|
539
|
+
onChange={() => {}}
|
|
540
|
+
hasSearch
|
|
541
|
+
/>,
|
|
542
|
+
);
|
|
543
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
544
|
+
const search = screen.getByRole<HTMLInputElement>('combobox', h);
|
|
545
|
+
await user.type(search, 'an');
|
|
546
|
+
expect(search.selectionStart).toBe(2);
|
|
547
|
+
const activeBefore = search.getAttribute('aria-activedescendant');
|
|
548
|
+
// Home/End stay on the input for caret movement (APG editable
|
|
549
|
+
// combobox); the option highlight must not move.
|
|
550
|
+
await user.keyboard('{Home}');
|
|
551
|
+
expect(search.selectionStart).toBe(0);
|
|
552
|
+
expect(search.getAttribute('aria-activedescendant')).toBe(activeBefore);
|
|
553
|
+
await user.keyboard('{End}');
|
|
554
|
+
expect(search.selectionStart).toBe(2);
|
|
555
|
+
expect(search.getAttribute('aria-activedescendant')).toBe(activeBefore);
|
|
556
|
+
});
|
|
557
|
+
|
|
506
558
|
it('does not render search input when hasSearch is false', async () => {
|
|
507
559
|
const user = userEvent.setup();
|
|
508
560
|
render(
|
|
@@ -722,6 +774,23 @@ describe('Selector', () => {
|
|
|
722
774
|
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
723
775
|
});
|
|
724
776
|
|
|
777
|
+
it('End/Home jump the highlight to the last/first option (non-search)', async () => {
|
|
778
|
+
const user = userEvent.setup();
|
|
779
|
+
render(<Selector label="Fruit" options={OPTIONS} />);
|
|
780
|
+
|
|
781
|
+
const trigger = screen.getByRole('combobox');
|
|
782
|
+
await user.click(trigger);
|
|
783
|
+
const options = screen.getAllByRole('option', h);
|
|
784
|
+
|
|
785
|
+
await user.keyboard('{End}');
|
|
786
|
+
expect(trigger).toHaveAttribute(
|
|
787
|
+
'aria-activedescendant',
|
|
788
|
+
options[options.length - 1].id,
|
|
789
|
+
);
|
|
790
|
+
await user.keyboard('{Home}');
|
|
791
|
+
expect(trigger).toHaveAttribute('aria-activedescendant', options[0].id);
|
|
792
|
+
});
|
|
793
|
+
|
|
725
794
|
it('opens and selects an option with Enter (no mouse)', async () => {
|
|
726
795
|
const user = userEvent.setup();
|
|
727
796
|
const onChange = vi.fn();
|
|
@@ -858,10 +858,14 @@ export function Selector<T extends SelectorOptionType>(
|
|
|
858
858
|
onChange={handleSearchChange}
|
|
859
859
|
onKeyDown={e => {
|
|
860
860
|
// Arrow keys navigate options; Enter selects; Escape/Tab close.
|
|
861
|
-
// Home/End are left to the input for caret movement
|
|
861
|
+
// Home/End are left to the input for caret movement (APG editable
|
|
862
|
+
// combobox); PageUp/PageDown are the sanctioned substitute for
|
|
863
|
+
// jumping to the first/last option.
|
|
862
864
|
if (
|
|
863
865
|
e.key === 'ArrowDown' ||
|
|
864
866
|
e.key === 'ArrowUp' ||
|
|
867
|
+
e.key === 'PageUp' ||
|
|
868
|
+
e.key === 'PageDown' ||
|
|
865
869
|
e.key === 'Enter' ||
|
|
866
870
|
e.key === 'Escape' ||
|
|
867
871
|
e.key === 'Tab'
|
|
@@ -20,7 +20,7 @@ export const docs = {
|
|
|
20
20
|
name: 'icon',
|
|
21
21
|
type: 'IconType',
|
|
22
22
|
description:
|
|
23
|
-
'Icon displayed before the label. See `
|
|
23
|
+
'Icon displayed before the label. See `astryx docs icons` for valid semantic names.',
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: 'description',
|
package/src/Selector/hooks.ts
CHANGED
|
@@ -318,6 +318,23 @@ export function useCombobox({
|
|
|
318
318
|
}
|
|
319
319
|
break;
|
|
320
320
|
|
|
321
|
+
// PageUp/PageDown mirror Home/End. In search mode Home/End stay on
|
|
322
|
+
// the input for caret movement (APG editable combobox), so these are
|
|
323
|
+
// the sanctioned substitute for jumping to the first/last option.
|
|
324
|
+
case 'PageUp':
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
if (isOpen && enabledIndices.length > 0) {
|
|
327
|
+
setHighlightedIndex(enabledIndices[0]);
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
|
|
331
|
+
case 'PageDown':
|
|
332
|
+
e.preventDefault();
|
|
333
|
+
if (isOpen && enabledIndices.length > 0) {
|
|
334
|
+
setHighlightedIndex(enabledIndices[enabledIndices.length - 1]);
|
|
335
|
+
}
|
|
336
|
+
break;
|
|
337
|
+
|
|
321
338
|
case 'Delete':
|
|
322
339
|
case 'Backspace':
|
|
323
340
|
// Keyboard equivalent of the clear button (comboboxes-2): clear the
|