Skip to content

Commit

Permalink
Components: Remove Framer Motion from DropZone (#62044)
Browse files Browse the repository at this point in the history
* Start implementingthe fadein/fadeout animation in pure CSS

* First working iteration

* Implement scale animation in the inner element

* Remove unneeded CSS

* Make it closer to the original Framer Motion animation

* Refactor to support reducedMotion

* Simplify by moving the Fade component one level up

* Cleanup styles

* Fix formatting issue

* Fix import category

* Extract `MaybeFade` to its own component for easier further extractions later if used across components

* Manually namespace CSS animation keyframe identifiers and classnames

* Remove debug code

* Cleanup

* Simplify by using CSS transition instead of keyframe and remove the `MaybeFade` animation orchestrator

* American english spelling

* Switch to `has-dragged-out` instead of `inactive` class, less CSS

* Add back legacy classnames

* Remove "reduce" from prefers reduced motion

* Add back safari pointer events fix

* Add back root styles

* Restore active class styles

* move back 'is-active- check inline

* CHANGELOG

---------

Co-authored-by: Marco Ciampini <marco.ciampo@gmail.com>
  • Loading branch information
fullofcaffeine and ciampo committed Jun 19, 2024
1 parent 17ecaa6 commit 9da6486
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 94 deletions.
8 changes: 6 additions & 2 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

## Unreleased

### Enhancements

- DropZone: rewrite animation without depending on framer-motion. ([#62044](https://github.com/WordPress/gutenberg/pull/62044))

## 28.1.0 (2024-06-15)

### Enhancements

- Add `text-wrap: balance` fallback to all instances of `text-wrap: pretty` for greater cross browser compatibility. ([#62233](https://github.com/WordPress/gutenberg/pull/62233))
- Updates the space between input + label to `8px` in CheckboxControl and RadioControl. Also increased the space between RadioControl components to `12px` to make it consistent with CheckboxControl. ([#61696](https://github.com/WordPress/gutenberg/pull/61696))
- Add `text-wrap: balance` fallback to all instances of `text-wrap: pretty` for greater cross browser compatibility. ([#62233](https://github.com/WordPress/gutenberg/pull/62233))
- Updates the space between input + label to `8px` in CheckboxControl and RadioControl. Also increased the space between RadioControl components to `12px` to make it consistent with CheckboxControl. ([#61696](https://github.com/WordPress/gutenberg/pull/61696))

### Bug Fixes

Expand Down
93 changes: 17 additions & 76 deletions packages/components/src/drop-zone/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,86 +10,14 @@ import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { upload, Icon } from '@wordpress/icons';
import { getFilesFromDataTransfer } from '@wordpress/dom';
import {
__experimentalUseDropZone as useDropZone,
useReducedMotion,
} from '@wordpress/compose';
import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose';

/**
* Internal dependencies
*/
import {
__unstableMotion as motion,
__unstableAnimatePresence as AnimatePresence,
} from '../animation';
import type { DropType, DropZoneProps } from './types';
import type { WordPressComponentProps } from '../context';

const backdrop = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
type: 'tween',
duration: 0.2,
delay: 0,
delayChildren: 0.1,
},
},
exit: {
opacity: 0,
transition: {
duration: 0.2,
delayChildren: 0,
},
},
};

const foreground = {
hidden: { opacity: 0, scale: 0.9 },
show: {
opacity: 1,
scale: 1,
transition: {
duration: 0.1,
},
},
exit: { opacity: 0, scale: 0.9 },
};

function DropIndicator( { label }: { label?: string } ) {
const disableMotion = useReducedMotion();
const children = (
<motion.div
variants={ backdrop }
initial={ disableMotion ? 'show' : 'hidden' }
animate="show"
exit={ disableMotion ? 'show' : 'exit' }
className="components-drop-zone__content"
// Without this, when this div is shown,
// Safari calls a onDropZoneLeave causing a loop because of this bug
// https://bugs.webkit.org/show_bug.cgi?id=66547
style={ { pointerEvents: 'none' } }
>
<motion.div variants={ foreground }>
<Icon
icon={ upload }
className="components-drop-zone__content-icon"
/>
<span className="components-drop-zone__content-text">
{ label ? label : __( 'Drop files to upload' ) }
</span>
</motion.div>
</motion.div>
);

if ( disableMotion ) {
return children;
}

return <AnimatePresence>{ children }</AnimatePresence>;
}

/**
* `DropZone` is a component creating a drop zone area taking the full size of its parent element. It supports dropping files, HTML content or any other HTML drop event.
*
Expand Down Expand Up @@ -135,7 +63,7 @@ export function DropZoneComponent( {

/**
* From Windows Chrome 96, the `event.dataTransfer` returns both file object and HTML.
* The order of the checks is important to recognise the HTML drop.
* The order of the checks is important to recognize the HTML drop.
*/
if ( html && onHTMLDrop ) {
onHTMLDrop( html );
Expand All @@ -152,7 +80,7 @@ export function DropZoneComponent( {

/**
* From Windows Chrome 96, the `event.dataTransfer` returns both file object and HTML.
* The order of the checks is important to recognise the HTML drop.
* The order of the checks is important to recognize the HTML drop.
*/
if ( event.dataTransfer?.types.includes( 'text/html' ) ) {
_type = 'html';
Expand Down Expand Up @@ -181,20 +109,33 @@ export function DropZoneComponent( {
setIsDraggingOverElement( false );
},
} );

const classes = clsx( 'components-drop-zone', className, {
'is-active':
( isDraggingOverDocument || isDraggingOverElement ) &&
( ( type === 'file' && onFilesDrop ) ||
( type === 'html' && onHTMLDrop ) ||
( type === 'default' && onDrop ) ),
'has-dragged-out': ! isDraggingOverElement,
// Keeping the following classnames for legacy purposes
'is-dragging-over-document': isDraggingOverDocument,
'is-dragging-over-element': isDraggingOverElement,
[ `is-dragging-${ type }` ]: !! type,
} );

return (
<div { ...restProps } ref={ ref } className={ classes }>
{ isDraggingOverElement && <DropIndicator label={ label } /> }
<div className="components-drop-zone__content">
<div className="components-drop-zone__content-inner">
<Icon
icon={ upload }
className="components-drop-zone__content-icon"
/>
<span className="components-drop-zone__content-text">
{ label ? label : __( 'Drop files to upload' ) }
</span>
</div>
</div>
</div>
);
}
Expand Down
67 changes: 51 additions & 16 deletions packages/components/src/drop-zone/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,58 @@
opacity: 1;
visibility: visible;
}
}

.components-drop-zone__content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
display: flex;
background-color: $components-color-accent;
align-items: center;
justify-content: center;
z-index: z-index(".components-drop-zone__content");
text-align: center;
color: $white;
.components-drop-zone__content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
display: flex;
background-color: $components-color-accent;
align-items: center;
justify-content: center;
z-index: z-index(".components-drop-zone__content");
text-align: center;
color: $white;
opacity: 0;

// Without this, when this div is shown,
// Safari calls a onDropZoneLeave causing a loop because of this bug
// https://bugs.webkit.org/show_bug.cgi?id=66547
pointer-events: none;
}

.components-drop-zone__content-inner {
opacity: 0;
transform: scale(0.9);
}

&.is-active:not(.has-dragged-out) {
.components-drop-zone__content {
opacity: 1;

transition: opacity 0.2s ease-in-out;
@media (prefers-reduced-motion) {
transition: none;
}
}

.components-drop-zone__content-inner {
opacity: 1;
transform: scale(1);

transition:
opacity 0.1s ease-in-out 0.1s,
transform 0.1s ease-in-out 0.1s;

@media (prefers-reduced-motion) {
transition: none;
}
}
}
}

.components-drop-zone__content-icon,
Expand Down

0 comments on commit 9da6486

Please sign in to comment.