Skip to content

Commit

Permalink
[@mantine/core] Add onEnterTranstionEnd and onExitTransitionEnd p…
Browse files Browse the repository at this point in the history
…rops support to Modal, Drawer and Popover components
  • Loading branch information
rtivital committed Nov 24, 2024
1 parent 12ef5d8 commit c248131
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 3 deletions.
9 changes: 8 additions & 1 deletion packages/@mantine/core/src/components/Modal/Modal.story.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import { useDisclosure } from '@mantine/hooks';
import { Button } from '../Button';
import { Menu } from '../Menu';
Expand Down Expand Up @@ -31,7 +32,13 @@ export function Usage() {
<Button onClick={open}>Open modal</Button>
{content}
<Button onClick={open}>Open modal</Button>
<Modal opened={opened} onClose={close} title="Just a Modal" zIndex={73812}>
<Modal
opened={opened}
onClose={close}
title="Just a Modal"
transitionProps={{ duration: 500, onExited: () => console.log('onExited') }}
onExitTransitionEnd={() => console.log('onExitTransitionEnd')}
>
<input data-autofocus />
</Modal>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface ModalBaseContextValue {
getTitleId: () => string;
getBodyId: () => string;
transitionProps: Partial<TransitionOverride> | undefined;
onExitTransitionEnd: (() => void) | undefined;
onEnterTransitionEnd: (() => void) | undefined;
zIndex: string | number | undefined;

opened: boolean;
Expand Down
10 changes: 10 additions & 0 deletions packages/@mantine/core/src/components/ModalBase/ModalBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -84,6 +90,8 @@ export const ModalBase = forwardRef<HTMLDivElement, ModalBaseProps>(
onClose,
id,
transitionProps,
onExitTransitionEnd,
onEnterTransitionEnd,
trapFocus,
closeOnEscape,
returnFocus,
Expand Down Expand Up @@ -114,6 +122,8 @@ export const ModalBase = forwardRef<HTMLDivElement, ModalBaseProps>(
opened,
onClose,
closeOnClickOutside,
onExitTransitionEnd,
onEnterTransitionEnd,
transitionProps: { ...transitionProps, keepMounted },
getTitleId: () => `${_id}-title`,
getBodyId: () => `${_id}-body`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export const ModalBaseContent = forwardRef<HTMLDivElement, _ModalBaseContentProp
mounted={ctx.opened}
transition="pop"
{...ctx.transitionProps}
onExited={() => {
ctx.onExitTransitionEnd?.();
ctx.transitionProps?.onExited?.();
}}
onEntered={() => {
ctx.onEnterTransitionEnd?.();
ctx.transitionProps?.onEntered?.();
}}
{...transitionProps}
>
{(transitionStyles) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ export function Uncontrolled() {
}}
>
<div style={{ padding: 40 }}>
<Popover onClose={() => console.log('closed')} onOpen={() => console.log('opened')}>
<Popover
onClose={() => console.log('closed')}
onOpen={() => console.log('opened')}
onExitTransitionEnd={() => console.log('exited')}
onEnterTransitionEnd={() => console.log('entered')}
>
<Popover.Target>
<button type="button">Toggle popover</button>
</Popover.Target>
Expand Down
20 changes: 19 additions & 1 deletion packages/@mantine/core/src/components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -186,6 +192,8 @@ export function Popover(_props: PopoverProps) {
positionDependencies,
opened,
transitionProps,
onExitTransitionEnd,
onEnterTransitionEnd,
width,
middlewares,
withArrow,
Expand Down Expand Up @@ -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 (
<PopoverContextProvider
value={{
Expand All @@ -293,7 +311,7 @@ export function Popover(_props: PopoverProps) {
arrowY: popover.floating?.middlewareData?.arrow?.y,
opened: popover.opened,
arrowRef,
transitionProps,
transitionProps: { ...transitionProps, onExited, onEntered },
width,
withArrow,
arrowSize: arrowSize!,
Expand Down

0 comments on commit c248131

Please sign in to comment.