maisano / react-router-transition Goto Github PK
View Code? Open in Web Editor NEWpainless transitions built for react-router, powered by react-motion
Home Page: http://maisano.github.io/react-router-transition/
License: MIT License
painless transitions built for react-router, powered by react-motion
Home Page: http://maisano.github.io/react-router-transition/
License: MIT License
Loving this library.
Wondering if there was a simple way to add delays to animations.
Say for instance you have multiple components that you want to animate in one after another or at specified times.
Might be something simple but I don't see it anywhere in the code.
high level looking to do something like this:
atEnter={{
'opacity' : '0',
'animation-delay' : '250ms',
'-webkit-animation-delay' : '200ms'
}}
or perhaps is there a way to add a custom class to the element that handles the transition?
Does it work with react-router dynamic routing/code splitting?
In the atEnter, AtLeave, and atActive parameters, the spring method is applied to the animations by default. In react-motion, however, if you don't add the spring method to your interpolated value, the "unspringed" value just gets passed in without being interpolated over the duration of the spring. Would a better alternative be to either
OR
I see this as beneficial by giving more granular control over what values get "springed" and what doesn't. Just a thought.
hello
i am trying use this with react-router@4
but it don't work as expect.
package.json
still dep on react-router@2, got any plan to make it compatible with v4?
I'm going for a full material design app and I'd like to implement more transitions inside the views when they appear or disappear.
Something like this, with the ❤️ icon appearing while the whole view is transitionning, taken from official guidelines, § Motion is clear*
I think that just adding a enter
and leave
class to the component whenever a transition starts would be enough.
Can you think of any other way ? Would you accept a PR on this ?
there is no informartion on how to control the duration of a transition animation.
uh, my bad. this should be fixed.
In demos,
<Lorem />
Component's position is set to absolute
, So transition seems to work well.
https://github.com/maisano/react-router-transition/blob/master/demos/index.html#L36
but If you can't set router's position to absolute, (like each router's height are different and it can be changed) transition wouldn't work well.
I've tried to set position: absolute
on atLeave
only, but it didn't work.
Also, I couldn't figure out how to handle it using mapStyes
.
Any ideas? 😞
When transition to the next page, the content of the page appears from bottom.
<RouteTransition
pathname={this.props.location.pathname}
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}
>
{ this.props.children }
</RouteTransition>
There seems to be a delay between the opacity change and the element fixing its size. Here is a quick vid:
As you can see, there is a slight delay after I have changed tabs and the size of the content readjusting. Is this intentional, or is this an issue?
Here is what I have on my RouteTransition
:
<RouteTransition
pathname={this.props.location.pathname}
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}
>
{this.props.children}
</RouteTransition>
people get (very understandbly) confused about the pathname prop. it should probably be changed to "key".
Please add "jsnext:main": "src/RouteTransition.jsx"
into package.json
to let devs transpile for their own environment.
When applying spring
to a value on transform it causes a constant looping error. "[object Object]NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNa…NNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN"}
Getting the following error.
Warning:
NaNis an invalid value for the
opacity css style property.
This is what the code looks like
<RouteTransition pathname={location.pathname} {...presets.slideLeft}>
{children}
</RouteTransition>
Have you seen this before?
The component
Prop can technically be a component, and the code functions fine when this is the case, but it still gives a warning that it must either be a string or a bool.
Hi,
I'm facing to a big big lag on a webapp on Android 6.0.1 with an old Android System Webview.
My RouteTransition configuration is like this:
<RouteTransition
className="transition-wrapper"
pathname={this.props.location.pathname}
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}>
<div className="wrapper">{childrenWithProps}</div>
</RouteTransition>
Of course:
<div className="wrapper">{childrenWithProps}</div>
is in position absolute.
While transitioning, the computation of the opacity is extremely slow on my wrapper div and very strange... :
It could be endless or took lot of time.
If anyone could help me on that hot topic for me?
Thanks.
If I use this with react-sanpshot the resulting static markup from react-snaptshot has a less then 1 opacity.
I'm using react-router-Transition like so in my main App.js:
<RouteTransition
pathname={this.props.location.pathname}
atEnter={{opacity: 0}}
atLeave={{opacity: 2}}
atActive={{opacity: 1}}
mapStyles={styles => {
if (styles.opacity > 1) {
return {display: 'none'}
}
return {opacity: styles.opacity}
}}>
Any suggestions as to why that is?
Sounds great -- would it be possible to get a demo online? Would like to add to react.rocks... thanks!
Thanks for the component! I'd like to use them in my flexbox based app.
All my divs are styled as relative and with flex layout
div, span {
box-sizing: border-box;
position: relative;
border: 0 solid black;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-start;
flex-shrink: 0;
}
And this is my markup that renders the children
<div style={{height:"100vh", width: "100vw"}}>
<div style={STYLES.appbar}></div>
<div style={STYLES.content}>
{children}
</div>
<NavBar style={STYLES.navbar}/>
</div>
const STYLES = {
appbar: {
flex: "none"
},
content: {
flex: 1
},
navbar: {
flex: "none"
},
}
Wrapping children
into ReactRouterTransition
displays the old content for a moment together with the new content but then the new content jumps up to the page start (when the previous page has been removed).
Any ideas how to get this Component to work with flexbox?
I'm having issues with navigating to index routes when wrapping a bunch of routes with <RouteTransition>
. This issue might fall more-so under react router, but I'm wondering what you guys did in situations like these.
Working example - scroll down to the bottom for the router
If my router is:
<Router history={ReactRouter.hashHistory}>
<Route path="/" component={Internal}>
<Route path="/" component={CustomTransition}>
<IndexRoute component={Home} />
<Route path="/images" component={Images} />
<Route path="/search" component={Search} />
</Route>
</Route>
<Route path="/auth" component={Auth}>
// any auth routes would go here
</Route>
</Router>
My <IndexRoute component={Home} />
doesn't render at all - i'm guessing it's something related props.children
not being passed down? If I place the index before the CustomTransition
, like:
<Route path="/" component={Internal}>
<IndexRoute component={Home} />
<Route path="/" component={CustomTransition}>
<Route path="/images" component={Images} />
<Route path="/search" component={Search} />
</Route>
</Route>
It renders correctly, but longer animates (since it's outside of CustomTransition
). Is there some different way of setting things up so navigating to /
goes to {Home}
but also animates the transition?
The only solution I can think of is creating /home
path within customTransition
, and redirecting to it when navigating to /
. The only annoyance being that the root of the app is ultimately /home
.
<Route path="/" component={Internal}>
<IndexRedirect to="/home"/>
<Route path="/" component={CustomTransition}>
<Route path="/home" component={Home} />
<Route path="/images" component={Images} />
<Route path="/search" component={Search} />
</Route>
</Route>
It took me 2-3 hours to find out that if you don't use absolute positioning, your pages will be created below the existing one
<RouteTransition
pathname={this.props.pathname}
atEnter={{ translateX: 100 }}
atLeave={{ translateX: -100 }}
atActive={{ translateX: 0}}
mapStyles={mapStyles}>
<div style={{
"position": "absolute", "margin-left": "auto",
"margin-right": "auto",
"left": 0,
"right": 0}}>
<div className="container" style={this.state.containerStyle}>
{this.props.children}
</div>
</div>
</RouteTransition>
It would be a good idea to specify this in the Readme
to gain more control on page transition elements, i think will help a lopt to have the o option to work like the ReactCSSTransitionGroup component https://facebook.github.io/react/docs/animation.html or the ngAnimate in the view directive on angular
It doesn't seem to work on IOS devices less than v9.
Is there any way to make it work, even if it is a hacky way?
I am aware of the fact that IOS 9 is the latest which supports CSS transitions.
Hi, I'd like to use slideLeft/Right in my app, however I'd like to control which route uses which transition effect depending from where you access it.
Lets have four tabs A,B,C,D . Default is A.
From A to any other lets use slideLeft.
From B to C or D still slideLeft, but to A slideRight.
Now I'm using example from main 'wiki' of this repo:
<Route render={({location, history, match}) => {
return (
<RouteTransition pathname={location.pathname} {...presets.slideLeft} >
<Switch key={location.key} location={location}>
<Route exact path="/" component={Home}/>
<Route path="/projects" component={ProjectsPage} />
<Route exact path="/about" component={AboutPage}/>
</Switch>
</RouteTransition>
);}} />
I tried:
<Route render={({location, history, match}) => {
return (
<Switch key={location.key} location={location.pathname}>
<RouteTransition {...presets.slideRight}>
<Route exact path="/" component={Home}/>
</RouteTransition>,
<RouteTransition {...presets.slideLeft}>
<Route path="/projects" component={ProjectsPage}/>
</RouteTransition>,
<RouteTransition {...presets.slideLeft}>
<Route exact path="/about" component={AboutPage}/>
</RouteTransition>
</Switch>
);}}/>
Renders only first Route
And:
<Route render={({location, history, match}) => {
return (
<RouteTransition pathname={location.pathname} {...presets.slideRight}>
<Route exact path="/" component={Home}/>
</RouteTransition>
);}}/>
<Route render={({location, history, match}) => {
return (
<RouteTransition pathname={location.pathname} {...presets.slideLeft}>
<Route path="/projects" component={ProjectsPage}/>
</RouteTransition>
);}}/>
<Route render={({location, history, match}) => {
return (
<RouteTransition pathname={location.pathname} {...presets.slideLeft}>
<Route exact path="/about" component={AboutPage}/>
</RouteTransition>
);}}/>
Which works ok but feels redundant.
Is this the way to go?
I was having some problems with a modal that I wanted to transition from the bottom up. I tried using translateY as you used translateX in the demos and it didn't work.
I'm working with dave zuko's react redux starter kit and I'm trying to apply some router transitions. If I understand correctly I should wrap my component with a transitions container and send the wrapped component to my router.
From the demo:
const SlideRightDemo = props => (
<RouteTransitionDemo preset={presets.slideRight} {...props} />
);
const Demo = () => (
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="slideright" component={SlideRightDemo}>
Here's the router index file and a component route index:
import CoreLayout from '../layouts/CoreLayout/CoreLayout'
import Home from './Home'
import CounterRoute from './Counter'
export const createRoutes = (store) => ({
path: '/',
component: CoreLayout,
indexRoute: Home,
childRoutes: [
CounterRoute(store)
]
})
component index
import { injectReducer } from '../../store/reducers'
export default (store) => ({
path: 'counter',
/* Async getComponent is only invoked when route matches */
getComponent (nextState, cb) {
/* Webpack - use 'require.ensure' to create a split point
and embed an async module loader (jsonp) when bundling */
require.ensure([], (require) => {
/* Webpack - use require callback to define
dependencies for bundling */
const Counter = require('./containers/CounterContainer').default
const reducer = require('./modules/counter').default
/* Add the reducer to the store on key 'counter' */
injectReducer(store, { key: 'counter', reducer })
/* Return getComponent */
cb(null, Counter)
/* Webpack named bundle */
}, 'counter')
}
})
I have this warning when running react-router-transition from create-react-app boilterplate.
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
Could you consider replacing this by below in src/RouteTransition.jsx?
import React, { Component, PropTypes } from 'react'
to
import React, { Component } from 'react'
import PropTypes from 'prop-types'
Thanks in advance
I had this warning when running react-router-transition in React 15.5.4.
Motion: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.
Thanks
React motion appears to be trying to reverse the animation if you go from from /route/a
to /route/b
and back to /route/a
before the animation ends. Because the animation is running in reverse atEnter
and atLeave
should also be reversed.
This behavior is noticeable on the demo if you quickly clicks between "another slideLeft" http://maisano.github.io/react-router-transition/demos/#/slideLeft/demo-2?_k=ycnlzx
@maisano I can't figure out why my component appears before the transition and then it gets animated.
Here a simple repro: https://github.com/damianobarbati/react-app
git clone https://github.com/damianobarbati/react-app
cd react-app
yarn install
yarn serve:dev
yarn build:dev
The user app running at http://localhost:8080/user/
shows this behaviour: clicking list
and then home
you can see:
View container is position:fixed
=> https://github.com/damianobarbati/react-app/blob/master/apps/user/components/layout.js#L23
What am I doing wrong? Thanks in advance for your effort with this project, I'm trying to use it in a cordova app hoping for great performance!
I'm trying to configure a nested transition with a few rules.
RouteTransition
that fade transitions among it's child peers, and slide left transitions to a grandchild page.RouteTransition
(?) that has different transition behavior (i.e. no transition among its peers and a slide right to go back up to it's parent).pathname
prop can't be as simple as this.props.location.pathname
because that will interfere with grandchild rendering and transitions: URL change causes each children to fully re-mount, which disrupts the nested transition.Can you help me understand how to set this up? Is it possible to prevent peer children from totally re-mounting (they have basically 50% shared components)? I think a code example would be really helpful. Thanks!
Hello, I want to access your presets for fade, slideLeft, etc. How would I access them from the app to set the atEnter atLeave atActive? Also is react-motion accessible straight from react-router-transition
in order to add custom transitions without having to install react-motion from my project?
When using currently suggested location.pathname
and navigating back and forth between URLs that are currently in use then there's a weird animation overlap. Replacing it with location.key
does exactly what it should - correctly identifies routes, and not depending on current pathname.
So the proposal is to alter readme to make location.key
the default and maybe rename prop from pathname
to key
to reflect the real meaning.
This should resolve
#21
First of all, thanks a lot for the great plugin! Was searching for this for ages.
I just used it on my app and things are working fine. But there's a small delay un-mounting the current component when it have the same parent route as the previous one. For example moving between, /posts/add
and /posts/edit
have a delay while moving between /posts/add
and /comments
works fine. Looks like it takes time for the previous component to unload. Is it possible to set it's display
property to none
when the animation is done?
Great library, it has been working perfectly! I do have one exception though that might actually make this library unusable in my case though.
The only case that is not working for me is when the user uses the built-in iOS back and forward swipe gestures on safari. This swipe looks like this: https://cl.ly/1g1H44452V3l
When this transition happens in my react app, the from
page is given the atEnter
styles although it is already out of the screen (as we have landed on the previous page from the iOS swipe gesture).
Have any users of this library (or react-router as a whole) had trouble with this? And has anyone found a fix?
Thanks!
I switch between two paths repeatedly,until the animation finished,then the last route Component will unmount actually. so, I can not do something in componentWillmount
in the last Component
In order to suppress React's warnings regarding "PropTypes" and "createClass" code needs to be refactored.
Seems like commits are already being made but package version on npm is still outdated.
Maybe you forgot to publish it? ;)
So i tried to change URL manually using guide.
App
. A nice opacity transition is done.App
immediately at componentWillMount
changes URL.App
components in DOM.In the README
I strongly recommend looking at [React Router v4](https://react-router.now.sh/) and the authors' provided [animation example](https://react-router.now.sh/animated-transitions) before choosing this library.
The animation example no longer exists.
Package.json points to lib/index.js
but the generated file is called react-router-transition.js
. This naturally causes a bug in Webpack at compile time:
ERROR in ./path/to/file.js
Module not found: Error: Cannot resolve module 'react-router-transition' in /path/to/project
@ ./path/to/file.js 13:29-63
I wanted to patch this and submit a pull request, but both my attempts at fixing this didn't work. First I tried changing the reference to main
in package.json so it pointed at react-router-transition.js
instead, then, when that didn't work, I renamed the compiled files filename to index.js
. Both solutions netted the same result: Webpack just imports an empty object that looks like this when inspected in the browser: { default: {} }
. I'm not sure why renaming the file doesn't work, but there's something funky going on here ...
I want to use react-router-config. Is had example?Thanks!
I try overwrite react-router-config,but react-router-transition not work!Was I forgetting something?
/* @flow */
import React from 'react'
import styled from 'styled-components'
import { AnimatedSwitch } from 'react-router-transition'
import { Switch, Route } from 'react-router-dom'
const Modernizr = window.Modernizr
const StyledAnimatedSwitch = styled(AnimatedSwitch)`
position: relative;
> div {
position: absolute;
top: 0;
width: 100%;
}
`
const renderRoutes = (
routes: Array<any>,
extraProps: Object = {},
isRoot: boolean = false,
isAnimate?: boolean = false
) => {
if (!routes) {
return null
}
const contents = routes.map((route, i) => {
const key = `${i}_${route.path}`
return (
<Route
key={key}
path={route.path}
exact={route.exact}
strict={route.strict}
render={(props: Object) => (
typeof route.render === 'function' ? route.render(props) : (
<route.component {...props} {...extraProps} route={route} />
))}
/>
)
})
if (isRoot) {
return contents
}
if (isAnimate) {
return (
<StyledAnimatedSwitch
atEnter={{
translateX: 100,
opacity: 0
}}
atLeave={{
translateX: -220,
opacity: 0
}}
atActive={{
translateX: 0,
opacity: 1
}}
mapStyles={(styles) => {
const style = {}
style[Modernizr.prefixed('opacity')] = styles.opacity
style[Modernizr.prefixed('transform')] = `translateX(${styles.translateX > 0 ? `${styles.translateX}%` : `${styles.translateX}px`})`
return style
}}
>
{contents}
</StyledAnimatedSwitch>
)
}
return (
<Switch>{contents}</Switch>
)
}
export default renderRoutes
I started to see this after upgrading to v1. Is there a quick fix for this?
Warning: Failed prop type: Invalid prop `styles` supplied to `TransitionMotion`.
const slideLeft = {
atEnter: {
opacity: 0,
offset: 100,
pos: 0,
},
atLeave: {
opacity: 0,
offset: -100,
pos: 2,
},
atActive: {
opacity: 1,
offset: 0,
pos: 1,
},
mapStyles(styles) {
return {
position: (styles.pos <= 1) ? 'relative' : 'absolute',
opacity: styles.opacity,
transform: `translateX(${styles.offset}%)`,
};
},
};
<RouteTransition
pathname={params.location.pathname}
className="transition-wrapper"
{...slideLeft}
>
<Switch key={params.location.key} location={params.location}>
<Route path={`${match.url}/info/`} component={PatientInfoPage} />
<Route path={`${match.url}/confirmed/`} component={ShowConfirmationPage} />
</Switch>
</RouteTransition>
I have a component that checks user authorization and redirects them if they are unauthorized. It redirects them using the Redirect
component from react-router-dom
.
When I wrapped my routes in a RouteTransition
component and passed location
and location.key
to the Switch
component, I noticed that whenever my app would redirect someone, the render logic would execute twice.
If you spin up a server with the following code and visit /dashboard
, you will see that "wot" gets logged to the console twice before being redirected to /
.
import React from 'react';
import {render} from 'react-dom';
import {BrowserRouter, Redirect, Route, Switch} from 'react-router-dom';
import {RouteTransition} from 'react-router-transition';
render(
<BrowserRouter>
<Route render={({location}) => (
<RouteTransition
atActive={{opacity: 1}}
atEnter={{opacity: 0}}
atLeave={{opacity: 0}}
pathname={location.pathname}
>
<Switch key={location.key} location={location}>
<Route exact path="/" render={() => <div>Please log in</div>}/>
<Route exact path="/dashboard" render={() => {
console.log('wot');
return <Redirect to="/"/>;
}}/>
</Switch>
</RouteTransition>
)}/>
</BrowserRouter>,
document.getElementById('root')
);
What do I need to do to make my render logic only execute once?
@maisano I'm reporting here a couple of violations emitted on Chrome.
First at on.js:18
=>
[Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive.
return node.addEventListener(eventName, handler, capture || false);
Second at react-router-transition.js:587
=>
[Violation] 'requestAnimationFrame' handler took 97ms
this.animationID = _raf2['default'](function (timestamp) {
I'm not sure if the problem is caused by the way I'm using react-router-transition
but here a reference in case (and it's working fine):
Router.js
export default class Router extends React.Component {
render() {
return (
<ConnectedRouter history={history}>
<Layout>
<Switch>
<Route exact path={'/'} component={Home} />
<Route exact path={'/news'} component={News} />
<Route exact path={'/classes'} component={Classes} />
</Switch>
</Layout>
</ConnectedRouter>
);
}
}
Layout.js
render () {
const { children, history } = this.props;
const { action } = history;
const animation = action === 'PUSH' ? presets.slideLeft : presets.slideRight;
const viewStyle = { marginTop: '0px', height: 'calc(100vh - 50px)', overflowY: 'auto' };
const navStyle = { position: 'fixed', bottom: 0, left: 0, zIndex: 1, width: '100%', overflowX: 'scroll', borderTop: '1px solid rgba(0, 0, 0, 0.12)' };
return (
<MuiThemeProvider theme={theme}>
<Grid container={true} gutter={0}>
<RouteTransition pathname={location.pathname} {...animation} style={{ width: '100vw' }}>
<div style={{ position: 'absolute', width: '100vw' }}>
<Grid item={true} xs={12} style={viewStyle}>
{children}
</Grid>
</div>
</RouteTransition>
<Grid item={true} xs={12} style={navStyle}>
<Nav />
</Grid>
</Grid>
</MuiThemeProvider>
);
}
Great work!
Hello,
I would like to avoid having the router animation kick in at initial app load, instead having it only at route change. Do you support this scenario?
Thank you.
I'm using this code to great effect, thank you for sharing it.
I have a following question: right now using a transition makes the program correctly leave the previous view, but it transitions to an empty page, then the next view pops in. Is there a way to make it transition directly to the next page?
Sorry I was a bit confused as you your router v4 ref and the beginning of the readme.
We're really struggling with v2 and trying to get very granular page transitions across our site.
For instance, we have two elements on a single page animating in completely different directions and transforms. (GSAP)
The code is pretty kludgy and we've gotten to the point we're dieing to try something more reliable.
Does this mean we should look at pivoting to v4...... or rather to using this component? Just curious as to what you think based on the fact that you seem to know both fairly well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.