@astryxdesign/core 0.7.5 → 0.7.6-canary.0ef60dd
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/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 +7 -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/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/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 +101 -15
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +8 -3
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +1 -1
- 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 +7 -3
- 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 +4 -4
- package/dist/Field/InputClearButton.js +3 -3
- package/dist/Field/PanelSearchInput.js +2 -2
- package/dist/FieldStatus/FieldStatus.js +2 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -1
- 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 +2 -1
- 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 +93 -59
- 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/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -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/CreateRow.a11y.chromium.spec.js +7 -6
- package/dist/MultiSelector/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +26 -10
- package/dist/NumberInput/NumberInput.d.ts +3 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +3 -3
- 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/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +16 -12
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +28 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
- 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/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 +10 -2
- 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/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +16 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
- 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 +82 -51
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +13 -2
- package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
- 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/Typeahead/Typeahead.d.ts +1 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +9 -1
- package/dist/astryx.css +20 -4
- package/dist/gestures/GestureArena.d.ts +6 -0
- package/dist/gestures/GestureArena.d.ts.map +1 -1
- package/dist/gestures/GestureArena.js +39 -0
- package/dist/gestures/GestureHost.d.ts +352 -0
- package/dist/gestures/GestureHost.d.ts.map +1 -0
- package/dist/gestures/GestureHost.js +1773 -0
- package/dist/gestures/GestureRecognizer.d.ts +10 -0
- package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/GestureRecognizer.js +16 -0
- 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/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/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/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/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/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +5 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +5 -0
- package/dist/motion/animator.d.ts +7 -1
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +119 -27
- 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/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/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.map +1 -1
- package/dist/utils/touchPresentation.js +5 -3
- 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/unicodeDigits.d.ts +20 -0
- package/dist/utils/unicodeDigits.d.ts.map +1 -0
- package/dist/utils/unicodeDigits.js +70 -0
- package/locales/en.json +23 -3
- package/locales/pseudo.json +15 -0
- package/package.json +5 -4
- package/src/AlertDialog/AlertDialog.tsx +6 -5
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
- package/src/Avatar/Avatar.spec.md +22 -22
- package/src/Avatar/Avatar.tsx +18 -1
- package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
- package/src/Badge/Badge.doc.mjs +1 -1
- package/src/Badge/Badge.tsx +19 -2
- package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
- package/src/BottomSheet/BottomSheet.test.tsx +46 -0
- package/src/BottomSheet/BottomSheet.tsx +1 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
- package/src/BottomSheet/useSheetGestures.test.ts +52 -0
- package/src/BottomSheet/useSheetGestures.ts +37 -6
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
- package/src/Button/Button.tsx +4 -4
- package/src/Calendar/Calendar.spec.md +87 -48
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
- package/src/CheckboxInput/CheckboxInput.tsx +6 -5
- package/src/ClickableCard/ClickableCard.test.tsx +96 -0
- 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/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
- package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
- package/src/ContextMenu/ContextMenu.test.tsx +35 -0
- package/src/DateInput/DateInput.test.tsx +115 -3
- package/src/DateInput/DateInput.tsx +29 -14
- package/src/DateInput/DateInputTouch.test.tsx +76 -0
- package/src/DateInput/MonthScroller.tsx +106 -20
- package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
- package/src/DateInput/TouchDateField.tsx +14 -3
- package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
- package/src/DateRangeInput/DateRangeInput.tsx +16 -12
- package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
- package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
- package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
- 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.test.tsx +216 -2
- package/src/Dialog/Dialog.tsx +42 -9
- package/src/Dialog/DialogHeader.tsx +5 -4
- package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
- package/src/Divider/Divider.tsx +2 -1
- package/src/Drawer/Drawer.spec.md +111 -80
- package/src/Drawer/Drawer.test.tsx +35 -0
- package/src/Drawer/Drawer.tsx +13 -2
- package/src/Drawer/DrawerHeader.spec.md +181 -0
- package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
- package/src/DropdownMenu/DropdownMenu.tsx +10 -3
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
- package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
- package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
- package/src/EmptyState/EmptyState.tsx +2 -1
- package/src/Field/FieldLabel.tsx +5 -4
- package/src/Field/InputClearButton.tsx +3 -3
- package/src/Field/PanelSearchInput.tsx +2 -2
- package/src/FieldStatus/FieldStatus.tsx +2 -2
- package/src/FileInput/FileInput.test.tsx +21 -0
- package/src/FileInput/FileInput.tsx +4 -1
- package/src/FormLayout/FormLayout.spec.md +7 -8
- 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 +2 -1
- package/src/Item/ItemSwipeLayer.tsx +1 -1
- package/src/Kbd/Kbd.spec.md +81 -38
- package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
- package/src/Layer/popoverOperations.test.ts +205 -0
- package/src/Layer/popoverOperations.ts +172 -0
- package/src/Layer/useLayer.test.tsx +348 -1
- package/src/Layer/useLayer.tsx +118 -71
- 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/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
- package/src/Lightbox/Lightbox.test.tsx +18 -0
- package/src/Lightbox/Lightbox.tsx +5 -0
- package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
- 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.test.tsx +15 -0
- package/src/MobileNav/MobileNav.tsx +9 -1
- package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
- package/src/MoreMenu/MoreMenu.test.tsx +11 -0
- package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
- package/src/MultiSelector/MultiSelector.spec.md +7 -4
- package/src/MultiSelector/MultiSelector.test.tsx +270 -1
- package/src/MultiSelector/MultiSelector.tsx +25 -10
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
- package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
- package/src/NumberInput/NumberInput.doc.mjs +13 -7
- package/src/NumberInput/NumberInput.spec.md +59 -37
- package/src/NumberInput/NumberInput.tsx +13 -3
- package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
- package/src/NumberInput/numberParser.ts +7 -45
- package/src/ProgressBar/ProgressBar.test.tsx +108 -32
- package/src/ProgressBar/ProgressBar.tsx +58 -10
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
- package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
- package/src/Resizable/useResizable.test.ts +43 -0
- package/src/Resizable/useResizable.ts +32 -9
- package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
- package/src/Selector/Selector.test.tsx +90 -1
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
- package/src/Selector/useSelectorPresentation.ts +31 -3
- package/src/SideNav/SideNav.test.tsx +27 -0
- package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
- package/src/Skeleton/Skeleton.tsx +3 -1
- package/src/Slider/Slider.test.tsx +31 -0
- package/src/Slider/Slider.tsx +8 -3
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
- package/src/Spinner/Spinner.tsx +5 -3
- package/src/Stack/Stack.tsx +1 -1
- package/src/Stack/StackItem.tsx +1 -1
- package/src/TabList/TabList.test.tsx +58 -4
- package/src/TabList/TabList.tsx +16 -1
- package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
- package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
- package/src/Text/Text.tsx +1 -1
- package/src/Text/useTruncation.test.tsx +128 -1
- package/src/Text/useTruncation.ts +23 -5
- package/src/TextArea/TextArea.spec.md +10 -13
- package/src/TextArea/TextArea.test.tsx +60 -0
- package/src/TextArea/TextArea.tsx +15 -1
- package/src/TextInput/TextInput.test.tsx +21 -0
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
- package/src/TimeInput/Presentation.test.tsx +21 -0
- package/src/TimeInput/TimeInput.doc.mjs +8 -8
- package/src/TimeInput/TimeInput.spec.md +45 -48
- package/src/TimeInput/TimeInput.test.tsx +76 -0
- 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.test.tsx +30 -5
- package/src/Timestamp/Timestamp.tsx +6 -2
- package/src/Timestamp/TimestampHoverCard.tsx +4 -4
- package/src/Toast/Toast.spec.md +14 -20
- package/src/Toast/Toast.tsx +104 -36
- package/src/Toast/ToastViewport.test.tsx +719 -1
- package/src/Toast/ToastViewport.tsx +100 -50
- package/src/Tokenizer/Tokenizer.spec.md +5 -3
- package/src/Tokenizer/Tokenizer.test.tsx +68 -0
- package/src/Tokenizer/Tokenizer.tsx +14 -2
- package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
- package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
- package/src/Toolbar/Toolbar.spec.md +5 -6
- package/src/Toolbar/Toolbar.test.tsx +30 -0
- package/src/Toolbar/Toolbar.tsx +2 -1
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
- package/src/TopNav/TopNav.test.tsx +27 -0
- package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
- package/src/TopNav/TopNavMegaMenu.tsx +4 -1
- package/src/TopNav/TopNavMenu.test.tsx +17 -0
- package/src/TopNav/TopNavMenu.tsx +1 -0
- package/src/Typeahead/Typeahead.test.tsx +40 -0
- package/src/Typeahead/Typeahead.tsx +12 -1
- package/src/__tests__/pressState.ts +8 -4
- package/src/gestures/GestureArena.ts +35 -0
- package/src/gestures/GestureHost.ts +2065 -0
- package/src/gestures/GestureRecognizer.ts +18 -0
- package/src/gestures/LongPressGestureRecognizer.ts +4 -0
- package/src/gestures/PanGestureRecognizer.ts +4 -0
- package/src/gestures/PinchGestureRecognizer.ts +148 -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/__tests__/GestureHost.test.ts +2087 -0
- package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
- package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
- package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
- package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
- package/src/gestures/__tests__/arena.test.ts +5 -0
- package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
- package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
- package/src/gestures/__tests__/browser/fixture.ts +307 -0
- package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
- package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
- package/src/gestures/__tests__/haptics.test.ts +187 -0
- package/src/gestures/__tests__/harness.ts +21 -2
- package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
- package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
- package/src/gestures/haptics.ts +203 -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/hooks/index.ts +5 -1
- package/src/hooks/modalAnnounce.ts +129 -72
- package/src/hooks/useAdaptivePresentation.ts +4 -1
- package/src/hooks/useAnnounce.doc.mjs +35 -3
- package/src/hooks/useAnnounce.replace.test.tsx +516 -0
- package/src/hooks/useAnnounce.ts +209 -102
- package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
- package/src/hooks/useAnnounceRenderedText.ts +17 -3
- package/src/hooks/useBusyAnnouncement.ts +7 -10
- package/src/hooks/useMenuHover.ts +15 -1
- package/src/i18n/generated-locales/en.generated.ts +6 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +6 -0
- package/src/motion/README.md +11 -1
- package/src/motion/animator.test.ts +151 -3
- package/src/motion/animator.ts +149 -33
- package/src/theme/Theme.doc.mjs +1 -1
- package/src/theme/defineTheme.ts +117 -8
- package/src/theme/derivedVarRegistry.test.ts +4 -0
- package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
- package/src/theme/domainTokens/index.ts +6 -10
- package/src/theme/expandMotionScale.test.ts +1 -1
- 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.test.ts +620 -0
- 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/focusReturn.ts +17 -6
- package/src/utils/getNodeText.test.ts +24 -0
- package/src/utils/getNodeText.ts +37 -0
- package/src/utils/interactionModality.test.ts +45 -1
- package/src/utils/interactionModality.ts +64 -5
- package/src/utils/interactionOverlay.stylex.ts +12 -3
- package/src/utils/plainDate.test.ts +90 -0
- package/src/utils/plainDate.ts +58 -3
- package/src/utils/presentation.test.ts +380 -0
- package/src/utils/presentation.ts +180 -0
- package/src/utils/pressFeedback.test.ts +138 -0
- package/src/utils/pressFeedback.ts +34 -11
- package/src/utils/pressPaintPriority.test.ts +80 -0
- package/src/utils/primaryClick.test.ts +38 -0
- package/src/utils/primaryClick.ts +28 -0
- package/src/utils/timeFormat.test.ts +204 -0
- package/src/utils/timeFormat.ts +314 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.test.ts +140 -1
- package/src/utils/touchPresentation.ts +5 -3
- package/src/utils/unicodeDigits.test.ts +44 -0
- package/src/utils/unicodeDigits.ts +71 -0
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
waitFor,
|
|
31
31
|
within,
|
|
32
32
|
} from '@testing-library/react';
|
|
33
|
-
import React from 'react';
|
|
33
|
+
import React, {useRef} from 'react';
|
|
34
34
|
import {readFileSync} from 'node:fs';
|
|
35
35
|
import {type AnnounceFn, __resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
36
36
|
import {Button} from '../Button';
|
|
@@ -602,6 +602,173 @@ describe('ToastViewport keyboard reach + focus', () => {
|
|
|
602
602
|
expect(document.activeElement).toBe(dismiss);
|
|
603
603
|
});
|
|
604
604
|
|
|
605
|
+
it('moves focus to the neighbour when a control inside a toast raises its repeat and dismisses it', () => {
|
|
606
|
+
function OfflineFlow() {
|
|
607
|
+
const toast = useToast();
|
|
608
|
+
const dismissOfflineRef = useRef<(() => void) | null>(null);
|
|
609
|
+
const showOffline = (body: string) => {
|
|
610
|
+
dismissOfflineRef.current = toast({
|
|
611
|
+
uniqueID: 'offline',
|
|
612
|
+
isAutoHide: false,
|
|
613
|
+
body,
|
|
614
|
+
endContent: (
|
|
615
|
+
<button
|
|
616
|
+
type="button"
|
|
617
|
+
onClick={() => {
|
|
618
|
+
// A retry reports the state again, then closes the toast it
|
|
619
|
+
// was pressed in.
|
|
620
|
+
const dismissPressed = dismissOfflineRef.current;
|
|
621
|
+
showOffline('Still offline');
|
|
622
|
+
dismissPressed?.();
|
|
623
|
+
}}>
|
|
624
|
+
Retry
|
|
625
|
+
</button>
|
|
626
|
+
),
|
|
627
|
+
});
|
|
628
|
+
};
|
|
629
|
+
return (
|
|
630
|
+
<>
|
|
631
|
+
<button
|
|
632
|
+
type="button"
|
|
633
|
+
onClick={() => {
|
|
634
|
+
toast({isAutoHide: false, body: 'Alpha'});
|
|
635
|
+
toast({isAutoHide: false, body: 'Bravo'});
|
|
636
|
+
}}>
|
|
637
|
+
Show two
|
|
638
|
+
</button>
|
|
639
|
+
<button type="button" onClick={() => showOffline('Offline')}>
|
|
640
|
+
Show offline
|
|
641
|
+
</button>
|
|
642
|
+
</>
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
render(
|
|
646
|
+
<ToastViewport isTopLayer={false} maxVisible={2}>
|
|
647
|
+
<OfflineFlow />
|
|
648
|
+
</ToastViewport>,
|
|
649
|
+
);
|
|
650
|
+
act(() => {
|
|
651
|
+
fireEvent.click(screen.getByText('Show two'));
|
|
652
|
+
});
|
|
653
|
+
act(() => {
|
|
654
|
+
fireEvent.click(screen.getByText('Show offline'));
|
|
655
|
+
});
|
|
656
|
+
// Alpha waits hidden; Bravo and Offline show.
|
|
657
|
+
const retry = within(getToastWrapperByText('Offline')).getByRole('button', {
|
|
658
|
+
name: 'Retry',
|
|
659
|
+
});
|
|
660
|
+
retry.focus();
|
|
661
|
+
act(() => {
|
|
662
|
+
fireEvent.click(retry);
|
|
663
|
+
});
|
|
664
|
+
// Toast.spec.md FR10: focus moves to a control in a remaining toast, the
|
|
665
|
+
// neighbour of the dismissed one, not to the hidden oldest toast or the
|
|
666
|
+
// region.
|
|
667
|
+
expect(
|
|
668
|
+
getToastWrapperByText('Bravo').contains(document.activeElement),
|
|
669
|
+
).toBe(true);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('moves focus into the replacement when a control inside the only toast raises its repeat and dismisses it', () => {
|
|
673
|
+
function OfflineFlow() {
|
|
674
|
+
const toast = useToast();
|
|
675
|
+
const dismissOfflineRef = useRef<(() => void) | null>(null);
|
|
676
|
+
const showOffline = (body: string) => {
|
|
677
|
+
dismissOfflineRef.current = toast({
|
|
678
|
+
uniqueID: 'offline',
|
|
679
|
+
isAutoHide: false,
|
|
680
|
+
body,
|
|
681
|
+
endContent: (
|
|
682
|
+
<button
|
|
683
|
+
type="button"
|
|
684
|
+
onClick={() => {
|
|
685
|
+
const dismissPressed = dismissOfflineRef.current;
|
|
686
|
+
showOffline('Still offline');
|
|
687
|
+
dismissPressed?.();
|
|
688
|
+
}}>
|
|
689
|
+
Retry
|
|
690
|
+
</button>
|
|
691
|
+
),
|
|
692
|
+
});
|
|
693
|
+
};
|
|
694
|
+
return (
|
|
695
|
+
<button type="button" onClick={() => showOffline('Offline')}>
|
|
696
|
+
Show offline
|
|
697
|
+
</button>
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
render(
|
|
701
|
+
<ToastViewport isTopLayer={false}>
|
|
702
|
+
<OfflineFlow />
|
|
703
|
+
</ToastViewport>,
|
|
704
|
+
);
|
|
705
|
+
act(() => {
|
|
706
|
+
fireEvent.click(screen.getByText('Show offline'));
|
|
707
|
+
});
|
|
708
|
+
const retry = within(getToastWrapperByText('Offline')).getByRole('button', {
|
|
709
|
+
name: 'Retry',
|
|
710
|
+
});
|
|
711
|
+
retry.focus();
|
|
712
|
+
act(() => {
|
|
713
|
+
fireEvent.click(retry);
|
|
714
|
+
});
|
|
715
|
+
// FR10: the replacement is the remaining toast, so focus goes into it.
|
|
716
|
+
expect(
|
|
717
|
+
getToastWrapperByText('Still offline').contains(document.activeElement),
|
|
718
|
+
).toBe(true);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it('moves focus to a toast that shows when a control inside a toast raises two toasts at the cap and dismisses its own', () => {
|
|
722
|
+
function UploadFlow() {
|
|
723
|
+
const toast = useToast();
|
|
724
|
+
const dismissSavedRef = useRef<(() => void) | null>(null);
|
|
725
|
+
return (
|
|
726
|
+
<button
|
|
727
|
+
type="button"
|
|
728
|
+
onClick={() => {
|
|
729
|
+
dismissSavedRef.current = toast({
|
|
730
|
+
isAutoHide: false,
|
|
731
|
+
body: 'Saved',
|
|
732
|
+
endContent: (
|
|
733
|
+
<button
|
|
734
|
+
type="button"
|
|
735
|
+
onClick={() => {
|
|
736
|
+
toast({isAutoHide: false, body: 'Uploading'});
|
|
737
|
+
toast({isAutoHide: false, body: 'Uploaded'});
|
|
738
|
+
dismissSavedRef.current?.();
|
|
739
|
+
}}>
|
|
740
|
+
Upload
|
|
741
|
+
</button>
|
|
742
|
+
),
|
|
743
|
+
});
|
|
744
|
+
}}>
|
|
745
|
+
Save
|
|
746
|
+
</button>
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
render(
|
|
750
|
+
<ToastViewport isTopLayer={false} maxVisible={1}>
|
|
751
|
+
<UploadFlow />
|
|
752
|
+
</ToastViewport>,
|
|
753
|
+
);
|
|
754
|
+
act(() => {
|
|
755
|
+
fireEvent.click(screen.getByText('Save'));
|
|
756
|
+
});
|
|
757
|
+
const upload = within(getToastWrapperByText('Saved')).getByRole('button', {
|
|
758
|
+
name: 'Upload',
|
|
759
|
+
});
|
|
760
|
+
upload.focus();
|
|
761
|
+
act(() => {
|
|
762
|
+
fireEvent.click(upload);
|
|
763
|
+
});
|
|
764
|
+
// FR10: with one visible place, "Uploaded" shows and "Uploading" waits
|
|
765
|
+
// hidden, so focus goes to "Uploaded", not to the hidden toast or the
|
|
766
|
+
// region.
|
|
767
|
+
expect(
|
|
768
|
+
getToastWrapperByText('Uploaded').contains(document.activeElement),
|
|
769
|
+
).toBe(true);
|
|
770
|
+
});
|
|
771
|
+
|
|
605
772
|
it('dismissing a focused toast moves focus to a remaining toast, not body', () => {
|
|
606
773
|
renderViewport(
|
|
607
774
|
<>
|
|
@@ -2061,6 +2228,413 @@ describe('toast announcements via singleton live regions', () => {
|
|
|
2061
2228
|
expect(within(viewport).getByText('Kept')).toBeInTheDocument();
|
|
2062
2229
|
expect(within(viewport).queryByText('Dropped')).not.toBeInTheDocument();
|
|
2063
2230
|
});
|
|
2231
|
+
|
|
2232
|
+
it('drops an ignored-collision toast while its namesake is still leaving', () => {
|
|
2233
|
+
renderViewport(
|
|
2234
|
+
<>
|
|
2235
|
+
<ShowToastButton
|
|
2236
|
+
options={{
|
|
2237
|
+
uniqueID: 'offline',
|
|
2238
|
+
collisionBehavior: 'ignore',
|
|
2239
|
+
isAutoHide: false,
|
|
2240
|
+
body: 'You are offline',
|
|
2241
|
+
}}
|
|
2242
|
+
triggerLabel="Show 1"
|
|
2243
|
+
/>
|
|
2244
|
+
<ShowToastButton
|
|
2245
|
+
options={{
|
|
2246
|
+
uniqueID: 'offline',
|
|
2247
|
+
collisionBehavior: 'ignore',
|
|
2248
|
+
isAutoHide: false,
|
|
2249
|
+
body: 'Still offline',
|
|
2250
|
+
}}
|
|
2251
|
+
triggerLabel="Show 2"
|
|
2252
|
+
/>
|
|
2253
|
+
</>,
|
|
2254
|
+
);
|
|
2255
|
+
act(() => {
|
|
2256
|
+
fireEvent.click(screen.getByText('Show 1'));
|
|
2257
|
+
});
|
|
2258
|
+
const first = getToastWrapperByText('You are offline');
|
|
2259
|
+
act(() => {
|
|
2260
|
+
fireEvent.click(
|
|
2261
|
+
within(first).getByRole('button', {name: 'Dismiss notification'}),
|
|
2262
|
+
);
|
|
2263
|
+
});
|
|
2264
|
+
// Toast.spec.md FR8: a leaving toast still holds its uniqueID, so the
|
|
2265
|
+
// ignored namesake is neither shown nor announced.
|
|
2266
|
+
act(() => {
|
|
2267
|
+
fireEvent.click(screen.getByText('Show 2'));
|
|
2268
|
+
});
|
|
2269
|
+
expect(announceSpy).toHaveBeenCalledTimes(1);
|
|
2270
|
+
expect(screen.queryByText('Still offline')).toBeNull();
|
|
2271
|
+
act(() => {
|
|
2272
|
+
completeExit(first.dataset.toastId ?? '');
|
|
2273
|
+
});
|
|
2274
|
+
expect(document.querySelectorAll('[data-toast-id]')).toHaveLength(0);
|
|
2275
|
+
});
|
|
2276
|
+
|
|
2277
|
+
it('lets a leaving toast finish its exit when a new toast arrives with no cap', () => {
|
|
2278
|
+
render(
|
|
2279
|
+
<ToastViewport isTopLayer={false} maxVisible={0}>
|
|
2280
|
+
<ShowToastButton
|
|
2281
|
+
options={{isAutoHide: false, body: 'Saved'}}
|
|
2282
|
+
triggerLabel="Show 1"
|
|
2283
|
+
/>
|
|
2284
|
+
<ShowToastButton
|
|
2285
|
+
options={{isAutoHide: false, body: 'Uploaded'}}
|
|
2286
|
+
triggerLabel="Show 2"
|
|
2287
|
+
/>
|
|
2288
|
+
</ToastViewport>,
|
|
2289
|
+
);
|
|
2290
|
+
act(() => {
|
|
2291
|
+
fireEvent.click(screen.getByText('Show 1'));
|
|
2292
|
+
});
|
|
2293
|
+
const first = getToastWrapperByText('Saved');
|
|
2294
|
+
const firstId = first.dataset.toastId ?? '';
|
|
2295
|
+
act(() => {
|
|
2296
|
+
fireEvent.click(
|
|
2297
|
+
within(first).getByRole('button', {name: 'Dismiss notification'}),
|
|
2298
|
+
);
|
|
2299
|
+
});
|
|
2300
|
+
// maxVisible={0} shows every toast (Toast.spec.md FR7), so the closing
|
|
2301
|
+
// toast keeps its row and collapses (FR5) while the new one arrives.
|
|
2302
|
+
act(() => {
|
|
2303
|
+
fireEvent.click(screen.getByText('Show 2'));
|
|
2304
|
+
});
|
|
2305
|
+
expect(getToastWrapperByText('Saved').dataset.toastId).toBe(firstId);
|
|
2306
|
+
expect(screen.getByText('Uploaded')).toBeInTheDocument();
|
|
2307
|
+
act(() => {
|
|
2308
|
+
completeExit(firstId);
|
|
2309
|
+
});
|
|
2310
|
+
expect(screen.queryByText('Saved')).toBeNull();
|
|
2311
|
+
expect(screen.getByText('Uploaded')).toBeInTheDocument();
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2314
|
+
it('drops a second ignore toast with the same uniqueID raised in the same handler', () => {
|
|
2315
|
+
function ShowTwoIgnored() {
|
|
2316
|
+
const toast = useToast();
|
|
2317
|
+
return (
|
|
2318
|
+
<button
|
|
2319
|
+
type="button"
|
|
2320
|
+
onClick={() => {
|
|
2321
|
+
toast({
|
|
2322
|
+
uniqueID: 'offline',
|
|
2323
|
+
collisionBehavior: 'ignore',
|
|
2324
|
+
isAutoHide: false,
|
|
2325
|
+
body: 'You are offline',
|
|
2326
|
+
});
|
|
2327
|
+
toast({
|
|
2328
|
+
uniqueID: 'offline',
|
|
2329
|
+
collisionBehavior: 'ignore',
|
|
2330
|
+
isAutoHide: false,
|
|
2331
|
+
body: 'Still offline',
|
|
2332
|
+
});
|
|
2333
|
+
}}>
|
|
2334
|
+
Show twice
|
|
2335
|
+
</button>
|
|
2336
|
+
);
|
|
2337
|
+
}
|
|
2338
|
+
render(
|
|
2339
|
+
<ToastViewport isTopLayer={false}>
|
|
2340
|
+
<ShowTwoIgnored />
|
|
2341
|
+
</ToastViewport>,
|
|
2342
|
+
);
|
|
2343
|
+
act(() => {
|
|
2344
|
+
fireEvent.click(screen.getByText('Show twice'));
|
|
2345
|
+
});
|
|
2346
|
+
// Toast.spec.md FR8 and ORD1: the ignored namesake is neither shown nor
|
|
2347
|
+
// announced, even before the first toast renders.
|
|
2348
|
+
expect(announceSpy).toHaveBeenCalledTimes(1);
|
|
2349
|
+
expect(announceSpy).toHaveBeenLastCalledWith('You are offline', 'polite');
|
|
2350
|
+
const rows = [...document.querySelectorAll('[data-toast-id]')];
|
|
2351
|
+
expect(rows).toHaveLength(1);
|
|
2352
|
+
expect(rows[0].textContent).toContain('You are offline');
|
|
2353
|
+
});
|
|
2354
|
+
|
|
2355
|
+
it('leaves no row behind when a new toast takes the last visible slot from a leaving one', () => {
|
|
2356
|
+
render(
|
|
2357
|
+
<ToastViewport isTopLayer={false} maxVisible={1}>
|
|
2358
|
+
<ShowToastButton
|
|
2359
|
+
options={{isAutoHide: false, body: 'Saved'}}
|
|
2360
|
+
triggerLabel="Show 1"
|
|
2361
|
+
/>
|
|
2362
|
+
<ShowToastButton
|
|
2363
|
+
options={{isAutoHide: false, body: 'Uploaded'}}
|
|
2364
|
+
triggerLabel="Show 2"
|
|
2365
|
+
/>
|
|
2366
|
+
</ToastViewport>,
|
|
2367
|
+
);
|
|
2368
|
+
act(() => {
|
|
2369
|
+
fireEvent.click(screen.getByText('Show 1'));
|
|
2370
|
+
});
|
|
2371
|
+
const first = getToastWrapperByText('Saved');
|
|
2372
|
+
act(() => {
|
|
2373
|
+
fireEvent.click(
|
|
2374
|
+
within(first).getByRole('button', {name: 'Dismiss notification'}),
|
|
2375
|
+
);
|
|
2376
|
+
});
|
|
2377
|
+
// A new toast arrives at once; with one visible slot it takes the place of
|
|
2378
|
+
// the leaving toast, which can no longer finish its exit on screen.
|
|
2379
|
+
act(() => {
|
|
2380
|
+
fireEvent.click(screen.getByText('Show 2'));
|
|
2381
|
+
});
|
|
2382
|
+
const second = getToastWrapperByText('Uploaded');
|
|
2383
|
+
act(() => {
|
|
2384
|
+
fireEvent.click(
|
|
2385
|
+
within(second).getByRole('button', {name: 'Dismiss notification'}),
|
|
2386
|
+
);
|
|
2387
|
+
});
|
|
2388
|
+
act(() => {
|
|
2389
|
+
completeExit(second.dataset.toastId ?? '');
|
|
2390
|
+
});
|
|
2391
|
+
// Nothing is left: no row comes back, and the landmark is gone.
|
|
2392
|
+
expect(document.querySelectorAll('[data-toast-id]')).toHaveLength(0);
|
|
2393
|
+
expect(screen.queryByRole('region', {name: 'Notifications'})).toBeNull();
|
|
2394
|
+
});
|
|
2395
|
+
|
|
2396
|
+
it('reports the namesake once when one handler shows a repeat and dismisses the namesake', () => {
|
|
2397
|
+
const onHide = vi.fn();
|
|
2398
|
+
function RepeatAndDismiss() {
|
|
2399
|
+
const toast = useToast();
|
|
2400
|
+
const dismissFirstRef = useRef<(() => void) | null>(null);
|
|
2401
|
+
return (
|
|
2402
|
+
<>
|
|
2403
|
+
<button
|
|
2404
|
+
type="button"
|
|
2405
|
+
onClick={() => {
|
|
2406
|
+
dismissFirstRef.current = toast({
|
|
2407
|
+
uniqueID: 'offline',
|
|
2408
|
+
isAutoHide: false,
|
|
2409
|
+
body: 'Offline',
|
|
2410
|
+
onHide,
|
|
2411
|
+
});
|
|
2412
|
+
}}>
|
|
2413
|
+
Show first
|
|
2414
|
+
</button>
|
|
2415
|
+
<button
|
|
2416
|
+
type="button"
|
|
2417
|
+
onClick={() => {
|
|
2418
|
+
toast({
|
|
2419
|
+
uniqueID: 'offline',
|
|
2420
|
+
isAutoHide: false,
|
|
2421
|
+
body: 'Still offline',
|
|
2422
|
+
});
|
|
2423
|
+
dismissFirstRef.current?.();
|
|
2424
|
+
}}>
|
|
2425
|
+
Repeat and dismiss
|
|
2426
|
+
</button>
|
|
2427
|
+
</>
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
render(
|
|
2431
|
+
<ToastViewport isTopLayer={false}>
|
|
2432
|
+
<RepeatAndDismiss />
|
|
2433
|
+
</ToastViewport>,
|
|
2434
|
+
);
|
|
2435
|
+
act(() => {
|
|
2436
|
+
fireEvent.click(screen.getByText('Show first'));
|
|
2437
|
+
});
|
|
2438
|
+
act(() => {
|
|
2439
|
+
fireEvent.click(screen.getByText('Repeat and dismiss'));
|
|
2440
|
+
});
|
|
2441
|
+
// As on `main`: the repeat replaces its namesake in place, and the
|
|
2442
|
+
// namesake's dismissal reports it once.
|
|
2443
|
+
expect(onHide).toHaveBeenCalledTimes(1);
|
|
2444
|
+
const rows = [...document.querySelectorAll('[data-toast-id]')];
|
|
2445
|
+
expect(rows).toHaveLength(1);
|
|
2446
|
+
expect(rows[0].textContent).toContain('Still offline');
|
|
2447
|
+
});
|
|
2448
|
+
|
|
2449
|
+
it('leaves no row behind when one handler raises a toast at the cap and dismisses the one it pushed out', () => {
|
|
2450
|
+
const onHide = vi.fn();
|
|
2451
|
+
function UndoFlow() {
|
|
2452
|
+
const toast = useToast();
|
|
2453
|
+
const dismissDeletedRef = useRef<(() => void) | null>(null);
|
|
2454
|
+
return (
|
|
2455
|
+
<>
|
|
2456
|
+
<button
|
|
2457
|
+
type="button"
|
|
2458
|
+
onClick={() => {
|
|
2459
|
+
dismissDeletedRef.current = toast({
|
|
2460
|
+
isAutoHide: false,
|
|
2461
|
+
body: 'Deleted',
|
|
2462
|
+
onHide,
|
|
2463
|
+
});
|
|
2464
|
+
}}>
|
|
2465
|
+
Delete
|
|
2466
|
+
</button>
|
|
2467
|
+
<button
|
|
2468
|
+
type="button"
|
|
2469
|
+
onClick={() => {
|
|
2470
|
+
// An undo shows its confirmation, then dismisses its own toast.
|
|
2471
|
+
toast({isAutoHide: false, body: 'Restored'});
|
|
2472
|
+
dismissDeletedRef.current?.();
|
|
2473
|
+
}}>
|
|
2474
|
+
Undo
|
|
2475
|
+
</button>
|
|
2476
|
+
</>
|
|
2477
|
+
);
|
|
2478
|
+
}
|
|
2479
|
+
render(
|
|
2480
|
+
<ToastViewport isTopLayer={false} maxVisible={1}>
|
|
2481
|
+
<UndoFlow />
|
|
2482
|
+
</ToastViewport>,
|
|
2483
|
+
);
|
|
2484
|
+
act(() => {
|
|
2485
|
+
fireEvent.click(screen.getByText('Delete'));
|
|
2486
|
+
});
|
|
2487
|
+
act(() => {
|
|
2488
|
+
fireEvent.click(screen.getByText('Undo'));
|
|
2489
|
+
});
|
|
2490
|
+
expect(onHide).toHaveBeenCalledTimes(1);
|
|
2491
|
+
const restored = getToastWrapperByText('Restored');
|
|
2492
|
+
act(() => {
|
|
2493
|
+
fireEvent.click(
|
|
2494
|
+
within(restored).getByRole('button', {name: 'Dismiss notification'}),
|
|
2495
|
+
);
|
|
2496
|
+
});
|
|
2497
|
+
act(() => {
|
|
2498
|
+
completeExit(restored.dataset.toastId ?? '');
|
|
2499
|
+
});
|
|
2500
|
+
// Nothing is left: no row comes back, and the landmark is gone.
|
|
2501
|
+
expect(document.querySelectorAll('[data-toast-id]')).toHaveLength(0);
|
|
2502
|
+
expect(screen.queryByRole('region', {name: 'Notifications'})).toBeNull();
|
|
2503
|
+
});
|
|
2504
|
+
|
|
2505
|
+
it('reports a leaving toast once when it is dismissed again after a new toast pushed it out of view', () => {
|
|
2506
|
+
const onHide = vi.fn();
|
|
2507
|
+
function ShowPushDismiss() {
|
|
2508
|
+
const toast = useToast();
|
|
2509
|
+
const dismissFirstRef = useRef<(() => void) | null>(null);
|
|
2510
|
+
return (
|
|
2511
|
+
<>
|
|
2512
|
+
<button
|
|
2513
|
+
type="button"
|
|
2514
|
+
onClick={() => {
|
|
2515
|
+
dismissFirstRef.current = toast({
|
|
2516
|
+
isAutoHide: false,
|
|
2517
|
+
body: 'Saved',
|
|
2518
|
+
onHide,
|
|
2519
|
+
});
|
|
2520
|
+
}}>
|
|
2521
|
+
Show first
|
|
2522
|
+
</button>
|
|
2523
|
+
<button
|
|
2524
|
+
type="button"
|
|
2525
|
+
onClick={() => {
|
|
2526
|
+
toast({isAutoHide: false, body: 'Uploaded'});
|
|
2527
|
+
}}>
|
|
2528
|
+
Show second
|
|
2529
|
+
</button>
|
|
2530
|
+
<button type="button" onClick={() => dismissFirstRef.current?.()}>
|
|
2531
|
+
Dismiss first
|
|
2532
|
+
</button>
|
|
2533
|
+
</>
|
|
2534
|
+
);
|
|
2535
|
+
}
|
|
2536
|
+
render(
|
|
2537
|
+
<ToastViewport isTopLayer={false} maxVisible={1}>
|
|
2538
|
+
<ShowPushDismiss />
|
|
2539
|
+
</ToastViewport>,
|
|
2540
|
+
);
|
|
2541
|
+
act(() => {
|
|
2542
|
+
fireEvent.click(screen.getByText('Show first'));
|
|
2543
|
+
});
|
|
2544
|
+
// It starts leaving, and reports it.
|
|
2545
|
+
act(() => {
|
|
2546
|
+
fireEvent.click(screen.getByText('Dismiss first'));
|
|
2547
|
+
});
|
|
2548
|
+
expect(onHide).toHaveBeenCalledTimes(1);
|
|
2549
|
+
// A new toast takes the only visible slot: the leaving one leaves the list.
|
|
2550
|
+
act(() => {
|
|
2551
|
+
fireEvent.click(screen.getByText('Show second'));
|
|
2552
|
+
});
|
|
2553
|
+
// Its dismissal again reports nothing more.
|
|
2554
|
+
act(() => {
|
|
2555
|
+
fireEvent.click(screen.getByText('Dismiss first'));
|
|
2556
|
+
});
|
|
2557
|
+
expect(onHide).toHaveBeenCalledTimes(1);
|
|
2558
|
+
const rows = [...document.querySelectorAll('[data-toast-id]')];
|
|
2559
|
+
expect(rows).toHaveLength(1);
|
|
2560
|
+
expect(rows[0].textContent).toContain('Uploaded');
|
|
2561
|
+
});
|
|
2562
|
+
|
|
2563
|
+
it('reports nothing for a toast replaced before it rendered, however often one handler dismisses it', () => {
|
|
2564
|
+
const onHide = vi.fn();
|
|
2565
|
+
function ShowReplaceDismiss() {
|
|
2566
|
+
const toast = useToast();
|
|
2567
|
+
return (
|
|
2568
|
+
<button
|
|
2569
|
+
type="button"
|
|
2570
|
+
onClick={() => {
|
|
2571
|
+
const dismissFirst = toast({
|
|
2572
|
+
uniqueID: 'offline',
|
|
2573
|
+
isAutoHide: false,
|
|
2574
|
+
body: 'Offline',
|
|
2575
|
+
onHide,
|
|
2576
|
+
});
|
|
2577
|
+
toast({
|
|
2578
|
+
uniqueID: 'offline',
|
|
2579
|
+
isAutoHide: false,
|
|
2580
|
+
body: 'Still offline',
|
|
2581
|
+
});
|
|
2582
|
+
dismissFirst();
|
|
2583
|
+
dismissFirst();
|
|
2584
|
+
}}>
|
|
2585
|
+
Show, replace and dismiss
|
|
2586
|
+
</button>
|
|
2587
|
+
);
|
|
2588
|
+
}
|
|
2589
|
+
render(
|
|
2590
|
+
<ToastViewport isTopLayer={false}>
|
|
2591
|
+
<ShowReplaceDismiss />
|
|
2592
|
+
</ToastViewport>,
|
|
2593
|
+
);
|
|
2594
|
+
act(() => {
|
|
2595
|
+
fireEvent.click(screen.getByText('Show, replace and dismiss'));
|
|
2596
|
+
});
|
|
2597
|
+
// Toast.spec.md FR3: a toast replaced through uniqueID is not dismissed
|
|
2598
|
+
// and reports no onHide.
|
|
2599
|
+
expect(onHide).not.toHaveBeenCalled();
|
|
2600
|
+
const rows = [...document.querySelectorAll('[data-toast-id]')];
|
|
2601
|
+
expect(rows).toHaveLength(1);
|
|
2602
|
+
expect(rows[0].textContent).toContain('Still offline');
|
|
2603
|
+
});
|
|
2604
|
+
|
|
2605
|
+
it('replaces a leaving namesake in place under overwrite and announces it again', () => {
|
|
2606
|
+
renderViewport(
|
|
2607
|
+
<>
|
|
2608
|
+
<ShowToastButton
|
|
2609
|
+
options={{uniqueID: 'upload', isAutoHide: false, body: 'Upload 30%'}}
|
|
2610
|
+
triggerLabel="Show 1"
|
|
2611
|
+
/>
|
|
2612
|
+
<ShowToastButton
|
|
2613
|
+
options={{uniqueID: 'upload', isAutoHide: false, body: 'Upload 31%'}}
|
|
2614
|
+
triggerLabel="Show 2"
|
|
2615
|
+
/>
|
|
2616
|
+
</>,
|
|
2617
|
+
);
|
|
2618
|
+
act(() => {
|
|
2619
|
+
fireEvent.click(screen.getByText('Show 1'));
|
|
2620
|
+
});
|
|
2621
|
+
const first = getToastWrapperByText('Upload 30%');
|
|
2622
|
+
act(() => {
|
|
2623
|
+
fireEvent.click(
|
|
2624
|
+
within(first).getByRole('button', {name: 'Dismiss notification'}),
|
|
2625
|
+
);
|
|
2626
|
+
});
|
|
2627
|
+
// Toast.spec.md FR8: an overwrite replaces its namesake in place even
|
|
2628
|
+
// while it is leaving, and is announced again.
|
|
2629
|
+
act(() => {
|
|
2630
|
+
fireEvent.click(screen.getByText('Show 2'));
|
|
2631
|
+
});
|
|
2632
|
+
expect(announceSpy).toHaveBeenLastCalledWith('Upload 31%', 'polite');
|
|
2633
|
+
expect(screen.queryByText('Upload 30%')).toBeNull();
|
|
2634
|
+
const rows = [...document.querySelectorAll('[data-toast-id]')];
|
|
2635
|
+
expect(rows).toHaveLength(1);
|
|
2636
|
+
expect(rows[0].textContent).toContain('Upload 31%');
|
|
2637
|
+
});
|
|
2064
2638
|
});
|
|
2065
2639
|
|
|
2066
2640
|
describe('toast timer lifecycle (#3589)', () => {
|
|
@@ -2084,6 +2658,150 @@ describe('toast timer lifecycle (#3589)', () => {
|
|
|
2084
2658
|
expect(onHide).toHaveBeenCalledTimes(1);
|
|
2085
2659
|
});
|
|
2086
2660
|
|
|
2661
|
+
// spec:Toast FR2/AR3: each pause condition is held on its own, so one
|
|
2662
|
+
// ending never resumes the timer while another still holds.
|
|
2663
|
+
function showPausableToast(onHide: () => void) {
|
|
2664
|
+
renderViewport(
|
|
2665
|
+
<ShowToastButton
|
|
2666
|
+
options={{
|
|
2667
|
+
body: 'Held',
|
|
2668
|
+
autoHideDuration: 3000,
|
|
2669
|
+
endContent: <Button label="Undo" />,
|
|
2670
|
+
onHide,
|
|
2671
|
+
}}
|
|
2672
|
+
triggerLabel="Show held"
|
|
2673
|
+
/>,
|
|
2674
|
+
);
|
|
2675
|
+
act(() => {
|
|
2676
|
+
fireEvent.click(screen.getByText('Show held'));
|
|
2677
|
+
});
|
|
2678
|
+
const viewport = screen.getByRole('region', {name: 'Notifications'});
|
|
2679
|
+
const card = within(viewport).getByText('Held').closest('[role="status"]');
|
|
2680
|
+
if (!(card instanceof HTMLElement)) {
|
|
2681
|
+
throw new Error('toast card not found');
|
|
2682
|
+
}
|
|
2683
|
+
return {card, action: within(card).getByRole('button', {name: 'Undo'})};
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
it('keeps the timer paused while focus is inside after the pointer leaves', () => {
|
|
2687
|
+
vi.useFakeTimers();
|
|
2688
|
+
try {
|
|
2689
|
+
const onHide = vi.fn();
|
|
2690
|
+
const {card, action} = showPausableToast(onHide);
|
|
2691
|
+
act(() => {
|
|
2692
|
+
fireEvent.mouseEnter(card);
|
|
2693
|
+
});
|
|
2694
|
+
act(() => {
|
|
2695
|
+
action.focus();
|
|
2696
|
+
});
|
|
2697
|
+
act(() => {
|
|
2698
|
+
fireEvent.mouseLeave(card);
|
|
2699
|
+
});
|
|
2700
|
+
act(() => {
|
|
2701
|
+
vi.advanceTimersByTime(60_000);
|
|
2702
|
+
});
|
|
2703
|
+
expect(onHide).not.toHaveBeenCalled();
|
|
2704
|
+
// Focus leaving the card releases the last hold.
|
|
2705
|
+
act(() => {
|
|
2706
|
+
action.blur();
|
|
2707
|
+
});
|
|
2708
|
+
act(() => {
|
|
2709
|
+
vi.advanceTimersByTime(60_000);
|
|
2710
|
+
});
|
|
2711
|
+
expect(onHide).toHaveBeenCalledWith('auto');
|
|
2712
|
+
} finally {
|
|
2713
|
+
vi.useRealTimers();
|
|
2714
|
+
}
|
|
2715
|
+
});
|
|
2716
|
+
|
|
2717
|
+
it('keeps the timer paused while the pointer is over it after the window regains focus', () => {
|
|
2718
|
+
vi.useFakeTimers();
|
|
2719
|
+
try {
|
|
2720
|
+
const onHide = vi.fn();
|
|
2721
|
+
const {card} = showPausableToast(onHide);
|
|
2722
|
+
act(() => {
|
|
2723
|
+
fireEvent.blur(window);
|
|
2724
|
+
});
|
|
2725
|
+
act(() => {
|
|
2726
|
+
fireEvent.mouseEnter(card);
|
|
2727
|
+
});
|
|
2728
|
+
act(() => {
|
|
2729
|
+
fireEvent.focus(window);
|
|
2730
|
+
});
|
|
2731
|
+
act(() => {
|
|
2732
|
+
vi.advanceTimersByTime(60_000);
|
|
2733
|
+
});
|
|
2734
|
+
expect(onHide).not.toHaveBeenCalled();
|
|
2735
|
+
act(() => {
|
|
2736
|
+
fireEvent.mouseLeave(card);
|
|
2737
|
+
});
|
|
2738
|
+
act(() => {
|
|
2739
|
+
vi.advanceTimersByTime(60_000);
|
|
2740
|
+
});
|
|
2741
|
+
expect(onHide).toHaveBeenCalledWith('auto');
|
|
2742
|
+
} finally {
|
|
2743
|
+
vi.useRealTimers();
|
|
2744
|
+
}
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
it('releases the focus hold when the focused control is removed', () => {
|
|
2748
|
+
vi.useFakeTimers();
|
|
2749
|
+
try {
|
|
2750
|
+
const onHide = vi.fn();
|
|
2751
|
+
const {card, action} = showPausableToast(onHide);
|
|
2752
|
+
act(() => {
|
|
2753
|
+
fireEvent.mouseEnter(card);
|
|
2754
|
+
});
|
|
2755
|
+
act(() => {
|
|
2756
|
+
action.focus();
|
|
2757
|
+
});
|
|
2758
|
+
// A control that unmounts while focused fires no blur.
|
|
2759
|
+
act(() => {
|
|
2760
|
+
action.remove();
|
|
2761
|
+
});
|
|
2762
|
+
act(() => {
|
|
2763
|
+
fireEvent.mouseLeave(card);
|
|
2764
|
+
});
|
|
2765
|
+
act(() => {
|
|
2766
|
+
vi.advanceTimersByTime(60_000);
|
|
2767
|
+
});
|
|
2768
|
+
expect(onHide).toHaveBeenCalledWith('auto');
|
|
2769
|
+
} finally {
|
|
2770
|
+
vi.useRealTimers();
|
|
2771
|
+
}
|
|
2772
|
+
});
|
|
2773
|
+
|
|
2774
|
+
it('keeps the timer paused while focus moves between controls inside the card', () => {
|
|
2775
|
+
vi.useFakeTimers();
|
|
2776
|
+
try {
|
|
2777
|
+
const onHide = vi.fn();
|
|
2778
|
+
const {card, action} = showPausableToast(onHide);
|
|
2779
|
+
const dismiss = within(card)
|
|
2780
|
+
.getAllByRole('button')
|
|
2781
|
+
.find(button => button !== action);
|
|
2782
|
+
if (!dismiss) {
|
|
2783
|
+
throw new Error('dismiss button not found');
|
|
2784
|
+
}
|
|
2785
|
+
act(() => {
|
|
2786
|
+
action.focus();
|
|
2787
|
+
});
|
|
2788
|
+
act(() => {
|
|
2789
|
+
vi.advanceTimersByTime(2_000);
|
|
2790
|
+
});
|
|
2791
|
+
act(() => {
|
|
2792
|
+
dismiss.focus();
|
|
2793
|
+
});
|
|
2794
|
+
// Moving between the card's own controls neither restarts nor resumes
|
|
2795
|
+
// the timer.
|
|
2796
|
+
act(() => {
|
|
2797
|
+
vi.advanceTimersByTime(60_000);
|
|
2798
|
+
});
|
|
2799
|
+
expect(onHide).not.toHaveBeenCalled();
|
|
2800
|
+
} finally {
|
|
2801
|
+
vi.useRealTimers();
|
|
2802
|
+
}
|
|
2803
|
+
});
|
|
2804
|
+
|
|
2087
2805
|
it('keeps a window-blur pause alive when another toast arrives', () => {
|
|
2088
2806
|
vi.useFakeTimers();
|
|
2089
2807
|
try {
|