@astryxdesign/core 0.1.8 → 0.1.9-canary.02ef052
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +6 -2
- package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
- package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
- package/dist/Avatar/Avatar.d.ts +58 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +240 -53
- package/dist/Avatar/AvatarStatusDot.d.ts +35 -5
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +144 -19
- package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +58 -6
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
- package/dist/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +33 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +215 -6
- package/dist/Breadcrumbs/index.d.ts +6 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +10 -1
- package/dist/Button/Button.d.ts +8 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +33 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +30 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +80 -11
- package/dist/Calendar/dayCellUtils.d.ts +4 -4
- package/dist/Calendar/dayCellUtils.js +3 -3
- package/dist/Calendar/styles.d.ts +30 -31
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +30 -31
- package/dist/Card/Card.d.ts +8 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +28 -2
- package/dist/Carousel/Carousel.d.ts +4 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +46 -16
- package/dist/Chat/ChatComposer.d.ts +8 -0
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +46 -7
- package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +11 -1
- package/dist/Chat/ChatComposerInput.d.ts +20 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +36 -4
- package/dist/Chat/ChatContext.d.ts +33 -0
- package/dist/Chat/ChatContext.d.ts.map +1 -1
- package/dist/Chat/ChatContext.js +16 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +4 -2
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +4 -4
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +4 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +7 -1
- package/dist/Chat/ChatToolCalls.d.ts +5 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +27 -11
- package/dist/Chat/index.d.ts +2 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/index.js +1 -1
- package/dist/Chat/useChatStreamScroll.d.ts +2 -1
- package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
- package/dist/Chat/useChatStreamScroll.js +22 -8
- package/dist/Chat/useSpeechRecognition.d.ts +0 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +1 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.js +5 -5
- package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +11 -1
- package/dist/Citation/Citation.d.ts +22 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +20 -6
- package/dist/ClickableCard/ClickableCard.d.ts +9 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +5 -2
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +22 -9
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +3 -1
- package/dist/CommandPalette/CommandPalette.d.ts +2 -2
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +45 -4
- package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
- package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +6 -1
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +14 -5
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +3 -1
- package/dist/DateInput/DateInput.d.ts +56 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +59 -21
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +23 -20
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +33 -19
- package/dist/Dialog/Dialog.d.ts +3 -0
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +57 -6
- package/dist/Dialog/DialogContext.d.ts +7 -0
- package/dist/Dialog/DialogContext.d.ts.map +1 -1
- package/dist/Dialog/DialogContext.js +2 -2
- package/dist/Dialog/DialogHeader.d.ts +5 -2
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +6 -1
- package/dist/Divider/Divider.js +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +22 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +5 -3
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
- package/dist/DropdownMenu/index.d.ts +10 -0
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +13 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemHover.js +33 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemRoles.js +10 -1
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -6
- package/dist/Field/Field.d.ts +3 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +6 -4
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +43 -16
- package/dist/Field/inputStyles.stylex.d.ts +1 -0
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +1 -0
- package/dist/FieldStatus/FieldStatus.d.ts +18 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +60 -6
- package/dist/FileInput/FileInput.d.ts +10 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +54 -35
- 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 +17 -6
- package/dist/Icon/Icon.d.ts +22 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +19 -3
- package/dist/Item/Item.d.ts +6 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +22 -1
- package/dist/Layer/useLayer.d.ts +6 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +2 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +19 -13
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -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 +9 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +104 -50
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts +10 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +22 -17
- package/dist/Outline/Outline.d.ts +0 -1
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +0 -1
- package/dist/OverflowList/OverflowList.d.ts +20 -3
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +29 -4
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +11 -3
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +3 -9
- package/dist/PowerSearch/PowerSearch.d.ts +9 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +2 -0
- package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/RadioList/RadioList.d.ts +2 -2
- package/dist/RadioList/RadioListItem.js +4 -4
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
- package/dist/SelectableCard/SelectableCard.d.ts +9 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +16 -13
- package/dist/Selector/Selector.d.ts +8 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +65 -19
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +5 -5
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +13 -10
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts +1 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +12 -10
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +106 -36
- package/dist/Stack/stack.stylex.d.ts +9 -9
- package/dist/Switch/Switch.d.ts +8 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +160 -91
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +33 -6
- package/dist/Table/TableCell.js +3 -3
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
- package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/index.js +3 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +7 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +105 -12
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
- package/dist/Table/types.d.ts +32 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- package/dist/TextArea/TextArea.d.ts +10 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +18 -19
- package/dist/TextInput/TextInput.d.ts +10 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +20 -17
- package/dist/Thumbnail/Thumbnail.d.ts +26 -5
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +97 -54
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
- package/dist/TimeInput/TimeInput.d.ts +10 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +32 -21
- package/dist/Timestamp/Timestamp.d.ts +3 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +8 -6
- package/dist/Toast/useToast.d.ts.map +1 -1
- package/dist/Toast/useToast.js +2 -5
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
- package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
- package/dist/Token/Token.d.ts +30 -3
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +17 -2
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts +10 -3
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +20 -6
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -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/TopNavMegaMenuFeaturedCard.d.ts +9 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
- package/dist/TopNav/TopNavMenu.d.ts +2 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +68 -6
- package/dist/TreeList/TreeList.d.ts +12 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +18 -10
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +59 -21
- package/dist/TreeList/TreeListTypes.d.ts +25 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/TreeList/index.d.ts +2 -2
- package/dist/TreeList/index.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +20 -11
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +3 -1
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +20 -10
- package/dist/astryx.css +61 -39
- package/dist/astryx.umd.js +53 -53
- package/dist/astryx.umd.js.map +4 -4
- package/dist/authoring/doc.d.ts.map +1 -1
- package/dist/docs-types.d.ts +8 -0
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/computeOverflow.d.ts +47 -0
- package/dist/hooks/computeOverflow.d.ts.map +1 -0
- package/dist/hooks/computeOverflow.js +213 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/isRtlElement.d.ts +18 -0
- package/dist/hooks/isRtlElement.d.ts.map +1 -0
- package/dist/hooks/isRtlElement.js +27 -0
- package/dist/hooks/useDevWarning.d.ts +18 -0
- package/dist/hooks/useDevWarning.d.ts.map +1 -0
- package/dist/hooks/useDevWarning.js +49 -0
- package/dist/hooks/useGridFocus.d.ts +6 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +12 -9
- package/dist/hooks/useInputStatusIcon.d.ts +38 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
- package/dist/hooks/useInputStatusIcon.js +158 -0
- package/dist/hooks/useListFocus.d.ts +39 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +54 -9
- package/dist/hooks/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +36 -25
- package/dist/i18n/InternationalizationContext.d.ts +1 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -0
- package/dist/i18n/InternationalizationProvider.d.ts +8 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +5 -1
- package/dist/i18n/getLocaleDirection.d.ts +18 -0
- package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
- package/dist/i18n/getLocaleDirection.js +29 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +7 -1
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- package/dist/i18n/useDirection.d.ts +2 -0
- package/dist/i18n/useDirection.d.ts.map +1 -0
- package/dist/i18n/useDirection.js +27 -0
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +51 -0
- package/dist/theme/hct.d.ts +0 -1
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
- package/dist/utils/devWarning.d.ts +42 -0
- package/dist/utils/devWarning.d.ts.map +1 -0
- package/dist/utils/devWarning.js +88 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +65 -3
- package/dist/utils/rtlStyles.d.ts +24 -0
- package/dist/utils/rtlStyles.d.ts.map +1 -0
- package/dist/utils/rtlStyles.js +27 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +104 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +78 -0
- package/package.json +6 -1
- package/src/AppShell/AppShell.tsx +6 -0
- package/src/AppShell/AppShellMobileContext.tsx +8 -0
- package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
- package/src/Avatar/Avatar.doc.mjs +64 -5
- package/src/Avatar/Avatar.test.tsx +374 -1
- package/src/Avatar/Avatar.tsx +367 -69
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +180 -21
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +141 -1
- package/src/AvatarGroup/AvatarGroup.tsx +58 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +53 -9
- package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +335 -2
- package/src/Breadcrumbs/index.ts +31 -0
- package/src/Button/Button.doc.mjs +9 -4
- package/src/Button/Button.test.tsx +49 -0
- package/src/Button/Button.tsx +27 -3
- package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
- package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
- package/src/ButtonGroup/ButtonGroup.tsx +32 -0
- package/src/Calendar/Calendar.doc.mjs +12 -1
- package/src/Calendar/Calendar.test.tsx +362 -19
- package/src/Calendar/Calendar.tsx +111 -32
- package/src/Calendar/dayCellUtils.test.ts +23 -18
- package/src/Calendar/dayCellUtils.ts +3 -3
- package/src/Calendar/styles.ts +33 -39
- package/src/Card/Card.doc.mjs +9 -0
- package/src/Card/Card.test.tsx +21 -3
- package/src/Card/Card.tsx +35 -2
- package/src/Carousel/Carousel.doc.mjs +1 -0
- package/src/Carousel/Carousel.test.tsx +53 -0
- package/src/Carousel/Carousel.tsx +59 -10
- package/src/Chat/ChatComposer.doc.mjs +12 -3
- package/src/Chat/ChatComposer.test.tsx +115 -0
- package/src/Chat/ChatComposer.tsx +73 -9
- package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
- package/src/Chat/ChatComposerDrawer.tsx +11 -1
- package/src/Chat/ChatComposerInput.doc.mjs +7 -0
- package/src/Chat/ChatComposerInput.test.tsx +103 -0
- package/src/Chat/ChatComposerInput.tsx +51 -5
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +11 -2
- package/src/Chat/ChatLayout.tsx +7 -5
- package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
- package/src/Chat/ChatMessageMetadata.tsx +1 -2
- package/src/Chat/ChatSendButton.tsx +11 -1
- package/src/Chat/ChatToolCalls.test.tsx +64 -0
- package/src/Chat/ChatToolCalls.tsx +33 -5
- package/src/Chat/index.ts +5 -1
- package/src/Chat/useChatStreamScroll.test.tsx +49 -0
- package/src/Chat/useChatStreamScroll.ts +27 -10
- package/src/Chat/useSpeechRecognition.ts +1 -1
- package/src/Chat/useTriggerMenu.tsx +4 -2
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -5
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/CheckboxList/CheckboxList.test.tsx +81 -3
- package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
- package/src/CheckboxList/CheckboxListItem.tsx +41 -5
- package/src/Citation/Citation.doc.mjs +4 -3
- package/src/Citation/Citation.test.tsx +97 -0
- package/src/Citation/Citation.tsx +43 -11
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
- package/src/ClickableCard/ClickableCard.test.tsx +34 -0
- package/src/ClickableCard/ClickableCard.tsx +13 -3
- package/src/CodeBlock/CodeBlock.test.tsx +56 -0
- package/src/CodeBlock/CodeBlock.tsx +45 -10
- package/src/Collapsible/Collapsible.doc.mjs +1 -0
- package/src/Collapsible/Collapsible.test.tsx +7 -0
- package/src/Collapsible/Collapsible.tsx +16 -6
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.test.tsx +95 -1
- package/src/CommandPalette/CommandPalette.tsx +44 -3
- package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
- package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
- package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ContextMenu/ContextMenu.test.tsx +235 -0
- package/src/ContextMenu/ContextMenu.tsx +13 -11
- package/src/ContextMenu/index.ts +5 -0
- package/src/DateInput/DateInput.doc.mjs +41 -0
- package/src/DateInput/DateInput.test.tsx +338 -0
- package/src/DateInput/DateInput.tsx +119 -32
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
- package/src/DateRangeInput/DateRangeInput.tsx +42 -30
- package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
- package/src/DateTimeInput/DateTimeInput.tsx +58 -41
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.test.tsx +77 -4
- package/src/Dialog/Dialog.tsx +89 -5
- package/src/Dialog/DialogContext.ts +9 -2
- package/src/Dialog/DialogHeader.doc.mjs +2 -2
- package/src/Dialog/DialogHeader.tsx +9 -2
- package/src/Divider/Divider.tsx +2 -2
- package/src/DropdownMenu/DropdownMenu.test.tsx +229 -0
- package/src/DropdownMenu/DropdownMenu.tsx +31 -12
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +9 -4
- package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
- package/src/DropdownMenu/index.ts +16 -0
- package/src/DropdownMenu/menuItemHover.ts +39 -0
- package/src/DropdownMenu/menuItemRoles.ts +9 -0
- package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +20 -14
- package/src/Field/FieldLabel.tsx +9 -1
- package/src/Field/inputStyles.stylex.ts +2 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +150 -40
- package/src/FieldStatus/FieldStatus.tsx +69 -5
- package/src/FileInput/FileInput.doc.mjs +23 -2
- package/src/FileInput/FileInput.test.tsx +135 -12
- package/src/FileInput/FileInput.tsx +65 -51
- 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 +39 -5
- package/src/Icon/Icon.doc.mjs +16 -2
- package/src/Icon/Icon.test.tsx +89 -0
- package/src/Icon/Icon.tsx +58 -5
- package/src/IconButton/IconButton.doc.mjs +8 -0
- package/src/IconButton/IconButton.test.tsx +15 -18
- package/src/Item/Item.test.tsx +40 -18
- package/src/Item/Item.tsx +38 -2
- package/src/Layer/useLayer.tsx +8 -0
- package/src/Lightbox/Lightbox.tsx +15 -7
- package/src/List/List.test.tsx +9 -8
- package/src/Markdown/Markdown.test.tsx +21 -0
- package/src/Markdown/Markdown.tsx +4 -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 +24 -2
- package/src/MultiSelector/MultiSelector.test.tsx +498 -3
- package/src/MultiSelector/MultiSelector.tsx +149 -65
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +21 -0
- package/src/NumberInput/NumberInput.test.tsx +82 -7
- package/src/NumberInput/NumberInput.tsx +36 -28
- package/src/Outline/Outline.tsx +0 -1
- package/src/OverflowList/OverflowList.doc.mjs +39 -6
- package/src/OverflowList/OverflowList.test.tsx +111 -0
- package/src/OverflowList/OverflowList.tsx +48 -8
- package/src/Pagination/Pagination.tsx +11 -3
- package/src/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
- package/src/PowerSearch/PowerSearch.test.tsx +43 -0
- package/src/PowerSearch/PowerSearch.tsx +10 -1
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
- package/src/PowerSearch/usePowerSearchSource.ts +1 -2
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/RadioList/RadioList.tsx +2 -2
- package/src/RadioList/RadioListItem.tsx +4 -4
- package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
- package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
- package/src/SelectableCard/SelectableCard.test.tsx +46 -4
- package/src/SelectableCard/SelectableCard.tsx +29 -16
- package/src/Selector/Selector.doc.mjs +15 -0
- package/src/Selector/Selector.test.tsx +417 -0
- package/src/Selector/Selector.tsx +86 -21
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNav.tsx +1 -8
- package/src/SideNav/SideNavCollapseButton.tsx +15 -8
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +10 -4
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +314 -13
- package/src/Slider/Slider.tsx +117 -28
- package/src/Switch/Switch.doc.mjs +142 -42
- package/src/Switch/Switch.test.tsx +54 -1
- package/src/Switch/Switch.tsx +90 -33
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +37 -7
- package/src/Table/Table.doc.mjs +11 -0
- package/src/Table/Table.test.tsx +85 -0
- package/src/Table/TableCell.tsx +3 -3
- package/src/Table/TableHeaderCell.tsx +3 -3
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +15 -8
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
- 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 +77 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +22 -1
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
- package/src/Table/plugins/tree/useTableTreeData.tsx +139 -8
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- package/src/Table/types.ts +33 -0
- package/src/Table/useBaseTablePlugins.ts +10 -6
- package/src/Table/useTableRowStatus.doc.mjs +30 -0
- package/src/Table/useTableSelection.doc.mjs +65 -14
- package/src/Table/useTableTreeData.doc.mjs +29 -0
- package/src/Table/useTableTreeState.doc.mjs +2 -2
- package/src/TextArea/TextArea.doc.mjs +21 -0
- package/src/TextArea/TextArea.test.tsx +32 -1
- package/src/TextArea/TextArea.tsx +27 -26
- package/src/TextInput/TextInput.doc.mjs +21 -0
- package/src/TextInput/TextInput.test.tsx +150 -0
- package/src/TextInput/TextInput.tsx +28 -25
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +142 -42
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.doc.mjs +21 -0
- package/src/TimeInput/TimeInput.test.tsx +99 -1
- package/src/TimeInput/TimeInput.tsx +43 -31
- package/src/Timestamp/Timestamp.doc.mjs +4 -4
- package/src/Timestamp/Timestamp.test.tsx +32 -0
- package/src/Timestamp/Timestamp.tsx +28 -8
- package/src/Toast/useToast.tsx +7 -8
- package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
- package/src/Token/Token.test.tsx +21 -15
- package/src/Token/Token.tsx +31 -14
- package/src/Token/index.ts +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +38 -2
- package/src/Tokenizer/Tokenizer.test.tsx +206 -2
- package/src/Tokenizer/Tokenizer.tsx +30 -6
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +125 -1
- package/src/TopNav/TopNavHeading.tsx +24 -8
- package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
- package/src/TopNav/TopNavMegaMenu.tsx +10 -4
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
- package/src/TopNav/TopNavMenu.test.tsx +118 -4
- package/src/TopNav/TopNavMenu.tsx +83 -5
- package/src/TreeList/TreeList.doc.mjs +28 -0
- package/src/TreeList/TreeList.test.tsx +272 -0
- package/src/TreeList/TreeList.tsx +23 -2
- package/src/TreeList/TreeListBranches.tsx +24 -8
- package/src/TreeList/TreeListItem.tsx +84 -22
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/Typeahead/BaseTypeahead.tsx +30 -15
- package/src/Typeahead/Typeahead.doc.mjs +13 -0
- package/src/Typeahead/Typeahead.test.tsx +50 -0
- package/src/Typeahead/Typeahead.tsx +11 -1
- package/src/Typeahead/TypeaheadItem.tsx +2 -1
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/authoring/doc.ts +1 -3
- package/src/doc-mjs.d.ts +19 -0
- package/src/docs-types.ts +5 -0
- package/src/hooks/computeOverflow.test.ts +422 -0
- package/src/hooks/computeOverflow.ts +290 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- package/src/hooks/useGridFocus.doc.mjs +3 -3
- package/src/hooks/useGridFocus.test.tsx +41 -0
- package/src/hooks/useGridFocus.ts +21 -10
- package/src/hooks/useInputStatusIcon.test.tsx +162 -0
- package/src/hooks/useInputStatusIcon.tsx +224 -0
- package/src/hooks/useListFocus.doc.mjs +25 -3
- package/src/hooks/useListFocus.test.tsx +153 -1
- package/src/hooks/useListFocus.ts +102 -9
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationContext.ts +4 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- package/src/i18n/InternationalizationProvider.tsx +12 -2
- package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
- package/src/i18n/__tests__/useDirection.test.tsx +66 -0
- package/src/i18n/getLocaleDirection.ts +29 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/resolve.ts +9 -21
- package/src/i18n/useDirection.ts +29 -0
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +107 -0
- package/src/theme/generateThemeRules.ts +56 -0
- package/src/theme/hct.ts +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
- package/src/utils/devWarning.test.ts +56 -0
- package/src/utils/devWarning.ts +102 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/plainDate.test.ts +46 -6
- package/src/utils/plainDate.ts +69 -3
- package/src/utils/rtlStyles.ts +27 -0
- package/src/utils/types.ts +14 -0
|
@@ -15,6 +15,7 @@ export const docs = {
|
|
|
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
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
|
+
{guidance: true, description: 'When wrapping an Avatar in your own Tooltip or HoverCard, set tooltip={false} so the built-in name tooltip does not overlap yours.'},
|
|
18
19
|
{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
20
|
{guidance: false, description: 'Force a square or custom shape. Avatars are always circular to stay consistent across the system.'},
|
|
20
21
|
],
|
|
@@ -22,13 +23,26 @@ export const docs = {
|
|
|
22
23
|
{name: 'Photo', required: false, description: 'The profile image, loaded from the src URL. Shown when available.'},
|
|
23
24
|
{name: 'Initials', required: false, description: 'One or two letters extracted from the name. Shown when no photo is available.'},
|
|
24
25
|
{name: 'Default icon', required: false, description: 'A generic person silhouette. Shown when there is no photo or name.'},
|
|
25
|
-
{name: 'Status dot', required: false, description: 'A small indicator in the bottom-right corner showing availability (online, away, busy).'},
|
|
26
|
+
{name: 'Status dot', required: false, description: 'A small indicator in the bottom-right corner showing availability (online, away, busy). Each variant pairs colour with a distinct shape so status does not rely on colour alone.'},
|
|
26
27
|
],
|
|
27
28
|
},
|
|
28
29
|
theming: {
|
|
29
30
|
targets: [
|
|
30
31
|
{className: 'astryx-avatar', visualProps: ['size']},
|
|
31
32
|
{className: 'astryx-avatar-status-dot', visualProps: ['variant']},
|
|
33
|
+
{className: 'astryx-avatar-status-dot-glyph', visualProps: ['shape']},
|
|
34
|
+
],
|
|
35
|
+
vars: [
|
|
36
|
+
{name: '--_avatar-fallback-font-size', description: 'Initials font size; default is proportional to the avatar size (size × 0.4). Override per size tier (e.g. size:sm) for a custom type scale.', default: 'calc(avatar-size × 0.4)', private: true},
|
|
37
|
+
{name: '--_avatar-fallback-font-weight', description: 'Initials font weight', default: 'var(--font-weight-medium)', private: true},
|
|
38
|
+
{name: '--_avatar-fallback-color', description: 'Fallback text and default-icon color', default: 'var(--color-text-secondary)', private: true},
|
|
39
|
+
{name: '--_avatar-fallback-background', description: 'Fallback wash background fill', default: 'var(--color-neutral)', private: true},
|
|
40
|
+
],
|
|
41
|
+
derived: [
|
|
42
|
+
{property: 'fontSize', vars: ['--_avatar-fallback-font-size']},
|
|
43
|
+
{property: 'fontWeight', vars: ['--_avatar-fallback-font-weight']},
|
|
44
|
+
{property: 'color', vars: ['--_avatar-fallback-color']},
|
|
45
|
+
{property: 'backgroundColor', vars: ['--_avatar-fallback-background']},
|
|
32
46
|
],
|
|
33
47
|
},
|
|
34
48
|
description: 'Displays a user avatar with image, initials fallback, and optional status indicator.',
|
|
@@ -62,16 +76,52 @@ export const docs = {
|
|
|
62
76
|
{
|
|
63
77
|
name: 'status',
|
|
64
78
|
type: 'ReactNode',
|
|
65
|
-
description: 'Corner content for status indicators.',
|
|
79
|
+
description: 'Corner content for status indicators. A string `label` on the element (as on AvatarStatusDot) is composed into the avatar\'s accessible name (e.g. "Jane Doe, Online") so screen readers announce the status.',
|
|
66
80
|
slotElements: [
|
|
67
81
|
{
|
|
68
|
-
__element: '
|
|
82
|
+
__element: 'AvatarStatusDot',
|
|
69
83
|
props: {
|
|
70
|
-
variant: '
|
|
84
|
+
variant: 'success',
|
|
85
|
+
label: 'Online',
|
|
71
86
|
},
|
|
72
87
|
},
|
|
73
88
|
],
|
|
74
89
|
},
|
|
90
|
+
{
|
|
91
|
+
name: 'tooltip',
|
|
92
|
+
type: 'string | boolean',
|
|
93
|
+
description:
|
|
94
|
+
"Tooltip shown on hover and keyboard focus. Omitted or true shows the avatar's name; a string shows that text instead; false shows no tooltip. Not auto-disabled when wrapped in your own Tooltip/HoverCard. Set tooltip={false} if you supply your own overlay. No tooltip is shown when tooltip is true/omitted and there is no name.",
|
|
95
|
+
default: 'true',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'href',
|
|
99
|
+
type: 'string',
|
|
100
|
+
description:
|
|
101
|
+
'When set, the avatar renders as an interactive link (`<a>` or a custom link component) pointing here. This follows the same element-swap rule as Button. Requires a meaningful accessible name via `alt` or `name`. Inside an AvatarGroup, interactive avatars share a single Tab stop and are reached with arrow keys.',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'as',
|
|
105
|
+
type: 'ElementType',
|
|
106
|
+
description:
|
|
107
|
+
'Custom link component used when `href` is set (e.g. Next.js `Link`). Overrides the provider-level LinkProvider default. Only applies with `href`.',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'target',
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: 'Link target attribute. Only applies with `href`.',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'rel',
|
|
116
|
+
type: 'string',
|
|
117
|
+
description: 'Link rel attribute. Only applies with `href`.',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'onClick',
|
|
121
|
+
type: '(e: MouseEvent) => void',
|
|
122
|
+
description:
|
|
123
|
+
'Click handler. When set without `href`, the avatar renders as a focusable `<button type="button">`. Requires a meaningful accessible name via `alt` or `name`.',
|
|
124
|
+
},
|
|
75
125
|
],
|
|
76
126
|
components: [
|
|
77
127
|
{name: 'AvatarStatusDot'},
|
|
@@ -102,6 +152,7 @@ export const docsDense = {
|
|
|
102
152
|
{guidance: true, description: 'Always pass a name for initials fallback and screen reader alt text.'},
|
|
103
153
|
{guidance: true, description: 'Match size to context: xsm/sm inline, md/lg in lists, xl for profiles.'},
|
|
104
154
|
{guidance: true, description: 'Add a status dot in chat or team views where availability matters.'},
|
|
155
|
+
{guidance: true, description: 'When wrapping Avatar in your own Tooltip or HoverCard, set tooltip={false} so the built-in name tooltip does not overlap yours.'},
|
|
105
156
|
{guidance: false, description: 'Use for logos or product images. Use an image or icon instead.'},
|
|
106
157
|
{guidance: false, description: 'Force a square or custom shape. Avatars are always circular.'},
|
|
107
158
|
],
|
|
@@ -112,7 +163,15 @@ export const docsDense = {
|
|
|
112
163
|
name: 'user name for initials and alt text',
|
|
113
164
|
alt: 'alt text; falls back to name',
|
|
114
165
|
size: "avatar size. Named ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or numeric px.",
|
|
115
|
-
status:
|
|
166
|
+
status:
|
|
167
|
+
'corner content for status indicators; its `label` is composed into the avatar accessible name ("Jane Doe, Online")',
|
|
168
|
+
tooltip:
|
|
169
|
+
"hover/focus tooltip. true/omitted → name; string → that text; false → none. Owns its tooltip; set false when wrapping in your own Tooltip/HoverCard. Default true.",
|
|
170
|
+
href: 'renders avatar as a link (<a>/custom). Needs alt/name. Button-style element swap.',
|
|
171
|
+
as: 'custom link component for href (e.g. Next Link). Only with href.',
|
|
172
|
+
target: 'link target. Only with href.',
|
|
173
|
+
rel: 'link rel. Only with href.',
|
|
174
|
+
onClick: 'click handler → renders <button> when no href. Needs alt/name.',
|
|
116
175
|
},
|
|
117
176
|
components: [
|
|
118
177
|
{name: 'AvatarStatusDot', description: 'size-aware status indicator rendered in the Avatar corner'},
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
3
|
+
import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
|
|
4
4
|
import {render, screen, fireEvent} from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
5
6
|
import {Avatar} from './Avatar';
|
|
7
|
+
import {AvatarStatusDot} from './AvatarStatusDot';
|
|
6
8
|
|
|
7
9
|
describe('Avatar', () => {
|
|
8
10
|
it('exposes role="img" with the name as accessible name', () => {
|
|
@@ -35,6 +37,19 @@ describe('Avatar', () => {
|
|
|
35
37
|
expect(innerImg).toHaveAttribute('alt', '');
|
|
36
38
|
});
|
|
37
39
|
|
|
40
|
+
it('renders fallback initials through the themeable font-size var, not a bare px literal', () => {
|
|
41
|
+
render(<Avatar name="Ada Lovelace" size="sm" data-testid="a" />);
|
|
42
|
+
const initials = screen.getByText('AL');
|
|
43
|
+
// The seam: the dynamic font size resolves to the Avatar-scoped var (with
|
|
44
|
+
// the proportional `size × 0.4` default baked in as the fallback), so a
|
|
45
|
+
// theme can re-scope it per size. A regression to a bare px literal would
|
|
46
|
+
// break theming.
|
|
47
|
+
const style = initials.getAttribute('style') ?? '';
|
|
48
|
+
expect(style).toContain('var(--_avatar-fallback-font-size,');
|
|
49
|
+
// Default still reproduces the proportional scale (sm = 24 × 0.4 = 9.6px).
|
|
50
|
+
expect(style).toMatch(/var\(--_avatar-fallback-font-size,\s*9\.6\d*px\)/);
|
|
51
|
+
});
|
|
52
|
+
|
|
38
53
|
it('retries a new src after a previous src failed to load', () => {
|
|
39
54
|
const {rerender} = render(
|
|
40
55
|
<Avatar name="Ada" src="https://example.com/broken.jpg" />,
|
|
@@ -52,6 +67,98 @@ describe('Avatar', () => {
|
|
|
52
67
|
expect(img).toHaveAttribute('src', 'https://example.com/ada.jpg');
|
|
53
68
|
});
|
|
54
69
|
|
|
70
|
+
describe('status in the accessible name (WCAG 4.1.2)', () => {
|
|
71
|
+
// The avatar root is role="img", which prunes descendant semantics —
|
|
72
|
+
// a label inside the status subtree is never announced on its own.
|
|
73
|
+
// Avatar composes the status element's `label` into its own name.
|
|
74
|
+
it('composes the status label into the accessible name for image avatars', () => {
|
|
75
|
+
render(
|
|
76
|
+
<Avatar
|
|
77
|
+
name="Ada Lovelace"
|
|
78
|
+
src="https://example.com/ada.jpg"
|
|
79
|
+
status={<AvatarStatusDot variant="success" label="Online" />}
|
|
80
|
+
/>,
|
|
81
|
+
);
|
|
82
|
+
expect(
|
|
83
|
+
screen.getByRole('img', {name: 'Ada Lovelace, Online'}),
|
|
84
|
+
).toBeInTheDocument();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('composes the status label into the accessible name for initials avatars', () => {
|
|
88
|
+
render(
|
|
89
|
+
<Avatar
|
|
90
|
+
name="Ada Lovelace"
|
|
91
|
+
status={<AvatarStatusDot variant="error" label="Busy" />}
|
|
92
|
+
/>,
|
|
93
|
+
);
|
|
94
|
+
const avatar = screen.getByRole('img', {name: 'Ada Lovelace, Busy'});
|
|
95
|
+
expect(avatar).toBeInTheDocument();
|
|
96
|
+
expect(avatar).toHaveTextContent('AL');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('composes the status label with alt when alt overrides name', () => {
|
|
100
|
+
render(
|
|
101
|
+
<Avatar
|
|
102
|
+
name="Ada"
|
|
103
|
+
alt="Ada Lovelace, profile photo"
|
|
104
|
+
status={<AvatarStatusDot label="Online" />}
|
|
105
|
+
/>,
|
|
106
|
+
);
|
|
107
|
+
expect(
|
|
108
|
+
screen.getByRole('img', {name: 'Ada Lovelace, profile photo, Online'}),
|
|
109
|
+
).toBeInTheDocument();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('keeps the plain name when there is no status', () => {
|
|
113
|
+
render(<Avatar name="Ada Lovelace" data-testid="a" />);
|
|
114
|
+
expect(screen.getByTestId('a')).toHaveAttribute(
|
|
115
|
+
'aria-label',
|
|
116
|
+
'Ada Lovelace',
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('keeps the plain name when the status dot has no label', () => {
|
|
121
|
+
render(
|
|
122
|
+
<Avatar
|
|
123
|
+
name="Ada Lovelace"
|
|
124
|
+
data-testid="a"
|
|
125
|
+
status={<AvatarStatusDot variant="success" />}
|
|
126
|
+
/>,
|
|
127
|
+
);
|
|
128
|
+
expect(screen.getByTestId('a')).toHaveAttribute(
|
|
129
|
+
'aria-label',
|
|
130
|
+
'Ada Lovelace',
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('keeps the plain name for custom status nodes without a label prop', () => {
|
|
135
|
+
render(<Avatar name="Ada Lovelace" data-testid="a" status={<span />} />);
|
|
136
|
+
expect(screen.getByTestId('a')).toHaveAttribute(
|
|
137
|
+
'aria-label',
|
|
138
|
+
'Ada Lovelace',
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('announces a labelled status even on an otherwise decorative avatar', () => {
|
|
143
|
+
// A labelled status is meaningful information on its own — the avatar
|
|
144
|
+
// must not stay aria-hidden and swallow it.
|
|
145
|
+
render(
|
|
146
|
+
<Avatar data-testid="a" status={<AvatarStatusDot label="Online" />} />,
|
|
147
|
+
);
|
|
148
|
+
const el = screen.getByTestId('a');
|
|
149
|
+
expect(el).toHaveAttribute('role', 'img');
|
|
150
|
+
expect(el).toHaveAttribute('aria-label', 'Online');
|
|
151
|
+
expect(el).not.toHaveAttribute('aria-hidden');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('stays decorative with an unlabelled status and no name', () => {
|
|
155
|
+
render(<Avatar data-testid="a" status={<AvatarStatusDot />} />);
|
|
156
|
+
const el = screen.getByTestId('a');
|
|
157
|
+
expect(el).toHaveAttribute('aria-hidden', 'true');
|
|
158
|
+
expect(el).not.toHaveAttribute('aria-label');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
55
162
|
it('retries a new fallbackSrc after a previous fallbackSrc failed to load', () => {
|
|
56
163
|
const {rerender} = render(
|
|
57
164
|
<Avatar name="Ada" fallbackSrc="https://example.com/broken.jpg" />,
|
|
@@ -65,4 +172,270 @@ describe('Avatar', () => {
|
|
|
65
172
|
expect(img).not.toBeNull();
|
|
66
173
|
expect(img).toHaveAttribute('src', 'https://example.com/ada.jpg');
|
|
67
174
|
});
|
|
175
|
+
|
|
176
|
+
// --- Name tooltip (tooltip?: string | boolean) ---
|
|
177
|
+
describe('name tooltip', () => {
|
|
178
|
+
const originalShowPopover = HTMLElement.prototype.showPopover;
|
|
179
|
+
const originalHidePopover = HTMLElement.prototype.hidePopover;
|
|
180
|
+
|
|
181
|
+
beforeEach(() => {
|
|
182
|
+
// jsdom does not implement the Popover API the tooltip layer uses.
|
|
183
|
+
HTMLElement.prototype.showPopover = vi.fn();
|
|
184
|
+
HTMLElement.prototype.hidePopover = vi.fn();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
afterEach(() => {
|
|
188
|
+
HTMLElement.prototype.showPopover = originalShowPopover;
|
|
189
|
+
HTMLElement.prototype.hidePopover = originalHidePopover;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('shows the name in a tooltip by default', () => {
|
|
193
|
+
render(<Avatar name="Ada Lovelace" />);
|
|
194
|
+
const tooltip = screen.getByRole('tooltip', {hidden: true});
|
|
195
|
+
expect(tooltip).toHaveTextContent('Ada Lovelace');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('shows a custom string tooltip instead of the name', () => {
|
|
199
|
+
render(<Avatar name="alovelace" tooltip="Ada Lovelace, Mathematician" />);
|
|
200
|
+
const tooltip = screen.getByRole('tooltip', {hidden: true});
|
|
201
|
+
expect(tooltip).toHaveTextContent('Ada Lovelace, Mathematician');
|
|
202
|
+
expect(tooltip).not.toHaveTextContent('alovelace');
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('renders no tooltip when tooltip={false}', () => {
|
|
206
|
+
render(<Avatar name="Ada Lovelace" tooltip={false} />);
|
|
207
|
+
expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('renders no tooltip for a decorative avatar (no name/alt)', () => {
|
|
211
|
+
render(<Avatar src="https://example.com/x.jpg" />);
|
|
212
|
+
expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('renders no tooltip when tooltip is true/default but name is empty', () => {
|
|
216
|
+
render(<Avatar name=" " alt="Profile photo" data-testid="a" />);
|
|
217
|
+
// A whitespace-only name yields nothing to show, and the default tooltip
|
|
218
|
+
// uses `name` (not `alt`), so there is no tooltip.
|
|
219
|
+
expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
|
|
220
|
+
// The accessible name still comes from alt, unaffected.
|
|
221
|
+
expect(
|
|
222
|
+
screen.getByRole('img', {name: 'Profile photo'}),
|
|
223
|
+
).toBeInTheDocument();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('still shows a custom string tooltip when there is no name', () => {
|
|
227
|
+
render(<Avatar tooltip="Anonymous user" data-testid="a" />);
|
|
228
|
+
const tooltip = screen.getByRole('tooltip', {hidden: true});
|
|
229
|
+
expect(tooltip).toHaveTextContent('Anonymous user');
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('makes the root focusable while a tooltip is attached', () => {
|
|
233
|
+
render(<Avatar name="Ada Lovelace" data-testid="a" />);
|
|
234
|
+
expect(screen.getByTestId('a')).toHaveAttribute('tabindex', '0');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('does not add a tab stop when the tooltip is disabled', () => {
|
|
238
|
+
render(<Avatar name="Ada Lovelace" tooltip={false} data-testid="a" />);
|
|
239
|
+
expect(screen.getByTestId('a')).not.toHaveAttribute('tabindex');
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('keeps the accessible name on the root regardless of the tooltip', () => {
|
|
243
|
+
const {rerender} = render(<Avatar name="Ada Lovelace" />);
|
|
244
|
+
expect(
|
|
245
|
+
screen.getByRole('img', {name: 'Ada Lovelace'}),
|
|
246
|
+
).toBeInTheDocument();
|
|
247
|
+
|
|
248
|
+
rerender(<Avatar name="Ada Lovelace" tooltip={false} />);
|
|
249
|
+
expect(
|
|
250
|
+
screen.getByRole('img', {name: 'Ada Lovelace'}),
|
|
251
|
+
).toBeInTheDocument();
|
|
252
|
+
|
|
253
|
+
rerender(<Avatar name="alovelace" tooltip="Ada Lovelace, Eng" />);
|
|
254
|
+
// alt||name still drives the accessible name — not the custom tooltip.
|
|
255
|
+
expect(screen.getByRole('img', {name: 'alovelace'})).toBeInTheDocument();
|
|
256
|
+
|
|
257
|
+
rerender(<Avatar name="alovelace" alt="Ada's profile photo" />);
|
|
258
|
+
expect(
|
|
259
|
+
screen.getByRole('img', {name: "Ada's profile photo"}),
|
|
260
|
+
).toBeInTheDocument();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('does not describe the root with the default name tooltip (no double-announce)', () => {
|
|
264
|
+
render(<Avatar name="Ada Lovelace" data-testid="a" />);
|
|
265
|
+
// The default name tooltip is visual-only: its text duplicates the root
|
|
266
|
+
// aria-label, so we deliberately do NOT wire aria-describedby (OQ-4).
|
|
267
|
+
expect(screen.getByTestId('a')).not.toHaveAttribute('aria-describedby');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('describes the root with a custom string tooltip (matches Button)', () => {
|
|
271
|
+
render(
|
|
272
|
+
<Avatar
|
|
273
|
+
name="alovelace"
|
|
274
|
+
tooltip="Ada Lovelace, Mathematician"
|
|
275
|
+
data-testid="a"
|
|
276
|
+
/>,
|
|
277
|
+
);
|
|
278
|
+
const root = screen.getByTestId('a');
|
|
279
|
+
const describedBy = root.getAttribute('aria-describedby');
|
|
280
|
+
expect(describedBy).toBeTruthy();
|
|
281
|
+
// aria-describedby points at the rendered tooltip layer.
|
|
282
|
+
const tooltip = screen.getByRole('tooltip', {hidden: true});
|
|
283
|
+
expect(tooltip.id).toBeTruthy();
|
|
284
|
+
expect(describedBy).toContain(tooltip.id);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('composes a consumer aria-describedby with the custom tooltip description', () => {
|
|
288
|
+
render(
|
|
289
|
+
<>
|
|
290
|
+
<span id="extra-desc">extra description</span>
|
|
291
|
+
<Avatar
|
|
292
|
+
name="alovelace"
|
|
293
|
+
tooltip="Ada Lovelace, Eng"
|
|
294
|
+
aria-describedby="extra-desc"
|
|
295
|
+
data-testid="a"
|
|
296
|
+
/>
|
|
297
|
+
</>,
|
|
298
|
+
);
|
|
299
|
+
const describedBy = screen
|
|
300
|
+
.getByTestId('a')
|
|
301
|
+
.getAttribute('aria-describedby');
|
|
302
|
+
expect(describedBy).toContain('extra-desc');
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('preserves a consumer aria-describedby with the default name tooltip', () => {
|
|
306
|
+
render(
|
|
307
|
+
<>
|
|
308
|
+
<span id="extra-desc">extra description</span>
|
|
309
|
+
<Avatar
|
|
310
|
+
name="Ada Lovelace"
|
|
311
|
+
aria-describedby="extra-desc"
|
|
312
|
+
data-testid="a"
|
|
313
|
+
/>
|
|
314
|
+
</>,
|
|
315
|
+
);
|
|
316
|
+
// Default name tooltip does not touch aria-describedby, so the consumer
|
|
317
|
+
// value passes through untouched.
|
|
318
|
+
expect(screen.getByTestId('a')).toHaveAttribute(
|
|
319
|
+
'aria-describedby',
|
|
320
|
+
'extra-desc',
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('forwards the consumer ref to the root while a tooltip is attached', () => {
|
|
325
|
+
const ref = {current: null as HTMLDivElement | null};
|
|
326
|
+
render(<Avatar name="Ada Lovelace" ref={ref} data-testid="a" />);
|
|
327
|
+
expect(ref.current).toBe(screen.getByTestId('a'));
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
describe('Avatar — interactivity (Button trichotomy)', () => {
|
|
333
|
+
afterEach(() => {
|
|
334
|
+
vi.restoreAllMocks();
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it('renders a link when `href` is set (default LinkComponent is <a>)', () => {
|
|
338
|
+
render(<Avatar name="Ada Lovelace" href="/users/ada" />);
|
|
339
|
+
const link = screen.getByRole('link', {name: 'Ada Lovelace'});
|
|
340
|
+
expect(link.tagName).toBe('A');
|
|
341
|
+
expect(link).toHaveAttribute('href', '/users/ada');
|
|
342
|
+
// The static img semantics are gone — it's a control now.
|
|
343
|
+
expect(screen.queryByRole('img')).not.toBeInTheDocument();
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('forwards target/rel on the link', () => {
|
|
347
|
+
render(
|
|
348
|
+
<Avatar
|
|
349
|
+
name="Ada"
|
|
350
|
+
href="https://example.com"
|
|
351
|
+
target="_blank"
|
|
352
|
+
rel="noopener noreferrer"
|
|
353
|
+
/>,
|
|
354
|
+
);
|
|
355
|
+
const link = screen.getByRole('link', {name: 'Ada'});
|
|
356
|
+
expect(link).toHaveAttribute('target', '_blank');
|
|
357
|
+
expect(link).toHaveAttribute('rel', 'noopener noreferrer');
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it('renders a <button type="button"> when `onClick` is set (no href)', async () => {
|
|
361
|
+
const user = userEvent.setup();
|
|
362
|
+
const handleClick = vi.fn();
|
|
363
|
+
render(<Avatar name="Ada" onClick={handleClick} />);
|
|
364
|
+
const button = screen.getByRole('button', {name: 'Ada'});
|
|
365
|
+
expect(button.tagName).toBe('BUTTON');
|
|
366
|
+
expect(button).toHaveAttribute('type', 'button');
|
|
367
|
+
await user.click(button);
|
|
368
|
+
expect(handleClick).toHaveBeenCalledOnce();
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it('href wins over onClick (link, not button)', () => {
|
|
372
|
+
render(<Avatar name="Ada" href="/ada" onClick={() => {}} />);
|
|
373
|
+
expect(screen.getByRole('link', {name: 'Ada'})).toBeInTheDocument();
|
|
374
|
+
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('stays a static element (no href, no onClick) — non-breaking default', () => {
|
|
378
|
+
render(<Avatar name="Ada" />);
|
|
379
|
+
expect(screen.getByRole('img', {name: 'Ada'})).toBeInTheDocument();
|
|
380
|
+
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
|
381
|
+
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('stamps the data-avatar-item marker on the interactive link', () => {
|
|
385
|
+
render(<Avatar name="Ada" href="/ada" />);
|
|
386
|
+
expect(screen.getByRole('link', {name: 'Ada'})).toHaveAttribute(
|
|
387
|
+
'data-avatar-item',
|
|
388
|
+
);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('stamps the data-avatar-item marker on the interactive button', () => {
|
|
392
|
+
render(<Avatar name="Ada" onClick={() => {}} />);
|
|
393
|
+
expect(screen.getByRole('button', {name: 'Ada'})).toHaveAttribute(
|
|
394
|
+
'data-avatar-item',
|
|
395
|
+
);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('does not stamp data-avatar-item on a static avatar', () => {
|
|
399
|
+
render(<Avatar name="Ada" data-testid="a" />);
|
|
400
|
+
expect(screen.getByTestId('a')).not.toHaveAttribute('data-avatar-item');
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('carries a focus-visible ring class on the interactive element', () => {
|
|
404
|
+
// The interactive element applies the shared focus-visible accent ring via
|
|
405
|
+
// its StyleX class. We assert the element is focusable and receives focus.
|
|
406
|
+
render(<Avatar name="Ada" onClick={() => {}} />);
|
|
407
|
+
const button = screen.getByRole('button', {name: 'Ada'});
|
|
408
|
+
button.focus();
|
|
409
|
+
expect(button).toHaveFocus();
|
|
410
|
+
// className carries the avatar theming target so themes can style it.
|
|
411
|
+
expect(button.className).toContain('astryx-avatar');
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it('warns in dev when interactive without an accessible name (href)', () => {
|
|
415
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
416
|
+
render(<Avatar href="/somewhere" />);
|
|
417
|
+
expect(warn).toHaveBeenCalledWith(
|
|
418
|
+
expect.stringContaining('interactive avatar'),
|
|
419
|
+
);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('warns in dev when interactive without an accessible name (onClick)', () => {
|
|
423
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
424
|
+
render(<Avatar onClick={() => {}} />);
|
|
425
|
+
expect(warn).toHaveBeenCalledWith(
|
|
426
|
+
expect.stringContaining('interactive avatar'),
|
|
427
|
+
);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('does not warn when interactive with a name', () => {
|
|
431
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
432
|
+
render(<Avatar name="Ada" href="/ada" />);
|
|
433
|
+
expect(warn).not.toHaveBeenCalled();
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('does not warn for a static avatar without a name (decorative is fine)', () => {
|
|
437
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
438
|
+
render(<Avatar data-testid="a" />);
|
|
439
|
+
expect(warn).not.toHaveBeenCalled();
|
|
440
|
+
});
|
|
68
441
|
});
|