Skip to content

Instantly share code, notes, and snippets.

@chapati23
Created November 8, 2016 22:41
Show Gist options
  • Save chapati23/f1af5a63c965b1267b46c3335afa2f76 to your computer and use it in GitHub Desktop.
Save chapati23/f1af5a63c965b1267b46c3335afa2f76 to your computer and use it in GitHub Desktop.
React Router v4 Page Transitions
import React from 'react'
import { TransitionMotion, spring } from 'react-motion'
import Router from 'react-router/BrowserRouter'
import Match from 'react-router/Match'
import Link from 'react-router/Link'
import Redirect from 'react-router/Redirect'
const styles = {}
styles.fill = {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0
}
styles.content = {
...styles.fill,
top: '40px',
textAlign: 'center'
}
styles.nav = {
padding: 0,
margin: 0,
position: 'absolute',
top: 0,
height: '40px',
width: '100%',
display: 'flex'
}
styles.navItem = {
textAlign: 'center',
flex: 1,
listStyleType: 'none',
padding: '10px'
}
styles.hsl = {
...styles.fill,
color: 'white',
paddingTop: '20px',
fontSize: '30px'
}
const transitions = {
'show-from-right': {
atEnter: {
opacity: 0,
offset: 100,
},
atLeave: {
opacity: spring(0),
offset: spring(-100)
},
atActive: {
opacity: spring(1),
offset: spring(0)
},
mapStyles: (styles) => ({
opacity: styles.opacity,
transform: `translateX(${styles.offset}%)`
})
}
}
const MatchWithTransition = (props) => {
const { component: Component, ...rest } = props
const willEnter = () => ({ ...transitions['show-from-right'].atEnter })
const willLeave = () => ({ ...transitions['show-from-right'].atLeave })
return (
<Match {...rest} children={({ matched, ...props }) => (
<TransitionMotion
willEnter={willEnter}
willLeave={willLeave}
styles={matched ? [ {
key: props.location.pathname,
style: { ...transitions['show-from-right'].atActive },
data: props
} ] : []}
>
{interpolatedStyles => (
<div>
{interpolatedStyles.map(config => (
<div
key={config.key}
style={{ ...styles.fill, ...transitions['show-from-right'].mapStyles(config.style) }}
>
<Component {...config.data} />
</div>
))}
</div>
)}
</TransitionMotion>
)}/>
)
}
const NavLink = (props) => (
<li style={styles.navItem}>
<Link {...props} style={{ color: 'inherit' }}/>
</li>
)
const HSL = ({ params }) => (
<div style={{
...styles.hsl,
background: `hsl(${params.h}, ${params.s}%, ${params.l}%)`
}}>hsl({params.h}, {params.s}%, {params.l}%)</div>
)
const About = (props) => {
return <section>About</section>
}
const App = ({ history }) => (
<Router history={history}>
<div style={styles.fill}>
<ul style={styles.nav}>
<NavLink to="/about">About</NavLink>
<NavLink to="/10/50/50">Red</NavLink>
<NavLink to="/50/70/50">Yellow</NavLink>
<NavLink to="/200/50/50">Blue</NavLink>
<NavLink to="/300/50/50">Dunno</NavLink>
</ul>
<div style={styles.content}>
<MatchWithTransition pattern="/:h/:s/:l" component={HSL}/>
<MatchWithTransition pattern="/about" component={About} history={history}/>
</div>
<Match exactly pattern="/" render={() => (
<Redirect to="/10/50/50"/>
)}/>
</div>
</Router>
)
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment