diff --git a/packages/@mantine/core/src/components/Modal/Modal.story.tsx b/packages/@mantine/core/src/components/Modal/Modal.story.tsx index e1de48a762..a7c8706119 100644 --- a/packages/@mantine/core/src/components/Modal/Modal.story.tsx +++ b/packages/@mantine/core/src/components/Modal/Modal.story.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { useDisclosure } from '@mantine/hooks'; import { Button } from '../Button'; import { Menu } from '../Menu'; @@ -31,7 +32,13 @@ export function Usage() { {content} - + console.log('onExited') }} + onExitTransitionEnd={() => console.log('onExitTransitionEnd')} + > diff --git a/packages/@mantine/core/src/components/ModalBase/ModalBase.context.ts b/packages/@mantine/core/src/components/ModalBase/ModalBase.context.ts index fe0547f989..e63da6c257 100644 --- a/packages/@mantine/core/src/components/ModalBase/ModalBase.context.ts +++ b/packages/@mantine/core/src/components/ModalBase/ModalBase.context.ts @@ -10,6 +10,8 @@ interface ModalBaseContextValue { getTitleId: () => string; getBodyId: () => string; transitionProps: Partial | undefined; + onExitTransitionEnd: (() => void) | undefined; + onEnterTransitionEnd: (() => void) | undefined; zIndex: string | number | undefined; opened: boolean; diff --git a/packages/@mantine/core/src/components/ModalBase/ModalBase.tsx b/packages/@mantine/core/src/components/ModalBase/ModalBase.tsx index be6d993008..4f3bda434f 100644 --- a/packages/@mantine/core/src/components/ModalBase/ModalBase.tsx +++ b/packages/@mantine/core/src/components/ModalBase/ModalBase.tsx @@ -54,6 +54,12 @@ export interface ModalBaseProps extends BoxProps, ElementProps<'div', 'title'> { /** Props added to the `Transition` component that used to animate overlay and body, use to configure duration and animation type, `{ duration: 200, transition: 'pop' }` by default */ transitionProps?: TransitionOverride; + /** Called when exit transition ends */ + onExitTransitionEnd?: () => void; + + /** Called when enter transition ends */ + onEnterTransitionEnd?: () => void; + /** Determines whether `onClose` should be called when user presses the escape key, `true` by default */ closeOnEscape?: boolean; @@ -84,6 +90,8 @@ export const ModalBase = forwardRef( onClose, id, transitionProps, + onExitTransitionEnd, + onEnterTransitionEnd, trapFocus, closeOnEscape, returnFocus, @@ -114,6 +122,8 @@ export const ModalBase = forwardRef( opened, onClose, closeOnClickOutside, + onExitTransitionEnd, + onEnterTransitionEnd, transitionProps: { ...transitionProps, keepMounted }, getTitleId: () => `${_id}-title`, getBodyId: () => `${_id}-body`, diff --git a/packages/@mantine/core/src/components/ModalBase/ModalBaseContent.tsx b/packages/@mantine/core/src/components/ModalBase/ModalBaseContent.tsx index 3ead27f149..306e9a84a3 100644 --- a/packages/@mantine/core/src/components/ModalBase/ModalBaseContent.tsx +++ b/packages/@mantine/core/src/components/ModalBase/ModalBaseContent.tsx @@ -31,6 +31,14 @@ export const ModalBaseContent = forwardRef { + ctx.onExitTransitionEnd?.(); + ctx.transitionProps?.onExited?.(); + }} + onEntered={() => { + ctx.onEnterTransitionEnd?.(); + ctx.transitionProps?.onEntered?.(); + }} {...transitionProps} > {(transitionStyles) => ( diff --git a/packages/@mantine/core/src/components/Popover/Popover.story.tsx b/packages/@mantine/core/src/components/Popover/Popover.story.tsx index c71d3627fa..7801af3cd5 100644 --- a/packages/@mantine/core/src/components/Popover/Popover.story.tsx +++ b/packages/@mantine/core/src/components/Popover/Popover.story.tsx @@ -28,7 +28,12 @@ export function Uncontrolled() { }} >
- console.log('closed')} onOpen={() => console.log('opened')}> + console.log('closed')} + onOpen={() => console.log('opened')} + onExitTransitionEnd={() => console.log('exited')} + onEnterTransitionEnd={() => console.log('entered')} + > diff --git a/packages/@mantine/core/src/components/Popover/Popover.tsx b/packages/@mantine/core/src/components/Popover/Popover.tsx index 855c3c83df..e4df18fafc 100644 --- a/packages/@mantine/core/src/components/Popover/Popover.tsx +++ b/packages/@mantine/core/src/components/Popover/Popover.tsx @@ -61,6 +61,12 @@ export interface __PopoverProps { /** Props passed down to the `Transition` component that used to animate dropdown presence, use to configure duration and animation type, `{ duration: 150, transition: 'fade' }` by default */ transitionProps?: TransitionOverride; + /** Called when exit transition ends */ + onExitTransitionEnd?: () => void; + + /** Called when enter transition ends */ + onEnterTransitionEnd?: () => void; + /** Dropdown width, or `'target'` to make dropdown width the same as target element, `'max-content'` by default */ width?: PopoverWidth; @@ -186,6 +192,8 @@ export function Popover(_props: PopoverProps) { positionDependencies, opened, transitionProps, + onExitTransitionEnd, + onEnterTransitionEnd, width, middlewares, withArrow, @@ -279,6 +287,16 @@ export function Popover(_props: PopoverProps) { [popover.floating.refs.setFloating] ); + const onExited = useCallback(() => { + transitionProps?.onExited?.(); + onExitTransitionEnd?.(); + }, [transitionProps?.onExited, onExitTransitionEnd]); + + const onEntered = useCallback(() => { + transitionProps?.onEntered?.(); + onEnterTransitionEnd?.(); + }, [transitionProps?.onEntered, onEnterTransitionEnd]); + return (