@astryxdesign/core 0.4.7 → 0.5.0-canary.055e75f
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 +161 -1
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +45 -20
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +3 -2
- package/dist/AspectRatio/AspectRatio.d.ts +24 -0
- package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
- package/dist/AspectRatio/AspectRatio.js +23 -4
- package/dist/Avatar/Avatar.d.ts +25 -1
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +58 -19
- package/dist/Avatar/index.d.ts +2 -2
- package/dist/Avatar/index.d.ts.map +1 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +8 -4
- package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
- package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
- package/dist/Banner/Banner.d.ts +40 -15
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +51 -18
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +17 -4
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -6
- package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +26 -7
- package/dist/Calendar/Calendar.d.ts +3 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +14 -15
- package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
- package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
- package/dist/Calendar/getInitialFocusDate.js +62 -0
- package/dist/Calendar/styles.d.ts +5 -14
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +15 -15
- package/dist/Card/Card.d.ts +6 -9
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +6 -6
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +3 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +2 -3
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +3 -3
- package/dist/Chat/ChatMessageList.d.ts +22 -3
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +6 -3
- package/dist/Chat/ChatTokenizedText.d.ts +2 -0
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +11 -6
- package/dist/Chat/useChatComposerTokens.js +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +10 -3
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -3
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +15 -4
- package/dist/CodeBlock/highlightRanges.js +1 -1
- package/dist/CodeBlock/highlightStyles.js +13 -13
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +3 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -2
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/DateInput/DateInput.d.ts +43 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +22 -2
- package/dist/DateInput/NativeDateField.d.ts +10 -0
- package/dist/DateInput/NativeDateField.d.ts.map +1 -0
- package/dist/DateInput/NativeDateField.js +494 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +82 -23
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateInput/nativeDateSegments.d.ts +22 -0
- package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
- package/dist/DateInput/nativeDateSegments.js +111 -0
- package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +406 -12
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.d.ts +21 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +110 -58
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +9 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +3 -2
- package/dist/Heading/Heading.d.ts.map +1 -1
- package/dist/Heading/Heading.js +6 -2
- package/dist/HoverCard/HoverCard.d.ts +6 -0
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +104 -3
- package/dist/HoverCard/useHoverCard.d.ts +19 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +74 -26
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +6 -2
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -2
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +2 -19
- package/dist/Layer/LayerDepthContext.d.ts +52 -0
- package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
- package/dist/Layer/LayerDepthContext.js +66 -0
- package/dist/Layer/index.d.ts +3 -0
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +4 -0
- package/dist/Layer/layerStack.d.ts +98 -0
- package/dist/Layer/layerStack.d.ts.map +1 -0
- package/dist/Layer/layerStack.js +306 -0
- package/dist/Layer/useLayerDismissal.d.ts +93 -0
- package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
- package/dist/Layer/useLayerDismissal.js +91 -0
- package/dist/Lightbox/Lightbox.d.ts +1 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +103 -81
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +9 -4
- package/dist/Markdown/index.d.ts +1 -1
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/parser.d.ts +38 -1
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +182 -32
- package/dist/MobileNav/MobileNav.d.ts +6 -1
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +61 -36
- package/dist/MultiSelector/MultiSelector.d.ts +32 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +63 -11
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.js +5 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +3 -2
- package/dist/NumberInput/NumberInput.d.ts +6 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +54 -104
- package/dist/NumberInput/numberInputCommit.d.ts +34 -0
- package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
- package/dist/NumberInput/numberInputCommit.js +71 -0
- package/dist/NumberInput/numberParser.d.ts +64 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -0
- package/dist/NumberInput/numberParser.js +350 -0
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -2
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +3 -2
- package/dist/Overlay/Overlay.d.ts.map +1 -1
- package/dist/Overlay/Overlay.js +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +20 -17
- package/dist/PowerSearch/PowerSearch.d.ts +8 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +19 -6
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
- package/dist/PowerSearch/types.d.ts +2 -0
- package/dist/PowerSearch/types.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.js +14 -5
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +18 -5
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +3 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +3 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +3 -3
- package/dist/Selector/Selector.d.ts +17 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +81 -14
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +4 -3
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +8 -7
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +4 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +37 -5
- package/dist/Spinner/Spinner.d.ts +3 -3
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +130 -78
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +6 -1
- package/dist/Stepper/Step.d.ts +140 -0
- package/dist/Stepper/Step.d.ts.map +1 -0
- package/dist/Stepper/Step.js +1045 -0
- package/dist/Stepper/StepStatus.d.ts +24 -0
- package/dist/Stepper/StepStatus.d.ts.map +1 -0
- package/dist/Stepper/StepStatus.js +1 -0
- package/dist/Stepper/Stepper.d.ts +93 -0
- package/dist/Stepper/Stepper.d.ts.map +1 -0
- package/dist/Stepper/Stepper.js +184 -0
- package/dist/Stepper/StepperContext.d.ts +41 -0
- package/dist/Stepper/StepperContext.d.ts.map +1 -0
- package/dist/Stepper/StepperContext.js +34 -0
- package/dist/Stepper/index.d.ts +8 -0
- package/dist/Stepper/index.d.ts.map +1 -0
- package/dist/Stepper/index.js +7 -0
- package/dist/Stepper/stepper.stylex.d.ts +15 -0
- package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
- package/dist/Stepper/stepper.stylex.js +20 -0
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +8 -3
- package/dist/TabList/Tab.d.ts +15 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +32 -7
- package/dist/TabList/TabList.d.ts +46 -7
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +353 -23
- package/dist/TabList/TabListContext.d.ts +11 -1
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +11 -2
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -2
- package/dist/TabList/index.d.ts +2 -2
- package/dist/TabList/index.d.ts.map +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +10 -2
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +3 -6
- package/dist/Table/TableRow.d.ts +16 -5
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +16 -5
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
- package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
- package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +19 -5
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
- package/dist/Table/types.d.ts +22 -4
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -0
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +6 -2
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +9 -3
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +3 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +5 -3
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +27 -8
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +2 -2
- package/dist/Tokenizer/Tokenizer.d.ts +3 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +2 -0
- package/dist/Tooltip/Tooltip.d.ts +5 -0
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +5 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +39 -24
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +5 -4
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +3 -3
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -3
- package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +68 -29
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +3 -2
- package/dist/astryx.css +98 -7
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +7 -4
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +60 -95
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +3 -18
- package/dist/hooks/useMergedRefs.d.ts +18 -0
- package/dist/hooks/useMergedRefs.d.ts.map +1 -0
- package/dist/hooks/useMergedRefs.js +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +24 -4
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +5 -2
- package/dist/utils/groupItems.d.ts +5 -1
- package/dist/utils/groupItems.d.ts.map +1 -1
- package/dist/utils/groupItems.js +9 -9
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/isApplePlatform.d.ts +18 -0
- package/dist/utils/isApplePlatform.d.ts.map +1 -0
- package/dist/utils/isApplePlatform.js +37 -0
- package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
- package/dist/utils/sharedResizeObserver.js +10 -1
- package/dist/utils/timeParser.d.ts +1 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +26 -12
- package/locales/en.json +154 -10
- package/locales/pseudo.json +108 -0
- package/package.json +8 -3
- package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
- package/src/AlertDialog/AlertDialog.test.tsx +211 -2
- package/src/AlertDialog/AlertDialog.tsx +62 -20
- package/src/AppShell/AppShell.tsx +3 -2
- package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
- package/src/AspectRatio/AspectRatio.test.tsx +57 -10
- package/src/AspectRatio/AspectRatio.tsx +40 -1
- package/src/Avatar/Avatar.doc.mjs +14 -3
- package/src/Avatar/Avatar.test.tsx +97 -0
- package/src/Avatar/Avatar.tsx +125 -52
- package/src/Avatar/index.ts +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
- package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
- package/src/AvatarGroup/AvatarGroup.tsx +15 -6
- package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
- package/src/Banner/Banner.doc.mjs +13 -11
- package/src/Banner/Banner.test.tsx +102 -15
- package/src/Banner/Banner.tsx +72 -25
- package/src/BottomSheet/BottomSheet.test.tsx +123 -0
- package/src/BottomSheet/BottomSheet.tsx +17 -4
- package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
- package/src/Button/Button.doc.mjs +24 -1
- package/src/Button/Button.test.tsx +32 -4
- package/src/Button/Button.tsx +12 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
- package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
- package/src/ButtonGroup/ButtonGroup.tsx +23 -5
- package/src/Calendar/Calendar.doc.mjs +4 -3
- package/src/Calendar/Calendar.test.tsx +103 -0
- package/src/Calendar/Calendar.tsx +19 -16
- package/src/Calendar/getInitialFocusDate.test.ts +94 -0
- package/src/Calendar/getInitialFocusDate.ts +93 -0
- package/src/Calendar/styles.ts +49 -31
- package/src/Card/Card.doc.mjs +10 -7
- package/src/Card/Card.test.tsx +44 -19
- package/src/Card/Card.tsx +12 -32
- package/src/Carousel/Carousel.tsx +3 -2
- package/src/Chat/ChatComposerInput.tsx +5 -1
- package/src/Chat/ChatLayout.tsx +3 -2
- package/src/Chat/ChatMessageList.doc.mjs +9 -1
- package/src/Chat/ChatMessageList.test.tsx +46 -0
- package/src/Chat/ChatMessageList.tsx +28 -4
- package/src/Chat/ChatTokenizedText.tsx +17 -10
- package/src/Chat/useChatComposerTokens.ts +1 -1
- package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
- package/src/CheckboxInput/CheckboxInput.tsx +8 -2
- package/src/ClickableCard/ClickableCard.tsx +3 -2
- package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
- package/src/CodeBlock/CodeBlock.test.tsx +37 -0
- package/src/CodeBlock/CodeBlock.tsx +20 -4
- package/src/CodeBlock/highlightRanges.ts +1 -1
- package/src/CodeBlock/highlightStyles.ts +13 -13
- package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
- package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
- package/src/ContextMenu/ContextMenu.tsx +4 -3
- package/src/DateInput/DateInput.doc.mjs +16 -0
- package/src/DateInput/DateInput.tsx +55 -2
- package/src/DateInput/DateInputTouch.test.tsx +146 -32
- package/src/DateInput/NativeDateField.test.tsx +635 -0
- package/src/DateInput/NativeDateField.tsx +641 -0
- package/src/DateInput/TouchDateField.tsx +108 -24
- package/src/DateInput/index.ts +1 -0
- package/src/DateInput/nativeDateSegments.ts +127 -0
- package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
- package/src/DateTimeInput/DateTimeInput.tsx +556 -24
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/Dialog.doc.mjs +8 -3
- package/src/Dialog/Dialog.test.tsx +429 -2
- package/src/Dialog/Dialog.tsx +133 -58
- package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
- package/src/Field/Field.doc.mjs +13 -2
- package/src/Field/FieldLabel.test.tsx +29 -0
- package/src/Field/FieldLabel.tsx +7 -0
- package/src/FileInput/FileInput.tsx +3 -2
- package/src/Heading/Heading.test.tsx +23 -1
- package/src/Heading/Heading.tsx +6 -2
- package/src/HoverCard/HoverCard.doc.mjs +13 -2
- package/src/HoverCard/HoverCard.test.tsx +154 -4
- package/src/HoverCard/HoverCard.tsx +143 -3
- package/src/HoverCard/useHoverCard.tsx +104 -33
- package/src/Indicator/CheckboxIndicator.tsx +14 -8
- package/src/Indicator/Indicator.doc.mjs +2 -0
- package/src/Item/Item.tsx +5 -4
- package/src/Kbd/Kbd.tsx +2 -19
- package/src/Layer/LayerDepthContext.tsx +62 -0
- package/src/Layer/index.ts +9 -0
- package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
- package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
- package/src/Layer/layerStack.ts +362 -0
- package/src/Layer/useLayer.test.tsx +62 -14
- package/src/Layer/useLayerDismissal.test.tsx +469 -0
- package/src/Layer/useLayerDismissal.ts +173 -0
- package/src/Layout/Layout.doc.mjs +2 -2
- package/src/Lightbox/Lightbox.doc.mjs +12 -0
- package/src/Lightbox/Lightbox.tsx +124 -102
- package/src/Link/Link.doc.mjs +39 -0
- package/src/Markdown/Markdown.doc.mjs +5 -0
- package/src/Markdown/Markdown.tsx +9 -4
- package/src/Markdown/incremental.test.ts +16 -2
- package/src/Markdown/index.ts +1 -0
- package/src/Markdown/parser.perf.test.ts +96 -1
- package/src/Markdown/parser.test.ts +178 -2
- package/src/Markdown/parser.ts +253 -32
- package/src/MobileNav/MobileNav.tsx +62 -36
- package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
- package/src/MultiSelector/MultiSelector.test.tsx +277 -0
- package/src/MultiSelector/MultiSelector.tsx +142 -11
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavIcon/NavIcon.doc.mjs +8 -2
- package/src/NavIcon/NavIcon.test.tsx +9 -0
- package/src/NavIcon/NavIcon.tsx +5 -1
- package/src/NavMenu/NavHeadingMenu.tsx +3 -2
- package/src/NumberInput/NumberInput.doc.mjs +31 -7
- package/src/NumberInput/NumberInput.test.tsx +436 -8
- package/src/NumberInput/NumberInput.tsx +62 -114
- package/src/NumberInput/numberInputCommit.test.ts +72 -0
- package/src/NumberInput/numberInputCommit.ts +103 -0
- package/src/NumberInput/numberParser.docblock.test.ts +234 -0
- package/src/NumberInput/numberParser.test.ts +222 -0
- package/src/NumberInput/numberParser.ts +403 -0
- package/src/Outline/Outline.tsx +3 -2
- package/src/OverflowList/OverflowList.tsx +3 -2
- package/src/Overlay/Overlay.tsx +3 -2
- package/src/Pagination/Pagination.test.tsx +3 -2
- package/src/Popover/usePopover.tsx +31 -28
- package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
- package/src/PowerSearch/PowerSearch.test.tsx +240 -1
- package/src/PowerSearch/PowerSearch.tsx +34 -5
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
- package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
- package/src/PowerSearch/types.ts +2 -0
- package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
- package/src/PowerSearch/usePowerSearchSource.ts +13 -3
- package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
- package/src/ProgressBar/ProgressBar.test.tsx +24 -0
- package/src/ProgressBar/ProgressBar.tsx +28 -8
- package/src/Resizable/ResizeHandle.tsx +3 -2
- package/src/SegmentedControl/SegmentedControl.tsx +3 -2
- package/src/SelectableCard/SelectableCard.tsx +3 -2
- package/src/Selector/Selector.doc.mjs +26 -1
- package/src/Selector/Selector.test.tsx +311 -1
- package/src/Selector/Selector.tsx +139 -16
- package/src/SideNav/SideNav.doc.mjs +6 -6
- package/src/SideNav/SideNav.tsx +4 -2
- package/src/SideNav/SideNavHeading.tsx +12 -12
- package/src/SideNav/SideNavItem.tsx +4 -2
- package/src/Slider/Slider.test.tsx +106 -1
- package/src/Slider/Slider.tsx +55 -3
- package/src/Spinner/Spinner.test.tsx +147 -1
- package/src/Spinner/Spinner.tsx +120 -101
- package/src/StatusDot/StatusDot.doc.mjs +8 -2
- package/src/StatusDot/StatusDot.test.tsx +9 -0
- package/src/StatusDot/StatusDot.tsx +7 -1
- package/src/Stepper/Step.doc.mjs +98 -0
- package/src/Stepper/Step.tsx +1638 -0
- package/src/Stepper/StepStatus.ts +26 -0
- package/src/Stepper/Stepper.doc.mjs +370 -0
- package/src/Stepper/Stepper.test.tsx +1024 -0
- package/src/Stepper/Stepper.tsx +258 -0
- package/src/Stepper/StepperContext.ts +71 -0
- package/src/Stepper/index.ts +18 -0
- package/src/Stepper/stepper.stylex.ts +19 -0
- package/src/Switch/Switch.doc.mjs +2 -0
- package/src/Switch/Switch.test.tsx +10 -0
- package/src/Switch/Switch.tsx +6 -2
- package/src/TabList/Tab.doc.mjs +13 -1
- package/src/TabList/Tab.tsx +67 -7
- package/src/TabList/TabList.doc.mjs +22 -6
- package/src/TabList/TabList.test.tsx +559 -0
- package/src/TabList/TabList.tsx +490 -22
- package/src/TabList/TabListContext.ts +13 -2
- package/src/TabList/TabMenu.tsx +3 -2
- package/src/TabList/index.ts +6 -2
- package/src/Table/BaseTable.tsx +12 -4
- package/src/Table/Table.doc.mjs +9 -2
- package/src/Table/Table.test.tsx +132 -14
- package/src/Table/Table.tsx +3 -8
- package/src/Table/TableBody.doc.mjs +40 -0
- package/src/Table/TableFooter.doc.mjs +40 -0
- package/src/Table/TableHeader.doc.mjs +40 -0
- package/src/Table/TableRow.tsx +16 -5
- package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
- package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
- package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
- package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
- package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
- package/src/Table/types.ts +22 -4
- package/src/Table/useBaseTablePlugins.ts +5 -0
- package/src/Table/useTableGroupedRows.doc.mjs +5 -4
- package/src/Table/useTablePagination.doc.mjs +7 -0
- package/src/Table/useTableRowStatus.doc.mjs +1 -1
- package/src/Table/useTableSelection.doc.mjs +31 -0
- package/src/Text/Text.test.tsx +23 -1
- package/src/Text/Text.tsx +6 -2
- package/src/TextArea/TextArea.doc.mjs +8 -2
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +15 -8
- package/src/TextInput/TextInput.doc.mjs +10 -0
- package/src/TextInput/TextInput.tsx +3 -2
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.tsx +2 -2
- package/src/Timestamp/Timestamp.test.tsx +18 -0
- package/src/Timestamp/Timestamp.tsx +4 -2
- package/src/Toast/Toast.doc.mjs +6 -0
- package/src/Toast/ToastViewport.tsx +17 -1
- package/src/Token/TokenLink.tsx +2 -2
- package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
- package/src/Tokenizer/Tokenizer.tsx +4 -0
- package/src/Toolbar/Toolbar.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.test.tsx +32 -0
- package/src/Tooltip/Tooltip.tsx +5 -0
- package/src/Tooltip/useTooltip.tsx +47 -24
- package/src/TopNav/TopNavHeading.tsx +5 -4
- package/src/TopNav/TopNavMegaMenu.tsx +3 -2
- package/src/TopNav/TopNavMenu.tsx +4 -3
- package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
- package/src/Typeahead/BaseTypeahead.tsx +85 -33
- package/src/Typeahead/Typeahead.doc.mjs +5 -0
- package/src/Typeahead/Typeahead.test.tsx +49 -0
- package/src/Typeahead/Typeahead.tsx +3 -2
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useContainerReveal.doc.mjs +2 -2
- package/src/hooks/useFocusTrap.test.tsx +14 -0
- package/src/hooks/useFocusTrap.ts +62 -111
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
- package/src/hooks/useHotkeys.ts +3 -18
- package/src/hooks/useMergedRefs.doc.mjs +79 -0
- package/src/hooks/useMergedRefs.test.tsx +62 -0
- package/src/hooks/useMergedRefs.ts +36 -0
- package/src/index.ts +1 -0
- package/src/raw-import.d.ts +14 -0
- package/src/theme/MediaTheme.doc.mjs +5 -5
- package/src/theme/derivedVarRegistry.test.ts +19 -3
- package/src/theme/derivedVarRegistry.ts +23 -4
- package/src/theme/generateThemeRules.test.ts +37 -0
- package/src/theme/syntax/tokens.ts +5 -2
- package/src/utils/groupItems.ts +12 -6
- package/src/utils/index.ts +1 -1
- package/src/utils/isApplePlatform.test.ts +61 -0
- package/src/utils/isApplePlatform.ts +37 -0
- package/src/utils/sharedResizeObserver.ts +10 -2
- package/src/utils/timeParser.test.ts +6 -1
- package/src/utils/timeParser.ts +35 -13
- package/src/__tests__/inputWidthContract.test.tsx +0 -69
|
@@ -365,7 +365,94 @@ describe('HoverCard', () => {
|
|
|
365
365
|
);
|
|
366
366
|
});
|
|
367
367
|
|
|
368
|
-
it('
|
|
368
|
+
it('advertises a dialog popup on the trigger when labelled', () => {
|
|
369
|
+
render(
|
|
370
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
371
|
+
<button type="button">Trigger</button>
|
|
372
|
+
</HoverCard>,
|
|
373
|
+
);
|
|
374
|
+
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
375
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
376
|
+
// While closed, the layer is not in the DOM, so aria-controls must not
|
|
377
|
+
// point at a missing id (see DateInput). It is set once the card opens.
|
|
378
|
+
expect(trigger).not.toHaveAttribute('aria-controls');
|
|
379
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
380
|
+
expect(trigger).not.toHaveAttribute('aria-describedby');
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('merges existing popup attributes on the trigger when labelled', () => {
|
|
384
|
+
render(
|
|
385
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
386
|
+
<button
|
|
387
|
+
type="button"
|
|
388
|
+
aria-haspopup="menu"
|
|
389
|
+
aria-controls="menu-id"
|
|
390
|
+
aria-expanded="true">
|
|
391
|
+
Trigger
|
|
392
|
+
</button>
|
|
393
|
+
</HoverCard>,
|
|
394
|
+
);
|
|
395
|
+
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
396
|
+
// The hover card's dialog popup is advertised, but the trigger's own
|
|
397
|
+
// popup semantics are preserved rather than overwritten.
|
|
398
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
399
|
+
expect(trigger.getAttribute('aria-controls')).toContain('menu-id');
|
|
400
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('omits aria-expanded on a trigger whose role does not support it', () => {
|
|
404
|
+
render(
|
|
405
|
+
<HoverCard content={<span>Card content</span>} label="Timestamp details">
|
|
406
|
+
<time dateTime="2026-08-25" tabIndex={0}>
|
|
407
|
+
2 hours ago
|
|
408
|
+
</time>
|
|
409
|
+
</HoverCard>,
|
|
410
|
+
);
|
|
411
|
+
const trigger = screen.getByText('2 hours ago');
|
|
412
|
+
expect(trigger.tagName).toBe('TIME');
|
|
413
|
+
// Global attributes are valid on any element, so the popup relationship is
|
|
414
|
+
// still advertised.
|
|
415
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
416
|
+
// aria-expanded is not: <time> has no role that supports it, and emitting
|
|
417
|
+
// it is a critical axe aria-allowed-attr violation.
|
|
418
|
+
expect(trigger).not.toHaveAttribute('aria-expanded');
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
it('keeps aria-expanded on a role-less trigger that declares a supporting role', () => {
|
|
422
|
+
render(
|
|
423
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
424
|
+
<span role="button" tabIndex={0}>
|
|
425
|
+
Trigger
|
|
426
|
+
</span>
|
|
427
|
+
</HoverCard>,
|
|
428
|
+
);
|
|
429
|
+
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
430
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it('leaves a role-less trigger own aria-expanded untouched', () => {
|
|
434
|
+
render(
|
|
435
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
436
|
+
<span aria-expanded="true">Trigger</span>
|
|
437
|
+
</HoverCard>,
|
|
438
|
+
);
|
|
439
|
+
const trigger = screen.getByText('Trigger');
|
|
440
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('keeps aria-expanded on triggers whose implicit role supports it', () => {
|
|
444
|
+
render(
|
|
445
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
446
|
+
<input type="button" value="Trigger" />
|
|
447
|
+
</HoverCard>,
|
|
448
|
+
);
|
|
449
|
+
expect(screen.getByRole('button')).toHaveAttribute(
|
|
450
|
+
'aria-expanded',
|
|
451
|
+
'false',
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it('keeps aria-describedby on the trigger when no label is provided', () => {
|
|
369
456
|
render(
|
|
370
457
|
<HoverCard content={<span>Card content</span>}>
|
|
371
458
|
<button type="button">Trigger</button>
|
|
@@ -373,9 +460,10 @@ describe('HoverCard', () => {
|
|
|
373
460
|
);
|
|
374
461
|
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
375
462
|
expect(trigger).toHaveAttribute('aria-describedby');
|
|
463
|
+
expect(trigger).not.toHaveAttribute('aria-haspopup');
|
|
376
464
|
});
|
|
377
465
|
|
|
378
|
-
it('
|
|
466
|
+
it('preserves existing aria-describedby when no label is provided', () => {
|
|
379
467
|
render(
|
|
380
468
|
<HoverCard content={<span>Card content</span>}>
|
|
381
469
|
<button type="button" aria-describedby="existing-id">
|
|
@@ -388,6 +476,34 @@ describe('HoverCard', () => {
|
|
|
388
476
|
expect(describedBy).toContain('existing-id');
|
|
389
477
|
});
|
|
390
478
|
|
|
479
|
+
it('updates aria-expanded when the labelled hover card opens and closes', async () => {
|
|
480
|
+
render(
|
|
481
|
+
<HoverCard
|
|
482
|
+
content={<span>Card content</span>}
|
|
483
|
+
label="Profile actions"
|
|
484
|
+
delay={0}>
|
|
485
|
+
<button type="button">Trigger</button>
|
|
486
|
+
</HoverCard>,
|
|
487
|
+
);
|
|
488
|
+
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
489
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
490
|
+
expect(trigger).not.toHaveAttribute('aria-controls');
|
|
491
|
+
|
|
492
|
+
fireEvent.mouseEnter(trigger);
|
|
493
|
+
await waitFor(() => {
|
|
494
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
495
|
+
// The layer is in the DOM now, so aria-controls points at it.
|
|
496
|
+
expect(trigger).toHaveAttribute('aria-controls');
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
fireEvent.mouseLeave(trigger);
|
|
500
|
+
await waitFor(() => {
|
|
501
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
502
|
+
// The layer is gone from the DOM, so aria-controls is cleared.
|
|
503
|
+
expect(trigger).not.toHaveAttribute('aria-controls');
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
391
507
|
it('calls onOpenChange(true) when shown', async () => {
|
|
392
508
|
const onOpenChange = vi.fn();
|
|
393
509
|
render(
|
|
@@ -429,16 +545,33 @@ describe('HoverCard', () => {
|
|
|
429
545
|
|
|
430
546
|
it('supports text-only children with inline wrapper', () => {
|
|
431
547
|
render(
|
|
432
|
-
<HoverCard content={<span>Card content</span>}>
|
|
548
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
433
549
|
Just text, no element
|
|
434
550
|
</HoverCard>,
|
|
435
551
|
);
|
|
436
552
|
// Text should be rendered
|
|
437
553
|
expect(screen.getByText('Just text, no element')).toBeInTheDocument();
|
|
438
|
-
//
|
|
554
|
+
// When labelled, the wrapper advertises a dialog popup.
|
|
555
|
+
const wrapper = screen.getByText('Just text, no element');
|
|
556
|
+
expect(wrapper.tagName).toBe('SPAN');
|
|
557
|
+
expect(wrapper).toHaveAttribute('aria-haspopup', 'dialog');
|
|
558
|
+
// The wrapper is a role-less <span>; aria-expanded is invalid there.
|
|
559
|
+
expect(wrapper).not.toHaveAttribute('aria-expanded');
|
|
560
|
+
// While closed, the layer is not in the DOM, so aria-controls is unset.
|
|
561
|
+
expect(wrapper).not.toHaveAttribute('aria-controls');
|
|
562
|
+
expect(wrapper).not.toHaveAttribute('aria-describedby');
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it('keeps aria-describedby on text-only children when no label is provided', () => {
|
|
566
|
+
render(
|
|
567
|
+
<HoverCard content={<span>Card content</span>}>
|
|
568
|
+
Just text, no element
|
|
569
|
+
</HoverCard>,
|
|
570
|
+
);
|
|
439
571
|
const wrapper = screen.getByText('Just text, no element');
|
|
440
572
|
expect(wrapper.tagName).toBe('SPAN');
|
|
441
573
|
expect(wrapper).toHaveAttribute('aria-describedby');
|
|
574
|
+
expect(wrapper).not.toHaveAttribute('aria-haspopup');
|
|
442
575
|
});
|
|
443
576
|
|
|
444
577
|
describe('isDefaultOpen', () => {
|
|
@@ -994,3 +1127,20 @@ describe('HoverCard', () => {
|
|
|
994
1127
|
});
|
|
995
1128
|
});
|
|
996
1129
|
});
|
|
1130
|
+
|
|
1131
|
+
describe('HoverCard theme target names', () => {
|
|
1132
|
+
it('renders the deprecated class beside the current one on the card surface', async () => {
|
|
1133
|
+
render(
|
|
1134
|
+
<HoverCard content={<span>Card content</span>} delay={0}>
|
|
1135
|
+
<button type="button">Trigger</button>
|
|
1136
|
+
</HoverCard>,
|
|
1137
|
+
);
|
|
1138
|
+
fireEvent.mouseEnter(screen.getByRole('button', {name: 'Trigger'}));
|
|
1139
|
+
|
|
1140
|
+
await waitFor(() => {
|
|
1141
|
+
const layer = screen.getByText('Card content').closest('[popover]');
|
|
1142
|
+
expect(layer).toHaveClass('astryx-hover-card');
|
|
1143
|
+
expect(layer).toHaveClass('astryx-hovercard');
|
|
1144
|
+
});
|
|
1145
|
+
});
|
|
1146
|
+
});
|
|
@@ -32,6 +32,66 @@ export type {
|
|
|
32
32
|
HoverCardTouchTrigger,
|
|
33
33
|
} from './useHoverCard';
|
|
34
34
|
|
|
35
|
+
// `aria-haspopup` and `aria-controls` are global, so any trigger may carry
|
|
36
|
+
// them. `aria-expanded` is not. This is the ARIA 1.2 "Supported States and
|
|
37
|
+
// Properties" list for it — deliberately the narrow reading: axe accepts the
|
|
38
|
+
// attribute on rather more roles, since it also allows every subclass of these,
|
|
39
|
+
// so a role outside this set is not necessarily a violation. Widening it is
|
|
40
|
+
// safe; the set is a floor, not the spec's ceiling. The same rule is applied in
|
|
41
|
+
// Chat/useTriggerMenu.tsx, which only emits the combobox attributes once the
|
|
42
|
+
// element is actually a combobox.
|
|
43
|
+
const EXPANDABLE_ROLES = new Set([
|
|
44
|
+
'application',
|
|
45
|
+
'button',
|
|
46
|
+
'checkbox',
|
|
47
|
+
'columnheader',
|
|
48
|
+
'combobox',
|
|
49
|
+
'gridcell',
|
|
50
|
+
'link',
|
|
51
|
+
'listbox',
|
|
52
|
+
'menuitem',
|
|
53
|
+
'menuitemcheckbox',
|
|
54
|
+
'menuitemradio',
|
|
55
|
+
'row',
|
|
56
|
+
'rowheader',
|
|
57
|
+
'switch',
|
|
58
|
+
'tab',
|
|
59
|
+
'treeitem',
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
const BUTTON_INPUT_TYPES = new Set(['button', 'submit', 'reset', 'image']);
|
|
63
|
+
|
|
64
|
+
// Deliberately partial, and unlisted elements are read as role-less: dropping
|
|
65
|
+
// aria-expanded where it might have been legal costs an AT user a state they
|
|
66
|
+
// can still infer, whereas emitting it where it is illegal is a critical
|
|
67
|
+
// aria-allowed-attr defect.
|
|
68
|
+
function supportsAriaExpanded(el: HTMLElement): boolean {
|
|
69
|
+
const explicit = el.getAttribute('role')?.trim().split(/\s+/)[0];
|
|
70
|
+
if (explicit) {
|
|
71
|
+
return EXPANDABLE_ROLES.has(explicit);
|
|
72
|
+
}
|
|
73
|
+
switch (el.tagName) {
|
|
74
|
+
case 'BUTTON':
|
|
75
|
+
case 'SUMMARY':
|
|
76
|
+
return true;
|
|
77
|
+
case 'A':
|
|
78
|
+
case 'AREA':
|
|
79
|
+
return el.hasAttribute('href');
|
|
80
|
+
case 'INPUT':
|
|
81
|
+
// The button-flavoured input types map to role="button"; every other
|
|
82
|
+
// type maps to a textbox-family role, which does not take it.
|
|
83
|
+
return BUTTON_INPUT_TYPES.has(
|
|
84
|
+
(el as HTMLInputElement).type?.toLowerCase(),
|
|
85
|
+
);
|
|
86
|
+
case 'SELECT':
|
|
87
|
+
// combobox when it is a single-line picker, listbox otherwise; both
|
|
88
|
+
// support aria-expanded.
|
|
89
|
+
return true;
|
|
90
|
+
default:
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
35
95
|
const styles = stylex.create({
|
|
36
96
|
wrapperContents: {
|
|
37
97
|
display: 'contents',
|
|
@@ -144,6 +204,12 @@ export interface HoverCardProps extends Pick<
|
|
|
144
204
|
* - `true`: force-show the hover card (hover/focus hide is suppressed)
|
|
145
205
|
* - `false`: force-hide the hover card
|
|
146
206
|
* - `undefined`: uncontrolled — hover/focus triggers manage visibility
|
|
207
|
+
*
|
|
208
|
+
* A controlled hover card still takes Escape when it is the top-most layer,
|
|
209
|
+
* and answers by calling `onOpenChange(false)` without hiding itself —
|
|
210
|
+
* closing is your update's decision, exactly as for a controlled Dialog.
|
|
211
|
+
* Ignore the call and the card stays, and so does the press: nothing
|
|
212
|
+
* underneath dismisses.
|
|
147
213
|
*/
|
|
148
214
|
isOpen?: boolean;
|
|
149
215
|
|
|
@@ -253,7 +319,70 @@ export function HoverCard({
|
|
|
253
319
|
// Use combined ref for position + interaction
|
|
254
320
|
hoverCard.ref(firstChild);
|
|
255
321
|
|
|
256
|
-
|
|
322
|
+
if (label) {
|
|
323
|
+
// When named, the hover card is a dialog. The trigger should advertise the
|
|
324
|
+
// popup relationship with aria-haspopup/aria-expanded, not describe the
|
|
325
|
+
// trigger with the dialog's content (aria-describedby is for plain-text
|
|
326
|
+
// descriptions, not navigable regions). See #5049.
|
|
327
|
+
//
|
|
328
|
+
// aria-expanded only goes on a trigger whose role permits it. A role-less
|
|
329
|
+
// trigger (Timestamp's <time>/<span>) gets haspopup + controls, which are
|
|
330
|
+
// global, and no expanded state.
|
|
331
|
+
//
|
|
332
|
+
// Merge rather than overwrite: the trigger may already carry its own
|
|
333
|
+
// popup semantics (e.g. a menu button wrapped in a labelled HoverCard),
|
|
334
|
+
// so preserve the existing values and restore them on cleanup.
|
|
335
|
+
const existingHaspopup = firstChild.getAttribute('aria-haspopup');
|
|
336
|
+
const existingControls = firstChild.getAttribute('aria-controls');
|
|
337
|
+
const existingExpanded = firstChild.getAttribute('aria-expanded');
|
|
338
|
+
const canExpand = supportsAriaExpanded(firstChild);
|
|
339
|
+
|
|
340
|
+
firstChild.setAttribute('aria-haspopup', 'dialog');
|
|
341
|
+
// Only point aria-controls at the layer while it is open and in the DOM.
|
|
342
|
+
// While closed, useLayer leaves only an inert <template> marker, so the
|
|
343
|
+
// id would reference nothing. DateInput gates it the same way. The
|
|
344
|
+
// trigger's own aria-controls (if any) is preserved either way.
|
|
345
|
+
if (hoverCard.isOpen) {
|
|
346
|
+
firstChild.setAttribute(
|
|
347
|
+
'aria-controls',
|
|
348
|
+
mergeIds(existingControls, hoverCard.id) ?? '',
|
|
349
|
+
);
|
|
350
|
+
} else if (existingControls) {
|
|
351
|
+
firstChild.setAttribute('aria-controls', existingControls);
|
|
352
|
+
} else {
|
|
353
|
+
firstChild.removeAttribute('aria-controls');
|
|
354
|
+
}
|
|
355
|
+
if (canExpand) {
|
|
356
|
+
firstChild.setAttribute('aria-expanded', String(hoverCard.isOpen));
|
|
357
|
+
} else if (existingExpanded) {
|
|
358
|
+
firstChild.setAttribute('aria-expanded', existingExpanded);
|
|
359
|
+
} else {
|
|
360
|
+
firstChild.removeAttribute('aria-expanded');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return () => {
|
|
364
|
+
hoverCard.ref(null);
|
|
365
|
+
if (existingHaspopup) {
|
|
366
|
+
firstChild.setAttribute('aria-haspopup', existingHaspopup);
|
|
367
|
+
} else {
|
|
368
|
+
firstChild.removeAttribute('aria-haspopup');
|
|
369
|
+
}
|
|
370
|
+
if (existingControls) {
|
|
371
|
+
firstChild.setAttribute('aria-controls', existingControls);
|
|
372
|
+
} else {
|
|
373
|
+
firstChild.removeAttribute('aria-controls');
|
|
374
|
+
}
|
|
375
|
+
if (existingExpanded) {
|
|
376
|
+
firstChild.setAttribute('aria-expanded', existingExpanded);
|
|
377
|
+
} else {
|
|
378
|
+
firstChild.removeAttribute('aria-expanded');
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Unnamed fallback: the popup remains role="group", which is not a dialog,
|
|
384
|
+
// so keep the previous description relationship until a naming decision is
|
|
385
|
+
// made for the no-label case (tracked in #5049).
|
|
257
386
|
const existingDescribedBy = firstChild.getAttribute('aria-describedby');
|
|
258
387
|
firstChild.setAttribute(
|
|
259
388
|
'aria-describedby',
|
|
@@ -268,7 +397,14 @@ export function HoverCard({
|
|
|
268
397
|
firstChild.removeAttribute('aria-describedby');
|
|
269
398
|
}
|
|
270
399
|
};
|
|
271
|
-
}, [
|
|
400
|
+
}, [
|
|
401
|
+
textOnly,
|
|
402
|
+
label,
|
|
403
|
+
hoverCard.ref,
|
|
404
|
+
hoverCard.id,
|
|
405
|
+
hoverCard.isOpen,
|
|
406
|
+
hoverCard.describedBy,
|
|
407
|
+
]);
|
|
272
408
|
|
|
273
409
|
// While closed, useLayer leaves only an inert <template> marker at this JSX
|
|
274
410
|
// position. When the card needs to open, it uses that marker to keep the
|
|
@@ -287,7 +423,11 @@ export function HoverCard({
|
|
|
287
423
|
<span
|
|
288
424
|
ref={hoverCard.ref}
|
|
289
425
|
tabIndex={0}
|
|
290
|
-
aria-
|
|
426
|
+
aria-haspopup={label ? 'dialog' : undefined}
|
|
427
|
+
aria-controls={label && hoverCard.isOpen ? hoverCard.id : undefined}
|
|
428
|
+
// No aria-expanded: this wrapper is a role-less <span>, and
|
|
429
|
+
// aria-expanded is invalid on it (see EXPANDABLE_ROLES above).
|
|
430
|
+
aria-describedby={label ? undefined : hoverCard.describedBy}
|
|
291
431
|
{...stylex.props(
|
|
292
432
|
styles.wrapperInline,
|
|
293
433
|
showHoverIndication && styles.hoverIndication,
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
type LayerTouchTrigger,
|
|
32
32
|
} from '../Layer/useTouchTrigger';
|
|
33
33
|
import {layerAnimations} from '../Layer/layerAnimations.stylex';
|
|
34
|
+
import {useLayerDismissal} from '../Layer/useLayerDismissal';
|
|
34
35
|
import {
|
|
35
36
|
colorVars,
|
|
36
37
|
shadowVars,
|
|
@@ -135,6 +136,11 @@ export interface HoverCardOptions {
|
|
|
135
136
|
* - `true`: force-show the hover card (hover/focus hide is suppressed)
|
|
136
137
|
* - `false`: force-hide the hover card
|
|
137
138
|
* - `undefined`: uncontrolled — hover/focus triggers manage visibility
|
|
139
|
+
*
|
|
140
|
+
* A controlled hover card still takes Escape when it is the top-most layer,
|
|
141
|
+
* and answers by calling `onHide` without hiding itself — closing is your
|
|
142
|
+
* update's decision, exactly as for a controlled Dialog. Ignore the call and
|
|
143
|
+
* the card stays, and so does the press: nothing underneath dismisses.
|
|
138
144
|
*/
|
|
139
145
|
isOpen?: boolean;
|
|
140
146
|
|
|
@@ -184,11 +190,25 @@ export interface HoverCardReturn {
|
|
|
184
190
|
anchorId: string;
|
|
185
191
|
|
|
186
192
|
/**
|
|
187
|
-
* ID for
|
|
188
|
-
*
|
|
193
|
+
* Unique ID for the hover card container.
|
|
194
|
+
* Useful for `aria-controls` or `aria-owns` on the trigger.
|
|
195
|
+
*/
|
|
196
|
+
id: string;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Deprecated alias of `id`. Kept for backwards compatibility; prefer `id`.
|
|
189
200
|
*/
|
|
190
201
|
describedBy: string;
|
|
191
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Whether the hover card is currently open.
|
|
205
|
+
* Useful for driving `aria-expanded` on the trigger — but only when the
|
|
206
|
+
* trigger's role permits it (`button`, `link`, `combobox`, …). On a role-less
|
|
207
|
+
* trigger `aria-expanded` is invalid; use `aria-haspopup`/`aria-controls`
|
|
208
|
+
* alone there.
|
|
209
|
+
*/
|
|
210
|
+
isOpen: boolean;
|
|
211
|
+
|
|
192
212
|
/**
|
|
193
213
|
* Render function for hover card content.
|
|
194
214
|
* Returns anchor-positioned popover element.
|
|
@@ -409,19 +429,71 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
409
429
|
[layer.id, scheduleHide],
|
|
410
430
|
);
|
|
411
431
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
432
|
+
// Escape dismissal (WCAG 1.4.13) goes through the shared layer stack: a
|
|
433
|
+
// visible card is the top-most layer, so it takes the press and consumes it.
|
|
434
|
+
//
|
|
435
|
+
// This replaces a keydown listener on the TRIGGER that called
|
|
436
|
+
// stopPropagation() on any Escape while the trigger merely had focus — open
|
|
437
|
+
// card or not — so focusing a HoverCard trigger inside a Dialog silently ate
|
|
438
|
+
// the press that should have closed the Dialog. Presence is now answered from
|
|
439
|
+
// the DOM, so a closed card never claims a press.
|
|
440
|
+
// A controlled hover card stays on the stack and takes the press like any
|
|
441
|
+
// other layer, but answers it by reporting instead of hiding: `isOpen` is
|
|
442
|
+
// the consumer's value, so only their update may change it. Same contract as
|
|
443
|
+
// a controlled Dialog.
|
|
444
|
+
useLayerDismissal({
|
|
445
|
+
// Registered for the hook's lifetime rather than gated on `layer.isOpen`:
|
|
446
|
+
// that state can lag a frame behind the DOM, so a press arriving right after
|
|
447
|
+
// the layer appears would find nothing registered. Because this layer
|
|
448
|
+
// CONSUMES the press, a stale registration would be worse than a missed one
|
|
449
|
+
// — it would silently eat Escapes meant for the dialog underneath — so
|
|
450
|
+
// presence is answered from the DOM at press time instead of from state.
|
|
451
|
+
isActive: true,
|
|
452
|
+
isPresent: () => {
|
|
453
|
+
const el =
|
|
454
|
+
typeof document === 'undefined'
|
|
455
|
+
? null
|
|
456
|
+
: document.getElementById(layer.id);
|
|
457
|
+
if (el == null) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
return el.matches(':popover-open');
|
|
462
|
+
} catch {
|
|
463
|
+
// Browsers without the Popover API (and some test environments) cannot
|
|
464
|
+
// answer the selector; fall back to the hook's own state.
|
|
465
|
+
return layer.isOpen;
|
|
421
466
|
}
|
|
422
467
|
},
|
|
423
|
-
|
|
424
|
-
|
|
468
|
+
onDismiss: () => {
|
|
469
|
+
clearTimeouts();
|
|
470
|
+
touch.clearTapOpen();
|
|
471
|
+
// Controlled: report and stop. The close — and the focus restore that
|
|
472
|
+
// goes with it — happens in the controlled effect if and when the
|
|
473
|
+
// consumer flips `isOpen`.
|
|
474
|
+
if (isOpen !== undefined) {
|
|
475
|
+
onHide?.();
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
// Only when the card itself held focus, which is the one case the
|
|
479
|
+
// content-level handler this replaced could run in. Refocusing
|
|
480
|
+
// unconditionally would drag the caret out of a field the user was
|
|
481
|
+
// typing in while a hover card happened to be up; arming the re-show
|
|
482
|
+
// guard unconditionally would swallow their next focus on the trigger,
|
|
483
|
+
// because a focus() on the already-focused trigger fires no focusin to
|
|
484
|
+
// clear it.
|
|
485
|
+
const card =
|
|
486
|
+
typeof document === 'undefined'
|
|
487
|
+
? null
|
|
488
|
+
: document.getElementById(layer.id);
|
|
489
|
+
const hadFocus = card?.contains(document.activeElement) ?? false;
|
|
490
|
+
layer.hide();
|
|
491
|
+
if (hadFocus) {
|
|
492
|
+
isEscapeDismissingRef.current = true;
|
|
493
|
+
triggerRef.current?.focus();
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
});
|
|
425
497
|
|
|
426
498
|
// Interaction ref that handles event listeners only
|
|
427
499
|
const {handlePointerEnter} = touch;
|
|
@@ -436,7 +508,6 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
436
508
|
'focusout',
|
|
437
509
|
handleFocusOut as EventListener,
|
|
438
510
|
);
|
|
439
|
-
triggerRef.current.removeEventListener('keydown', handleKeyDown);
|
|
440
511
|
triggerRef.current.removeEventListener(
|
|
441
512
|
'pointerenter',
|
|
442
513
|
handlePointerEnter,
|
|
@@ -465,9 +536,6 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
465
536
|
el.addEventListener('focusin', handleFocusIn);
|
|
466
537
|
el.addEventListener('focusout', handleFocusOut as EventListener);
|
|
467
538
|
}
|
|
468
|
-
|
|
469
|
-
// Attach keydown for Escape handling
|
|
470
|
-
el.addEventListener('keydown', handleKeyDown);
|
|
471
539
|
}
|
|
472
540
|
|
|
473
541
|
triggerRef.current = el;
|
|
@@ -478,7 +546,6 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
478
546
|
handleMouseLeave,
|
|
479
547
|
handleFocusIn,
|
|
480
548
|
handleFocusOut,
|
|
481
|
-
handleKeyDown,
|
|
482
549
|
handlePointerEnter,
|
|
483
550
|
handlePointerDown,
|
|
484
551
|
],
|
|
@@ -518,7 +585,19 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
518
585
|
layer.show();
|
|
519
586
|
} else {
|
|
520
587
|
clearTimeouts();
|
|
588
|
+
// A consumer closing the card while it holds focus would strand focus on
|
|
589
|
+
// <body>. Arming the re-show guard is what keeps the refocus from
|
|
590
|
+
// reopening the card through `handleFocusIn`, which shows on any focusin.
|
|
591
|
+
const card =
|
|
592
|
+
typeof document === 'undefined'
|
|
593
|
+
? null
|
|
594
|
+
: document.getElementById(layer.id);
|
|
595
|
+
const hadFocus = card?.contains(document.activeElement) ?? false;
|
|
521
596
|
layer.hide();
|
|
597
|
+
if (hadFocus) {
|
|
598
|
+
isEscapeDismissingRef.current = true;
|
|
599
|
+
triggerRef.current?.focus();
|
|
600
|
+
}
|
|
522
601
|
}
|
|
523
602
|
}, [isOpen, clearTimeouts, layer]);
|
|
524
603
|
|
|
@@ -529,7 +608,11 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
529
608
|
props?: Omit<ContextRenderProps, 'positioning'>,
|
|
530
609
|
): ReactNode => {
|
|
531
610
|
const renderPlacement = props?.placement ?? placement;
|
|
532
|
-
const themeClassName = themeProps('
|
|
611
|
+
const themeClassName = themeProps('hover-card', undefined, {
|
|
612
|
+
// `hovercard` ran the compound name together; themes styling it keep
|
|
613
|
+
// working until the next major.
|
|
614
|
+
legacyNames: ['hovercard'],
|
|
615
|
+
}).className;
|
|
533
616
|
const renderProps = {
|
|
534
617
|
placement: renderPlacement,
|
|
535
618
|
alignment: props?.alignment ?? alignment,
|
|
@@ -576,20 +659,6 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
576
659
|
isHoveringContentRef.current = false;
|
|
577
660
|
scheduleHide();
|
|
578
661
|
}}
|
|
579
|
-
onKeyDown={e => {
|
|
580
|
-
if (e.key === 'Escape') {
|
|
581
|
-
// Stop propagation so parent components don't react to the same Escape
|
|
582
|
-
e.stopPropagation();
|
|
583
|
-
// Set flag to prevent re-show when we refocus trigger
|
|
584
|
-
isEscapeDismissingRef.current = true;
|
|
585
|
-
// Hide immediately
|
|
586
|
-
clearTimeouts();
|
|
587
|
-
touch.clearTapOpen();
|
|
588
|
-
layer.hide();
|
|
589
|
-
// Refocus the trigger
|
|
590
|
-
triggerRef.current?.focus();
|
|
591
|
-
}
|
|
592
|
-
}}
|
|
593
662
|
onBlur={e => {
|
|
594
663
|
// Check if focus is moving back to the trigger or staying within content
|
|
595
664
|
const relatedTarget = e.relatedTarget as HTMLElement | null;
|
|
@@ -630,7 +699,9 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
630
699
|
positionRef: layer.ref,
|
|
631
700
|
interactionRef,
|
|
632
701
|
anchorId: layer.anchorId,
|
|
702
|
+
id: layer.id,
|
|
633
703
|
describedBy: layer.id,
|
|
704
|
+
isOpen: layer.isOpen,
|
|
634
705
|
renderHoverCard,
|
|
635
706
|
show: layer.show,
|
|
636
707
|
hide: layer.hide,
|
|
@@ -227,10 +227,13 @@ export function CheckboxIndicator({
|
|
|
227
227
|
<>
|
|
228
228
|
<svg
|
|
229
229
|
viewBox="0 0 10 10"
|
|
230
|
-
{...
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
{...mergeProps(
|
|
231
|
+
themeProps('checkbox-indicator-check', {size}),
|
|
232
|
+
stylex.props(
|
|
233
|
+
styles.checkmark,
|
|
234
|
+
checkmarkSizeStyles[size],
|
|
235
|
+
isChecked && styles.checkmarkVisible,
|
|
236
|
+
),
|
|
234
237
|
)}>
|
|
235
238
|
<path
|
|
236
239
|
d="M8.5 2.5L4 7.5L1.5 5"
|
|
@@ -242,10 +245,13 @@ export function CheckboxIndicator({
|
|
|
242
245
|
/>
|
|
243
246
|
</svg>
|
|
244
247
|
<span
|
|
245
|
-
{...
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
{...mergeProps(
|
|
249
|
+
themeProps('checkbox-indicator-dash', {size}),
|
|
250
|
+
stylex.props(
|
|
251
|
+
styles.indeterminateMark,
|
|
252
|
+
indeterminateSizeStyles[size],
|
|
253
|
+
isIndeterminate && styles.indeterminateMarkVisible,
|
|
254
|
+
),
|
|
249
255
|
)}
|
|
250
256
|
/>
|
|
251
257
|
</>
|
|
@@ -132,6 +132,8 @@ export const docs = {
|
|
|
132
132
|
visualProps: ['size'],
|
|
133
133
|
states: ['checked', 'disabled'],
|
|
134
134
|
},
|
|
135
|
+
{className: 'astryx-checkbox-indicator-check', visualProps: ['size']},
|
|
136
|
+
{className: 'astryx-checkbox-indicator-dash', visualProps: ['size']},
|
|
135
137
|
{
|
|
136
138
|
className: 'astryx-radio-indicator',
|
|
137
139
|
visualProps: ['size'],
|
package/src/Item/Item.tsx
CHANGED
|
@@ -27,7 +27,8 @@ import {
|
|
|
27
27
|
typeScaleVars,
|
|
28
28
|
} from '../theme/tokens.stylex';
|
|
29
29
|
import type {BaseProps} from '../BaseProps';
|
|
30
|
-
import {mergeProps
|
|
30
|
+
import {mergeProps} from '../utils';
|
|
31
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
31
32
|
import {computeTargetAndRel} from '../Link/computeTargetAndRel';
|
|
32
33
|
import {useLinkComponent} from '../Link/useLinkComponent';
|
|
33
34
|
import {useClickableContainer} from '../hooks/useClickableContainer';
|
|
@@ -579,11 +580,11 @@ export function Item({
|
|
|
579
580
|
</>
|
|
580
581
|
);
|
|
581
582
|
|
|
583
|
+
const mergedRef = useMergedRefs(ref, containerRef);
|
|
584
|
+
|
|
582
585
|
return (
|
|
583
586
|
<Component
|
|
584
|
-
ref={
|
|
585
|
-
(isDelegate ? mergeRefs(ref, containerRef) : ref) as React.Ref<never>
|
|
586
|
-
}
|
|
587
|
+
ref={(isDelegate ? mergedRef : ref) as React.Ref<never>}
|
|
587
588
|
{...restProps}
|
|
588
589
|
aria-selected={(allowsAriaSelected && isSelected) || undefined}
|
|
589
590
|
// aria-selected is invalid on roles that don't permit it (listitem, a
|