@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
|
@@ -96,6 +96,15 @@ export interface HoverCardProps extends Pick<
|
|
|
96
96
|
*/
|
|
97
97
|
isEnabled?: boolean;
|
|
98
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Accessible name for the hover card popup.
|
|
101
|
+
*
|
|
102
|
+
* When provided, the popup is exposed to assistive technology as a named
|
|
103
|
+
* `role="dialog"`. When omitted, the popup falls back to `role="group"` —
|
|
104
|
+
* a group may validly be unnamed, an unnamed dialog may not.
|
|
105
|
+
*/
|
|
106
|
+
label?: string;
|
|
107
|
+
|
|
99
108
|
/**
|
|
100
109
|
* Callback fired when hover card visibility changes.
|
|
101
110
|
* Called with `true` when shown and `false` when hidden.
|
|
@@ -166,6 +175,7 @@ export function HoverCard({
|
|
|
166
175
|
hideDelay = 200,
|
|
167
176
|
focusTrigger = 'auto',
|
|
168
177
|
isEnabled = true,
|
|
178
|
+
label,
|
|
169
179
|
onOpenChange,
|
|
170
180
|
hasHoverIndication = 'auto',
|
|
171
181
|
isOpen,
|
|
@@ -197,6 +207,7 @@ export function HoverCard({
|
|
|
197
207
|
hideDelay,
|
|
198
208
|
focusTrigger,
|
|
199
209
|
isEnabled,
|
|
210
|
+
label,
|
|
200
211
|
isOpen,
|
|
201
212
|
isDefaultOpen,
|
|
202
213
|
onShow: handleShow,
|
|
@@ -13,6 +13,7 @@ export const docs = {
|
|
|
13
13
|
{name: 'hideDelay', type: 'number', description: 'Delay before hiding after mouse or focus leaves, in milliseconds.', default: '200'},
|
|
14
14
|
{name: 'focusTrigger', type: "'auto' | 'always' | 'never'", description: 'When focus should open the hover card. auto only attaches focus listeners to naturally focusable elements.', default: "'auto'"},
|
|
15
15
|
{name: 'isEnabled', type: 'boolean', description: 'Whether hover and focus triggers are enabled.', default: 'true'},
|
|
16
|
+
{name: 'label', type: 'string', description: 'Accessible name for the hover card popup. When provided, the popup is exposed as a named role="dialog"; when omitted, it falls back to role="group" (a group may validly be unnamed).'},
|
|
16
17
|
{name: 'isOpen', type: 'boolean', description: 'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.'},
|
|
17
18
|
{name: 'isDefaultOpen', type: 'boolean', description: 'Whether the hover card should be shown on mount.', default: 'false'},
|
|
18
19
|
{name: 'onShow', type: '() => void', description: 'Callback fired when the hover card becomes visible.'},
|
|
@@ -52,6 +53,7 @@ export const docsDense = {
|
|
|
52
53
|
hideDelay: 'hide delay after mouse/focus leave in ms.',
|
|
53
54
|
focusTrigger: 'when focus opens hover card; auto = naturally focusable elements only.',
|
|
54
55
|
isEnabled: 'whether hover/focus triggers are enabled.',
|
|
56
|
+
label: 'accessible name for popup. with label: named role="dialog"; without: role="group".',
|
|
55
57
|
isOpen: 'controlled open state: true force-show, false force-hide, undefined unmanaged.',
|
|
56
58
|
isDefaultOpen: 'show on mount.',
|
|
57
59
|
onShow: 'fires when hover card becomes visible.',
|
|
@@ -34,7 +34,6 @@ import {
|
|
|
34
34
|
radiusVars,
|
|
35
35
|
spacingVars,
|
|
36
36
|
} from '../theme/tokens.stylex';
|
|
37
|
-
import {mergeProps} from '../utils';
|
|
38
37
|
import {themeProps} from '../utils/themeProps';
|
|
39
38
|
|
|
40
39
|
const styles = stylex.create({
|
|
@@ -119,6 +118,15 @@ export interface HoverCardOptions {
|
|
|
119
118
|
*/
|
|
120
119
|
isEnabled?: boolean;
|
|
121
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Accessible name for the hover card popup.
|
|
123
|
+
*
|
|
124
|
+
* When provided, the popup is exposed to assistive technology as a named
|
|
125
|
+
* `role="dialog"`. When omitted, the popup falls back to `role="group"` —
|
|
126
|
+
* a group may validly be unnamed, an unnamed dialog may not.
|
|
127
|
+
*/
|
|
128
|
+
label?: string;
|
|
129
|
+
|
|
122
130
|
/**
|
|
123
131
|
* Controlled open state. When provided, overrides hover/focus triggers:
|
|
124
132
|
* - `true`: force-show the hover card (hover/focus hide is suppressed)
|
|
@@ -250,6 +258,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
250
258
|
hideDelay = 200,
|
|
251
259
|
focusTrigger = 'auto',
|
|
252
260
|
isEnabled = true,
|
|
261
|
+
label,
|
|
253
262
|
isOpen,
|
|
254
263
|
isDefaultOpen = false,
|
|
255
264
|
onShow,
|
|
@@ -459,11 +468,28 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
459
468
|
props?: Omit<ContextRenderProps, 'positioning'>,
|
|
460
469
|
): ReactNode => {
|
|
461
470
|
const renderPlacement = props?.placement ?? placement;
|
|
471
|
+
const themeClassName = themeProps('hovercard').className;
|
|
462
472
|
const renderProps = {
|
|
463
473
|
placement: renderPlacement,
|
|
464
474
|
alignment: props?.alignment ?? alignment,
|
|
465
|
-
|
|
466
|
-
|
|
475
|
+
// A named dialog when a label is provided; otherwise a group. A group
|
|
476
|
+
// may validly be unnamed, an unnamed dialog may not — and hover cards
|
|
477
|
+
// are non-modal, so group is honest semantics without a name.
|
|
478
|
+
role: label ? 'dialog' : 'group',
|
|
479
|
+
'aria-label': label || undefined,
|
|
480
|
+
// Consumer surface style props land on the layer container — the
|
|
481
|
+
// themed surface (bg/radius/shadow) where the theme class lives — so
|
|
482
|
+
// customizing the card targets the same element as the theme. The inner
|
|
483
|
+
// span keeps `styles.content` for padding.
|
|
484
|
+
xstyle: [
|
|
485
|
+
popoverXstyle,
|
|
486
|
+
layerAnimations[renderPlacement],
|
|
487
|
+
props?.xstyle,
|
|
488
|
+
],
|
|
489
|
+
className: props?.className
|
|
490
|
+
? `${themeClassName} ${props.className}`
|
|
491
|
+
: themeClassName,
|
|
492
|
+
style: props?.style,
|
|
467
493
|
// Render the layer as inline-safe phrasing markup so HoverCard stays
|
|
468
494
|
// valid (and hydration-stable) inside inline contexts like a `<p>`.
|
|
469
495
|
as: 'span' as const,
|
|
@@ -471,7 +497,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
471
497
|
|
|
472
498
|
return layer.render(
|
|
473
499
|
<span
|
|
474
|
-
{...
|
|
500
|
+
{...stylex.props(styles.content)}
|
|
475
501
|
onMouseEnter={() => {
|
|
476
502
|
isHoveringContentRef.current = true;
|
|
477
503
|
clearTimeouts();
|
|
@@ -516,7 +542,15 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
516
542
|
renderProps,
|
|
517
543
|
);
|
|
518
544
|
},
|
|
519
|
-
[
|
|
545
|
+
[
|
|
546
|
+
layer,
|
|
547
|
+
placement,
|
|
548
|
+
alignment,
|
|
549
|
+
label,
|
|
550
|
+
clearTimeouts,
|
|
551
|
+
scheduleHide,
|
|
552
|
+
popoverXstyle,
|
|
553
|
+
],
|
|
520
554
|
);
|
|
521
555
|
|
|
522
556
|
return {
|
package/src/Icon/Icon.doc.mjs
CHANGED
|
@@ -37,7 +37,13 @@ export const docs = {
|
|
|
37
37
|
{
|
|
38
38
|
name: 'label',
|
|
39
39
|
type: 'string',
|
|
40
|
-
description: 'Accessible name for a MEANINGFUL, standalone icon (a status glyph or icon-only indicator with no adjacent text). Setting it exposes the icon to screen readers as role="img" with this text as the accessible name (aria-label) and removes the default aria-hidden. Omit it (default) for decorative icons and the icon stays hidden from assistive tech (aria-hidden="true"). This is the accessible-name / alt-text prop for icons
|
|
40
|
+
description: 'Accessible name for a MEANINGFUL, standalone icon (a status glyph or icon-only indicator with no adjacent text). Setting it exposes the icon to screen readers as role="img" with this text as the accessible name (aria-label) and removes the default aria-hidden. Omit it (default) for decorative icons and the icon stays hidden from assistive tech (aria-hidden="true"). This is the accessible-name / alt-text prop for icons: one prop instead of manually setting aria-label + role + aria-hidden. An empty string is treated as decorative. Do not set it when an interactive parent (Button, IconButton, link) already names the control.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'xstyle',
|
|
44
|
+
type: 'StyleXStyles',
|
|
45
|
+
description:
|
|
46
|
+
'StyleX styles for customization (color, size, opacity). Folded into the icon\'s own stylex.props() call so it composes with the base color/size styles. Must be a stylex.create() value, not an inline style object like style={{}}.',
|
|
41
47
|
},
|
|
42
48
|
],
|
|
43
49
|
theming: {
|
|
@@ -50,7 +56,7 @@ export const docs = {
|
|
|
50
56
|
bestPractices: [
|
|
51
57
|
{ guidance: true, description: 'Use semantic icon names when available; they adapt to theme changes automatically.' },
|
|
52
58
|
{ guidance: true, description: 'Pair icons with text labels for accessibility; icon-only elements need an accessible label.' },
|
|
53
|
-
{ guidance: true, description: 'For a meaningful standalone icon (no adjacent text), give it an accessible name via the `label` prop
|
|
59
|
+
{ guidance: true, description: 'For a meaningful standalone icon (no adjacent text), give it an accessible name via the `label` prop: it sets role="img" + aria-label and unhides the icon.' },
|
|
54
60
|
{ guidance: true, description: 'Use color tokens for icon colors, not hardcoded hex values.' },
|
|
55
61
|
{ guidance: true, description: 'Be mindful of context; decorative icons in compact components can distract rather than help.' },
|
|
56
62
|
{ guidance: false, description: 'Use icons as the sole means of conveying meaning; always provide a text alternative.' },
|
|
@@ -90,6 +96,12 @@ export const docsZh = {
|
|
|
90
96
|
type: 'string',
|
|
91
97
|
description: '有含义的独立图标的可访问名称(无相邻文字的状态图标或纯图标指示器)。设置后会将图标以 role="img" 暴露给辅助技术,并以该文本作为可访问名称(aria-label),同时移除默认的 aria-hidden。省略(默认)用于装饰性图标,图标对辅助技术保持隐藏(aria-hidden="true")。空字符串按装饰性处理。当交互式父元素(Button、IconButton、链接)已命名该控件时请勿设置。',
|
|
92
98
|
},
|
|
99
|
+
{
|
|
100
|
+
name: 'xstyle',
|
|
101
|
+
type: 'StyleXStyles',
|
|
102
|
+
description:
|
|
103
|
+
'用于自定义的 StyleX 样式(颜色、尺寸、不透明度)。会并入图标自身的 stylex.props() 调用,从而与基础的颜色/尺寸样式组合。必须是 stylex.create() 的值,而不是像 style={{}} 这样的内联样式对象。',
|
|
104
|
+
},
|
|
93
105
|
],
|
|
94
106
|
theming: {
|
|
95
107
|
targets: [
|
|
@@ -121,6 +133,7 @@ export const docsDense = {
|
|
|
121
133
|
bestPractices: [
|
|
122
134
|
{ guidance: true, description: 'Use semantic icon names when available; they adapt to theme changes automatically.' },
|
|
123
135
|
{ guidance: true, description: 'Pair icons with text labels for accessibility; icon-only elements need an accessible label.' },
|
|
136
|
+
{ guidance: true, description: 'For a meaningful standalone icon (no adjacent text), set an accessible name via `label`: sets role="img" + aria-label, unhides icon.' },
|
|
124
137
|
{ guidance: true, description: 'Use color tokens for icon colors, not hardcoded hex values.' },
|
|
125
138
|
{ guidance: true, description: 'Be mindful of context; decorative icons in compact components can distract rather than help.' },
|
|
126
139
|
{ guidance: false, description: 'Use icons as the sole means of conveying meaning; always provide a text alternative.' },
|
|
@@ -135,5 +148,6 @@ export const docsDense = {
|
|
|
135
148
|
color: 'Color variant mapped to Astryx icon color tokens.',
|
|
136
149
|
size: 'Icon size.',
|
|
137
150
|
label: 'Accessible name for a meaningful, standalone icon. Sets role="img" + aria-label and drops the default aria-hidden. Omit (default) for decorative icons (stays aria-hidden). Empty string = decorative. The accessible-name/alt-text prop for icons.',
|
|
151
|
+
xstyle: 'StyleX styles (color, size, opacity) via stylex.create(); composes with the base color/size styles.',
|
|
138
152
|
},
|
|
139
153
|
};
|
package/src/Icon/Icon.test.tsx
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import {describe, it, expect, vi} from 'vitest';
|
|
13
13
|
import {render, screen} from '@testing-library/react';
|
|
14
|
+
import * as stylex from '@stylexjs/stylex';
|
|
14
15
|
import {TestIcon} from '../__tests__/TestIcon';
|
|
15
16
|
import {Icon} from './Icon';
|
|
16
17
|
|
|
@@ -279,4 +280,92 @@ describe('Icon', () => {
|
|
|
279
280
|
);
|
|
280
281
|
});
|
|
281
282
|
});
|
|
283
|
+
|
|
284
|
+
describe('styling prop handling', () => {
|
|
285
|
+
it('composes a consumer className with the internal classes (string mode)', () => {
|
|
286
|
+
render(
|
|
287
|
+
<Icon icon="check" className="consumer-target" data-testid="icon" />,
|
|
288
|
+
);
|
|
289
|
+
const icon = screen.getByTestId('icon');
|
|
290
|
+
// Consumer className must survive alongside the stable astryx-icon class
|
|
291
|
+
// and the StyleX classes — previously it was clobbered by the later
|
|
292
|
+
// internal spread.
|
|
293
|
+
expect(icon).toHaveClass('consumer-target');
|
|
294
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
295
|
+
// At least one StyleX-generated class is still present.
|
|
296
|
+
expect(icon.className.split(' ').length).toBeGreaterThan(2);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('forwards a consumer className in component (SVG) mode', () => {
|
|
300
|
+
render(
|
|
301
|
+
<Icon icon={TestIcon} className="consumer-target" data-testid="icon" />,
|
|
302
|
+
);
|
|
303
|
+
const icon = screen.getByTestId('icon');
|
|
304
|
+
expect(icon).toHaveClass('consumer-target');
|
|
305
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('merges a consumer style onto the rendered element (string mode)', () => {
|
|
309
|
+
render(<Icon icon="check" style={{opacity: 0.5}} data-testid="icon" />);
|
|
310
|
+
expect(screen.getByTestId('icon')).toHaveStyle({opacity: '0.5'});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('merges a consumer style onto the rendered element (component mode)', () => {
|
|
314
|
+
render(
|
|
315
|
+
<Icon icon={TestIcon} style={{opacity: 0.5}} data-testid="icon" />,
|
|
316
|
+
);
|
|
317
|
+
expect(screen.getByTestId('icon')).toHaveStyle({opacity: '0.5'});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('applies xstyle to the rendered element (string mode)', () => {
|
|
321
|
+
const overrides = stylex.create({root: {opacity: 0.25}});
|
|
322
|
+
render(<Icon icon="check" xstyle={overrides.root} data-testid="icon" />);
|
|
323
|
+
const icon = screen.getByTestId('icon');
|
|
324
|
+
// xstyle is folded into stylex.props, so it contributes a StyleX class
|
|
325
|
+
// (and, in jsdom's stylex runtime, an inline style) alongside the base
|
|
326
|
+
// color/size classes rather than clobbering them.
|
|
327
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
328
|
+
expect(icon).toHaveStyle({opacity: '0.25'});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('applies xstyle to the rendered element (component mode)', () => {
|
|
332
|
+
const overrides = stylex.create({root: {opacity: 0.25}});
|
|
333
|
+
render(
|
|
334
|
+
<Icon icon={TestIcon} xstyle={overrides.root} data-testid="icon" />,
|
|
335
|
+
);
|
|
336
|
+
const icon = screen.getByTestId('icon');
|
|
337
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
338
|
+
expect(icon).toHaveStyle({opacity: '0.25'});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('leaves default rendering unchanged when no styling props are passed (string mode)', () => {
|
|
342
|
+
const {container} = render(
|
|
343
|
+
<Icon icon="check" size="sm" color="secondary" />,
|
|
344
|
+
);
|
|
345
|
+
const icon = container.querySelector('.astryx-icon') as HTMLElement;
|
|
346
|
+
const {container: refContainer} = render(
|
|
347
|
+
<Icon icon="check" size="sm" color="secondary" />,
|
|
348
|
+
);
|
|
349
|
+
const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
|
|
350
|
+
// Default output is identical to itself — the styling-prop handling adds
|
|
351
|
+
// nothing (no extra class, no inline style) unless a prop is passed.
|
|
352
|
+
expect(icon.className).toBe(refIcon.className);
|
|
353
|
+
expect(icon.getAttribute('style')).toBe(refIcon.getAttribute('style'));
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('leaves default rendering unchanged when no styling props are passed (component mode)', () => {
|
|
357
|
+
const {container} = render(
|
|
358
|
+
<Icon icon={TestIcon} size="sm" color="secondary" />,
|
|
359
|
+
);
|
|
360
|
+
const icon = container.querySelector('.astryx-icon') as HTMLElement;
|
|
361
|
+
const {container: refContainer} = render(
|
|
362
|
+
<Icon icon={TestIcon} size="sm" color="secondary" />,
|
|
363
|
+
);
|
|
364
|
+
const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
|
|
365
|
+
// SVGElement.className is an SVGAnimatedString, so compare the class
|
|
366
|
+
// attribute string rather than the property object.
|
|
367
|
+
expect(icon.getAttribute('class')).toBe(refIcon.getAttribute('class'));
|
|
368
|
+
expect(icon.getAttribute('style')).toBe(refIcon.getAttribute('style'));
|
|
369
|
+
});
|
|
370
|
+
});
|
|
282
371
|
});
|
package/src/Icon/Icon.tsx
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import React, {type ComponentType, type SVGProps} from 'react';
|
|
26
26
|
import * as stylex from '@stylexjs/stylex';
|
|
27
|
+
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
27
28
|
import {colorVars} from '../theme/tokens.stylex';
|
|
28
29
|
import {getIcon} from './globalIconRegistry';
|
|
29
30
|
import type {IconName} from './globalIconRegistry';
|
|
@@ -229,16 +230,34 @@ export interface IconProps extends Omit<
|
|
|
229
230
|
* Don't set `label` when an interactive parent (Button, IconButton, link)
|
|
230
231
|
* already names the control — that produces a duplicate announcement.
|
|
231
232
|
*
|
|
233
|
+
* Meaningful, standalone icon: give it a label.
|
|
234
|
+
*
|
|
232
235
|
* @example
|
|
233
236
|
* ```
|
|
234
|
-
* // Meaningful, standalone icon
|
|
235
237
|
* <Icon icon="success" label="Completed" />
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* Decorative icon (the default): omit label.
|
|
236
241
|
*
|
|
237
|
-
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```
|
|
238
244
|
* <Icon icon="search" />
|
|
239
245
|
* ```
|
|
240
246
|
*/
|
|
241
247
|
label?: string;
|
|
248
|
+
/**
|
|
249
|
+
* StyleX styles created via `stylex.create()`. Folded into the icon's own
|
|
250
|
+
* `stylex.props()` call (as the last argument) so it merges with the base
|
|
251
|
+
* color/size styles for optimal deduplication, matching how other Astryx
|
|
252
|
+
* components accept `xstyle`.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```
|
|
256
|
+
* const overrides = stylex.create({ root: { opacity: 0.5 } });
|
|
257
|
+
* <Icon icon="search" xstyle={overrides.root} />
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
xstyle?: StyleXStyles;
|
|
242
261
|
}
|
|
243
262
|
|
|
244
263
|
/**
|
|
@@ -278,6 +297,9 @@ export function Icon({
|
|
|
278
297
|
size = 'md',
|
|
279
298
|
label,
|
|
280
299
|
ref,
|
|
300
|
+
className,
|
|
301
|
+
style,
|
|
302
|
+
xstyle,
|
|
281
303
|
...props
|
|
282
304
|
}: IconProps) {
|
|
283
305
|
// Derive ARIA from `label`: decorative (aria-hidden) by default, or a
|
|
@@ -292,6 +314,9 @@ export function Icon({
|
|
|
292
314
|
color={color}
|
|
293
315
|
size={size}
|
|
294
316
|
a11yProps={a11yProps}
|
|
317
|
+
className={className}
|
|
318
|
+
style={style}
|
|
319
|
+
xstyle={xstyle}
|
|
295
320
|
spanProps={props}
|
|
296
321
|
/>
|
|
297
322
|
);
|
|
@@ -306,9 +331,16 @@ export function Icon({
|
|
|
306
331
|
// BEFORE {...props} so an explicit aria-hidden/role/aria-label from the
|
|
307
332
|
// consumer still wins as an escape hatch.
|
|
308
333
|
{...a11yProps}
|
|
334
|
+
// The styling props (className, style, xstyle) are handled here so they
|
|
335
|
+
// COMPOSE with the internal classes/styles instead of clobbering them:
|
|
336
|
+
// xstyle folds into stylex.props, and className/style merge via
|
|
337
|
+
// mergeProps. The remaining rest props keep their prior last-spread
|
|
338
|
+
// precedence as escape hatches.
|
|
309
339
|
{...mergeProps(
|
|
310
340
|
themeProps('icon', {size, color}),
|
|
311
|
-
stylex.props(styles.root, colorStyles[color], sizeStyles[size]),
|
|
341
|
+
stylex.props(styles.root, colorStyles[color], sizeStyles[size], xstyle),
|
|
342
|
+
className ?? undefined,
|
|
343
|
+
style,
|
|
312
344
|
)}
|
|
313
345
|
{...props}
|
|
314
346
|
/>
|
|
@@ -333,12 +365,18 @@ function IconFromRegistry({
|
|
|
333
365
|
color,
|
|
334
366
|
size,
|
|
335
367
|
a11yProps,
|
|
368
|
+
className,
|
|
369
|
+
style,
|
|
370
|
+
xstyle,
|
|
336
371
|
spanProps,
|
|
337
372
|
}: {
|
|
338
373
|
name: IconName;
|
|
339
374
|
color: IconColor;
|
|
340
375
|
size: IconSize;
|
|
341
376
|
a11yProps: {role: 'img'; 'aria-label': string} | {'aria-hidden': 'true'};
|
|
377
|
+
className?: string;
|
|
378
|
+
style?: React.CSSProperties;
|
|
379
|
+
xstyle?: StyleXStyles;
|
|
342
380
|
spanProps?: Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'>;
|
|
343
381
|
}) {
|
|
344
382
|
const resolvedIcon = getIcon(name);
|
|
@@ -347,6 +385,14 @@ function IconFromRegistry({
|
|
|
347
385
|
return null;
|
|
348
386
|
}
|
|
349
387
|
|
|
388
|
+
// The styling props (className, style, xstyle) are handled here so they
|
|
389
|
+
// COMPOSE with the internal astryx-icon + StyleX classes/styles instead of
|
|
390
|
+
// being shadowed by the later spread: xstyle folds into stylex.props, and
|
|
391
|
+
// className/style merge via mergeProps. Other span props keep their prior
|
|
392
|
+
// precedence (spread before the internal merge).
|
|
393
|
+
const restSpanProps =
|
|
394
|
+
(spanProps as React.HTMLAttributes<HTMLSpanElement>) ?? {};
|
|
395
|
+
|
|
350
396
|
return (
|
|
351
397
|
<span
|
|
352
398
|
// Derived a11y — decorative (aria-hidden) by default, or a meaningful
|
|
@@ -354,10 +400,17 @@ function IconFromRegistry({
|
|
|
354
400
|
// prop spread so consumers can still override it with explicit
|
|
355
401
|
// aria-hidden/role/aria-label. This mirrors component-mode Icon.
|
|
356
402
|
{...a11yProps}
|
|
357
|
-
{...
|
|
403
|
+
{...restSpanProps}
|
|
358
404
|
{...mergeProps(
|
|
359
405
|
themeProps('icon', {size, color}),
|
|
360
|
-
stylex.props(
|
|
406
|
+
stylex.props(
|
|
407
|
+
styles.span,
|
|
408
|
+
colorStyles[color],
|
|
409
|
+
spanSizeStyles[size],
|
|
410
|
+
xstyle,
|
|
411
|
+
),
|
|
412
|
+
className ?? undefined,
|
|
413
|
+
style,
|
|
361
414
|
)}>
|
|
362
415
|
{resolvedIcon}
|
|
363
416
|
</span>
|
|
@@ -36,6 +36,13 @@ export const docs = {
|
|
|
36
36
|
description: 'Size variant.',
|
|
37
37
|
default: "\'md\'",
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
name: 'elevation',
|
|
41
|
+
type: "'none' | 'low' | 'med' | 'high'",
|
|
42
|
+
description:
|
|
43
|
+
'Resting shadow depth. The most common FAB shape is an icon-only button, so raise it with `low`/`med`/`high` for a floating action button. `none` is the default flat button.',
|
|
44
|
+
default: "'none'",
|
|
45
|
+
},
|
|
39
46
|
{
|
|
40
47
|
name: 'isLoading',
|
|
41
48
|
type: 'boolean',
|
|
@@ -95,6 +102,7 @@ export const docsDense = {
|
|
|
95
102
|
icon: 'icon element rendered inside button',
|
|
96
103
|
variant: 'visual style variant',
|
|
97
104
|
size: 'size variant',
|
|
105
|
+
elevation: 'resting shadow depth: none|low|med|high; raise for a floating action button (FAB)',
|
|
98
106
|
isLoading: 'shows loading spinner + disables interaction',
|
|
99
107
|
isDisabled: 'disables button',
|
|
100
108
|
tooltip: 'tooltip text shown on hover',
|
|
@@ -17,10 +17,7 @@ import {IconButton} from './IconButton';
|
|
|
17
17
|
describe('IconButton', () => {
|
|
18
18
|
it('renders as an icon-only button with aria-label', () => {
|
|
19
19
|
render(
|
|
20
|
-
<IconButton
|
|
21
|
-
label="Settings"
|
|
22
|
-
icon={<span data-testid="icon">⚙</span>}
|
|
23
|
-
/>,
|
|
20
|
+
<IconButton label="Settings" icon={<span data-testid="icon">⚙</span>} />,
|
|
24
21
|
);
|
|
25
22
|
const button = screen.getByRole('button', {name: 'Settings'});
|
|
26
23
|
expect(button).toHaveAttribute('aria-label', 'Settings');
|
|
@@ -29,10 +26,7 @@ describe('IconButton', () => {
|
|
|
29
26
|
|
|
30
27
|
it('does not render label as visible text', () => {
|
|
31
28
|
render(
|
|
32
|
-
<IconButton
|
|
33
|
-
label="Settings"
|
|
34
|
-
icon={<span data-testid="icon">⚙</span>}
|
|
35
|
-
/>,
|
|
29
|
+
<IconButton label="Settings" icon={<span data-testid="icon">⚙</span>} />,
|
|
36
30
|
);
|
|
37
31
|
const button = screen.getByRole('button');
|
|
38
32
|
// The label text should not appear as visible content
|
|
@@ -42,11 +36,7 @@ describe('IconButton', () => {
|
|
|
42
36
|
|
|
43
37
|
it('forwards variant prop', () => {
|
|
44
38
|
render(
|
|
45
|
-
<IconButton
|
|
46
|
-
label="Delete"
|
|
47
|
-
icon={<span>🗑</span>}
|
|
48
|
-
variant="destructive"
|
|
49
|
-
/>,
|
|
39
|
+
<IconButton label="Delete" icon={<span>🗑</span>} variant="destructive" />,
|
|
50
40
|
);
|
|
51
41
|
expect(screen.getByRole('button', {name: 'Delete'})).toBeInTheDocument();
|
|
52
42
|
});
|
|
@@ -60,11 +50,7 @@ describe('IconButton', () => {
|
|
|
60
50
|
const user = userEvent.setup();
|
|
61
51
|
const handleClick = vi.fn();
|
|
62
52
|
render(
|
|
63
|
-
<IconButton
|
|
64
|
-
label="Close"
|
|
65
|
-
icon={<span>✕</span>}
|
|
66
|
-
onClick={handleClick}
|
|
67
|
-
/>,
|
|
53
|
+
<IconButton label="Close" icon={<span>✕</span>} onClick={handleClick} />,
|
|
68
54
|
);
|
|
69
55
|
|
|
70
56
|
await user.click(screen.getByRole('button'));
|
|
@@ -105,4 +91,15 @@ describe('IconButton', () => {
|
|
|
105
91
|
it('has displayName set', () => {
|
|
106
92
|
expect(IconButton.displayName).toBe('IconButton');
|
|
107
93
|
});
|
|
94
|
+
|
|
95
|
+
it('forwards the elevation prop through to the underlying button', () => {
|
|
96
|
+
const classFor = (elevation: 'none' | 'med') => {
|
|
97
|
+
const {container} = render(
|
|
98
|
+
<IconButton label="Add" icon={<span>+</span>} elevation={elevation} />,
|
|
99
|
+
);
|
|
100
|
+
return container.querySelector('button')!.className;
|
|
101
|
+
};
|
|
102
|
+
// A raised FAB must render differently from the default flat icon button.
|
|
103
|
+
expect(classFor('med')).not.toBe(classFor('none'));
|
|
104
|
+
});
|
|
108
105
|
});
|
package/src/Item/Item.test.tsx
CHANGED
|
@@ -31,18 +31,13 @@ describe('Item', () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
it('renders marker', () => {
|
|
34
|
-
render(
|
|
35
|
-
<Item label="Item" marker={<span data-testid="marker">•</span>} />,
|
|
36
|
-
);
|
|
34
|
+
render(<Item label="Item" marker={<span data-testid="marker">•</span>} />);
|
|
37
35
|
expect(screen.getByTestId('marker')).toBeInTheDocument();
|
|
38
36
|
});
|
|
39
37
|
|
|
40
38
|
it('renders startContent', () => {
|
|
41
39
|
render(
|
|
42
|
-
<Item
|
|
43
|
-
label="Item"
|
|
44
|
-
startContent={<span data-testid="avatar">A</span>}
|
|
45
|
-
/>,
|
|
40
|
+
<Item label="Item" startContent={<span data-testid="avatar">A</span>} />,
|
|
46
41
|
);
|
|
47
42
|
expect(screen.getByTestId('avatar')).toBeInTheDocument();
|
|
48
43
|
});
|
|
@@ -255,12 +250,7 @@ describe('Item', () => {
|
|
|
255
250
|
it('does not fire onClick when disabled item is clicked', async () => {
|
|
256
251
|
const onClick = vi.fn();
|
|
257
252
|
render(
|
|
258
|
-
<Item
|
|
259
|
-
label="Disabled"
|
|
260
|
-
onClick={onClick}
|
|
261
|
-
isDisabled
|
|
262
|
-
data-testid="item"
|
|
263
|
-
/>,
|
|
253
|
+
<Item label="Disabled" onClick={onClick} isDisabled data-testid="item" />,
|
|
264
254
|
);
|
|
265
255
|
const item = screen.getByTestId('item');
|
|
266
256
|
item.dispatchEvent(new MouseEvent('click', {bubbles: true}));
|
|
@@ -276,14 +266,46 @@ describe('Item', () => {
|
|
|
276
266
|
// Selected state
|
|
277
267
|
// ===========================================================================
|
|
278
268
|
|
|
279
|
-
it('
|
|
269
|
+
it('conveys selection via aria-current on the default div root', () => {
|
|
270
|
+
// aria-selected is invalid ARIA on a generic div (axe: aria-allowed-attr),
|
|
271
|
+
// so selection is exposed via aria-current, which is valid on any element.
|
|
280
272
|
render(<Item label="Selected" isSelected data-testid="item" />);
|
|
281
|
-
|
|
273
|
+
const item = screen.getByTestId('item');
|
|
274
|
+
expect(item).not.toHaveAttribute('aria-selected');
|
|
275
|
+
expect(item).toHaveAttribute('aria-current', 'true');
|
|
282
276
|
});
|
|
283
277
|
|
|
284
|
-
it('
|
|
285
|
-
render(
|
|
286
|
-
|
|
278
|
+
it('applies aria-selected (not aria-current) when the role permits it', () => {
|
|
279
|
+
render(
|
|
280
|
+
<Item label="Selected" isSelected role="option" data-testid="item" />,
|
|
281
|
+
);
|
|
282
|
+
const item = screen.getByTestId('item');
|
|
283
|
+
expect(item).toHaveAttribute('aria-selected', 'true');
|
|
284
|
+
// A permitted role uses aria-selected; aria-current would be redundant.
|
|
285
|
+
expect(item).not.toHaveAttribute('aria-current');
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('falls back to aria-current when the role does not permit aria-selected', () => {
|
|
289
|
+
render(
|
|
290
|
+
<Item label="Selected" isSelected role="menuitem" data-testid="item" />,
|
|
291
|
+
);
|
|
292
|
+
const item = screen.getByTestId('item');
|
|
293
|
+
expect(item).not.toHaveAttribute('aria-selected');
|
|
294
|
+
expect(item).toHaveAttribute('aria-current', 'true');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('applies neither aria-selected nor aria-current when not selected', () => {
|
|
298
|
+
render(<Item label="Not Selected" role="option" data-testid="item" />);
|
|
299
|
+
const item = screen.getByTestId('item');
|
|
300
|
+
expect(item).not.toHaveAttribute('aria-selected');
|
|
301
|
+
expect(item).not.toHaveAttribute('aria-current');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('lets a consumer-provided aria-current win over the selection default', () => {
|
|
305
|
+
render(
|
|
306
|
+
<Item label="Step" isSelected aria-current="step" data-testid="item" />,
|
|
307
|
+
);
|
|
308
|
+
expect(screen.getByTestId('item')).toHaveAttribute('aria-current', 'step');
|
|
287
309
|
});
|
|
288
310
|
|
|
289
311
|
// ===========================================================================
|
package/src/Item/Item.tsx
CHANGED
|
@@ -131,7 +131,12 @@ export interface ItemProps extends BaseProps<HTMLElement> {
|
|
|
131
131
|
isHighlighted?: boolean;
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* Selected state.
|
|
134
|
+
* Selected state. Always applies the selected visual styling. When `role`
|
|
135
|
+
* permits it (option, tab, row, gridcell, columnheader, rowheader, treeitem)
|
|
136
|
+
* the state is exposed as `aria-selected`; otherwise (e.g. a listitem or a
|
|
137
|
+
* bare div, where `aria-selected` is invalid ARIA) it falls back to
|
|
138
|
+
* `aria-current="true"` so assistive tech is still told which item is
|
|
139
|
+
* selected. A consumer-provided `aria-current` always wins.
|
|
135
140
|
* @default false
|
|
136
141
|
*/
|
|
137
142
|
isSelected?: boolean;
|
|
@@ -148,6 +153,24 @@ export interface ItemProps extends BaseProps<HTMLElement> {
|
|
|
148
153
|
'data-testid'?: string;
|
|
149
154
|
}
|
|
150
155
|
|
|
156
|
+
// =============================================================================
|
|
157
|
+
// Constants
|
|
158
|
+
// =============================================================================
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Roles on which WAI-ARIA permits the aria-selected attribute.
|
|
162
|
+
* https://www.w3.org/TR/wai-aria-1.2/#aria-selected
|
|
163
|
+
*/
|
|
164
|
+
const ARIA_SELECTED_ROLES = new Set([
|
|
165
|
+
'option',
|
|
166
|
+
'tab',
|
|
167
|
+
'row',
|
|
168
|
+
'gridcell',
|
|
169
|
+
'columnheader',
|
|
170
|
+
'rowheader',
|
|
171
|
+
'treeitem',
|
|
172
|
+
]);
|
|
173
|
+
|
|
151
174
|
// =============================================================================
|
|
152
175
|
// Styles
|
|
153
176
|
// =============================================================================
|
|
@@ -346,6 +369,11 @@ export function Item({
|
|
|
346
369
|
// handles keyboard access. Skip the invisible button/anchor and put
|
|
347
370
|
// onClick directly on the root element instead.
|
|
348
371
|
const hasParentRole = role != null;
|
|
372
|
+
// aria-selected is only valid on selectable roles (option, tab, treeitem,
|
|
373
|
+
// grid cells). On the default div/li root the attribute is invalid ARIA
|
|
374
|
+
// (axe: aria-allowed-attr), so selection stays visual-only there — callers
|
|
375
|
+
// that need selection semantics pass a permitted role.
|
|
376
|
+
const allowsAriaSelected = role != null && ARIA_SELECTED_ROLES.has(role);
|
|
349
377
|
|
|
350
378
|
const isStringLabel = typeof label === 'string';
|
|
351
379
|
const isStringDescription = typeof description === 'string';
|
|
@@ -471,7 +499,15 @@ export function Item({
|
|
|
471
499
|
<Component
|
|
472
500
|
ref={ref as React.Ref<never>}
|
|
473
501
|
{...restProps}
|
|
474
|
-
aria-selected={isSelected || undefined}
|
|
502
|
+
aria-selected={(allowsAriaSelected && isSelected) || undefined}
|
|
503
|
+
// aria-selected is invalid on roles that don't permit it (listitem, a
|
|
504
|
+
// bare div, etc.). For those, convey selection via aria-current — valid
|
|
505
|
+
// on any element — so the state still reaches AT. Written after
|
|
506
|
+
// {...restProps} so it must defer to a consumer-provided aria-current.
|
|
507
|
+
aria-current={
|
|
508
|
+
restProps['aria-current'] ??
|
|
509
|
+
(isSelected && !allowsAriaSelected ? true : undefined)
|
|
510
|
+
}
|
|
475
511
|
aria-disabled={isDisabled || undefined}
|
|
476
512
|
{...mergeProps(
|
|
477
513
|
themeProps('item', {density, align}),
|