@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
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@astryx.pagination.previous": {
|
|
3
|
+
"defaultMessage": "Aller à la page précédente",
|
|
4
|
+
"description": "Aria label for the previous-page button."
|
|
5
|
+
},
|
|
6
|
+
"@astryx.pagination.next": {
|
|
7
|
+
"defaultMessage": "Aller à la page suivante",
|
|
8
|
+
"description": "Aria label for the next-page button."
|
|
9
|
+
}
|
|
10
|
+
}
|
package/locales/pseudo.json
CHANGED
|
@@ -197,6 +197,9 @@
|
|
|
197
197
|
"@astryx.carousel.scrollRight": {
|
|
198
198
|
"defaultMessage": "⟦Šçřółł říĝĥţ⟧"
|
|
199
199
|
},
|
|
200
|
+
"@astryx.carousel.slideLabel": {
|
|
201
|
+
"defaultMessage": "⟦Šłíðé {current, number} óƒ {total, number}⟧"
|
|
202
|
+
},
|
|
200
203
|
"@astryx.chat.status.sending": {
|
|
201
204
|
"defaultMessage": "⟦Šéñðíñĝ⟧"
|
|
202
205
|
},
|
|
@@ -308,6 +311,9 @@
|
|
|
308
311
|
"@astryx.table.selection.selectRow": {
|
|
309
312
|
"defaultMessage": "⟦Šéłéçţ řóŵ⟧"
|
|
310
313
|
},
|
|
314
|
+
"@astryx.table.selection.selectRowNamed": {
|
|
315
|
+
"defaultMessage": "⟦Šéłéçţ {label}⟧"
|
|
316
|
+
},
|
|
311
317
|
"@astryx.table.sort.ascending": {
|
|
312
318
|
"defaultMessage": "⟦Šóřţ àšçéñðíñĝ⟧"
|
|
313
319
|
},
|
|
@@ -317,6 +323,21 @@
|
|
|
317
323
|
"@astryx.table.sort.clear": {
|
|
318
324
|
"defaultMessage": "⟦Çłéàř šóřţ⟧"
|
|
319
325
|
},
|
|
326
|
+
"@astryx.table.sort.direction.ascending": {
|
|
327
|
+
"defaultMessage": "⟦àšçéñðíñĝ⟧"
|
|
328
|
+
},
|
|
329
|
+
"@astryx.table.sort.direction.descending": {
|
|
330
|
+
"defaultMessage": "⟦ðéšçéñðíñĝ⟧"
|
|
331
|
+
},
|
|
332
|
+
"@astryx.table.sort.sortBy": {
|
|
333
|
+
"defaultMessage": "⟦Šóřţ ƀý {label}⟧"
|
|
334
|
+
},
|
|
335
|
+
"@astryx.table.sort.sortedBy": {
|
|
336
|
+
"defaultMessage": "⟦Šóřţ ƀý {label}, šóřţéð {direction}⟧"
|
|
337
|
+
},
|
|
338
|
+
"@astryx.table.sort.sortedByWithPriority": {
|
|
339
|
+
"defaultMessage": "⟦Šóřţ ƀý {label}, šóřţéð {direction}, þříóříţý {rank, number} óƒ {total, number}⟧"
|
|
340
|
+
},
|
|
320
341
|
"@astryx.toast.dismiss": {
|
|
321
342
|
"defaultMessage": "⟦Ðíšɱíšš ñóţíƒíçàţíóñ⟧"
|
|
322
343
|
},
|
|
@@ -494,6 +515,9 @@
|
|
|
494
515
|
"@astryx.fileInput.clearLabel": {
|
|
495
516
|
"defaultMessage": "⟦Çłéàř {label}⟧"
|
|
496
517
|
},
|
|
518
|
+
"@astryx.fileInput.triggerWithFiles": {
|
|
519
|
+
"defaultMessage": "⟦{label}, {fileNames}⟧"
|
|
520
|
+
},
|
|
497
521
|
"@astryx.lightbox.mediaViewer": {
|
|
498
522
|
"defaultMessage": "⟦Ṁéðíà ṽíéŵéř⟧"
|
|
499
523
|
},
|
|
@@ -542,6 +566,12 @@
|
|
|
542
566
|
"@astryx.tableRowExpansion.expandAllRows": {
|
|
543
567
|
"defaultMessage": "⟦Éẋþàñð àłł řóŵš⟧"
|
|
544
568
|
},
|
|
569
|
+
"@astryx.tableTree.collapseRow": {
|
|
570
|
+
"defaultMessage": "⟦Çółłàþšé řóŵ⟧"
|
|
571
|
+
},
|
|
572
|
+
"@astryx.tableTree.expandRow": {
|
|
573
|
+
"defaultMessage": "⟦Éẋþàñð řóŵ⟧"
|
|
574
|
+
},
|
|
545
575
|
"@astryx.textInput.clearLabel": {
|
|
546
576
|
"defaultMessage": "⟦Çłéàř {label}⟧"
|
|
547
577
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8-canary.0c4d8d7",
|
|
4
4
|
"displayName": "Astryx Core",
|
|
5
5
|
"description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -636,6 +636,7 @@
|
|
|
636
636
|
"files": [
|
|
637
637
|
"dist",
|
|
638
638
|
"src",
|
|
639
|
+
"scripts/postinstall.mjs",
|
|
639
640
|
"locales",
|
|
640
641
|
"docs.mjs",
|
|
641
642
|
"groups.doc.mjs",
|
|
@@ -662,6 +663,7 @@
|
|
|
662
663
|
"intl-messageformat": "^11.2.9"
|
|
663
664
|
},
|
|
664
665
|
"scripts": {
|
|
666
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
665
667
|
"build": "rimraf dist && pnpm build:i18n && pnpm build:esm && tsc --project tsconfig.build.json && pnpm build:css && pnpm build:umd && node ../../scripts/check-no-dev-jsx.mjs",
|
|
666
668
|
"build:i18n": "node scripts/build-pseudo-locale.mjs",
|
|
667
669
|
"build:esm": "babel src --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.ts,**/*.test.tsx,**/__tests__/**,**/*.perf.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css,**/*.css.d.ts\" --config-file ./babel.config.json",
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file @astryxdesign/core postinstall — nudge to run `npx @astryxdesign/cli init`.
|
|
5
|
+
*
|
|
6
|
+
* Enforcement layer 1 of making `astryx init` foolproof: when the design system
|
|
7
|
+
* is installed and the project hasn't run init yet, print a one-line next-step
|
|
8
|
+
* so agents/humans discover it (this is the most common fresh-install entry).
|
|
9
|
+
*
|
|
10
|
+
* Self-contained: core is a separate package and cannot import the CLI, so the
|
|
11
|
+
* agent-doc locations + marker below intentionally DUPLICATE the CLI's agent-doc
|
|
12
|
+
* discovery in packages/cli/src/commands/agent-docs.mjs — keep them aligned with
|
|
13
|
+
* that file. The .hermes.md / HERMES.md entries are an intentional superset (the
|
|
14
|
+
* CLI writes those via `--agent hermes`). Non-interactive, never fails the
|
|
15
|
+
* install, and quiet in the monorepo build, during npx's fetch, and once set up.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import {fileURLToPath, pathToFileURL} from 'node:url';
|
|
21
|
+
|
|
22
|
+
const HERE = fileURLToPath(import.meta.url);
|
|
23
|
+
|
|
24
|
+
// Duplicates the CLI's agent-doc locations + markers — keep aligned with
|
|
25
|
+
// packages/cli/src/commands/agent-docs.mjs. Hermes files are an intentional superset.
|
|
26
|
+
const AGENT_DOC_PATHS = [
|
|
27
|
+
'AGENTS.md',
|
|
28
|
+
'CLAUDE.md',
|
|
29
|
+
'.claude/CLAUDE.md',
|
|
30
|
+
'.cursorrules',
|
|
31
|
+
'.hermes.md',
|
|
32
|
+
'HERMES.md',
|
|
33
|
+
];
|
|
34
|
+
const MARKERS = ['<!-- ASTRYX:START -->', '<!-- XDS:START -->'];
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* True when the project already has the Astryx agent prompt installed (an Astryx
|
|
38
|
+
* marker is present in any agent-doc file) — the same check the CLI performs.
|
|
39
|
+
* @param {string} root @returns {boolean}
|
|
40
|
+
*/
|
|
41
|
+
export function isAstryxInitialized(root) {
|
|
42
|
+
for (const rel of AGENT_DOC_PATHS) {
|
|
43
|
+
try {
|
|
44
|
+
const content = fs.readFileSync(path.join(root, rel), 'utf-8');
|
|
45
|
+
if (MARKERS.some(m => content.includes(m))) return true;
|
|
46
|
+
} catch {
|
|
47
|
+
// Unreadable/missing — keep checking the others.
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Pure decision: should the postinstall print the setup nudge? Unit-testable
|
|
55
|
+
* without an actual npm install.
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
export function shouldNudge({scriptPath, npmCommand, isSetUp} = {}) {
|
|
59
|
+
if (!scriptPath || !scriptPath.includes('node_modules')) return false; // monorepo/source build
|
|
60
|
+
if (scriptPath.includes('_npx') || npmCommand === 'exec') return false; // npx transient
|
|
61
|
+
if (isSetUp) return false; // already set up — stay quiet
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function main() {
|
|
66
|
+
const root = process.env.INIT_CWD || process.cwd();
|
|
67
|
+
if (
|
|
68
|
+
shouldNudge({
|
|
69
|
+
scriptPath: HERE,
|
|
70
|
+
npmCommand: process.env.npm_command,
|
|
71
|
+
isSetUp: isAstryxInitialized(root),
|
|
72
|
+
})
|
|
73
|
+
) {
|
|
74
|
+
// Scoped package form (`@astryxdesign/cli`) — always resolves to us, even
|
|
75
|
+
// before the CLI is installed. Bare `npx astryx` would fetch an unrelated
|
|
76
|
+
// look-alike package (see PR #4151). After that lands, switch this to its
|
|
77
|
+
// getCliInvocation() single source of truth.
|
|
78
|
+
process.stdout.write(
|
|
79
|
+
'\nNext step: run `npx @astryxdesign/cli init` to finish setup and install the Astryx agent prompt.\n\n',
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Run only when executed directly (`node scripts/postinstall.mjs`), never when
|
|
85
|
+
// imported by tests.
|
|
86
|
+
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
|
|
87
|
+
try {
|
|
88
|
+
main();
|
|
89
|
+
} catch {
|
|
90
|
+
// never break an install
|
|
91
|
+
}
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
isValidElement,
|
|
25
25
|
useCallback,
|
|
26
26
|
useEffect,
|
|
27
|
+
useId,
|
|
27
28
|
useMemo,
|
|
28
29
|
useRef,
|
|
29
30
|
useState,
|
|
@@ -600,10 +601,14 @@ export function AppShell({
|
|
|
600
601
|
// =========================================================================
|
|
601
602
|
// Mobile context — shared with MobileNavToggle and future TopNav mobile
|
|
602
603
|
// =========================================================================
|
|
604
|
+
// Stable id shared by the drawer (applied as its `id`) and the toggle
|
|
605
|
+
// (referenced via `aria-controls`) so screen readers know what it controls.
|
|
606
|
+
const mobileNavId = useId();
|
|
603
607
|
const mobileContextValue = useMemo<AppShellMobileContextValue>(
|
|
604
608
|
() => ({
|
|
605
609
|
isMobile: isBelowBreakpoint,
|
|
606
610
|
isMobileNavOpen,
|
|
611
|
+
mobileNavId,
|
|
607
612
|
toggleMobileNav: () =>
|
|
608
613
|
mobileNavEnabled && setMobileNavOpen(!isMobileNavOpen),
|
|
609
614
|
openMobileNav: () => mobileNavEnabled && setMobileNavOpen(true),
|
|
@@ -614,6 +619,7 @@ export function AppShell({
|
|
|
614
619
|
[
|
|
615
620
|
isBelowBreakpoint,
|
|
616
621
|
isMobileNavOpen,
|
|
622
|
+
mobileNavId,
|
|
617
623
|
setMobileNavOpen,
|
|
618
624
|
mobileNavEnabled,
|
|
619
625
|
mobileNavHasToggle,
|
|
@@ -20,6 +20,14 @@ export interface AppShellMobileContextValue {
|
|
|
20
20
|
isMobile: boolean;
|
|
21
21
|
/** Whether the mobile nav drawer is currently open */
|
|
22
22
|
isMobileNavOpen: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* DOM id of the mobile nav drawer. `AppShell` sets this so the toggle can
|
|
25
|
+
* point its `aria-controls` at the drawer and the drawer can apply it as its
|
|
26
|
+
* `id`. Optional: callers that construct this context by hand may omit it, in
|
|
27
|
+
* which case `MobileNav` falls back to a locally generated id and the toggle
|
|
28
|
+
* simply drops `aria-controls`.
|
|
29
|
+
*/
|
|
30
|
+
mobileNavId?: string;
|
|
23
31
|
/** Toggle the mobile nav drawer open/closed */
|
|
24
32
|
toggleMobileNav: () => void;
|
|
25
33
|
/** Open the mobile nav drawer */
|
|
@@ -31,6 +31,12 @@ export const docs = {
|
|
|
31
31
|
description:
|
|
32
32
|
'Whether the AppShell-managed mobile navigation drawer is open.',
|
|
33
33
|
},
|
|
34
|
+
{
|
|
35
|
+
name: 'mobileNavId',
|
|
36
|
+
type: 'string | undefined',
|
|
37
|
+
description:
|
|
38
|
+
'DOM id of the mobile navigation drawer, set by AppShell. Point aria-controls of a custom toggle at this so screen-reader users know which element the toggle expands. Undefined outside an AppShell that manages the drawer.',
|
|
39
|
+
},
|
|
34
40
|
{
|
|
35
41
|
name: 'toggleMobileNav',
|
|
36
42
|
type: '() => void',
|
|
@@ -111,6 +117,8 @@ export const docsDense = {
|
|
|
111
117
|
isMobile:
|
|
112
118
|
'viewport below AppShell mobile nav breakpoint? Use to sync AppShell-adjacent mobile UI',
|
|
113
119
|
isMobileNavOpen: 'AppShell-managed mobile nav drawer open?',
|
|
120
|
+
mobileNavId:
|
|
121
|
+
'DOM id of the drawer; point custom toggle aria-controls at it',
|
|
114
122
|
toggleMobileNav: 'toggle drawer; no-op when mobile nav disabled',
|
|
115
123
|
openMobileNav: 'open drawer; no-op when mobile nav disabled',
|
|
116
124
|
closeMobileNav: 'close drawer',
|
|
@@ -13,7 +13,7 @@ export const docs = {
|
|
|
13
13
|
'Avatar represents a person or team with a profile photo, initials, or a default icon. Use it in comment headers, contact lists, chat messages, user cards, and anywhere you need to identify someone visually.',
|
|
14
14
|
bestPractices: [
|
|
15
15
|
{guidance: true, description: 'Always pass a name so the avatar can show initials if the photo fails to load, and so screen readers can announce who it represents.'},
|
|
16
|
-
{guidance: true, description: 'Pick a size that matches the context:
|
|
16
|
+
{guidance: true, description: 'Pick a size that matches the context: xsm or sm for inline mentions, md or lg for lists and cards, xl for profile headers.'},
|
|
17
17
|
{guidance: true, description: 'Add a status dot when knowing someone\'s availability matters, like in chat or team views.'},
|
|
18
18
|
{guidance: false, description: 'Use Avatar for logos, product images, or anything that isn\'t a person or team. Use an image or icon instead.'},
|
|
19
19
|
{guidance: false, description: 'Force a square or custom shape. Avatars are always circular to stay consistent across the system.'},
|
|
@@ -55,9 +55,9 @@ export const docs = {
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
name: 'size',
|
|
58
|
-
type: "'
|
|
59
|
-
description: "Avatar size. Use a named size ('
|
|
60
|
-
default: "'
|
|
58
|
+
type: "'xsm' | 'sm' | 'md' | 'lg' | 'xl' | number",
|
|
59
|
+
description: "Avatar size. Use a named size ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or a numeric pixel value. Avatar shares Icon's abbreviated scale, but its tiers are larger because avatars align with media rather than glyphs.",
|
|
60
|
+
default: "'md'",
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
name: 'status',
|
|
@@ -100,7 +100,7 @@ export const docsDense = {
|
|
|
100
100
|
'Avatar represents a person or team with a profile photo, initials, or a default icon. Falls back automatically. Use in comment headers, contact lists, chat, user cards.',
|
|
101
101
|
bestPractices: [
|
|
102
102
|
{guidance: true, description: 'Always pass a name for initials fallback and screen reader alt text.'},
|
|
103
|
-
{guidance: true, description: 'Match size to context:
|
|
103
|
+
{guidance: true, description: 'Match size to context: xsm/sm inline, md/lg in lists, xl for profiles.'},
|
|
104
104
|
{guidance: true, description: 'Add a status dot in chat or team views where availability matters.'},
|
|
105
105
|
{guidance: false, description: 'Use for logos or product images. Use an image or icon instead.'},
|
|
106
106
|
{guidance: false, description: 'Force a square or custom shape. Avatars are always circular.'},
|
|
@@ -111,7 +111,7 @@ export const docsDense = {
|
|
|
111
111
|
fallbackSrc: 'fallback image when primary fails',
|
|
112
112
|
name: 'user name for initials and alt text',
|
|
113
113
|
alt: 'alt text; falls back to name',
|
|
114
|
-
size: "avatar size. Named ('
|
|
114
|
+
size: "avatar size. Named ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or numeric px.",
|
|
115
115
|
status: 'corner content for status indicators',
|
|
116
116
|
},
|
|
117
117
|
components: [
|
package/src/Avatar/Avatar.tsx
CHANGED
|
@@ -55,9 +55,13 @@ const CIRCLE_EDGE_OFFSET_RATIO = (1 - 1 / Math.SQRT2) / 2;
|
|
|
55
55
|
const INITIALS_FONT_SIZE_RATIO = 0.4;
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* Named size options
|
|
58
|
+
* Named size options.
|
|
59
|
+
*
|
|
60
|
+
* Avatar uses the same abbreviated scale as Icon (`xsm`/`sm`/`md`/`lg`/`xl`),
|
|
61
|
+
* but the values are larger because avatars align with media rather than
|
|
62
|
+
* glyphs. The tiers match EPS's avatar sizes.
|
|
59
63
|
*/
|
|
60
|
-
type AvatarNamedSize = '
|
|
64
|
+
type AvatarNamedSize = 'xsm' | 'sm' | 'md' | 'lg' | 'xl';
|
|
61
65
|
|
|
62
66
|
/**
|
|
63
67
|
* Numeric size options (in pixels)
|
|
@@ -78,15 +82,15 @@ export function resolveSize(size: AvatarSize): number {
|
|
|
78
82
|
return size;
|
|
79
83
|
}
|
|
80
84
|
switch (size) {
|
|
81
|
-
case '
|
|
85
|
+
case 'xsm':
|
|
82
86
|
return 20;
|
|
83
|
-
case '
|
|
87
|
+
case 'sm':
|
|
84
88
|
return 24;
|
|
85
|
-
case '
|
|
89
|
+
case 'md':
|
|
86
90
|
return 36;
|
|
87
|
-
case '
|
|
91
|
+
case 'lg':
|
|
88
92
|
return 48;
|
|
89
|
-
case '
|
|
93
|
+
case 'xl':
|
|
90
94
|
return 128;
|
|
91
95
|
}
|
|
92
96
|
}
|
|
@@ -198,8 +202,9 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
|
|
|
198
202
|
*/
|
|
199
203
|
name?: string;
|
|
200
204
|
/**
|
|
201
|
-
* The size of the avatar.
|
|
202
|
-
*
|
|
205
|
+
* The size of the avatar. A named size (`xsm` 20px, `sm` 24px, `md` 36px,
|
|
206
|
+
* `lg` 48px, `xl` 128px) or a specific pixel value.
|
|
207
|
+
* @default 'md'
|
|
203
208
|
*/
|
|
204
209
|
size?: AvatarSize;
|
|
205
210
|
/**
|
|
@@ -258,7 +263,7 @@ function DefaultIcon({size}: {size: number}) {
|
|
|
258
263
|
* @example
|
|
259
264
|
* ```
|
|
260
265
|
* <Avatar src="/user.jpg" name="John Doe" />
|
|
261
|
-
* <Avatar name="Jane Smith" size="
|
|
266
|
+
* <Avatar name="Jane Smith" size="xl" />
|
|
262
267
|
* <Avatar src="/user.jpg" status={<OnlineIndicator />} />
|
|
263
268
|
* ```
|
|
264
269
|
*/
|
|
@@ -267,7 +272,7 @@ export function Avatar({
|
|
|
267
272
|
'data-testid': testId,
|
|
268
273
|
fallbackSrc,
|
|
269
274
|
name,
|
|
270
|
-
size = '
|
|
275
|
+
size = 'md',
|
|
271
276
|
src,
|
|
272
277
|
status,
|
|
273
278
|
xstyle,
|
|
@@ -18,7 +18,7 @@ import {createContext} from 'react';
|
|
|
18
18
|
* Context that provides the resolved numeric avatar size (in pixels)
|
|
19
19
|
* to child components like AvatarStatusDot.
|
|
20
20
|
*
|
|
21
|
-
* Default value of 36 matches the default '
|
|
21
|
+
* Default value of 36 matches the default 'md' avatar size.
|
|
22
22
|
*/
|
|
23
23
|
export const AvatarSizeContext = createContext<number>(36);
|
|
24
24
|
AvatarSizeContext.displayName = 'AvatarSizeContext';
|
|
@@ -168,12 +168,12 @@ const variantStyleMap: Partial<
|
|
|
168
168
|
* ```
|
|
169
169
|
* <Avatar
|
|
170
170
|
* name="John Doe"
|
|
171
|
-
* size="
|
|
171
|
+
* size="lg"
|
|
172
172
|
* status={<AvatarStatusDot variant="success" label="Online" />}
|
|
173
173
|
* />
|
|
174
174
|
* <Avatar
|
|
175
175
|
* name="Jane Smith"
|
|
176
|
-
* size="
|
|
176
|
+
* size="xl"
|
|
177
177
|
* status={<AvatarStatusDot variant="success" label="Verified" icon={<CheckIcon />} />}
|
|
178
178
|
* />
|
|
179
179
|
* ```
|
|
@@ -56,14 +56,14 @@ describe('AvatarGroup', () => {
|
|
|
56
56
|
|
|
57
57
|
it('applies size class to the group', () => {
|
|
58
58
|
render(
|
|
59
|
-
<AvatarGroup size="
|
|
59
|
+
<AvatarGroup size="lg">
|
|
60
60
|
<Avatar name="Alice" />
|
|
61
61
|
</AvatarGroup>,
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
const group = screen.getByRole('group');
|
|
65
65
|
expect(group.className).toContain('astryx-avatar-group');
|
|
66
|
-
expect(group.className).toContain('
|
|
66
|
+
expect(group.className).toContain('lg');
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
it('renders empty group when no children', () => {
|
|
@@ -134,7 +134,7 @@ describe('AvatarGroupOverflow', () => {
|
|
|
134
134
|
const visibleCount = 3;
|
|
135
135
|
|
|
136
136
|
render(
|
|
137
|
-
<AvatarGroup size="
|
|
137
|
+
<AvatarGroup size="lg">
|
|
138
138
|
{users.slice(0, visibleCount).map(name => (
|
|
139
139
|
<Avatar key={name} name={name} />
|
|
140
140
|
))}
|
|
@@ -211,4 +211,18 @@ describe('AvatarGroupOverflow — hardening', () => {
|
|
|
211
211
|
|
|
212
212
|
expect(screen.getByText('+999')).toBeInTheDocument();
|
|
213
213
|
});
|
|
214
|
+
|
|
215
|
+
it('renders the full "+N" text for wide multi-digit counts', () => {
|
|
216
|
+
// The indicator grows into a pill for long counts, so the entire number
|
|
217
|
+
// must remain present (nothing clipped away in the DOM).
|
|
218
|
+
render(
|
|
219
|
+
<AvatarGroup>
|
|
220
|
+
<Avatar name="Alice" />
|
|
221
|
+
<AvatarGroupOverflow count={4912} />
|
|
222
|
+
</AvatarGroup>,
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
expect(screen.getByText('+4912')).toBeInTheDocument();
|
|
226
|
+
expect(screen.getByLabelText('4912 more')).toBeInTheDocument();
|
|
227
|
+
});
|
|
214
228
|
});
|
|
@@ -39,7 +39,7 @@ export interface AvatarGroupProps extends BaseProps<HTMLDivElement> {
|
|
|
39
39
|
children: ReactNode;
|
|
40
40
|
/**
|
|
41
41
|
* Size applied to all avatars via context.
|
|
42
|
-
* @default '
|
|
42
|
+
* @default 'md'
|
|
43
43
|
*/
|
|
44
44
|
size?: AvatarSize;
|
|
45
45
|
/**
|
|
@@ -65,7 +65,7 @@ const styles = stylex.create({
|
|
|
65
65
|
*
|
|
66
66
|
* @example
|
|
67
67
|
* ```
|
|
68
|
-
* <AvatarGroup size="
|
|
68
|
+
* <AvatarGroup size="lg">
|
|
69
69
|
* {users.slice(0, 3).map(u => (
|
|
70
70
|
* <Avatar key={u.id} src={u.src} name={u.name} />
|
|
71
71
|
* ))}
|
|
@@ -75,7 +75,7 @@ const styles = stylex.create({
|
|
|
75
75
|
*/
|
|
76
76
|
export function AvatarGroup({
|
|
77
77
|
children,
|
|
78
|
-
size = '
|
|
78
|
+
size = 'md',
|
|
79
79
|
'data-testid': testId,
|
|
80
80
|
'aria-label': ariaLabelFromProps,
|
|
81
81
|
xstyle,
|
|
@@ -51,7 +51,7 @@ export const docs = {
|
|
|
51
51
|
'AvatarGroupOverflow appears at the end of an AvatarGroup to summarize people who are not shown individually. Use it when a group is sliced to a small number of visible avatars but the hidden count still matters.',
|
|
52
52
|
bestPractices: [
|
|
53
53
|
{guidance: true, description: 'Pass the real hidden count to `count` so the accessible label matches the visible indicator.'},
|
|
54
|
-
{guidance: true, description: 'Use short custom text such as `+12` or `99
|
|
54
|
+
{guidance: true, description: 'Use short custom text such as `+12` or `99+`. The indicator is circular for short counts and grows into a pill for wider counts so the number always fits.'},
|
|
55
55
|
{guidance: true, description: 'Provide `onClick` when the overflow opens a member list, popover, or detail view.'},
|
|
56
56
|
{guidance: false, description: 'Do not use long labels inside the indicator; place longer participant details next to the group instead.'},
|
|
57
57
|
],
|
|
@@ -64,7 +64,7 @@ export const docs = {
|
|
|
64
64
|
{
|
|
65
65
|
label: 'Default overflow count',
|
|
66
66
|
code: `
|
|
67
|
-
<AvatarGroup size="
|
|
67
|
+
<AvatarGroup size="lg">
|
|
68
68
|
{users.slice(0, 3).map(user => (
|
|
69
69
|
<Avatar key={user.id} src={user.src} name={user.name} />
|
|
70
70
|
))}
|
|
@@ -75,7 +75,7 @@ export const docs = {
|
|
|
75
75
|
{
|
|
76
76
|
label: 'Custom count text',
|
|
77
77
|
code: `
|
|
78
|
-
<AvatarGroup size="
|
|
78
|
+
<AvatarGroup size="lg">
|
|
79
79
|
{users.slice(0, 3).map(user => (
|
|
80
80
|
<Avatar key={user.id} src={user.src} name={user.name} />
|
|
81
81
|
))}
|
|
@@ -104,7 +104,7 @@ export const docsZh = {
|
|
|
104
104
|
'AvatarGroupOverflow 显示在 AvatarGroup 末尾,用来汇总未单独展示的成员。适用于只展示少量头像但仍需要显示隐藏数量的场景。',
|
|
105
105
|
bestPractices: [
|
|
106
106
|
{guidance: true, description: '向 `count` 传入真实隐藏数量,确保无障碍标签与可见指示器一致。'},
|
|
107
|
-
{guidance: true, description: '使用 `+12` 或 `99+`
|
|
107
|
+
{guidance: true, description: '使用 `+12` 或 `99+` 等短文本;指示器在计数较短时为圆形,计数较宽时会拉伸为胶囊形,确保数字始终完整显示。'},
|
|
108
108
|
{guidance: true, description: '当溢出项会打开成员列表、弹出层或详情视图时提供 `onClick`。'},
|
|
109
109
|
{guidance: false, description: '不要在指示器内使用长标签;更长的参与者详情应放在头像组旁边。'},
|
|
110
110
|
],
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
typographyVars,
|
|
21
21
|
fontWeightVars,
|
|
22
22
|
radiusVars,
|
|
23
|
+
spacingVars,
|
|
23
24
|
} from '../theme/tokens.stylex';
|
|
24
25
|
import {mergeProps} from '../utils';
|
|
25
26
|
import {useAvatarGroup} from './AvatarGroupContext';
|
|
@@ -67,13 +68,21 @@ const styles = stylex.create({
|
|
|
67
68
|
borderWidth: BORDER_WIDTH,
|
|
68
69
|
borderStyle: 'solid',
|
|
69
70
|
borderColor: colorVars['--color-background-surface'],
|
|
70
|
-
|
|
71
|
+
// border-box so the border and inline padding are included in the box
|
|
72
|
+
// size: a short "+N" stays a circle at exactly the avatar size, while
|
|
73
|
+
// longer content pushes past the min width and grows into a pill.
|
|
74
|
+
boxSizing: 'border-box',
|
|
75
|
+
// Horizontal breathing room so multi-digit "+N" counts don't crowd the
|
|
76
|
+
// edges once the indicator grows into a pill.
|
|
77
|
+
paddingInline: spacingVars['--spacing-2'],
|
|
71
78
|
// Neutral tint layer (preserves opaque base underneath)
|
|
72
79
|
backgroundImage: `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
|
|
73
80
|
},
|
|
74
81
|
button: {
|
|
75
82
|
cursor: 'pointer',
|
|
76
|
-
padding
|
|
83
|
+
// Reset the UA button's block padding only; the inline padding from `base`
|
|
84
|
+
// provides the pill's breathing room and must be preserved.
|
|
85
|
+
paddingBlock: 0,
|
|
77
86
|
// Interactive overlay states layered on top via backgroundImage
|
|
78
87
|
backgroundImage: {
|
|
79
88
|
default: `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
|
|
@@ -99,8 +108,15 @@ const styles = stylex.create({
|
|
|
99
108
|
|
|
100
109
|
const dynamicStyles = stylex.create({
|
|
101
110
|
size: (s: number) => ({
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
// Pin height to the avatar's rendered size and enforce the same value as a
|
|
112
|
+
// *minimum* width, so short counts (`+5`) render a perfect circle. With
|
|
113
|
+
// border-box, the inline padding lives inside this size; longer content
|
|
114
|
+
// (`+4912`) pushes past the min width and grows into a stadium/pill.
|
|
115
|
+
// The border is added to the declared size (like the avatars' ring, which
|
|
116
|
+
// uses content-box + a 2px border) to keep the indicator the same overall
|
|
117
|
+
// size as its sibling avatars.
|
|
118
|
+
minWidth: s + BORDER_WIDTH * 2,
|
|
119
|
+
height: s + BORDER_WIDTH * 2,
|
|
104
120
|
}),
|
|
105
121
|
fontSize: (s: number) => ({
|
|
106
122
|
fontSize: s * OVERFLOW_FONT_RATIO,
|
|
@@ -116,7 +132,7 @@ const dynamicStyles = stylex.create({
|
|
|
116
132
|
*
|
|
117
133
|
* @example
|
|
118
134
|
* ```
|
|
119
|
-
* <AvatarGroup size="
|
|
135
|
+
* <AvatarGroup size="lg">
|
|
120
136
|
* {users.slice(0, 3).map(u => (
|
|
121
137
|
* <Avatar key={u.id} src={u.src} name={u.name} />
|
|
122
138
|
* ))}
|
|
@@ -81,6 +81,13 @@ export const docs = {
|
|
|
81
81
|
'Container type: card has border-radius; section is full-width with no border-radius for page-level use.',
|
|
82
82
|
default: "'card'",
|
|
83
83
|
},
|
|
84
|
+
{
|
|
85
|
+
name: 'elevation',
|
|
86
|
+
type: "'none' | 'low' | 'med' | 'high'",
|
|
87
|
+
description:
|
|
88
|
+
'Resting shadow depth. Use for a floating banner that hovers above content; `none` is the default inline banner. A `card`-container banner rounds its shadow to match.',
|
|
89
|
+
default: "'none'",
|
|
90
|
+
},
|
|
84
91
|
{
|
|
85
92
|
name: 'children',
|
|
86
93
|
type: 'ReactNode',
|
|
@@ -157,6 +164,7 @@ export const docsZh = {
|
|
|
157
164
|
{name: 'onDismiss', type: '() => void', description: '点击关闭按钮时调用;无论是否提供此回调,横幅都会自动隐藏。'},
|
|
158
165
|
{name: 'endContent', type: 'ReactNode', description: '渲染在头部区域末端对齐的操作内容,通常是按钮或链接。'},
|
|
159
166
|
{name: 'container', type: "'card' | 'section'", description: '视觉变体:card 带圆角;section 无圆角全宽,适用于页面级场景。', default: "'card'"},
|
|
167
|
+
{name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '静止阴影深度。用于悬浮于内容之上的浮动横幅;none 为默认内联横幅。', default: "'none'"},
|
|
160
168
|
{name: 'children', type: 'ReactNode', description: '渲染在彩色头部下方卡片背景区域的内容。'},
|
|
161
169
|
{name: 'defaultIsExpanded', type: 'boolean', description: '内容区域(children)是否初始展开。仅在提供 children 时相关。', default: 'false'},
|
|
162
170
|
{
|
|
@@ -230,6 +238,7 @@ export const docsDense = {
|
|
|
230
238
|
onDismiss: 'dismiss callback; banner self-hides regardless',
|
|
231
239
|
endContent: 'end-aligned action in header, typically button/link',
|
|
232
240
|
container: 'card=border-radius; section=full-width no radius for page-level',
|
|
241
|
+
elevation: 'resting shadow depth: none|low|med|high; raise for a floating banner',
|
|
233
242
|
children: 'content in card-bg area below colored header',
|
|
234
243
|
xstyle: 'StyleX layout customization via stylex.create()',
|
|
235
244
|
},
|
|
@@ -368,4 +368,34 @@ describe('Banner', () => {
|
|
|
368
368
|
);
|
|
369
369
|
expect(screen.getByTestId('custom-chevron')).toBeInTheDocument();
|
|
370
370
|
});
|
|
371
|
+
|
|
372
|
+
describe('elevation', () => {
|
|
373
|
+
it('renders a distinct root class for each elevation level', () => {
|
|
374
|
+
const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
|
|
375
|
+
const {container} = render(
|
|
376
|
+
<Banner status="info" title="Heads up" elevation={elevation} />,
|
|
377
|
+
);
|
|
378
|
+
return container.firstElementChild!.className;
|
|
379
|
+
};
|
|
380
|
+
const classes = new Set([
|
|
381
|
+
classFor('none'),
|
|
382
|
+
classFor('low'),
|
|
383
|
+
classFor('med'),
|
|
384
|
+
classFor('high'),
|
|
385
|
+
]);
|
|
386
|
+
expect(classes.size).toBe(4);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('defaults to flat (elevation none)', () => {
|
|
390
|
+
const {container: def} = render(
|
|
391
|
+
<Banner status="info" title="Heads up" />,
|
|
392
|
+
);
|
|
393
|
+
const {container: none} = render(
|
|
394
|
+
<Banner status="info" title="Heads up" elevation="none" />,
|
|
395
|
+
);
|
|
396
|
+
expect(def.firstElementChild!.className).toBe(
|
|
397
|
+
none.firstElementChild!.className,
|
|
398
|
+
);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
371
401
|
});
|