Skip to content

Commit

Permalink
Components: update snackbar to use framer motion instead of react spr…
Browse files Browse the repository at this point in the history
…ing (#33717)

* Export framer motion from wordpress/components as __unstable
  • Loading branch information
gwwar authored Aug 5, 2021
1 parent 9e2fc57 commit 27942d7
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ module.exports = {
'error',
{
paths: [
{
name: 'framer-motion',
message:
'Please use the Framer Motion API through `@wordpress/components` instead.',
},
{
name: 'lodash',
importNames: [ 'memoize' ],
Expand Down
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"classnames": "^2.3.1",
"dom-scroll-into-view": "^1.2.1",
"downshift": "^6.0.15",
"framer-motion": "^4.1.17",
"gradient-parser": "^0.1.5",
"highlight-words-core": "^1.2.2",
"lodash": "^4.17.21",
Expand All @@ -60,7 +61,6 @@
"re-resizable": "^6.4.0",
"react-dates": "^17.1.1",
"react-resize-aware": "^3.1.0",
"react-spring": "^8.0.20",
"react-use-gesture": "^9.0.0",
"reakit": "^1.3.8",
"rememo": "^3.0.0",
Expand Down
14 changes: 14 additions & 0 deletions packages/components/src/animation/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Framer Motion is used to create animated, interactive interfaces. The package is roughly ~30kb so
* this should ideally be loaded once across all Gutenberg packages. To give ourselves more flexibility
* in trying animation options, we avoid making this public API.
*
* @see https://www.framer.com/docs/animation/
*/

// eslint-disable-next-line no-restricted-imports
export {
motion as __unstableMotion,
AnimatePresence as __unstableAnimatePresence,
AnimateSharedLayout as __unstableAnimateSharedLayout,
} from 'framer-motion';
1 change: 1 addition & 0 deletions packages/components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {
default as Animate,
getAnimateClassName as __unstableGetAnimateClassName,
} from './animate';
export { __unstableMotion } from './animation';
export { default as AnglePickerControl } from './angle-picker-control';
export {
default as Autocomplete,
Expand Down
88 changes: 56 additions & 32 deletions packages/components/src/snackbar/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,46 @@
*/
import classnames from 'classnames';
import { omit, noop } from 'lodash';
import { useTransition, animated } from 'react-spring/web.cjs';

/**
* WordPress dependencies
*/
import { useReducedMotion } from '@wordpress/compose';
import { useState } from '@wordpress/element';

/**
* Internal dependencies
*/
import Snackbar from './';
import {
__unstableMotion as motion,
__unstableAnimatePresence as AnimatePresence,
} from '../animation';

const SNACKBAR_VARIANTS = {
init: {
height: 0,
opacity: 0,
},
open: {
height: 'auto',
opacity: 1,
transition: {
height: { stiffness: 1000, velocity: -100 },
},
},
exit: {
opacity: 0,
transition: {
duration: 0.5,
},
},
};

const SNACKBAR_REDUCE_MOTION_VARIANTS = {
init: false,
open: false,
exit: false,
};

/**
* Renders a list of notices.
Expand All @@ -29,42 +57,38 @@ import Snackbar from './';
*/
function SnackbarList( { notices, className, children, onRemove = noop } ) {
const isReducedMotion = useReducedMotion();
const [ refMap ] = useState( () => new WeakMap() );
const transitions = useTransition( notices, ( notice ) => notice.id, {
from: { opacity: 0, height: 0 },
enter: ( item ) => async ( next ) =>
await next( {
opacity: 1,
height: refMap.get( item ).offsetHeight,
} ),
leave: () => async ( next ) => {
await next( { opacity: 0 } );
await next( { height: 0 } );
},
immediate: isReducedMotion,
} );

className = classnames( 'components-snackbar-list', className );
const removeNotice = ( notice ) => () => onRemove( notice.id );

return (
<div className={ className }>
{ children }
{ transitions.map( ( { item: notice, key, props: style } ) => (
<animated.div key={ key } style={ style }>
<div
className="components-snackbar-list__notice-container"
ref={ ( ref ) => ref && refMap.set( notice, ref ) }
>
<Snackbar
{ ...omit( notice, [ 'content' ] ) }
onRemove={ removeNotice( notice ) }
<AnimatePresence>
{ notices.map( ( notice ) => {
return (
<motion.div
layout={ ! isReducedMotion } //see https://www.framer.com/docs/animation/#layout-animations
initial={ 'init' }
animate={ 'open' }
exit={ 'exit' }
key={ notice.id }
variants={
isReducedMotion
? SNACKBAR_REDUCE_MOTION_VARIANTS
: SNACKBAR_VARIANTS
}
>
{ notice.content }
</Snackbar>
</div>
</animated.div>
) ) }
<div className="components-snackbar-list__notice-container">
<Snackbar
{ ...omit( notice, [ 'content' ] ) }
onRemove={ removeNotice( notice ) }
>
{ notice.content }
</Snackbar>
</div>
</motion.div>
);
} ) }
</AnimatePresence>
</div>
);
}
Expand Down
1 change: 0 additions & 1 deletion packages/edit-post/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
"@wordpress/viewport": "file:../viewport",
"@wordpress/warning": "file:../warning",
"classnames": "^2.3.1",
"framer-motion": "^4.1.3",
"lodash": "^4.17.21",
"memize": "^1.1.0",
"rememo": "^3.0.0",
Expand Down
3 changes: 1 addition & 2 deletions packages/edit-post/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import classnames from 'classnames';
import { motion } from 'framer-motion';

/**
* WordPress dependencies
Expand Down Expand Up @@ -32,7 +31,7 @@ import {
__experimentalUseNoRecursiveRenders as useNoRecursiveRenders,
} from '@wordpress/block-editor';
import { useRef, useMemo } from '@wordpress/element';
import { Button } from '@wordpress/components';
import { Button, __unstableMotion as motion } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { useMergeRefs } from '@wordpress/compose';
import { arrowLeft } from '@wordpress/icons';
Expand Down

0 comments on commit 27942d7

Please sign in to comment.