@astryxdesign/core 0.4.7 → 0.5.0-canary.32a62fd
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/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 +5 -4
- 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 +13 -14
- 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/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 +477 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +38 -4
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- 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 +7 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +89 -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 +52 -3
- package/dist/HoverCard/useHoverCard.d.ts +16 -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/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 +177 -29
- 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 +15 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +17 -6
- 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 +1 -0
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +27 -37
- package/dist/NumberInput/numberParser.d.ts +43 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -0
- package/dist/NumberInput/numberParser.js +293 -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 +19 -9
- 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.map +1 -1
- package/dist/Selector/Selector.js +5 -0
- 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 +3 -3
- 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/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/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 +94 -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 +31 -7
- package/locales/pseudo.json +18 -0
- package/package.json +8 -3
- 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 +22 -0
- package/src/Button/Button.test.tsx +13 -0
- package/src/Button/Button.tsx +5 -4
- package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
- package/src/ButtonGroup/ButtonGroup.test.tsx +391 -1
- package/src/ButtonGroup/ButtonGroup.tsx +23 -5
- package/src/Calendar/Calendar.doc.mjs +4 -3
- package/src/Calendar/Calendar.test.tsx +52 -0
- package/src/Calendar/Calendar.tsx +18 -15
- package/src/Calendar/getInitialFocusDate.test.ts +94 -0
- package/src/Calendar/getInitialFocusDate.ts +93 -0
- 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 +68 -9
- package/src/DateInput/NativeDateField.test.tsx +565 -0
- package/src/DateInput/NativeDateField.tsx +623 -0
- package/src/DateInput/TouchDateField.tsx +38 -4
- package/src/DateInput/index.ts +1 -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 +261 -1
- package/src/Dialog/Dialog.tsx +109 -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 +101 -4
- package/src/HoverCard/HoverCard.tsx +71 -3
- package/src/HoverCard/useHoverCard.tsx +101 -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/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/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 +145 -2
- package/src/Markdown/parser.ts +244 -29
- package/src/MobileNav/MobileNav.tsx +62 -36
- package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +27 -0
- package/src/MultiSelector/MultiSelector.test.tsx +106 -0
- package/src/MultiSelector/MultiSelector.tsx +50 -6
- 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 +20 -0
- package/src/NumberInput/NumberInput.tsx +28 -29
- package/src/NumberInput/numberParser.test.ts +137 -0
- package/src/NumberInput/numberParser.ts +346 -0
- package/src/Outline/Outline.tsx +3 -2
- package/src/OverflowList/OverflowList.tsx +3 -2
- package/src/Overlay/Overlay.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 +201 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +47 -1
- package/src/PowerSearch/PowerSearchValueEditor.tsx +15 -0
- 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 +12 -1
- package/src/Selector/Selector.test.tsx +45 -1
- package/src/Selector/Selector.tsx +11 -1
- 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.tsx +3 -2
- 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/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.tsx +4 -2
- package/src/Toast/Toast.doc.mjs +6 -0
- 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/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
|
@@ -476,20 +476,17 @@ export function DropdownMenuSubMenu(
|
|
|
476
476
|
);
|
|
477
477
|
|
|
478
478
|
const endAffordance = hasSpinner ? (
|
|
479
|
-
<span
|
|
480
|
-
{...mergeProps(
|
|
481
|
-
themeProps('dropdown-menu-indicator-icon'),
|
|
482
|
-
stylex.props(triggerStyles.caret),
|
|
483
|
-
)}>
|
|
479
|
+
<span {...stylex.props(triggerStyles.caret)}>
|
|
484
480
|
<Spinner size="sm" />
|
|
485
481
|
</span>
|
|
486
482
|
) : (
|
|
487
|
-
<span
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
483
|
+
<span {...stylex.props(triggerStyles.caret)}>
|
|
484
|
+
<Icon
|
|
485
|
+
icon="chevronRight"
|
|
486
|
+
size="sm"
|
|
487
|
+
color="secondary"
|
|
488
|
+
{...themeProps('dropdown-menu-indicator-icon')}
|
|
489
|
+
/>
|
|
493
490
|
</span>
|
|
494
491
|
);
|
|
495
492
|
|
package/src/Field/Field.doc.mjs
CHANGED
|
@@ -39,8 +39,8 @@ export const docs = {
|
|
|
39
39
|
],
|
|
40
40
|
vars: [
|
|
41
41
|
{name: '--_field-radius', description: 'Border radius of input fields', default: 'var(--radius-element)', private: true},
|
|
42
|
-
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\
|
|
43
|
-
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\
|
|
42
|
+
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\'s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
|
|
43
|
+
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\'s invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `""` on a coarse one, where the overlay provides the 24px touch target.', default: 'none', private: true},
|
|
44
44
|
],
|
|
45
45
|
derived: [
|
|
46
46
|
{property: 'borderRadius', vars: ['--_field-radius']},
|
|
@@ -60,6 +60,17 @@ export const docs = {
|
|
|
60
60
|
description: 'ID for the input element (used for the label htmlFor attribute).',
|
|
61
61
|
required: true,
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
name: 'labelID',
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'ID applied to the label element itself for group accessibility.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'isGroupLabel',
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
description: 'Renders the label as a span for control groups (radiogroup, checkbox list).',
|
|
72
|
+
default: 'false',
|
|
73
|
+
},
|
|
63
74
|
{
|
|
64
75
|
name: 'children',
|
|
65
76
|
type: 'ReactNode',
|
|
@@ -15,6 +15,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
15
15
|
import {TestIcon} from '../__tests__/TestIcon';
|
|
16
16
|
import {InternationalizationProvider} from '../i18n';
|
|
17
17
|
import {FieldLabel} from './FieldLabel';
|
|
18
|
+
import {themeProps} from '../utils/themeProps';
|
|
18
19
|
|
|
19
20
|
describe('FieldLabel', () => {
|
|
20
21
|
it('renders label text', () => {
|
|
@@ -197,4 +198,32 @@ describe('FieldLabel', () => {
|
|
|
197
198
|
expect(description.closest('label')).toBeNull();
|
|
198
199
|
});
|
|
199
200
|
});
|
|
201
|
+
|
|
202
|
+
describe('a control can name its own label target', () => {
|
|
203
|
+
it('composes a passed target onto the field-label one', () => {
|
|
204
|
+
// How CheckboxInput and Switch reach their label: the control spreads
|
|
205
|
+
// its own themeProps in, and both classes end up on the same element,
|
|
206
|
+
// so a theme can style every label or just this kind.
|
|
207
|
+
render(
|
|
208
|
+
<FieldLabel
|
|
209
|
+
{...themeProps('checkbox-label')}
|
|
210
|
+
label="Notify me"
|
|
211
|
+
inputID="notify-input"
|
|
212
|
+
/>,
|
|
213
|
+
);
|
|
214
|
+
const label = screen.getByText('Notify me').closest('label');
|
|
215
|
+
expect(label).toHaveClass('astryx-field-label');
|
|
216
|
+
expect(label).toHaveClass('astryx-checkbox-label');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('describes no placement of its own', () => {
|
|
220
|
+
// The label cannot know how its caller arranged it, so it says nothing:
|
|
221
|
+
// a `data-layout` here would be a claim that is wrong for at least one
|
|
222
|
+
// caller (Field's horizontal-labels puts a label beside its control),
|
|
223
|
+
// and a consumer could set it untruthfully.
|
|
224
|
+
render(<FieldLabel label="Email" inputID="email-input" />);
|
|
225
|
+
const label = screen.getByText('Email').closest('label');
|
|
226
|
+
expect(label).not.toHaveAttribute('data-layout');
|
|
227
|
+
});
|
|
228
|
+
});
|
|
200
229
|
});
|
package/src/Field/FieldLabel.tsx
CHANGED
|
@@ -285,6 +285,13 @@ export function FieldLabel({
|
|
|
285
285
|
htmlFor={isGroupLabel ? undefined : inputID}
|
|
286
286
|
{...rest}
|
|
287
287
|
{...mergeProps(
|
|
288
|
+
// A control that knows what kind of label this is passes its own
|
|
289
|
+
// target down (CheckboxInput's `checkbox-label`, Switch's
|
|
290
|
+
// `switch-label`); it arrives as `className` and composes onto this
|
|
291
|
+
// one. The label itself does not describe its own placement — it
|
|
292
|
+
// cannot know it, and any encoding it guessed would be wrong for a
|
|
293
|
+
// caller that arranges labels differently (Field's
|
|
294
|
+
// `horizontal-labels`).
|
|
288
295
|
themeProps('field-label'),
|
|
289
296
|
stylex.props(
|
|
290
297
|
styles.label,
|
|
@@ -54,13 +54,14 @@ export type {
|
|
|
54
54
|
InputStatus as FileInputStatus,
|
|
55
55
|
InputStatusType as FileInputStatusType,
|
|
56
56
|
} from '../Field';
|
|
57
|
-
import {mergeProps
|
|
57
|
+
import {mergeProps} from '../utils';
|
|
58
58
|
import type {BaseProps} from '../BaseProps';
|
|
59
59
|
import type {SizeValue} from '../utils/types';
|
|
60
60
|
import {themeProps} from '../utils/themeProps';
|
|
61
61
|
import {useTranslator} from '../i18n';
|
|
62
62
|
import type {TranslatorFn} from '../i18n';
|
|
63
63
|
|
|
64
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
64
65
|
function formatFileSize(bytes: number): string {
|
|
65
66
|
if (bytes < 1024) {
|
|
66
67
|
return `${bytes} B`;
|
|
@@ -827,7 +828,7 @@ export function FileInput({
|
|
|
827
828
|
</VisuallyHidden>
|
|
828
829
|
<input
|
|
829
830
|
{...rest}
|
|
830
|
-
ref={
|
|
831
|
+
ref={useMergedRefs(ref, inputRef)}
|
|
831
832
|
id={id}
|
|
832
833
|
type="file"
|
|
833
834
|
accept={accept}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {render, screen} from '@testing-library/react';
|
|
9
|
-
import {describe, it, expect} from 'vitest';
|
|
9
|
+
import {describe, it, expect, vi} from 'vitest';
|
|
10
10
|
import {Heading} from './Heading';
|
|
11
11
|
|
|
12
12
|
describe('Heading', () => {
|
|
@@ -16,6 +16,28 @@ describe('Heading', () => {
|
|
|
16
16
|
expect(screen.getByText('Page Title')).toBeInTheDocument();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it('keeps a forwarded ref attached across rerenders', () => {
|
|
20
|
+
const ref = vi.fn();
|
|
21
|
+
const {rerender} = render(
|
|
22
|
+
<Heading ref={ref} level={1}>
|
|
23
|
+
Before
|
|
24
|
+
</Heading>,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const element = screen.getByText('Before');
|
|
28
|
+
expect(ref).toHaveBeenLastCalledWith(element);
|
|
29
|
+
ref.mockClear();
|
|
30
|
+
|
|
31
|
+
rerender(
|
|
32
|
+
<Heading ref={ref} level={1}>
|
|
33
|
+
After
|
|
34
|
+
</Heading>,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(ref).not.toHaveBeenCalled();
|
|
38
|
+
expect(screen.getByText('After')).toBe(element);
|
|
39
|
+
});
|
|
40
|
+
|
|
19
41
|
it('renders h1 for level 1', () => {
|
|
20
42
|
render(<Heading level={1}>H1</Heading>);
|
|
21
43
|
const element = screen.getByText('H1');
|
package/src/Heading/Heading.tsx
CHANGED
|
@@ -43,7 +43,8 @@ import {
|
|
|
43
43
|
import {useTruncation} from '../Text/useTruncation';
|
|
44
44
|
import {resolveStyleColor} from '../Text/Text';
|
|
45
45
|
import type {LayerPlacement} from '../Layer';
|
|
46
|
-
import {mergeProps
|
|
46
|
+
import {mergeProps} from '../utils';
|
|
47
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
47
48
|
import type {BaseProps} from '../BaseProps';
|
|
48
49
|
import {themeProps} from '../utils/themeProps';
|
|
49
50
|
|
|
@@ -242,13 +243,16 @@ export function Heading({
|
|
|
242
243
|
// Ref for the heading element (used as tooltip anchor)
|
|
243
244
|
const headingRef = useRef<HTMLHeadingElement>(null);
|
|
244
245
|
|
|
246
|
+
// Keep the merged ref stable across rerenders.
|
|
247
|
+
const mergedRef = useMergedRefs(ref, truncation.ref, headingRef);
|
|
248
|
+
|
|
245
249
|
// Build inline style for -webkit-line-clamp (dynamic value)
|
|
246
250
|
const inlineStyle = maxLines > 1 ? {WebkitLineClamp: maxLines} : undefined;
|
|
247
251
|
|
|
248
252
|
return (
|
|
249
253
|
<>
|
|
250
254
|
<Component
|
|
251
|
-
ref={
|
|
255
|
+
ref={mergedRef}
|
|
252
256
|
{...mergeProps(
|
|
253
257
|
themeProps('heading', {level, color, ...(type && {type})}),
|
|
254
258
|
stylex.props(
|
|
@@ -16,7 +16,10 @@ export const docs = {
|
|
|
16
16
|
},
|
|
17
17
|
theming: {
|
|
18
18
|
targets: [
|
|
19
|
-
{className: 'astryx-
|
|
19
|
+
{className: 'astryx-hover-card'},
|
|
20
|
+
// Still emitted beside the names above, so themes written against
|
|
21
|
+
// them keep working. Drop in the next major.
|
|
22
|
+
{className: 'astryx-hovercard', deprecatedFor: 'hover-card'},
|
|
20
23
|
],
|
|
21
24
|
vars: [
|
|
22
25
|
{name: '--_hovercard-radius', description: 'Border radius of the hover card', default: 'var(--radius-container)', private: true},
|
|
@@ -109,6 +112,11 @@ export const docs = {
|
|
|
109
112
|
type: 'boolean',
|
|
110
113
|
description: 'Whether the hover card should be shown on mount. Still dismissible.',
|
|
111
114
|
},
|
|
115
|
+
{
|
|
116
|
+
name: 'isOpen',
|
|
117
|
+
type: 'boolean',
|
|
118
|
+
description: 'Controlled open state for the hover card.',
|
|
119
|
+
},
|
|
112
120
|
],
|
|
113
121
|
},
|
|
114
122
|
],
|
|
@@ -139,7 +147,10 @@ export const docsZh = {
|
|
|
139
147
|
displayName: 'Hover Card',
|
|
140
148
|
theming: {
|
|
141
149
|
targets: [
|
|
142
|
-
{className: 'astryx-
|
|
150
|
+
{className: 'astryx-hover-card'},
|
|
151
|
+
// Still emitted beside the names above, so themes written against
|
|
152
|
+
// them keep working. Drop in the next major.
|
|
153
|
+
{className: 'astryx-hovercard', deprecatedFor: 'hover-card'},
|
|
143
154
|
],
|
|
144
155
|
vars: [
|
|
145
156
|
{name: '--_hovercard-radius', description: 'Border radius of the hover card', default: 'var(--radius-container)', private: true},
|
|
@@ -365,7 +365,42 @@ 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('keeps aria-describedby on the trigger when no label is provided', () => {
|
|
369
404
|
render(
|
|
370
405
|
<HoverCard content={<span>Card content</span>}>
|
|
371
406
|
<button type="button">Trigger</button>
|
|
@@ -373,9 +408,10 @@ describe('HoverCard', () => {
|
|
|
373
408
|
);
|
|
374
409
|
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
375
410
|
expect(trigger).toHaveAttribute('aria-describedby');
|
|
411
|
+
expect(trigger).not.toHaveAttribute('aria-haspopup');
|
|
376
412
|
});
|
|
377
413
|
|
|
378
|
-
it('
|
|
414
|
+
it('preserves existing aria-describedby when no label is provided', () => {
|
|
379
415
|
render(
|
|
380
416
|
<HoverCard content={<span>Card content</span>}>
|
|
381
417
|
<button type="button" aria-describedby="existing-id">
|
|
@@ -388,6 +424,34 @@ describe('HoverCard', () => {
|
|
|
388
424
|
expect(describedBy).toContain('existing-id');
|
|
389
425
|
});
|
|
390
426
|
|
|
427
|
+
it('updates aria-expanded when the labelled hover card opens and closes', async () => {
|
|
428
|
+
render(
|
|
429
|
+
<HoverCard
|
|
430
|
+
content={<span>Card content</span>}
|
|
431
|
+
label="Profile actions"
|
|
432
|
+
delay={0}>
|
|
433
|
+
<button type="button">Trigger</button>
|
|
434
|
+
</HoverCard>,
|
|
435
|
+
);
|
|
436
|
+
const trigger = screen.getByRole('button', {name: 'Trigger'});
|
|
437
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
438
|
+
expect(trigger).not.toHaveAttribute('aria-controls');
|
|
439
|
+
|
|
440
|
+
fireEvent.mouseEnter(trigger);
|
|
441
|
+
await waitFor(() => {
|
|
442
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
443
|
+
// The layer is in the DOM now, so aria-controls points at it.
|
|
444
|
+
expect(trigger).toHaveAttribute('aria-controls');
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
fireEvent.mouseLeave(trigger);
|
|
448
|
+
await waitFor(() => {
|
|
449
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
450
|
+
// The layer is gone from the DOM, so aria-controls is cleared.
|
|
451
|
+
expect(trigger).not.toHaveAttribute('aria-controls');
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
391
455
|
it('calls onOpenChange(true) when shown', async () => {
|
|
392
456
|
const onOpenChange = vi.fn();
|
|
393
457
|
render(
|
|
@@ -429,16 +493,32 @@ describe('HoverCard', () => {
|
|
|
429
493
|
|
|
430
494
|
it('supports text-only children with inline wrapper', () => {
|
|
431
495
|
render(
|
|
432
|
-
<HoverCard content={<span>Card content</span>}>
|
|
496
|
+
<HoverCard content={<span>Card content</span>} label="Profile actions">
|
|
433
497
|
Just text, no element
|
|
434
498
|
</HoverCard>,
|
|
435
499
|
);
|
|
436
500
|
// Text should be rendered
|
|
437
501
|
expect(screen.getByText('Just text, no element')).toBeInTheDocument();
|
|
438
|
-
//
|
|
502
|
+
// When labelled, the wrapper advertises a dialog popup.
|
|
503
|
+
const wrapper = screen.getByText('Just text, no element');
|
|
504
|
+
expect(wrapper.tagName).toBe('SPAN');
|
|
505
|
+
expect(wrapper).toHaveAttribute('aria-haspopup', 'dialog');
|
|
506
|
+
expect(wrapper).toHaveAttribute('aria-expanded', 'false');
|
|
507
|
+
// While closed, the layer is not in the DOM, so aria-controls is unset.
|
|
508
|
+
expect(wrapper).not.toHaveAttribute('aria-controls');
|
|
509
|
+
expect(wrapper).not.toHaveAttribute('aria-describedby');
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('keeps aria-describedby on text-only children when no label is provided', () => {
|
|
513
|
+
render(
|
|
514
|
+
<HoverCard content={<span>Card content</span>}>
|
|
515
|
+
Just text, no element
|
|
516
|
+
</HoverCard>,
|
|
517
|
+
);
|
|
439
518
|
const wrapper = screen.getByText('Just text, no element');
|
|
440
519
|
expect(wrapper.tagName).toBe('SPAN');
|
|
441
520
|
expect(wrapper).toHaveAttribute('aria-describedby');
|
|
521
|
+
expect(wrapper).not.toHaveAttribute('aria-haspopup');
|
|
442
522
|
});
|
|
443
523
|
|
|
444
524
|
describe('isDefaultOpen', () => {
|
|
@@ -994,3 +1074,20 @@ describe('HoverCard', () => {
|
|
|
994
1074
|
});
|
|
995
1075
|
});
|
|
996
1076
|
});
|
|
1077
|
+
|
|
1078
|
+
describe('HoverCard theme target names', () => {
|
|
1079
|
+
it('renders the deprecated class beside the current one on the card surface', async () => {
|
|
1080
|
+
render(
|
|
1081
|
+
<HoverCard content={<span>Card content</span>} delay={0}>
|
|
1082
|
+
<button type="button">Trigger</button>
|
|
1083
|
+
</HoverCard>,
|
|
1084
|
+
);
|
|
1085
|
+
fireEvent.mouseEnter(screen.getByRole('button', {name: 'Trigger'}));
|
|
1086
|
+
|
|
1087
|
+
await waitFor(() => {
|
|
1088
|
+
const layer = screen.getByText('Card content').closest('[popover]');
|
|
1089
|
+
expect(layer).toHaveClass('astryx-hover-card');
|
|
1090
|
+
expect(layer).toHaveClass('astryx-hovercard');
|
|
1091
|
+
});
|
|
1092
|
+
});
|
|
1093
|
+
});
|
|
@@ -144,6 +144,12 @@ export interface HoverCardProps extends Pick<
|
|
|
144
144
|
* - `true`: force-show the hover card (hover/focus hide is suppressed)
|
|
145
145
|
* - `false`: force-hide the hover card
|
|
146
146
|
* - `undefined`: uncontrolled — hover/focus triggers manage visibility
|
|
147
|
+
*
|
|
148
|
+
* A controlled hover card still takes Escape when it is the top-most layer,
|
|
149
|
+
* and answers by calling `onOpenChange(false)` without hiding itself —
|
|
150
|
+
* closing is your update's decision, exactly as for a controlled Dialog.
|
|
151
|
+
* Ignore the call and the card stays, and so does the press: nothing
|
|
152
|
+
* underneath dismisses.
|
|
147
153
|
*/
|
|
148
154
|
isOpen?: boolean;
|
|
149
155
|
|
|
@@ -253,7 +259,59 @@ export function HoverCard({
|
|
|
253
259
|
// Use combined ref for position + interaction
|
|
254
260
|
hoverCard.ref(firstChild);
|
|
255
261
|
|
|
256
|
-
|
|
262
|
+
if (label) {
|
|
263
|
+
// When named, the hover card is a dialog. The trigger should advertise the
|
|
264
|
+
// popup relationship with aria-haspopup/aria-expanded, not describe the
|
|
265
|
+
// trigger with the dialog's content (aria-describedby is for plain-text
|
|
266
|
+
// descriptions, not navigable regions). See #5049.
|
|
267
|
+
//
|
|
268
|
+
// Merge rather than overwrite: the trigger may already carry its own
|
|
269
|
+
// popup semantics (e.g. a menu button wrapped in a labelled HoverCard),
|
|
270
|
+
// so preserve the existing values and restore them on cleanup.
|
|
271
|
+
const existingHaspopup = firstChild.getAttribute('aria-haspopup');
|
|
272
|
+
const existingControls = firstChild.getAttribute('aria-controls');
|
|
273
|
+
const existingExpanded = firstChild.getAttribute('aria-expanded');
|
|
274
|
+
|
|
275
|
+
firstChild.setAttribute('aria-haspopup', 'dialog');
|
|
276
|
+
// Only point aria-controls at the layer while it is open and in the DOM.
|
|
277
|
+
// While closed, useLayer leaves only an inert <template> marker, so the
|
|
278
|
+
// id would reference nothing. DateInput gates it the same way. The
|
|
279
|
+
// trigger's own aria-controls (if any) is preserved either way.
|
|
280
|
+
if (hoverCard.isOpen) {
|
|
281
|
+
firstChild.setAttribute(
|
|
282
|
+
'aria-controls',
|
|
283
|
+
mergeIds(existingControls, hoverCard.id) ?? '',
|
|
284
|
+
);
|
|
285
|
+
} else if (existingControls) {
|
|
286
|
+
firstChild.setAttribute('aria-controls', existingControls);
|
|
287
|
+
} else {
|
|
288
|
+
firstChild.removeAttribute('aria-controls');
|
|
289
|
+
}
|
|
290
|
+
firstChild.setAttribute('aria-expanded', String(hoverCard.isOpen));
|
|
291
|
+
|
|
292
|
+
return () => {
|
|
293
|
+
hoverCard.ref(null);
|
|
294
|
+
if (existingHaspopup) {
|
|
295
|
+
firstChild.setAttribute('aria-haspopup', existingHaspopup);
|
|
296
|
+
} else {
|
|
297
|
+
firstChild.removeAttribute('aria-haspopup');
|
|
298
|
+
}
|
|
299
|
+
if (existingControls) {
|
|
300
|
+
firstChild.setAttribute('aria-controls', existingControls);
|
|
301
|
+
} else {
|
|
302
|
+
firstChild.removeAttribute('aria-controls');
|
|
303
|
+
}
|
|
304
|
+
if (existingExpanded) {
|
|
305
|
+
firstChild.setAttribute('aria-expanded', existingExpanded);
|
|
306
|
+
} else {
|
|
307
|
+
firstChild.removeAttribute('aria-expanded');
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Unnamed fallback: the popup remains role="group", which is not a dialog,
|
|
313
|
+
// so keep the previous description relationship until a naming decision is
|
|
314
|
+
// made for the no-label case (tracked in #5049).
|
|
257
315
|
const existingDescribedBy = firstChild.getAttribute('aria-describedby');
|
|
258
316
|
firstChild.setAttribute(
|
|
259
317
|
'aria-describedby',
|
|
@@ -268,7 +326,14 @@ export function HoverCard({
|
|
|
268
326
|
firstChild.removeAttribute('aria-describedby');
|
|
269
327
|
}
|
|
270
328
|
};
|
|
271
|
-
}, [
|
|
329
|
+
}, [
|
|
330
|
+
textOnly,
|
|
331
|
+
label,
|
|
332
|
+
hoverCard.ref,
|
|
333
|
+
hoverCard.id,
|
|
334
|
+
hoverCard.isOpen,
|
|
335
|
+
hoverCard.describedBy,
|
|
336
|
+
]);
|
|
272
337
|
|
|
273
338
|
// While closed, useLayer leaves only an inert <template> marker at this JSX
|
|
274
339
|
// position. When the card needs to open, it uses that marker to keep the
|
|
@@ -287,7 +352,10 @@ export function HoverCard({
|
|
|
287
352
|
<span
|
|
288
353
|
ref={hoverCard.ref}
|
|
289
354
|
tabIndex={0}
|
|
290
|
-
aria-
|
|
355
|
+
aria-haspopup={label ? 'dialog' : undefined}
|
|
356
|
+
aria-controls={label && hoverCard.isOpen ? hoverCard.id : undefined}
|
|
357
|
+
aria-expanded={label ? hoverCard.isOpen : undefined}
|
|
358
|
+
aria-describedby={label ? undefined : hoverCard.describedBy}
|
|
291
359
|
{...stylex.props(
|
|
292
360
|
styles.wrapperInline,
|
|
293
361
|
showHoverIndication && styles.hoverIndication,
|