@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
|
@@ -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],
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
|
+
|
|
5
|
+
export const docs = {
|
|
6
|
+
name: 'Step',
|
|
7
|
+
subComponentOf: 'Stepper',
|
|
8
|
+
displayName: 'Step',
|
|
9
|
+
group: 'Stepper',
|
|
10
|
+
category: 'Navigation',
|
|
11
|
+
isHiddenFromOverview: true,
|
|
12
|
+
description:
|
|
13
|
+
'Individual step within a Stepper. Renders a progress-bar segment, an indicator, and a label with optional description. Progress (completed/active/not-started) is derived from the parent Stepper\u2019s activeStep and this step\u2019s step index.',
|
|
14
|
+
props: [
|
|
15
|
+
{
|
|
16
|
+
name: 'step',
|
|
17
|
+
type: 'number',
|
|
18
|
+
description:
|
|
19
|
+
'Zero-based index of this step. Used to derive progress (completed/active/not-started) relative to the parent activeStep.',
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'label',
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'Step label text.',
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'description',
|
|
30
|
+
type: 'string',
|
|
31
|
+
description:
|
|
32
|
+
'Optional description shown below the label for additional context.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'children',
|
|
36
|
+
type: 'ReactNode',
|
|
37
|
+
description:
|
|
38
|
+
'Content rendered below the label and description. Useful in vertical steppers for form fields or detailed step content.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'status',
|
|
42
|
+
type: "'accent' | 'success' | 'warning' | 'error'",
|
|
43
|
+
description:
|
|
44
|
+
'Semantic color for the step. Controls color only and maps to the global Astryx semantic tokens. Leave unset for the progress-derived default coloring.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'indicator',
|
|
48
|
+
type: "'auto' | 'number' | 'none' | ReactNode",
|
|
49
|
+
description:
|
|
50
|
+
"What to show as the step indicator. 'auto' shows a number until completed then a check, 'number' always shows a numbered badge, 'none' hides it, or pass any ReactNode (e.g. an Icon) for a fully custom indicator.",
|
|
51
|
+
slotElements: [{__element: 'Icon', props: {icon: 'check', size: 'sm'}}],
|
|
52
|
+
default: "'auto'",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'isDisabled',
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
description:
|
|
58
|
+
'Disables interaction and dims the step indicator and label.',
|
|
59
|
+
default: 'false',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'isOptional',
|
|
63
|
+
type: 'boolean',
|
|
64
|
+
description:
|
|
65
|
+
'Marks the step as optional, appending an "Optional" affordance after the label.',
|
|
66
|
+
default: 'false',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'endContent',
|
|
70
|
+
type: 'ReactNode',
|
|
71
|
+
description: 'Trailing content rendered at the end of the label row.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'density',
|
|
75
|
+
type: "'compact' | 'balanced' | 'spacious'",
|
|
76
|
+
description:
|
|
77
|
+
'Controls vertical padding of the step. Falls back to the stepper-level density when unset.',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
// A Step reads its progress from the parent Stepper's context and throws
|
|
81
|
+
// without one, so the preview needs a real Stepper around it. Without this
|
|
82
|
+
// block Step inherits Stepper's playground, which renders it bare and hands
|
|
83
|
+
// it the parent's `activeStep`. The wrapper is vertical because that is the
|
|
84
|
+
// orientation where one step shows its whole anatomy — indicator, label, and
|
|
85
|
+
// description stacked — and `step` matches the wrapper's `activeStep` so the
|
|
86
|
+
// preview opens on the current step rather than an inert upcoming one.
|
|
87
|
+
playground: {
|
|
88
|
+
wrapper: {
|
|
89
|
+
component: 'Stepper',
|
|
90
|
+
props: {activeStep: 1, orientation: 'vertical'},
|
|
91
|
+
},
|
|
92
|
+
defaults: {
|
|
93
|
+
step: 1,
|
|
94
|
+
label: 'Billing address',
|
|
95
|
+
description: 'Used for invoices and tax',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
};
|