From 61d2696687e00e20757c7e228617ddf861310315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Wed, 29 May 2024 17:50:16 +0200 Subject: [PATCH] Update animation playground --- docs/pages/experiments/dialog.module.css | 12 ++++++---- .../src/Dialog/Backdrop/DialogBackdrop.tsx | 11 +++++++-- .../mui-base/src/Dialog/Popup/DialogPopup.tsx | 12 +++++++++- .../src/Dialog/Popup/DialogPopup.types.ts | 6 +++++ .../src/Dialog/Popup/useDialogPopup.tsx | 24 ++++++------------- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/docs/pages/experiments/dialog.module.css b/docs/pages/experiments/dialog.module.css index 1b31380e6..a9f470680 100644 --- a/docs/pages/experiments/dialog.module.css +++ b/docs/pages/experiments/dialog.module.css @@ -109,6 +109,8 @@ &.withAnimations { transform: translate(-50%, -35%) scale(0.8, 0.9) translateY(0); + visibility: hidden; + opacity: 0; &[data-state='open'] { animation: @@ -119,7 +121,7 @@ transition: transform var(--transition-duration) ease-out; } - &[data-state='closed'] { + &[data-exiting] { animation: dialog-closing var(--transition-duration) ease-in forwards; } } @@ -137,11 +139,11 @@ z-index: 0; position: fixed; inset: 0; + opacity: 0; + visibility: hidden; + backdrop-filter: blur(1px); &.withTransitions { - opacity: 0; - visibility: hidden; - backdrop-filter: blur(1px); transition: backdrop-filter 300ms ease-in, opacity 300ms ease-in, @@ -169,7 +171,7 @@ animation: backdrop-opening 500ms ease-out forwards; } - &[data-state='closed'] { + &[data-exiting] { animation: backdrop-closing 500ms ease-in forwards; } } diff --git a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx b/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx index 86a374d2f..31b1cdfa4 100644 --- a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx +++ b/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx @@ -31,8 +31,15 @@ const DialogBackdrop = React.forwardRef(function DialogBackdrop( extraProps: other, customStyleHookMapping: { open: (value) => ({ 'data-state': value ? 'open' : 'closed' }), - transitionStatus: (value) => - value !== undefined ? { 'data-transition-status': value } : null, + transitionStatus: (value) => { + if (value === 'entering') { + return { 'data-entering': '' }; + } + if (value === 'exiting') { + return { 'data-exiting': '' }; + } + return null; + }, }, }); diff --git a/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx b/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx index 8860002e3..c9dfeb90c 100644 --- a/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx +++ b/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx @@ -23,7 +23,7 @@ const DialogPopup = React.forwardRef(function DialogPopup( const rootContext = useDialogRootContext(); const { open, modal, nestedOpenDialogCount } = rootContext; - const { getRootProps, floatingContext, mounted } = useDialogPopup({ + const { getRootProps, floatingContext, mounted, transitionStatus } = useDialogPopup({ id: idProp, animated, ref: forwardedRef, @@ -35,6 +35,7 @@ const DialogPopup = React.forwardRef(function DialogPopup( open, modal, nestedOpenDialogCount, + transitionStatus, }; const { renderElement } = useComponentRenderer({ @@ -49,6 +50,15 @@ const DialogPopup = React.forwardRef(function DialogPopup( customStyleHookMapping: { open: (value) => ({ 'data-state': value ? 'open' : 'closed' }), nestedOpenDialogCount: (value) => ({ 'data-nested-dialogs': value.toString() }), + transitionStatus: (value) => { + if (value === 'entering') { + return { 'data-entering': '' }; + } + if (value === 'exiting') { + return { 'data-exiting': '' }; + } + return null; + }, }, }); diff --git a/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts b/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts index 73b45488e..ced1dc641 100644 --- a/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts +++ b/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts @@ -2,6 +2,7 @@ import * as React from 'react'; import { type FloatingContext } from '@floating-ui/react'; import { type BaseUIComponentProps } from '../../utils/BaseUI.types'; import { DialogType, SoftCloseOptions } from '../Root/DialogRoot.types'; +import { TransitionStatus } from '../../utils/useTransitionStatus'; export interface DialogPopupProps extends BaseUIComponentProps<'div', DialogPopupOwnerState> { /** @@ -27,6 +28,7 @@ export interface DialogPopupOwnerState { open: boolean; modal: boolean; nestedOpenDialogCount: number; + transitionStatus: TransitionStatus; } export interface UseDialogPopupParameters { @@ -96,4 +98,8 @@ export interface UseDialogPopupReturnValue { * Determines if the dialog should be mounted even if closed (as the exit animation is still in progress). */ mounted: boolean; + /** + * The current transition status of the dialog. + */ + transitionStatus: TransitionStatus; } diff --git a/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx b/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx index df05c2daf..02bc22297 100644 --- a/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx +++ b/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx @@ -4,8 +4,7 @@ import { UseDialogPopupParameters, UseDialogPopupReturnValue } from './DialogPop import { useId } from '../../utils/useId'; import { useForkRef } from '../../utils/useForkRef'; import { mergeReactProps } from '../../utils/mergeReactProps'; -import { useAnimationsFinished } from '../../utils/useAnimationsFinished'; -import { useTransitionStatus } from '../../utils/useTransitionStatus'; +import { useAnimatedElement } from '../../utils/useAnimatedElement'; /** * * Demos: @@ -49,20 +48,11 @@ export function useDialogPopup(parameters: UseDialogPopupParameters): UseDialogP const id = useId(idParam); const handleRef = useForkRef(ref, popupRef, refs.setFloating); - const { mounted, setMounted, transitionStatus } = useTransitionStatus(open, animated); - const runOnceAnimationsFinish = useAnimationsFinished(() => popupRef.current); - - React.useEffect(() => { - if (!open) { - if (animated) { - runOnceAnimationsFinish(() => { - setMounted(false); - }); - } else { - setMounted(false); - } - } - }, [animated, open, runOnceAnimationsFinish, setMounted]); + const { mounted, transitionStatus } = useAnimatedElement({ + open, + ref: popupRef, + enabled: animated, + }); React.useEffect(() => { setPopupElementId(id); @@ -82,12 +72,12 @@ export function useDialogPopup(parameters: UseDialogPopupParameters): UseDialogP ...getFloatingProps(), id, ref: handleRef, - 'data-transition-status': transitionStatus, }); return { floatingContext: context, getRootProps, mounted, + transitionStatus, }; }