@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
|
@@ -45,6 +45,23 @@ afterEach(() => {
|
|
|
45
45
|
vi.unstubAllGlobals();
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
+
// The global test setup polyfills matchMedia with a never-matching stub;
|
|
49
|
+
// this override makes only the reduced-motion query match, mirroring the
|
|
50
|
+
// pattern in useStreamingText.test.ts. Undone by afterEach's
|
|
51
|
+
// unstubAllGlobals.
|
|
52
|
+
function stubReducedMotion() {
|
|
53
|
+
vi.stubGlobal('matchMedia', (query: string) => ({
|
|
54
|
+
matches: query.includes('prefers-reduced-motion'),
|
|
55
|
+
media: query,
|
|
56
|
+
onchange: null,
|
|
57
|
+
addListener: () => {},
|
|
58
|
+
removeListener: () => {},
|
|
59
|
+
addEventListener: () => {},
|
|
60
|
+
removeEventListener: () => {},
|
|
61
|
+
dispatchEvent: () => false,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
function setGeometry(
|
|
49
66
|
el: HTMLElement,
|
|
50
67
|
{scrollHeight, clientHeight}: {scrollHeight: number; clientHeight: number},
|
|
@@ -166,3 +183,35 @@ describe("useChatStreamScroll — scrollToBottom({behavior: 'instant'})", () =>
|
|
|
166
183
|
expect(rafQueue.length).toBeGreaterThan(0);
|
|
167
184
|
});
|
|
168
185
|
});
|
|
186
|
+
|
|
187
|
+
describe('useChatStreamScroll — prefers-reduced-motion', () => {
|
|
188
|
+
it('streaming growth jumps synchronously instead of springing', () => {
|
|
189
|
+
stubReducedMotion();
|
|
190
|
+
const {api, el} = renderHook();
|
|
191
|
+
setGeometry(el, {scrollHeight: 1000, clientHeight: 400});
|
|
192
|
+
flushRaf(); // consume the mount jump
|
|
193
|
+
expect(el.scrollTop).toBe(600);
|
|
194
|
+
|
|
195
|
+
// Post-first-fill growth would normally take the spring path; under
|
|
196
|
+
// reduced motion it must land in the same synchronous step.
|
|
197
|
+
setGeometry(el, {scrollHeight: 1400, clientHeight: 400});
|
|
198
|
+
rafQueue = [];
|
|
199
|
+
act(() => api.current!.scrollIfLocked());
|
|
200
|
+
expect(el.scrollTop).toBe(1000);
|
|
201
|
+
expect(rafQueue).toHaveLength(0);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('default scrollToBottom falls back to an instant jump', () => {
|
|
205
|
+
stubReducedMotion();
|
|
206
|
+
const {api, el} = renderHook();
|
|
207
|
+
setGeometry(el, {scrollHeight: 1000, clientHeight: 400});
|
|
208
|
+
flushRaf();
|
|
209
|
+
el.scrollTop = 100; // user scrolled up
|
|
210
|
+
|
|
211
|
+
rafQueue = [];
|
|
212
|
+
act(() => api.current!.scrollToBottom());
|
|
213
|
+
expect(el.scrollTop).toBe(600);
|
|
214
|
+
expect(rafQueue).toHaveLength(0);
|
|
215
|
+
expect(api.current!.isLocked).toBe(true);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useChatStreamScroll.ts
|
|
7
|
-
* @input Uses React refs, state, callbacks
|
|
7
|
+
* @input Uses React refs, state, callbacks, useMediaQuery
|
|
8
8
|
* @output Exports useChatStreamScroll hook for AI chat scroll behavior
|
|
9
9
|
* @position Utility hook — used by ChatLayout, also usable standalone
|
|
10
10
|
*
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* - The first fill positions instantly (whether content is present at
|
|
16
16
|
* mount or arrives async); only subsequent growth springs
|
|
17
17
|
* - `scrollToBottom({behavior: 'instant'})` jumps in one frame, no animation
|
|
18
|
+
* - Under `prefers-reduced-motion`, every spring path falls back to the
|
|
19
|
+
* same instant jump — following still works, it just doesn't animate
|
|
18
20
|
*
|
|
19
21
|
* Uses scroll direction (lastScrollTop comparison) to detect user
|
|
20
22
|
* intent — works for wheel, touch, scrollbar drag, keyboard, everything.
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
*/
|
|
27
29
|
|
|
28
30
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
|
31
|
+
import {useMediaQuery} from '../hooks/useMediaQuery';
|
|
29
32
|
|
|
30
33
|
// =============================================================================
|
|
31
34
|
// Types
|
|
@@ -37,7 +40,8 @@ export interface ChatScrollToBottomOptions {
|
|
|
37
40
|
* the spring animation. Use for programmatic positioning (opening a
|
|
38
41
|
* conversation, restoring a session) — keep the default `'spring'` for
|
|
39
42
|
* user-initiated scrolls like the scroll-to-bottom button. Mirrors the
|
|
40
|
-
* DOM's `scrollTo({behavior})`.
|
|
43
|
+
* DOM's `scrollTo({behavior})`. When the user prefers reduced motion,
|
|
44
|
+
* `'spring'` also jumps instantly.
|
|
41
45
|
* @default 'spring'
|
|
42
46
|
*/
|
|
43
47
|
behavior?: 'instant' | 'spring';
|
|
@@ -189,14 +193,6 @@ export function useChatStreamScroll({
|
|
|
189
193
|
requestAnimationFrame(animate);
|
|
190
194
|
}, [scrollRef, damping, stiffness, mass]);
|
|
191
195
|
|
|
192
|
-
const startAnimation = useCallback(() => {
|
|
193
|
-
if (!animatingRef.current && lockedRef.current) {
|
|
194
|
-
animatingRef.current = true;
|
|
195
|
-
lastTickRef.current = undefined;
|
|
196
|
-
requestAnimationFrame(animate);
|
|
197
|
-
}
|
|
198
|
-
}, [animate]);
|
|
199
|
-
|
|
200
196
|
// Jump to the bottom in a single frame — cancels any in-flight spring so
|
|
201
197
|
// a later animation tick can't fight the assignment.
|
|
202
198
|
const jumpToBottom = useCallback(() => {
|
|
@@ -211,6 +207,27 @@ export function useChatStreamScroll({
|
|
|
211
207
|
lastScrollTopRef.current = el.scrollTop;
|
|
212
208
|
}, [scrollRef]);
|
|
213
209
|
|
|
210
|
+
const prefersReducedMotion = useMediaQuery(
|
|
211
|
+
'(prefers-reduced-motion: reduce)',
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
// Every spring entry point (scrollToBottom, lock, scrollIfLocked growth
|
|
215
|
+
// follow) funnels through here, so this one branch covers them all.
|
|
216
|
+
const startAnimation = useCallback(() => {
|
|
217
|
+
if (!lockedRef.current) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (prefersReducedMotion) {
|
|
221
|
+
jumpToBottom();
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (!animatingRef.current) {
|
|
225
|
+
animatingRef.current = true;
|
|
226
|
+
lastTickRef.current = undefined;
|
|
227
|
+
requestAnimationFrame(animate);
|
|
228
|
+
}
|
|
229
|
+
}, [animate, jumpToBottom, prefersReducedMotion]);
|
|
230
|
+
|
|
214
231
|
// --- Public API ---
|
|
215
232
|
|
|
216
233
|
const scrollToBottom = useCallback(
|
|
@@ -242,7 +242,7 @@ async function createVolumeAnalyser(
|
|
|
242
242
|
|
|
243
243
|
let _sharedAudioCtx: AudioContext | null = null;
|
|
244
244
|
|
|
245
|
-
|
|
245
|
+
function getDefaultAudioContext(): AudioContext {
|
|
246
246
|
if (!_sharedAudioCtx || _sharedAudioCtx.state === 'closed') {
|
|
247
247
|
_sharedAudioCtx = new AudioContext();
|
|
248
248
|
}
|
|
@@ -125,7 +125,7 @@ const styles = stylex.create({
|
|
|
125
125
|
outline: 'none',
|
|
126
126
|
backgroundColor: 'transparent',
|
|
127
127
|
border: 'none',
|
|
128
|
-
textAlign: '
|
|
128
|
+
textAlign: 'start' as const,
|
|
129
129
|
fontFamily: typographyVars['--font-family-body'],
|
|
130
130
|
fontSize: typeScaleVars['--text-body-size'],
|
|
131
131
|
lineHeight: typeScaleVars['--text-body-leading'],
|
|
@@ -699,7 +699,9 @@ export function useTriggerMenu(
|
|
|
699
699
|
<div
|
|
700
700
|
id={listboxId}
|
|
701
701
|
role="listbox"
|
|
702
|
-
aria-label={
|
|
702
|
+
aria-label={
|
|
703
|
+
trigger?.menuLabel ?? t('@astryx.chatTriggerMenu.suggestions')
|
|
704
|
+
}
|
|
703
705
|
{...mergeProps(
|
|
704
706
|
themeProps('trigger-menu'),
|
|
705
707
|
stylex.props(styles.dropdown),
|
|
@@ -121,6 +121,12 @@ export const docs = {
|
|
|
121
121
|
description:
|
|
122
122
|
'Status indicator. Displays a colored message box below the checkbox and sets aria-invalid for errors.',
|
|
123
123
|
},
|
|
124
|
+
{
|
|
125
|
+
name: 'width',
|
|
126
|
+
type: 'SizeValue',
|
|
127
|
+
description:
|
|
128
|
+
'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
|
|
129
|
+
},
|
|
124
130
|
],
|
|
125
131
|
theming: {
|
|
126
132
|
targets: [
|
|
@@ -9,10 +9,15 @@
|
|
|
9
9
|
* SYNC: When CheckboxInput.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
12
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
13
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {CheckboxInput} from './CheckboxInput';
|
|
16
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
__resetLiveRegionsForTest();
|
|
20
|
+
});
|
|
16
21
|
|
|
17
22
|
// Mock showPopover/hidePopover (not implemented in jsdom) so the tooltip layer
|
|
18
23
|
// reflects its open state via a `popover-open` attribute the tests can assert.
|
|
@@ -333,6 +338,32 @@ describe('CheckboxInput', () => {
|
|
|
333
338
|
);
|
|
334
339
|
});
|
|
335
340
|
|
|
341
|
+
// Regression: the status is conditionally mounted, so it must be announced
|
|
342
|
+
// through the persistent useAnnounce live region — a live region born
|
|
343
|
+
// together with its content is not reliably announced.
|
|
344
|
+
it('announces a status message that appears after mount', async () => {
|
|
345
|
+
const {rerender} = render(
|
|
346
|
+
<CheckboxInput label="Accept terms" value={false} onChange={() => {}} />,
|
|
347
|
+
);
|
|
348
|
+
expect(
|
|
349
|
+
document.querySelector('[data-astryx-live-region="assertive"]'),
|
|
350
|
+
).toBeNull();
|
|
351
|
+
|
|
352
|
+
rerender(
|
|
353
|
+
<CheckboxInput
|
|
354
|
+
label="Accept terms"
|
|
355
|
+
value={false}
|
|
356
|
+
onChange={() => {}}
|
|
357
|
+
status={{type: 'error', message: 'Required field'}}
|
|
358
|
+
/>,
|
|
359
|
+
);
|
|
360
|
+
await waitFor(() => {
|
|
361
|
+
expect(
|
|
362
|
+
document.querySelector('[data-astryx-live-region="assertive"]'),
|
|
363
|
+
).toHaveTextContent('Required field');
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
336
367
|
describe('disabledMessage', () => {
|
|
337
368
|
const h = {hidden: true} as const;
|
|
338
369
|
|
|
@@ -166,7 +166,7 @@ const styles = stylex.create({
|
|
|
166
166
|
indeterminateMark: {
|
|
167
167
|
display: 'none',
|
|
168
168
|
backgroundColor: colorVars['--color-on-accent'],
|
|
169
|
-
borderRadius:
|
|
169
|
+
borderRadius: radiusVars['--radius-full'],
|
|
170
170
|
},
|
|
171
171
|
indeterminateMarkVisible: {
|
|
172
172
|
display: 'block',
|
|
@@ -198,12 +198,12 @@ const wrapperSizeStyles = stylex.create({
|
|
|
198
198
|
|
|
199
199
|
const checkboxSizeStyles = stylex.create({
|
|
200
200
|
sm: {
|
|
201
|
-
width:
|
|
202
|
-
height:
|
|
201
|
+
width: 20,
|
|
202
|
+
height: 20,
|
|
203
203
|
},
|
|
204
204
|
md: {
|
|
205
|
-
width:
|
|
206
|
-
height:
|
|
205
|
+
width: 24,
|
|
206
|
+
height: 24,
|
|
207
207
|
},
|
|
208
208
|
});
|
|
209
209
|
|
|
@@ -88,6 +88,12 @@ export const docs = {
|
|
|
88
88
|
type: "{type: 'warning' | 'error' | 'success', message?: string}",
|
|
89
89
|
description: 'Status indicator ({ type, message }).',
|
|
90
90
|
},
|
|
91
|
+
{
|
|
92
|
+
name: 'width',
|
|
93
|
+
type: 'SizeValue',
|
|
94
|
+
description:
|
|
95
|
+
'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
|
|
96
|
+
},
|
|
91
97
|
{
|
|
92
98
|
name: 'xstyle',
|
|
93
99
|
type: 'StyleXStyles',
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* SYNC: When CheckboxList.tsx or CheckboxListItem.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
12
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
13
|
import {
|
|
14
14
|
render,
|
|
15
15
|
screen,
|
|
@@ -20,8 +20,16 @@ import {
|
|
|
20
20
|
import userEvent from '@testing-library/user-event';
|
|
21
21
|
import {CheckboxList} from './CheckboxList';
|
|
22
22
|
import {CheckboxListItem} from './CheckboxListItem';
|
|
23
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
23
24
|
import {List} from '../List/List';
|
|
24
25
|
|
|
26
|
+
// FieldStatus announces status messages through the persistent useAnnounce
|
|
27
|
+
// singletons; remove them between tests so role/aria-live queries in this
|
|
28
|
+
// file never match a leftover region.
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
__resetLiveRegionsForTest();
|
|
31
|
+
});
|
|
32
|
+
|
|
25
33
|
// Mock showPopover/hidePopover (not implemented in jsdom) so the tooltip layer
|
|
26
34
|
// reflects its open state via a `popover-open` attribute the tests can assert.
|
|
27
35
|
beforeEach(() => {
|
|
@@ -437,6 +445,71 @@ describe('CheckboxListItem standalone mode', () => {
|
|
|
437
445
|
});
|
|
438
446
|
});
|
|
439
447
|
|
|
448
|
+
describe('CheckboxListItem accessible name', () => {
|
|
449
|
+
it('names the checkbox from a string label', () => {
|
|
450
|
+
render(
|
|
451
|
+
<CheckboxList label="Preferences" value={[]} onChange={() => {}}>
|
|
452
|
+
<CheckboxListItem label="Option A" value="a" />
|
|
453
|
+
</CheckboxList>,
|
|
454
|
+
);
|
|
455
|
+
expect(
|
|
456
|
+
screen.getByRole('checkbox', {name: 'Option A'}),
|
|
457
|
+
).toBeInTheDocument();
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('names the checkbox from aria-label when the label is a ReactNode', () => {
|
|
461
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
462
|
+
render(
|
|
463
|
+
<CheckboxList label="Plans" value={[]} onChange={() => {}}>
|
|
464
|
+
<CheckboxListItem
|
|
465
|
+
label={
|
|
466
|
+
<span>
|
|
467
|
+
Pro plan <em>(recommended)</em>
|
|
468
|
+
</span>
|
|
469
|
+
}
|
|
470
|
+
aria-label="Pro plan"
|
|
471
|
+
value="pro"
|
|
472
|
+
/>
|
|
473
|
+
</CheckboxList>,
|
|
474
|
+
);
|
|
475
|
+
expect(
|
|
476
|
+
screen.getByRole('checkbox', {name: 'Pro plan'}),
|
|
477
|
+
).toBeInTheDocument();
|
|
478
|
+
// A named checkbox needs no dev guidance.
|
|
479
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
480
|
+
warnSpy.mockRestore();
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it('warns once when a ReactNode label has no aria-label', () => {
|
|
484
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
485
|
+
const richLabel = (
|
|
486
|
+
<span>
|
|
487
|
+
Pro plan <em>(recommended)</em>
|
|
488
|
+
</span>
|
|
489
|
+
);
|
|
490
|
+
const {rerender} = render(
|
|
491
|
+
<CheckboxList label="Plans" value={[]} onChange={() => {}}>
|
|
492
|
+
<CheckboxListItem label={richLabel} value="pro" />
|
|
493
|
+
</CheckboxList>,
|
|
494
|
+
);
|
|
495
|
+
// Falls back to the generic name, and tells the developer how to fix it.
|
|
496
|
+
expect(
|
|
497
|
+
screen.getByRole('checkbox', {name: 'Checkbox'}),
|
|
498
|
+
).toBeInTheDocument();
|
|
499
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
500
|
+
expect(String(warnSpy.mock.calls[0]?.[0])).toContain('aria-label');
|
|
501
|
+
|
|
502
|
+
// Warn once per item instance — re-renders don't repeat it.
|
|
503
|
+
rerender(
|
|
504
|
+
<CheckboxList label="Plans" value={['pro']} onChange={() => {}}>
|
|
505
|
+
<CheckboxListItem label={richLabel} value="pro" />
|
|
506
|
+
</CheckboxList>,
|
|
507
|
+
);
|
|
508
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
509
|
+
warnSpy.mockRestore();
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
|
|
440
513
|
describe('CheckboxListItem ARIA props', () => {
|
|
441
514
|
it('conveys checked state via the inner checkbox, not aria-checked on the listitem', () => {
|
|
442
515
|
render(
|
|
@@ -567,7 +640,7 @@ describe('CheckboxListItem ARIA props', () => {
|
|
|
567
640
|
expect(changeAction).toHaveBeenCalledWith(['a']);
|
|
568
641
|
});
|
|
569
642
|
|
|
570
|
-
it('forwards arbitrary aria attributes to the list item
|
|
643
|
+
it('forwards arbitrary aria attributes to the list item, but aria-label names the checkbox', () => {
|
|
571
644
|
render(
|
|
572
645
|
<List>
|
|
573
646
|
<CheckboxListItem
|
|
@@ -578,8 +651,13 @@ describe('CheckboxListItem ARIA props', () => {
|
|
|
578
651
|
</List>,
|
|
579
652
|
);
|
|
580
653
|
const item = screen.getByRole('listitem');
|
|
654
|
+
// Arbitrary aria-* still forward to the row...
|
|
581
655
|
expect(item).toHaveAttribute('aria-describedby', 'help-text');
|
|
582
|
-
|
|
656
|
+
// ...but aria-label names the checkbox control, not the row.
|
|
657
|
+
expect(item).not.toHaveAttribute('aria-label');
|
|
658
|
+
expect(
|
|
659
|
+
screen.getByRole('checkbox', {name: 'custom label'}),
|
|
660
|
+
).toBeInTheDocument();
|
|
583
661
|
});
|
|
584
662
|
|
|
585
663
|
describe('disabledMessage', () => {
|
|
@@ -7,14 +7,22 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'CheckboxList',
|
|
8
8
|
displayName: 'Checkbox List Item',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Individual checkbox item with label, description, and end content slot. Works in collection mode (inside CheckboxList) or standalone mode (inside List).',
|
|
11
12
|
props: [
|
|
12
13
|
{
|
|
13
14
|
name: 'label',
|
|
14
|
-
type: '
|
|
15
|
-
description:
|
|
15
|
+
type: 'ReactNode',
|
|
16
|
+
description:
|
|
17
|
+
'Primary text label for the item. A plain string names the checkbox automatically; a rich (ReactNode) label should be paired with aria-label so screen readers get a concise name.',
|
|
16
18
|
required: true,
|
|
17
19
|
},
|
|
20
|
+
{
|
|
21
|
+
name: 'aria-label',
|
|
22
|
+
type: 'string',
|
|
23
|
+
description:
|
|
24
|
+
'Plain-text accessible name for the checkbox when label is a ReactNode. Applied to the checkbox control. Without it, rich-label items all announce as the generic "Checkbox" to screen readers.',
|
|
25
|
+
},
|
|
18
26
|
{
|
|
19
27
|
name: 'value',
|
|
20
28
|
type: 'string',
|
|
@@ -69,13 +77,24 @@ export const docs = {
|
|
|
69
77
|
description: 'Direct check handler (standalone mode only).',
|
|
70
78
|
},
|
|
71
79
|
],
|
|
80
|
+
examples: [
|
|
81
|
+
{
|
|
82
|
+
label: 'Rich label with an accessible name',
|
|
83
|
+
code: `<CheckboxListItem
|
|
84
|
+
label={<span>Pro plan <Badge label="Recommended" /></span>}
|
|
85
|
+
aria-label="Pro plan"
|
|
86
|
+
value="pro"
|
|
87
|
+
/>`,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
72
90
|
};
|
|
73
91
|
|
|
74
92
|
export const docsZh = {
|
|
75
93
|
name: 'CheckboxListItem',
|
|
76
94
|
isHiddenFromOverview: true,
|
|
77
95
|
displayName: 'Checkbox List Item',
|
|
78
|
-
description:
|
|
96
|
+
description:
|
|
97
|
+
'单个复选框选项,包含标签、描述和尾部内容插槽。可在集合模式或独立模式下使用。',
|
|
79
98
|
props: [
|
|
80
99
|
{
|
|
81
100
|
name: 'label',
|
|
@@ -83,6 +102,12 @@ export const docsZh = {
|
|
|
83
102
|
description: '选项的主要文本标签。',
|
|
84
103
|
required: true,
|
|
85
104
|
},
|
|
105
|
+
{
|
|
106
|
+
name: 'aria-label',
|
|
107
|
+
type: 'string',
|
|
108
|
+
description:
|
|
109
|
+
'当 label 是 ReactNode 时,复选框的纯文本无障碍名称。缺少它时,富标签选项都会向屏幕阅读器播报为通用的 "Checkbox"。',
|
|
110
|
+
},
|
|
86
111
|
{
|
|
87
112
|
name: 'value',
|
|
88
113
|
type: 'string',
|
|
@@ -128,9 +153,12 @@ export const docsDense = {
|
|
|
128
153
|
name: 'CheckboxListItem',
|
|
129
154
|
isHiddenFromOverview: true,
|
|
130
155
|
displayName: 'Checkbox List Item',
|
|
131
|
-
description:
|
|
156
|
+
description:
|
|
157
|
+
'Individual checkbox item w/ label, description, end content slot.',
|
|
132
158
|
propDescriptions: {
|
|
133
159
|
label: 'Primary text label for item.',
|
|
160
|
+
'aria-label':
|
|
161
|
+
'Plain-text checkbox name when label is a ReactNode. Without it, rich-label items all announce as "Checkbox".',
|
|
134
162
|
value: 'Identity key (required inside CheckboxList).',
|
|
135
163
|
description: 'Secondary text below label.',
|
|
136
164
|
endContent: 'Content rendered after label area.',
|
|
@@ -22,6 +22,7 @@ import type {StyleXStyles} from '@stylexjs/stylex';
|
|
|
22
22
|
import {colorVars} from '../theme/tokens.stylex';
|
|
23
23
|
import type {BaseProps} from '../BaseProps';
|
|
24
24
|
import {composeEventHandlers} from '../utils';
|
|
25
|
+
import {useDevWarning} from '../hooks/useDevWarning';
|
|
25
26
|
import {CheckboxInput} from '../CheckboxInput/CheckboxInput';
|
|
26
27
|
import {ListItem} from '../List/ListItem';
|
|
27
28
|
import {ListContext} from '../List/ListContext';
|
|
@@ -51,6 +52,25 @@ export interface CheckboxListItemProps extends BaseProps<HTMLLIElement> {
|
|
|
51
52
|
* child components control their own text behavior).
|
|
52
53
|
*/
|
|
53
54
|
label: ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* Plain-text accessible name for the checkbox when `label` is a ReactNode.
|
|
57
|
+
*
|
|
58
|
+
* A string `label` names the checkbox automatically. A rich (ReactNode)
|
|
59
|
+
* `label` cannot, so pass a concise string equivalent via the standard
|
|
60
|
+
* `aria-label` — otherwise the checkbox falls back to the generic name
|
|
61
|
+
* "Checkbox" and every rich-label item in a list announces identically to
|
|
62
|
+
* screen readers. Applied to the checkbox control, not the row.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```
|
|
66
|
+
* <CheckboxListItem
|
|
67
|
+
* label={<span>Pro plan <Badge label="Recommended" /></span>}
|
|
68
|
+
* aria-label="Pro plan"
|
|
69
|
+
* value="pro"
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
'aria-label'?: string;
|
|
54
74
|
/**
|
|
55
75
|
* Identity key for collection mode (REQUIRED inside CheckboxList).
|
|
56
76
|
* Throws a runtime error if missing when used inside CheckboxList.
|
|
@@ -119,6 +139,7 @@ export interface CheckboxListItemProps extends BaseProps<HTMLLIElement> {
|
|
|
119
139
|
*/
|
|
120
140
|
export function CheckboxListItem({
|
|
121
141
|
label,
|
|
142
|
+
'aria-label': ariaLabel,
|
|
122
143
|
value,
|
|
123
144
|
description,
|
|
124
145
|
endContent,
|
|
@@ -142,6 +163,25 @@ export function CheckboxListItem({
|
|
|
142
163
|
);
|
|
143
164
|
}
|
|
144
165
|
|
|
166
|
+
// Accessible name for the (visually hidden) checkbox label. A string
|
|
167
|
+
// `label` names it directly; a rich label needs `aria-label`.
|
|
168
|
+
const checkboxLabel =
|
|
169
|
+
ariaLabel ??
|
|
170
|
+
(typeof label === 'string'
|
|
171
|
+
? label
|
|
172
|
+
: t('@astryx.checkboxList.item.checkbox'));
|
|
173
|
+
|
|
174
|
+
// Dev-time guardrail: a rich label without `aria-label` leaves the
|
|
175
|
+
// checkbox with the generic name "Checkbox".
|
|
176
|
+
useDevWarning(
|
|
177
|
+
'CheckboxListItem',
|
|
178
|
+
'`label` is a ReactNode, so the checkbox falls ' +
|
|
179
|
+
'back to the generic accessible name "Checkbox". Pass ' +
|
|
180
|
+
'`aria-label` with a concise string equivalent of the visible ' +
|
|
181
|
+
'label so screen readers can tell items apart.',
|
|
182
|
+
typeof label !== 'string' && ariaLabel == null,
|
|
183
|
+
);
|
|
184
|
+
|
|
145
185
|
// Density from list context for checkbox sizing
|
|
146
186
|
const listCtx = use(ListContext);
|
|
147
187
|
const density = listCtx?.density ?? 'balanced';
|
|
@@ -226,11 +266,7 @@ export function CheckboxListItem({
|
|
|
226
266
|
style={style}
|
|
227
267
|
startContent={
|
|
228
268
|
<CheckboxInput
|
|
229
|
-
label={
|
|
230
|
-
typeof label === 'string'
|
|
231
|
-
? label
|
|
232
|
-
: t('@astryx.checkboxList.item.checkbox')
|
|
233
|
-
}
|
|
269
|
+
label={checkboxLabel}
|
|
234
270
|
isLabelHidden
|
|
235
271
|
value={resolvedChecked}
|
|
236
272
|
onChange={() => handleToggle()}
|
|
@@ -39,7 +39,7 @@ export const docs = {
|
|
|
39
39
|
name: 'Icon',
|
|
40
40
|
required: false,
|
|
41
41
|
description:
|
|
42
|
-
'An optional
|
|
42
|
+
'An optional source icon shown before the label text. Accepts a favicon/logo image URL (via source.src) or a React node such as an Astryx <Icon>. Only available in the label variant.',
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
name: 'Label text',
|
|
@@ -71,7 +71,7 @@ export const docs = {
|
|
|
71
71
|
name: 'source',
|
|
72
72
|
type: 'CitationSource',
|
|
73
73
|
description:
|
|
74
|
-
'The citation source object containing title, url, and optional icon.',
|
|
74
|
+
'The citation source object containing title, url, an optional image src, and an optional icon node.',
|
|
75
75
|
required: true,
|
|
76
76
|
},
|
|
77
77
|
{
|
|
@@ -121,7 +121,8 @@ export const docsDense = {
|
|
|
121
121
|
],
|
|
122
122
|
},
|
|
123
123
|
propDescriptions: {
|
|
124
|
-
source:
|
|
124
|
+
source:
|
|
125
|
+
'citation source object with title, url, optional image src, and optional icon node.',
|
|
125
126
|
number: 'display index for this citation.',
|
|
126
127
|
variant: 'display style: label chip with source title or compact numbered badge.',
|
|
127
128
|
},
|
|
@@ -169,4 +169,101 @@ describe('Citation', () => {
|
|
|
169
169
|
expect(el.classList.contains(cls)).toBe(true);
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
|
+
|
|
173
|
+
// --- Source icon: image URL (back-compat) vs ReactNode ---------------------
|
|
174
|
+
|
|
175
|
+
it('renders a legacy string icon as a decorative image (back-compat)', () => {
|
|
176
|
+
// Existing callers pass a favicon URL to `source.icon`. A bare string must
|
|
177
|
+
// still render as <img src>, unchanged from the original behavior.
|
|
178
|
+
const {container} = render(
|
|
179
|
+
<Citation
|
|
180
|
+
source={{
|
|
181
|
+
title: 'GitHub',
|
|
182
|
+
url: 'https://github.com',
|
|
183
|
+
icon: 'https://example.com/favicon.png',
|
|
184
|
+
}}
|
|
185
|
+
number={1}
|
|
186
|
+
data-testid="citation"
|
|
187
|
+
/>,
|
|
188
|
+
);
|
|
189
|
+
const img = container.querySelector('img');
|
|
190
|
+
expect(img).not.toBeNull();
|
|
191
|
+
expect(img).toHaveAttribute('src', 'https://example.com/favicon.png');
|
|
192
|
+
// Decorative: empty alt, and the wrapper is aria-hidden.
|
|
193
|
+
expect(img).toHaveAttribute('alt', '');
|
|
194
|
+
expect(container.querySelector('[aria-hidden="true"] img')).toBe(img);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('renders source.src as a decorative image', () => {
|
|
198
|
+
const {container} = render(
|
|
199
|
+
<Citation
|
|
200
|
+
source={{
|
|
201
|
+
title: 'GitHub',
|
|
202
|
+
url: 'https://github.com',
|
|
203
|
+
src: 'https://example.com/logo.png',
|
|
204
|
+
}}
|
|
205
|
+
number={1}
|
|
206
|
+
data-testid="citation"
|
|
207
|
+
/>,
|
|
208
|
+
);
|
|
209
|
+
const img = container.querySelector('img');
|
|
210
|
+
expect(img).toHaveAttribute('src', 'https://example.com/logo.png');
|
|
211
|
+
expect(img).toHaveAttribute('alt', '');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('renders a ReactNode icon as-is (not an <img>)', () => {
|
|
215
|
+
const {container} = render(
|
|
216
|
+
<Citation
|
|
217
|
+
source={{
|
|
218
|
+
title: 'GitHub',
|
|
219
|
+
url: 'https://github.com',
|
|
220
|
+
icon: <svg data-testid="custom-icon" />,
|
|
221
|
+
}}
|
|
222
|
+
number={1}
|
|
223
|
+
data-testid="citation"
|
|
224
|
+
/>,
|
|
225
|
+
);
|
|
226
|
+
// The node renders directly; no <img> is produced for a node icon.
|
|
227
|
+
expect(container.querySelector('img')).toBeNull();
|
|
228
|
+
expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
|
|
229
|
+
// Still decorative — wrapped in an aria-hidden container.
|
|
230
|
+
expect(
|
|
231
|
+
container.querySelector(
|
|
232
|
+
'[aria-hidden="true"] [data-testid="custom-icon"]',
|
|
233
|
+
),
|
|
234
|
+
).not.toBeNull();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('prefers a node icon over src when both are provided', () => {
|
|
238
|
+
const {container} = render(
|
|
239
|
+
<Citation
|
|
240
|
+
source={{
|
|
241
|
+
title: 'GitHub',
|
|
242
|
+
url: 'https://github.com',
|
|
243
|
+
src: 'https://example.com/logo.png',
|
|
244
|
+
icon: <svg data-testid="custom-icon" />,
|
|
245
|
+
}}
|
|
246
|
+
number={1}
|
|
247
|
+
data-testid="citation"
|
|
248
|
+
/>,
|
|
249
|
+
);
|
|
250
|
+
expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
|
|
251
|
+
expect(container.querySelector('img')).toBeNull();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('keeps aria-label as the sole accessible name when an icon is present', () => {
|
|
255
|
+
render(
|
|
256
|
+
<Citation
|
|
257
|
+
source={{
|
|
258
|
+
title: 'GitHub',
|
|
259
|
+
url: 'https://github.com',
|
|
260
|
+
icon: 'https://example.com/favicon.png',
|
|
261
|
+
}}
|
|
262
|
+
number={2}
|
|
263
|
+
data-testid="citation"
|
|
264
|
+
/>,
|
|
265
|
+
);
|
|
266
|
+
const el = screen.getByTestId('citation');
|
|
267
|
+
expect(el).toHaveAttribute('aria-label', 'Citation 2: GitHub');
|
|
268
|
+
});
|
|
172
269
|
});
|