@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
package/src/Banner/Banner.tsx
CHANGED
|
@@ -46,8 +46,10 @@ import {
|
|
|
46
46
|
borderVars,
|
|
47
47
|
durationVars,
|
|
48
48
|
easeVars,
|
|
49
|
+
shadowVars,
|
|
49
50
|
} from '../theme/tokens.stylex';
|
|
50
51
|
import {mergeProps} from '../utils';
|
|
52
|
+
import type {Elevation} from '../utils/types';
|
|
51
53
|
import {edgeCompSlot} from '../Layout/edgeCompensation.stylex';
|
|
52
54
|
import {themeProps} from '../utils/themeProps';
|
|
53
55
|
import {useTranslator} from '../i18n';
|
|
@@ -157,6 +159,13 @@ export interface BannerProps extends BaseProps<HTMLDivElement> {
|
|
|
157
159
|
* @default 'card'
|
|
158
160
|
*/
|
|
159
161
|
container?: BannerContainer;
|
|
162
|
+
/**
|
|
163
|
+
* Resting elevation — the shadow depth the banner sits at. Use for a
|
|
164
|
+
* floating banner that hovers above content. `none` is the default inline
|
|
165
|
+
* banner.
|
|
166
|
+
* @default 'none'
|
|
167
|
+
*/
|
|
168
|
+
elevation?: Elevation;
|
|
160
169
|
/**
|
|
161
170
|
* Whether the content area (children) starts expanded.
|
|
162
171
|
* Only relevant when children are provided.
|
|
@@ -215,6 +224,11 @@ const styles = stylex.create({
|
|
|
215
224
|
flexDirection: 'column',
|
|
216
225
|
fontFamily: 'inherit',
|
|
217
226
|
},
|
|
227
|
+
// When elevated, a card-container banner rounds its root so the shadow
|
|
228
|
+
// follows the same silhouette as the header/content border-radius.
|
|
229
|
+
rootElevatedCard: {
|
|
230
|
+
borderRadius: radiusVars['--radius-container'],
|
|
231
|
+
},
|
|
218
232
|
// Header area — colored status background with icon, title, description, actions
|
|
219
233
|
// This is the primary theme target ('banner')
|
|
220
234
|
header: {
|
|
@@ -323,6 +337,18 @@ const statusStyles = stylex.create({
|
|
|
323
337
|
},
|
|
324
338
|
});
|
|
325
339
|
|
|
340
|
+
// Resting elevation for the banner. Applied to the root so the shadow wraps
|
|
341
|
+
// the whole banner (header + optional content). 'none' is the default and
|
|
342
|
+
// leaves the layout-only root untouched. For the `card` container the root is
|
|
343
|
+
// rounded (rootElevatedCard) so the shadow follows the card silhouette; the
|
|
344
|
+
// full-width `section` container stays square.
|
|
345
|
+
const elevationStyles = stylex.create({
|
|
346
|
+
none: {boxShadow: 'none'},
|
|
347
|
+
low: {boxShadow: shadowVars['--shadow-low']},
|
|
348
|
+
med: {boxShadow: shadowVars['--shadow-med']},
|
|
349
|
+
high: {boxShadow: shadowVars['--shadow-high']},
|
|
350
|
+
});
|
|
351
|
+
|
|
326
352
|
// =============================================================================
|
|
327
353
|
// Component
|
|
328
354
|
// =============================================================================
|
|
@@ -381,6 +407,7 @@ export function Banner({
|
|
|
381
407
|
onDismiss,
|
|
382
408
|
endContent,
|
|
383
409
|
container = 'card',
|
|
410
|
+
elevation = 'none',
|
|
384
411
|
defaultIsExpanded = false,
|
|
385
412
|
children,
|
|
386
413
|
xstyle,
|
|
@@ -429,7 +456,16 @@ export function Banner({
|
|
|
429
456
|
<div
|
|
430
457
|
ref={ref}
|
|
431
458
|
role={role}
|
|
432
|
-
{...mergeProps(
|
|
459
|
+
{...mergeProps(
|
|
460
|
+
stylex.props(
|
|
461
|
+
styles.root,
|
|
462
|
+
elevationStyles[elevation],
|
|
463
|
+
isCard && elevation !== 'none' && styles.rootElevatedCard,
|
|
464
|
+
xstyle,
|
|
465
|
+
),
|
|
466
|
+
className,
|
|
467
|
+
style,
|
|
468
|
+
)}
|
|
433
469
|
{...rest}>
|
|
434
470
|
{/* Header: colored status background — primary theme target ('banner') */}
|
|
435
471
|
<div
|
|
@@ -474,8 +510,16 @@ export function Banner({
|
|
|
474
510
|
<Button
|
|
475
511
|
variant="ghost"
|
|
476
512
|
size="sm"
|
|
477
|
-
label={
|
|
478
|
-
|
|
513
|
+
label={
|
|
514
|
+
isExpanded
|
|
515
|
+
? t('@astryx.banner.collapse')
|
|
516
|
+
: t('@astryx.banner.expand')
|
|
517
|
+
}
|
|
518
|
+
tooltip={
|
|
519
|
+
isExpanded
|
|
520
|
+
? t('@astryx.banner.collapse')
|
|
521
|
+
: t('@astryx.banner.expand')
|
|
522
|
+
}
|
|
479
523
|
icon={
|
|
480
524
|
<span
|
|
481
525
|
{...stylex.props(
|
|
@@ -51,6 +51,13 @@ export const docs = {
|
|
|
51
51
|
description: 'Size variant.',
|
|
52
52
|
default: "'md'",
|
|
53
53
|
},
|
|
54
|
+
{
|
|
55
|
+
name: 'elevation',
|
|
56
|
+
type: "'none' | 'low' | 'med' | 'high'",
|
|
57
|
+
description:
|
|
58
|
+
'Resting shadow depth for floating buttons (e.g. a FAB). `none` is the default flat button; `low`/`med`/`high` map to the shadow token scale. Ignored inside a ButtonGroup, where elevation is owned by the group.',
|
|
59
|
+
default: "'none'",
|
|
60
|
+
},
|
|
54
61
|
{
|
|
55
62
|
name: 'type',
|
|
56
63
|
type: "'button' | 'submit' | 'reset'",
|
|
@@ -199,6 +206,7 @@ export const docsZh = {
|
|
|
199
206
|
default: "'secondary'",
|
|
200
207
|
},
|
|
201
208
|
{name: 'size', type: "'sm' | 'md' | 'lg'", description: '尺寸变体。', default: "'md'"},
|
|
209
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '浮动按钮(如 FAB)的静止阴影深度。`none` 为默认扁平按钮;在 ButtonGroup 内忽略。', default: "'none'"},
|
|
202
210
|
{name: 'type', type: "'button' | 'submit' | 'reset'", description: 'HTML 按钮类型属性。', default: "'button'"},
|
|
203
211
|
{name: 'name', type: 'string', description: '表单提交的 HTML name 属性。'},
|
|
204
212
|
{name: 'value', type: 'string | number | readonly string[]', description: '表单提交的 HTML value 属性。'},
|
|
@@ -271,6 +279,7 @@ export const docsDense = {
|
|
|
271
279
|
label: 'accessible label; visible text by default, aria-label when isIconOnly',
|
|
272
280
|
variant: 'visual style variant',
|
|
273
281
|
size: 'size variant',
|
|
282
|
+
elevation: 'resting shadow depth for floating buttons/FABs: none|low|med|high; ignored inside ButtonGroup',
|
|
274
283
|
type: 'HTML button type; defaults to "button"',
|
|
275
284
|
name: 'HTML name for form submission',
|
|
276
285
|
displayName: 'HTML name for form submission',
|
|
@@ -445,4 +445,53 @@ describe('Button', () => {
|
|
|
445
445
|
rerender(<Button label="Submit" isLoading />);
|
|
446
446
|
expect(liveRegion).toHaveTextContent('Loading');
|
|
447
447
|
});
|
|
448
|
+
|
|
449
|
+
describe('elevation', () => {
|
|
450
|
+
it('renders a distinct class for each elevation level', () => {
|
|
451
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
452
|
+
const {container} = render(
|
|
453
|
+
<Button label="Save" elevation={elevation} />,
|
|
454
|
+
);
|
|
455
|
+
return container.querySelector('button')!.className;
|
|
456
|
+
};
|
|
457
|
+
const classes = new Set([
|
|
458
|
+
classFor('none'),
|
|
459
|
+
classFor('low'),
|
|
460
|
+
classFor('med'),
|
|
461
|
+
classFor('high'),
|
|
462
|
+
]);
|
|
463
|
+
expect(classes.size).toBe(4);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it('defaults to flat (elevation none)', () => {
|
|
467
|
+
const {container: def} = render(<Button label="Save" />);
|
|
468
|
+
const {container: none} = render(
|
|
469
|
+
<Button label="Save" elevation="none" />,
|
|
470
|
+
);
|
|
471
|
+
expect(def.querySelector('button')!.className).toBe(
|
|
472
|
+
none.querySelector('button')!.className,
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('exposes aria-busy on the link-rendered button while loading', () => {
|
|
478
|
+
// Non-interruptible loading disables the button, which falls back to
|
|
479
|
+
// <button> rendering — so an anchor only shows loading when interruptible.
|
|
480
|
+
render(
|
|
481
|
+
<Button
|
|
482
|
+
label="Docs"
|
|
483
|
+
href="https://example.com"
|
|
484
|
+
isLoading
|
|
485
|
+
isInterruptible
|
|
486
|
+
/>,
|
|
487
|
+
);
|
|
488
|
+
const link = screen.getByRole('link');
|
|
489
|
+
expect(link).toHaveAttribute('aria-busy', 'true');
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('does not set aria-busy on the link-rendered button when not loading', () => {
|
|
493
|
+
render(<Button label="Docs" href="https://example.com" />);
|
|
494
|
+
const link = screen.getByRole('link');
|
|
495
|
+
expect(link).not.toHaveAttribute('aria-busy');
|
|
496
|
+
});
|
|
448
497
|
});
|
package/src/Button/Button.tsx
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import {useRef, useTransition, type ReactNode} from 'react';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
|
-
import type {SizeValue} from '../utils/types';
|
|
23
|
+
import type {Elevation, SizeValue} from '../utils/types';
|
|
24
24
|
import * as stylex from '@stylexjs/stylex';
|
|
25
25
|
import {useTooltip} from '../Tooltip/useTooltip';
|
|
26
26
|
import {
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
easeVars,
|
|
34
34
|
fontWeightVars,
|
|
35
35
|
typeScaleVars,
|
|
36
|
+
shadowVars,
|
|
36
37
|
} from '../theme/tokens.stylex';
|
|
37
38
|
import {Spinner} from '../Spinner';
|
|
38
39
|
import {VisuallyHidden} from '../VisuallyHidden';
|
|
@@ -160,6 +161,18 @@ const iconSizeStyles = stylex.create({
|
|
|
160
161
|
lg: {width: 20, height: 20, fontSize: 20},
|
|
161
162
|
});
|
|
162
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Resting elevation for floating buttons (e.g. a FAB). `none` is the default
|
|
166
|
+
* flat button; `low`/`med`/`high` map to the shadow token scale. 'none' stays
|
|
167
|
+
* a literal so it never conflicts with a variant's background layering.
|
|
168
|
+
*/
|
|
169
|
+
const elevationStyles = stylex.create({
|
|
170
|
+
none: {boxShadow: 'none'},
|
|
171
|
+
low: {boxShadow: shadowVars['--shadow-low']},
|
|
172
|
+
med: {boxShadow: shadowVars['--shadow-med']},
|
|
173
|
+
high: {boxShadow: shadowVars['--shadow-high']},
|
|
174
|
+
});
|
|
175
|
+
|
|
163
176
|
/**
|
|
164
177
|
* Variant styles using backgroundImage for layered colors
|
|
165
178
|
* Pseudo-classes are nested within properties per StyleX recommendation
|
|
@@ -307,6 +320,12 @@ export interface ButtonProps extends BaseProps<HTMLButtonElement> {
|
|
|
307
320
|
* @default 'md'
|
|
308
321
|
*/
|
|
309
322
|
size?: ButtonSize;
|
|
323
|
+
/**
|
|
324
|
+
* Resting elevation — the shadow depth the button sits at. Use for floating
|
|
325
|
+
* buttons (FABs) that hover above content. `none` is the default flat button.
|
|
326
|
+
* @default 'none'
|
|
327
|
+
*/
|
|
328
|
+
elevation?: Elevation;
|
|
310
329
|
/**
|
|
311
330
|
* Whether the button is disabled.
|
|
312
331
|
* @default false
|
|
@@ -578,6 +597,7 @@ export function Button({
|
|
|
578
597
|
icon,
|
|
579
598
|
isIconOnly = false,
|
|
580
599
|
width,
|
|
600
|
+
elevation = 'none',
|
|
581
601
|
children,
|
|
582
602
|
endContent,
|
|
583
603
|
tooltip,
|
|
@@ -691,6 +711,9 @@ export function Button({
|
|
|
691
711
|
(buttonGroup.orientation === 'horizontal'
|
|
692
712
|
? groupStyles.onSolidHorizontal
|
|
693
713
|
: groupStyles.onSolidVertical),
|
|
714
|
+
// Standalone floating buttons only — a grouped button's elevation is owned
|
|
715
|
+
// by the ButtonGroup so the shared surface lifts as one unit.
|
|
716
|
+
!buttonGroup && elevationStyles[elevation],
|
|
694
717
|
width != null && dynamicStyles.width(width),
|
|
695
718
|
xstyle,
|
|
696
719
|
);
|
|
@@ -786,6 +809,7 @@ export function Button({
|
|
|
786
809
|
{...ariaLabelProp}
|
|
787
810
|
{...describedByProp}
|
|
788
811
|
{...edgeCompAttr}
|
|
812
|
+
aria-busy={isLoadingState || undefined}
|
|
789
813
|
onClick={handleClick}>
|
|
790
814
|
{buttonContent}
|
|
791
815
|
</LinkComponent>
|
|
@@ -29,6 +29,7 @@ export const docs = {
|
|
|
29
29
|
{name: 'orientation', type: "'horizontal' | 'vertical'", description: 'Layout direction of the button group.', default: "'horizontal'"},
|
|
30
30
|
{name: 'size', type: "'sm' | 'md' | 'lg'", description: 'Default size for buttons in the group. Individual buttons can override.', default: "'md'"},
|
|
31
31
|
{name: 'isDisabled', type: 'boolean', description: 'Whether all buttons in the group are disabled.', default: 'false'},
|
|
32
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: 'Resting shadow depth for the whole group. The connected buttons share one surface, so the shadow lifts them as a unit. Use for a group that floats above content.', default: "'none'"},
|
|
32
33
|
{name: 'ref', type: 'React.Ref<HTMLDivElement>', description: 'Ref forwarded to the root element.'},
|
|
33
34
|
{name: 'xstyle', type: 'StyleXStyles', description: 'StyleX styles for layout customization. Must be a stylex.create() value.'},
|
|
34
35
|
{name: 'data-testid', type: 'string', description: 'Test selector for automated testing frameworks.'},
|
|
@@ -66,6 +67,7 @@ export const docsZh = {
|
|
|
66
67
|
orientation: '按钮组的布局方向。',
|
|
67
68
|
size: '组内按钮的默认尺寸。单个按钮可覆盖。',
|
|
68
69
|
isDisabled: '组内所有按钮是否禁用。',
|
|
70
|
+
elevation: '整个组的静止阴影深度。连接的按钮共享一个表面,阴影将它们作为整体抬起。',
|
|
69
71
|
ref: '转发到根元素的引用。',
|
|
70
72
|
xstyle: 'StyleX 样式,用于布局自定义。必须是 stylex.create() 的值。',
|
|
71
73
|
'data-testid': '自动化测试的选择器。',
|
|
@@ -116,6 +118,7 @@ export const docsDense = {
|
|
|
116
118
|
orientation: 'layout direction',
|
|
117
119
|
size: 'default btn size; individual btns override',
|
|
118
120
|
isDisabled: 'all btns disabled',
|
|
121
|
+
elevation: 'resting shadow depth for whole group: none|low|med|high',
|
|
119
122
|
xstyle: 'StyleX layout styles; must be stylex.create() value',
|
|
120
123
|
'data-testid': 'test selector',
|
|
121
124
|
},
|
|
@@ -572,4 +572,41 @@ describe('ButtonGroup', () => {
|
|
|
572
572
|
expect(hasRoundedTrailingCorners(save)).toBe(false);
|
|
573
573
|
});
|
|
574
574
|
});
|
|
575
|
+
|
|
576
|
+
describe('elevation', () => {
|
|
577
|
+
it('renders a distinct class on the group for each elevation level', () => {
|
|
578
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
579
|
+
const {container} = render(
|
|
580
|
+
<ButtonGroup label="Actions" elevation={elevation}>
|
|
581
|
+
<Button label="One" />
|
|
582
|
+
<Button label="Two" />
|
|
583
|
+
</ButtonGroup>,
|
|
584
|
+
);
|
|
585
|
+
return container.querySelector('[role="group"]')!.className;
|
|
586
|
+
};
|
|
587
|
+
const classes = new Set([
|
|
588
|
+
classFor('none'),
|
|
589
|
+
classFor('low'),
|
|
590
|
+
classFor('med'),
|
|
591
|
+
classFor('high'),
|
|
592
|
+
]);
|
|
593
|
+
expect(classes.size).toBe(4);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('defaults to flat (elevation none)', () => {
|
|
597
|
+
const {container: def} = render(
|
|
598
|
+
<ButtonGroup label="Actions">
|
|
599
|
+
<Button label="One" />
|
|
600
|
+
</ButtonGroup>,
|
|
601
|
+
);
|
|
602
|
+
const {container: none} = render(
|
|
603
|
+
<ButtonGroup label="Actions" elevation="none">
|
|
604
|
+
<Button label="One" />
|
|
605
|
+
</ButtonGroup>,
|
|
606
|
+
);
|
|
607
|
+
expect(def.querySelector('[role="group"]')!.className).toBe(
|
|
608
|
+
none.querySelector('[role="group"]')!.className,
|
|
609
|
+
);
|
|
610
|
+
});
|
|
611
|
+
});
|
|
575
612
|
});
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
import {useMemo, type ReactNode} from 'react';
|
|
25
25
|
import * as stylex from '@stylexjs/stylex';
|
|
26
26
|
import type {ButtonSize} from '../Button';
|
|
27
|
+
import {radiusVars, shadowVars} from '../theme/tokens.stylex';
|
|
28
|
+
import type {Elevation} from '../utils/types';
|
|
27
29
|
import {SizeProvider, useSize} from '../SizeContext/SizeContext';
|
|
28
30
|
import {useListFocus} from '../hooks/useListFocus';
|
|
29
31
|
import {mergeProps, mergeRefs, composeEventHandlers} from '../utils';
|
|
@@ -63,6 +65,14 @@ export interface ButtonGroupProps extends BaseProps<HTMLDivElement> {
|
|
|
63
65
|
*/
|
|
64
66
|
size?: ButtonSize;
|
|
65
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Resting elevation for the group. The connected buttons share one surface,
|
|
70
|
+
* so the shadow sits on the group and lifts them together. Use for a floating
|
|
71
|
+
* group of actions above content.
|
|
72
|
+
* @default 'none'
|
|
73
|
+
*/
|
|
74
|
+
elevation?: Elevation;
|
|
75
|
+
|
|
66
76
|
/**
|
|
67
77
|
* Whether all buttons in the group are disabled.
|
|
68
78
|
* @default false
|
|
@@ -89,6 +99,26 @@ const styles = stylex.create({
|
|
|
89
99
|
},
|
|
90
100
|
});
|
|
91
101
|
|
|
102
|
+
// Resting elevation for the whole group — the connected buttons share one
|
|
103
|
+
// surface, so the shadow sits on the group wrapper and lifts them as a unit.
|
|
104
|
+
// The wrapper takes the element radius so the shadow follows the group's
|
|
105
|
+
// rounded outer corners rather than a bare rectangle. 'none' is the default.
|
|
106
|
+
const elevationStyles = stylex.create({
|
|
107
|
+
none: {boxShadow: 'none'},
|
|
108
|
+
low: {
|
|
109
|
+
boxShadow: shadowVars['--shadow-low'],
|
|
110
|
+
borderRadius: radiusVars['--radius-element'],
|
|
111
|
+
},
|
|
112
|
+
med: {
|
|
113
|
+
boxShadow: shadowVars['--shadow-med'],
|
|
114
|
+
borderRadius: radiusVars['--radius-element'],
|
|
115
|
+
},
|
|
116
|
+
high: {
|
|
117
|
+
boxShadow: shadowVars['--shadow-high'],
|
|
118
|
+
borderRadius: radiusVars['--radius-element'],
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
92
122
|
// =============================================================================
|
|
93
123
|
// Component
|
|
94
124
|
// =============================================================================
|
|
@@ -129,6 +159,7 @@ export function ButtonGroup({
|
|
|
129
159
|
orientation = 'horizontal',
|
|
130
160
|
size: sizeProp,
|
|
131
161
|
isDisabled = false,
|
|
162
|
+
elevation = 'none',
|
|
132
163
|
xstyle,
|
|
133
164
|
className,
|
|
134
165
|
style,
|
|
@@ -160,6 +191,7 @@ export function ButtonGroup({
|
|
|
160
191
|
stylex.props(
|
|
161
192
|
styles.group,
|
|
162
193
|
orientation === 'vertical' && styles.vertical,
|
|
194
|
+
elevationStyles[elevation],
|
|
163
195
|
xstyle,
|
|
164
196
|
),
|
|
165
197
|
className,
|
package/src/Card/Card.doc.mjs
CHANGED
|
@@ -67,6 +67,13 @@ export const docs = {
|
|
|
67
67
|
'Background color variant. `default` uses the standard card background. `transparent` drops the background entirely. `muted` uses the muted background for de-emphasised cards. The non-semantic variants use the corresponding `--color-background-<name>` token.',
|
|
68
68
|
default: "'default'",
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
name: 'elevation',
|
|
72
|
+
type: "'none' | 'low' | 'med' | 'high'",
|
|
73
|
+
description:
|
|
74
|
+
'Resting shadow depth. `none` is flat; `low`/`med`/`high` map to the shadow token scale. Raise a card only when it needs to float above surrounding content.',
|
|
75
|
+
default: "'none'",
|
|
76
|
+
},
|
|
70
77
|
],
|
|
71
78
|
playground: {
|
|
72
79
|
defaults: {
|
|
@@ -127,6 +134,7 @@ export const docsZh = {
|
|
|
127
134
|
{name: 'minHeight', type: 'SizeValue', description: '卡片最小高度。'},
|
|
128
135
|
{name: 'children', type: 'ReactNode', description: '在卡片内部渲染的内容。'},
|
|
129
136
|
{name: 'padding', type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10', description: '使用间距比例的内边距。', default: '4'},
|
|
137
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '静止阴影深度。`none` 为扁平;`low`/`med`/`high` 对应阴影令牌比例。', default: "'none'"},
|
|
130
138
|
],
|
|
131
139
|
theming: {
|
|
132
140
|
container: true,
|
|
@@ -170,5 +178,6 @@ export const docsDense = {
|
|
|
170
178
|
children: 'content inside card',
|
|
171
179
|
padding: 'internal padding via spacing scale',
|
|
172
180
|
variant: 'background color variant; `default` = standard card bg, `transparent` = no background at all, `muted` = muted bg for de-emphasised cards; non-semantic variants use the corresponding `--color-background-<name>` token',
|
|
181
|
+
elevation: 'resting shadow depth: none (flat) | low | med | high (shadow token scale). Raise only to float above content.',
|
|
173
182
|
},
|
|
174
183
|
};
|
package/src/Card/Card.test.tsx
CHANGED
|
@@ -17,11 +17,29 @@ describe('Card', () => {
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
it('renders transparent variant with variant class', () => {
|
|
20
|
-
const {container} = render(
|
|
21
|
-
<Card variant="transparent">Content</Card>,
|
|
22
|
-
);
|
|
20
|
+
const {container} = render(<Card variant="transparent">Content</Card>);
|
|
23
21
|
const root = container.firstElementChild!;
|
|
24
22
|
expect(root.className).toContain('astryx-card');
|
|
25
23
|
expect(root.className).toContain('transparent');
|
|
26
24
|
});
|
|
25
|
+
|
|
26
|
+
it('applies a distinct class for each elevation level', () => {
|
|
27
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
28
|
+
const {container} = render(<Card elevation={elevation}>C</Card>);
|
|
29
|
+
return container.firstElementChild!.className;
|
|
30
|
+
};
|
|
31
|
+
const none = classFor('none');
|
|
32
|
+
const low = classFor('low');
|
|
33
|
+
const med = classFor('med');
|
|
34
|
+
const high = classFor('high');
|
|
35
|
+
expect(new Set([none, low, med, high]).size).toBe(4);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('defaults to flat (elevation none) — same class as explicit none', () => {
|
|
39
|
+
const {container: defaultContainer} = render(<Card>C</Card>);
|
|
40
|
+
const {container: noneContainer} = render(<Card elevation="none">C</Card>);
|
|
41
|
+
expect(defaultContainer.firstElementChild!.className).toBe(
|
|
42
|
+
noneContainer.firstElementChild!.className,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
27
45
|
});
|
package/src/Card/Card.tsx
CHANGED
|
@@ -17,7 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
import type {ReactNode} from 'react';
|
|
19
19
|
import * as stylex from '@stylexjs/stylex';
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
borderVars,
|
|
22
|
+
colorVars,
|
|
23
|
+
radiusVars,
|
|
24
|
+
shadowVars,
|
|
25
|
+
} from '../theme/tokens.stylex';
|
|
21
26
|
import {container} from '../Layout/container.stylex';
|
|
22
27
|
import type {SpacingToken} from '../Layout/container.stylex';
|
|
23
28
|
import {
|
|
@@ -27,7 +32,7 @@ import {
|
|
|
27
32
|
containerPaddingBlockEndVarStyles,
|
|
28
33
|
spacingStepToToken,
|
|
29
34
|
} from '../Layout/padding.stylex';
|
|
30
|
-
import type {SizeValue, SpacingStep} from '../utils/types';
|
|
35
|
+
import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
|
|
31
36
|
import {mergeProps} from '../utils';
|
|
32
37
|
import type {BaseProps} from '../BaseProps';
|
|
33
38
|
import {themeProps} from '../utils/themeProps';
|
|
@@ -73,6 +78,13 @@ const styles = stylex.create({
|
|
|
73
78
|
'--_card-radius': radiusVars['--radius-container'],
|
|
74
79
|
borderRadius: 'var(--_card-radius)',
|
|
75
80
|
overflow: 'clip',
|
|
81
|
+
// Resting elevation is set via --_card-elevation (see elevationStyles).
|
|
82
|
+
// The shadow list also reads --_card-ring so composing surfaces — e.g.
|
|
83
|
+
// SelectableCard's inset selection ring — can layer their own shadow
|
|
84
|
+
// alongside elevation instead of clobbering the single box-shadow property.
|
|
85
|
+
// Unset vars fall back to a transparent no-op shadow.
|
|
86
|
+
boxShadow:
|
|
87
|
+
'var(--_card-ring, 0 0 transparent), var(--_card-elevation, 0 0 transparent)',
|
|
76
88
|
},
|
|
77
89
|
// The border is drawn *inside* the padding — its width is subtracted from
|
|
78
90
|
// each side — so total inset (border + padding) equals the padding token
|
|
@@ -135,6 +147,18 @@ const variantStyles = stylex.create({
|
|
|
135
147
|
},
|
|
136
148
|
});
|
|
137
149
|
|
|
150
|
+
// Elevation → shadow-token map. Sets the private --_card-elevation variable
|
|
151
|
+
// (not box-shadow directly) so it composes with --_card-ring in the shadow
|
|
152
|
+
// list above — a selection ring and a resting elevation coexist without one
|
|
153
|
+
// overwriting the other. 'none' is a transparent no-op (not the CSS literal
|
|
154
|
+
// `none`, which would be invalid inside the comma-separated shadow list).
|
|
155
|
+
const elevationStyles = stylex.create({
|
|
156
|
+
none: {'--_card-elevation': '0 0 transparent'},
|
|
157
|
+
low: {'--_card-elevation': shadowVars['--shadow-low']},
|
|
158
|
+
med: {'--_card-elevation': shadowVars['--shadow-med']},
|
|
159
|
+
high: {'--_card-elevation': shadowVars['--shadow-high']},
|
|
160
|
+
});
|
|
161
|
+
|
|
138
162
|
// Dynamic styles for sizing props
|
|
139
163
|
const dynamicStyles = stylex.create({
|
|
140
164
|
sizing: (
|
|
@@ -208,6 +232,13 @@ export interface CardProps extends BaseProps<HTMLDivElement> {
|
|
|
208
232
|
* @default 'default'
|
|
209
233
|
*/
|
|
210
234
|
variant?: CardVariant;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Resting elevation — the shadow depth the card sits at.
|
|
238
|
+
* `none` is flat; `low`/`med`/`high` map to the shadow token scale.
|
|
239
|
+
* @default 'none'
|
|
240
|
+
*/
|
|
241
|
+
elevation?: Elevation;
|
|
211
242
|
}
|
|
212
243
|
|
|
213
244
|
/**
|
|
@@ -252,6 +283,7 @@ export function Card({
|
|
|
252
283
|
children,
|
|
253
284
|
padding,
|
|
254
285
|
variant = 'default',
|
|
286
|
+
elevation = 'none',
|
|
255
287
|
xstyle,
|
|
256
288
|
className,
|
|
257
289
|
style,
|
|
@@ -274,6 +306,7 @@ export function Card({
|
|
|
274
306
|
stylex.props(
|
|
275
307
|
styles.card,
|
|
276
308
|
variantStyles[variant],
|
|
309
|
+
elevationStyles[elevation],
|
|
277
310
|
hasFixedHeight && styles.scrollable,
|
|
278
311
|
dynamicStyles.sizing(
|
|
279
312
|
width ?? null,
|
|
@@ -14,6 +14,7 @@ export const docs = {
|
|
|
14
14
|
{guidance: true, description: 'Enable scroll-snap when each item should land precisely at the start edge, like a gallery or product list.'},
|
|
15
15
|
{guidance: true, description: 'Always provide an aria-label that describes what the carousel contains, like "Featured products" or "Team members".'},
|
|
16
16
|
{guidance: true, description: 'Use a consistent gap and item width so the carousel looks intentional, not like content overflowing by accident.'},
|
|
17
|
+
{guidance: true, description: 'Trust the built-in navigation: trackpad users can swipe horizontally, and mouse users can hold Shift while scrolling the wheel to move through items.'},
|
|
17
18
|
{guidance: false, description: 'Use a carousel for content every user must see. Not everyone scrolls horizontally, so put critical content above the fold.'},
|
|
18
19
|
{guidance: false, description: 'Auto-advance items. Let the user scroll at their own pace.'},
|
|
19
20
|
{guidance: false, description: 'Nest carousels. A carousel inside a carousel is confusing and breaks keyboard navigation.'},
|