diff --git a/packages/components/src/drop-zone/index.tsx b/packages/components/src/drop-zone/index.tsx index 0219eb4f17f3f..abd158f7ce63d 100644 --- a/packages/components/src/drop-zone/index.tsx +++ b/packages/components/src/drop-zone/index.tsx @@ -12,7 +12,7 @@ import { upload, Icon } from '@wordpress/icons'; import { getFilesFromDataTransfer } from '@wordpress/dom'; import { __experimentalUseDropZone as useDropZone, - //useReducedMotion, + useReducedMotion, } from '@wordpress/compose'; /** @@ -22,41 +22,41 @@ import type { DropType, DropZoneProps } from './types'; import type { WordPressComponentProps } from '../context'; import type { ReactNode } from 'react'; -interface FadeProps { +/** + * Handles fade-in/fade-out animation for its children if `reducedMotion` is disabled. + * Relies on the animations being defined in the CSS styles. + * + * @returns {JSX.Element | null} The animated container with children or null. + */ +const MaybeFade: React.FC< { show: boolean; children: ReactNode; duration?: number; -} - -// Could call it Animate? Also, probably need to move out so it can be used -// across other components. The idea is to "hook" into the mount/unmount -// lifecycle to animate the component. -const Fade: React.FC< FadeProps > = ( { show, children, duration } ) => { +} > = ( { show, children, duration = 200 } ) => { const [ shouldRender, setRender ] = useState( show ); + const reducedMotion = useReducedMotion(); useEffect( () => { if ( show ) { setRender( true ); - } - }, [ show ] ); - - const onAnimationEnd = () => { - if ( ! show ) { + } else if ( reducedMotion ) { setRender( false ); } - }; + }, [ show, reducedMotion ] ); - return ( - shouldRender && ( -
- { children } -
- ) - ); + const props = ! reducedMotion + ? { + className: show ? 'fade-enter' : 'fade-exit', + style: { animationDuration: `${ duration }ms` }, + onAnimationEnd: () => { + if ( ! show ) { + setRender( false ); + } + }, + } + : {}; + + return shouldRender &&
{ children }
; }; function DropIndicator( { @@ -66,13 +66,10 @@ function DropIndicator( { label?: string; isActive: boolean; } ) { - const disableMotion = false; return ( - +
@@ -85,7 +82,7 @@ function DropIndicator( {
-
+ ); } diff --git a/packages/components/src/drop-zone/style.scss b/packages/components/src/drop-zone/style.scss index 55434b6048a6b..b7635f2df193b 100644 --- a/packages/components/src/drop-zone/style.scss +++ b/packages/components/src/drop-zone/style.scss @@ -63,6 +63,11 @@ animation: scaleOut 0.2s forwards; } +.no-motion, +.no-motion .components-drop-zone__content-inner { + animation: none !important; +} + .components-drop-zone { position: absolute; top: 0;