From 72baa4d748eefc0e6c9cf38fd14ad4bb0fed2168 Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 6 Dec 2024 11:47:08 +1100 Subject: [PATCH] [Tooltip] `useAfterExitAnimation` (#943) --- .../react/src/dialog/root/useDialogRoot.ts | 2 +- packages/react/src/menu/root/useMenuRoot.ts | 2 +- .../react/src/popover/root/usePopoverRoot.ts | 2 +- .../preview-card/root/usePreviewCardRoot.ts | 2 +- .../react/src/select/root/useSelectRoot.ts | 2 +- .../react/src/tooltip/root/useTooltipRoot.ts | 34 ++++++------------- ...nimation.tsx => useAfterExitAnimation.tsx} | 0 7 files changed, 15 insertions(+), 29 deletions(-) rename packages/react/src/utils/{useAfterCloseAnimation.tsx => useAfterExitAnimation.tsx} (100%) diff --git a/packages/react/src/dialog/root/useDialogRoot.ts b/packages/react/src/dialog/root/useDialogRoot.ts index 5ac517ee54..68cc0941da 100644 --- a/packages/react/src/dialog/root/useDialogRoot.ts +++ b/packages/react/src/dialog/root/useDialogRoot.ts @@ -14,7 +14,7 @@ import { type InteractionType } from '../../utils/useEnhancedClickHandler'; import type { RequiredExcept, GenericHTMLProps } from '../../utils/types'; import { useOpenInteractionType } from '../../utils/useOpenInteractionType'; import { mergeReactProps } from '../../utils/mergeReactProps'; -import { useAfterExitAnimation } from '../../utils/useAfterCloseAnimation'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; export function useDialogRoot(parameters: useDialogRoot.Parameters): useDialogRoot.ReturnValue { const { diff --git a/packages/react/src/menu/root/useMenuRoot.ts b/packages/react/src/menu/root/useMenuRoot.ts index c9a6b9edbe..56ce8b746b 100644 --- a/packages/react/src/menu/root/useMenuRoot.ts +++ b/packages/react/src/menu/root/useMenuRoot.ts @@ -18,7 +18,7 @@ import { useTransitionStatus } from '../../utils/useTransitionStatus'; import { useEventCallback } from '../../utils/useEventCallback'; import { useControlled } from '../../utils/useControlled'; import { TYPEAHEAD_RESET_MS } from '../../utils/constants'; -import { useAfterExitAnimation } from '../../utils/useAfterCloseAnimation'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; const EMPTY_ARRAY: never[] = []; diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 4698d4dfd4..6e974aea56 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -23,7 +23,7 @@ import { translateOpenChangeReason, type OpenChangeReason, } from '../../utils/translateOpenChangeReason'; -import { useAfterExitAnimation } from '../../utils/useAfterCloseAnimation'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoot.ReturnValue { const { diff --git a/packages/react/src/preview-card/root/usePreviewCardRoot.ts b/packages/react/src/preview-card/root/usePreviewCardRoot.ts index c0aa8fc5e7..781de8cc45 100644 --- a/packages/react/src/preview-card/root/usePreviewCardRoot.ts +++ b/packages/react/src/preview-card/root/usePreviewCardRoot.ts @@ -19,7 +19,7 @@ import { translateOpenChangeReason, type OpenChangeReason, } from '../../utils/translateOpenChangeReason'; -import { useAfterExitAnimation } from '../../utils/useAfterCloseAnimation'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; export function usePreviewCardRoot( params: usePreviewCardRoot.Parameters, diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index 843eb5b562..30f92a313e 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -18,7 +18,7 @@ import { useEventCallback } from '../../utils/useEventCallback'; import { warn } from '../../utils/warn'; import type { SelectRootContext } from './SelectRootContext'; import type { SelectIndexContext } from './SelectIndexContext'; -import { useAfterExitAnimation } from '../../utils/useAfterCloseAnimation'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; export function useSelectRoot(params: useSelectRoot.Parameters): useSelectRoot.ReturnValue { const { diff --git a/packages/react/src/tooltip/root/useTooltipRoot.ts b/packages/react/src/tooltip/root/useTooltipRoot.ts index 984f26c4b1..bf29af64ac 100644 --- a/packages/react/src/tooltip/root/useTooltipRoot.ts +++ b/packages/react/src/tooltip/root/useTooltipRoot.ts @@ -13,23 +13,21 @@ import { } from '@floating-ui/react'; import { useControlled } from '../../utils/useControlled'; import { useTransitionStatus } from '../../utils/useTransitionStatus'; -import { useAnimationsFinished } from '../../utils/useAnimationsFinished'; import { useEventCallback } from '../../utils/useEventCallback'; import { OPEN_DELAY } from '../utils/constants'; import type { TransitionStatus } from '../../utils/useTransitionStatus'; import type { GenericHTMLProps } from '../../utils/types'; -import { useLatestRef } from '../../utils/useLatestRef'; import { translateOpenChangeReason, type OpenChangeReason, } from '../../utils/translateOpenChangeReason'; +import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; export function useTooltipRoot(params: useTooltipRoot.Parameters): useTooltipRoot.ReturnValue { const { open: externalOpen, onOpenChange: onOpenChangeProp = () => {}, defaultOpen = false, - keepMounted = false, hoverable = true, animated = true, trackCursorAxis = 'none', @@ -63,11 +61,16 @@ export function useTooltipRoot(params: useTooltipRoot.Parameters): useTooltipRoo [onOpenChange, setOpenUnwrapped], ); - const { mounted, setMounted, transitionStatus } = useTransitionStatus(open, animated); + const { mounted, setMounted, transitionStatus } = useTransitionStatus(open); - const runOnceAnimationsFinish = useAnimationsFinished(popupRef); - - const openRef = useLatestRef(open); + useAfterExitAnimation({ + open, + animated, + animatedElementRef: popupRef, + onFinished() { + setMounted(false); + }, + }); const context = useFloatingRootContext({ elements: { reference: triggerElement, floating: positionerElement }, @@ -95,18 +98,6 @@ export function useTooltipRoot(params: useTooltipRoot.Parameters): useTooltipRoo } else if (reasonValue === 'hover') { setInstantTypeState(undefined); } - - if (!keepMounted && !openValue) { - if (animated) { - runOnceAnimationsFinish(() => { - if (!openRef.current) { - setMounted(false); - } - }); - } else { - setMounted(false); - } - } }, }); @@ -220,11 +211,6 @@ export namespace useTooltipRoot { * @default 0 */ closeDelay?: number; - /** - * Whether the tooltip popup element stays mounted in the DOM when closed. - * @default false - */ - keepMounted?: boolean; } export interface ReturnValue { diff --git a/packages/react/src/utils/useAfterCloseAnimation.tsx b/packages/react/src/utils/useAfterExitAnimation.tsx similarity index 100% rename from packages/react/src/utils/useAfterCloseAnimation.tsx rename to packages/react/src/utils/useAfterExitAnimation.tsx