transition.tsx
import React from 'react'
import { CSSTransition } from 'react-transition-group'
import { CSSTransitionProps } from 'react-transition-group/CSSTransition'
type AnimationName = 'zoom-in-top' | 'zoom-in-left' | 'zoom-in-bottom' | 'zoom-in-right'
type TransitionProps = CSSTransitionProps & {
animation?: AnimationName,
wrapper? : boolean,
}
const Transition: React.FC<TransitionProps> = (props) => {
const {
children,
classNames,
animation,
wrapper,
...restProps
} = props
return (
<CSSTransition
classNames = { classNames ? classNames : animation}
{...restProps}
>
{wrapper ? <div>{children}</div> : children}
</CSSTransition>
)
}
Transition.defaultProps = {
unmountOnExit: true,
appear: true,
}
export default Transition
animation.scss
@include zoom-animation('top', scaleY(0), scaleY(1), center top);
@include zoom-animation('left', scale(.45, .45), scale(1, 1), top left);
@include zoom-animation('right', scale(.45, .45), scale(1, 1), top right);
@include zoom-animation('bottom', scaleY(0), scaleY(1), center bottom);
_mixin.scss
@mixin zoom-animation(
$direction: 'top',
$scaleStart: scaleY(0),
$scaleEnd: scaleY(1),
$origin: center top,
) {
.zoom-in-
opacity: 0;
transform: $scaleStart;
}
.zoom-in-
opacity: 1;
transform: $scaleEnd;
transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
transform-origin: $origin
}
.zoom-in-
opacity: 1;
}
.zoom-in-
opacity: 0;
transform: $scaleStart;
transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
transform-origin: $origin;
}
}