import React, { Component } from 'react'; import { TransitionMotion, spring } from 'react-motion'; import ReactHeight from 'react-height'; import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel'; import {helpLinks as helpLinksStyles} from 'components/auth/helpLinks.scss'; import panelStyles from 'components/ui/panel.scss'; import icons from 'components/ui/icons.scss'; const opacitySpringConfig = [200, 20]; const heightSpringConfig = [200, 18]; const transformSpringConfig = [500, 20]; // TODO: сделать более быстрый фейд на горизонтальном скролле export default class PanelTransition extends Component { state = { height: {} }; componentWillReceiveProps(nextProps) { var previousRoute = this.props.location; var next = nextProps.path; var prev = previousRoute && previousRoute.pathname; var direction = this.getDirection(next, next, prev); var forceHeight = direction === 'Y' ? 1 : 0; this.setState({ forceHeight: forceHeight, previousRoute: this.props.location }); if (forceHeight) { setTimeout(() => { this.setState({forceHeight: 0}); }, 100); } } render() { var {previousRoute, height} = this.state; var {path, Title, Body, Footer, Links} = this.props; return ( {(items) => { var keys = Object.keys(items).filter((key) => key !== 'common'); return (
{keys.map((key) => this.getHeader(key, items[key]))}
{keys.map((key) => this.getBody(key, items[key]))}
{keys.map((key) => this.getFooter(key, items[key]))}
{keys.map((key) => this.getLinks(key, items[key]))}
); }}
); } willEnter = (key, styles) => { var map = { '/login': -1, '/register': -1, '/password': 1, '/activation': 1, '/oauth/permissions': -1 }; var sign = map[key]; return { ...styles, transformSpring: spring(sign * 100, transformSpringConfig), opacitySpring: spring(1, opacitySpringConfig) }; }; willLeave = (key, styles) => { var map = { '/login': -1, '/register': -1, '/password': 1, '/activation': 1, '/oauth/permissions': -1 }; var sign = map[key]; return { ...styles, transformSpring: spring(sign * 100, transformSpringConfig), opacitySpring: spring(0, opacitySpringConfig) }; }; updateHeight = (height) => { this.setState({ height: { ...this.state.height, [this.props.path]: height } }); }; onGoBack = (event) => { event.preventDefault(); this.props.history.goBack(); }; getHeader(key, props) { var {hasBackButton, transformSpring, Title} = props; var style = { position: 'absolute', top: 0, left: 0, width: '100%' }; var scrollStyle = { WebkitTransform: `translateY(${transformSpring}%)`, transform: `translateY(${transformSpring}%)` }; var sideScrollStyle = { position: 'relative', zIndex: 2, WebkitTransform: `translateX(${-Math.abs(transformSpring)}%)`, transform: `translateX(${-Math.abs(transformSpring)}%)` }; var backButton = ( ); return (
{hasBackButton ? backButton : null}
{Title}
); } getBody(key, props) { var {transformSpring, opacitySpring, Body} = props; var {previousRoute} = this.state; var next = this.props.path; var prev = previousRoute && previousRoute.pathname; var direction = this.getDirection(key, next, prev); var verticalOrigin = 'top'; if (direction === 'Y') { // TODO: do not activate animation when nothing was unmounted transformSpring = Math.abs(transformSpring); if (prev === key) { transformSpring *= -1; } verticalOrigin = 'bottom'; } var style = { position: 'absolute', [verticalOrigin]: 0, left: 0, width: '100%', WebkitTransform: `translate${direction}(${transformSpring}%)`, transform: `translate${direction}(${transformSpring}%)`, opacity: opacitySpring }; return ( {Body} ); } getDirection(key, next, prev) { var not = (path) => prev !== path && next !== path; var map = { '/login': not('/password') ? 'Y' : 'X', '/password': not('/login') ? 'Y' : 'X', '/register': not('/activation') ? 'Y' : 'X', '/activation': not('/register') ? 'Y' : 'X', '/oauth/permissions': 'Y' }; return map[key]; } getFooter(key, props) { var {opacitySpring, Footer} = props; var style = { position: 'absolute', top: 0, left: 0, width: '100%', opacity: opacitySpring }; return (
{Footer}
); } getLinks(key, props) { var {opacitySpring, Links} = props; var style = { position: 'absolute', top: 0, left: 0, width: '100%', opacity: opacitySpring }; return (
{Links}
); } }