From 155dcbba5d560678ee266ec5d132b556b4362ada Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Tue, 27 Jul 2021 13:58:23 -0700 Subject: [PATCH 1/5] Components: update snackbar to use framer motion instead of react spring --- package-lock.json | 2 +- packages/components/package.json | 2 +- packages/components/src/snackbar/list.js | 91 +++++++++++++++--------- 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87002bae72d99..67764a631dbf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14681,6 +14681,7 @@ "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "downshift": "^6.0.15", + "framer-motion": "^4.1.3", "gradient-parser": "^0.1.5", "highlight-words-core": "^1.2.2", "lodash": "^4.17.21", @@ -14689,7 +14690,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", diff --git a/packages/components/package.json b/packages/components/package.json index a5818b5908bb8..5646e4138b4a9 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -52,6 +52,7 @@ "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "downshift": "^6.0.15", + "framer-motion": "^4.1.3", "gradient-parser": "^0.1.5", "highlight-words-core": "^1.2.2", "lodash": "^4.17.21", @@ -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", diff --git a/packages/components/src/snackbar/list.js b/packages/components/src/snackbar/list.js index cc0c8dc7e0cd9..5e99f6d1a3e52 100644 --- a/packages/components/src/snackbar/list.js +++ b/packages/components/src/snackbar/list.js @@ -3,19 +3,51 @@ */ import classnames from 'classnames'; import { omit, noop } from 'lodash'; -import { useTransition, animated } from 'react-spring/web.cjs'; +import { motion, AnimatePresence } from 'framer-motion'; /** * WordPress dependencies */ import { useReducedMotion } from '@wordpress/compose'; -import { useState } from '@wordpress/element'; /** * Internal dependencies */ import Snackbar from './'; +const SNACKBAR_VARIANTS = { + init: { + height: 0, + opacity: 0, + }, + open: { + height: 'auto', + opacity: 1, + transition: { + height: { stiffness: 1000, velocity: -100 }, + }, + }, + exit: { + x: -300, + opacity: 0, + transition: { + x: { stiffness: 1000, velocity: -100 }, + }, + }, +}; + +const SNACKBAR_REDUCE_MOTION_VARIANTS = { + init: { + opacity: 0, + }, + open: { + opacity: 1, + }, + exit: { + opacity: 0, + }, +}; + /** * Renders a list of notices. * @@ -29,42 +61,37 @@ 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 (
{ children } - { transitions.map( ( { item: notice, key, props: style } ) => ( - -
ref && refMap.set( notice, ref ) } - > - + { notices.map( ( notice ) => { + return ( + - { notice.content } - -
-
- ) ) } +
+ + { notice.content } + +
+ + ); + } ) } +
); } From e4e5d7700693392d8a51885e227a17c94b4b690e Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Wed, 28 Jul 2021 11:33:03 -0700 Subject: [PATCH 2/5] Snackbar: fully turn off animations with useReduceMotion --- packages/components/src/snackbar/list.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/components/src/snackbar/list.js b/packages/components/src/snackbar/list.js index 5e99f6d1a3e52..a9c1bb4fbb627 100644 --- a/packages/components/src/snackbar/list.js +++ b/packages/components/src/snackbar/list.js @@ -28,24 +28,17 @@ const SNACKBAR_VARIANTS = { }, }, exit: { - x: -300, opacity: 0, transition: { - x: { stiffness: 1000, velocity: -100 }, + duration: 0.5, }, }, }; const SNACKBAR_REDUCE_MOTION_VARIANTS = { - init: { - opacity: 0, - }, - open: { - opacity: 1, - }, - exit: { - opacity: 0, - }, + init: false, + open: false, + exit: false, }; /** @@ -70,6 +63,7 @@ function SnackbarList( { notices, className, children, onRemove = noop } ) { { notices.map( ( notice ) => { return ( Date: Wed, 4 Aug 2021 09:35:05 -0700 Subject: [PATCH 3/5] Export motion from wordpress/components as __unstable --- package-lock.json | 3 +-- packages/components/package.json | 2 +- packages/components/src/animation/index.js | 13 +++++++++++++ packages/components/src/index.js | 5 +++++ packages/components/src/snackbar/list.js | 5 ++++- packages/edit-post/package.json | 1 - .../edit-post/src/components/visual-editor/index.js | 3 +-- 7 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 packages/components/src/animation/index.js diff --git a/package-lock.json b/package-lock.json index 67764a631dbf7..26cb192adf729 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14681,7 +14681,7 @@ "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "downshift": "^6.0.15", - "framer-motion": "^4.1.3", + "framer-motion": "^4.1.17", "gradient-parser": "^0.1.5", "highlight-words-core": "^1.2.2", "lodash": "^4.17.21", @@ -14956,7 +14956,6 @@ "@wordpress/viewport": "file:packages/viewport", "@wordpress/warning": "file:packages/warning", "classnames": "^2.3.1", - "framer-motion": "^4.1.3", "lodash": "^4.17.21", "memize": "^1.1.0", "rememo": "^3.0.0", diff --git a/packages/components/package.json b/packages/components/package.json index 5646e4138b4a9..c131e5b6ea52a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -52,7 +52,7 @@ "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "downshift": "^6.0.15", - "framer-motion": "^4.1.3", + "framer-motion": "^4.1.17", "gradient-parser": "^0.1.5", "highlight-words-core": "^1.2.2", "lodash": "^4.17.21", diff --git a/packages/components/src/animation/index.js b/packages/components/src/animation/index.js new file mode 100644 index 0000000000000..44132b237de0b --- /dev/null +++ b/packages/components/src/animation/index.js @@ -0,0 +1,13 @@ +/** + * 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/ + */ + +export { + motion as __unstableMotion, + AnimatePresence as __unstableAnimatePresence, + AnimateSharedLayout as __unstableAnimateSharedLayout, +} from 'framer-motion'; diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 639b4fa704af4..877e399a6e567 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -16,6 +16,11 @@ export { default as Animate, getAnimateClassName as __unstableGetAnimateClassName, } from './animate'; +export { + __unstableMotion, + __unstableAnimatePresence, + __unstableAnimateSharedLayout, +} from './animation'; export { default as AnglePickerControl } from './angle-picker-control'; export { default as Autocomplete, diff --git a/packages/components/src/snackbar/list.js b/packages/components/src/snackbar/list.js index a9c1bb4fbb627..d3e24571d420a 100644 --- a/packages/components/src/snackbar/list.js +++ b/packages/components/src/snackbar/list.js @@ -3,7 +3,6 @@ */ import classnames from 'classnames'; import { omit, noop } from 'lodash'; -import { motion, AnimatePresence } from 'framer-motion'; /** * WordPress dependencies @@ -14,6 +13,10 @@ import { useReducedMotion } from '@wordpress/compose'; * Internal dependencies */ import Snackbar from './'; +import { + __unstableMotion as motion, + __unstableAnimatePresence as AnimatePresence, +} from '../animation'; const SNACKBAR_VARIANTS = { init: { diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 197b568d20102..b5fe7f1c5e301 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -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", diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index eced55ecdc0a8..a845de6d7a340 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { motion } from 'framer-motion'; /** * WordPress dependencies @@ -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'; From 0a5f4c08382b9e64a82c3013d6c54b365adf8629 Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Wed, 4 Aug 2021 09:45:07 -0700 Subject: [PATCH 4/5] Add eslint rule when importing from framer motion directly --- .eslintrc.js | 5 +++++ packages/components/src/animation/index.js | 1 + 2 files changed, 6 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 2563edaafd004..a9ce5392e2f2e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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' ], diff --git a/packages/components/src/animation/index.js b/packages/components/src/animation/index.js index 44132b237de0b..1c6d14e00f2cd 100644 --- a/packages/components/src/animation/index.js +++ b/packages/components/src/animation/index.js @@ -6,6 +6,7 @@ * @see https://www.framer.com/docs/animation/ */ +// eslint-disable-next-line no-restricted-imports export { motion as __unstableMotion, AnimatePresence as __unstableAnimatePresence, From 63520aa5dc45f9b774aad47ece74f318d6ac5c35 Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Thu, 5 Aug 2021 08:33:35 -0700 Subject: [PATCH 5/5] Avoid exposing AnimatePresence and AnimateSharedLayout for now --- packages/components/src/index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 877e399a6e567..59550b082e7d6 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -16,11 +16,7 @@ export { default as Animate, getAnimateClassName as __unstableGetAnimateClassName, } from './animate'; -export { - __unstableMotion, - __unstableAnimatePresence, - __unstableAnimateSharedLayout, -} from './animation'; +export { __unstableMotion } from './animation'; export { default as AnglePickerControl } from './angle-picker-control'; export { default as Autocomplete,