@astryxdesign/core 0.7.5 → 0.7.6-canary.0bd3b37
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/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +5 -5
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +183 -5
- package/dist/AppShell/observeMainOverflow.d.ts +9 -0
- package/dist/AppShell/observeMainOverflow.d.ts.map +1 -0
- package/dist/AppShell/observeMainOverflow.js +125 -0
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +12 -3
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +8 -1
- package/dist/BottomSheet/BottomSheet.js +1 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +2 -1
- package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +30 -3
- package/dist/Button/Button.js +4 -4
- package/dist/Carousel/Carousel.d.ts +3 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +12 -3
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +6 -5
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +37 -4
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +49 -6
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +12 -4
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +108 -23
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +8 -3
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +11 -7
- package/dist/DateInput/usePointerDragScroll.d.ts +10 -1
- package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
- package/dist/DateInput/usePointerDragScroll.js +25 -9
- package/dist/DateInput/useScrollSettle.d.ts +3 -1
- package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
- package/dist/DateInput/useScrollSettle.js +37 -8
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +9 -5
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +23 -12
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
- package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +34 -9
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +5 -4
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +2 -1
- package/dist/Drawer/Drawer.d.ts +1 -0
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +7 -2
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +35 -22
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuGroup.js +2 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -16
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +2 -1
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +31 -6
- package/dist/Field/InputClearButton.js +3 -3
- package/dist/Field/PanelSearchInput.js +2 -2
- package/dist/FieldStatus/FieldStatus.d.ts +3 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +3 -2
- package/dist/FileInput/FileInput.d.ts +3 -0
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +66 -34
- package/dist/Heading/Heading.js +1 -1
- package/dist/Icon/Icon.js +1 -1
- package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckIndicator.js +2 -1
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +3 -1
- package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
- package/dist/Indicator/RadioIndicator.js +3 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +21 -7
- package/dist/Item/ItemSwipeLayer.js +1 -1
- package/dist/Layer/popoverOperations.d.ts +27 -0
- package/dist/Layer/popoverOperations.d.ts.map +1 -0
- package/dist/Layer/popoverOperations.js +159 -0
- package/dist/Layer/useLayer.d.ts +1 -1
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +120 -65
- package/dist/Layer/useTouchTrigger.d.ts +9 -0
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
- package/dist/Layer/useTouchTrigger.js +1 -1
- package/dist/Layout/Layout.js +1 -1
- package/dist/Layout/LayoutContent.js +1 -1
- package/dist/Layout/LayoutFooter.js +1 -1
- package/dist/Layout/LayoutHeader.js +1 -1
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -0
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +18 -4
- package/dist/List/List.js +1 -1
- package/dist/List/ListItem.js +3 -3
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +7 -2
- package/dist/MultiSelector/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +45 -19
- package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenuItem.js +5 -29
- package/dist/NumberInput/NumberInput.d.ts +3 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +21 -4
- package/dist/NumberInput/numberParser.d.ts +3 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -1
- package/dist/NumberInput/numberParser.js +7 -44
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +27 -0
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +32 -12
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +10 -3
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +37 -30
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +16 -12
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +11 -3
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +81 -12
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +9 -6
- package/dist/Selector/hooks.js +2 -2
- package/dist/Selector/useSelectorPresentation.d.ts +8 -1
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
- package/dist/Selector/useSelectorPresentation.js +20 -4
- package/dist/SideNav/SideNavItem.d.ts +2 -2
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +18 -7
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +100 -12
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +3 -3
- package/dist/Stack/Stack.js +1 -1
- package/dist/Stack/StackItem.js +1 -1
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +26 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +10 -3
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +16 -1
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +36 -10
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +46 -58
- package/dist/Text/Text.js +1 -1
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +23 -5
- package/dist/TextArea/TextArea.d.ts +1 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +13 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -3
- package/dist/TimeInput/TimeInput.d.ts +6 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +21 -14
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +5 -4
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +2 -2
- package/dist/Timestamp/TimestampHoverCard.js +4 -4
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +60 -20
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +101 -54
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +7 -1
- package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButtonGroup.js +16 -2
- package/dist/Token/Token.d.ts +1 -1
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +52 -5
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +14 -2
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +95 -54
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
- package/dist/Tokenizer/TokenizerBottomSheet.js +11 -17
- package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts +2 -0
- package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts.map +1 -0
- package/dist/Tokenizer/TokenizerClearAllMessageContext.js +17 -0
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +2 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +3 -0
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +1 -0
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +27 -4
- package/dist/Typeahead/BaseTypeahead.d.ts +4 -4
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +52 -9
- package/dist/Typeahead/Typeahead.d.ts +1 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +43 -9
- package/dist/astryx.css +26 -5
- package/dist/gestures/GestureArena.d.ts +32 -1
- package/dist/gestures/GestureArena.d.ts.map +1 -1
- package/dist/gestures/GestureArena.js +110 -9
- package/dist/gestures/GestureHost.d.ts +351 -0
- package/dist/gestures/GestureHost.d.ts.map +1 -0
- package/dist/gestures/GestureHost.js +1773 -0
- package/dist/gestures/GestureRecognizer.d.ts +13 -1
- package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/GestureRecognizer.js +19 -1
- package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
- package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/LongPressGestureRecognizer.js +3 -0
- package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
- package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/PanGestureRecognizer.js +3 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/PinchGestureRecognizer.js +128 -0
- package/dist/gestures/PressTracker.d.ts +112 -0
- package/dist/gestures/PressTracker.d.ts.map +1 -0
- package/dist/gestures/PressTracker.js +267 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/SwipeGestureRecognizer.js +148 -0
- package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
- package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/TapGestureRecognizer.js +3 -0
- package/dist/gestures/VelocityTracker.d.ts +6 -2
- package/dist/gestures/VelocityTracker.d.ts.map +1 -1
- package/dist/gestures/VelocityTracker.js +7 -3
- package/dist/gestures/haptics.d.ts +65 -0
- package/dist/gestures/haptics.d.ts.map +1 -0
- package/dist/gestures/haptics.js +182 -0
- package/dist/gestures/index.d.ts +37 -0
- package/dist/gestures/index.d.ts.map +1 -0
- package/dist/gestures/index.js +25 -0
- package/dist/gestures/nativeScroll.d.ts +42 -0
- package/dist/gestures/nativeScroll.d.ts.map +1 -0
- package/dist/gestures/nativeScroll.js +228 -0
- package/dist/gestures/touchAction.d.ts +60 -0
- package/dist/gestures/touchAction.d.ts.map +1 -0
- package/dist/gestures/touchAction.js +157 -0
- package/dist/gestures/touchActionRule.d.ts +34 -0
- package/dist/gestures/touchActionRule.d.ts.map +1 -0
- package/dist/gestures/touchActionRule.js +140 -0
- package/dist/gestures/types.d.ts +18 -7
- package/dist/gestures/types.d.ts.map +1 -1
- package/dist/gestures/types.js +22 -2
- package/dist/gestures/useGestureRecognizer.d.ts +56 -0
- package/dist/gestures/useGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/useGestureRecognizer.js +226 -0
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/modalAnnounce.d.ts.map +1 -1
- package/dist/hooks/modalAnnounce.js +107 -61
- package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -1
- package/dist/hooks/scrollKeyboardDelegation.js +7 -3
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
- package/dist/hooks/useAdaptivePresentation.js +4 -1
- package/dist/hooks/useAnnounce.d.ts +101 -42
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +161 -75
- package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
- package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
- package/dist/hooks/useAnnounceRenderedText.js +5 -3
- package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
- package/dist/hooks/useBusyAnnouncement.js +6 -12
- package/dist/hooks/useMenuHover.d.ts.map +1 -1
- package/dist/hooks/useMenuHover.js +12 -1
- package/dist/hooks/useScrollOverflow.d.ts +2 -1
- package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
- package/dist/hooks/useScrollOverflow.js +56 -10
- package/dist/i18n/generated-locales/af-ZA.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/af-ZA.generated.js +0 -5
- package/dist/i18n/generated-locales/ar-SA.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ar-SA.generated.js +0 -5
- package/dist/i18n/generated-locales/ca-ES.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ca-ES.generated.js +0 -5
- package/dist/i18n/generated-locales/cs-CZ.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/cs-CZ.generated.js +0 -5
- package/dist/i18n/generated-locales/da-DK.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/da-DK.generated.js +0 -5
- package/dist/i18n/generated-locales/de-DE.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/de-DE.generated.js +0 -5
- package/dist/i18n/generated-locales/el-GR.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/el-GR.generated.js +0 -5
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +8 -5
- package/dist/i18n/generated-locales/es-ES.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/es-ES.generated.js +0 -5
- package/dist/i18n/generated-locales/fi-FI.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/fi-FI.generated.js +0 -5
- package/dist/i18n/generated-locales/fr-FR.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/fr-FR.generated.js +0 -5
- package/dist/i18n/generated-locales/he-IL.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/he-IL.generated.js +0 -5
- package/dist/i18n/generated-locales/hu-HU.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/hu-HU.generated.js +0 -5
- package/dist/i18n/generated-locales/it-IT.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/it-IT.generated.js +0 -5
- package/dist/i18n/generated-locales/ja-JP.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ja-JP.generated.js +0 -5
- package/dist/i18n/generated-locales/ko-KR.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ko-KR.generated.js +0 -5
- package/dist/i18n/generated-locales/nl-NL.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/nl-NL.generated.js +0 -5
- package/dist/i18n/generated-locales/no-NO.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/no-NO.generated.js +0 -5
- package/dist/i18n/generated-locales/pl-PL.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pl-PL.generated.js +0 -5
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +8 -5
- package/dist/i18n/generated-locales/pt-BR.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pt-BR.generated.js +0 -5
- package/dist/i18n/generated-locales/pt-PT.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pt-PT.generated.js +0 -5
- package/dist/i18n/generated-locales/ro-RO.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ro-RO.generated.js +0 -5
- package/dist/i18n/generated-locales/ru-RU.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/ru-RU.generated.js +0 -5
- package/dist/i18n/generated-locales/sr-SP.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/sr-SP.generated.js +0 -5
- package/dist/i18n/generated-locales/sv-SE.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/sv-SE.generated.js +0 -5
- package/dist/i18n/generated-locales/tr-TR.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/tr-TR.generated.js +0 -5
- package/dist/i18n/generated-locales/uk-UA.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/uk-UA.generated.js +0 -5
- package/dist/i18n/generated-locales/vi-VN.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/vi-VN.generated.js +0 -5
- package/dist/i18n/generated-locales/zh-CN.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/zh-CN.generated.js +0 -5
- package/dist/i18n/generated-locales/zh-TW.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/zh-TW.generated.js +0 -5
- package/dist/i18n/useListFormatter.d.ts +9 -0
- package/dist/i18n/useListFormatter.d.ts.map +1 -0
- package/dist/i18n/useListFormatter.js +41 -0
- package/dist/motion/animator.d.ts +83 -8
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +701 -119
- package/dist/motion/coast.d.ts +4 -1
- package/dist/motion/coast.d.ts.map +1 -1
- package/dist/motion/coast.js +4 -2
- package/dist/motion/reducedMotion.d.ts.map +1 -1
- package/dist/motion/reducedMotion.js +6 -2
- package/dist/motion/reducedMotionPlan.d.ts +7 -0
- package/dist/motion/reducedMotionPlan.d.ts.map +1 -1
- package/dist/motion/reducedMotionPlan.js +14 -1
- package/dist/motion/resolveMotion.d.ts +42 -0
- package/dist/motion/resolveMotion.d.ts.map +1 -0
- package/dist/motion/resolveMotion.js +43 -0
- package/dist/motion/roleValue.d.ts +2 -1
- package/dist/motion/roleValue.d.ts.map +1 -1
- package/dist/motion/roleValue.js +2 -1
- package/dist/motion/uikit/timing.d.ts +7 -1
- package/dist/motion/uikit/timing.d.ts.map +1 -1
- package/dist/motion/uikit/timing.js +19 -1
- package/dist/theme/defineTheme.d.ts +19 -5
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +64 -4
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
- package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
- package/dist/theme/domainTokens/index.d.ts +5 -4
- package/dist/theme/domainTokens/index.d.ts.map +1 -1
- package/dist/theme/domainTokens/index.js +5 -9
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/motionKnobs.d.ts +56 -0
- package/dist/theme/motionKnobs.d.ts.map +1 -0
- package/dist/theme/motionKnobs.js +48 -0
- package/dist/theme/resolveThemeValues.d.ts +11 -4
- package/dist/theme/resolveThemeValues.d.ts.map +1 -1
- package/dist/theme/resolveThemeValues.js +40 -4
- package/dist/theme/themeAdaptations.d.ts +7 -3
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +36 -7
- package/dist/theme/themeMotion.d.ts +96 -0
- package/dist/theme/themeMotion.d.ts.map +1 -0
- package/dist/theme/themeMotion.js +177 -0
- package/dist/theme/tokenReferences.d.ts +31 -0
- package/dist/theme/tokenReferences.d.ts.map +1 -0
- package/dist/theme/tokenReferences.js +132 -0
- package/dist/theme/tokens.d.ts +1 -0
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +9 -129
- package/dist/theme/tokens.stylex.d.ts +12 -0
- package/dist/theme/tokens.stylex.d.ts.map +1 -1
- package/dist/theme/tokens.stylex.js +12 -0
- package/dist/utils/focusOutline.stylex.d.ts +6 -0
- package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
- package/dist/utils/focusOutline.stylex.js +7 -0
- package/dist/utils/focusReturn.d.ts +17 -1
- package/dist/utils/focusReturn.d.ts.map +1 -1
- package/dist/utils/focusReturn.js +11 -4
- package/dist/utils/getNodeText.d.ts +8 -0
- package/dist/utils/getNodeText.d.ts.map +1 -0
- package/dist/utils/getNodeText.js +37 -0
- package/dist/utils/interactionModality.d.ts +11 -2
- package/dist/utils/interactionModality.d.ts.map +1 -1
- package/dist/utils/interactionModality.js +58 -5
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +17 -8
- package/dist/utils/plainDate.d.ts +2 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +46 -3
- package/dist/utils/presentation.d.ts +50 -0
- package/dist/utils/presentation.d.ts.map +1 -0
- package/dist/utils/presentation.js +125 -0
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +20 -1
- package/dist/utils/primaryClick.d.ts +11 -0
- package/dist/utils/primaryClick.d.ts.map +1 -0
- package/dist/utils/primaryClick.js +25 -0
- package/dist/utils/sharedMutationObserver.d.ts +19 -11
- package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
- package/dist/utils/sharedMutationObserver.js +66 -26
- package/dist/utils/timeFormat.d.ts +47 -0
- package/dist/utils/timeFormat.d.ts.map +1 -0
- package/dist/utils/timeFormat.js +240 -0
- package/dist/utils/touchPresentation.d.ts +2 -2
- package/dist/utils/touchPresentation.d.ts.map +1 -1
- package/dist/utils/touchPresentation.js +13 -8
- package/dist/utils/touchPresentation.stylex.d.ts +15 -0
- package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
- package/dist/utils/touchPresentation.stylex.js +33 -0
- package/dist/utils/touchQueries.d.ts +13 -0
- package/dist/utils/touchQueries.d.ts.map +1 -0
- package/dist/utils/touchQueries.js +15 -0
- package/dist/utils/unicodeDigits.d.ts +20 -0
- package/dist/utils/unicodeDigits.d.ts.map +1 -0
- package/dist/utils/unicodeDigits.js +70 -0
- package/dist/utils/useFocusAcrossSwap.d.ts +19 -0
- package/dist/utils/useFocusAcrossSwap.d.ts.map +1 -0
- package/dist/utils/useFocusAcrossSwap.js +41 -0
- package/locales/af-ZA.json +0 -21
- package/locales/ar-SA.json +0 -21
- package/locales/ca-ES.json +0 -21
- package/locales/cs-CZ.json +0 -21
- package/locales/da-DK.json +0 -21
- package/locales/de-DE.json +0 -21
- package/locales/el-GR.json +0 -21
- package/locales/en.json +35 -23
- package/locales/es-ES.json +0 -21
- package/locales/fi-FI.json +0 -21
- package/locales/fr-FR.json +0 -21
- package/locales/he-IL.json +0 -21
- package/locales/hu-HU.json +0 -21
- package/locales/it-IT.json +0 -21
- package/locales/ja-JP.json +0 -21
- package/locales/ko-KR.json +0 -21
- package/locales/nl-NL.json +0 -21
- package/locales/no-NO.json +0 -21
- package/locales/pl-PL.json +0 -21
- package/locales/pseudo.json +23 -14
- package/locales/pt-BR.json +0 -21
- package/locales/pt-PT.json +0 -21
- package/locales/ro-RO.json +0 -21
- package/locales/ru-RU.json +0 -21
- package/locales/sr-SP.json +0 -21
- package/locales/sv-SE.json +0 -21
- package/locales/tr-TR.json +0 -21
- package/locales/uk-UA.json +0 -21
- package/locales/vi-VN.json +0 -21
- package/locales/zh-CN.json +0 -21
- package/locales/zh-TW.json +0 -21
- package/package.json +19 -5
- package/src/AlertDialog/AlertDialog.tsx +6 -5
- package/src/AppShell/AppShell.doc.mjs +1 -1
- package/src/AppShell/AppShell.spec.md +9 -12
- package/src/AppShell/AppShell.tsx +225 -5
- package/src/AppShell/observeMainOverflow.ts +143 -0
- package/src/Avatar/Avatar.spec.md +22 -22
- package/src/Avatar/Avatar.tsx +18 -1
- package/src/Badge/Badge.doc.mjs +1 -1
- package/src/Badge/Badge.tsx +20 -2
- package/src/BottomSheet/BottomSheet.tsx +1 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
- package/src/BottomSheet/useSheetGestures.ts +37 -6
- package/src/Button/Button.tsx +4 -4
- package/src/Calendar/Calendar.spec.md +87 -48
- package/src/Carousel/Carousel.doc.mjs +1 -1
- package/src/Carousel/Carousel.spec.md +9 -9
- package/src/Carousel/Carousel.tsx +10 -2
- package/src/Chat/ChatComposer.spec.md +75 -59
- package/src/Chat/ChatComposerTokenElement.spec.md +45 -33
- package/src/Chat/ChatDictationButton.spec.md +126 -81
- package/src/Chat/ChatLayout.spec.md +41 -36
- package/src/Chat/ChatLayoutScrollButton.spec.md +87 -103
- package/src/Chat/ChatMessage.spec.md +64 -65
- package/src/Chat/ChatSendButton.spec.md +78 -67
- package/src/CheckboxInput/CheckboxInput.tsx +6 -5
- package/src/Citation/Citation.spec.md +60 -47
- package/src/ClickableCard/ClickableCard.tsx +48 -4
- package/src/Collapsible/Collapsible.spec.md +2 -0
- package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
- package/src/ComplexSelector/ComplexSelector.tsx +60 -6
- package/src/ContextMenu/ContextMenu.spec.md +84 -56
- package/src/ContextMenu/ContextMenuItem.spec.md +132 -0
- package/src/DateInput/DateInput.spec.md +74 -57
- package/src/DateInput/DateInput.tsx +29 -14
- package/src/DateInput/MonthScroller.tsx +108 -24
- package/src/DateInput/TouchDateField.tsx +14 -3
- package/src/DateInput/Wheel.tsx +9 -6
- package/src/DateInput/usePointerDragScroll.ts +34 -10
- package/src/DateInput/useScrollSettle.ts +38 -7
- package/src/DateRangeInput/DateRangeInput.tsx +34 -15
- package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
- package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
- package/src/DateTimeInput/DateTimeInput.tsx +46 -24
- package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
- package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
- package/src/Dialog/Dialog.tsx +42 -9
- package/src/Dialog/DialogHeader.tsx +5 -4
- package/src/Divider/Divider.tsx +2 -1
- package/src/Drawer/Drawer.spec.md +111 -80
- package/src/Drawer/Drawer.tsx +13 -2
- package/src/Drawer/DrawerHeader.spec.md +181 -0
- package/src/DropdownMenu/DropdownMenu.spec.md +198 -218
- package/src/DropdownMenu/DropdownMenu.tsx +43 -21
- package/src/DropdownMenu/DropdownMenuCheckboxItem.spec.md +192 -0
- package/src/DropdownMenu/DropdownMenuDivider.spec.md +25 -31
- package/src/DropdownMenu/DropdownMenuGroup.spec.md +145 -0
- package/src/DropdownMenu/DropdownMenuGroup.tsx +2 -1
- package/src/DropdownMenu/DropdownMenuItem.spec.md +48 -42
- package/src/DropdownMenu/DropdownMenuRadioGroup.spec.md +34 -37
- package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +54 -53
- package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +47 -41
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
- package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
- package/src/EmptyState/EmptyState.spec.md +35 -29
- package/src/EmptyState/EmptyState.tsx +2 -1
- package/src/Field/Field.doc.mjs +2 -1
- package/src/Field/FieldLabel.doc.mjs +4 -2
- package/src/Field/FieldLabel.spec.md +30 -21
- package/src/Field/FieldLabel.tsx +42 -7
- package/src/Field/InputClearButton.tsx +3 -3
- package/src/Field/PanelSearchInput.tsx +2 -2
- package/src/FieldStatus/FieldStatus.tsx +9 -2
- package/src/FileInput/FileInput.tsx +73 -29
- package/src/FormLayout/FormLayout.spec.md +11 -20
- package/src/Heading/Heading.tsx +1 -1
- package/src/Icon/Icon.tsx +1 -1
- package/src/Indicator/CheckIndicator.spec.md +47 -42
- package/src/Indicator/CheckIndicator.tsx +2 -1
- package/src/Indicator/CheckboxIndicator.spec.md +40 -37
- package/src/Indicator/CheckboxIndicator.tsx +3 -1
- package/src/Indicator/Indicator.spec.md +188 -0
- package/src/Indicator/RadioIndicator.tsx +3 -1
- package/src/Item/Item.tsx +16 -8
- package/src/Item/ItemSwipeLayer.tsx +1 -1
- package/src/Kbd/Kbd.spec.md +81 -38
- package/src/Layer/popoverOperations.ts +172 -0
- package/src/Layer/useLayer.tsx +145 -77
- package/src/Layer/useTouchTrigger.ts +1 -1
- package/src/Layout/Layout.spec.md +127 -131
- package/src/Layout/Layout.tsx +1 -1
- package/src/Layout/LayoutContent.spec.md +205 -0
- package/src/Layout/LayoutContent.tsx +1 -1
- package/src/Layout/LayoutFooter.spec.md +190 -0
- package/src/Layout/LayoutFooter.tsx +1 -1
- package/src/Layout/LayoutHeader.spec.md +193 -0
- package/src/Layout/LayoutHeader.tsx +1 -1
- package/src/Layout/LayoutPanel.spec.md +194 -0
- package/src/Lightbox/Lightbox.spec.md +249 -61
- package/src/Lightbox/Lightbox.tsx +5 -0
- package/src/Link/Link.spec.md +3 -2
- package/src/Link/Link.tsx +20 -2
- package/src/List/List.tsx +1 -1
- package/src/List/ListItem.spec.md +205 -0
- package/src/List/ListItem.tsx +3 -3
- package/src/MetadataList/MetadataList.spec.md +187 -0
- package/src/MetadataList/MetadataListItem.spec.md +165 -0
- package/src/MobileNav/MobileNav.tsx +9 -1
- package/src/MultiSelector/MultiSelector.spec.md +124 -114
- package/src/MultiSelector/MultiSelector.tsx +44 -15
- package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
- package/src/NavMenu/NavHeadingMenuItem.tsx +5 -39
- package/src/NumberInput/NumberInput.doc.mjs +13 -7
- package/src/NumberInput/NumberInput.spec.md +59 -37
- package/src/NumberInput/NumberInput.tsx +37 -4
- package/src/NumberInput/numberParser.ts +7 -45
- package/src/Outline/Outline.spec.md +165 -69
- package/src/Outline/Outline.tsx +23 -0
- package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +3 -4
- package/src/OverflowList/OverflowList.spec.md +102 -55
- package/src/Pagination/Pagination.spec.md +158 -84
- package/src/Popover/Popover.tsx +34 -14
- package/src/Popover/usePopover.tsx +10 -3
- package/src/PowerSearch/PowerSearch.tsx +42 -31
- package/src/ProgressBar/ProgressBar.spec.md +143 -119
- package/src/ProgressBar/ProgressBar.tsx +58 -10
- package/src/RadioList/RadioList.spec.md +1 -1
- package/src/RadioList/RadioListItem.tsx +11 -2
- package/src/Resizable/Resizable.spec.md +144 -124
- package/src/Resizable/useResizable.ts +82 -16
- package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
- package/src/Selector/Selector.tsx +16 -6
- package/src/Selector/hooks.ts +2 -2
- package/src/Selector/useSelectorPresentation.ts +31 -3
- package/src/SideNav/SideNavItem.spec.md +14 -24
- package/src/SideNav/SideNavItem.tsx +27 -10
- package/src/Skeleton/Skeleton.tsx +3 -1
- package/src/Slider/Slider.spec.md +18 -16
- package/src/Slider/Slider.tsx +117 -12
- package/src/Spinner/Spinner.tsx +5 -3
- package/src/Stack/Stack.tsx +1 -1
- package/src/Stack/StackItem.tsx +1 -1
- package/src/Stepper/Step.spec.md +36 -42
- package/src/Stepper/Step.tsx +33 -6
- package/src/Stepper/Stepper.doc.mjs +1 -1
- package/src/Switch/Switch.spec.md +1 -1
- package/src/Switch/Switch.tsx +11 -3
- package/src/TabList/TabList.tsx +16 -1
- package/src/Table/Table.spec.md +1 -1
- package/src/Table/Table.tsx +43 -11
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
- package/src/Table/plugins/sortable/useTableSortable.tsx +44 -73
- package/src/Text/Text.tsx +1 -1
- package/src/Text/useTruncation.ts +23 -5
- package/src/TextArea/TextArea.spec.md +10 -13
- package/src/TextArea/TextArea.tsx +15 -1
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/TimeInput/TimeInput.doc.mjs +8 -8
- package/src/TimeInput/TimeInput.spec.md +58 -61
- package/src/TimeInput/TimeInput.tsx +36 -18
- package/src/TimeInput/TouchTimeField.tsx +4 -6
- package/src/Timestamp/Timestamp.spec.md +6 -12
- package/src/Timestamp/Timestamp.tsx +6 -2
- package/src/Timestamp/TimestampHoverCard.tsx +4 -4
- package/src/Toast/Toast.spec.md +15 -24
- package/src/Toast/Toast.tsx +104 -36
- package/src/Toast/ToastViewport.tsx +121 -53
- package/src/ToggleButton/ToggleButtonGroup.tsx +20 -1
- package/src/Token/Token.doc.mjs +2 -2
- package/src/Token/Token.spec.md +52 -61
- package/src/Token/Token.tsx +75 -5
- package/src/Token/TokenLink.tsx +21 -7
- package/src/Tokenizer/Tokenizer.spec.md +18 -4
- package/src/Tokenizer/Tokenizer.tsx +102 -60
- package/src/Tokenizer/TokenizerBottomSheet.tsx +11 -17
- package/src/Tokenizer/TokenizerClearAllMessageContext.ts +21 -0
- package/src/Toolbar/Toolbar.spec.md +5 -6
- package/src/Toolbar/Toolbar.tsx +2 -1
- package/src/TopNav/TopNavMegaMenu.tsx +4 -1
- package/src/TopNav/TopNavMenu.tsx +1 -0
- package/src/TreeList/TreeListItem.tsx +26 -4
- package/src/Typeahead/BaseTypeahead.doc.mjs +3 -3
- package/src/Typeahead/BaseTypeahead.spec.md +45 -45
- package/src/Typeahead/BaseTypeahead.tsx +66 -11
- package/src/Typeahead/Typeahead.tsx +51 -9
- package/src/gestures/GestureArena.ts +111 -11
- package/src/gestures/GestureHost.ts +2064 -0
- package/src/gestures/GestureRecognizer.ts +21 -1
- package/src/gestures/LongPressGestureRecognizer.ts +4 -0
- package/src/gestures/PanGestureRecognizer.ts +4 -0
- package/src/gestures/PinchGestureRecognizer.ts +148 -0
- package/src/gestures/PressTracker.ts +386 -0
- package/src/gestures/README.md +420 -0
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
- package/src/gestures/SwipeGestureRecognizer.ts +197 -0
- package/src/gestures/TapGestureRecognizer.ts +4 -0
- package/src/gestures/VelocityTracker.ts +10 -3
- package/src/gestures/haptics.ts +203 -0
- package/src/gestures/index.ts +79 -0
- package/src/gestures/nativeScroll.ts +277 -0
- package/src/gestures/touchAction.ts +191 -0
- package/src/gestures/touchActionRule.ts +157 -0
- package/src/gestures/types.ts +30 -9
- package/src/gestures/useGestureRecognizer.ts +305 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/modalAnnounce.ts +129 -72
- package/src/hooks/scrollKeyboardDelegation.ts +9 -3
- package/src/hooks/useAdaptivePresentation.ts +4 -1
- package/src/hooks/useAnnounce.doc.mjs +35 -3
- package/src/hooks/useAnnounce.ts +209 -102
- package/src/hooks/useAnnounceRenderedText.ts +17 -3
- package/src/hooks/useBusyAnnouncement.ts +7 -10
- package/src/hooks/useMenuHover.ts +15 -1
- package/src/hooks/useScrollOverflow.doc.mjs +1 -1
- package/src/hooks/useScrollOverflow.ts +59 -10
- package/src/i18n/generated-locales/af-ZA.generated.ts +0 -7
- package/src/i18n/generated-locales/ar-SA.generated.ts +0 -6
- package/src/i18n/generated-locales/ca-ES.generated.ts +0 -7
- package/src/i18n/generated-locales/cs-CZ.generated.ts +0 -6
- package/src/i18n/generated-locales/da-DK.generated.ts +0 -6
- package/src/i18n/generated-locales/de-DE.generated.ts +0 -6
- package/src/i18n/generated-locales/el-GR.generated.ts +0 -7
- package/src/i18n/generated-locales/en.generated.ts +9 -6
- package/src/i18n/generated-locales/es-ES.generated.ts +0 -7
- package/src/i18n/generated-locales/fi-FI.generated.ts +0 -6
- package/src/i18n/generated-locales/fr-FR.generated.ts +0 -7
- package/src/i18n/generated-locales/he-IL.generated.ts +0 -6
- package/src/i18n/generated-locales/hu-HU.generated.ts +0 -6
- package/src/i18n/generated-locales/it-IT.generated.ts +0 -7
- package/src/i18n/generated-locales/ja-JP.generated.ts +0 -6
- package/src/i18n/generated-locales/ko-KR.generated.ts +0 -6
- package/src/i18n/generated-locales/nl-NL.generated.ts +0 -6
- package/src/i18n/generated-locales/no-NO.generated.ts +0 -6
- package/src/i18n/generated-locales/pl-PL.generated.ts +0 -7
- package/src/i18n/generated-locales/pseudo.generated.ts +9 -6
- package/src/i18n/generated-locales/pt-BR.generated.ts +0 -7
- package/src/i18n/generated-locales/pt-PT.generated.ts +0 -7
- package/src/i18n/generated-locales/ro-RO.generated.ts +0 -6
- package/src/i18n/generated-locales/ru-RU.generated.ts +0 -7
- package/src/i18n/generated-locales/sr-SP.generated.ts +0 -6
- package/src/i18n/generated-locales/sv-SE.generated.ts +0 -6
- package/src/i18n/generated-locales/tr-TR.generated.ts +0 -7
- package/src/i18n/generated-locales/uk-UA.generated.ts +0 -7
- package/src/i18n/generated-locales/vi-VN.generated.ts +0 -6
- package/src/i18n/generated-locales/zh-CN.generated.ts +0 -6
- package/src/i18n/generated-locales/zh-TW.generated.ts +0 -6
- package/src/i18n/useListFormatter.ts +42 -0
- package/src/motion/MEASUREMENTS.md +2 -1
- package/src/motion/README.md +113 -33
- package/src/motion/animator.ts +932 -130
- package/src/motion/coast.ts +10 -3
- package/src/motion/reducedMotion.ts +12 -2
- package/src/motion/reducedMotionPlan.ts +20 -1
- package/src/motion/resolveMotion.ts +68 -0
- package/src/motion/roleValue.ts +2 -1
- package/src/motion/uikit/timing.ts +15 -1
- package/src/theme/Theme.doc.mjs +1 -1
- package/src/theme/defineTheme.ts +117 -8
- package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
- package/src/theme/domainTokens/index.ts +6 -10
- package/src/theme/index.ts +5 -0
- package/src/theme/motionKnobs.ts +82 -0
- package/src/theme/resolveThemeValues.ts +68 -6
- package/src/theme/themeAdaptations.ts +52 -12
- package/src/theme/themeMotion.ts +221 -0
- package/src/theme/tokenReferences.ts +149 -0
- package/src/theme/tokens.stylex.ts +10 -0
- package/src/theme/tokens.ts +15 -158
- package/src/utils/focusOutline.stylex.ts +28 -0
- package/src/utils/focusReturn.ts +17 -6
- package/src/utils/getNodeText.ts +37 -0
- package/src/utils/interactionModality.ts +64 -5
- package/src/utils/interactionOverlay.stylex.ts +12 -3
- package/src/utils/plainDate.ts +58 -3
- package/src/utils/presentation.ts +180 -0
- package/src/utils/pressFeedback.ts +34 -11
- package/src/utils/primaryClick.ts +28 -0
- package/src/utils/sharedMutationObserver.ts +87 -29
- package/src/utils/timeFormat.ts +314 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.ts +13 -8
- package/src/utils/touchQueries.ts +15 -0
- package/src/utils/unicodeDigits.ts +71 -0
- package/src/utils/useFocusAcrossSwap.ts +55 -0
- package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts +0 -2
- package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.js +0 -132
- package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +0 -2
- package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +0 -78
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +0 -2
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +0 -65
- package/dist/List/ListMarkers.a11y.chromium.spec.d.ts +0 -2
- package/dist/List/ListMarkers.a11y.chromium.spec.js +0 -677
- package/dist/Markdown/Markdown.fr23.bench.d.ts +0 -2
- package/dist/Markdown/Markdown.fr23.bench.d.ts.map +0 -1
- package/dist/Markdown/Markdown.fr23.bench.js +0 -152
- package/dist/Markdown/MarkdownTable.a11y.chromium.spec.d.ts +0 -2
- package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +0 -590
- package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.d.ts +0 -2
- package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.js +0 -657
- package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.d.ts +0 -2
- package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +0 -153
- package/dist/MultiSelector/CreateRow.a11y.chromium.spec.d.ts +0 -2
- package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +0 -116
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.d.ts +0 -2
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +0 -49
- package/dist/MultiSelector/OptionActions.a11y.chromium.spec.d.ts +0 -2
- package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +0 -273
- package/dist/Outline/OutlineFocus.a11y.chromium.spec.d.ts +0 -2
- package/dist/Outline/OutlineFocus.a11y.chromium.spec.js +0 -421
- package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts +0 -2
- package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.js +0 -118
- package/dist/reset.a11y.chromium.spec.d.ts +0 -2
- package/dist/reset.a11y.chromium.spec.js +0 -231
- package/dist/reset.until-found.a11y.browser.spec.d.ts +0 -2
- package/dist/reset.until-found.a11y.browser.spec.js +0 -72
- package/src/AlertDialog/AlertDialog.test.tsx +0 -519
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +0 -116
- package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +0 -52
- package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +0 -68
- package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +0 -144
- package/src/AlertDialog/useImperativeAlertDialog.test.tsx +0 -163
- package/src/AppShell/AppShell.test.tsx +0 -1148
- package/src/AspectRatio/AspectRatio.test.tsx +0 -398
- package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +0 -158
- package/src/Avatar/Avatar.test.tsx +0 -867
- package/src/Avatar/AvatarStatusDot.test.tsx +0 -306
- package/src/AvatarGroup/AvatarGroup.test.tsx +0 -313
- package/src/AvatarGroup/AvatarGroupOverflow.test.tsx +0 -263
- package/src/Badge/Badge.test.tsx +0 -125
- package/src/Banner/Banner.test.tsx +0 -879
- package/src/Blockquote/Blockquote.test.tsx +0 -121
- package/src/BottomSheet/BottomSheet.test.tsx +0 -3108
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +0 -248
- package/src/BottomSheet/BottomSheetKeyboard.test.tsx +0 -195
- package/src/BottomSheet/BottomSheetPanel.test.tsx +0 -549
- package/src/BottomSheet/BottomSheetReplace.test.tsx +0 -1638
- package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +0 -246
- package/src/BottomSheet/BottomSheetStacking.test.tsx +0 -3184
- package/src/BottomSheet/BottomSheetSwitcher.test.tsx +0 -2010
- package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +0 -129
- package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +0 -97
- package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +0 -415
- package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +0 -462
- package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +0 -247
- package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +0 -83
- package/src/BottomSheet/snapOffsets.test.ts +0 -254
- package/src/BottomSheet/useSheetGestures.test.ts +0 -1638
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +0 -921
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +0 -120
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.renders.tsx +0 -45
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.states.ts +0 -81
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.test.tsx +0 -125
- package/src/Button/Button.test.tsx +0 -864
- package/src/Button/__tests__/Button.a11y.chromium.spec.ts +0 -355
- package/src/Button/__tests__/Button.a11y.harnesses.tsx +0 -47
- package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -25
- package/src/Button/__tests__/Button.a11y.renders.tsx +0 -139
- package/src/Button/__tests__/Button.a11y.states.ts +0 -317
- package/src/Button/__tests__/Button.a11y.test.tsx +0 -187
- package/src/ButtonGroup/ButtonGroup.test.tsx +0 -1025
- package/src/Calendar/Calendar.test.tsx +0 -2186
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +0 -127
- package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +0 -12
- package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +0 -57
- package/src/Calendar/__tests__/Calendar.a11y.states.ts +0 -139
- package/src/Calendar/__tests__/Calendar.a11y.test.tsx +0 -137
- package/src/Calendar/dayCellUtils.test.ts +0 -520
- package/src/Calendar/getInitialFocusDate.test.ts +0 -94
- package/src/Calendar/getStandaloneShortWeekdayNames.test.ts +0 -54
- package/src/Calendar/hooks/useCalendarConstraints.test.ts +0 -153
- package/src/Calendar/hooks/useCalendarDays.test.ts +0 -265
- package/src/Calendar/hooks/useCalendarNavigation.test.ts +0 -252
- package/src/Card/Card.test.tsx +0 -202
- package/src/Carousel/Carousel.test.tsx +0 -915
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +0 -193
- package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +0 -27
- package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +0 -39
- package/src/Carousel/__tests__/Carousel.a11y.states.ts +0 -139
- package/src/Carousel/__tests__/Carousel.a11y.test.tsx +0 -127
- package/src/Center/Center.test.tsx +0 -406
- package/src/Chat/ChatComposer.test.tsx +0 -364
- package/src/Chat/ChatComposerDrawer.test.tsx +0 -130
- package/src/Chat/ChatComposerInput.test.tsx +0 -2136
- package/src/Chat/ChatComposerTokenElement.test.tsx +0 -85
- package/src/Chat/ChatDictationButton.test.tsx +0 -108
- package/src/Chat/ChatLayout.test.tsx +0 -311
- package/src/Chat/ChatLayoutScrollButton.test.tsx +0 -99
- package/src/Chat/ChatMessage.test.tsx +0 -344
- package/src/Chat/ChatMessageBubble.test.tsx +0 -294
- package/src/Chat/ChatMessageList.test.tsx +0 -198
- package/src/Chat/ChatMessageMetadata.test.tsx +0 -66
- package/src/Chat/ChatPastedTextToken.test.tsx +0 -71
- package/src/Chat/ChatSendButton.test.tsx +0 -309
- package/src/Chat/ChatSystemMessage.test.tsx +0 -189
- package/src/Chat/ChatTokenizedText.test.tsx +0 -163
- package/src/Chat/ChatToolCalls.test.tsx +0 -413
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +0 -577
- package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +0 -740
- package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +0 -457
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +0 -91
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +0 -91
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +0 -465
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +0 -416
- package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +0 -1523
- package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +0 -1004
- package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +0 -574
- package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +0 -263
- package/src/Chat/__tests__/useChatStreamScroll.fixture.tsx +0 -61
- package/src/Chat/useChatDictation.test.tsx +0 -369
- package/src/Chat/useChatNewMessages.test.tsx +0 -209
- package/src/Chat/useChatPasteAsToken.test.ts +0 -191
- package/src/Chat/useChatStreamScroll.test.tsx +0 -381
- package/src/Chat/useTriggerMenu.test.tsx +0 -994
- package/src/CheckboxInput/CheckboxInput.test.tsx +0 -926
- package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +0 -354
- package/src/CheckboxInput/__tests__/Checkbox.a11y.known-failures.ts +0 -54
- package/src/CheckboxInput/__tests__/Checkbox.a11y.renders.tsx +0 -310
- package/src/CheckboxInput/__tests__/Checkbox.a11y.states.ts +0 -404
- package/src/CheckboxInput/__tests__/Checkbox.a11y.test.tsx +0 -128
- package/src/CheckboxList/CheckboxList.fr10.test.tsx +0 -51
- package/src/CheckboxList/CheckboxList.test.tsx +0 -1159
- package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +0 -1998
- package/src/Citation/Citation.test.tsx +0 -361
- package/src/ClickableCard/ClickableCard.test.tsx +0 -286
- package/src/Code/Code.test.tsx +0 -75
- package/src/CodeBlock/CodeBlock.highlightStyles.test.tsx +0 -87
- package/src/CodeBlock/CodeBlock.test.tsx +0 -752
- package/src/CodeBlock/CodeLanguage.test.tsx +0 -173
- package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +0 -290
- package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +0 -64
- package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +0 -126
- package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +0 -94
- package/src/CodeBlock/highlightRanges.test.ts +0 -253
- package/src/CodeBlock/languages.test.ts +0 -402
- package/src/CodeBlock/tokenizer.test.ts +0 -280
- package/src/CodeBlock/tokenizerBudget.test.ts +0 -112
- package/src/Collapsible/Collapsible.test.tsx +0 -620
- package/src/Collapsible/CollapsibleGroup.test.tsx +0 -656
- package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +0 -183
- package/src/Collapsible/__tests__/Collapsible.a11y.states.ts +0 -117
- package/src/Collapsible/__tests__/Collapsible.a11y.test.tsx +0 -140
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +0 -559
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +0 -45
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +0 -139
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +0 -135
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +0 -129
- package/src/Collapsible/useCollapsible.test.tsx +0 -236
- package/src/CommandPalette/CommandPalette.perf.test.ts +0 -100
- package/src/CommandPalette/CommandPalette.test.tsx +0 -750
- package/src/CommandPalette/CommandPaletteEmpty.test.tsx +0 -101
- package/src/CommandPalette/CommandPaletteFooter.test.tsx +0 -122
- package/src/CommandPalette/CommandPaletteGroup.test.tsx +0 -129
- package/src/CommandPalette/CommandPaletteInput.test.tsx +0 -539
- package/src/CommandPalette/CommandPaletteItem.test.tsx +0 -417
- package/src/CommandPalette/CommandPaletteList.test.tsx +0 -184
- package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +0 -600
- package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +0 -715
- package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +0 -582
- package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +0 -336
- package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +0 -523
- package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +0 -76
- package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +0 -262
- package/src/ComplexSelector/ComplexSelector.test.tsx +0 -1023
- package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +0 -965
- package/src/ContextMenu/ContextMenu.test.tsx +0 -1582
- package/src/ContextMenu/ContextMenu.triggerProps.test.tsx +0 -54
- package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +0 -439
- package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +0 -154
- package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +0 -117
- package/src/DateInput/DateInput.fr10.test.tsx +0 -283
- package/src/DateInput/DateInput.test.tsx +0 -1459
- package/src/DateInput/DateInputTouch.test.tsx +0 -2828
- package/src/DateInput/NativeDateField.test.tsx +0 -741
- package/src/DateInput/Presentation.test.tsx +0 -121
- package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +0 -577
- package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +0 -171
- package/src/DateRangeInput/DateRangeInput.fr10.test.tsx +0 -165
- package/src/DateRangeInput/DateRangeInput.test.tsx +0 -1108
- package/src/DateTimeInput/DateTimeInput.fr10.test.tsx +0 -319
- package/src/DateTimeInput/DateTimeInput.test.tsx +0 -2575
- package/src/DateTimeInput/DateTimeInputTouch.test.tsx +0 -1071
- package/src/DateTimeInput/NativePickerSegments.test.tsx +0 -657
- package/src/DateTimeInput/Presentation.test.tsx +0 -89
- package/src/Dialog/Dialog.source-build.test.mjs +0 -43
- package/src/Dialog/Dialog.test.tsx +0 -1385
- package/src/Dialog/DialogHeader.test.tsx +0 -477
- package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +0 -111
- package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +0 -218
- package/src/Dialog/__tests__/Dialog.a11y.known-failures.ts +0 -28
- package/src/Dialog/__tests__/Dialog.a11y.renders.tsx +0 -107
- package/src/Dialog/__tests__/Dialog.a11y.states.ts +0 -104
- package/src/Dialog/__tests__/Dialog.a11y.test.tsx +0 -102
- package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +0 -252
- package/src/Dialog/useImperativeDialog.test.tsx +0 -78
- package/src/Divider/Divider.test.tsx +0 -155
- package/src/Drawer/Drawer.test.tsx +0 -1300
- package/src/Drawer/DrawerDirection.test.tsx +0 -127
- package/src/Drawer/DrawerHeader.test.tsx +0 -102
- package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +0 -402
- package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +0 -298
- package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +0 -93
- package/src/DropdownMenu/DropdownMenu.test.tsx +0 -4340
- package/src/DropdownMenu/DropdownMenuContext.public.test.ts +0 -22
- package/src/DropdownMenu/DropdownMenuLazySheet.test.tsx +0 -126
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +0 -635
- package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +0 -72
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +0 -2408
- package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +0 -281
- package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +0 -175
- package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +0 -74
- package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +0 -335
- package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +0 -367
- package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +0 -328
- package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +0 -540
- package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +0 -671
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +0 -146
- package/src/DropdownMenu/__tests__/Menu.a11y.known-failures.ts +0 -26
- package/src/DropdownMenu/__tests__/Menu.a11y.renders.tsx +0 -65
- package/src/DropdownMenu/__tests__/Menu.a11y.states.ts +0 -138
- package/src/DropdownMenu/__tests__/Menu.a11y.test.tsx +0 -136
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +0 -137
- package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +0 -12
- package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +0 -67
- package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +0 -141
- package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +0 -138
- package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +0 -231
- package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +0 -238
- package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +0 -173
- package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +0 -503
- package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +0 -268
- package/src/DropdownMenu/__tests__/warmMenuBottomSheet.tsx +0 -43
- package/src/EmptyState/EmptyState.announce.test.tsx +0 -227
- package/src/EmptyState/EmptyState.test.tsx +0 -284
- package/src/Field/Field.test.tsx +0 -800
- package/src/Field/FieldLabel.test.tsx +0 -244
- package/src/Field/InputClearButton.test.tsx +0 -395
- package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +0 -297
- package/src/Field/fieldInputFamily.test.tsx +0 -160
- package/src/FieldStatus/FieldStatus.test.tsx +0 -482
- package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +0 -206
- package/src/FieldStatus/__tests__/StatusMessage.a11y.known-failures.ts +0 -13
- package/src/FieldStatus/__tests__/StatusMessage.a11y.renders.tsx +0 -287
- package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +0 -302
- package/src/FieldStatus/__tests__/StatusMessage.a11y.test.tsx +0 -154
- package/src/FileInput/FileInput.fr10.test.tsx +0 -21
- package/src/FileInput/FileInput.test.tsx +0 -1270
- package/src/FormLayout/FormLayout.test.tsx +0 -444
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -46
- package/src/Grid/Grid.test.tsx +0 -509
- package/src/HStack/HStack.test.tsx +0 -129
- package/src/Heading/Heading.test.tsx +0 -328
- package/src/HoverCard/HoverCard.test.tsx +0 -1339
- package/src/Icon/Icon.test.tsx +0 -990
- package/src/Icon/globalIconRegistry.test.tsx +0 -613
- package/src/IconButton/IconButton.test.tsx +0 -156
- package/src/Indicator/Indicator.test.tsx +0 -389
- package/src/Indicator/indicatorRegistry.test.tsx +0 -106
- package/src/InputGroup/InputGroup.test.tsx +0 -502
- package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +0 -185
- package/src/Item/Item.source-build.test.mjs +0 -88
- package/src/Item/Item.swipeLayer.test.tsx +0 -74
- package/src/Item/Item.test.tsx +0 -1455
- package/src/Item/ItemMarkerColumns.a11y.chromium.spec.ts +0 -211
- package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +0 -337
- package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +0 -186
- package/src/Kbd/Kbd.test.tsx +0 -299
- package/src/Layer/LayerProvider.test.tsx +0 -143
- package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +0 -176
- package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +0 -200
- package/src/Layer/anchorName.test.ts +0 -146
- package/src/Layer/layerDismissalFamilies.test.tsx +0 -487
- package/src/Layer/layerDismissalInvariants.test.tsx +0 -501
- package/src/Layer/layerHost.test.ts +0 -117
- package/src/Layer/layerScopedContext.test.tsx +0 -499
- package/src/Layer/layerViewportInset.source-build.test.mjs +0 -90
- package/src/Layer/layerViewportInset.test.ts +0 -120
- package/src/Layer/useLayer.test.tsx +0 -2423
- package/src/Layer/useLayerDismissal.test.tsx +0 -580
- package/src/Layer/useTouchTrigger.test.ts +0 -70
- package/src/Layout/Layout.test.tsx +0 -375
- package/src/Layout/LayoutSlots.test.tsx +0 -376
- package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +0 -122
- package/src/Layout/__tests__/Layout.a11y.renders.tsx +0 -110
- package/src/Layout/__tests__/Layout.a11y.states.ts +0 -93
- package/src/Layout/__tests__/Layout.a11y.test.tsx +0 -142
- package/src/Layout/__tests__/childrenAsContent.test.tsx +0 -59
- package/src/Layout/__tests__/contentWidth.test.tsx +0 -303
- package/src/Layout/__tests__/edgeCompensation.test.tsx +0 -191
- package/src/Layout/__tests__/nestedPadding.test.tsx +0 -264
- package/src/Layout/overlayPaddingReset.test.tsx +0 -224
- package/src/Lightbox/Lightbox.test.tsx +0 -819
- package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +0 -78
- package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +0 -70
- package/src/Lightbox/useLightbox.test.tsx +0 -263
- package/src/Link/Link.test.tsx +0 -457
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +0 -143
- package/src/Link/__tests__/Link.a11y.renders.tsx +0 -97
- package/src/Link/__tests__/Link.a11y.states.ts +0 -104
- package/src/Link/__tests__/Link.a11y.test.tsx +0 -127
- package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +0 -262
- package/src/Link/useLinkComponent.test.tsx +0 -572
- package/src/Link/useLinkify.test.tsx +0 -146
- package/src/List/List.test.tsx +0 -1052
- package/src/List/ListItem.source-build.test.mjs +0 -41
- package/src/List/ListMarkers.a11y.chromium.spec.ts +0 -904
- package/src/Markdown/Markdown.codeLanguages.test.tsx +0 -137
- package/src/Markdown/Markdown.fr23.bench.ts +0 -176
- package/src/Markdown/Markdown.fr23.perf.test.ts +0 -484
- package/src/Markdown/Markdown.helpers.perf.test.ts +0 -495
- package/src/Markdown/Markdown.public.test.ts +0 -309
- package/src/Markdown/Markdown.renderBoundary.test.tsx +0 -72
- package/src/Markdown/Markdown.rerender.test.tsx +0 -143
- package/src/Markdown/Markdown.test.tsx +0 -1383
- package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +0 -727
- package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +0 -102
- package/src/Markdown/angleDestinations.test.tsx +0 -104
- package/src/Markdown/ast.test.ts +0 -374
- package/src/Markdown/atxHeadingIndentation.test.tsx +0 -53
- package/src/Markdown/blockNesting.test.tsx +0 -124
- package/src/Markdown/blockquoteMarkers.test.tsx +0 -69
- package/src/Markdown/characterReferences.test.ts +0 -47
- package/src/Markdown/codeSpans.test.tsx +0 -65
- package/src/Markdown/emphasis.test.tsx +0 -214
- package/src/Markdown/fenceInfo.test.tsx +0 -47
- package/src/Markdown/imageAlt.test.tsx +0 -84
- package/src/Markdown/incremental.test.ts +0 -1198
- package/src/Markdown/incrementalIndentation.test.tsx +0 -36
- package/src/Markdown/indentedFences.test.tsx +0 -374
- package/src/Markdown/indentedTables.test.tsx +0 -53
- package/src/Markdown/linkBrackets.test.tsx +0 -116
- package/src/Markdown/linkDestinationLinear.test.tsx +0 -54
- package/src/Markdown/linkDestinations.test.tsx +0 -127
- package/src/Markdown/linkTextCode.test.tsx +0 -65
- package/src/Markdown/listBullets.test.tsx +0 -55
- package/src/Markdown/listContinuation.test.tsx +0 -94
- package/src/Markdown/listThematicBreak.test.tsx +0 -49
- package/src/Markdown/longLinkLabels.test.tsx +0 -49
- package/src/Markdown/openFenceFinalNewline.test.tsx +0 -85
- package/src/Markdown/parser.perf.test.ts +0 -398
- package/src/Markdown/parser.public.test.ts +0 -144
- package/src/Markdown/parser.test.ts +0 -1925
- package/src/Markdown/plugin-renderer/MarkdownPluginNodeRenderer.test.tsx +0 -300
- package/src/Markdown/plugins/frontmatter.test.tsx +0 -150
- package/src/Markdown/plugins/headingLinks.a11y.chromium.spec.ts +0 -856
- package/src/Markdown/plugins/headingLinks.ssr.test.tsx +0 -143
- package/src/Markdown/plugins/headingLinks.test.tsx +0 -637
- package/src/Markdown/plugins/protocol.test.tsx +0 -1083
- package/src/Markdown/plugins/semanticFence.test.tsx +0 -655
- package/src/Markdown/plugins/softBreaks.test.tsx +0 -172
- package/src/Markdown/plugins/sourceDecoration.test.tsx +0 -799
- package/src/Markdown/plugins/sourceLines.test.tsx +0 -715
- package/src/Markdown/plugins/textTransform.test.ts +0 -467
- package/src/Markdown/remark.test.tsx +0 -1877
- package/src/Markdown/streaming.test.ts +0 -148
- package/src/Markdown/streamingListShapes.test.tsx +0 -93
- package/src/Markdown/trailingSpaces.test.tsx +0 -45
- package/src/MetadataList/MetadataList.test.tsx +0 -383
- package/src/MobileNav/MobileNav.test.tsx +0 -281
- package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +0 -584
- package/src/MobileNav/MobileNavCloseTiming.test.ts +0 -58
- package/src/MobileNav/MobileNavCloseVisibility.test.tsx +0 -172
- package/src/MobileNav/MobileNavEntryAnimation.test.tsx +0 -212
- package/src/MobileNav/MobileNavFocus.test.tsx +0 -553
- package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +0 -147
- package/src/MobileNav/MobileNavReopen.test.tsx +0 -118
- package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +0 -109
- package/src/MobileNav/MobileNavToggle.test.tsx +0 -179
- package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +0 -103
- package/src/MoreMenu/MoreMenu.test.tsx +0 -356
- package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +0 -149
- package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +0 -72
- package/src/MultiSelector/MultiSelector.focusableDisabled.test.tsx +0 -121
- package/src/MultiSelector/MultiSelector.fr10.test.tsx +0 -221
- package/src/MultiSelector/MultiSelector.test.tsx +0 -4702
- package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +0 -310
- package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +0 -46
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +0 -128
- package/src/NavIcon/NavIcon.test.tsx +0 -41
- package/src/NavMenu/NavHeadingMenu.test.tsx +0 -714
- package/src/NavMenu/__tests__/NavMenusSlideSelection.a11y.chromium.spec.ts +0 -137
- package/src/NumberInput/NumberInput.fr10.test.tsx +0 -21
- package/src/NumberInput/NumberInput.test.tsx +0 -2636
- package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +0 -124
- package/src/NumberInput/__tests__/NumberInput.a11y.known-failures.ts +0 -26
- package/src/NumberInput/__tests__/NumberInput.a11y.renders.tsx +0 -77
- package/src/NumberInput/__tests__/NumberInput.a11y.states.ts +0 -116
- package/src/NumberInput/__tests__/NumberInput.a11y.test.tsx +0 -154
- package/src/NumberInput/numberInputCommit.test.ts +0 -72
- package/src/NumberInput/numberParser.docblock.test.ts +0 -234
- package/src/NumberInput/numberParser.test.ts +0 -222
- package/src/Outline/Outline.test.tsx +0 -1069
- package/src/Outline/OutlineFocus.a11y.chromium.spec.ts +0 -551
- package/src/Outline/parseOutlineFromMarkdown.test.ts +0 -104
- package/src/OverflowList/OverflowList.test.tsx +0 -1073
- package/src/Overlay/Overlay.test.tsx +0 -424
- package/src/Pagination/Pagination.test.tsx +0 -1754
- package/src/Popover/Popover.test.tsx +0 -1424
- package/src/Popover/PopoverPresentation.test.tsx +0 -952
- package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +0 -205
- package/src/PowerSearch/PowerSearch.test.tsx +0 -1003
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +0 -1190
- package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +0 -377
- package/src/PowerSearch/PowerSearchToken.test.tsx +0 -230
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +0 -754
- package/src/PowerSearch/formatFilterValue.test.ts +0 -339
- package/src/PowerSearch/resolveDateTimeRangePart.test.ts +0 -40
- package/src/PowerSearch/usePowerSearchConfig.test.ts +0 -832
- package/src/PowerSearch/usePowerSearchSource.test.ts +0 -621
- package/src/ProgressBar/ProgressBar.test.tsx +0 -852
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +0 -115
- package/src/ProgressBar/__tests__/ProgressBar.a11y.known-failures.ts +0 -12
- package/src/ProgressBar/__tests__/ProgressBar.a11y.renders.tsx +0 -38
- package/src/ProgressBar/__tests__/ProgressBar.a11y.states.ts +0 -123
- package/src/ProgressBar/__tests__/ProgressBar.a11y.test.tsx +0 -107
- package/src/RadioList/RadioList.fr10.test.tsx +0 -67
- package/src/RadioList/RadioList.test.tsx +0 -967
- package/src/RadioList/RadioListItem.press.source-build.test.mjs +0 -80
- package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +0 -274
- package/src/RadioList/__tests__/RadioGroup.a11y.known-failures.ts +0 -12
- package/src/RadioList/__tests__/RadioGroup.a11y.renders.tsx +0 -232
- package/src/RadioList/__tests__/RadioGroup.a11y.states.ts +0 -503
- package/src/RadioList/__tests__/RadioGroup.a11y.test.tsx +0 -217
- package/src/Resizable/ResizeHandle.test.tsx +0 -1067
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +0 -120
- package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +0 -39
- package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +0 -80
- package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +0 -197
- package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +0 -123
- package/src/Resizable/shippedDirections.test.ts +0 -462
- package/src/Resizable/useResizable.test.ts +0 -1682
- package/src/Resizable/utils.test.ts +0 -74
- package/src/ScrollableArea/ScrollableArea.test.tsx +0 -304
- package/src/Section/Section.test.tsx +0 -376
- package/src/SegmentedControl/SegmentedControl.test.tsx +0 -897
- package/src/SelectableCard/SelectableCard.test.tsx +0 -216
- package/src/Selector/Selector.focusableDisabled.test.tsx +0 -127
- package/src/Selector/Selector.fr10.test.tsx +0 -149
- package/src/Selector/Selector.sheetActiveDescendant.test.tsx +0 -95
- package/src/Selector/Selector.source-build.test.mjs +0 -79
- package/src/Selector/Selector.test.tsx +0 -5028
- package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +0 -27
- package/src/Selector/__tests__/Combobox.a11y.states.ts +0 -145
- package/src/Selector/__tests__/ComboboxField.a11y.chromium.spec.ts +0 -458
- package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +0 -91
- package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +0 -131
- package/src/Selector/__tests__/Listbox.a11y.dom.ts +0 -38
- package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +0 -63
- package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +0 -12
- package/src/Selector/__tests__/Listbox.a11y.states.ts +0 -232
- package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +0 -46
- package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +0 -109
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +0 -126
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +0 -121
- package/src/Selector/useCombobox.public.test.tsx +0 -89
- package/src/Selector/useCombobox.test.tsx +0 -444
- package/src/SideNav/SideNav.test.tsx +0 -4128
- package/src/SideNav/SideNavRailMotion.test.tsx +0 -620
- package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +0 -417
- package/src/SizeContext/SizeContext.test.tsx +0 -226
- package/src/Skeleton/Skeleton.test.tsx +0 -148
- package/src/Slider/Slider.fr10.test.tsx +0 -93
- package/src/Slider/Slider.test.tsx +0 -1630
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +0 -113
- package/src/Slider/__tests__/Slider.a11y.known-failures.ts +0 -12
- package/src/Slider/__tests__/Slider.a11y.renders.tsx +0 -42
- package/src/Slider/__tests__/Slider.a11y.states.ts +0 -106
- package/src/Slider/__tests__/Slider.a11y.test.tsx +0 -105
- package/src/Spinner/Spinner.test.tsx +0 -484
- package/src/Stack/Stack.test.tsx +0 -473
- package/src/Stack/StackItem.test.tsx +0 -105
- package/src/StatusDot/StatusDot.test.tsx +0 -213
- package/src/Stepper/Stepper.public.test.ts +0 -91
- package/src/Stepper/Stepper.test.tsx +0 -2068
- package/src/Switch/Switch.focusRing.source-build.test.mjs +0 -81
- package/src/Switch/Switch.test.tsx +0 -1071
- package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +0 -211
- package/src/Switch/__tests__/Switch.a11y.known-failures.ts +0 -28
- package/src/Switch/__tests__/Switch.a11y.states.ts +0 -275
- package/src/Switch/__tests__/Switch.a11y.test.tsx +0 -144
- package/src/TabList/TabList.test.tsx +0 -1701
- package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +0 -99
- package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +0 -199
- package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +0 -12
- package/src/TabList/__tests__/Tabs.a11y.renders.tsx +0 -92
- package/src/TabList/__tests__/Tabs.a11y.states.ts +0 -247
- package/src/TabList/__tests__/Tabs.a11y.test.tsx +0 -153
- package/src/Table/Table.perf.test.tsx +0 -569
- package/src/Table/Table.test.tsx +0 -1851
- package/src/Table/TableHeaderCell.test.tsx +0 -291
- package/src/Table/TableSelectionToolbar.test.tsx +0 -109
- package/src/Table/__tests__/Table.a11y.chromium.spec.ts +0 -129
- package/src/Table/__tests__/Table.a11y.contracts.ts +0 -35
- package/src/Table/__tests__/Table.a11y.renders.tsx +0 -112
- package/src/Table/__tests__/Table.a11y.states.ts +0 -140
- package/src/Table/__tests__/Table.a11y.test.tsx +0 -198
- package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +0 -75
- package/src/Table/__tests__/TableRowGlide.a11y.browser.spec.ts +0 -382
- package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +0 -138
- package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +0 -560
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +0 -919
- package/src/Table/plugins/columnSettings/useTableColumnSettings.test.tsx +0 -175
- package/src/Table/plugins/columnSettings/useTableColumnSettingsState.test.tsx +0 -296
- package/src/Table/plugins/filtering/useTableFilterState.test.tsx +0 -143
- package/src/Table/plugins/filtering/useTableFiltering.test.tsx +0 -357
- package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +0 -112
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +0 -409
- package/src/Table/plugins/pagination/useTablePagination-perf.test.tsx +0 -232
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +0 -666
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.glide.test.tsx +0 -280
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +0 -681
- package/src/Table/plugins/rowIndex/useTableRowIndex.test.tsx +0 -132
- package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +0 -92
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +0 -519
- package/src/Table/plugins/selection/useTableSelection-perf.test.tsx +0 -258
- package/src/Table/plugins/selection/useTableSelection.test.tsx +0 -424
- package/src/Table/plugins/selection/useTableSelectionState.test.tsx +0 -451
- package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +0 -174
- package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +0 -86
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -857
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +0 -592
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +0 -334
- package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +0 -163
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +0 -992
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +0 -740
- package/src/Table/tableContextMenu.test.tsx +0 -208
- package/src/Text/Text.test.tsx +0 -405
- package/src/Text/useTruncation.test.tsx +0 -69
- package/src/TextArea/TextArea.fr10.test.tsx +0 -21
- package/src/TextArea/TextArea.test.tsx +0 -1257
- package/src/TextInput/TextInput.fr10.test.tsx +0 -21
- package/src/TextInput/TextInput.test.tsx +0 -1259
- package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +0 -214
- package/src/TextInput/__tests__/TextInput.a11y.known-failures.ts +0 -40
- package/src/TextInput/__tests__/TextInput.a11y.renders.tsx +0 -202
- package/src/TextInput/__tests__/TextInput.a11y.states.ts +0 -384
- package/src/TextInput/__tests__/TextInput.a11y.test.tsx +0 -130
- package/src/Thumbnail/Thumbnail.test.tsx +0 -384
- package/src/TimeInput/NativeTimeInput.test.tsx +0 -326
- package/src/TimeInput/Presentation.test.tsx +0 -171
- package/src/TimeInput/TimeInput.fr10.test.tsx +0 -312
- package/src/TimeInput/TimeInput.test.tsx +0 -831
- package/src/Timer/Timer.test.tsx +0 -302
- package/src/Timestamp/Timestamp.test.tsx +0 -1636
- package/src/Timestamp/tooltipEntries.test.ts +0 -566
- package/src/Toast/ToastViewport.modalHost.test.tsx +0 -891
- package/src/Toast/ToastViewport.test.tsx +0 -2333
- package/src/Toast/useToast.test.tsx +0 -258
- package/src/ToggleButton/ToggleButton.test.tsx +0 -973
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +0 -177
- package/src/ToggleButton/__tests__/ToggleButton.a11y.renders.tsx +0 -133
- package/src/ToggleButton/__tests__/ToggleButton.a11y.states.ts +0 -167
- package/src/ToggleButton/__tests__/ToggleButton.a11y.test.tsx +0 -103
- package/src/Token/Token.test.tsx +0 -640
- package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +0 -87
- package/src/Tokenizer/Tokenizer.fr10.test.tsx +0 -28
- package/src/Tokenizer/Tokenizer.props-type.test.tsx +0 -126
- package/src/Tokenizer/Tokenizer.ssr.test.tsx +0 -196
- package/src/Tokenizer/Tokenizer.test.tsx +0 -2121
- package/src/Tokenizer/TokenizerBottomSheet.test.tsx +0 -2719
- package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +0 -505
- package/src/Toolbar/Toolbar.test.tsx +0 -570
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +0 -164
- package/src/Toolbar/__tests__/Toolbar.a11y.renders.tsx +0 -63
- package/src/Toolbar/__tests__/Toolbar.a11y.states.ts +0 -142
- package/src/Toolbar/__tests__/Toolbar.a11y.test.tsx +0 -126
- package/src/Tooltip/Tooltip.test.tsx +0 -819
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +0 -130
- package/src/Tooltip/__tests__/Tooltip.a11y.renders.tsx +0 -86
- package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +0 -132
- package/src/Tooltip/__tests__/Tooltip.a11y.test.tsx +0 -126
- package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +0 -130
- package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +0 -75
- package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +0 -673
- package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +0 -1162
- package/src/Tooltip/useTooltip.test.tsx +0 -483
- package/src/TopNav/TopNav.test.tsx +0 -836
- package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +0 -83
- package/src/TopNav/TopNavMegaMenu.test.tsx +0 -1132
- package/src/TopNav/TopNavMenu.test.tsx +0 -485
- package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +0 -75
- package/src/TreeList/TreeList.test.tsx +0 -1711
- package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +0 -138
- package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +0 -44
- package/src/TreeList/__tests__/TreeList.a11y.states.ts +0 -164
- package/src/TreeList/__tests__/TreeList.a11y.test.tsx +0 -138
- package/src/TreeList/__tests__/TreeListGuideAlignment.interaction.browser.spec.ts +0 -127
- package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +0 -83
- package/src/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.ts +0 -138
- package/src/Typeahead/BaseTypeahead.test.tsx +0 -553
- package/src/Typeahead/Typeahead.fr10.test.tsx +0 -28
- package/src/Typeahead/Typeahead.test.tsx +0 -2824
- package/src/Typeahead/TypeaheadItem.test.tsx +0 -134
- package/src/VStack/VStack.test.tsx +0 -128
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +0 -115
- package/src/__tests__/BusyOwnerAnnouncement.test.tsx +0 -853
- package/src/__tests__/CardPress.a11y.chromium.spec.ts +0 -353
- package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +0 -87
- package/src/__tests__/PressModality.a11y.chromium.spec.ts +0 -392
- package/src/__tests__/PressedState.a11y.chromium.spec.ts +0 -814
- package/src/__tests__/TestIcon.tsx +0 -26
- package/src/__tests__/babelPluginAddExtensions.test.ts +0 -190
- package/src/__tests__/fastRoleQueries.ts +0 -66
- package/src/__tests__/forcedColors.ts +0 -60
- package/src/__tests__/pressState.ts +0 -212
- package/src/__tests__/stubMatchMedia.test.ts +0 -79
- package/src/__tests__/stubMatchMedia.ts +0 -95
- package/src/__tests__/stylexDeclarations.ts +0 -51
- package/src/__tests__/unthemedLength.ts +0 -34
- package/src/docPropLiterals.test.ts +0 -964
- package/src/docPropReferences.test.ts +0 -178
- package/src/docs-script.test.mjs +0 -55
- package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +0 -141
- package/src/gestures/__tests__/PanGestureRecognizer.test.ts +0 -327
- package/src/gestures/__tests__/TapGestureRecognizer.test.ts +0 -154
- package/src/gestures/__tests__/VelocityTracker.streams.test.ts +0 -243
- package/src/gestures/__tests__/VelocityTracker.test.ts +0 -261
- package/src/gestures/__tests__/arena.test.ts +0 -824
- package/src/gestures/__tests__/arenaContinuous.test.ts +0 -207
- package/src/gestures/__tests__/arenaTapLongPress.test.ts +0 -211
- package/src/gestures/__tests__/fixtures/pointer-streams/README.md +0 -82
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-fling.json +0 -130
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-slow.json +0 -860
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-stop-release.json +0 -357
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-fling.json +0 -66
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-slow.json +0 -268
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-stop-release.json +0 -128
- package/src/gestures/__tests__/fixtures/pointer-streams/capture.html +0 -123
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-fling.json +0 -64
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-slow.json +0 -268
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-stop-release.json +0 -124
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-fling.json +0 -64
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-slow.json +0 -268
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-stop-release.json +0 -124
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-fling.json +0 -84
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-slow.json +0 -381
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-stop-release.json +0 -171
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-fling.json +0 -45
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-slow.json +0 -101
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-stop-release.json +0 -130
- package/src/gestures/__tests__/harness.ts +0 -204
- package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +0 -144
- package/src/hooks/__tests__/menuLinkClicks.ts +0 -71
- package/src/hooks/actionGroupTracker.exports.test.ts +0 -28
- package/src/hooks/actionGroupTracker.test.ts +0 -510
- package/src/hooks/computeOverflow.test.ts +0 -422
- package/src/hooks/deprecatedApis.public.test.ts +0 -33
- package/src/hooks/menuPressGesture.test.ts +0 -253
- package/src/hooks/scrollKeyboardDelegation.test.ts +0 -155
- package/src/hooks/scrollbarGutter.test.ts +0 -167
- package/src/hooks/useAnnounce.modal.test.tsx +0 -1291
- package/src/hooks/useAnnounce.test.tsx +0 -293
- package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +0 -226
- package/src/hooks/useAutoMediaMode.test.ts +0 -109
- package/src/hooks/useBusyAnnouncement.adopters.test.tsx +0 -69
- package/src/hooks/useBusyAnnouncement.test.tsx +0 -112
- package/src/hooks/useClickableContainer.test.tsx +0 -236
- package/src/hooks/useClipboard.test.tsx +0 -151
- package/src/hooks/useContainerReveal.test.tsx +0 -163
- package/src/hooks/useDevWarning.test.tsx +0 -45
- package/src/hooks/useEntryAnimation.ssr.test.tsx +0 -143
- package/src/hooks/useFocusTrap.test.tsx +0 -635
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +0 -166
- package/src/hooks/useGridFocus.test.tsx +0 -165
- package/src/hooks/useHotkeys.test.ts +0 -265
- package/src/hooks/useImageMode.test.ts +0 -133
- package/src/hooks/useInputContainer.test.tsx +0 -180
- package/src/hooks/useInputStatusIcon.test.tsx +0 -240
- package/src/hooks/useIsHydrating.test.tsx +0 -70
- package/src/hooks/useKeyboardHint.test.tsx +0 -92
- package/src/hooks/useListFocus.test.tsx +0 -664
- package/src/hooks/useLongPress.test.tsx +0 -152
- package/src/hooks/useMediaQuery.test.ts +0 -165
- package/src/hooks/useMenuHover.test.tsx +0 -536
- package/src/hooks/useMenuPress.test.tsx +0 -565
- package/src/hooks/useMergedRefs.test.tsx +0 -62
- package/src/hooks/useOverflow.test.ts +0 -504
- package/src/hooks/useRenamedProp.test.tsx +0 -95
- package/src/hooks/useScrollLock.test.ts +0 -248
- package/src/hooks/useScrollOverflow.test.tsx +0 -222
- package/src/hooks/useScrollableArea.test.tsx +0 -836
- package/src/hooks/useStreamingText.test.ts +0 -237
- package/src/hooks/useTreeFocus.test.tsx +0 -351
- package/src/hooks/useTypeahead.test.tsx +0 -351
- package/src/i18n/__tests__/InternationalizationProvider.test.tsx +0 -128
- package/src/i18n/__tests__/e2e-pagination.test.tsx +0 -172
- package/src/i18n/__tests__/e2e-powersearch.test.tsx +0 -166
- package/src/i18n/__tests__/getLocaleDirection.test.ts +0 -40
- package/src/i18n/__tests__/resolve.test.ts +0 -325
- package/src/i18n/__tests__/useCollator.test.tsx +0 -115
- package/src/i18n/__tests__/useDirection.test.tsx +0 -66
- package/src/i18n/__tests__/useLocale.test.tsx +0 -52
- package/src/i18n/useTranslator.test.tsx +0 -267
- package/src/inputFontFloor.test.ts +0 -106
- package/src/internal/tokenizer-presentation.test.ts +0 -29
- package/src/internal/touch.test.ts +0 -44
- package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +0 -1613
- package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +0 -217
- package/src/motion/__tests__/animatedLayoutBundle.ts +0 -17
- package/src/motion/animatedLayout.boundary.test.ts +0 -155
- package/src/motion/animatedLayout.swap.test.ts +0 -827
- package/src/motion/animatedLayout.test.ts +0 -1154
- package/src/motion/animatedLayoutAdopters.test.tsx +0 -500
- package/src/motion/animator.test.ts +0 -2653
- package/src/motion/bezier.test.ts +0 -52
- package/src/motion/coast.test.ts +0 -99
- package/src/motion/decay.test.ts +0 -120
- package/src/motion/projection.test.ts +0 -107
- package/src/motion/reducedMotion.test.ts +0 -129
- package/src/motion/reducedMotionPlan.test.ts +0 -182
- package/src/motion/resolveSnapPoint.test.ts +0 -189
- package/src/motion/roles.test.ts +0 -256
- package/src/motion/rubberBand.test.ts +0 -88
- package/src/motion/selectPage.test.ts +0 -31
- package/src/motion/spring.test.ts +0 -650
- package/src/motion/uikit/gestures.test.ts +0 -89
- package/src/motion/uikit/springRows.test.ts +0 -71
- package/src/motion/uikit/uikit.test.ts +0 -364
- package/src/motion/uikit/values.test.ts +0 -110
- package/src/naming.test.ts +0 -44
- package/src/postinstall.test.mjs +0 -216
- package/src/reset.a11y.chromium.spec.ts +0 -238
- package/src/reset.test.ts +0 -205
- package/src/reset.until-found.a11y.browser.spec.ts +0 -76
- package/src/reset.until-found.test.ts +0 -32
- package/src/serverSafeComponents.test.ts +0 -675
- package/src/stylexValidation.source-build.test.mjs +0 -42
- package/src/tailwind-theme.test.ts +0 -153
- package/src/theme/MediaTheme.dom.test.tsx +0 -97
- package/src/theme/Theme.test.tsx +0 -337
- package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +0 -199
- package/src/theme/contrast.test.ts +0 -94
- package/src/theme/declarationBoundary.test.ts +0 -126
- package/src/theme/defineTheme.test.ts +0 -2028
- package/src/theme/derivedVarRegistry.test.ts +0 -588
- package/src/theme/expandColorScale.test.ts +0 -651
- package/src/theme/expandMotionScale.test.ts +0 -145
- package/src/theme/expandRadiusScale.test.ts +0 -59
- package/src/theme/expandTypeScale.test.ts +0 -351
- package/src/theme/extensibleAxes.test.ts +0 -432
- package/src/theme/generateThemeRules.test.ts +0 -1870
- package/src/theme/hct.test.ts +0 -93
- package/src/theme/onMediaTokens.test.ts +0 -431
- package/src/theme/publicThemeHelperContract.test.ts +0 -67
- package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +0 -91
- package/src/theme/syntax/serverSafeSyntax.test.ts +0 -68
- package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +0 -40
- package/src/theme/themeAdaptations.test.ts +0 -1795
- package/src/theme/themeRegistry.test.ts +0 -59
- package/src/theme/themingTargets.test.ts +0 -589
- package/src/theme/tokenValueCompat.test.ts +0 -204
- package/src/theme/tokens.test.ts +0 -441
- package/src/theme/useTheme.test.tsx +0 -322
- package/src/unicodePropertyEscapes.source-build.test.mjs +0 -69
- package/src/utils/chainEventHandlers.test.ts +0 -39
- package/src/utils/characters.test.ts +0 -141
- package/src/utils/color.test.ts +0 -233
- package/src/utils/composeEventHandlers.test.ts +0 -71
- package/src/utils/customPropertyArmLayering.test.ts +0 -131
- package/src/utils/dateParser.test.ts +0 -402
- package/src/utils/dateTypes.test.ts +0 -40
- package/src/utils/devWarning.test.ts +0 -56
- package/src/utils/edgeAutoscroll.test.ts +0 -192
- package/src/utils/focusReturn.test.ts +0 -119
- package/src/utils/getKey.test.ts +0 -25
- package/src/utils/hitArea.test.ts +0 -628
- package/src/utils/ime.test.ts +0 -32
- package/src/utils/inputAria.test.ts +0 -39
- package/src/utils/interactionModality.test.ts +0 -100
- package/src/utils/isApplePlatform.test.ts +0 -61
- package/src/utils/mergeProps.test.ts +0 -166
- package/src/utils/mergeRefs.test.ts +0 -48
- package/src/utils/parseStyleKey.test.ts +0 -56
- package/src/utils/plainDate.test.ts +0 -848
- package/src/utils/pressFeedback.test.ts +0 -874
- package/src/utils/pressGesture.test.ts +0 -323
- package/src/utils/pressPaintSource.test.ts +0 -65
- package/src/utils/pressableCoverage.test.ts +0 -192
- package/src/utils/safeUrl.test.ts +0 -101
- package/src/utils/sharedMutationObserver.test.ts +0 -53
- package/src/utils/sharedResizeObserver.test.ts +0 -283
- package/src/utils/themeProps.test.ts +0 -62
- package/src/utils/timeParser.test.ts +0 -295
- package/src/utils/touchPresentation.test.ts +0 -323
|
@@ -1,2068 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {StrictMode, createRef, useLayoutEffect} from 'react';
|
|
4
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
5
|
-
import {act, render, screen, within} from '@testing-library/react';
|
|
6
|
-
import userEvent from '@testing-library/user-event';
|
|
7
|
-
import {Stepper} from './Stepper';
|
|
8
|
-
import {Step} from './Step';
|
|
9
|
-
import {useStepperContext} from './StepperContext';
|
|
10
|
-
import {useLayer} from '../Layer/useLayer';
|
|
11
|
-
import {defineTheme} from '../theme/defineTheme';
|
|
12
|
-
import {generateThemeCSS} from '../theme/generateThemeRules';
|
|
13
|
-
import {getForcedColorsRules} from '../__tests__/forcedColors';
|
|
14
|
-
|
|
15
|
-
describe('Stepper', () => {
|
|
16
|
-
it('renders an ordered list of steps (not a nav landmark)', () => {
|
|
17
|
-
render(
|
|
18
|
-
<Stepper activeStep={0}>
|
|
19
|
-
<Step step={0} label="Step 1" />
|
|
20
|
-
<Step step={1} label="Step 2" />
|
|
21
|
-
<Step step={2} label="Step 3" />
|
|
22
|
-
</Stepper>,
|
|
23
|
-
);
|
|
24
|
-
// A stepper is a sequence/progress list, not a navigation landmark.
|
|
25
|
-
expect(screen.queryByRole('navigation')).not.toBeInTheDocument();
|
|
26
|
-
const list = screen.getByRole('list', {name: 'Progress'});
|
|
27
|
-
expect(list.tagName).toBe('OL');
|
|
28
|
-
expect(screen.getByText('Step 1')).toBeInTheDocument();
|
|
29
|
-
expect(screen.getByText('Step 2')).toBeInTheDocument();
|
|
30
|
-
expect(screen.getByText('Step 3')).toBeInTheDocument();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('renders step numbers', () => {
|
|
34
|
-
render(
|
|
35
|
-
<Stepper activeStep={0}>
|
|
36
|
-
<Step step={0} label="First" indicator="number" />
|
|
37
|
-
<Step step={1} label="Second" indicator="number" />
|
|
38
|
-
</Stepper>,
|
|
39
|
-
);
|
|
40
|
-
expect(screen.getByText('1')).toBeInTheDocument();
|
|
41
|
-
expect(screen.getByText('2')).toBeInTheDocument();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('marks the active step with aria-current', () => {
|
|
45
|
-
render(
|
|
46
|
-
<Stepper activeStep={1}>
|
|
47
|
-
<Step step={0} label="Step 1" data-testid="step-0" />
|
|
48
|
-
<Step step={1} label="Step 2" data-testid="step-1" />
|
|
49
|
-
<Step step={2} label="Step 3" data-testid="step-2" />
|
|
50
|
-
</Stepper>,
|
|
51
|
-
);
|
|
52
|
-
expect(screen.getByTestId('step-0')).not.toHaveAttribute('aria-current');
|
|
53
|
-
expect(screen.getByTestId('step-1')).toHaveAttribute(
|
|
54
|
-
'aria-current',
|
|
55
|
-
'step',
|
|
56
|
-
);
|
|
57
|
-
expect(screen.getByTestId('step-2')).not.toHaveAttribute('aria-current');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('renders descriptions when provided', () => {
|
|
61
|
-
render(
|
|
62
|
-
<Stepper activeStep={0}>
|
|
63
|
-
<Step step={0} label="Account" description="Create your account" />
|
|
64
|
-
<Step step={1} label="Profile" />
|
|
65
|
-
</Stepper>,
|
|
66
|
-
);
|
|
67
|
-
expect(screen.getByText('Create your account')).toBeInTheDocument();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('supports custom accessible label', () => {
|
|
71
|
-
render(
|
|
72
|
-
<Stepper activeStep={0} label="Checkout progress">
|
|
73
|
-
<Step step={0} label="Cart" />
|
|
74
|
-
<Step step={1} label="Payment" />
|
|
75
|
-
</Stepper>,
|
|
76
|
-
);
|
|
77
|
-
expect(
|
|
78
|
-
screen.getByRole('list', {name: 'Checkout progress'}),
|
|
79
|
-
).toBeInTheDocument();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it.each(['horizontal', 'vertical'] as const)(
|
|
83
|
-
'exposes only the supported public context keys at runtime when %s',
|
|
84
|
-
orientation => {
|
|
85
|
-
let contextKeys: string[] = [];
|
|
86
|
-
|
|
87
|
-
function ContextProbe() {
|
|
88
|
-
contextKeys = Object.keys(useStepperContext()).sort();
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
render(
|
|
93
|
-
<Stepper activeStep={0} orientation={orientation}>
|
|
94
|
-
<ContextProbe />
|
|
95
|
-
<Step step={0} label="Step 1" />
|
|
96
|
-
</Stepper>,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
expect(contextKeys).toEqual(
|
|
100
|
-
[
|
|
101
|
-
'activeStep',
|
|
102
|
-
'previousActiveStep',
|
|
103
|
-
'orientation',
|
|
104
|
-
'isNonLinear',
|
|
105
|
-
'onStepClick',
|
|
106
|
-
'density',
|
|
107
|
-
'indicatorPosition',
|
|
108
|
-
'registerStep',
|
|
109
|
-
].sort(),
|
|
110
|
-
);
|
|
111
|
-
},
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
it('supports vertical orientation', () => {
|
|
115
|
-
render(
|
|
116
|
-
<Stepper activeStep={0} orientation="vertical">
|
|
117
|
-
<Step step={0} label="Step 1" />
|
|
118
|
-
<Step step={1} label="Step 2" />
|
|
119
|
-
</Stepper>,
|
|
120
|
-
);
|
|
121
|
-
const list = screen.getByRole('list');
|
|
122
|
-
expect(list).toHaveAttribute('data-orientation', 'vertical');
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('calls onStepClick when a completed step is clicked', async () => {
|
|
126
|
-
const user = userEvent.setup();
|
|
127
|
-
const handleClick = vi.fn();
|
|
128
|
-
render(
|
|
129
|
-
<Stepper activeStep={2} onStepClick={handleClick}>
|
|
130
|
-
<Step step={0} label="Step 1" />
|
|
131
|
-
<Step step={1} label="Step 2" />
|
|
132
|
-
<Step step={2} label="Step 3" />
|
|
133
|
-
</Stepper>,
|
|
134
|
-
);
|
|
135
|
-
await user.click(
|
|
136
|
-
screen.getByRole('button', {name: 'Go to step 1: Step 1, completed'}),
|
|
137
|
-
);
|
|
138
|
-
expect(handleClick).toHaveBeenCalledWith(0);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('calls onStepClick when the active step is clicked', async () => {
|
|
142
|
-
const user = userEvent.setup();
|
|
143
|
-
const handleClick = vi.fn();
|
|
144
|
-
render(
|
|
145
|
-
<Stepper activeStep={1} onStepClick={handleClick}>
|
|
146
|
-
<Step step={0} label="Step 1" />
|
|
147
|
-
<Step step={1} label="Step 2" />
|
|
148
|
-
<Step step={2} label="Step 3" />
|
|
149
|
-
</Stepper>,
|
|
150
|
-
);
|
|
151
|
-
await user.click(
|
|
152
|
-
screen.getByRole('button', {name: 'Go to step 2: Step 2'}),
|
|
153
|
-
);
|
|
154
|
-
expect(handleClick).toHaveBeenCalledWith(1);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('renders buttons for upcoming steps in non-linear mode', () => {
|
|
158
|
-
render(
|
|
159
|
-
<Stepper activeStep={0} onStepClick={() => {}}>
|
|
160
|
-
<Step step={0} label="Step 1" />
|
|
161
|
-
<Step step={1} label="Step 2" />
|
|
162
|
-
</Stepper>,
|
|
163
|
-
);
|
|
164
|
-
expect(
|
|
165
|
-
screen.getByRole('button', {name: 'Go to step 1: Step 1'}),
|
|
166
|
-
).toBeInTheDocument();
|
|
167
|
-
expect(
|
|
168
|
-
screen.getByRole('button', {name: 'Go to step 2: Step 2'}),
|
|
169
|
-
).toBeInTheDocument();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('calls onStepClick when an upcoming step is clicked', async () => {
|
|
173
|
-
const user = userEvent.setup();
|
|
174
|
-
const handleClick = vi.fn();
|
|
175
|
-
render(
|
|
176
|
-
<Stepper activeStep={0} onStepClick={handleClick}>
|
|
177
|
-
<Step step={0} label="Step 1" />
|
|
178
|
-
<Step step={1} label="Step 2" />
|
|
179
|
-
<Step step={2} label="Step 3" />
|
|
180
|
-
</Stepper>,
|
|
181
|
-
);
|
|
182
|
-
await user.click(
|
|
183
|
-
screen.getByRole('button', {name: 'Go to step 3: Step 3'}),
|
|
184
|
-
);
|
|
185
|
-
expect(handleClick).toHaveBeenCalledWith(2);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('does not render buttons for disabled steps', () => {
|
|
189
|
-
render(
|
|
190
|
-
<Stepper activeStep={2} onStepClick={() => {}}>
|
|
191
|
-
<Step step={0} label="Step 1" isDisabled />
|
|
192
|
-
<Step step={1} label="Step 2" />
|
|
193
|
-
<Step step={2} label="Step 3" />
|
|
194
|
-
</Stepper>,
|
|
195
|
-
);
|
|
196
|
-
expect(
|
|
197
|
-
screen.queryByRole('button', {name: /Go to step 1: Step 1/}),
|
|
198
|
-
).not.toBeInTheDocument();
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('does not render buttons when onStepClick is not provided', () => {
|
|
202
|
-
render(
|
|
203
|
-
<Stepper activeStep={2}>
|
|
204
|
-
<Step step={0} label="Step 1" />
|
|
205
|
-
<Step step={1} label="Step 2" />
|
|
206
|
-
<Step step={2} label="Step 3" />
|
|
207
|
-
</Stepper>,
|
|
208
|
-
);
|
|
209
|
-
expect(screen.queryAllByRole('button')).toHaveLength(0);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('applies a semantic color status (color only) via data attribute', () => {
|
|
213
|
-
render(
|
|
214
|
-
<Stepper activeStep={1}>
|
|
215
|
-
<Step step={0} label="Step 1" data-testid="step-0" />
|
|
216
|
-
<Step step={1} label="Step 2" status="error" data-testid="step-1" />
|
|
217
|
-
</Stepper>,
|
|
218
|
-
);
|
|
219
|
-
expect(screen.getByTestId('step-1')).toHaveAttribute(
|
|
220
|
-
'data-status',
|
|
221
|
-
'error',
|
|
222
|
-
);
|
|
223
|
-
// status is color-only — it must not change progress semantics.
|
|
224
|
-
expect(screen.getByTestId('step-1')).toHaveAttribute(
|
|
225
|
-
'aria-current',
|
|
226
|
-
'step',
|
|
227
|
-
);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('reflects each global semantic status on the data attribute', () => {
|
|
231
|
-
render(
|
|
232
|
-
<Stepper activeStep={0}>
|
|
233
|
-
<Step step={0} label="A" status="accent" data-testid="s-accent" />
|
|
234
|
-
<Step step={1} label="B" status="success" data-testid="s-success" />
|
|
235
|
-
<Step step={2} label="C" status="warning" data-testid="s-warning" />
|
|
236
|
-
<Step step={3} label="D" status="error" data-testid="s-error" />
|
|
237
|
-
</Stepper>,
|
|
238
|
-
);
|
|
239
|
-
expect(screen.getByTestId('s-accent')).toHaveAttribute(
|
|
240
|
-
'data-status',
|
|
241
|
-
'accent',
|
|
242
|
-
);
|
|
243
|
-
expect(screen.getByTestId('s-success')).toHaveAttribute(
|
|
244
|
-
'data-status',
|
|
245
|
-
'success',
|
|
246
|
-
);
|
|
247
|
-
expect(screen.getByTestId('s-warning')).toHaveAttribute(
|
|
248
|
-
'data-status',
|
|
249
|
-
'warning',
|
|
250
|
-
);
|
|
251
|
-
expect(screen.getByTestId('s-error')).toHaveAttribute(
|
|
252
|
-
'data-status',
|
|
253
|
-
'error',
|
|
254
|
-
);
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
it('keeps the progress bar progress-colored regardless of status, recoloring only the indicator', () => {
|
|
258
|
-
// Baseline: a completed step with no status.
|
|
259
|
-
const baseline = render(
|
|
260
|
-
<Stepper activeStep={1}>
|
|
261
|
-
<Step step={0} label="A" data-testid="base" />
|
|
262
|
-
</Stepper>,
|
|
263
|
-
);
|
|
264
|
-
const baseStep = baseline.getByTestId('base');
|
|
265
|
-
const baseBar = baseStep.querySelector('.astryx-step-bar') as HTMLElement;
|
|
266
|
-
const baseIndicator = baseStep.querySelector('svg')
|
|
267
|
-
?.parentElement as HTMLElement;
|
|
268
|
-
|
|
269
|
-
// Same completed step, now with a semantic status.
|
|
270
|
-
const themed = render(
|
|
271
|
-
<Stepper activeStep={1}>
|
|
272
|
-
<Step step={0} label="A" status="error" data-testid="themed" />
|
|
273
|
-
</Stepper>,
|
|
274
|
-
);
|
|
275
|
-
const themedStep = themed.getByTestId('themed');
|
|
276
|
-
const themedBar = themedStep.querySelector(
|
|
277
|
-
'.astryx-step-bar',
|
|
278
|
-
) as HTMLElement;
|
|
279
|
-
const themedIndicator = themedStep.querySelector('svg')
|
|
280
|
-
?.parentElement as HTMLElement;
|
|
281
|
-
|
|
282
|
-
// Bar coloring must be identical — status must NOT recolor the bar
|
|
283
|
-
// (always --color-accent when filled / --color-border when incomplete).
|
|
284
|
-
expect(themedBar.className).toBe(baseBar.className);
|
|
285
|
-
|
|
286
|
-
// The indicator, however, must pick up the status color.
|
|
287
|
-
expect(themedIndicator.className).not.toBe(baseIndicator.className);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('keeps an incomplete step bar border-colored regardless of status', () => {
|
|
291
|
-
// Baseline: a not-started step with no status.
|
|
292
|
-
const baseline = render(
|
|
293
|
-
<Stepper activeStep={0}>
|
|
294
|
-
<Step step={0} label="A" data-testid="base-active" />
|
|
295
|
-
<Step step={1} label="B" data-testid="base" />
|
|
296
|
-
</Stepper>,
|
|
297
|
-
);
|
|
298
|
-
const baseBar = baseline
|
|
299
|
-
.getByTestId('base')
|
|
300
|
-
.querySelector('.astryx-step-bar') as HTMLElement;
|
|
301
|
-
|
|
302
|
-
// Same not-started step, now with a semantic status.
|
|
303
|
-
const themed = render(
|
|
304
|
-
<Stepper activeStep={0}>
|
|
305
|
-
<Step step={0} label="A" data-testid="themed-active" />
|
|
306
|
-
<Step step={1} label="B" status="warning" data-testid="themed" />
|
|
307
|
-
</Stepper>,
|
|
308
|
-
);
|
|
309
|
-
const themedBar = themed
|
|
310
|
-
.getByTestId('themed')
|
|
311
|
-
.querySelector('.astryx-step-bar') as HTMLElement;
|
|
312
|
-
|
|
313
|
-
// Incomplete bar stays border-colored — status must not recolor it.
|
|
314
|
-
expect(themedBar.className).toBe(baseBar.className);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('does not set a status data attribute when status is unset', () => {
|
|
318
|
-
render(
|
|
319
|
-
<Stepper activeStep={0}>
|
|
320
|
-
<Step step={0} label="Step 1" data-testid="step-0" />
|
|
321
|
-
</Stepper>,
|
|
322
|
-
);
|
|
323
|
-
expect(screen.getByTestId('step-0')).not.toHaveAttribute('data-status');
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it('handles zero active step correctly', () => {
|
|
327
|
-
render(
|
|
328
|
-
<Stepper activeStep={0}>
|
|
329
|
-
<Step step={0} label="Step 1" data-testid="step-0" />
|
|
330
|
-
<Step step={1} label="Step 2" data-testid="step-1" />
|
|
331
|
-
</Stepper>,
|
|
332
|
-
);
|
|
333
|
-
expect(screen.getByTestId('step-0')).toHaveAttribute(
|
|
334
|
-
'aria-current',
|
|
335
|
-
'step',
|
|
336
|
-
);
|
|
337
|
-
expect(screen.getByTestId('step-1')).not.toHaveAttribute('aria-current');
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
it('renders each step as a list item', () => {
|
|
341
|
-
render(
|
|
342
|
-
<Stepper activeStep={0}>
|
|
343
|
-
<Step step={0} label="Step 1" />
|
|
344
|
-
<Step step={1} label="Step 2" />
|
|
345
|
-
<Step step={2} label="Step 3" />
|
|
346
|
-
</Stepper>,
|
|
347
|
-
);
|
|
348
|
-
const items = screen.getAllByRole('listitem');
|
|
349
|
-
expect(items).toHaveLength(3);
|
|
350
|
-
expect(items[0].tagName).toBe('LI');
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('accepts a custom ReactNode as indicator', () => {
|
|
354
|
-
render(
|
|
355
|
-
<Stepper activeStep={0}>
|
|
356
|
-
<Step
|
|
357
|
-
step={0}
|
|
358
|
-
label="Step 1"
|
|
359
|
-
indicator={<span data-testid="custom-icon">★</span>}
|
|
360
|
-
/>
|
|
361
|
-
</Stepper>,
|
|
362
|
-
);
|
|
363
|
-
expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
|
|
364
|
-
expect(screen.getByText('★')).toBeInTheDocument();
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it('accepts a ReactNode as indicator', () => {
|
|
368
|
-
render(
|
|
369
|
-
<Stepper activeStep={1}>
|
|
370
|
-
<Step
|
|
371
|
-
step={1}
|
|
372
|
-
label="Payment"
|
|
373
|
-
indicator={<span data-testid="pay-icon">$</span>}
|
|
374
|
-
/>
|
|
375
|
-
</Stepper>,
|
|
376
|
-
);
|
|
377
|
-
expect(screen.getByTestId('pay-icon')).toBeInTheDocument();
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it('renders a distinct indicator glyph per status on non-current steps', () => {
|
|
381
|
-
// All steps completed (activeStep past them) so none is the current step.
|
|
382
|
-
render(
|
|
383
|
-
<Stepper activeStep={4}>
|
|
384
|
-
<Step step={0} label="A" status="success" data-testid="s-success" />
|
|
385
|
-
<Step step={1} label="B" status="warning" data-testid="s-warning" />
|
|
386
|
-
<Step step={2} label="C" status="error" data-testid="s-error" />
|
|
387
|
-
<Step step={3} label="D" data-testid="s-plain" />
|
|
388
|
-
</Stepper>,
|
|
389
|
-
);
|
|
390
|
-
|
|
391
|
-
const indicatorClass = (testid: string) =>
|
|
392
|
-
(
|
|
393
|
-
screen.getByTestId(testid).querySelector('svg')
|
|
394
|
-
?.parentElement as HTMLElement
|
|
395
|
-
).className;
|
|
396
|
-
|
|
397
|
-
// Each status renders an svg indicator (no number badge)...
|
|
398
|
-
expect(screen.getByTestId('s-success').querySelector('svg')).toBeTruthy();
|
|
399
|
-
expect(screen.getByTestId('s-warning').querySelector('svg')).toBeTruthy();
|
|
400
|
-
expect(screen.getByTestId('s-error').querySelector('svg')).toBeTruthy();
|
|
401
|
-
|
|
402
|
-
// ...and each status tints the indicator differently from the others and
|
|
403
|
-
// from the plain completed (accent) step.
|
|
404
|
-
const classes = new Set([
|
|
405
|
-
indicatorClass('s-success'),
|
|
406
|
-
indicatorClass('s-warning'),
|
|
407
|
-
indicatorClass('s-error'),
|
|
408
|
-
indicatorClass('s-plain'),
|
|
409
|
-
]);
|
|
410
|
-
expect(classes.size).toBe(4);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
it('lets the current step keep its ring indicator regardless of status', () => {
|
|
414
|
-
// The current-step ring's painted color is driven by the StyleX
|
|
415
|
-
// `iconInProgress` class (accent), never a status color — the ring replaces
|
|
416
|
-
// any status glyph. The `astryx-step-indicator` theme target reflects
|
|
417
|
-
// `status` as a data attribute so a theme can still reach it, which is
|
|
418
|
-
// orthogonal to the painted color, so assert the StyleX color class here.
|
|
419
|
-
const stylexColorClasses = (el: HTMLElement) =>
|
|
420
|
-
el.className
|
|
421
|
-
.split(/\s+/)
|
|
422
|
-
// Keep StyleX classes (debug `Step__styles.*` names + `x*` atomic
|
|
423
|
-
// hashes); drop the themeProps data reflections (`in-progress`,
|
|
424
|
-
// `success`, `astryx-*`) which are orthogonal to the painted color.
|
|
425
|
-
.filter(c => c.startsWith('Step__styles.') || /^x[a-z0-9]+$/.test(c))
|
|
426
|
-
.sort()
|
|
427
|
-
.join(' ');
|
|
428
|
-
|
|
429
|
-
const plain = render(
|
|
430
|
-
<Stepper activeStep={0}>
|
|
431
|
-
<Step step={0} label="A" data-testid="plain" />
|
|
432
|
-
</Stepper>,
|
|
433
|
-
);
|
|
434
|
-
const plainIndicator = stylexColorClasses(
|
|
435
|
-
plain.getByTestId('plain').querySelector('svg')
|
|
436
|
-
?.parentElement as HTMLElement,
|
|
437
|
-
);
|
|
438
|
-
|
|
439
|
-
// The same current step, now with status="success": the painted ring must
|
|
440
|
-
// be unchanged (the current-step ring replaces any status glyph).
|
|
441
|
-
const themed = render(
|
|
442
|
-
<Stepper activeStep={0}>
|
|
443
|
-
<Step step={0} label="A" status="success" data-testid="themed" />
|
|
444
|
-
</Stepper>,
|
|
445
|
-
);
|
|
446
|
-
const themedIndicator = stylexColorClasses(
|
|
447
|
-
themed.getByTestId('themed').querySelector('svg')
|
|
448
|
-
?.parentElement as HTMLElement,
|
|
449
|
-
);
|
|
450
|
-
|
|
451
|
-
expect(themedIndicator).toBe(plainIndicator);
|
|
452
|
-
// And it is the in-progress (accent) color, not a status color.
|
|
453
|
-
expect(plainIndicator).toContain('Step__styles.iconInProgress');
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
it('replaces the number badge with a status glyph on not-started steps', () => {
|
|
457
|
-
render(
|
|
458
|
-
<Stepper activeStep={0}>
|
|
459
|
-
<Step step={0} label="A" data-testid="current" />
|
|
460
|
-
<Step step={1} label="B" status="error" data-testid="future" />
|
|
461
|
-
</Stepper>,
|
|
462
|
-
);
|
|
463
|
-
const future = screen.getByTestId('future');
|
|
464
|
-
// The not-started step would normally show its number ("2"); with a status
|
|
465
|
-
// glyph it shows an icon instead.
|
|
466
|
-
expect(future.textContent).not.toContain('2');
|
|
467
|
-
expect(future.querySelector('svg')).toBeTruthy();
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
it('exposes progress/status as visually hidden text (indicators are aria-hidden)', () => {
|
|
471
|
-
render(
|
|
472
|
-
<Stepper activeStep={2}>
|
|
473
|
-
<Step step={0} label="Account" data-testid="done" />
|
|
474
|
-
<Step step={1} label="Payment" status="error" data-testid="failed" />
|
|
475
|
-
<Step step={2} label="Review" data-testid="current" />
|
|
476
|
-
<Step step={3} label="Confirm" data-testid="upcoming" />
|
|
477
|
-
</Stepper>,
|
|
478
|
-
);
|
|
479
|
-
// Completed step announces "completed"; error status wins over completion.
|
|
480
|
-
expect(
|
|
481
|
-
within(screen.getByTestId('done')).getByText('completed'),
|
|
482
|
-
).toBeInTheDocument();
|
|
483
|
-
expect(
|
|
484
|
-
within(screen.getByTestId('failed')).getByText('error'),
|
|
485
|
-
).toBeInTheDocument();
|
|
486
|
-
expect(
|
|
487
|
-
within(screen.getByTestId('failed')).queryByText('completed'),
|
|
488
|
-
).not.toBeInTheDocument();
|
|
489
|
-
// Current step is announced via aria-current, not hidden text; upcoming
|
|
490
|
-
// steps stay silent.
|
|
491
|
-
expect(
|
|
492
|
-
within(screen.getByTestId('current')).queryByText('completed'),
|
|
493
|
-
).not.toBeInTheDocument();
|
|
494
|
-
expect(
|
|
495
|
-
within(screen.getByTestId('upcoming')).queryByText(
|
|
496
|
-
/completed|error|warning/,
|
|
497
|
-
),
|
|
498
|
-
).not.toBeInTheDocument();
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
it('exposes warning and success statuses as visually hidden text', () => {
|
|
502
|
-
render(
|
|
503
|
-
<Stepper activeStep={2}>
|
|
504
|
-
<Step step={0} label="Build" status="warning" data-testid="warned" />
|
|
505
|
-
<Step step={1} label="Deploy" status="success" data-testid="passed" />
|
|
506
|
-
</Stepper>,
|
|
507
|
-
);
|
|
508
|
-
expect(
|
|
509
|
-
within(screen.getByTestId('warned')).getByText('warning'),
|
|
510
|
-
).toBeInTheDocument();
|
|
511
|
-
expect(
|
|
512
|
-
within(screen.getByTestId('passed')).getByText('completed'),
|
|
513
|
-
).toBeInTheDocument();
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
it('composes status into the accessible name of clickable steps', () => {
|
|
517
|
-
render(
|
|
518
|
-
<Stepper activeStep={2} onStepClick={() => {}}>
|
|
519
|
-
<Step step={0} label="Account" />
|
|
520
|
-
<Step step={1} label="Payment" status="error" />
|
|
521
|
-
<Step step={2} label="Review" />
|
|
522
|
-
</Stepper>,
|
|
523
|
-
);
|
|
524
|
-
expect(
|
|
525
|
-
screen.getByRole('button', {name: 'Go to step 1: Account, completed'}),
|
|
526
|
-
).toBeInTheDocument();
|
|
527
|
-
expect(
|
|
528
|
-
screen.getByRole('button', {name: 'Go to step 2: Payment, error'}),
|
|
529
|
-
).toBeInTheDocument();
|
|
530
|
-
// The current step gets no status suffix (aria-current covers it).
|
|
531
|
-
expect(
|
|
532
|
-
screen.getByRole('button', {name: 'Go to step 3: Review'}),
|
|
533
|
-
).toBeInTheDocument();
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
it('exposes hidden status text in the on-track layout too', () => {
|
|
537
|
-
render(
|
|
538
|
-
<Stepper activeStep={1} indicatorPosition="on-track">
|
|
539
|
-
<Step step={0} label="Account" data-testid="ot-done" />
|
|
540
|
-
<Step step={1} label="Payment" data-testid="ot-current" />
|
|
541
|
-
</Stepper>,
|
|
542
|
-
);
|
|
543
|
-
expect(
|
|
544
|
-
within(screen.getByTestId('ot-done')).getByText('completed'),
|
|
545
|
-
).toBeInTheDocument();
|
|
546
|
-
expect(
|
|
547
|
-
within(screen.getByTestId('ot-current')).queryByText('completed'),
|
|
548
|
-
).not.toBeInTheDocument();
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
// A vertical on-track step's content slot renders outside the row that draws
|
|
552
|
-
// the connector, so without its own segment the track breaks open around any
|
|
553
|
-
// step carrying content. jsdom can't measure the line, so assert the wiring:
|
|
554
|
-
// the slot carries a segment, and it hides on the last step like the row's
|
|
555
|
-
// trailing one does.
|
|
556
|
-
it('continues the on-track connector past a step content slot', () => {
|
|
557
|
-
render(
|
|
558
|
-
<Stepper
|
|
559
|
-
activeStep={1}
|
|
560
|
-
orientation="vertical"
|
|
561
|
-
indicatorPosition="on-track">
|
|
562
|
-
<Step step={0} label="Account" data-testid="ot-plain" />
|
|
563
|
-
<Step step={1} label="Payment" data-testid="ot-content">
|
|
564
|
-
<button type="button">Pay now</button>
|
|
565
|
-
</Step>
|
|
566
|
-
</Stepper>,
|
|
567
|
-
);
|
|
568
|
-
expect(
|
|
569
|
-
screen
|
|
570
|
-
.getByTestId('ot-content')
|
|
571
|
-
.querySelector('[class*="otContentSegV"][class*="otSegHiddenIfLast"]'),
|
|
572
|
-
).toBeInTheDocument();
|
|
573
|
-
// A step without content has no slot, so no extra segment.
|
|
574
|
-
expect(
|
|
575
|
-
screen.getByTestId('ot-plain').querySelector('[class*="otContentSegV"]'),
|
|
576
|
-
).not.toBeInTheDocument();
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
describe('keyboard interaction', () => {
|
|
580
|
-
it('activates a step with Enter', async () => {
|
|
581
|
-
const user = userEvent.setup();
|
|
582
|
-
const handleClick = vi.fn();
|
|
583
|
-
render(
|
|
584
|
-
<Stepper activeStep={2} onStepClick={handleClick}>
|
|
585
|
-
<Step step={0} label="Step 1" />
|
|
586
|
-
<Step step={1} label="Step 2" />
|
|
587
|
-
<Step step={2} label="Step 3" />
|
|
588
|
-
</Stepper>,
|
|
589
|
-
);
|
|
590
|
-
await user.tab();
|
|
591
|
-
expect(
|
|
592
|
-
screen.getByRole('button', {name: 'Go to step 1: Step 1, completed'}),
|
|
593
|
-
).toHaveFocus();
|
|
594
|
-
await user.keyboard('{Enter}');
|
|
595
|
-
expect(handleClick).toHaveBeenCalledWith(0);
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
it('activates a step with Space', async () => {
|
|
599
|
-
const user = userEvent.setup();
|
|
600
|
-
const handleClick = vi.fn();
|
|
601
|
-
render(
|
|
602
|
-
<Stepper activeStep={2} onStepClick={handleClick}>
|
|
603
|
-
<Step step={0} label="Step 1" />
|
|
604
|
-
<Step step={1} label="Step 2" />
|
|
605
|
-
<Step step={2} label="Step 3" />
|
|
606
|
-
</Stepper>,
|
|
607
|
-
);
|
|
608
|
-
await user.tab();
|
|
609
|
-
await user.keyboard(' ');
|
|
610
|
-
expect(handleClick).toHaveBeenCalledWith(0);
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
it('tabs through steps in document order, skipping disabled ones', async () => {
|
|
614
|
-
const user = userEvent.setup();
|
|
615
|
-
render(
|
|
616
|
-
<Stepper activeStep={3} onStepClick={() => {}}>
|
|
617
|
-
<Step step={0} label="One" />
|
|
618
|
-
<Step step={1} label="Two" isDisabled />
|
|
619
|
-
<Step step={2} label="Three" />
|
|
620
|
-
</Stepper>,
|
|
621
|
-
);
|
|
622
|
-
await user.tab();
|
|
623
|
-
expect(
|
|
624
|
-
screen.getByRole('button', {name: 'Go to step 1: One, completed'}),
|
|
625
|
-
).toHaveFocus();
|
|
626
|
-
// The disabled step renders no button, so Tab lands on step 3 next.
|
|
627
|
-
await user.tab();
|
|
628
|
-
expect(
|
|
629
|
-
screen.getByRole('button', {name: 'Go to step 3: Three, completed'}),
|
|
630
|
-
).toHaveFocus();
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
it('supports keyboard activation in the on-track layout', async () => {
|
|
634
|
-
const user = userEvent.setup();
|
|
635
|
-
const handleClick = vi.fn();
|
|
636
|
-
render(
|
|
637
|
-
<Stepper
|
|
638
|
-
activeStep={2}
|
|
639
|
-
indicatorPosition="on-track"
|
|
640
|
-
onStepClick={handleClick}>
|
|
641
|
-
<Step step={0} label="Cart" />
|
|
642
|
-
<Step step={1} label="Shipping" />
|
|
643
|
-
<Step step={2} label="Payment" />
|
|
644
|
-
</Stepper>,
|
|
645
|
-
);
|
|
646
|
-
await user.tab();
|
|
647
|
-
await user.keyboard('{Enter}');
|
|
648
|
-
expect(handleClick).toHaveBeenCalledWith(0);
|
|
649
|
-
});
|
|
650
|
-
});
|
|
651
|
-
|
|
652
|
-
describe('fragment-grouped steps', () => {
|
|
653
|
-
const onTrackSteps = (
|
|
654
|
-
<>
|
|
655
|
-
<Step step={0} label="Cart" />
|
|
656
|
-
<Step step={1} label="Shipping" />
|
|
657
|
-
<Step step={2} label="Payment" />
|
|
658
|
-
</>
|
|
659
|
-
);
|
|
660
|
-
|
|
661
|
-
it('renders on-track steps identically whether they are flat or grouped in a fragment', () => {
|
|
662
|
-
const flat = render(
|
|
663
|
-
<Stepper activeStep={1} indicatorPosition="on-track">
|
|
664
|
-
<Step step={0} label="Cart" />
|
|
665
|
-
<Step step={1} label="Shipping" />
|
|
666
|
-
<Step step={2} label="Payment" />
|
|
667
|
-
</Stepper>,
|
|
668
|
-
);
|
|
669
|
-
const flatHtml = flat.container.innerHTML;
|
|
670
|
-
flat.unmount();
|
|
671
|
-
|
|
672
|
-
const grouped = render(
|
|
673
|
-
<Stepper activeStep={1} indicatorPosition="on-track">
|
|
674
|
-
{onTrackSteps}
|
|
675
|
-
</Stepper>,
|
|
676
|
-
);
|
|
677
|
-
expect(grouped.container.innerHTML).toBe(flatHtml);
|
|
678
|
-
});
|
|
679
|
-
|
|
680
|
-
// The connector's end segments are hidden by CSS keyed to the step's own
|
|
681
|
-
// <li> position, which jsdom can't evaluate — assert the wiring instead:
|
|
682
|
-
// every step carries the same hide-if-first/hide-if-last classes, so no
|
|
683
|
-
// step is singled out by counting children.
|
|
684
|
-
it('gives every grouped step the same structural connector classes', () => {
|
|
685
|
-
render(
|
|
686
|
-
<Stepper activeStep={1} indicatorPosition="on-track">
|
|
687
|
-
{onTrackSteps}
|
|
688
|
-
</Stepper>,
|
|
689
|
-
);
|
|
690
|
-
const items = screen.getAllByRole('listitem');
|
|
691
|
-
expect(items).toHaveLength(3);
|
|
692
|
-
for (const item of items) {
|
|
693
|
-
expect(
|
|
694
|
-
item.querySelector('[class*="otSegHiddenIfFirst"]'),
|
|
695
|
-
).toBeInTheDocument();
|
|
696
|
-
expect(
|
|
697
|
-
item.querySelector('[class*="otSegHiddenIfLast"]'),
|
|
698
|
-
).toBeInTheDocument();
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
it('keeps every grouped step keyboard-activatable', async () => {
|
|
703
|
-
const user = userEvent.setup();
|
|
704
|
-
const handleClick = vi.fn();
|
|
705
|
-
render(
|
|
706
|
-
<Stepper
|
|
707
|
-
activeStep={2}
|
|
708
|
-
indicatorPosition="on-track"
|
|
709
|
-
onStepClick={handleClick}>
|
|
710
|
-
{onTrackSteps}
|
|
711
|
-
</Stepper>,
|
|
712
|
-
);
|
|
713
|
-
screen
|
|
714
|
-
.getByRole('button', {name: 'Go to step 2: Shipping, completed'})
|
|
715
|
-
.focus();
|
|
716
|
-
await user.keyboard('{Enter}');
|
|
717
|
-
expect(handleClick).toHaveBeenCalledWith(1);
|
|
718
|
-
});
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
// The connector fill animates a ::before scaled along the track axis, which
|
|
722
|
-
// jsdom neither renders nor times — so assert the wiring the animation hangs
|
|
723
|
-
// off: every connector carries the shared track style (the element that owns
|
|
724
|
-
// the fill layer and its transition), and the fill/empty pair it gets is the
|
|
725
|
-
// one for its axis, since the wrong axis would scale the line's thickness
|
|
726
|
-
// away instead of its length.
|
|
727
|
-
describe('connector fill', () => {
|
|
728
|
-
const barEl = (testId: string) =>
|
|
729
|
-
screen
|
|
730
|
-
.getByTestId(testId)
|
|
731
|
-
.querySelector('[class*="connectorTrack"]') as HTMLElement;
|
|
732
|
-
|
|
733
|
-
it('scales the separated bar along the inline axis when horizontal', () => {
|
|
734
|
-
render(
|
|
735
|
-
<Stepper activeStep={1} orientation="horizontal">
|
|
736
|
-
<Step step={0} label="A" data-testid="a" />
|
|
737
|
-
<Step step={1} label="B" data-testid="b" />
|
|
738
|
-
<Step step={2} label="C" data-testid="c" />
|
|
739
|
-
</Stepper>,
|
|
740
|
-
);
|
|
741
|
-
// Reached steps are filled, upcoming ones empty — both on the H pair.
|
|
742
|
-
expect(barEl('a').className).toContain('connectorFillH');
|
|
743
|
-
expect(barEl('b').className).toContain('connectorFillH');
|
|
744
|
-
expect(barEl('c').className).toContain('connectorEmptyH');
|
|
745
|
-
expect(barEl('c').className).not.toContain('connectorEmptyV');
|
|
746
|
-
});
|
|
747
|
-
|
|
748
|
-
it('scales the separated bar along the block axis when vertical', () => {
|
|
749
|
-
render(
|
|
750
|
-
<Stepper activeStep={1} orientation="vertical">
|
|
751
|
-
<Step step={0} label="A" data-testid="a" />
|
|
752
|
-
<Step step={1} label="B" data-testid="b" />
|
|
753
|
-
<Step step={2} label="C" data-testid="c" />
|
|
754
|
-
</Stepper>,
|
|
755
|
-
);
|
|
756
|
-
expect(barEl('a').className).toContain('connectorFillV');
|
|
757
|
-
expect(barEl('c').className).toContain('connectorEmptyV');
|
|
758
|
-
expect(barEl('c').className).not.toContain('connectorEmptyH');
|
|
759
|
-
});
|
|
760
|
-
|
|
761
|
-
it('gives every on-track segment the track style and its axis pair', () => {
|
|
762
|
-
render(
|
|
763
|
-
<Stepper activeStep={1} indicatorPosition="on-track">
|
|
764
|
-
<Step step={0} label="A" data-testid="a" />
|
|
765
|
-
<Step step={1} label="B" data-testid="b" />
|
|
766
|
-
<Step step={2} label="C" data-testid="c" />
|
|
767
|
-
</Stepper>,
|
|
768
|
-
);
|
|
769
|
-
// A step draws the segments flanking its own indicator, so each carries
|
|
770
|
-
// the track style; none may fall back to the vertical axis pair here.
|
|
771
|
-
for (const id of ['a', 'b', 'c']) {
|
|
772
|
-
const segs = Array.from(
|
|
773
|
-
screen.getByTestId(id).querySelectorAll('[class*="connectorTrack"]'),
|
|
774
|
-
);
|
|
775
|
-
expect(segs).toHaveLength(2);
|
|
776
|
-
for (const seg of segs) {
|
|
777
|
-
expect(seg.className).toMatch(/connector(Fill|Empty)H/);
|
|
778
|
-
expect(seg.className).not.toMatch(/connector(Fill|Empty)V/);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
// Progress splits at the current step: the segment arriving at it is
|
|
782
|
-
// filled, the one leaving it is not.
|
|
783
|
-
const current = Array.from(
|
|
784
|
-
screen.getByTestId('b').querySelectorAll('[class*="connectorTrack"]'),
|
|
785
|
-
);
|
|
786
|
-
expect(current[0].className).toContain('connectorFillH');
|
|
787
|
-
expect(current[1].className).toContain('connectorEmptyH');
|
|
788
|
-
});
|
|
789
|
-
});
|
|
790
|
-
|
|
791
|
-
// One change animates the connector: advancing a single step. jsdom runs no
|
|
792
|
-
// transitions, so what is asserted here is the schedule one would run on.
|
|
793
|
-
// Every segment's slice is expressed in one unit — the node-to-node span —
|
|
794
|
-
// so a slice reads as `{start, length}` in spans, a segment that lands at
|
|
795
|
-
// once reads as a pair of zeros, and a span stitched from several segments
|
|
796
|
-
// is contiguous when its slices abut in track order.
|
|
797
|
-
describe('connector fill motion', () => {
|
|
798
|
-
const separated = (activeStep: number) => (
|
|
799
|
-
<Stepper activeStep={activeStep} orientation="horizontal">
|
|
800
|
-
<Step step={0} label="A" data-testid="a" />
|
|
801
|
-
<Step step={1} label="B" data-testid="b" />
|
|
802
|
-
<Step step={2} label="C" data-testid="c" />
|
|
803
|
-
<Step step={3} label="D" data-testid="d" />
|
|
804
|
-
<Step step={4} label="E" data-testid="e" />
|
|
805
|
-
</Stepper>
|
|
806
|
-
);
|
|
807
|
-
|
|
808
|
-
// StyleX routes dynamic values through hashed custom properties, whose
|
|
809
|
-
// names are not readable by hand. Recover the mapping from the one change
|
|
810
|
-
// that animates — the only one where the two carry different values. The
|
|
811
|
-
// probe mounts alongside whatever the calling test rendered, so it needs a
|
|
812
|
-
// test id of its own to be found.
|
|
813
|
-
const timingVarNames = (() => {
|
|
814
|
-
let cached: {duration: string; delay: string} | null = null;
|
|
815
|
-
return () => {
|
|
816
|
-
if (cached) {
|
|
817
|
-
return cached;
|
|
818
|
-
}
|
|
819
|
-
const steps = (
|
|
820
|
-
<>
|
|
821
|
-
<Step step={0} label="A" />
|
|
822
|
-
<Step step={1} label="B" data-testid="timing-probe" />
|
|
823
|
-
</>
|
|
824
|
-
);
|
|
825
|
-
const probe = render(<Stepper activeStep={0}>{steps}</Stepper>);
|
|
826
|
-
probe.rerender(<Stepper activeStep={1}>{steps}</Stepper>);
|
|
827
|
-
const el = probe
|
|
828
|
-
.getByTestId('timing-probe')
|
|
829
|
-
.querySelector('[class*="connectorTiming"]') as HTMLElement;
|
|
830
|
-
const found: Record<string, string> = {};
|
|
831
|
-
for (const name of Array.from(el.style)) {
|
|
832
|
-
const value = el.style.getPropertyValue(name).trim();
|
|
833
|
-
if (value === 'var(--duration-medium)') {
|
|
834
|
-
found.duration = name;
|
|
835
|
-
} else if (value === '0s') {
|
|
836
|
-
found.delay = name;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
probe.unmount();
|
|
840
|
-
cached = found as {duration: string; delay: string};
|
|
841
|
-
return cached;
|
|
842
|
-
};
|
|
843
|
-
})();
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* A slice as a multiple of one span: `0s` is none of a span, a bare span
|
|
847
|
-
* expression is all of one, and `calc(<span> * n)` is n of them.
|
|
848
|
-
*/
|
|
849
|
-
const spans = (value: string): number => {
|
|
850
|
-
if (value === '0s') {
|
|
851
|
-
return 0;
|
|
852
|
-
}
|
|
853
|
-
const scaled = value.match(/\* ([\d.]+)\)$/);
|
|
854
|
-
return scaled ? Number(scaled[1]) : 1;
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
/** Every connector in track order, as `{start, length}` in spans. */
|
|
858
|
-
const schedule = (el: HTMLElement) =>
|
|
859
|
-
Array.from(
|
|
860
|
-
el.querySelectorAll<HTMLElement>('[class*="connectorTiming"]'),
|
|
861
|
-
).map(seg => {
|
|
862
|
-
const names = timingVarNames();
|
|
863
|
-
return {
|
|
864
|
-
start: spans(seg.style.getPropertyValue(names.delay).trim()),
|
|
865
|
-
length: spans(seg.style.getPropertyValue(names.duration).trim()),
|
|
866
|
-
};
|
|
867
|
-
});
|
|
868
|
-
|
|
869
|
-
/** Nothing in this subtree moves over time. */
|
|
870
|
-
const isInstant = (el: HTMLElement) =>
|
|
871
|
-
schedule(el).every(slice => slice.start === 0 && slice.length === 0);
|
|
872
|
-
|
|
873
|
-
/** The span expression itself, which carries the fill's duration. */
|
|
874
|
-
const spanExpression = (el: HTMLElement) => {
|
|
875
|
-
const raw = (
|
|
876
|
-
el.querySelector('[class*="connectorTiming"]') as HTMLElement
|
|
877
|
-
).style
|
|
878
|
-
.getPropertyValue(timingVarNames().duration)
|
|
879
|
-
.trim();
|
|
880
|
-
return raw.replace(/^calc\((.*) \* [\d.]+\)$/, '$1');
|
|
881
|
-
};
|
|
882
|
-
|
|
883
|
-
/**
|
|
884
|
-
* The timing functions the fills in this subtree run on. Unlike the
|
|
885
|
-
* duration and the delay this is a static style, so it lives in the
|
|
886
|
-
* injected stylesheet under one of each segment's atomic classes rather
|
|
887
|
-
* than in an inline custom property.
|
|
888
|
-
*/
|
|
889
|
-
const fillEasings = (el: HTMLElement) => {
|
|
890
|
-
const found = new Set<string>();
|
|
891
|
-
for (const seg of Array.from(
|
|
892
|
-
el.querySelectorAll<HTMLElement>('[class*="connectorTrack"]'),
|
|
893
|
-
)) {
|
|
894
|
-
const classes = new Set(seg.className.split(/\s+/));
|
|
895
|
-
for (const sheet of Array.from(document.styleSheets)) {
|
|
896
|
-
for (const rule of Array.from(sheet.cssRules)) {
|
|
897
|
-
if (!('selectorText' in rule)) {
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
const {selectorText, style} = rule as CSSStyleRule;
|
|
901
|
-
const owner = selectorText.match(/^\.([\w-]+)/);
|
|
902
|
-
if (
|
|
903
|
-
owner == null ||
|
|
904
|
-
!classes.has(owner[1]) ||
|
|
905
|
-
!selectorText.endsWith('::before')
|
|
906
|
-
) {
|
|
907
|
-
continue;
|
|
908
|
-
}
|
|
909
|
-
const value = style
|
|
910
|
-
.getPropertyValue('transition-timing-function')
|
|
911
|
-
.trim();
|
|
912
|
-
if (value !== '') {
|
|
913
|
-
found.add(value);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
return [...found];
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
it('animates the one span a single forward step crosses', () => {
|
|
922
|
-
const {rerender, getByTestId} = render(separated(0));
|
|
923
|
-
rerender(separated(1));
|
|
924
|
-
// The bar arriving at the new step fills across the whole span.
|
|
925
|
-
expect(schedule(getByTestId('b'))).toEqual([{start: 0, length: 1}]);
|
|
926
|
-
// Every other bar is untouched, so it is handed no timing that a later
|
|
927
|
-
// change could inherit as a stale delay.
|
|
928
|
-
for (const id of ['a', 'c', 'd', 'e']) {
|
|
929
|
-
expect(isInstant(getByTestId(id))).toBe(true);
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
|
|
933
|
-
it('fills that span over the medium duration', () => {
|
|
934
|
-
// A fill crossing a whole segment is a spatial change, not a
|
|
935
|
-
// micro-interaction, so it sits above the fast band.
|
|
936
|
-
const {rerender, getByTestId} = render(separated(0));
|
|
937
|
-
rerender(separated(1));
|
|
938
|
-
expect(spanExpression(getByTestId('b'))).toBe('var(--duration-medium)');
|
|
939
|
-
});
|
|
940
|
-
|
|
941
|
-
it('fills linearly so a stitched span reads as one front', () => {
|
|
942
|
-
// An on-track span is drawn by two segments, three where a content slot
|
|
943
|
-
// splits it. A curve applied per segment restarts its deceleration at
|
|
944
|
-
// every seam, and the seam becomes the most visible part of the result.
|
|
945
|
-
const {container} = render(separated(0));
|
|
946
|
-
expect(fillEasings(container.firstElementChild as HTMLElement)).toEqual([
|
|
947
|
-
'linear',
|
|
948
|
-
]);
|
|
949
|
-
});
|
|
950
|
-
|
|
951
|
-
it('lands a forward jump of more than one step at once', () => {
|
|
952
|
-
// A jump is a navigation rather than a progression: sweeping a front
|
|
953
|
-
// across the crossed segments makes the user sit out a journey they
|
|
954
|
-
// asked to skip.
|
|
955
|
-
const {rerender, getByTestId} = render(separated(0));
|
|
956
|
-
rerender(separated(3));
|
|
957
|
-
for (const id of ['a', 'b', 'c', 'd', 'e']) {
|
|
958
|
-
expect(isInstant(getByTestId(id))).toBe(true);
|
|
959
|
-
}
|
|
960
|
-
});
|
|
961
|
-
|
|
962
|
-
it('lands a backward change at once, one step or several', () => {
|
|
963
|
-
// Retracting is the same arithmetic as filling, but it ends on a
|
|
964
|
-
// shrinking stub of accent rather than a nearly-full bar, and a remnant
|
|
965
|
-
// still on the track reads as unfinished however briefly it is there.
|
|
966
|
-
for (const to of [2, 0]) {
|
|
967
|
-
const view = render(separated(3));
|
|
968
|
-
view.rerender(separated(to));
|
|
969
|
-
for (const id of ['a', 'b', 'c', 'd', 'e']) {
|
|
970
|
-
expect(isInstant(view.getByTestId(id))).toBe(true);
|
|
971
|
-
}
|
|
972
|
-
view.unmount();
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
|
|
976
|
-
it('leaves every segment instant on mount', () => {
|
|
977
|
-
// A stepper opening mid-flow has no previous step to have travelled
|
|
978
|
-
// from, so its completed segments must paint filled at once rather than
|
|
979
|
-
// replaying the history that would have produced them.
|
|
980
|
-
const {getByTestId} = render(separated(3));
|
|
981
|
-
for (const id of ['a', 'b', 'c', 'd', 'e']) {
|
|
982
|
-
expect(isInstant(getByTestId(id))).toBe(true);
|
|
983
|
-
}
|
|
984
|
-
});
|
|
985
|
-
|
|
986
|
-
const onTrack = (activeStep: number) => (
|
|
987
|
-
<Stepper
|
|
988
|
-
activeStep={activeStep}
|
|
989
|
-
orientation="horizontal"
|
|
990
|
-
indicatorPosition="on-track">
|
|
991
|
-
<Step step={0} label="A" data-testid="a" />
|
|
992
|
-
<Step step={1} label="B" data-testid="b" />
|
|
993
|
-
<Step step={2} label="C" data-testid="c" />
|
|
994
|
-
</Stepper>
|
|
995
|
-
);
|
|
996
|
-
|
|
997
|
-
it('runs the leaving half of an on-track span before the arriving half', () => {
|
|
998
|
-
const {rerender, getByTestId} = render(onTrack(0));
|
|
999
|
-
rerender(onTrack(1));
|
|
1000
|
-
// The span is drawn by two steps. Left alone both halves flip together
|
|
1001
|
-
// and the gap between two nodes reads as two dashes converging on the
|
|
1002
|
-
// space between them; split, the one leaving the near node runs first
|
|
1003
|
-
// and the pair reads as one stretch of track filling.
|
|
1004
|
-
const [aCap, aRail] = schedule(getByTestId('a'));
|
|
1005
|
-
const [bCap, bRail] = schedule(getByTestId('b'));
|
|
1006
|
-
expect(aRail).toEqual({start: 0, length: 0.5});
|
|
1007
|
-
expect(bCap).toEqual({start: 0.5, length: 0.5});
|
|
1008
|
-
// The segments either side of the span are not part of it.
|
|
1009
|
-
expect(aCap).toEqual({start: 0, length: 0});
|
|
1010
|
-
expect(bRail).toEqual({start: 0, length: 0});
|
|
1011
|
-
expect(isInstant(getByTestId('c'))).toBe(true);
|
|
1012
|
-
});
|
|
1013
|
-
|
|
1014
|
-
const verticalWithContent = (activeStep: number) => (
|
|
1015
|
-
<Stepper
|
|
1016
|
-
activeStep={activeStep}
|
|
1017
|
-
orientation="vertical"
|
|
1018
|
-
indicatorPosition="on-track">
|
|
1019
|
-
<Step step={0} label="A" data-testid="a" />
|
|
1020
|
-
<Step step={1} label="B" data-testid="b">
|
|
1021
|
-
<button type="button">Do it</button>
|
|
1022
|
-
</Step>
|
|
1023
|
-
<Step step={2} label="C" data-testid="c" />
|
|
1024
|
-
</Stepper>
|
|
1025
|
-
);
|
|
1026
|
-
|
|
1027
|
-
it('threads a content slot segment into its span between rail and cap', () => {
|
|
1028
|
-
const {rerender, getByTestId} = render(verticalWithContent(1));
|
|
1029
|
-
rerender(verticalWithContent(2));
|
|
1030
|
-
// A vertical step with content draws a third segment down the side of
|
|
1031
|
-
// the slot, so the span leaving it is stitched from three pieces and all
|
|
1032
|
-
// three have to fall in track order. The rail and cap are unequal
|
|
1033
|
-
// lengths, so the slices are unequal too.
|
|
1034
|
-
const [bCap, bRail, bContent] = schedule(getByTestId('b'));
|
|
1035
|
-
const [cCap] = schedule(getByTestId('c'));
|
|
1036
|
-
expect(bRail).toEqual({start: 0, length: 0.175});
|
|
1037
|
-
expect(bContent).toEqual({start: 0.175, length: 0.525});
|
|
1038
|
-
expect(cCap).toEqual({start: 0.7, length: 0.3});
|
|
1039
|
-
// The span arriving at this step belongs to the previous change.
|
|
1040
|
-
expect(bCap).toEqual({start: 0, length: 0});
|
|
1041
|
-
expect(isInstant(getByTestId('a'))).toBe(true);
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
|
-
it('tracks the previous step correctly under StrictMode double rendering', () => {
|
|
1045
|
-
// The previous step is derived during render from state, so StrictMode
|
|
1046
|
-
// invoking the render twice must queue the same successor both times
|
|
1047
|
-
// rather than losing a step or advancing two — which would turn a single
|
|
1048
|
-
// forward step into a two-step jump and stop it animating.
|
|
1049
|
-
const {rerender, getByTestId} = render(
|
|
1050
|
-
<StrictMode>{separated(0)}</StrictMode>,
|
|
1051
|
-
);
|
|
1052
|
-
rerender(<StrictMode>{separated(1)}</StrictMode>);
|
|
1053
|
-
expect(schedule(getByTestId('b'))).toEqual([{start: 0, length: 1}]);
|
|
1054
|
-
// A second step measures from step 1, not from the original mount, so
|
|
1055
|
-
// the next span animates and the one behind it stops.
|
|
1056
|
-
rerender(<StrictMode>{separated(2)}</StrictMode>);
|
|
1057
|
-
expect(schedule(getByTestId('c'))).toEqual([{start: 0, length: 1}]);
|
|
1058
|
-
expect(isInstant(getByTestId('b'))).toBe(true);
|
|
1059
|
-
});
|
|
1060
|
-
});
|
|
1061
|
-
|
|
1062
|
-
describe('Stepper collapse (narrow containers)', () => {
|
|
1063
|
-
const FRAME = '.astryx-stepper-frame';
|
|
1064
|
-
const SUMMARY = '.astryx-stepper-summary';
|
|
1065
|
-
|
|
1066
|
-
/**
|
|
1067
|
-
* jsdom has no layout, so the width the public Stepper list measures is
|
|
1068
|
-
* described by hand. The frame deliberately reports a wide parent: this
|
|
1069
|
-
* catches any accidental switch to measuring an unconstrained wrapper, while
|
|
1070
|
-
* the regression below separately pins consumer layout styling to that frame.
|
|
1071
|
-
* The value has to be in place before the first render because the shared
|
|
1072
|
-
* resize observer takes its opening measurement synchronously during commit.
|
|
1073
|
-
*/
|
|
1074
|
-
function atWidth(width: number, ui: React.ReactElement) {
|
|
1075
|
-
const original = Object.getOwnPropertyDescriptor(
|
|
1076
|
-
Element.prototype,
|
|
1077
|
-
'clientWidth',
|
|
1078
|
-
);
|
|
1079
|
-
Object.defineProperty(Element.prototype, 'clientWidth', {
|
|
1080
|
-
configurable: true,
|
|
1081
|
-
get(this: Element) {
|
|
1082
|
-
if (this.classList.contains('astryx-stepper')) {
|
|
1083
|
-
return width;
|
|
1084
|
-
}
|
|
1085
|
-
return this.classList.contains('astryx-stepper-frame') ? 1000 : 0;
|
|
1086
|
-
},
|
|
1087
|
-
});
|
|
1088
|
-
try {
|
|
1089
|
-
return render(ui);
|
|
1090
|
-
} finally {
|
|
1091
|
-
if (original) {
|
|
1092
|
-
Object.defineProperty(Element.prototype, 'clientWidth', original);
|
|
1093
|
-
} else {
|
|
1094
|
-
delete (Element.prototype as {clientWidth?: number}).clientWidth;
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
const fourSteps = (
|
|
1100
|
-
props: Partial<React.ComponentProps<typeof Stepper>>,
|
|
1101
|
-
) => (
|
|
1102
|
-
<Stepper activeStep={1} {...props}>
|
|
1103
|
-
<Step step={0} label="Cart" />
|
|
1104
|
-
<Step step={1} label="Shipping" description="Where it goes" />
|
|
1105
|
-
<Step step={2} label="Delivery" />
|
|
1106
|
-
<Step step={3} label="Payment" />
|
|
1107
|
-
</Stepper>
|
|
1108
|
-
);
|
|
1109
|
-
|
|
1110
|
-
it('keeps every label while each step has room for one', () => {
|
|
1111
|
-
// Four steps across 600px is 150 each, comfortably over the threshold.
|
|
1112
|
-
atWidth(600, fourSteps({}));
|
|
1113
|
-
for (const name of ['Cart', 'Shipping', 'Delivery', 'Payment']) {
|
|
1114
|
-
expect(screen.getByText(name)).toBeInTheDocument();
|
|
1115
|
-
}
|
|
1116
|
-
expect(document.querySelector(FRAME)).toBeInTheDocument();
|
|
1117
|
-
});
|
|
1118
|
-
|
|
1119
|
-
it('keeps a consumer-constrained summary inside the styled component box', () => {
|
|
1120
|
-
atWidth(
|
|
1121
|
-
320,
|
|
1122
|
-
<div style={{width: 1000}}>
|
|
1123
|
-
<Stepper activeStep={1} style={{width: 320}}>
|
|
1124
|
-
<Step step={0} label="Cart" />
|
|
1125
|
-
<Step step={1} label="Shipping" />
|
|
1126
|
-
<Step step={2} label="Delivery" />
|
|
1127
|
-
<Step step={3} label="Payment" />
|
|
1128
|
-
</Stepper>
|
|
1129
|
-
</div>,
|
|
1130
|
-
);
|
|
1131
|
-
|
|
1132
|
-
const list = screen.getByRole<HTMLOListElement>('list');
|
|
1133
|
-
const frame = list.parentElement as HTMLElement;
|
|
1134
|
-
const summary = document.querySelector<HTMLElement>(SUMMARY);
|
|
1135
|
-
expect(summary).not.toBeNull();
|
|
1136
|
-
expect(frame).toHaveClass('astryx-stepper-frame');
|
|
1137
|
-
expect(frame).toHaveStyle({width: '320px'});
|
|
1138
|
-
expect(summary!.parentElement).toBe(frame);
|
|
1139
|
-
expect(list.style.width).toBe('');
|
|
1140
|
-
});
|
|
1141
|
-
|
|
1142
|
-
it('puts horizontal className on the frame without moving list DOM props or ref', () => {
|
|
1143
|
-
const ref = createRef<HTMLOListElement>();
|
|
1144
|
-
atWidth(
|
|
1145
|
-
320,
|
|
1146
|
-
<Stepper
|
|
1147
|
-
ref={ref}
|
|
1148
|
-
activeStep={1}
|
|
1149
|
-
className="consumer-stepper"
|
|
1150
|
-
data-testid="public-stepper-list"
|
|
1151
|
-
aria-describedby="stepper-help">
|
|
1152
|
-
<Step step={0} label="Cart" />
|
|
1153
|
-
<Step step={1} label="Shipping" />
|
|
1154
|
-
<Step step={2} label="Delivery" />
|
|
1155
|
-
<Step step={3} label="Payment" />
|
|
1156
|
-
</Stepper>,
|
|
1157
|
-
);
|
|
1158
|
-
|
|
1159
|
-
const list = screen.getByTestId('public-stepper-list');
|
|
1160
|
-
const frame = list.parentElement as HTMLElement;
|
|
1161
|
-
expect(ref.current).toBe(list);
|
|
1162
|
-
expect(list).toHaveAttribute('aria-describedby', 'stepper-help');
|
|
1163
|
-
expect(list).not.toHaveClass('consumer-stepper');
|
|
1164
|
-
expect(frame).toHaveClass('consumer-stepper');
|
|
1165
|
-
expect(frame).not.toHaveAttribute('data-testid');
|
|
1166
|
-
expect(frame).not.toHaveAttribute('aria-describedby');
|
|
1167
|
-
});
|
|
1168
|
-
|
|
1169
|
-
it('drops the labels and names the current step once they no longer fit', () => {
|
|
1170
|
-
// 320px over four steps is 80 each, under the 112px a label needs.
|
|
1171
|
-
atWidth(320, fourSteps({}));
|
|
1172
|
-
const summary = document.querySelector<HTMLElement>(SUMMARY);
|
|
1173
|
-
expect(summary).not.toBeNull();
|
|
1174
|
-
|
|
1175
|
-
// Only the current step is named where it can be seen, and only it keeps
|
|
1176
|
-
// a description — the rest have no label left to hang one under.
|
|
1177
|
-
expect(within(summary!).getByText('Shipping')).toBeInTheDocument();
|
|
1178
|
-
expect(within(summary!).getByText('Where it goes')).toBeInTheDocument();
|
|
1179
|
-
// The separated track has no indicator nodes of its own, so the compact
|
|
1180
|
-
// label keeps the active indicator beside it.
|
|
1181
|
-
expect(
|
|
1182
|
-
summary!.querySelector('.astryx-step-indicator'),
|
|
1183
|
-
).toBeInTheDocument();
|
|
1184
|
-
|
|
1185
|
-
const list = screen.getByRole('list');
|
|
1186
|
-
expect(within(list).queryByText('Where it goes')).toBeNull();
|
|
1187
|
-
expect(screen.getAllByRole('listitem')).toHaveLength(4);
|
|
1188
|
-
});
|
|
1189
|
-
|
|
1190
|
-
it('places the compact summary directly against the track', () => {
|
|
1191
|
-
atWidth(320, fourSteps({}));
|
|
1192
|
-
const frame = document.querySelector<HTMLElement>(FRAME);
|
|
1193
|
-
expect(frame).not.toBeNull();
|
|
1194
|
-
expect(['0', '0px']).toContain(getComputedStyle(frame!).gap);
|
|
1195
|
-
});
|
|
1196
|
-
|
|
1197
|
-
it('collapses later the more steps there are', () => {
|
|
1198
|
-
// 320px is ample for two steps at 160 each, and far too little for four.
|
|
1199
|
-
atWidth(
|
|
1200
|
-
320,
|
|
1201
|
-
<Stepper activeStep={0}>
|
|
1202
|
-
<Step step={0} label="Details" />
|
|
1203
|
-
<Step step={1} label="Review" />
|
|
1204
|
-
</Stepper>,
|
|
1205
|
-
);
|
|
1206
|
-
expect(screen.getByRole('list')).toBeInTheDocument();
|
|
1207
|
-
expect(document.querySelector('.astryx-stepper-summary')).toBeNull();
|
|
1208
|
-
});
|
|
1209
|
-
|
|
1210
|
-
it('treats the minimum step width as pixels without a measurement probe', () => {
|
|
1211
|
-
atWidth(
|
|
1212
|
-
360,
|
|
1213
|
-
fourSteps({
|
|
1214
|
-
horizontalOptions: {
|
|
1215
|
-
minimumStepWidth: 80,
|
|
1216
|
-
collapsedVariant: 'withLabelAndControls',
|
|
1217
|
-
},
|
|
1218
|
-
}),
|
|
1219
|
-
);
|
|
1220
|
-
|
|
1221
|
-
expect(document.querySelector(SUMMARY)).toBeNull();
|
|
1222
|
-
expect(
|
|
1223
|
-
Array.from(
|
|
1224
|
-
document.querySelectorAll<HTMLElement>('[aria-hidden="true"]'),
|
|
1225
|
-
).find(element => element.style.width !== ''),
|
|
1226
|
-
).toBeUndefined();
|
|
1227
|
-
});
|
|
1228
|
-
|
|
1229
|
-
it('leaves a vertical stepper alone at any width', () => {
|
|
1230
|
-
// A column gives every label a row of its own, so there is nothing to
|
|
1231
|
-
// run out of and no frame to measure.
|
|
1232
|
-
atWidth(120, fourSteps({orientation: 'vertical'}));
|
|
1233
|
-
for (const name of ['Cart', 'Shipping', 'Delivery', 'Payment']) {
|
|
1234
|
-
expect(screen.getByText(name)).toBeInTheDocument();
|
|
1235
|
-
}
|
|
1236
|
-
expect(document.querySelector(FRAME)).toBeNull();
|
|
1237
|
-
});
|
|
1238
|
-
|
|
1239
|
-
it('keeps the sequence whole for a screen reader after collapsing', () => {
|
|
1240
|
-
atWidth(320, fourSteps({}));
|
|
1241
|
-
const items = screen.getAllByRole('listitem');
|
|
1242
|
-
// Every step still names itself and the current one is still marked, so
|
|
1243
|
-
// the list reads as a complete sequence with the labels off the screen.
|
|
1244
|
-
// The status word rides along with the name, as it does when visible —
|
|
1245
|
-
// "Cart" is behind the current step, so it reads as completed.
|
|
1246
|
-
expect(items.map(li => li.textContent)).toEqual([
|
|
1247
|
-
'Cartcompleted',
|
|
1248
|
-
'Shipping',
|
|
1249
|
-
'Delivery',
|
|
1250
|
-
'Payment',
|
|
1251
|
-
]);
|
|
1252
|
-
expect(items[1]).toHaveAttribute('aria-current', 'step');
|
|
1253
|
-
});
|
|
1254
|
-
|
|
1255
|
-
it('offers no step controls on a stepper that cannot be navigated', () => {
|
|
1256
|
-
// A linear flow is driven by the form's own Back and Continue; a second
|
|
1257
|
-
// pair pointed at a step it will not honour is worse than none.
|
|
1258
|
-
atWidth(320, fourSteps({}));
|
|
1259
|
-
expect(screen.queryByRole('button', {name: 'Next step'})).toBeNull();
|
|
1260
|
-
expect(screen.queryByRole('button', {name: 'Previous step'})).toBeNull();
|
|
1261
|
-
});
|
|
1262
|
-
|
|
1263
|
-
it('moves a step at a time through the controls when one is given', async () => {
|
|
1264
|
-
const user = userEvent.setup();
|
|
1265
|
-
const onStepClick = vi.fn();
|
|
1266
|
-
atWidth(320, fourSteps({onStepClick}));
|
|
1267
|
-
|
|
1268
|
-
await user.click(screen.getByRole('button', {name: 'Next step'}));
|
|
1269
|
-
expect(onStepClick).toHaveBeenCalledWith(2);
|
|
1270
|
-
|
|
1271
|
-
await user.click(screen.getByRole('button', {name: 'Previous step'}));
|
|
1272
|
-
expect(onStepClick).toHaveBeenCalledWith(0);
|
|
1273
|
-
});
|
|
1274
|
-
|
|
1275
|
-
it('skips disabled steps in either direction', async () => {
|
|
1276
|
-
const user = userEvent.setup();
|
|
1277
|
-
const onStepClick = vi.fn();
|
|
1278
|
-
const forward = atWidth(
|
|
1279
|
-
320,
|
|
1280
|
-
<Stepper activeStep={1} onStepClick={onStepClick}>
|
|
1281
|
-
<Step step={0} label="Cart" />
|
|
1282
|
-
<Step step={1} label="Shipping" />
|
|
1283
|
-
<Step step={2} label="Delivery" isDisabled />
|
|
1284
|
-
<Step step={3} label="Payment" />
|
|
1285
|
-
</Stepper>,
|
|
1286
|
-
);
|
|
1287
|
-
|
|
1288
|
-
await user.click(screen.getByRole('button', {name: 'Next step'}));
|
|
1289
|
-
expect(onStepClick).toHaveBeenLastCalledWith(3);
|
|
1290
|
-
forward.unmount();
|
|
1291
|
-
|
|
1292
|
-
atWidth(
|
|
1293
|
-
320,
|
|
1294
|
-
<Stepper activeStep={2} onStepClick={onStepClick}>
|
|
1295
|
-
<Step step={0} label="Cart" />
|
|
1296
|
-
<Step step={1} label="Shipping" isDisabled />
|
|
1297
|
-
<Step step={2} label="Delivery" />
|
|
1298
|
-
<Step step={3} label="Payment" />
|
|
1299
|
-
</Stepper>,
|
|
1300
|
-
);
|
|
1301
|
-
await user.click(screen.getByRole('button', {name: 'Previous step'}));
|
|
1302
|
-
expect(onStepClick).toHaveBeenLastCalledWith(0);
|
|
1303
|
-
});
|
|
1304
|
-
|
|
1305
|
-
it('reads registration state again when a compact control activates', async () => {
|
|
1306
|
-
const user = userEvent.setup();
|
|
1307
|
-
const onStepClick = vi.fn();
|
|
1308
|
-
const disabled = {
|
|
1309
|
-
0: false,
|
|
1310
|
-
1: false,
|
|
1311
|
-
2: false,
|
|
1312
|
-
3: false,
|
|
1313
|
-
};
|
|
1314
|
-
|
|
1315
|
-
function Registration({step}: {step: 0 | 1 | 2 | 3}) {
|
|
1316
|
-
const {registerStep} = useStepperContext();
|
|
1317
|
-
useLayoutEffect(
|
|
1318
|
-
() =>
|
|
1319
|
-
registerStep(step, {
|
|
1320
|
-
getIsDisabled: () => disabled[step],
|
|
1321
|
-
}),
|
|
1322
|
-
[registerStep, step],
|
|
1323
|
-
);
|
|
1324
|
-
return null;
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
atWidth(
|
|
1328
|
-
320,
|
|
1329
|
-
<Stepper activeStep={1} onStepClick={onStepClick}>
|
|
1330
|
-
<Registration step={0} />
|
|
1331
|
-
<Registration step={1} />
|
|
1332
|
-
<Registration step={2} />
|
|
1333
|
-
<Registration step={3} />
|
|
1334
|
-
</Stepper>,
|
|
1335
|
-
);
|
|
1336
|
-
|
|
1337
|
-
// Step 2 was the target during render. Change only the registered source;
|
|
1338
|
-
// no parent render should be needed before activation skips it.
|
|
1339
|
-
disabled[2] = true;
|
|
1340
|
-
await user.click(screen.getByRole('button', {name: 'Next step'}));
|
|
1341
|
-
expect(onStepClick).toHaveBeenCalledWith(3);
|
|
1342
|
-
});
|
|
1343
|
-
|
|
1344
|
-
it('reads the current disabled state from each registration', async () => {
|
|
1345
|
-
const user = userEvent.setup();
|
|
1346
|
-
const onStepClick = vi.fn();
|
|
1347
|
-
const steps = (isDeliveryDisabled: boolean) => (
|
|
1348
|
-
<Stepper activeStep={1} onStepClick={onStepClick}>
|
|
1349
|
-
<Step step={0} label="Cart" />
|
|
1350
|
-
<Step step={1} label="Shipping" />
|
|
1351
|
-
<Step step={2} label="Delivery" isDisabled={isDeliveryDisabled} />
|
|
1352
|
-
<Step step={3} label="Payment" />
|
|
1353
|
-
</Stepper>
|
|
1354
|
-
);
|
|
1355
|
-
const {rerender} = atWidth(320, steps(true));
|
|
1356
|
-
|
|
1357
|
-
await user.click(screen.getByRole('button', {name: 'Next step'}));
|
|
1358
|
-
expect(onStepClick).toHaveBeenLastCalledWith(3);
|
|
1359
|
-
|
|
1360
|
-
rerender(steps(false));
|
|
1361
|
-
await user.click(screen.getByRole('button', {name: 'Next step'}));
|
|
1362
|
-
expect(onStepClick).toHaveBeenLastCalledWith(2);
|
|
1363
|
-
});
|
|
1364
|
-
|
|
1365
|
-
it('disables a summary control with no enabled step in its direction', () => {
|
|
1366
|
-
atWidth(
|
|
1367
|
-
320,
|
|
1368
|
-
<Stepper activeStep={1} onStepClick={() => {}}>
|
|
1369
|
-
<Step step={0} label="Cart" />
|
|
1370
|
-
<Step step={1} label="Shipping" />
|
|
1371
|
-
<Step step={2} label="Delivery" isDisabled />
|
|
1372
|
-
<Step step={3} label="Payment" isDisabled />
|
|
1373
|
-
</Stepper>,
|
|
1374
|
-
);
|
|
1375
|
-
expect(screen.getByRole('button', {name: 'Next step'})).toHaveAttribute(
|
|
1376
|
-
'aria-disabled',
|
|
1377
|
-
'true',
|
|
1378
|
-
);
|
|
1379
|
-
});
|
|
1380
|
-
|
|
1381
|
-
it.each(['separated', 'on-track'] as const)(
|
|
1382
|
-
'keeps %s step content mounted across compact resizing',
|
|
1383
|
-
async indicatorPosition => {
|
|
1384
|
-
const originalWidth = Object.getOwnPropertyDescriptor(
|
|
1385
|
-
Element.prototype,
|
|
1386
|
-
'clientWidth',
|
|
1387
|
-
);
|
|
1388
|
-
let width = 600;
|
|
1389
|
-
let resize: ResizeObserverCallback = () => {};
|
|
1390
|
-
class ResizeObserverStub {
|
|
1391
|
-
constructor(callback: ResizeObserverCallback) {
|
|
1392
|
-
resize = callback;
|
|
1393
|
-
}
|
|
1394
|
-
observe() {}
|
|
1395
|
-
unobserve() {}
|
|
1396
|
-
disconnect() {}
|
|
1397
|
-
}
|
|
1398
|
-
vi.stubGlobal('ResizeObserver', ResizeObserverStub);
|
|
1399
|
-
Object.defineProperty(Element.prototype, 'clientWidth', {
|
|
1400
|
-
configurable: true,
|
|
1401
|
-
get(this: Element) {
|
|
1402
|
-
return this.classList.contains('astryx-stepper') ? width : 0;
|
|
1403
|
-
},
|
|
1404
|
-
});
|
|
1405
|
-
|
|
1406
|
-
let view: ReturnType<typeof render> | null = null;
|
|
1407
|
-
try {
|
|
1408
|
-
view = render(
|
|
1409
|
-
<Stepper activeStep={0} indicatorPosition={indicatorPosition}>
|
|
1410
|
-
<Step step={0} label="Account">
|
|
1411
|
-
<input aria-label="Account name" defaultValue="" />
|
|
1412
|
-
</Step>
|
|
1413
|
-
<Step step={1} label="Review" />
|
|
1414
|
-
</Stepper>,
|
|
1415
|
-
);
|
|
1416
|
-
const user = userEvent.setup();
|
|
1417
|
-
const input = screen.getByRole<HTMLInputElement>('textbox', {
|
|
1418
|
-
name: 'Account name',
|
|
1419
|
-
});
|
|
1420
|
-
await user.type(input, 'Draft');
|
|
1421
|
-
const list = screen.getByRole('list');
|
|
1422
|
-
|
|
1423
|
-
width = 120;
|
|
1424
|
-
act(() =>
|
|
1425
|
-
resize([{target: list} as unknown as ResizeObserverEntry], null!),
|
|
1426
|
-
);
|
|
1427
|
-
const compactInput = document.querySelector<HTMLInputElement>(
|
|
1428
|
-
'input[aria-label="Account name"]',
|
|
1429
|
-
);
|
|
1430
|
-
expect(compactInput).toBe(input);
|
|
1431
|
-
expect(compactInput).toHaveValue('Draft');
|
|
1432
|
-
expect(compactInput?.closest('[hidden]')).not.toBeNull();
|
|
1433
|
-
expect(document.querySelector(SUMMARY)).toBeInTheDocument();
|
|
1434
|
-
|
|
1435
|
-
width = 600;
|
|
1436
|
-
act(() =>
|
|
1437
|
-
resize([{target: list} as unknown as ResizeObserverEntry], null!),
|
|
1438
|
-
);
|
|
1439
|
-
expect(
|
|
1440
|
-
document.querySelector('input[aria-label="Account name"]'),
|
|
1441
|
-
).toBe(input);
|
|
1442
|
-
expect(input.closest('[hidden]')).toBeNull();
|
|
1443
|
-
expect(document.querySelector(SUMMARY)).toBeNull();
|
|
1444
|
-
} finally {
|
|
1445
|
-
view?.unmount();
|
|
1446
|
-
vi.unstubAllGlobals();
|
|
1447
|
-
if (originalWidth) {
|
|
1448
|
-
Object.defineProperty(
|
|
1449
|
-
Element.prototype,
|
|
1450
|
-
'clientWidth',
|
|
1451
|
-
originalWidth,
|
|
1452
|
-
);
|
|
1453
|
-
} else {
|
|
1454
|
-
delete (Element.prototype as {clientWidth?: number}).clientWidth;
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
},
|
|
1458
|
-
);
|
|
1459
|
-
|
|
1460
|
-
it('stops the controls at both ends of the sequence', () => {
|
|
1461
|
-
const onStepClick = vi.fn();
|
|
1462
|
-
// Disabled the Astryx way: aria-disabled, so the control keeps its place
|
|
1463
|
-
// in the tab order and can still explain itself at the end of a flow.
|
|
1464
|
-
const disabled = (name: string) =>
|
|
1465
|
-
screen.getByRole('button', {name}).getAttribute('aria-disabled');
|
|
1466
|
-
|
|
1467
|
-
const {unmount} = atWidth(320, fourSteps({onStepClick, activeStep: 0}));
|
|
1468
|
-
expect(disabled('Previous step')).toBe('true');
|
|
1469
|
-
expect(disabled('Next step')).not.toBe('true');
|
|
1470
|
-
unmount();
|
|
1471
|
-
|
|
1472
|
-
atWidth(320, fourSteps({onStepClick, activeStep: 3}));
|
|
1473
|
-
expect(disabled('Previous step')).not.toBe('true');
|
|
1474
|
-
expect(disabled('Next step')).toBe('true');
|
|
1475
|
-
});
|
|
1476
|
-
|
|
1477
|
-
it('takes the collapsed steps out of the tab order', () => {
|
|
1478
|
-
// The label goes and the click target goes with it: a 4px bar is not
|
|
1479
|
-
// something to press, and a focus stop with nothing visible to show for
|
|
1480
|
-
// it is worse than no focus stop at all.
|
|
1481
|
-
atWidth(320, fourSteps({onStepClick: vi.fn()}));
|
|
1482
|
-
const stepButtons = screen
|
|
1483
|
-
.getAllByRole('button')
|
|
1484
|
-
.filter(b => (b.getAttribute('aria-label') ?? '').startsWith('Go to'));
|
|
1485
|
-
expect(stepButtons).toHaveLength(0);
|
|
1486
|
-
});
|
|
1487
|
-
|
|
1488
|
-
it('keeps collapsed on-track nodes visible but non-interactive', () => {
|
|
1489
|
-
// The indicator stays on the rail as progress information, while the
|
|
1490
|
-
// summary controls below it own navigation in the compact presentation.
|
|
1491
|
-
atWidth(
|
|
1492
|
-
320,
|
|
1493
|
-
fourSteps({indicatorPosition: 'on-track', onStepClick: vi.fn()}),
|
|
1494
|
-
);
|
|
1495
|
-
const delivery = screen.getAllByRole('listitem')[2];
|
|
1496
|
-
expect(
|
|
1497
|
-
delivery.querySelector('.astryx-step-indicator'),
|
|
1498
|
-
).toBeInTheDocument();
|
|
1499
|
-
const summary = document.querySelector<HTMLElement>(SUMMARY);
|
|
1500
|
-
expect(summary).not.toBeNull();
|
|
1501
|
-
expect(summary!.querySelector('.astryx-step-indicator')).toBeNull();
|
|
1502
|
-
expect(
|
|
1503
|
-
screen.queryByRole('button', {name: /^Go to step 3: Delivery/}),
|
|
1504
|
-
).not.toBeInTheDocument();
|
|
1505
|
-
expect(screen.getByRole('button', {name: 'Previous step'})).toBeEnabled();
|
|
1506
|
-
expect(screen.getByRole('button', {name: 'Next step'})).toBeEnabled();
|
|
1507
|
-
});
|
|
1508
|
-
|
|
1509
|
-
it('drops the controls but keeps the name on request', () => {
|
|
1510
|
-
// The shape of a wizard whose footer already has Back and Continue: the
|
|
1511
|
-
// steps stay clickable at full width, and the phone gets one pair of
|
|
1512
|
-
// controls rather than two.
|
|
1513
|
-
atWidth(
|
|
1514
|
-
320,
|
|
1515
|
-
fourSteps({
|
|
1516
|
-
onStepClick: vi.fn(),
|
|
1517
|
-
horizontalOptions: {
|
|
1518
|
-
minimumStepWidth: 112,
|
|
1519
|
-
collapsedVariant: 'withLabel',
|
|
1520
|
-
},
|
|
1521
|
-
}),
|
|
1522
|
-
);
|
|
1523
|
-
expect(screen.queryByRole('button', {name: 'Next step'})).toBeNull();
|
|
1524
|
-
expect(screen.queryByRole('button', {name: 'Previous step'})).toBeNull();
|
|
1525
|
-
|
|
1526
|
-
const summary = document.querySelector<HTMLElement>(SUMMARY);
|
|
1527
|
-
expect(summary).not.toBeNull();
|
|
1528
|
-
expect(within(summary!).getByText('Shipping')).toBeInTheDocument();
|
|
1529
|
-
});
|
|
1530
|
-
|
|
1531
|
-
it('leaves a bare track when the label is hidden, even with a handler', () => {
|
|
1532
|
-
// The surrounding flow owns both its heading and navigation. Keeping an
|
|
1533
|
-
// onStepClick handler for the expanded layout must not add a compact row.
|
|
1534
|
-
atWidth(
|
|
1535
|
-
320,
|
|
1536
|
-
fourSteps({
|
|
1537
|
-
onStepClick: vi.fn(),
|
|
1538
|
-
horizontalOptions: {
|
|
1539
|
-
minimumStepWidth: 112,
|
|
1540
|
-
collapsedVariant: 'hiddenLabel',
|
|
1541
|
-
},
|
|
1542
|
-
}),
|
|
1543
|
-
);
|
|
1544
|
-
expect(document.querySelector(SUMMARY)).toBeNull();
|
|
1545
|
-
expect(screen.queryByRole('button', {name: 'Previous step'})).toBeNull();
|
|
1546
|
-
expect(screen.queryByRole('button', {name: 'Next step'})).toBeNull();
|
|
1547
|
-
expect(screen.getByRole('list')).toBeInTheDocument();
|
|
1548
|
-
expect(screen.getAllByRole('listitem')).toHaveLength(4);
|
|
1549
|
-
});
|
|
1550
|
-
|
|
1551
|
-
it('also leaves the bare track when there is no handler', () => {
|
|
1552
|
-
atWidth(
|
|
1553
|
-
320,
|
|
1554
|
-
fourSteps({
|
|
1555
|
-
horizontalOptions: {
|
|
1556
|
-
minimumStepWidth: 112,
|
|
1557
|
-
collapsedVariant: 'hiddenLabel',
|
|
1558
|
-
},
|
|
1559
|
-
}),
|
|
1560
|
-
);
|
|
1561
|
-
expect(document.querySelector(SUMMARY)).toBeNull();
|
|
1562
|
-
expect(screen.getByRole('list')).toBeInTheDocument();
|
|
1563
|
-
expect(screen.getAllByRole('listitem')).toHaveLength(4);
|
|
1564
|
-
});
|
|
1565
|
-
|
|
1566
|
-
it('keeps the sequence whole for a screen reader when the label is hidden', () => {
|
|
1567
|
-
// The visible row only repeats the list, so suppressing it cannot shorten
|
|
1568
|
-
// what a screen reader hears. Same expectation as the default collapse.
|
|
1569
|
-
atWidth(
|
|
1570
|
-
320,
|
|
1571
|
-
fourSteps({
|
|
1572
|
-
horizontalOptions: {
|
|
1573
|
-
minimumStepWidth: 112,
|
|
1574
|
-
collapsedVariant: 'hiddenLabel',
|
|
1575
|
-
},
|
|
1576
|
-
}),
|
|
1577
|
-
);
|
|
1578
|
-
const items = screen.getAllByRole('listitem');
|
|
1579
|
-
expect(items.map(li => li.textContent)).toEqual([
|
|
1580
|
-
'Cartcompleted',
|
|
1581
|
-
'Shipping',
|
|
1582
|
-
'Delivery',
|
|
1583
|
-
'Payment',
|
|
1584
|
-
]);
|
|
1585
|
-
expect(items[1]).toHaveAttribute('aria-current', 'step');
|
|
1586
|
-
});
|
|
1587
|
-
|
|
1588
|
-
it('leaves a stepper that has room for its labels alone', () => {
|
|
1589
|
-
// The variant is scoped to the collapse and does not strip desktop labels.
|
|
1590
|
-
atWidth(
|
|
1591
|
-
600,
|
|
1592
|
-
fourSteps({
|
|
1593
|
-
onStepClick: vi.fn(),
|
|
1594
|
-
horizontalOptions: {
|
|
1595
|
-
minimumStepWidth: 112,
|
|
1596
|
-
collapsedVariant: 'hiddenLabel',
|
|
1597
|
-
},
|
|
1598
|
-
}),
|
|
1599
|
-
);
|
|
1600
|
-
for (const name of ['Cart', 'Shipping', 'Delivery', 'Payment']) {
|
|
1601
|
-
expect(screen.getByText(name)).toBeInTheDocument();
|
|
1602
|
-
}
|
|
1603
|
-
expect(
|
|
1604
|
-
screen.getByRole('button', {name: /^Go to step 3: Delivery/}),
|
|
1605
|
-
).toBeInTheDocument();
|
|
1606
|
-
});
|
|
1607
|
-
|
|
1608
|
-
it('keeps on-track nodes presentational after controls are dropped', () => {
|
|
1609
|
-
// Compact navigation belongs to the summary controls in both layouts.
|
|
1610
|
-
// Turning those controls off leaves the rail as progress information,
|
|
1611
|
-
// rather than reviving a second, denser set of click targets.
|
|
1612
|
-
atWidth(
|
|
1613
|
-
320,
|
|
1614
|
-
fourSteps({
|
|
1615
|
-
indicatorPosition: 'on-track',
|
|
1616
|
-
onStepClick: vi.fn(),
|
|
1617
|
-
horizontalOptions: {
|
|
1618
|
-
minimumStepWidth: 112,
|
|
1619
|
-
collapsedVariant: 'withLabel',
|
|
1620
|
-
},
|
|
1621
|
-
}),
|
|
1622
|
-
);
|
|
1623
|
-
expect(screen.queryByRole('button', {name: 'Next step'})).toBeNull();
|
|
1624
|
-
expect(
|
|
1625
|
-
screen.queryByRole('button', {name: /^Go to step 3: Delivery/}),
|
|
1626
|
-
).toBeNull();
|
|
1627
|
-
const indicators = screen
|
|
1628
|
-
.getAllByRole('listitem')
|
|
1629
|
-
.map(item => item.querySelector('.astryx-step-indicator'));
|
|
1630
|
-
expect(indicators).toHaveLength(4);
|
|
1631
|
-
expect(indicators.every(Boolean)).toBe(true);
|
|
1632
|
-
});
|
|
1633
|
-
});
|
|
1634
|
-
describe('--step-connector-gap', () => {
|
|
1635
|
-
// The on-track layouts draw the connector as one segment either side of
|
|
1636
|
-
// the indicator. A theme that wants the track to stop short of the node
|
|
1637
|
-
// sets one var; Astryx spends it on whichever side each segment faces the
|
|
1638
|
-
// node from, so the pair leaves a symmetric hole and the caller never
|
|
1639
|
-
// names the pieces.
|
|
1640
|
-
const onTrack = (orientation: 'vertical' | 'horizontal') => (
|
|
1641
|
-
<Stepper
|
|
1642
|
-
activeStep={1}
|
|
1643
|
-
orientation={orientation}
|
|
1644
|
-
indicatorPosition="on-track">
|
|
1645
|
-
<Step step={0} label="One" />
|
|
1646
|
-
<Step step={1} label="Two" />
|
|
1647
|
-
</Stepper>
|
|
1648
|
-
);
|
|
1649
|
-
|
|
1650
|
-
/**
|
|
1651
|
-
* Every declaration the injected stylesheet carries for an element's own
|
|
1652
|
-
* atomic classes, `::before` rules included — the same route `fillEasings`
|
|
1653
|
-
* above takes, because StyleX puts static styles in the sheet rather than
|
|
1654
|
-
* inline and jsdom resolves no cascade of its own.
|
|
1655
|
-
*
|
|
1656
|
-
* Atomic class names are unique hashes, so the owning class is matched
|
|
1657
|
-
* anywhere in the selector rather than only at its head: a StyleX variant
|
|
1658
|
-
* such as the `dir="rtl"` mirror emits a compound selector the class does
|
|
1659
|
-
* not lead. Those rules are tagged `rtl:` so a test can tell the two
|
|
1660
|
-
* directions apart.
|
|
1661
|
-
*/
|
|
1662
|
-
const declarationsFor = (el: Element) => {
|
|
1663
|
-
const classes = new Set(el.className.split(/\s+/));
|
|
1664
|
-
const out: string[] = [];
|
|
1665
|
-
for (const sheet of Array.from(document.styleSheets)) {
|
|
1666
|
-
for (const rule of Array.from(sheet.cssRules)) {
|
|
1667
|
-
if (!('selectorText' in rule)) {
|
|
1668
|
-
continue;
|
|
1669
|
-
}
|
|
1670
|
-
const {selectorText, style} = rule as CSSStyleRule;
|
|
1671
|
-
const owner = [...selectorText.matchAll(/\.([\w-]+)/g)].find(match =>
|
|
1672
|
-
classes.has(match[1]),
|
|
1673
|
-
);
|
|
1674
|
-
if (owner == null) {
|
|
1675
|
-
continue;
|
|
1676
|
-
}
|
|
1677
|
-
const prefix =
|
|
1678
|
-
(selectorText.includes('[dir="rtl"]') ? 'rtl:' : '') +
|
|
1679
|
-
(selectorText.endsWith('::before') ? 'before:' : '');
|
|
1680
|
-
for (const prop of Array.from(style)) {
|
|
1681
|
-
out.push(`${prefix}${prop}:${style.getPropertyValue(prop)}`);
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
return out.join(';');
|
|
1686
|
-
};
|
|
1687
|
-
|
|
1688
|
-
it('clips the side each segment faces the node from', () => {
|
|
1689
|
-
const {container} = render(onTrack('vertical'));
|
|
1690
|
-
const [lead, rail] = [
|
|
1691
|
-
...container.querySelectorAll('.astryx-step-connector'),
|
|
1692
|
-
];
|
|
1693
|
-
// Above the node clips its bottom edge, below it clips its top —
|
|
1694
|
-
// mirrored, so the hole is centred on the indicator.
|
|
1695
|
-
expect(declarationsFor(lead)).toMatch(/clip-path:inset\(0 0 [^;]*\)/);
|
|
1696
|
-
expect(declarationsFor(rail)).toMatch(/clip-path:inset\([^0][^;]*0 0\)/);
|
|
1697
|
-
});
|
|
1698
|
-
|
|
1699
|
-
it('uses the inline axis when the stepper is horizontal', () => {
|
|
1700
|
-
const {container} = render(onTrack('horizontal'));
|
|
1701
|
-
const [lead, rail] = [
|
|
1702
|
-
...container.querySelectorAll('.astryx-step-connector'),
|
|
1703
|
-
];
|
|
1704
|
-
expect(declarationsFor(lead)).toMatch(
|
|
1705
|
-
/clip-path:inset\(0 [^0][^;]*0 0\)/,
|
|
1706
|
-
);
|
|
1707
|
-
expect(declarationsFor(rail)).toMatch(
|
|
1708
|
-
/clip-path:inset\(0 0 0 [^0][^;]*\)/,
|
|
1709
|
-
);
|
|
1710
|
-
});
|
|
1711
|
-
|
|
1712
|
-
it('clips the track and the fill with one declaration', () => {
|
|
1713
|
-
// The gap has to reach two layers: the track is the segment's own
|
|
1714
|
-
// background, the accent fill an absolutely placed ::before. Spending it
|
|
1715
|
-
// on each separately meant two declarations on two boxes, so a
|
|
1716
|
-
// percentage resolved against a different containing block for each and
|
|
1717
|
-
// stopped them ~1.2px apart. One clip on the segment covers both.
|
|
1718
|
-
const {container} = render(onTrack('vertical'));
|
|
1719
|
-
const lead = container.querySelector(
|
|
1720
|
-
'.astryx-step-connector',
|
|
1721
|
-
) as HTMLElement;
|
|
1722
|
-
const declarations = declarationsFor(lead);
|
|
1723
|
-
expect(declarations).toContain('clip-path');
|
|
1724
|
-
// No per-layer copy of the gap to disagree with.
|
|
1725
|
-
expect(declarations).not.toMatch(
|
|
1726
|
-
/before:[a-z-]*padding[^;]*connector-gap/,
|
|
1727
|
-
);
|
|
1728
|
-
expect(declarations).not.toMatch(/before:inset[^;]*connector-gap/);
|
|
1729
|
-
});
|
|
1730
|
-
|
|
1731
|
-
it('clamps a negative gap away and caps an oversized one', () => {
|
|
1732
|
-
// A theme value arrives with nothing in between to reject it, and
|
|
1733
|
-
// `inset()` is not padding: Chromium ACCEPTS `inset(0 0 -4px 0)` rather
|
|
1734
|
-
// than clamping it, so the floor has to be written. The cap is the
|
|
1735
|
-
// flexible segment's own `min-height`, bounding an oversized gap to a
|
|
1736
|
-
// short track. Neither can grow the Stepper — a clip cannot change
|
|
1737
|
-
// layout.
|
|
1738
|
-
const {container} = render(onTrack('vertical'));
|
|
1739
|
-
const lead = container.querySelector(
|
|
1740
|
-
'.astryx-step-connector',
|
|
1741
|
-
) as HTMLElement;
|
|
1742
|
-
const declarations = declarationsFor(lead);
|
|
1743
|
-
expect(declarations).toContain('max(0px');
|
|
1744
|
-
expect(declarations).toContain('min(var(--step-connector-gap');
|
|
1745
|
-
});
|
|
1746
|
-
|
|
1747
|
-
it('flips the horizontal clip under dir="rtl"', () => {
|
|
1748
|
-
// `clip-path: inset()` is physical (top/right/bottom/left) and has no
|
|
1749
|
-
// logical form, but the row reverses under `dir="rtl"`. Unflipped, the
|
|
1750
|
-
// leading segment sits to the RIGHT of the node in RTL and still clips
|
|
1751
|
-
// its right edge, opening the hole at the join between steps instead of
|
|
1752
|
-
// at the indicator.
|
|
1753
|
-
const {container} = render(onTrack('horizontal'));
|
|
1754
|
-
const [lead, rail] = [
|
|
1755
|
-
...container.querySelectorAll('.astryx-step-connector'),
|
|
1756
|
-
];
|
|
1757
|
-
// Each segment carries BOTH the LTR clip and its mirrored RTL variant.
|
|
1758
|
-
const leadRules = declarationsFor(lead);
|
|
1759
|
-
const railRules = declarationsFor(rail);
|
|
1760
|
-
expect(leadRules).toMatch(/rtl:clip-path:inset\(0 0 0 [^0]/);
|
|
1761
|
-
expect(railRules).toMatch(/rtl:clip-path:inset\(0 [^0][^;]*0 0\)/);
|
|
1762
|
-
});
|
|
1763
|
-
|
|
1764
|
-
it('leaves the track unbroken when there is no indicator to avoid', () => {
|
|
1765
|
-
// `indicator="none"` renders no node, so a gap is a hole in a track that
|
|
1766
|
-
// is meant to be continuous.
|
|
1767
|
-
const {container} = render(
|
|
1768
|
-
<Stepper activeStep={0} indicatorPosition="on-track">
|
|
1769
|
-
<Step step={0} label="One" indicator="none" />
|
|
1770
|
-
<Step step={1} label="Two" indicator="none" />
|
|
1771
|
-
</Stepper>,
|
|
1772
|
-
);
|
|
1773
|
-
const connectors = [
|
|
1774
|
-
...container.querySelectorAll('.astryx-step-connector'),
|
|
1775
|
-
];
|
|
1776
|
-
expect(connectors.length).toBeGreaterThan(0);
|
|
1777
|
-
for (const node of connectors) {
|
|
1778
|
-
expect(declarationsFor(node)).not.toContain('--step-connector-gap');
|
|
1779
|
-
}
|
|
1780
|
-
});
|
|
1781
|
-
|
|
1782
|
-
it('defaults to no connector gap at the point of use', () => {
|
|
1783
|
-
const {container} = render(onTrack('vertical'));
|
|
1784
|
-
const root = container.querySelector('.astryx-stepper') as HTMLElement;
|
|
1785
|
-
const lead = container.querySelector(
|
|
1786
|
-
'.astryx-step-connector',
|
|
1787
|
-
) as HTMLElement;
|
|
1788
|
-
|
|
1789
|
-
expect(declarationsFor(root)).toContain('--step-connector-gap:inherit');
|
|
1790
|
-
expect(declarationsFor(lead)).toContain('var(--step-connector-gap,0px)');
|
|
1791
|
-
});
|
|
1792
|
-
|
|
1793
|
-
it('inherits a horizontal frame override through the root', () => {
|
|
1794
|
-
// Horizontal layout props belong to the frame. The list must leave the
|
|
1795
|
-
// public variable inheriting so that value reaches its connectors; the
|
|
1796
|
-
// use-site fallback above supplies 0px when no ancestor sets a value.
|
|
1797
|
-
const {container} = render(
|
|
1798
|
-
<Stepper
|
|
1799
|
-
activeStep={1}
|
|
1800
|
-
orientation="horizontal"
|
|
1801
|
-
indicatorPosition="on-track"
|
|
1802
|
-
style={{'--step-connector-gap': '6px'} as React.CSSProperties}>
|
|
1803
|
-
<Step step={0} label="One" />
|
|
1804
|
-
<Step step={1} label="Two" />
|
|
1805
|
-
</Stepper>,
|
|
1806
|
-
);
|
|
1807
|
-
const root = container.querySelector('.astryx-stepper') as HTMLElement;
|
|
1808
|
-
const frame = container.querySelector(
|
|
1809
|
-
'.astryx-stepper-frame',
|
|
1810
|
-
) as HTMLElement;
|
|
1811
|
-
expect(frame.style.getPropertyValue('--step-connector-gap')).toBe('6px');
|
|
1812
|
-
expect(declarationsFor(frame)).toContain('--step-connector-gap:0px');
|
|
1813
|
-
expect(root.style.getPropertyValue('--step-connector-gap')).toBe('');
|
|
1814
|
-
expect(declarationsFor(root)).toContain('--step-connector-gap:inherit');
|
|
1815
|
-
});
|
|
1816
|
-
|
|
1817
|
-
it('emits a root-owned override through the theme build path', () => {
|
|
1818
|
-
const theme = defineTheme({
|
|
1819
|
-
name: 'stepper-connector-gap-test',
|
|
1820
|
-
components: {
|
|
1821
|
-
stepper: {
|
|
1822
|
-
base: {'--step-connector-gap': '6px'},
|
|
1823
|
-
},
|
|
1824
|
-
},
|
|
1825
|
-
});
|
|
1826
|
-
const {component} = generateThemeCSS(theme);
|
|
1827
|
-
|
|
1828
|
-
expect(component).toMatch(
|
|
1829
|
-
/\.astryx-stepper\s*\{[^}]*--step-connector-gap:\s*6px;/,
|
|
1830
|
-
);
|
|
1831
|
-
expect(component).not.toMatch(
|
|
1832
|
-
/\.astryx-step-connector\s*\{[^}]*--step-connector-gap:/,
|
|
1833
|
-
);
|
|
1834
|
-
});
|
|
1835
|
-
|
|
1836
|
-
it('stops an outer gap at a layer opened from a step', async () => {
|
|
1837
|
-
// An outer Stepper's gap is scoped to its own track. A layer opened from
|
|
1838
|
-
// one of its steps is new content, so an inner Stepper there starts from
|
|
1839
|
-
// the connector's own 0px fallback (AST-038 FR7) instead of inheriting
|
|
1840
|
-
// the outer value through the DOM.
|
|
1841
|
-
function StepLayer() {
|
|
1842
|
-
const layer = useLayer({mode: 'context'});
|
|
1843
|
-
return (
|
|
1844
|
-
<>
|
|
1845
|
-
<button type="button" ref={layer.ref} onClick={layer.show}>
|
|
1846
|
-
Details
|
|
1847
|
-
</button>
|
|
1848
|
-
{layer.render(
|
|
1849
|
-
<Stepper activeStep={0} indicatorPosition="on-track">
|
|
1850
|
-
<Step step={0} label="Inner one" />
|
|
1851
|
-
<Step step={1} label="Inner two" />
|
|
1852
|
-
</Stepper>,
|
|
1853
|
-
)}
|
|
1854
|
-
</>
|
|
1855
|
-
);
|
|
1856
|
-
}
|
|
1857
|
-
const user = userEvent.setup();
|
|
1858
|
-
const {container} = render(
|
|
1859
|
-
<div style={{'--step-connector-gap': '6px'} as React.CSSProperties}>
|
|
1860
|
-
<Stepper activeStep={0} indicatorPosition="on-track">
|
|
1861
|
-
<Step step={0} label="Outer one">
|
|
1862
|
-
<StepLayer />
|
|
1863
|
-
</Step>
|
|
1864
|
-
<Step step={1} label="Outer two" />
|
|
1865
|
-
</Stepper>
|
|
1866
|
-
</div>,
|
|
1867
|
-
);
|
|
1868
|
-
await user.click(screen.getByRole('button', {name: 'Details'}));
|
|
1869
|
-
|
|
1870
|
-
const layerRoot = container.querySelector('[popover]') as HTMLElement;
|
|
1871
|
-
expect(layerRoot).not.toBeNull();
|
|
1872
|
-
expect(declarationsFor(layerRoot)).toContain(
|
|
1873
|
-
'--step-connector-gap:initial',
|
|
1874
|
-
);
|
|
1875
|
-
|
|
1876
|
-
// Ancestor inheritance still works outside the layer, and the inner
|
|
1877
|
-
// Stepper keeps the same inheriting root, so a value set on it or through
|
|
1878
|
-
// the `stepper` target still reaches its connectors.
|
|
1879
|
-
const [outerRoot, innerRoot] = [
|
|
1880
|
-
...container.querySelectorAll<HTMLElement>('.astryx-stepper'),
|
|
1881
|
-
];
|
|
1882
|
-
expect(layerRoot.contains(outerRoot)).toBe(false);
|
|
1883
|
-
expect(layerRoot.contains(innerRoot)).toBe(true);
|
|
1884
|
-
expect(declarationsFor(innerRoot)).toContain(
|
|
1885
|
-
'--step-connector-gap:inherit',
|
|
1886
|
-
);
|
|
1887
|
-
});
|
|
1888
|
-
|
|
1889
|
-
it('leaves the connector target itself free of a segment vocabulary', () => {
|
|
1890
|
-
// The pieces are an implementation of the on-track layout, not API: no
|
|
1891
|
-
// `data-segment`, and no bare `lead`/`rail`/`content` class that could
|
|
1892
|
-
// collide with a consumer's own stylesheet.
|
|
1893
|
-
const {container} = render(onTrack('vertical'));
|
|
1894
|
-
const connectors = [
|
|
1895
|
-
...container.querySelectorAll('.astryx-step-connector'),
|
|
1896
|
-
];
|
|
1897
|
-
expect(connectors.length).toBeGreaterThan(0);
|
|
1898
|
-
for (const node of connectors) {
|
|
1899
|
-
expect(node.getAttribute('data-segment')).toBeNull();
|
|
1900
|
-
for (const cls of ['lead', 'rail', 'content']) {
|
|
1901
|
-
expect(node.classList.contains(cls)).toBe(false);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
});
|
|
1905
|
-
});
|
|
1906
|
-
});
|
|
1907
|
-
|
|
1908
|
-
describe('step-label and step-description theme targets', () => {
|
|
1909
|
-
// A step's two text parts each declare their own typography, so a theme
|
|
1910
|
-
// cannot reach them by styling the step and letting the cascade do the rest
|
|
1911
|
-
// — an inherited value never beats a value the element declares itself.
|
|
1912
|
-
// These targets are the seam; the assertions below pin what a theme selects
|
|
1913
|
-
// and, in the last case, why the cheaper route does not work.
|
|
1914
|
-
|
|
1915
|
-
const withText = (props = {}) => (
|
|
1916
|
-
<Stepper activeStep={1}>
|
|
1917
|
-
<Step step={0} label="Account" description="Your email" {...props} />
|
|
1918
|
-
<Step step={1} label="Payment" description="Card details" />
|
|
1919
|
-
<Step step={2} label="Review" description="Check and submit" />
|
|
1920
|
-
</Stepper>
|
|
1921
|
-
);
|
|
1922
|
-
|
|
1923
|
-
it('puts the target on the element that paints the text', () => {
|
|
1924
|
-
const {container} = render(withText());
|
|
1925
|
-
const label = container.querySelector('.astryx-step-label') as HTMLElement;
|
|
1926
|
-
const description = container.querySelector(
|
|
1927
|
-
'.astryx-step-description',
|
|
1928
|
-
) as HTMLElement;
|
|
1929
|
-
// The text is the element's own content, not a descendant's: the target
|
|
1930
|
-
// sits where the paint is rather than on a wrapper around it.
|
|
1931
|
-
expect(label.textContent).toBe('Account');
|
|
1932
|
-
expect(description.textContent).toBe('Your email');
|
|
1933
|
-
});
|
|
1934
|
-
|
|
1935
|
-
it('reflects progress and status, the vocabulary step-indicator uses', () => {
|
|
1936
|
-
// Same shape as the sibling target in this file, so a theme states a
|
|
1937
|
-
// step's phase identically wherever it reaches in. Without it a theme
|
|
1938
|
-
// could not say "the label of a completed step": the compiler emits a
|
|
1939
|
-
// compound selector on one element, never a descendant of `.astryx-step`.
|
|
1940
|
-
const {container} = render(
|
|
1941
|
-
<Stepper activeStep={1}>
|
|
1942
|
-
<Step step={0} label="Done" description="d" />
|
|
1943
|
-
<Step step={1} label="Now" description="d" />
|
|
1944
|
-
<Step step={2} label="Later" description="d" status="error" />
|
|
1945
|
-
</Stepper>,
|
|
1946
|
-
);
|
|
1947
|
-
const labels = [
|
|
1948
|
-
...container.querySelectorAll<HTMLElement>('.astryx-step-label'),
|
|
1949
|
-
];
|
|
1950
|
-
expect(labels.map(el => el.dataset.progress)).toEqual([
|
|
1951
|
-
'completed',
|
|
1952
|
-
'in-progress',
|
|
1953
|
-
'not-started',
|
|
1954
|
-
]);
|
|
1955
|
-
expect(labels[2].dataset.status).toBe('error');
|
|
1956
|
-
|
|
1957
|
-
const descriptions = [
|
|
1958
|
-
...container.querySelectorAll<HTMLElement>('.astryx-step-description'),
|
|
1959
|
-
];
|
|
1960
|
-
expect(descriptions.map(el => el.dataset.progress)).toEqual([
|
|
1961
|
-
'completed',
|
|
1962
|
-
'in-progress',
|
|
1963
|
-
'not-started',
|
|
1964
|
-
]);
|
|
1965
|
-
expect(descriptions[2].dataset.status).toBe('error');
|
|
1966
|
-
});
|
|
1967
|
-
|
|
1968
|
-
it('reflects disabled on the label target and emits its theme selector', () => {
|
|
1969
|
-
// The label owns disabled paint (`styles.labelDisabled`); the description
|
|
1970
|
-
// does not. The selector follows that ownership instead of being copied to
|
|
1971
|
-
// every text target for vocabulary symmetry.
|
|
1972
|
-
const {container} = render(
|
|
1973
|
-
<Stepper activeStep={0}>
|
|
1974
|
-
<Step
|
|
1975
|
-
step={0}
|
|
1976
|
-
label="Unavailable"
|
|
1977
|
-
description="Try again later"
|
|
1978
|
-
isDisabled
|
|
1979
|
-
/>
|
|
1980
|
-
</Stepper>,
|
|
1981
|
-
);
|
|
1982
|
-
const label = container.querySelector('.astryx-step-label');
|
|
1983
|
-
const description = container.querySelector('.astryx-step-description');
|
|
1984
|
-
expect(label).toHaveAttribute('data-disabled', 'disabled');
|
|
1985
|
-
expect(label).toHaveAttribute('data-disabled', 'disabled');
|
|
1986
|
-
expect(description).not.toHaveAttribute('data-disabled');
|
|
1987
|
-
expect(description).not.toHaveAttribute('data-disabled');
|
|
1988
|
-
|
|
1989
|
-
// A DOM attribute alone would not prove the public defineTheme path accepts
|
|
1990
|
-
// and emits the state. Hold both halves of the contract.
|
|
1991
|
-
const theme = defineTheme({
|
|
1992
|
-
name: 'step-label-disabled-state-test',
|
|
1993
|
-
components: {
|
|
1994
|
-
'step-label': {
|
|
1995
|
-
'disabled:disabled': {opacity: '0.4'},
|
|
1996
|
-
},
|
|
1997
|
-
},
|
|
1998
|
-
});
|
|
1999
|
-
const {component: css} = generateThemeCSS(theme);
|
|
2000
|
-
expect(css).toContain('.astryx-step-label[data-disabled="disabled"]');
|
|
2001
|
-
expect(css).toContain('opacity: 0.4');
|
|
2002
|
-
});
|
|
2003
|
-
|
|
2004
|
-
it('carries them on the on-track layout too', () => {
|
|
2005
|
-
// The indicator-on-the-connector layout renders its own label and
|
|
2006
|
-
// description nodes; a target that only covered the default layout would
|
|
2007
|
-
// leave a theme reaching for structural selectors in exactly one mode.
|
|
2008
|
-
const {container} = render(
|
|
2009
|
-
<Stepper activeStep={0} indicatorPosition="on-track">
|
|
2010
|
-
<Step step={0} label="Account" description="Your email" />
|
|
2011
|
-
<Step step={1} label="Payment" description="Card details" />
|
|
2012
|
-
</Stepper>,
|
|
2013
|
-
);
|
|
2014
|
-
expect(container.querySelectorAll('.astryx-step-label')).toHaveLength(2);
|
|
2015
|
-
expect(container.querySelectorAll('.astryx-step-description')).toHaveLength(
|
|
2016
|
-
2,
|
|
2017
|
-
);
|
|
2018
|
-
});
|
|
2019
|
-
});
|
|
2020
|
-
|
|
2021
|
-
describe('clickable step text reading', () => {
|
|
2022
|
-
// axe-core's Label in Name rule joins a button's text nodes with nothing
|
|
2023
|
-
// between them, aria-hidden ones included, so a number badge next to a label
|
|
2024
|
-
// reads as one word ("1Account") that the step's name does not contain.
|
|
2025
|
-
// Whitespace between them changes nothing on screen (the rows are flex
|
|
2026
|
-
// containers) and keeps the two words apart.
|
|
2027
|
-
it.each([
|
|
2028
|
-
['vertical', 'separated'],
|
|
2029
|
-
['horizontal', 'separated'],
|
|
2030
|
-
['vertical', 'on-track'],
|
|
2031
|
-
['horizontal', 'on-track'],
|
|
2032
|
-
] as const)(
|
|
2033
|
-
'keeps the number and label apart in a %s %s step',
|
|
2034
|
-
(orientation, indicatorPosition) => {
|
|
2035
|
-
render(
|
|
2036
|
-
<Stepper
|
|
2037
|
-
orientation={orientation}
|
|
2038
|
-
indicatorPosition={indicatorPosition}
|
|
2039
|
-
activeStep={0}
|
|
2040
|
-
label="Steps"
|
|
2041
|
-
onStepClick={() => {}}>
|
|
2042
|
-
<Step step={0} label="Account" indicator="number" />
|
|
2043
|
-
<Step step={1} label="Payment" indicator="number" />
|
|
2044
|
-
</Stepper>,
|
|
2045
|
-
);
|
|
2046
|
-
|
|
2047
|
-
const button = screen.getByRole('button', {name: /Account/});
|
|
2048
|
-
expect(button.textContent).toMatch(/1\s+Account/);
|
|
2049
|
-
expect(button.textContent).not.toMatch(/1Account/);
|
|
2050
|
-
},
|
|
2051
|
-
);
|
|
2052
|
-
});
|
|
2053
|
-
|
|
2054
|
-
// jsdom cannot emulate forced colors, so this asserts the compiled rule the
|
|
2055
|
-
// number badge fill relies on (architecture:theme-tokens INV11).
|
|
2056
|
-
describe('Step number badge forced colors', () => {
|
|
2057
|
-
it('keeps a visible boundary on the badge fill', () => {
|
|
2058
|
-
render(
|
|
2059
|
-
<Stepper activeStep={0}>
|
|
2060
|
-
<Step step={0} label="First" indicator="number" />
|
|
2061
|
-
<Step step={1} label="Second" indicator="number" />
|
|
2062
|
-
</Stepper>,
|
|
2063
|
-
);
|
|
2064
|
-
const css = getForcedColorsRules();
|
|
2065
|
-
expect(css).toContain('outline-style: solid;');
|
|
2066
|
-
expect(css).toContain('outline-color: canvastext;');
|
|
2067
|
-
});
|
|
2068
|
-
});
|