feat: allow for flexible position in position animation component

This commit is contained in:
fragosti 2018-10-30 15:32:43 -07:00
parent a49bf353f8
commit 4456c3ee14
3 changed files with 23 additions and 13 deletions

View File

@ -23,18 +23,19 @@ const generateTransitionInfoCss = (
}; };
const slideKeyframeGenerator = ( const slideKeyframeGenerator = (
position: string,
top?: TransitionInfo, top?: TransitionInfo,
bottom?: TransitionInfo, bottom?: TransitionInfo,
left?: TransitionInfo, left?: TransitionInfo,
right?: TransitionInfo, right?: TransitionInfo,
) => keyframes` ) => keyframes`
from { from {
position: relative; position: ${position};
${generateTransitionInfoCss('from', top, bottom, left, right)} ${generateTransitionInfoCss('from', top, bottom, left, right)}
} }
to { to {
position: relative; position: ${position};
${generateTransitionInfoCss('to', top, bottom, left, right)} ${generateTransitionInfoCss('to', top, bottom, left, right)}
} }
`; `;
@ -44,7 +45,7 @@ export interface TransitionInfo {
to: string; to: string;
} }
export interface PositionAnimationProps { export interface PositionAnimationSettings {
top?: TransitionInfo; top?: TransitionInfo;
bottom?: TransitionInfo; bottom?: TransitionInfo;
left?: TransitionInfo; left?: TransitionInfo;
@ -53,18 +54,22 @@ export interface PositionAnimationProps {
direction?: string; direction?: string;
} }
export interface PositionAnimationProps extends PositionAnimationSettings {
position: string;
}
export const PositionAnimation = export const PositionAnimation =
styled.div < styled.div <
PositionAnimationProps > PositionAnimationProps >
` `
animation-name: ${props => animation-name: ${props =>
css` css`
${slideKeyframeGenerator(props.top, props.bottom, props.left, props.right)}; ${slideKeyframeGenerator(props.position, props.top, props.bottom, props.left, props.right)};
`}; `};
animation-duration: 0.3s; animation-duration: 0.3s;
animation-timing-function: ${props => props.timingFunction}; animation-timing-function: ${props => props.timingFunction};
animation-delay: 0s; animation-delay: 0s;
animation-iteration-count: 1; animation-iteration-count: 1;
animation-fill-mode: ${props => props.direction || 'none'}; animation-fill-mode: ${props => props.direction || 'none'};
position: relative; position: ${props => props.position};
`; `;

View File

@ -3,16 +3,21 @@ import { Keyframes } from 'styled-components';
import { css, keyframes, styled } from '../../style/theme'; import { css, keyframes, styled } from '../../style/theme';
import { PositionAnimation, PositionAnimationProps } from './position_animation'; import { PositionAnimation, PositionAnimationSettings } from './position_animation';
export type SlideAnimationPhase = 'slideIn' | 'slideOut'; export type SlideAnimationPhase = 'slideIn' | 'slideOut';
export interface SlideAnimationProps { export interface SlideAnimationProps {
position: string;
phase: SlideAnimationPhase; phase: SlideAnimationPhase;
slideIn: PositionAnimationProps; slideIn: PositionAnimationSettings;
slideOut: PositionAnimationProps; slideOut: PositionAnimationSettings;
} }
export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => { export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => {
const propsToUse = props.phase === 'slideIn' ? props.slideIn : props.slideOut; const propsToUse = props.phase === 'slideIn' ? props.slideIn : props.slideOut;
return <PositionAnimation {...propsToUse}>{props.children}</PositionAnimation>; return (
<PositionAnimation position={props.position} {...propsToUse}>
{props.children}
</PositionAnimation>
);
}; };

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import { ColorOption } from '../style/theme'; import { ColorOption } from '../style/theme';
import { PositionAnimationProps } from './animations/position_animation'; import { PositionAnimationSettings } from './animations/position_animation';
import { SlideAnimation, SlideAnimationPhase } from './animations/slide_animations'; import { SlideAnimation, SlideAnimationPhase } from './animations/slide_animations';
import { Container, Flex, Text } from './ui'; import { Container, Flex, Text } from './ui';
@ -37,14 +37,14 @@ export interface SlidingErrorProps extends ErrorProps {
} }
export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props => { export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props => {
const slideAmount = '120px'; const slideAmount = '120px';
const slideUp: PositionAnimationProps = { const slideUp: PositionAnimationSettings = {
timingFunction: 'ease-in', timingFunction: 'ease-in',
top: { top: {
from: slideAmount, from: slideAmount,
to: '0px', to: '0px',
}, },
}; };
const slideDown: PositionAnimationProps = { const slideDown: PositionAnimationSettings = {
timingFunction: 'cubic-bezier(0.25, 0.1, 0.25, 1)', timingFunction: 'cubic-bezier(0.25, 0.1, 0.25, 1)',
top: { top: {
from: '0px', from: '0px',
@ -53,7 +53,7 @@ export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props =
direction: 'forwards', direction: 'forwards',
}; };
return ( return (
<SlideAnimation slideIn={slideUp} slideOut={slideDown} phase={props.phase}> <SlideAnimation position="relative" slideIn={slideUp} slideOut={slideDown} phase={props.phase}>
<Error icon={props.icon} message={props.message} /> <Error icon={props.icon} message={props.message} />
</SlideAnimation> </SlideAnimation>
); );