Guest User

Untitled

a guest
Nov 24th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.98 KB | None | 0 0
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withRouter, matchPath } from 'react-router-dom';
  4. import { TransitionMotion, spring } from 'react-motion';
  5.  
  6. class MotionRoute extends Component {
  7. static propTypes = {
  8. path: PropTypes.string.isRequired,
  9. atEnter: PropTypes.object.isRequired,
  10. atLeave: PropTypes.object.isRequired,
  11. atActive: PropTypes.object.isRequired,
  12. mapStyles: PropTypes.func.isRequired,
  13. exact: PropTypes.bool,
  14. component: PropTypes.func,
  15. render: PropTypes.func
  16. };
  17. static defaultProps = {
  18. exact: false
  19. };
  20.  
  21. /**
  22. * Does this component match the current router location?
  23. * We use the build in matchPath method from react-router.
  24. * @returns {bool} - Match or no match (true, false).
  25. */
  26. computeMatch = () => {
  27. const { location, path, exact } = this.props;
  28. return matchPath(location.pathname, { path, exact });
  29. };
  30.  
  31. /**
  32. * Ensure that react-motions spring is wrapping the object
  33. * values of the provided style object.
  34. * @returns {object} - Enhanced object.
  35. */
  36. ensureSpring = (style) => {
  37. return Object.keys(style).reduce((acc, key) => {
  38. const value = style[key];
  39. acc[key] = spring(value);
  40. return acc;
  41. }, {});
  42. };
  43.  
  44. /**
  45. * If we have a component to render,
  46. * create the default styles object
  47. */
  48. getDefaultStyles = () => {
  49. return this.computeMatch() ? [
  50. {
  51. key: this.props.location.key,
  52. style: this.props.atEnter,
  53. },
  54. ] : null;
  55. };
  56.  
  57. /**
  58. * If we have a component to render,
  59. * create the styles object with the spring(..) values
  60. */
  61. getStyles = () => {
  62. return this.computeMatch() ? [
  63. {
  64. key: this.props.location.key,
  65. style: this.ensureSpring(this.props.atActive),
  66. },
  67. ] : [];
  68. }
  69.  
  70. /**
  71. * When the component enters, use the atEnter styles.
  72. */
  73. willEnter = () => {
  74. return this.props.atEnter;
  75. };
  76.  
  77. /**
  78. * When the component leaves, use the atLeave styles,
  79. * which we "springify".
  80. */
  81. willLeave = () => {
  82. return this.ensureSpring(this.props.atLeave);
  83. };
  84.  
  85. /**
  86. * Enhance the rendered element with the interpolated style.
  87. */
  88. renderChildren = (interpolatedStyle) => {
  89. const { component, render, mapStyles } = this.props;
  90. const children = interpolatedStyle.map(config => {
  91. const motionProps = {
  92. style: mapStyles(config.style),
  93. key: config.key
  94. };
  95. if (component) {
  96. return React.createElement(component, motionProps)
  97. }
  98. if (render) {
  99. return render(motionProps);
  100. }
  101. return null;
  102. });
  103.  
  104. // We only ever return the first child or nothing.
  105. return children[0] || null;
  106. };
  107.  
  108. render() {
  109. return (
  110. <TransitionMotion
  111. defaultStyles={this.getDefaultStyles()}
  112. styles={this.getStyles()}
  113. willEnter={this.willEnter}
  114. willLeave={this.willLeave}
  115. >
  116. {this.renderChildren}
  117. </TransitionMotion>
  118. )
  119. }
  120. }
  121.  
  122. export default withRouter(MotionRoute);
Add Comment
Please, Sign In to add comment