From 68d5b60dc0f3fcf5cd5a23fece9bce8994e3b747 Mon Sep 17 00:00:00 2001 From: Michael Dougall Date: Thu, 6 Jun 2019 12:45:48 +1000 Subject: [PATCH] feat(move): adds new prop to set stacking context on move motion --- .../src/__docs__/2-getting-started/docs.mdx | 4 ++-- packages/core/src/lib/dom.tsx | 10 ++++++++ packages/core/src/motions/FadeMove/index.tsx | 23 ++----------------- .../core/src/motions/Move/__docs__/docs.mdx | 7 ++++++ packages/core/src/motions/Move/index.tsx | 19 +++++++++++++-- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/packages/core/src/__docs__/2-getting-started/docs.mdx b/packages/core/src/__docs__/2-getting-started/docs.mdx index 8a92e98..03fe6f4 100644 --- a/packages/core/src/__docs__/2-getting-started/docs.mdx +++ b/packages/core/src/__docs__/2-getting-started/docs.mdx @@ -319,7 +319,7 @@ and `false` when you consider it to be hidden. - + {({ ref, style }) => ( - + {({ ref, style }) => } diff --git a/packages/core/src/lib/dom.tsx b/packages/core/src/lib/dom.tsx index 1dbdc0c..96bead5 100644 --- a/packages/core/src/lib/dom.tsx +++ b/packages/core/src/lib/dom.tsx @@ -1,3 +1,13 @@ +export function eventListener( + element: HTMLElement, + event: K, + cb: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, + options?: boolean | AddEventListenerOptions | undefined +) { + element.addEventListener(event, cb, options); + return () => element.removeEventListener(event, cb, options); +} + export function getDocumentScroll() { const scrollTop = document.documentElement && document.documentElement.scrollTop diff --git a/packages/core/src/motions/FadeMove/index.tsx b/packages/core/src/motions/FadeMove/index.tsx index f3cc8d9..cc71dcf 100644 --- a/packages/core/src/motions/FadeMove/index.tsx +++ b/packages/core/src/motions/FadeMove/index.tsx @@ -73,7 +73,7 @@ export default class FadeMove extends React.Component { transformOrigin: '0 0', transform: 'translate3d(0, 0, 0) scale3d(1, 1, 1)', opacity: 1, - // Elminate any margins so they don't affect the transition. + // Eliminate any margins so they don't affect the transition. margin: 0, height: `${originTarget.size.height}px`, width: `${originTarget.size.width}px`, @@ -87,14 +87,7 @@ export default class FadeMove extends React.Component { }); }; - beforeAnimate: MotionCallback = (data, onFinish, setChildProps) => { - setChildProps({ - style: prevStyle => ({ - ...prevStyle, - opacity: 0, - }), - }); - + beforeAnimate: MotionCallback = (data, onFinish) => { onFinish(); return this.renderMotion(data); @@ -105,17 +98,6 @@ export default class FadeMove extends React.Component { return this.renderMotion(data, { moveToTarget: true }); }; - afterAnimate: MotionCallback = (_, onFinish, setChildProps) => { - setChildProps({ - style: prevStyle => ({ - ...prevStyle, - opacity: 1, - }), - }); - - onFinish(); - }; - render() { const { children } = this.props; @@ -126,7 +108,6 @@ export default class FadeMove extends React.Component { payload: { beforeAnimate: this.beforeAnimate, animate: this.animate, - afterAnimate: this.afterAnimate, }, }} > diff --git a/packages/core/src/motions/Move/__docs__/docs.mdx b/packages/core/src/motions/Move/__docs__/docs.mdx index 1ad4f7e..019c2fe 100644 --- a/packages/core/src/motions/Move/__docs__/docs.mdx +++ b/packages/core/src/motions/Move/__docs__/docs.mdx @@ -47,3 +47,10 @@ import { Move } from '@element-motion/core'; ## Props + +## Gotchas + +Noticing that your in transit element isn't being stacked correctly? +You'll want to create a [stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context) by opting into `createStackingContext` which will set `position: relative` to the inflight element. + +This should fix your stacking problems. diff --git a/packages/core/src/motions/Move/index.tsx b/packages/core/src/motions/Move/index.tsx index 2f168bf..639fe8f 100644 --- a/packages/core/src/motions/Move/index.tsx +++ b/packages/core/src/motions/Move/index.tsx @@ -57,6 +57,13 @@ export interface MoveProps extends CollectorChildrenProps { * Defaults to true. */ scaleY?: boolean; + + /** + * Will set "position: relative" on the element during a transition. + * Useful for creating a stacking context to position the element where you want in the stack. + * Use "zIndex" prop to set the appropriate position in the stack. + */ + createStackingContext?: boolean; } export default class Move extends React.Component { @@ -74,7 +81,15 @@ export default class Move extends React.Component { abort = noop; beforeAnimate: MotionCallback = (data, onFinish, setChildProps) => { - const { zIndex, useFocalTarget, transformX, transformY, scaleX, scaleY } = this.props; + const { + zIndex, + useFocalTarget, + transformX, + transformY, + scaleX, + scaleY, + createStackingContext, + } = this.props; if (process.env.NODE_ENV === 'development') { throwIf( @@ -102,7 +117,7 @@ export default class Move extends React.Component { style: prevStyles => ({ ...prevStyles, zIndex, - opacity: 1, + position: createStackingContext ? 'relative' : undefined, transformOrigin: '0 0', visibility: 'visible', willChange: combine('transform')(prevStyles.willChange),