@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3
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 +49 -15
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +62 -20
- 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 +7 -3
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -23
- 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 +12 -12
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +17 -9
- package/dist/Card/index.d.ts +35 -1
- package/dist/Card/index.d.ts.map +1 -1
- package/dist/Card/index.js +21 -1
- 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/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -3
- 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/DateRangeInput/DateRangeInput.d.ts +4 -2
- package/dist/DateRangeInput/DateRangeInput.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 +21 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +110 -58
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -13
- 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/Field/InputClearButton.d.ts +9 -3
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +14 -3
- 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 -3
- 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/gestureCounter.d.ts +8 -0
- package/dist/Layer/gestureCounter.d.ts.map +1 -0
- package/dist/Layer/gestureCounter.js +53 -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/useLayer.d.ts +23 -13
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +128 -8
- 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/List/List.d.ts +1 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +15 -4
- package/dist/Markdown/Markdown.d.ts +1 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +20 -7
- 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/MetadataList/MetadataListItem.d.ts +1 -1
- package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
- package/dist/MetadataList/MetadataListItem.js +4 -1
- 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 +73 -15
- package/dist/MultiSelector/hooks.d.ts +7 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -2
- 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 +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +9 -5
- 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/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +1 -9
- package/dist/Popover/usePopover.d.ts +7 -41
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +40 -21
- 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 +12 -3
- package/dist/Selector/Selector.d.ts +18 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +91 -18
- package/dist/Selector/hooks.d.ts +7 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +3 -2
- 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 +26 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
- 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 +43 -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 -3
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +16 -10
- 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 +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +15 -21
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +22 -7
- package/dist/Toast/ToastViewport.d.ts +1 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +71 -18
- package/dist/Token/Token.d.ts +1 -1
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +20 -9
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +7 -4
- package/dist/Tokenizer/Tokenizer.d.ts +14 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +33 -21
- 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 +1 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +31 -11
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +22 -7
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +7 -2
- package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +119 -37
- package/dist/Typeahead/Typeahead.d.ts +8 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +5 -2
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +7 -2
- package/dist/astryx.css +113 -11
- 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/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +46 -10
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +24 -4
- package/dist/theme/generateThemeRules.d.ts +21 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +26 -0
- 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/af-ZA.json +6 -6
- package/locales/ar-SA.json +6 -6
- package/locales/ca-ES.json +5 -5
- package/locales/cs-CZ.json +6 -6
- package/locales/da-DK.json +6 -6
- package/locales/de-DE.json +6 -6
- package/locales/el-GR.json +6 -6
- package/locales/en.json +163 -11
- package/locales/es-ES.json +5 -5
- package/locales/fi-FI.json +6 -6
- package/locales/fr-FR.json +6 -6
- package/locales/he-IL.json +6 -6
- package/locales/hu-HU.json +6 -6
- package/locales/it-IT.json +6 -6
- package/locales/ja-JP.json +6 -6
- package/locales/ko-KR.json +6 -6
- package/locales/nl-NL.json +6 -6
- package/locales/no-NO.json +6 -6
- package/locales/pl-PL.json +6 -6
- package/locales/pseudo.json +114 -0
- package/locales/pt-BR.json +6 -6
- package/locales/pt-PT.json +6 -6
- package/locales/ro-RO.json +6 -6
- package/locales/ru-RU.json +6 -6
- package/locales/sr-SP.json +6 -6
- package/locales/sv-SE.json +6 -6
- package/locales/tr-TR.json +6 -6
- package/locales/uk-UA.json +6 -6
- package/locales/vi-VN.json +6 -6
- package/locales/zh-CN.json +6 -6
- package/locales/zh-TW.json +6 -6
- 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 +22 -11
- package/src/Banner/Banner.test.tsx +177 -25
- package/src/Banner/Banner.tsx +93 -27
- 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 +7 -6
- package/src/Calendar/Calendar.test.tsx +143 -0
- package/src/Calendar/Calendar.tsx +30 -26
- 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 +113 -19
- package/src/Card/Card.tsx +67 -89
- package/src/Card/index.ts +36 -1
- 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/ComplexSelector/ComplexSelector.test.tsx +32 -0
- package/src/ComplexSelector/ComplexSelector.tsx +1 -3
- 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/DateRangeInput/DateRangeInput.doc.mjs +2 -2
- package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
- package/src/DateRangeInput/DateRangeInput.tsx +4 -2
- 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/DropdownMenu.test.tsx +44 -10
- package/src/DropdownMenu/DropdownMenu.tsx +4 -13
- 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/Field/InputClearButton.test.tsx +15 -1
- package/src/Field/InputClearButton.tsx +28 -4
- package/src/FileInput/FileInput.tsx +3 -2
- package/src/Heading/Heading.test.tsx +23 -1
- package/src/Heading/Heading.tsx +6 -3
- 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/gestureCounter.ts +57 -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 +324 -15
- package/src/Layer/useLayer.tsx +164 -8
- 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/Layout/__tests__/edgeCompensation.test.tsx +1 -1
- 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/List/List.test.tsx +38 -0
- package/src/List/List.tsx +8 -1
- package/src/Markdown/Markdown.doc.mjs +5 -0
- package/src/Markdown/Markdown.test.tsx +37 -0
- package/src/Markdown/Markdown.tsx +16 -5
- 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/MetadataList/MetadataList.test.tsx +75 -2
- package/src/MetadataList/MetadataListItem.tsx +5 -2
- 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 +311 -0
- package/src/MultiSelector/MultiSelector.tsx +151 -15
- package/src/MultiSelector/hooks.ts +9 -2
- 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.test.tsx +30 -0
- package/src/NavMenu/NavHeadingMenu.tsx +9 -5
- 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/Popover.test.tsx +14 -0
- package/src/Popover/Popover.tsx +1 -9
- package/src/Popover/usePopover.tsx +57 -32
- 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.doc.mjs +3 -0
- package/src/SelectableCard/SelectableCard.tsx +19 -2
- package/src/Selector/Selector.doc.mjs +26 -1
- package/src/Selector/Selector.test.tsx +346 -1
- package/src/Selector/Selector.tsx +148 -21
- package/src/Selector/hooks.ts +17 -2
- 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 +67 -12
- 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 +138 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +63 -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 +67 -1
- package/src/Text/Text.tsx +6 -3
- package/src/TextArea/TextArea.doc.mjs +12 -2
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +37 -24
- 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 +58 -0
- package/src/Timestamp/Timestamp.tsx +12 -10
- package/src/Toast/Toast.doc.mjs +26 -12
- package/src/Toast/Toast.tsx +28 -4
- package/src/Toast/ToastViewport.test.tsx +536 -8
- package/src/Toast/ToastViewport.tsx +81 -12
- package/src/Token/Token.test.tsx +95 -0
- package/src/Token/Token.tsx +15 -10
- package/src/Token/TokenLink.tsx +14 -5
- package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
- package/src/Tokenizer/Tokenizer.test.tsx +161 -0
- package/src/Tokenizer/Tokenizer.tsx +53 -24
- 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.test.tsx +104 -0
- package/src/TopNav/TopNavMegaMenu.tsx +47 -5
- package/src/TopNav/TopNavMenu.test.tsx +133 -1
- package/src/TopNav/TopNavMenu.tsx +38 -7
- package/src/TreeList/TreeList.test.tsx +49 -0
- package/src/TreeList/TreeList.tsx +7 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
- package/src/Typeahead/BaseTypeahead.tsx +181 -39
- package/src/Typeahead/Typeahead.doc.mjs +11 -0
- package/src/Typeahead/Typeahead.test.tsx +203 -0
- package/src/Typeahead/Typeahead.tsx +12 -2
- package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
- package/src/Typeahead/TypeaheadItem.tsx +8 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useAnnounce.doc.mjs +96 -0
- package/src/hooks/useContainerReveal.doc.mjs +2 -2
- package/src/hooks/useDevWarning.doc.mjs +96 -0
- 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/useIndicatorFocusRing.doc.mjs +104 -0
- package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
- package/src/hooks/useInteractiveRole.doc.mjs +119 -0
- package/src/hooks/useLongPress.doc.mjs +123 -0
- 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/hooks/useTypeahead.doc.mjs +153 -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/Theme.test.tsx +104 -2
- package/src/theme/Theme.tsx +49 -14
- package/src/theme/defineTheme.test.ts +23 -0
- package/src/theme/derivedVarRegistry.test.ts +26 -3
- package/src/theme/derivedVarRegistry.ts +23 -4
- package/src/theme/generateThemeRules.test.ts +99 -1
- package/src/theme/generateThemeRules.ts +28 -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
package/src/Slider/Slider.tsx
CHANGED
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
|
+
useEffect,
|
|
20
21
|
useId,
|
|
21
22
|
useMemo,
|
|
22
23
|
useRef,
|
|
23
24
|
useState,
|
|
24
25
|
useCallback,
|
|
26
|
+
type FocusEvent,
|
|
25
27
|
type KeyboardEvent,
|
|
26
28
|
type PointerEvent,
|
|
27
29
|
} from 'react';
|
|
@@ -40,13 +42,18 @@ import {Tooltip} from '../Tooltip/Tooltip';
|
|
|
40
42
|
import {useTooltip} from '../Tooltip';
|
|
41
43
|
import {VisuallyHidden} from '../VisuallyHidden';
|
|
42
44
|
import type {InputStatus} from '../Field/types';
|
|
43
|
-
import {mergeProps,
|
|
45
|
+
import {mergeProps, rtlStyles} from '../utils';
|
|
44
46
|
import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
47
|
+
import {
|
|
48
|
+
getInteractionModality,
|
|
49
|
+
trackInteractionModality,
|
|
50
|
+
} from '../utils/interactionModality';
|
|
45
51
|
import {isRtlElement} from '../hooks/isRtlElement';
|
|
46
52
|
import type {BaseProps} from '../BaseProps';
|
|
47
53
|
import type {SizeValue} from '../utils/types';
|
|
48
54
|
import {themeProps} from '../utils/themeProps';
|
|
49
55
|
|
|
56
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
50
57
|
// =============================================================================
|
|
51
58
|
// Types
|
|
52
59
|
// =============================================================================
|
|
@@ -492,6 +499,36 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
492
499
|
const draggingThumbRef = useRef<number | null>(null);
|
|
493
500
|
const [draggingThumb, setDraggingThumb] = useState<number | null>(null);
|
|
494
501
|
|
|
502
|
+
// A thumb is a div[role="slider"], and `handlePointerDown` focuses it from
|
|
503
|
+
// script after preventDefault — which Chromium treats as focus-visible, so
|
|
504
|
+
// dragging with a mouse drew the keyboard ring (measured: `:focus-visible`
|
|
505
|
+
// true on pointerdown). Gate the ring on how the user last interacted; the
|
|
506
|
+
// CSS condition stays `:focus-visible`, this only narrows it.
|
|
507
|
+
const [keyboardFocusThumb, setKeyboardFocusThumb] = useState<number | null>(
|
|
508
|
+
null,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
useEffect(() => {
|
|
512
|
+
trackInteractionModality();
|
|
513
|
+
}, []);
|
|
514
|
+
|
|
515
|
+
const handleThumbFocus = useCallback(
|
|
516
|
+
(thumbIndex: number, _e: FocusEvent<HTMLDivElement>) => {
|
|
517
|
+
// A disabled thumb draws no ring even when it stays focusable for its
|
|
518
|
+
// reason tooltip, so there is nothing to track for one.
|
|
519
|
+
setKeyboardFocusThumb(
|
|
520
|
+
!isDisabled && getInteractionModality() === 'keyboard'
|
|
521
|
+
? thumbIndex
|
|
522
|
+
: null,
|
|
523
|
+
);
|
|
524
|
+
},
|
|
525
|
+
[isDisabled],
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
const handleThumbBlur = useCallback((_e: FocusEvent<HTMLDivElement>) => {
|
|
529
|
+
setKeyboardFocusThumb(null);
|
|
530
|
+
}, []);
|
|
531
|
+
|
|
495
532
|
// Disabled-reason tooltip. This is a *separate* useTooltip instance from the
|
|
496
533
|
// per-thumb value bubble (the `<Tooltip>` component below): it anchors to the
|
|
497
534
|
// track container and fires on hover/focus of the whole control. Disabled
|
|
@@ -678,6 +715,10 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
678
715
|
const thumbs = track.querySelectorAll<HTMLElement>('[role="slider"]');
|
|
679
716
|
thumbs[thumbIndex]?.focus();
|
|
680
717
|
}
|
|
718
|
+
// Also clear it explicitly: focusing an already-focused thumb fires no
|
|
719
|
+
// focus event, so a thumb the user had tabbed to would keep its ring
|
|
720
|
+
// through the drag.
|
|
721
|
+
setKeyboardFocusThumb(null);
|
|
681
722
|
|
|
682
723
|
if (
|
|
683
724
|
typeof (e.currentTarget as HTMLElement).setPointerCapture === 'function'
|
|
@@ -716,6 +757,13 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
716
757
|
if (isDisabled) {
|
|
717
758
|
return;
|
|
718
759
|
}
|
|
760
|
+
// Unlike a text field, a thumb has no caret to show where input is
|
|
761
|
+
// going, so a keypress after a mouse drag must bring the ring back.
|
|
762
|
+
// Ask the utility rather than assuming: a modifier chord (⌘R, ⌃C) is
|
|
763
|
+
// not navigation and must not re-ring a thumb the mouse is holding.
|
|
764
|
+
if (getInteractionModality() === 'keyboard') {
|
|
765
|
+
setKeyboardFocusThumb(thumbIndex);
|
|
766
|
+
}
|
|
719
767
|
const currentVal = values[thumbIndex];
|
|
720
768
|
let newVal: number;
|
|
721
769
|
|
|
@@ -842,6 +890,8 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
842
890
|
aria-labelledby={!isRange ? labelID : undefined}
|
|
843
891
|
aria-describedby={ariaDescribedBy}
|
|
844
892
|
onKeyDown={e => handleKeyDown(thumbIndex, e)}
|
|
893
|
+
onFocus={e => handleThumbFocus(thumbIndex, e)}
|
|
894
|
+
onBlur={handleThumbBlur}
|
|
845
895
|
{...mergeProps(
|
|
846
896
|
themeProps('slider-thumb', {
|
|
847
897
|
orientation,
|
|
@@ -853,7 +903,9 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
853
903
|
? styles.thumbHorizontal
|
|
854
904
|
: rtlStyles.centerInline('50%'),
|
|
855
905
|
!isDisabled && styles.thumbHover,
|
|
856
|
-
!isDisabled &&
|
|
906
|
+
!isDisabled &&
|
|
907
|
+
keyboardFocusThumb === thumbIndex &&
|
|
908
|
+
focusOutlineStyles.focusVisible,
|
|
857
909
|
isDisabled && styles.thumbDisabled,
|
|
858
910
|
),
|
|
859
911
|
undefined,
|
|
@@ -964,7 +1016,7 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
964
1016
|
/>
|
|
965
1017
|
))}
|
|
966
1018
|
<div
|
|
967
|
-
ref={
|
|
1019
|
+
ref={useMergedRefs(ref, trackRef, disabledMessageTooltip.ref)}
|
|
968
1020
|
{...(isRange
|
|
969
1021
|
? {role: 'group', 'aria-labelledby': labelID}
|
|
970
1022
|
: undefined)}
|
|
@@ -9,10 +9,29 @@
|
|
|
9
9
|
* SYNC: When Spinner.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect} from 'vitest';
|
|
12
|
+
import {describe, it, expect, vi, afterEach} from 'vitest';
|
|
13
13
|
import {render, screen} from '@testing-library/react';
|
|
14
14
|
import {Spinner} from './Spinner';
|
|
15
15
|
|
|
16
|
+
/** sm/md/lg/xl, as Spinner.tsx defines them. */
|
|
17
|
+
const SIZES = {
|
|
18
|
+
sm: {diameter: 10, border: 2},
|
|
19
|
+
md: {diameter: 14, border: 3},
|
|
20
|
+
lg: {diameter: 18, border: 3},
|
|
21
|
+
xl: {diameter: 28, border: 4},
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
const ring = (testId = 'spinner') =>
|
|
25
|
+
screen.getByTestId(testId).querySelector('svg') as SVGSVGElement;
|
|
26
|
+
|
|
27
|
+
const circles = (testId = 'spinner') => {
|
|
28
|
+
const [track, arc] = [...ring(testId).querySelectorAll('circle')];
|
|
29
|
+
return {track, arc};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const dashOf = (el: SVGCircleElement) =>
|
|
33
|
+
(el.getAttribute('stroke-dasharray') ?? '').split(/[\s,]+/).map(Number);
|
|
34
|
+
|
|
16
35
|
describe('Spinner', () => {
|
|
17
36
|
it('renders with default props', () => {
|
|
18
37
|
render(<Spinner data-testid="spinner" />);
|
|
@@ -122,3 +141,130 @@ describe('Spinner', () => {
|
|
|
122
141
|
expect(spinner.tagName.toLowerCase()).toBe('span');
|
|
123
142
|
});
|
|
124
143
|
});
|
|
144
|
+
|
|
145
|
+
describe('Spinner ring', () => {
|
|
146
|
+
afterEach(() => {
|
|
147
|
+
vi.restoreAllMocks();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('draws the ring in SVG', () => {
|
|
151
|
+
render(<Spinner data-testid="spinner" />);
|
|
152
|
+
const svg = ring();
|
|
153
|
+
expect(svg).not.toBeNull();
|
|
154
|
+
expect(svg.querySelectorAll('circle')).toHaveLength(2);
|
|
155
|
+
expect(screen.getByTestId('spinner').querySelector('canvas')).toBeNull();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it.each(Object.entries(SIZES))(
|
|
159
|
+
'sizes the %s ring from its size token',
|
|
160
|
+
(size, {diameter, border}) => {
|
|
161
|
+
render(
|
|
162
|
+
<Spinner size={size as keyof typeof SIZES} data-testid="spinner" />,
|
|
163
|
+
);
|
|
164
|
+
const frame = diameter + border * 2;
|
|
165
|
+
const svg = ring();
|
|
166
|
+
expect(svg.getAttribute('viewBox')).toBe(`0 0 ${frame} ${frame}`);
|
|
167
|
+
for (const c of [circles().track, circles().arc]) {
|
|
168
|
+
expect(Number(c.getAttribute('cx'))).toBe(frame / 2);
|
|
169
|
+
expect(Number(c.getAttribute('cy'))).toBe(frame / 2);
|
|
170
|
+
expect(Number(c.getAttribute('r'))).toBe(diameter / 2);
|
|
171
|
+
expect(Number(c.getAttribute('stroke-width'))).toBe(border);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// The canvas ring swept 135deg, not the 270deg its SPREAD comment claimed.
|
|
177
|
+
it.each(Object.entries(SIZES))(
|
|
178
|
+
'sweeps 135 degrees at %s',
|
|
179
|
+
(size, {diameter}) => {
|
|
180
|
+
render(
|
|
181
|
+
<Spinner size={size as keyof typeof SIZES} data-testid="spinner" />,
|
|
182
|
+
);
|
|
183
|
+
const {track, arc} = circles();
|
|
184
|
+
const [on, off] = dashOf(arc);
|
|
185
|
+
expect(on + off).toBeCloseTo(Math.PI * diameter, 6);
|
|
186
|
+
expect((on / (on + off)) * 360).toBeCloseTo(135, 6);
|
|
187
|
+
expect(track.getAttribute('stroke-dasharray')).toBeNull();
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
it('starts the arc at twelve o’clock', () => {
|
|
192
|
+
render(<Spinner data-testid="spinner" />);
|
|
193
|
+
const frame = SIZES.md.diameter + SIZES.md.border * 2;
|
|
194
|
+
expect(circles().arc.getAttribute('transform')).toBe(
|
|
195
|
+
`rotate(-90 ${frame / 2} ${frame / 2})`,
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// The whole point of the SVG ring: the colours come off the cascade, so
|
|
200
|
+
// nothing has to resolve them in JS. A read reaching the paint path again
|
|
201
|
+
// fails here.
|
|
202
|
+
it.each(['default', 'subtle', 'onMedia', 'inherit'] as const)(
|
|
203
|
+
'reads no computed style to paint the %s shade',
|
|
204
|
+
shade => {
|
|
205
|
+
const spy = vi.spyOn(window, 'getComputedStyle');
|
|
206
|
+
render(<Spinner shade={shade} data-testid="spinner" />);
|
|
207
|
+
const spinner = screen.getByTestId('spinner');
|
|
208
|
+
const onSpinner = spy.mock.calls.filter(
|
|
209
|
+
([el]) => el instanceof Element && spinner.contains(el),
|
|
210
|
+
);
|
|
211
|
+
expect(onSpinner).toEqual([]);
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
it('schedules no frame where the Web Animations API is absent', () => {
|
|
216
|
+
expect(SVGElement.prototype).not.toHaveProperty('getAnimations');
|
|
217
|
+
const raf = vi.spyOn(window, 'requestAnimationFrame');
|
|
218
|
+
render(<Spinner data-testid="spinner" />);
|
|
219
|
+
expect(ring()).not.toBeNull();
|
|
220
|
+
expect(raf).not.toHaveBeenCalled();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('pins every ring to the timeline origin in a single frame', () => {
|
|
224
|
+
const animations: {startTime: number | null}[] = [];
|
|
225
|
+
const getAnimations = vi.fn(function (this: SVGElement) {
|
|
226
|
+
const a = {startTime: null as number | null};
|
|
227
|
+
animations.push(a);
|
|
228
|
+
return [a];
|
|
229
|
+
});
|
|
230
|
+
Object.defineProperty(SVGElement.prototype, 'getAnimations', {
|
|
231
|
+
value: getAnimations,
|
|
232
|
+
configurable: true,
|
|
233
|
+
writable: true,
|
|
234
|
+
});
|
|
235
|
+
const frames: FrameRequestCallback[] = [];
|
|
236
|
+
const raf = vi
|
|
237
|
+
.spyOn(window, 'requestAnimationFrame')
|
|
238
|
+
.mockImplementation(cb => {
|
|
239
|
+
frames.push(cb);
|
|
240
|
+
return frames.length;
|
|
241
|
+
});
|
|
242
|
+
const computed = vi.spyOn(window, 'getComputedStyle');
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const {container} = render(
|
|
246
|
+
<>
|
|
247
|
+
{Array.from({length: 5}, (_, i) => (
|
|
248
|
+
<Spinner key={i} />
|
|
249
|
+
))}
|
|
250
|
+
</>,
|
|
251
|
+
);
|
|
252
|
+
// One frame for five spinners: the reads are batched, so no mount
|
|
253
|
+
// re-forces what the previous mount invalidated.
|
|
254
|
+
expect(raf).toHaveBeenCalledTimes(1);
|
|
255
|
+
frames.forEach(cb => cb(0));
|
|
256
|
+
expect(animations).toHaveLength(5);
|
|
257
|
+
expect(animations.every(a => a.startTime === 0)).toBe(true);
|
|
258
|
+
// The pin runs on the branch the other shade cases cannot reach, so the
|
|
259
|
+
// no-read assertion is made here too.
|
|
260
|
+
expect(
|
|
261
|
+
computed.mock.calls.filter(
|
|
262
|
+
([el]) => el instanceof Element && container.contains(el),
|
|
263
|
+
),
|
|
264
|
+
).toEqual([]);
|
|
265
|
+
} finally {
|
|
266
|
+
// @ts-expect-error — removing the stub restores jsdom's real surface
|
|
267
|
+
delete SVGElement.prototype.getAnimations;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
});
|
package/src/Spinner/Spinner.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Spinner.tsx
|
|
7
|
-
* @input Uses React, StyleX,
|
|
7
|
+
* @input Uses React, StyleX, SVG rendering
|
|
8
8
|
* @output Exports Spinner component, SpinnerProps, SpinnerSize, SpinnerShade types
|
|
9
9
|
* @position Core implementation of spinner loading indicator
|
|
10
10
|
*
|
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
* - /packages/cli/assets/templates/blocks/components/Spinner/ (showcase blocks)
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import {useId, type ReactNode} from 'react';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
|
-
import {durationVars, spacingVars} from '../theme/tokens.stylex';
|
|
22
|
-
import {useTheme} from '../theme/useTheme';
|
|
21
|
+
import {colorVars, durationVars, spacingVars} from '../theme/tokens.stylex';
|
|
23
22
|
import type {BaseProps} from '../BaseProps';
|
|
24
23
|
import {Text} from '../Text/Text';
|
|
25
24
|
import {mergeProps} from '../utils';
|
|
@@ -29,10 +28,11 @@ import {themeProps} from '../utils/themeProps';
|
|
|
29
28
|
// Constants
|
|
30
29
|
// =============================================================================
|
|
31
30
|
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Fraction of the ring the moving arc covers. The canvas ring this replaces
|
|
33
|
+
* swept 135deg, not the 270deg its constant's comment claimed.
|
|
34
|
+
*/
|
|
35
|
+
const ARC_FRACTION = 0.375;
|
|
36
36
|
|
|
37
37
|
const SIZES = {
|
|
38
38
|
sm: {diameter: 10, border: 2},
|
|
@@ -41,6 +41,61 @@ const SIZES = {
|
|
|
41
41
|
xl: {diameter: 28, border: 4},
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
+
/** `onMedia` keeps the 77/255 its token's `4D` hex suffix used to encode. */
|
|
45
|
+
const TRACK_OPACITY = {
|
|
46
|
+
default: 1,
|
|
47
|
+
subtle: 1,
|
|
48
|
+
onMedia: 77 / 255,
|
|
49
|
+
inherit: 0.3,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Pin every ring's rotation to the document timeline's origin instead of its
|
|
54
|
+
* own start time, so spinners mounted seconds apart turn in phase.
|
|
55
|
+
*
|
|
56
|
+
* Setting `startTime` is exact where arithmetic on a clock read is not: a
|
|
57
|
+
* negative `animation-delay` computed at mount is only as good as the gap
|
|
58
|
+
* between reading the clock and the frame the animation starts in, which at
|
|
59
|
+
* 10x CPU throttling measured 116deg of drift.
|
|
60
|
+
*
|
|
61
|
+
* Rings are collected and pinned in one frame because `getAnimations()`
|
|
62
|
+
* resolves style and `startTime` dirties it again, so pinning them one at a
|
|
63
|
+
* time makes each mount re-force what the previous one invalidated — 53 style
|
|
64
|
+
* recalcs for 38 spinners against 19 batched.
|
|
65
|
+
*/
|
|
66
|
+
const pendingRings = new Set<SVGSVGElement>();
|
|
67
|
+
let flushScheduled = false;
|
|
68
|
+
|
|
69
|
+
function pinRingsToTimelineOrigin(): void {
|
|
70
|
+
flushScheduled = false;
|
|
71
|
+
const animations: Animation[] = [];
|
|
72
|
+
for (const svg of pendingRings) {
|
|
73
|
+
animations.push(...svg.getAnimations());
|
|
74
|
+
}
|
|
75
|
+
pendingRings.clear();
|
|
76
|
+
for (const animation of animations) {
|
|
77
|
+
animation.startTime = 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function syncRotationPhase(
|
|
82
|
+
svg: SVGSVGElement | null,
|
|
83
|
+
): (() => void) | undefined {
|
|
84
|
+
// jsdom implements no Web Animations, and this runs in every consumer's
|
|
85
|
+
// component tests.
|
|
86
|
+
if (svg == null || typeof svg.getAnimations !== 'function') {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
pendingRings.add(svg);
|
|
90
|
+
if (!flushScheduled) {
|
|
91
|
+
flushScheduled = true;
|
|
92
|
+
requestAnimationFrame(pinRingsToTimelineOrigin);
|
|
93
|
+
}
|
|
94
|
+
return () => {
|
|
95
|
+
pendingRings.delete(svg);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
44
99
|
// =============================================================================
|
|
45
100
|
// Animation
|
|
46
101
|
// =============================================================================
|
|
@@ -67,7 +122,7 @@ const styles = stylex.create({
|
|
|
67
122
|
overflow: 'hidden',
|
|
68
123
|
verticalAlign: 'middle',
|
|
69
124
|
},
|
|
70
|
-
|
|
125
|
+
ring: {
|
|
71
126
|
backfaceVisibility: 'hidden',
|
|
72
127
|
display: 'block',
|
|
73
128
|
willChange: 'transform',
|
|
@@ -82,6 +137,33 @@ const styles = stylex.create({
|
|
|
82
137
|
animationName: rotation,
|
|
83
138
|
animationTimingFunction: 'linear',
|
|
84
139
|
},
|
|
140
|
+
circle: {
|
|
141
|
+
fill: 'none',
|
|
142
|
+
strokeLinecap: 'round',
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const arcStyles = stylex.create({
|
|
147
|
+
default: {stroke: colorVars['--color-accent']},
|
|
148
|
+
subtle: {stroke: colorVars['--color-text-secondary']},
|
|
149
|
+
onMedia: {stroke: colorVars['--color-on-dark']},
|
|
150
|
+
inherit: {stroke: 'currentColor'},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const trackStyles = stylex.create({
|
|
154
|
+
default: {
|
|
155
|
+
stroke: colorVars['--color-track'],
|
|
156
|
+
strokeOpacity: TRACK_OPACITY.default,
|
|
157
|
+
},
|
|
158
|
+
subtle: {
|
|
159
|
+
stroke: colorVars['--color-track'],
|
|
160
|
+
strokeOpacity: TRACK_OPACITY.subtle,
|
|
161
|
+
},
|
|
162
|
+
onMedia: {
|
|
163
|
+
stroke: colorVars['--color-on-dark'],
|
|
164
|
+
strokeOpacity: TRACK_OPACITY.onMedia,
|
|
165
|
+
},
|
|
166
|
+
inherit: {stroke: 'currentColor', strokeOpacity: TRACK_OPACITY.inherit},
|
|
85
167
|
});
|
|
86
168
|
|
|
87
169
|
// =============================================================================
|
|
@@ -100,7 +182,7 @@ export interface SpinnerProps extends BaseProps<HTMLSpanElement> {
|
|
|
100
182
|
* - 'sm': 10px diameter
|
|
101
183
|
* - 'md': 14px diameter
|
|
102
184
|
* - 'lg': 18px diameter
|
|
103
|
-
* - 'xl':
|
|
185
|
+
* - 'xl': 28px diameter
|
|
104
186
|
* @default 'md'
|
|
105
187
|
*/
|
|
106
188
|
size?: SpinnerSize;
|
|
@@ -141,7 +223,7 @@ export interface SpinnerProps extends BaseProps<HTMLSpanElement> {
|
|
|
141
223
|
// =============================================================================
|
|
142
224
|
|
|
143
225
|
/**
|
|
144
|
-
* An animated loading indicator. Available in
|
|
226
|
+
* An animated loading indicator. Available in four sizes and four color shades.
|
|
145
227
|
*
|
|
146
228
|
* @example
|
|
147
229
|
* ```
|
|
@@ -164,97 +246,11 @@ export function Spinner({
|
|
|
164
246
|
ref,
|
|
165
247
|
...restProps
|
|
166
248
|
}: SpinnerProps) {
|
|
167
|
-
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
168
|
-
const {tokens: themeTokens} = useTheme();
|
|
169
|
-
|
|
170
|
-
useEffect(() => {
|
|
171
|
-
const canvas = canvasRef.current;
|
|
172
|
-
if (canvas == null) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const context = canvas.getContext('2d');
|
|
177
|
-
if (!context) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const {border, diameter} = SIZES[size];
|
|
182
|
-
const pixelRatio = window.devicePixelRatio || 1;
|
|
183
|
-
|
|
184
|
-
// Resolve colors from theme tokens (useTheme handles light/dark resolution).
|
|
185
|
-
// - default → accent ring on a track tuned to body luminance
|
|
186
|
-
// - subtle → secondary text color, less prominent
|
|
187
|
-
// - onMedia → on-dark color, with a translucent track for photos/video
|
|
188
|
-
// - inherit → the inherited currentColor, so the ring matches the parent's
|
|
189
|
-
// resolved foreground (e.g. a button's variant text color)
|
|
190
|
-
const inheritedColor =
|
|
191
|
-
shade === 'inherit' ? getComputedStyle(canvas).color : null;
|
|
192
|
-
const activeColor =
|
|
193
|
-
shade === 'inherit'
|
|
194
|
-
? (inheritedColor as string)
|
|
195
|
-
: shade === 'onMedia'
|
|
196
|
-
? themeTokens['--color-on-dark']
|
|
197
|
-
: shade === 'subtle'
|
|
198
|
-
? themeTokens['--color-text-secondary']
|
|
199
|
-
: themeTokens['--color-accent'];
|
|
200
|
-
// Track derives from --color-on-dark for onMedia (with a 30% alpha so the
|
|
201
|
-
// ring reads against arbitrary backgrounds) and from --color-track for the
|
|
202
|
-
// body-luminance shades. For inherit, the track is the same currentColor
|
|
203
|
-
// drawn at reduced alpha via globalAlpha (see below). All branches are
|
|
204
|
-
// fully theme-driven.
|
|
205
|
-
const backgroundColor =
|
|
206
|
-
shade === 'inherit'
|
|
207
|
-
? (inheritedColor as string)
|
|
208
|
-
: shade === 'onMedia'
|
|
209
|
-
? `${themeTokens['--color-on-dark']}4D`
|
|
210
|
-
: themeTokens['--color-track'];
|
|
211
|
-
|
|
212
|
-
const cssSize = diameter + border * 2;
|
|
213
|
-
|
|
214
|
-
// Round to an even number of device pixels so the center stays on a whole
|
|
215
|
-
// pixel (avoids rotation jitter); keep CSS size pinned to cssSize (#2732).
|
|
216
|
-
const rawFrameSize = Math.round(cssSize * pixelRatio);
|
|
217
|
-
const frameSize = rawFrameSize + (rawFrameSize % 2);
|
|
218
|
-
|
|
219
|
-
const scale = frameSize / cssSize;
|
|
220
|
-
const radius = (diameter / 2) * scale;
|
|
221
|
-
const lineWidth = border * scale;
|
|
222
|
-
|
|
223
|
-
canvas.height = canvas.width = frameSize;
|
|
224
|
-
canvas.style.width = canvas.style.height = cssSize + 'px';
|
|
225
|
-
|
|
226
|
-
context.lineCap = 'round';
|
|
227
|
-
context.lineWidth = lineWidth;
|
|
228
|
-
|
|
229
|
-
const center = frameSize / 2;
|
|
230
|
-
|
|
231
|
-
// Background circle (full ring, faded). For the inherit shade the track is
|
|
232
|
-
// the same currentColor as the arc, so fade it via globalAlpha (the
|
|
233
|
-
// computed color is an opaque rgb() string with no alpha channel to tweak).
|
|
234
|
-
context.beginPath();
|
|
235
|
-
context.arc(center, center, radius, 0, 2 * Math.PI);
|
|
236
|
-
context.strokeStyle = backgroundColor;
|
|
237
|
-
if (shade === 'inherit') {
|
|
238
|
-
context.globalAlpha = 0.3;
|
|
239
|
-
}
|
|
240
|
-
context.stroke();
|
|
241
|
-
context.globalAlpha = 1;
|
|
242
|
-
|
|
243
|
-
// Active arc (partial ring, colored)
|
|
244
|
-
context.beginPath();
|
|
245
|
-
context.arc(
|
|
246
|
-
center,
|
|
247
|
-
center,
|
|
248
|
-
radius,
|
|
249
|
-
START_POINT * Math.PI,
|
|
250
|
-
((START_POINT + SPREAD) % 2) * Math.PI,
|
|
251
|
-
);
|
|
252
|
-
context.strokeStyle = activeColor;
|
|
253
|
-
context.stroke();
|
|
254
|
-
}, [shade, size, themeTokens]);
|
|
255
|
-
|
|
256
249
|
const {border, diameter} = SIZES[size];
|
|
257
250
|
const frameSize = diameter + border * 2;
|
|
251
|
+
const center = frameSize / 2;
|
|
252
|
+
const circumference = Math.PI * diameter;
|
|
253
|
+
const arcLength = circumference * ARC_FRACTION;
|
|
258
254
|
const hasLabel = label != null;
|
|
259
255
|
const labelId = useId();
|
|
260
256
|
|
|
@@ -283,7 +279,30 @@ export function Spinner({
|
|
|
283
279
|
hasLabel ? undefined : className,
|
|
284
280
|
{...(hasLabel ? {} : style), width: frameSize, height: frameSize},
|
|
285
281
|
)}>
|
|
286
|
-
<
|
|
282
|
+
<svg
|
|
283
|
+
ref={syncRotationPhase}
|
|
284
|
+
width={frameSize}
|
|
285
|
+
height={frameSize}
|
|
286
|
+
viewBox={`0 0 ${frameSize} ${frameSize}`}
|
|
287
|
+
aria-hidden="true"
|
|
288
|
+
{...stylex.props(styles.ring)}>
|
|
289
|
+
<circle
|
|
290
|
+
cx={center}
|
|
291
|
+
cy={center}
|
|
292
|
+
r={diameter / 2}
|
|
293
|
+
strokeWidth={border}
|
|
294
|
+
{...stylex.props(styles.circle, trackStyles[shade])}
|
|
295
|
+
/>
|
|
296
|
+
<circle
|
|
297
|
+
cx={center}
|
|
298
|
+
cy={center}
|
|
299
|
+
r={diameter / 2}
|
|
300
|
+
strokeWidth={border}
|
|
301
|
+
strokeDasharray={`${arcLength} ${circumference - arcLength}`}
|
|
302
|
+
transform={`rotate(-90 ${center} ${center})`}
|
|
303
|
+
{...stylex.props(styles.circle, arcStyles[shade])}
|
|
304
|
+
/>
|
|
305
|
+
</svg>
|
|
287
306
|
</span>
|
|
288
307
|
);
|
|
289
308
|
|
|
@@ -48,7 +48,10 @@ export const docs = {
|
|
|
48
48
|
],
|
|
49
49
|
theming: {
|
|
50
50
|
targets: [
|
|
51
|
-
{className: 'astryx-
|
|
51
|
+
{className: 'astryx-status-dot', visualProps: ['variant']},
|
|
52
|
+
// Still emitted beside the names above, so themes written against
|
|
53
|
+
// them keep working. Drop in the next major.
|
|
54
|
+
{className: 'astryx-statusdot', visualProps: ['variant'], deprecatedFor: 'status-dot'},
|
|
52
55
|
],
|
|
53
56
|
},
|
|
54
57
|
usage: {
|
|
@@ -105,7 +108,10 @@ export const docsZh = {
|
|
|
105
108
|
],
|
|
106
109
|
theming: {
|
|
107
110
|
targets: [
|
|
108
|
-
{className: 'astryx-
|
|
111
|
+
{className: 'astryx-status-dot', visualProps: ['variant']},
|
|
112
|
+
// Still emitted beside the names above, so themes written against
|
|
113
|
+
// them keep working. Drop in the next major.
|
|
114
|
+
{className: 'astryx-statusdot', visualProps: ['variant'], deprecatedFor: 'status-dot'},
|
|
109
115
|
],
|
|
110
116
|
},
|
|
111
117
|
usage: {
|
|
@@ -189,3 +189,12 @@ describe('StatusDot', () => {
|
|
|
189
189
|
});
|
|
190
190
|
});
|
|
191
191
|
});
|
|
192
|
+
|
|
193
|
+
describe('StatusDot theme target names', () => {
|
|
194
|
+
it('renders the deprecated class beside the current one', () => {
|
|
195
|
+
render(<StatusDot variant="success" label="Online" />);
|
|
196
|
+
const dot = screen.getByRole('img', {name: 'Online'});
|
|
197
|
+
expect(dot).toHaveClass('astryx-status-dot');
|
|
198
|
+
expect(dot).toHaveClass('astryx-statusdot');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -200,7 +200,13 @@ export function StatusDot({
|
|
|
200
200
|
role="img"
|
|
201
201
|
aria-label={label}
|
|
202
202
|
{...mergeProps(
|
|
203
|
-
themeProps(
|
|
203
|
+
themeProps(
|
|
204
|
+
'status-dot',
|
|
205
|
+
{variant},
|
|
206
|
+
// `statusdot` ran the compound name together; themes styling it keep
|
|
207
|
+
// working until the next major.
|
|
208
|
+
{legacyNames: ['statusdot']},
|
|
209
|
+
),
|
|
204
210
|
stylex.props(
|
|
205
211
|
styles.base,
|
|
206
212
|
variants[variant],
|