From 83a8db34732da54d019f43897232ceecd6b84e01 Mon Sep 17 00:00:00 2001 From: Andrew Musgrave Date: Wed, 14 Aug 2019 13:55:09 -0400 Subject: [PATCH] Removed RTG from ContextualSaveBar and replaced it with a custom CSSAnimation component --- src/components/Frame/Frame.scss | 18 ---- src/components/Frame/Frame.tsx | 41 +++------ .../components/CSSAnimation/CSSAnimation.scss | 11 +++ .../components/CSSAnimation/CSSAnimation.tsx | 88 +++++++++++++++++++ .../Frame/components/CSSAnimation/index.ts | 1 + src/components/Frame/components/index.ts | 1 + 6 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 src/components/Frame/components/CSSAnimation/CSSAnimation.scss create mode 100644 src/components/Frame/components/CSSAnimation/CSSAnimation.tsx create mode 100644 src/components/Frame/components/CSSAnimation/index.ts diff --git a/src/components/Frame/Frame.scss b/src/components/Frame/Frame.scss index 090334b8..ec18f1b1 100644 --- a/src/components/Frame/Frame.scss +++ b/src/components/Frame/Frame.scss @@ -114,24 +114,6 @@ $skip-vertical-offset: rem(10px); width: 100%; } -.ContextualSaveBar-enter { - opacity: 0; -} - -.ContextualSaveBar-enterActive { - opacity: 1; - transition: opacity duration() easing(out); -} - -.ContextualSaveBar-exit { - opacity: 1; -} - -.ContextualSaveBar-exitActive { - opacity: 0; - transition: opacity duration() easing(out); -} - .Main { flex: 1; display: flex; diff --git a/src/components/Frame/Frame.tsx b/src/components/Frame/Frame.tsx index b7c1de96..ca7e4add 100644 --- a/src/components/Frame/Frame.tsx +++ b/src/components/Frame/Frame.tsx @@ -20,7 +20,13 @@ import { ToastID, ToastPropsWithID, } from '../../utilities/frame'; -import {ToastManager, Loading, ContextualSaveBar} from './components'; +import { + ToastManager, + Loading, + ContextualSaveBar, + CSSAnimation, + AnimationType, +} from './components'; import styles from './Frame.scss'; @@ -72,7 +78,6 @@ class Frame extends React.PureComponent { private contextualSaveBar: ContextualSaveBarProps | null; private globalRibbonContainer: HTMLDivElement | null = null; private navigationNode = createRef(); - private contextualSaveBarNode = createRef(); private skipToMainContentTargetNode = React.createRef(); componentDidMount() { @@ -161,23 +166,13 @@ class Frame extends React.PureComponent { ) : null; const contextualSaveBarMarkup = ( - -
- -
-
+ + ); const topBarMarkup = topBar ? ( @@ -402,10 +397,6 @@ class Frame extends React.PureComponent { private findNavigationNode = () => { return this.navigationNode.current; }; - - private findContextualSaveBarNode = () => { - return this.contextualSaveBarNode.current; - }; } const navTransitionClasses = { @@ -416,14 +407,6 @@ const navTransitionClasses = { exitActive: classNames(styles['Navigation-exitActive']), }; -const contextualSaveBarTransitionClasses = { - enter: classNames(styles['ContextualSaveBar-enter']), - enterActive: classNames(styles['ContextualSaveBar-enterActive']), - enterDone: classNames(styles['ContextualSaveBar-enterActive']), - exit: classNames(styles['ContextualSaveBar-exit']), - exitActive: classNames(styles['ContextualSaveBar-exitActive']), -}; - function isMobileView() { return navigationBarCollapsed().matches; } diff --git a/src/components/Frame/components/CSSAnimation/CSSAnimation.scss b/src/components/Frame/components/CSSAnimation/CSSAnimation.scss new file mode 100644 index 00000000..1648f34f --- /dev/null +++ b/src/components/Frame/components/CSSAnimation/CSSAnimation.scss @@ -0,0 +1,11 @@ +@import '../../../../styles/common'; + +.startFade { + opacity: 0; + will-change: opacity; + transition: opacity duration(slow) easing(out); +} + +.endFade { + opacity: 1; +} diff --git a/src/components/Frame/components/CSSAnimation/CSSAnimation.tsx b/src/components/Frame/components/CSSAnimation/CSSAnimation.tsx new file mode 100644 index 00000000..e1e4c436 --- /dev/null +++ b/src/components/Frame/components/CSSAnimation/CSSAnimation.tsx @@ -0,0 +1,88 @@ +import React, {useRef, useState, useEffect} from 'react'; +import {classNames, variationName} from '../../../../utilities/css'; + +import styles from './CSSAnimation.scss'; + +export enum AnimationType { + Fade = 'fade', +} + +export interface Props { + in: boolean; + className: string; + type: AnimationType; + children?: React.ReactNode; +} + +enum TransitionStatus { + Entering = 'entering', + Entered = 'entered', + Exiting = 'exiting', + Exited = 'exited', +} + +export default function Collapsible({ + in: inProp, + className, + type, + children, +}: Props) { + const [transitionStatus, setTransitionStatus] = useState( + inProp ? TransitionStatus.Entering : TransitionStatus.Exited, + ); + const isMounted = useRef(false); + const node = useRef(null); + + useEffect( + () => { + if (!isMounted.current) return; + transitionStatus === TransitionStatus.Entering && + changeTransitionStatus(TransitionStatus.Entered); + }, + [transitionStatus], + ); + + useEffect( + () => { + if (!isMounted.current) return; + inProp && changeTransitionStatus(TransitionStatus.Entering); + !inProp && changeTransitionStatus(TransitionStatus.Exiting); + }, + [inProp], + ); + + useEffect(() => { + isMounted.current = true; + }, []); + + const wrapperClassName = classNames( + className, + styles[variationName('start', type)], + inProp && styles[variationName('end', type)], + ); + + const content = + transitionStatus === TransitionStatus.Exited && !inProp ? null : children; + + return ( +
+ {content} +
+ ); + + function handleTransitionEnd() { + transitionStatus === TransitionStatus.Exiting && + changeTransitionStatus(TransitionStatus.Exited); + } + + function changeTransitionStatus(transitionStatus: TransitionStatus) { + setTransitionStatus(transitionStatus); + // Forcing a reflow to enable the animation + if (transitionStatus === TransitionStatus.Entering) + node.current && node.current.getBoundingClientRect(); + } +} diff --git a/src/components/Frame/components/CSSAnimation/index.ts b/src/components/Frame/components/CSSAnimation/index.ts new file mode 100644 index 00000000..942b2b02 --- /dev/null +++ b/src/components/Frame/components/CSSAnimation/index.ts @@ -0,0 +1 @@ +export {default, AnimationType} from './CSSAnimation'; diff --git a/src/components/Frame/components/index.ts b/src/components/Frame/components/index.ts index e883cd4e..6b364c71 100644 --- a/src/components/Frame/components/index.ts +++ b/src/components/Frame/components/index.ts @@ -9,3 +9,4 @@ export { } from './ToastManager'; export {default as Loading, Props as LoadingProps} from './Loading'; export {default as ContextualSaveBar} from './ContextualSaveBar'; +export {default as CSSAnimation, AnimationType} from './CSSAnimation';