@astryxdesign/core 0.1.3 → 0.1.4-canary.01e5b29
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 +51 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +20 -18
- package/dist/AlertDialog/useImperativeAlertDialog.js +3 -3
- package/dist/AppShell/AppShell.d.ts +1 -1
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +55 -53
- package/dist/AspectRatio/AspectRatio.js +5 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +27 -25
- package/dist/Avatar/AvatarStatusDot.js +5 -5
- package/dist/AvatarGroup/AvatarGroup.js +5 -5
- package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -5
- package/dist/Badge/Badge.js +3 -3
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +32 -25
- package/dist/Blockquote/Blockquote.js +7 -7
- package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
- package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +47 -26
- package/dist/ButtonGroup/ButtonGroup.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +108 -64
- package/dist/Calendar/dayCellUtils.d.ts +67 -5
- package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
- package/dist/Calendar/dayCellUtils.js +139 -18
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +2 -2
- package/dist/Card/Card.d.ts +4 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +18 -10
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +20 -19
- package/dist/Center/Center.js +3 -3
- package/dist/Chat/ChatComposer.js +23 -23
- package/dist/Chat/ChatComposerDrawer.js +14 -14
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +27 -15
- package/dist/Chat/ChatDictationButton.d.ts +1 -1
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +13 -11
- package/dist/Chat/ChatLayout.js +17 -17
- package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +12 -10
- package/dist/Chat/ChatMessage.js +12 -12
- package/dist/Chat/ChatMessageBubble.js +7 -7
- package/dist/Chat/ChatMessageList.js +14 -14
- package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +14 -12
- package/dist/Chat/ChatPastedTextToken.js +13 -13
- package/dist/Chat/ChatSendButton.js +3 -3
- package/dist/Chat/ChatSystemMessage.d.ts +1 -1
- package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
- package/dist/Chat/ChatSystemMessage.js +17 -17
- package/dist/Chat/ChatTokenizedText.d.ts +1 -1
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +24 -15
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +81 -74
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -15
- package/dist/CheckboxInput/CheckboxInput.d.ts +6 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +32 -24
- package/dist/CheckboxList/CheckboxList.js +9 -9
- package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +8 -6
- package/dist/Citation/Citation.js +10 -10
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +32 -9
- package/dist/Code/Code.d.ts +15 -1
- package/dist/Code/Code.d.ts.map +1 -1
- package/dist/Code/Code.js +35 -5
- package/dist/Code/index.d.ts +1 -1
- package/dist/Code/index.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +88 -52
- package/dist/CodeBlock/index.d.ts +1 -1
- package/dist/CodeBlock/index.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.d.ts +9 -3
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +110 -22
- package/dist/Collapsible/CollapsibleGroup.d.ts +39 -7
- package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroup.js +73 -12
- package/dist/Collapsible/CollapsibleGroupContext.d.ts +31 -0
- package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroupContext.js +33 -3
- package/dist/Collapsible/index.d.ts +1 -0
- package/dist/Collapsible/index.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.d.ts +4 -1
- package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.js +20 -6
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +36 -34
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +27 -7
- package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
- package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
- package/dist/CommandPalette/CommandPaletteInput.js +13 -13
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/CommandPalette/CommandPaletteList.js +3 -3
- package/dist/ContextMenu/ContextMenu.d.ts +9 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +16 -11
- package/dist/DateInput/DateInput.js +18 -18
- package/dist/DateRangeInput/DateRangeInput.js +23 -23
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -7
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +30 -26
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +9 -9
- package/dist/Dialog/DialogHeader.js +16 -16
- package/dist/Dialog/useImperativeDialog.js +3 -3
- package/dist/Divider/Divider.d.ts +0 -22
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +7 -7
- package/dist/DropdownMenu/DropdownMenu.js +10 -10
- package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
- package/dist/DropdownMenu/renderDropdownItems.js +10 -10
- package/dist/EmptyState/EmptyState.js +9 -9
- package/dist/Field/Field.js +17 -17
- package/dist/Field/FieldLabel.js +15 -15
- package/dist/Field/InputClearButton.js +5 -5
- package/dist/FieldStatus/FieldStatus.js +3 -3
- package/dist/FileInput/FileInput.js +29 -29
- package/dist/FormLayout/FormLayout.js +5 -5
- package/dist/Grid/Grid.d.ts +4 -3
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +29 -12
- package/dist/Grid/GridSpan.js +3 -3
- package/dist/HStack/HStack.js +3 -3
- package/dist/Heading/Heading.js +10 -10
- package/dist/HoverCard/HoverCard.js +9 -9
- package/dist/HoverCard/useHoverCard.js +3 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +16 -12
- package/dist/Icon/defaultIcons.js +116 -116
- package/dist/IconButton/IconButton.js +3 -3
- package/dist/InputGroup/InputGroup.js +11 -11
- package/dist/InputGroup/InputGroupText.js +3 -3
- package/dist/Item/Item.js +18 -18
- package/dist/Kbd/Kbd.js +5 -5
- package/dist/Layer/LayerProvider.js +7 -7
- package/dist/Layer/useLayer.js +5 -5
- package/dist/Layout/Layout.js +21 -21
- package/dist/Layout/LayoutContent.js +3 -3
- package/dist/Layout/LayoutFooter.js +5 -5
- package/dist/Layout/LayoutHeader.js +5 -5
- package/dist/Layout/LayoutPanel.js +3 -3
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +55 -31
- package/dist/Lightbox/useLightbox.js +3 -3
- package/dist/Link/Link.js +15 -15
- package/dist/Link/LinkProvider.js +3 -3
- package/dist/Link/useLinkify.js +3 -3
- package/dist/List/List.js +11 -11
- package/dist/List/ListItem.js +11 -11
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +102 -102
- package/dist/Markdown/parser.d.ts +7 -0
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +300 -6
- package/dist/MetadataList/MetadataList.js +10 -10
- package/dist/MetadataList/MetadataListItem.js +15 -15
- package/dist/MobileNav/MobileNav.js +15 -15
- package/dist/MobileNav/MobileNavToggle.js +5 -5
- package/dist/MoreMenu/MoreMenu.js +3 -3
- package/dist/MultiSelector/MultiSelector.d.ts +7 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +64 -55
- package/dist/NavIcon/NavIcon.js +3 -3
- package/dist/NavMenu/NavHeadingMenu.js +5 -5
- package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +48 -32
- package/dist/Outline/Outline.js +15 -15
- package/dist/OverflowList/OverflowList.js +8 -8
- package/dist/Overlay/Overlay.js +3 -3
- package/dist/Overlay/OverlayScrim.js +5 -5
- package/dist/Overlay/useOverlay.js +3 -3
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +125 -72
- package/dist/Popover/Popover.js +16 -16
- package/dist/Popover/usePopover.js +7 -7
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +110 -92
- package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
- package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
- package/dist/PowerSearch/PowerSearchToken.js +5 -5
- package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +25 -18
- package/dist/RadioList/RadioList.d.ts +7 -1
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +10 -8
- package/dist/RadioList/RadioListItem.d.ts +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +30 -22
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +28 -10
- package/dist/Section/Section.js +5 -5
- package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +32 -10
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +18 -12
- package/dist/SelectableCard/SelectableCard.js +5 -5
- package/dist/Selector/Selector.d.ts +6 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +54 -45
- package/dist/Selector/SelectorOption.js +3 -3
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +38 -34
- package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +8 -6
- package/dist/SideNav/SideNavHeading.js +87 -87
- package/dist/SideNav/SideNavItem.js +42 -42
- package/dist/SideNav/SideNavSection.d.ts +1 -1
- package/dist/SideNav/SideNavSection.d.ts.map +1 -1
- package/dist/SideNav/SideNavSection.js +18 -16
- package/dist/Skeleton/Skeleton.js +3 -3
- package/dist/Slider/Slider.d.ts +6 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +31 -22
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +10 -10
- package/dist/StatusDot/StatusDot.js +5 -5
- package/dist/Switch/Switch.d.ts +13 -4
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -30
- package/dist/TabList/Tab.js +18 -18
- package/dist/TabList/TabList.js +5 -5
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +57 -30
- package/dist/TabList/tab.markers.stylex.d.ts +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +51 -39
- package/dist/Table/Table.js +7 -7
- package/dist/Table/TableBody.d.ts +1 -1
- package/dist/Table/TableBody.d.ts.map +1 -1
- package/dist/Table/TableBody.js +9 -5
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +76 -7
- package/dist/Table/TableFooter.d.ts +1 -1
- package/dist/Table/TableFooter.d.ts.map +1 -1
- package/dist/Table/TableFooter.js +9 -5
- package/dist/Table/TableHeader.d.ts +1 -1
- package/dist/Table/TableHeader.d.ts.map +1 -1
- package/dist/Table/TableHeader.js +9 -5
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/TableRow.js +5 -5
- 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/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
- package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +5 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +7 -7
- package/dist/Table/plugins/rowExpansion/index.d.ts +3 -0
- package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/index.js +3 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
- package/dist/Table/plugins/selection/useTableSelection.js +18 -18
- package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
- package/dist/Table/tableContextMenu.d.ts +5 -1
- package/dist/Table/tableContextMenu.d.ts.map +1 -1
- package/dist/Table/tableContextMenu.js +19 -12
- package/dist/Text/Text.d.ts +1 -1
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +14 -13
- package/dist/Text/text.stylex.d.ts +35 -0
- package/dist/Text/text.stylex.d.ts.map +1 -1
- package/dist/Text/text.stylex.js +52 -1
- package/dist/TextArea/TextArea.js +14 -14
- package/dist/TextInput/TextInput.js +15 -15
- package/dist/Thumbnail/Thumbnail.d.ts +3 -2
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +30 -29
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +26 -21
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +37 -26
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +25 -17
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +23 -11
- package/dist/Toast/useToast.js +4 -4
- package/dist/ToggleButton/ToggleButton.js +12 -12
- package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
- package/dist/Token/Token.js +21 -21
- package/dist/Tokenizer/Tokenizer.d.ts +6 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +38 -29
- package/dist/Toolbar/Toolbar.js +18 -18
- package/dist/Tooltip/Tooltip.js +11 -11
- package/dist/Tooltip/useTooltip.js +3 -3
- package/dist/TopNav/TopNav.js +32 -32
- package/dist/TopNav/TopNavHeading.js +67 -67
- package/dist/TopNav/TopNavItem.js +5 -5
- package/dist/TopNav/TopNavMegaMenu.js +30 -30
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
- package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
- package/dist/TopNav/TopNavMenu.js +32 -32
- package/dist/TreeList/TreeList.js +8 -8
- package/dist/TreeList/TreeListBranches.js +11 -11
- package/dist/TreeList/TreeListItem.js +30 -30
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +23 -20
- package/dist/Typeahead/Typeahead.js +12 -12
- package/dist/Typeahead/TypeaheadItem.js +10 -10
- package/dist/VStack/VStack.js +3 -3
- package/dist/astryx.css +23 -0
- package/dist/astryx.umd.js +60 -58
- package/dist/astryx.umd.js.map +4 -4
- package/dist/docs-types.d.ts +13 -1
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.d.ts +1 -1
- package/dist/hooks/focusableSelector.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.js +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +3 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +38 -1
- package/dist/hooks/useHotkeys.d.ts +51 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -0
- package/dist/hooks/useHotkeys.js +160 -0
- package/dist/hooks/useInteractiveRole.d.ts +6 -2
- package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
- package/dist/hooks/useInteractiveRole.js +6 -2
- package/dist/hooks/useKeyboardHint.js +9 -9
- package/dist/hooks/useStreamingText.d.ts +3 -1
- package/dist/hooks/useStreamingText.d.ts.map +1 -1
- package/dist/hooks/useStreamingText.js +14 -5
- package/dist/theme/MediaTheme.js +3 -3
- package/dist/theme/Theme.js +7 -7
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/expandColorScale.d.ts.map +1 -1
- package/dist/theme/expandColorScale.js +10 -3
- package/dist/theme/hct.d.ts +0 -15
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +9 -9
- package/dist/theme/syntax/SyntaxTheme.js +5 -5
- package/dist/theme/tokens.d.ts +10 -2
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +220 -4
- package/dist/utils/color.d.ts +42 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +150 -0
- package/dist/utils/composeEventHandlers.d.ts +30 -0
- package/dist/utils/composeEventHandlers.d.ts.map +1 -0
- package/dist/utils/composeEventHandlers.js +40 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +8 -5
- package/package.json +3 -3
- package/src/AlertDialog/AlertDialog.tsx +2 -0
- package/src/AppShell/AppShell.tsx +2 -0
- package/src/AspectRatio/AspectRatio.doc.mjs +1 -1
- package/src/Avatar/Avatar.doc.mjs +13 -2
- package/src/Avatar/Avatar.test.tsx +32 -1
- package/src/Avatar/Avatar.tsx +12 -20
- package/src/Banner/Banner.doc.mjs +8 -0
- package/src/Banner/Banner.test.tsx +38 -0
- package/src/Banner/Banner.tsx +8 -1
- package/src/Button/Button.tsx +39 -6
- package/src/ButtonGroup/ButtonGroup.doc.mjs +1 -1
- package/src/Calendar/Calendar.doc.mjs +1 -1
- package/src/Calendar/Calendar.test.tsx +201 -17
- package/src/Calendar/Calendar.tsx +79 -26
- package/src/Calendar/dayCellUtils.test.ts +306 -1
- package/src/Calendar/dayCellUtils.ts +206 -13
- package/src/Calendar/styles.ts +12 -2
- package/src/Card/Card.doc.mjs +1 -1
- package/src/Card/Card.tsx +16 -6
- package/src/Carousel/Carousel.doc.mjs +12 -12
- package/src/Carousel/Carousel.test.tsx +13 -0
- package/src/Carousel/Carousel.tsx +1 -0
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.test.tsx +24 -0
- package/src/Chat/ChatComposerInput.tsx +17 -1
- package/src/Chat/ChatDictationButton.test.tsx +43 -0
- package/src/Chat/ChatDictationButton.tsx +4 -4
- package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
- package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
- package/src/Chat/ChatMessageMetadata.tsx +4 -6
- package/src/Chat/ChatSystemMessage.test.tsx +26 -11
- package/src/Chat/ChatSystemMessage.tsx +7 -7
- package/src/Chat/ChatTokenizedText.test.tsx +29 -16
- package/src/Chat/ChatTokenizedText.tsx +15 -8
- package/src/Chat/ChatToolCalls.test.tsx +55 -0
- package/src/Chat/ChatToolCalls.tsx +10 -12
- package/src/Chat/index.ts +1 -4
- package/src/Chat/useChatNewMessages.test.tsx +4 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +12 -4
- package/src/CheckboxInput/CheckboxInput.test.tsx +103 -0
- package/src/CheckboxInput/CheckboxInput.tsx +13 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
- package/src/CheckboxList/CheckboxList.test.tsx +19 -0
- package/src/CheckboxList/CheckboxListItem.tsx +11 -2
- package/src/Citation/Citation.doc.mjs +5 -0
- package/src/ClickableCard/ClickableCard.tsx +45 -2
- package/src/Code/Code.test.tsx +54 -0
- package/src/Code/Code.tsx +48 -4
- package/src/Code/index.ts +1 -1
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
- package/src/CodeBlock/CodeBlock.test.tsx +122 -3
- package/src/CodeBlock/CodeBlock.tsx +62 -4
- package/src/CodeBlock/index.ts +1 -1
- package/src/Collapsible/Collapsible.doc.mjs +8 -4
- package/src/Collapsible/Collapsible.test.tsx +405 -0
- package/src/Collapsible/Collapsible.tsx +86 -10
- package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
- package/src/Collapsible/CollapsibleGroup.test.tsx +318 -0
- package/src/Collapsible/CollapsibleGroup.tsx +107 -9
- package/src/Collapsible/CollapsibleGroupContext.tsx +42 -2
- package/src/Collapsible/index.ts +4 -0
- package/src/Collapsible/useCollapsible.ts +20 -6
- package/src/CommandPalette/CommandPalette.tsx +5 -3
- package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
- package/src/CommandPalette/CommandPaletteEmpty.tsx +15 -1
- package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
- package/src/ContextMenu/ContextMenu.test.tsx +15 -0
- package/src/ContextMenu/ContextMenu.tsx +19 -1
- package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
- package/src/DateInput/DateInput.doc.mjs +6 -1
- package/src/DateInput/DateInput.test.tsx +11 -20
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
- package/src/DateRangeInput/DateRangeInput.tsx +2 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -3
- package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
- package/src/DateTimeInput/DateTimeInput.tsx +9 -8
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/DialogHeader.doc.mjs +45 -0
- package/src/Divider/Divider.tsx +1 -23
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -3
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
- package/src/EmptyState/EmptyState.doc.mjs +1 -1
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/FieldLabel.test.tsx +2 -2
- package/src/FieldStatus/FieldStatus.test.tsx +282 -0
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
- package/src/Grid/Grid.doc.mjs +3 -3
- package/src/Grid/Grid.test.tsx +43 -18
- package/src/Grid/Grid.tsx +26 -9
- package/src/Icon/Icon.test.tsx +41 -29
- package/src/Icon/Icon.tsx +6 -2
- package/src/InputGroup/InputGroup.tsx +2 -2
- package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
- package/src/Item/Item.tsx +1 -1
- package/src/Layout/Layout.test.tsx +285 -0
- package/src/Layout/LayoutContent.doc.mjs +12 -0
- package/src/Layout/LayoutPanel.doc.mjs +40 -0
- package/src/Layout/LayoutSlots.test.tsx +364 -0
- package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
- package/src/Lightbox/Lightbox.doc.mjs +5 -0
- package/src/Lightbox/Lightbox.test.tsx +123 -2
- package/src/Lightbox/Lightbox.tsx +29 -1
- package/src/Markdown/Markdown.test.tsx +23 -0
- package/src/Markdown/Markdown.tsx +9 -7
- package/src/Markdown/incremental.test.ts +36 -0
- package/src/Markdown/parser.perf.test.ts +34 -12
- package/src/Markdown/parser.test.ts +210 -0
- package/src/Markdown/parser.ts +301 -6
- package/src/MobileNav/MobileNav.doc.mjs +20 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +14 -1
- package/src/MultiSelector/MultiSelector.test.tsx +33 -0
- package/src/MultiSelector/MultiSelector.tsx +20 -0
- package/src/NavMenu/NavMenu.doc.mjs +15 -0
- package/src/NumberInput/NumberInput.test.tsx +48 -3
- package/src/NumberInput/NumberInput.tsx +32 -15
- package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
- package/src/OverflowList/OverflowList.test.tsx +416 -0
- package/src/Overlay/Overlay.doc.mjs +6 -0
- package/src/Overlay/Overlay.test.tsx +356 -0
- package/src/Pagination/Pagination.test.tsx +162 -0
- package/src/Pagination/Pagination.tsx +80 -26
- package/src/Popover/Popover.test.tsx +65 -0
- package/src/PowerSearch/PowerSearch.doc.mjs +4 -4
- package/src/PowerSearch/PowerSearch.test.tsx +109 -1
- package/src/PowerSearch/PowerSearch.tsx +37 -16
- package/src/ProgressBar/ProgressBar.test.tsx +30 -0
- package/src/ProgressBar/ProgressBar.tsx +12 -5
- package/src/RadioList/RadioList.doc.mjs +7 -1
- package/src/RadioList/RadioList.test.tsx +65 -0
- package/src/RadioList/RadioList.tsx +10 -1
- package/src/RadioList/RadioListItem.tsx +13 -4
- package/src/Resizable/ResizeHandle.test.tsx +218 -0
- package/src/Resizable/ResizeHandle.tsx +22 -4
- package/src/Section/Section.test.tsx +4 -10
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
- package/src/SegmentedControl/SegmentedControl.tsx +27 -5
- package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +12 -1
- package/src/Selector/Selector.test.tsx +30 -0
- package/src/Selector/Selector.tsx +18 -0
- package/src/SideNav/SideNav.doc.mjs +7 -1
- package/src/SideNav/SideNav.test.tsx +66 -0
- package/src/SideNav/SideNav.tsx +6 -2
- package/src/SideNav/SideNavCollapseButton.tsx +4 -3
- package/src/SideNav/SideNavSection.tsx +6 -4
- package/src/SizeContext/SizeContext.test.tsx +226 -0
- package/src/Slider/Slider.doc.mjs +14 -2
- package/src/Slider/Slider.test.tsx +30 -0
- package/src/Slider/Slider.tsx +20 -0
- package/src/Spinner/Spinner.tsx +1 -0
- package/src/Switch/Switch.doc.mjs +21 -9
- package/src/Switch/Switch.test.tsx +137 -0
- package/src/Switch/Switch.tsx +32 -7
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +185 -1
- package/src/TabList/TabMenu.tsx +45 -9
- package/src/Table/BaseTable.tsx +16 -3
- package/src/Table/Table.test.tsx +87 -0
- package/src/Table/TableBody.tsx +15 -2
- package/src/Table/TableCell.tsx +87 -8
- package/src/Table/TableFooter.tsx +15 -2
- package/src/Table/TableHeader.tsx +15 -2
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
- package/src/Table/plugins/pagination/paginateData.ts +5 -1
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
- package/src/Table/plugins/rowExpansion/index.ts +7 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
- package/src/Table/plugins/selection/useTableSelectionState.test.tsx +23 -0
- package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
- package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
- package/src/Table/tableContextMenu.test.tsx +27 -3
- package/src/Table/tableContextMenu.tsx +20 -2
- package/src/Table/useTablePagination.doc.mjs +4 -1
- package/src/Table/useTableRowExpansion.doc.mjs +80 -0
- package/src/Table/useTableSortable.doc.mjs +4 -1
- package/src/Text/Text.doc.mjs +2 -2
- package/src/Text/Text.test.tsx +11 -0
- package/src/Text/Text.tsx +4 -2
- package/src/Text/text.stylex.ts +41 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.test.tsx +3 -3
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TextInput/TextInput.test.tsx +3 -3
- package/src/Thumbnail/Thumbnail.test.tsx +36 -2
- package/src/Thumbnail/Thumbnail.tsx +4 -2
- package/src/TimeInput/TimeInput.doc.mjs +11 -6
- package/src/TimeInput/TimeInput.test.tsx +37 -0
- package/src/TimeInput/TimeInput.tsx +11 -1
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +52 -0
- package/src/Timestamp/Timestamp.tsx +30 -16
- package/src/Toast/Toast.tsx +11 -3
- package/src/Toast/ToastViewport.test.tsx +64 -0
- package/src/Toast/ToastViewport.tsx +12 -0
- package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -4
- package/src/Tokenizer/Tokenizer.test.tsx +33 -0
- package/src/Tokenizer/Tokenizer.tsx +19 -0
- package/src/Toolbar/Toolbar.test.tsx +1 -1
- package/src/TopNav/TopNav.doc.mjs +1 -1
- package/src/TopNav/TopNav.test.tsx +18 -0
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
- package/src/TreeList/TreeList.doc.mjs +2 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.doc.mjs +7 -2
- package/src/Typeahead/Typeahead.test.tsx +45 -1
- package/src/__tests__/TestIcon.tsx +26 -0
- package/src/__tests__/fastRoleQueries.ts +66 -0
- package/src/docPropReferences.test.ts +178 -0
- package/src/docs-types.ts +14 -0
- package/src/hooks/focusableSelector.ts +1 -1
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useFocusTrap.doc.mjs +4 -2
- package/src/hooks/useFocusTrap.test.tsx +149 -1
- package/src/hooks/useFocusTrap.ts +50 -1
- package/src/hooks/useHotkeys.doc.mjs +52 -0
- package/src/hooks/useHotkeys.test.ts +245 -0
- package/src/hooks/useHotkeys.ts +203 -0
- package/src/hooks/useInteractiveRole.ts +12 -4
- package/src/hooks/useKeyboardHint.doc.mjs +6 -6
- package/src/hooks/useStreamingText.test.ts +54 -19
- package/src/hooks/useStreamingText.ts +16 -5
- package/src/theme/SyntaxTheme.doc.mjs +4 -4
- package/src/theme/defineTheme.ts +4 -13
- package/src/theme/derivedVarRegistry.test.ts +2 -2
- package/src/theme/expandColorScale.test.ts +29 -0
- package/src/theme/expandColorScale.ts +11 -6
- package/src/theme/hct.ts +9 -17
- package/src/theme/tokens.test.ts +182 -9
- package/src/theme/tokens.ts +239 -4
- package/src/theme/useTheme.test.tsx +20 -0
- package/src/utils/color.test.ts +133 -0
- package/src/utils/color.ts +148 -0
- package/src/utils/composeEventHandlers.test.ts +71 -0
- package/src/utils/composeEventHandlers.ts +44 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/mergeProps.test.ts +166 -0
- package/src/utils/sharedResizeObserver.test.ts +2 -2
- package/src/utils/timeParser.test.ts +13 -0
- package/src/utils/timeParser.ts +8 -5
|
@@ -354,4 +354,69 @@ describe('Popover', () => {
|
|
|
354
354
|
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
355
355
|
});
|
|
356
356
|
});
|
|
357
|
+
|
|
358
|
+
describe('focus restoration', () => {
|
|
359
|
+
it('returns focus to the trigger when closed via Escape', () => {
|
|
360
|
+
render(
|
|
361
|
+
<Popover
|
|
362
|
+
content={
|
|
363
|
+
<button type="button" data-testid="inside-content">
|
|
364
|
+
Inside
|
|
365
|
+
</button>
|
|
366
|
+
}
|
|
367
|
+
label="Test">
|
|
368
|
+
<button type="button">Open</button>
|
|
369
|
+
</Popover>,
|
|
370
|
+
);
|
|
371
|
+
const trigger = screen.getByRole('button', {name: 'Open'});
|
|
372
|
+
trigger.focus();
|
|
373
|
+
expect(trigger).toHaveFocus();
|
|
374
|
+
|
|
375
|
+
fireEvent.click(trigger);
|
|
376
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
377
|
+
|
|
378
|
+
// Move focus into the open popover, as a keyboard user would.
|
|
379
|
+
const inside = screen.getByTestId('inside-content');
|
|
380
|
+
inside.focus();
|
|
381
|
+
expect(inside).toHaveFocus();
|
|
382
|
+
|
|
383
|
+
fireEvent.keyDown(document, {key: 'Escape'});
|
|
384
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
385
|
+
expect(trigger).toHaveFocus();
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('returns focus to the trigger on light dismiss', () => {
|
|
389
|
+
render(
|
|
390
|
+
<Popover
|
|
391
|
+
content={
|
|
392
|
+
<button type="button" data-testid="inside-content">
|
|
393
|
+
Inside
|
|
394
|
+
</button>
|
|
395
|
+
}
|
|
396
|
+
label="Test">
|
|
397
|
+
<button type="button">Open</button>
|
|
398
|
+
</Popover>,
|
|
399
|
+
);
|
|
400
|
+
const trigger = screen.getByRole('button', {name: 'Open'});
|
|
401
|
+
trigger.focus();
|
|
402
|
+
|
|
403
|
+
fireEvent.click(trigger);
|
|
404
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
405
|
+
|
|
406
|
+
const inside = screen.getByTestId('inside-content');
|
|
407
|
+
inside.focus();
|
|
408
|
+
expect(inside).toHaveFocus();
|
|
409
|
+
|
|
410
|
+
// Simulate the browser's light dismiss for popover="auto": clicking
|
|
411
|
+
// outside fires a `toggle` event with newState "closed".
|
|
412
|
+
const popoverEl = document.querySelector('[popover]');
|
|
413
|
+
expect(popoverEl).not.toBeNull();
|
|
414
|
+
const toggleEvent = new Event('toggle');
|
|
415
|
+
Object.defineProperty(toggleEvent, 'newState', {value: 'closed'});
|
|
416
|
+
fireEvent(popoverEl as HTMLElement, toggleEvent);
|
|
417
|
+
|
|
418
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
419
|
+
expect(trigger).toHaveFocus();
|
|
420
|
+
});
|
|
421
|
+
});
|
|
357
422
|
});
|
|
@@ -75,7 +75,7 @@ export const docs = {
|
|
|
75
75
|
name: 'disabledMessage',
|
|
76
76
|
type: 'string',
|
|
77
77
|
description:
|
|
78
|
-
'Explains why the search is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled PowerSearch in Tooltip
|
|
78
|
+
'Explains why the search is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled PowerSearch in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
81
|
name: 'status',
|
|
@@ -120,7 +120,7 @@ export const docs = {
|
|
|
120
120
|
name: 'resultCount',
|
|
121
121
|
type: 'number | string',
|
|
122
122
|
description:
|
|
123
|
-
'Number of results matching the current filters. When a number, formatted as "N results". When a string, displayed as-is.',
|
|
123
|
+
'Number of results matching the current filters. When a number, formatted as "N results". When a string, displayed as-is. Changes are announced to screen readers via a polite live region.',
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
126
|
name: 'size',
|
|
@@ -223,7 +223,7 @@ export const docsZh = {
|
|
|
223
223
|
name: 'disabledMessage',
|
|
224
224
|
type: 'string',
|
|
225
225
|
description:
|
|
226
|
-
'Explains why the search is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled PowerSearch in Tooltip
|
|
226
|
+
'Explains why the search is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled PowerSearch in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
name: 'status',
|
|
@@ -261,7 +261,7 @@ export const docsZh = {
|
|
|
261
261
|
name: 'resultCount',
|
|
262
262
|
type: 'number | string',
|
|
263
263
|
description:
|
|
264
|
-
'匹配当前过滤器的结果数量。数字类型时格式化为"N results"
|
|
264
|
+
'匹配当前过滤器的结果数量。数字类型时格式化为"N results"。字符串类型时按原样显示。数量变化会通过 polite 实时区域向屏幕阅读器播报。',
|
|
265
265
|
},
|
|
266
266
|
{
|
|
267
267
|
name: 'size',
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {useState} from 'react';
|
|
13
|
-
import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest';
|
|
13
|
+
import {describe, it, expect, vi, beforeAll, afterAll, afterEach} from 'vitest';
|
|
14
14
|
import {render, screen, act, fireEvent, waitFor} from '@testing-library/react';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
16
|
import {PowerSearch} from './PowerSearch';
|
|
17
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
17
18
|
import type {PowerSearchConfig, PowerSearchFilter} from './types';
|
|
18
19
|
|
|
19
20
|
// =============================================================================
|
|
@@ -59,6 +60,12 @@ afterAll(() => {
|
|
|
59
60
|
(HTMLElement.prototype as any).matches = originalMatches;
|
|
60
61
|
});
|
|
61
62
|
|
|
63
|
+
// Reset the singleton live regions between tests so result-count
|
|
64
|
+
// announcements from one test don't leak into the next.
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
__resetLiveRegionsForTest();
|
|
67
|
+
});
|
|
68
|
+
|
|
62
69
|
// =============================================================================
|
|
63
70
|
// Fixtures
|
|
64
71
|
// =============================================================================
|
|
@@ -295,4 +302,105 @@ describe('PowerSearch', () => {
|
|
|
295
302
|
expect(screen.getByRole('combobox')).toBeDisabled();
|
|
296
303
|
});
|
|
297
304
|
});
|
|
305
|
+
|
|
306
|
+
describe('result count announcements', () => {
|
|
307
|
+
const politeRegion = () =>
|
|
308
|
+
document.querySelector('[data-astryx-live-region="polite"]');
|
|
309
|
+
|
|
310
|
+
it('announces the result count to a polite live region when it changes', async () => {
|
|
311
|
+
const {rerender} = render(
|
|
312
|
+
<PowerSearch
|
|
313
|
+
config={config}
|
|
314
|
+
filters={[]}
|
|
315
|
+
onChange={() => {}}
|
|
316
|
+
resultCount={0}
|
|
317
|
+
/>,
|
|
318
|
+
);
|
|
319
|
+
rerender(
|
|
320
|
+
<PowerSearch
|
|
321
|
+
config={config}
|
|
322
|
+
filters={[]}
|
|
323
|
+
onChange={() => {}}
|
|
324
|
+
resultCount={5}
|
|
325
|
+
/>,
|
|
326
|
+
);
|
|
327
|
+
await waitFor(() => {
|
|
328
|
+
expect(politeRegion()).toHaveTextContent('5 results');
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('announces "1 result" (singular) for a single match', async () => {
|
|
333
|
+
const {rerender} = render(
|
|
334
|
+
<PowerSearch
|
|
335
|
+
config={config}
|
|
336
|
+
filters={[]}
|
|
337
|
+
onChange={() => {}}
|
|
338
|
+
resultCount={0}
|
|
339
|
+
/>,
|
|
340
|
+
);
|
|
341
|
+
rerender(
|
|
342
|
+
<PowerSearch
|
|
343
|
+
config={config}
|
|
344
|
+
filters={[]}
|
|
345
|
+
onChange={() => {}}
|
|
346
|
+
resultCount={1}
|
|
347
|
+
/>,
|
|
348
|
+
);
|
|
349
|
+
await waitFor(() => {
|
|
350
|
+
expect(politeRegion()).toHaveTextContent('1 result');
|
|
351
|
+
});
|
|
352
|
+
expect(politeRegion()?.textContent).not.toMatch(/results/);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('announces a string result count verbatim', async () => {
|
|
356
|
+
const {rerender} = render(
|
|
357
|
+
<PowerSearch
|
|
358
|
+
config={config}
|
|
359
|
+
filters={[]}
|
|
360
|
+
onChange={() => {}}
|
|
361
|
+
resultCount="0 items"
|
|
362
|
+
/>,
|
|
363
|
+
);
|
|
364
|
+
rerender(
|
|
365
|
+
<PowerSearch
|
|
366
|
+
config={config}
|
|
367
|
+
filters={[]}
|
|
368
|
+
onChange={() => {}}
|
|
369
|
+
resultCount="Showing 1.2k matches"
|
|
370
|
+
/>,
|
|
371
|
+
);
|
|
372
|
+
await waitFor(() => {
|
|
373
|
+
expect(politeRegion()).toHaveTextContent('Showing 1.2k matches');
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('does not announce the result count present on initial mount', async () => {
|
|
378
|
+
render(
|
|
379
|
+
<PowerSearch
|
|
380
|
+
config={config}
|
|
381
|
+
filters={[]}
|
|
382
|
+
onChange={() => {}}
|
|
383
|
+
resultCount={42}
|
|
384
|
+
/>,
|
|
385
|
+
);
|
|
386
|
+
// Flush effects and any pending live-region rAF writes.
|
|
387
|
+
await act(async () => {
|
|
388
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
389
|
+
});
|
|
390
|
+
expect(politeRegion()?.textContent ?? '').not.toContain('42');
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('leaves Typeahead dropdown announcements intact and stays silent when no resultCount is set', async () => {
|
|
394
|
+
const user = userEvent.setup();
|
|
395
|
+
render(<PowerSearchWrapper config={config} />);
|
|
396
|
+
const input = screen.getByRole('combobox');
|
|
397
|
+
await user.click(input);
|
|
398
|
+
await user.type(input, 'Status');
|
|
399
|
+
// BaseTypeahead announces the dropdown suggestion count; PowerSearch adds
|
|
400
|
+
// no result-count announcement because resultCount is unset.
|
|
401
|
+
await waitFor(() => {
|
|
402
|
+
expect(politeRegion()?.textContent).toMatch(/\d+ results?/);
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});
|
|
298
406
|
});
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import React, {
|
|
18
18
|
useCallback,
|
|
19
|
+
useEffect,
|
|
19
20
|
useImperativeHandle,
|
|
20
21
|
useMemo,
|
|
21
22
|
useRef,
|
|
@@ -38,6 +39,7 @@ import type {IconType} from '../Icon';
|
|
|
38
39
|
import type {IconName} from '../Icon/globalIconRegistry';
|
|
39
40
|
import type {InputStatus} from '../Field';
|
|
40
41
|
import {usePopover} from '../Popover/usePopover';
|
|
42
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
41
43
|
import {
|
|
42
44
|
spacingVars,
|
|
43
45
|
colorVars,
|
|
@@ -945,23 +947,42 @@ export function PowerSearch({
|
|
|
945
947
|
isReadOnly,
|
|
946
948
|
]);
|
|
947
949
|
|
|
950
|
+
// Plain-text form of the result count, shared by the visible label and the
|
|
951
|
+
// screen-reader announcement so the two never drift.
|
|
952
|
+
const resultCountText = useMemo((): string | null => {
|
|
953
|
+
if (resultCount == null) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
if (typeof resultCount === 'number') {
|
|
957
|
+
const formatted = new Intl.NumberFormat().format(resultCount);
|
|
958
|
+
return `${formatted} ${resultCount === 1 ? 'result' : 'results'}`;
|
|
959
|
+
}
|
|
960
|
+
return resultCount;
|
|
961
|
+
}, [resultCount]);
|
|
962
|
+
|
|
963
|
+
// Announce result-count changes to screen readers through a polite live
|
|
964
|
+
// region, mirroring the way Typeahead announces its dropdown result count.
|
|
965
|
+
// The count is otherwise only shown visually and stays silent to assistive
|
|
966
|
+
// tech. Skip the first run so the count already present on mount isn't
|
|
967
|
+
// announced unprompted — only user-driven changes are spoken.
|
|
968
|
+
const announce = useAnnounce();
|
|
969
|
+
const hasMountedRef = useRef(false);
|
|
970
|
+
useEffect(() => {
|
|
971
|
+
if (!hasMountedRef.current) {
|
|
972
|
+
hasMountedRef.current = true;
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (resultCountText != null) {
|
|
976
|
+
announce(resultCountText);
|
|
977
|
+
}
|
|
978
|
+
}, [resultCountText, announce]);
|
|
979
|
+
|
|
948
980
|
// Build combined endContent from resultCount + endContent props
|
|
949
981
|
const combinedEndContent = useMemo((): React.ReactNode => {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
resultCountNode = (
|
|
955
|
-
<span {...stylex.props(resultCountStyles.text)}>
|
|
956
|
-
{formatted} {resultCount === 1 ? 'result' : 'results'}
|
|
957
|
-
</span>
|
|
958
|
-
);
|
|
959
|
-
} else {
|
|
960
|
-
resultCountNode = (
|
|
961
|
-
<span {...stylex.props(resultCountStyles.text)}>{resultCount}</span>
|
|
962
|
-
);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
982
|
+
const resultCountNode =
|
|
983
|
+
resultCountText != null ? (
|
|
984
|
+
<span {...stylex.props(resultCountStyles.text)}>{resultCountText}</span>
|
|
985
|
+
) : null;
|
|
965
986
|
|
|
966
987
|
if (resultCountNode && endContent) {
|
|
967
988
|
return (
|
|
@@ -972,7 +993,7 @@ export function PowerSearch({
|
|
|
972
993
|
);
|
|
973
994
|
}
|
|
974
995
|
return resultCountNode || endContent || undefined;
|
|
975
|
-
}, [
|
|
996
|
+
}, [resultCountText, endContent]);
|
|
976
997
|
|
|
977
998
|
return (
|
|
978
999
|
<>
|
|
@@ -140,6 +140,36 @@ describe('ProgressBar', () => {
|
|
|
140
140
|
expect(progressbar).toHaveAttribute('aria-valuemax', '0');
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
+
it('treats a NaN value as empty progress instead of leaking "NaN"', () => {
|
|
144
|
+
// e.g. an upstream `loaded / total * 100` where total is still 0.
|
|
145
|
+
render(<ProgressBar value={NaN} label="Upload" hasValueLabel />);
|
|
146
|
+
const progressbar = screen.getByRole('progressbar');
|
|
147
|
+
expect(progressbar).toHaveAttribute('aria-valuenow', '0');
|
|
148
|
+
expect(progressbar.getAttribute('aria-valuetext')).toBe('0%');
|
|
149
|
+
expect(screen.queryByText(/NaN/)).not.toBeInTheDocument();
|
|
150
|
+
// The fill width must be a real percentage, not "NaN%".
|
|
151
|
+
const fill = progressbar.firstElementChild as HTMLElement;
|
|
152
|
+
expect(fill.style.width).toBe('0%');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('treats a NaN max as an empty range instead of leaking "NaN"', () => {
|
|
156
|
+
render(<ProgressBar value={5} max={NaN} label="Steps" hasValueLabel />);
|
|
157
|
+
const progressbar = screen.getByRole('progressbar');
|
|
158
|
+
expect(progressbar).toHaveAttribute('aria-valuenow', '0');
|
|
159
|
+
expect(progressbar).toHaveAttribute('aria-valuemax', '0');
|
|
160
|
+
expect(screen.queryByText(/NaN/)).not.toBeInTheDocument();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('does not render NaN in the value label when max is zero', () => {
|
|
164
|
+
render(<ProgressBar value={0} max={0} label="Empty" hasValueLabel />);
|
|
165
|
+
expect(screen.queryByText(/NaN|Infinity/)).not.toBeInTheDocument();
|
|
166
|
+
const progressbar = screen.getByRole('progressbar');
|
|
167
|
+
expect(progressbar.getAttribute('aria-valuetext') ?? '').not.toMatch(
|
|
168
|
+
/NaN|Infinity/,
|
|
169
|
+
);
|
|
170
|
+
expect(screen.getByText('0%')).toBeInTheDocument();
|
|
171
|
+
});
|
|
172
|
+
|
|
143
173
|
// Disabled state
|
|
144
174
|
describe('disabled state', () => {
|
|
145
175
|
it('renders with isDisabled', () => {
|
|
@@ -228,7 +228,8 @@ const variantStyles = stylex.create({
|
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
function defaultFormatValueLabel(value: number, max: number): string {
|
|
231
|
-
|
|
231
|
+
const pct = max > 0 ? Math.round((value / max) * 100) : 0;
|
|
232
|
+
return `${pct}%`;
|
|
232
233
|
}
|
|
233
234
|
|
|
234
235
|
/**
|
|
@@ -272,9 +273,15 @@ export function ProgressBar({
|
|
|
272
273
|
...rest
|
|
273
274
|
}: ProgressBarProps) {
|
|
274
275
|
const labelId = useId();
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
// A non-finite value or max (e.g. a NaN from an upstream `loaded / total`
|
|
277
|
+
// with total 0) would otherwise leak into aria-valuenow, the value label,
|
|
278
|
+
// and the fill width as the string "NaN". Treat it as empty progress,
|
|
279
|
+
// matching the max=0 handling below.
|
|
280
|
+
const safeValue = Number.isFinite(value) ? value : 0;
|
|
281
|
+
const safeMax = Number.isFinite(max) ? max : 0;
|
|
282
|
+
const clampedValue = Math.min(Math.max(0, safeValue), safeMax);
|
|
283
|
+
const percentage = safeMax > 0 ? (clampedValue / safeMax) * 100 : 0;
|
|
284
|
+
const valueText = formatValueLabel(clampedValue, safeMax);
|
|
278
285
|
|
|
279
286
|
const showValueLabel = hasValueLabel && !isIndeterminate;
|
|
280
287
|
|
|
@@ -322,7 +329,7 @@ export function ProgressBar({
|
|
|
322
329
|
role="progressbar"
|
|
323
330
|
aria-valuenow={isIndeterminate ? undefined : clampedValue}
|
|
324
331
|
aria-valuemin={isIndeterminate ? undefined : 0}
|
|
325
|
-
aria-valuemax={isIndeterminate ? undefined :
|
|
332
|
+
aria-valuemax={isIndeterminate ? undefined : safeMax}
|
|
326
333
|
aria-labelledby={labelId}
|
|
327
334
|
aria-valuetext={isIndeterminate ? undefined : valueText}
|
|
328
335
|
{...mergeProps(
|
|
@@ -74,11 +74,17 @@ export const docs = {
|
|
|
74
74
|
description: 'Whether all radio items are disabled.',
|
|
75
75
|
default: 'false',
|
|
76
76
|
},
|
|
77
|
+
{
|
|
78
|
+
name: 'htmlName',
|
|
79
|
+
type: 'string',
|
|
80
|
+
description:
|
|
81
|
+
'The HTML name attribute shared by the radio inputs, useful for form submissions. When omitted, a unique internal name still groups the radios.',
|
|
82
|
+
},
|
|
77
83
|
{
|
|
78
84
|
name: 'disabledMessage',
|
|
79
85
|
type: 'string',
|
|
80
86
|
description:
|
|
81
|
-
'Explains why the group is disabled. Applies to the whole-group disabled state (isDisabled), not per item. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the radios focusable via aria-disabled (selection stays blocked). Use this instead of wrapping a disabled RadioList in Tooltip
|
|
87
|
+
'Explains why the group is disabled. Applies to the whole-group disabled state (isDisabled), not per item. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the radios focusable via aria-disabled (selection stays blocked). Use this instead of wrapping a disabled RadioList in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
82
88
|
},
|
|
83
89
|
{
|
|
84
90
|
name: 'isRequired',
|
|
@@ -576,4 +576,69 @@ describe('RadioList', () => {
|
|
|
576
576
|
}
|
|
577
577
|
});
|
|
578
578
|
});
|
|
579
|
+
describe('form participation', () => {
|
|
580
|
+
it('submits the selected value under htmlName', () => {
|
|
581
|
+
const {container} = render(
|
|
582
|
+
<form>
|
|
583
|
+
<RadioList label="Preference" htmlName="pref" value="b" onChange={() => {}}>
|
|
584
|
+
<RadioListItem label="Option A" value="a" />
|
|
585
|
+
<RadioListItem label="Option B" value="b" />
|
|
586
|
+
</RadioList>
|
|
587
|
+
</form>,
|
|
588
|
+
);
|
|
589
|
+
const data = new FormData(container.querySelector('form')!);
|
|
590
|
+
expect(data.get('pref')).toBe('b');
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
it('is excluded from form data when disabled, even with a disabledMessage', () => {
|
|
594
|
+
const {container} = render(
|
|
595
|
+
<form>
|
|
596
|
+
<RadioList
|
|
597
|
+
label="Preference"
|
|
598
|
+
htmlName="pref"
|
|
599
|
+
value="a"
|
|
600
|
+
onChange={() => {}}
|
|
601
|
+
isDisabled
|
|
602
|
+
disabledMessage="Locked"
|
|
603
|
+
>
|
|
604
|
+
<RadioListItem label="Option A" value="a" />
|
|
605
|
+
</RadioList>
|
|
606
|
+
</form>,
|
|
607
|
+
);
|
|
608
|
+
expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
it('keeps working as an isolated group when htmlName is omitted', () => {
|
|
612
|
+
const {container} = render(
|
|
613
|
+
<form>
|
|
614
|
+
<RadioList label="Preference" value="a" onChange={() => {}}>
|
|
615
|
+
<RadioListItem label="Option A" value="a" />
|
|
616
|
+
</RadioList>
|
|
617
|
+
</form>,
|
|
618
|
+
);
|
|
619
|
+
// Auto-generated internal name still groups the radios, but the field
|
|
620
|
+
// name is not part of the public form contract.
|
|
621
|
+
const input = container.querySelector('input[type="radio"]')!;
|
|
622
|
+
expect(input.getAttribute('name')).toBeTruthy();
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
describe('RadioListItem rest forwarding', () => {
|
|
627
|
+
it('forwards data-testid, id, and aria-* to the item root element', () => {
|
|
628
|
+
render(
|
|
629
|
+
<RadioList label="Preference" value="" onChange={() => {}}>
|
|
630
|
+
<RadioListItem
|
|
631
|
+
label="Option A"
|
|
632
|
+
value="a"
|
|
633
|
+
data-testid="item-a"
|
|
634
|
+
id="item-a-id"
|
|
635
|
+
aria-label="First option"
|
|
636
|
+
/>
|
|
637
|
+
</RadioList>,
|
|
638
|
+
);
|
|
639
|
+
const item = screen.getByTestId('item-a');
|
|
640
|
+
expect(item).toHaveAttribute('id', 'item-a-id');
|
|
641
|
+
expect(item).toHaveAttribute('aria-label', 'First option');
|
|
642
|
+
});
|
|
643
|
+
});
|
|
579
644
|
});
|
|
@@ -111,6 +111,13 @@ export interface RadioListProps extends Omit<
|
|
|
111
111
|
* @default false
|
|
112
112
|
*/
|
|
113
113
|
isDisabled?: boolean;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The HTML name attribute shared by the radio inputs in the group.
|
|
117
|
+
* Useful for form submissions; when omitted, a unique internal name is
|
|
118
|
+
* generated so the group still roves correctly.
|
|
119
|
+
*/
|
|
120
|
+
htmlName?: string;
|
|
114
121
|
/**
|
|
115
122
|
* Explains why the radio group is disabled. Applies to the whole-group
|
|
116
123
|
* disabled state (`isDisabled`), not individual items. When set together with
|
|
@@ -199,9 +206,11 @@ export function RadioList({
|
|
|
199
206
|
className,
|
|
200
207
|
style,
|
|
201
208
|
'data-testid': dataTestId,
|
|
209
|
+
htmlName,
|
|
202
210
|
children,
|
|
203
211
|
}: RadioListProps) {
|
|
204
|
-
const
|
|
212
|
+
const autoName = useId();
|
|
213
|
+
const name = htmlName ?? autoName;
|
|
205
214
|
const inputID = useId();
|
|
206
215
|
const labelID = useId();
|
|
207
216
|
const descriptionID = useId();
|
|
@@ -220,7 +220,10 @@ export function RadioListItem({
|
|
|
220
220
|
isDisabled: isItemDisabled = false,
|
|
221
221
|
startContent,
|
|
222
222
|
endContent,
|
|
223
|
-
|
|
223
|
+
xstyle,
|
|
224
|
+
className,
|
|
225
|
+
style,
|
|
226
|
+
...rest
|
|
224
227
|
}: RadioListItemProps) {
|
|
225
228
|
const context = use(RadioListContext);
|
|
226
229
|
if (!context) {
|
|
@@ -254,6 +257,10 @@ export function RadioListItem({
|
|
|
254
257
|
checked={isChecked}
|
|
255
258
|
disabled={isDisabled && !keepsFocusableForMessage}
|
|
256
259
|
aria-disabled={keepsFocusableForMessage ? 'true' : undefined}
|
|
260
|
+
// A focusable-disabled radio is not natively disabled, so detach it
|
|
261
|
+
// from the form instead: it keeps its name (grouping) but is excluded
|
|
262
|
+
// from submission, matching a natively disabled control.
|
|
263
|
+
form={keepsFocusableForMessage ? '' : undefined}
|
|
257
264
|
required={context.isRequired}
|
|
258
265
|
onChange={() => {
|
|
259
266
|
if (isDisabled) {
|
|
@@ -309,11 +316,13 @@ export function RadioListItem({
|
|
|
309
316
|
return (
|
|
310
317
|
<div
|
|
311
318
|
ref={ref}
|
|
312
|
-
data-testid={dataTestId}
|
|
313
319
|
{...mergeProps(
|
|
314
320
|
themeProps('radio-list-item'),
|
|
315
|
-
stylex.props(styles.container, !isDisabled && radioScope),
|
|
316
|
-
|
|
321
|
+
stylex.props(styles.container, !isDisabled && radioScope, xstyle),
|
|
322
|
+
className,
|
|
323
|
+
style,
|
|
324
|
+
)}
|
|
325
|
+
{...rest}>
|
|
317
326
|
<Item
|
|
318
327
|
startContent={mediaContent}
|
|
319
328
|
label={
|