Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { Component } from 'react';
- import PropTypes from 'prop-types';
- import { withRouter, matchPath } from 'react-router-dom';
- import { TransitionMotion, spring } from 'react-motion';
- class MotionRoute extends Component {
- static propTypes = {
- path: PropTypes.string.isRequired,
- atEnter: PropTypes.object.isRequired,
- atLeave: PropTypes.object.isRequired,
- atActive: PropTypes.object.isRequired,
- mapStyles: PropTypes.func.isRequired,
- exact: PropTypes.bool,
- component: PropTypes.func,
- render: PropTypes.func
- };
- static defaultProps = {
- exact: false
- };
- /**
- * Does this component match the current router location?
- * We use the build in matchPath method from react-router.
- * @returns {bool} - Match or no match (true, false).
- */
- computeMatch = () => {
- const { location, path, exact } = this.props;
- return matchPath(location.pathname, { path, exact });
- };
- /**
- * Ensure that react-motions spring is wrapping the object
- * values of the provided style object.
- * @returns {object} - Enhanced object.
- */
- ensureSpring = (style) => {
- return Object.keys(style).reduce((acc, key) => {
- const value = style[key];
- acc[key] = spring(value);
- return acc;
- }, {});
- };
- /**
- * If we have a component to render,
- * create the default styles object
- */
- getDefaultStyles = () => {
- return this.computeMatch() ? [
- {
- key: this.props.location.key,
- style: this.props.atEnter,
- },
- ] : null;
- };
- /**
- * If we have a component to render,
- * create the styles object with the spring(..) values
- */
- getStyles = () => {
- return this.computeMatch() ? [
- {
- key: this.props.location.key,
- style: this.ensureSpring(this.props.atActive),
- },
- ] : [];
- }
- /**
- * When the component enters, use the atEnter styles.
- */
- willEnter = () => {
- return this.props.atEnter;
- };
- /**
- * When the component leaves, use the atLeave styles,
- * which we "springify".
- */
- willLeave = () => {
- return this.ensureSpring(this.props.atLeave);
- };
- /**
- * Enhance the rendered element with the interpolated style.
- */
- renderChildren = (interpolatedStyle) => {
- const { component, render, mapStyles } = this.props;
- const children = interpolatedStyle.map(config => {
- const motionProps = {
- style: mapStyles(config.style),
- key: config.key
- };
- if (component) {
- return React.createElement(component, motionProps)
- }
- if (render) {
- return render(motionProps);
- }
- return null;
- });
- // We only ever return the first child or nothing.
- return children[0] || null;
- };
- render() {
- return (
- <TransitionMotion
- defaultStyles={this.getDefaultStyles()}
- styles={this.getStyles()}
- willEnter={this.willEnter}
- willLeave={this.willLeave}
- >
- {this.renderChildren}
- </TransitionMotion>
- )
- }
- }
- export default withRouter(MotionRoute);
Add Comment
Please, Sign In to add comment