Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ed373e6
Full rewrite.
marnusw Dec 6, 2016
0249594
Add third image to the carousel animation.
marnusw Feb 27, 2017
4ee94c7
Not opening the demo in a browser automatically.
marnusw Feb 27, 2017
bb60952
Update docs to include childComponent.
marnusw Mar 8, 2017
ba38fe0
Define prop types using the util in react-transition-group.
marnusw Apr 29, 2017
64ae270
Maintain component callback refs by not overwriting with string refs.
marnusw Apr 29, 2017
f8b0a29
Only add the isLeaving prop to children if notifyLeaving is true.
marnusw Apr 29, 2017
6b3938e
Support multiple children provided all but one child renders null.
marnusw Apr 29, 2017
0000db1
Use requestAnimationFrame to queue the height transition rather than …
marnusw Apr 30, 2017
058551a
The transition nameShape prop type includes the height and heightActi…
marnusw Apr 30, 2017
a69c6fe
Clear the selection after transitions to avoid the child being selec…
marnusw Apr 30, 2017
6c3be56
Entering child renders with absolute positioning since switching from…
marnusw Apr 30, 2017
9ce33e9
Fix enter animation of absolutely positioned elements in Chrome not w…
marnusw Apr 30, 2017
7b7a2b0
Fix Edge glitch when render starts by always applying container posit…
marnusw Apr 30, 2017
5e924c7
Remove demo animated paragraph margins.
marnusw Apr 30, 2017
cd82460
3.0.0-beta.2
marnusw Apr 30, 2017
05069bd
Revert the getChildMapping change since detecting nulls can't work.
marnusw Apr 30, 2017
1b73b4f
Update the changelog for v3.
marnusw Apr 30, 2017
6513728
Add back support for changeWidth.
marnusw Aug 27, 2017
64b4693
React-Router 4 demo and support children rendering null.
marnusw Aug 27, 2017
143ee62
Leave transition dominates for no current child or one that renders n…
marnusw Aug 27, 2017
3f9a4ca
Update demo and docs.
marnusw Aug 27, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
*/
"indent": [1, 2, {"SwitchCase": 1}], // http://eslint.org/docs/rules/indent
"brace-style": [2, // http://eslint.org/docs/rules/brace-style
"stroustrup", {
"1tbs", {
"allowSingleLine": true
}],
"quotes": [
Expand Down Expand Up @@ -155,7 +155,7 @@
"no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
"max": 2
}],
"no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary
"no-nested-ternary": 0, // http://eslint.org/docs/rules/no-nested-ternary
"no-new-object": 2, // http://eslint.org/docs/rules/no-new-object
"no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func
"no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
### v3.0.0 (27 August 2017)

* [ENHANCEMENT] Treat a child rendering `null` as if there is no child; specifically helps avoid errors with RR4.
* [ENHANCEMENT] Maintain component callback refs by not overwriting with string refs similar to `react-transition-group`.
* [FEATURE] Only add the `isLeaving` prop to children if opted in with `notifyLeaving={true}` since it's
a departure from `react-transition-group` features.
* [ENHANCEMENT] Use `requestAnimationFrame` to queue the height transition rather than a timeout.
* [ENHANCEMENT] Handle the enter and leave animation of changes due to successive child updates before the current transition ends.
* [ENHANCEMENT] Clear the selection after transitions to avoid the child being selected after multiple clicks.
* [ENHANCEMENT] Entering child renders with absolute positioning since switching from relative to abs on a premature leave cancels the active enter animation.
* [ENHANCEMENT] Fix enter animation of absolutely positioned elements in Chrome not working by skipping one animation frame in the Child component.
* [ENHANCEMENT] Fix Edge glitch when render starts by always applying container `position`, `display` (use a `div`) and `overflow` styles.

### v2.2.1 (29 April 2017)

* [UPGRADE] Add a `yarn` lock file.
Expand Down
52 changes: 49 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Using `react-css-transition-replace` provides two distinct benefits:

Animations are fully configurable with CSS, including having the entering component wait to enter until
the leaving component's animation completes. Following suit with the
[React.js API](https://facebook.github.io/react/docs/animation.html#getting-started) the one caveat is
[React.js API](https://facebook.github.io/react/docs/animation.html) the one caveat is
that the transition duration must be specified in JavaScript as well as CSS.

[Live Examples](http://marnusw.github.io/react-css-transition-replace) |
Expand All @@ -39,8 +39,9 @@ follows the exact same API as `ReactCSSTransitionGroup`, with support for `trans
and `transitionAppear`. When the `key` of the child component changes, the previous component is animated out
and the new component animated in. During this process:

- The leaving component continues to be rendered as usual with `static` positioning.
- The entering component is positioned on top of the leaving component with `absolute` positioning.
- All leaving components continue to be rendered; if the animation is slow there may be multiple components
in the process of leaving.
- The entering component is positioned on top of the leaving component(s) with `absolute` positioning.
- The height of the container is set to that of the leaving component, and then immediately to that of the
entering component. If the `transitionName` is a `String` the `{animation-name}-height` class name is applied
to it, and if `transitionName` is an `Object` the `transitionName.height` class will be used if present.
Expand All @@ -56,6 +57,10 @@ It is also possible to remove the child component (i.e. leave `ReactCSSTransitio
which will animate the `height` going to zero along with the `leave` transition. Similarly, a single child
can be added to an empty `ReactCSSTransitionReplace`, triggering the inverse animation.

By default a `span` is rendered as a wrapper of the child components. Each child is also wrapped in a `span`
used in the positioning of the actual rendered child. These can be overridden with the `component` and
`childComponent` props respectively.

### Cross-fading two components

The `ReactCSSTransitionReplace` component is used exactly like its `ReactCSSTransitionGroup` counterpart:
Expand Down Expand Up @@ -141,6 +146,47 @@ the duration of the transition. In this case:
See the live example [here](http://marnusw.github.io/react-css-transition-replace#fade-wait).


### React-Router v4

Animated transitions of react-router v4 routes is supported with two caveats shown in the example below:

1. The current `location` must be applied to the `Switch` to force it to maintain the previous matched route on
the leaving component.
2. If the `Switch` might render `null`, i.e. there is no catch-all `"*"` route, the `Switch` must be wrapped in a
`div` or similar for the leave transition to work; if not the previous component will disappear instantaneously
when there is no match.

```javascript
<Router>
<div className="router-example">
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/one">One</Link></li>
<li><Link to="/two">Two</Link></li>
<li><Link to="/three">Three (no match)</Link></li>
</ul>
<Route render={({location}) => (
<ReactCSSTransitionReplace
transitionName="fade"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
<div key={location.pathname}>
<Switch location={location}>
<Route path="/" exact component={Home}/>
<Route path="/one" component={One}/>
<Route path="/two" component={Two}/>
</Switch>
</div>
</ReactCSSTransitionReplace>
)}/>
</div>
</Router>
```

See the live example [here](http://marnusw.github.io/react-css-transition-replace#react-router-v4).


### Hardware acceleration for smoother transitions

For smoother transitions hardware acceleration, which is achieved by using translate3d instead of the 2D
Expand Down
11 changes: 7 additions & 4 deletions UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
# Upgrade Guide

## 2.2.1 -> 3.0.0

Applying the `isLeaving` prop on leaving children is now an opt-in behaviour controlled
by the `notifyLeaving` prop.


## 2.1.0 -> 2.2.0

The library has always had a bug causing subsequent changes while an animation is in
progress to be ignored. This has been fixed in v2.2.0. While the functioning of the
library is now technically more correct, this but may have been a feature used to
smooth over multiple transitions by some which will no longer be the case.

If this causes problems it might be worthwhile to introduce a flag that could direct
the component to ignore changes during transitions to restore the previous behaviour.


## 1.3.0 -> 2.0.0

Expand All @@ -20,7 +23,7 @@ You can pass `transitionName={{ height: 'my-height-className' }}` now, if
you need to use a custom className (useful for `css-modules`).

The leaving component will receive `isLeaving={true}` prop during it's leaving transition.
You can use it in your child components to prevent their rerendering during that period, for example.
You can use it in your child components to prevent their re-rendering during that period, for example.


## 1.0.x -> 1.1.0
Expand Down
14 changes: 13 additions & 1 deletion demo/assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ h3 {
margin-top: 50px;
}

.examples p {
p {
margin-bottom: 0;
}

hr {
border-color: #bbb;
}

.examples > p {
margin-bottom: 20px;
}

.router-example h2 {
margin-top: 0;
}
29 changes: 26 additions & 3 deletions demo/assets/transitions.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,23 @@
/* Carousel-like transition */

.carousel-swap-leave {
transition: transform .3s ease-in-out;
transition: transform 1s ease-in-out;
transform: translate(0, 0);
}
.carousel-swap-leave-active {
transform: translate(-100%, 0);
}

.carousel-swap-enter {
transition: transform .3s ease-in-out;
transition: transform 1s ease-in-out;
transform: translate(100%, 0);
}
.carousel-swap-enter-active {
transform: translate(0, 0);
}

.carousel-swap-height {
transition: height .3s ease-in-out;
transition: height 1s ease-in-out;
}


Expand Down Expand Up @@ -94,3 +94,26 @@
.roll-up-height {
transition: height .8s ease-in-out;
}


/* Fade with width transition */

.fade-fast-leave {
opacity: 1;
}
.fade-fast-leave.fade-fast-leave-active {
opacity: 0;
transition: opacity .5s ease-in-out;
}

.fade-fast-enter {
opacity: 0;
}
.fade-fast-enter.fade-fast-enter-active {
opacity: 1;
transition: opacity .5s ease-in-out;
}

.fade-fast-height {
transition: height .5s ease-in-out, width .5s ease-in-out;
}
60 changes: 60 additions & 0 deletions demo/components/AnimatedRouter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* eslint-disable react/no-multi-comp */
import React from 'react'
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'
import ReactCSSTransitionReplace from '../../src/ReactCSSTransitionReplace.jsx'

const Home = () => (
<div>
<h2>Home</h2>
<img src="img/vista3.jpg" width="600" height="255"/>
</div>
)

const One = () => (
<div>
<h2>One</h2>
<img src="img/vista4.jpg" width="600" height="280"/>
</div>
)

const Two = () => (
<div>
<h2>Two</h2>
<img src="img/vista2.jpg" width="600" height="290"/>
</div>
)

const AnimatedRouter = () => (
<Router>
<div className="router-example">
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/one">One</Link></li>
<li><Link to="/two">Two</Link></li>
<li><Link to="/three">Three (no match)</Link></li>
</ul>

<hr/>

<Route render={({location}) => (
<ReactCSSTransitionReplace
transitionName="fade-fast"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
<div key={location.pathname}>
<Switch location={location}>
<Route path="/" exact component={Home}/>
<Route path="/one" component={One}/>
<Route path="/two" component={Two}/>
</Switch>
</div>
</ReactCSSTransitionReplace>
)}/>

<hr/>
</div>
</Router>
)

export default AnimatedRouter
2 changes: 1 addition & 1 deletion demo/components/ContentAddRemove.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ContentAddRemove extends React.Component {
<div style={style} onClick={this.handleClick}>
<a>Click to {this.state.added ? 'remove' : 'add'} content</a><br/>
<br/>
<ReactCSSTransitionReplace {...this.props} onClick={this.handleClick}>
<ReactCSSTransitionReplace {...this.props}>
{this.state.added ? this.props.children : null}
</ReactCSSTransitionReplace>
</div>
Expand Down
7 changes: 4 additions & 3 deletions demo/components/ContentSwapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import ReactCSSTransitionReplace from '../../src/ReactCSSTransitionReplace.jsx'

class ContentSwapper extends React.Component {

state = {swapped: false}
state = {index: 0}

handleClick = () => {
this.setState({swapped: !this.state.swapped})
const index = this.state.index + 1
this.setState({index: index >= React.Children.count(this.props.children) ? 0 : index})
}

render() {
Expand All @@ -18,7 +19,7 @@ class ContentSwapper extends React.Component {

return (
<ReactCSSTransitionReplace {...this.props} style={style} onClick={this.handleClick}>
{this.state.swapped ? content[1] : content[0]}
{content[this.state.index]}
</ReactCSSTransitionReplace>
)
}
Expand Down
30 changes: 26 additions & 4 deletions demo/components/Demo.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react'
import { Navbar, Nav, NavItem, Grid } from 'react-bootstrap'

const NavbarBrand = Navbar.Brand

import PageHead from './PageHead.jsx'
import ContentSwapper from './ContentSwapper.jsx'
import ContentAddRemove from './ContentAddRemove.jsx'
import AnimatedRouter from './AnimatedRouter.jsx'

import ContentLong from './ContentLong.jsx'
import ContentShort from './ContentShort.jsx'
Expand Down Expand Up @@ -36,7 +38,7 @@ class Demo extends React.Component {
</Navbar>

<Grid>
<PageHead />
<PageHead/>

<div className="examples">
<h2>Examples</h2>
Expand Down Expand Up @@ -71,10 +73,11 @@ class Demo extends React.Component {
<code>{'<ReactCSSTransitionReplace transitionName="carousel-swap" /*...*/ style={{width: 600}}>'}</code>.
</p>

<ContentSwapper transitionName="carousel-swap" transitionEnterTimeout={500} transitionLeaveTimeout={500}
<ContentSwapper transitionName="carousel-swap" transitionEnterTimeout={2000} transitionLeaveTimeout={2000}
style={{width: 600}}>
<img key="img3" src="img/vista3.jpg" width="600" height="255"/>
<img key="img4" src="img/vista4.jpg" width="600" height="280"/>
<img key="img1" src="img/vista3.jpg" width="600" height="255"/>
<img key="img2" src="img/vista4.jpg" width="600" height="280"/>
<img key="img3" src="img/vista2.jpg" width="600" height="290"/>
</ContentSwapper>

<h3 id="roll-up">Add/Remove Content</h3>
Expand All @@ -88,6 +91,25 @@ class Demo extends React.Component {
<img key="img1" src="img/vista1.jpg" width="600" height="235"/>
</ContentAddRemove>

<h3 id="height-and-width">Height and Width animation</h3>
<p>By setting the <code>changeWidth</code> prop the container width is managed along with the height.
This example realizes the same effect as above using this property and just a fade CSS animation.
In this case the <code>height</code> class should configure the transition of both the height
and width properties: <code>transition: height .5s ease-in-out, width .5s ease-in-out;</code>
</p>

<ContentAddRemove
transitionName="fade-fast" transitionEnterTimeout={500} transitionLeaveTimeout={500} changeWidth
>
<img key="img1" src="img/vista1.jpg" width="600" height="235"/>
</ContentAddRemove>

<h3 id="react-router-v4">React Router v4</h3>
<p>Animating React-Router v4 transitions is supported. See the <a
href="https://github.com/marnusw/react-css-transition-replace#cross-fading-two-components"
target="_blank">example</a> for details.</p>

<AnimatedRouter/>
</div>
</Grid>
</div>
Expand Down
2 changes: 2 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ gulp.task('demo:bundleAndWatch', function() {

gulp.task('demo', ['demo:bundleAndWatch'], function() {
browserSync.init({
port: 3010,
browser: ['google chrome'],
open: false,
notify: false,
server: {
baseDir: "demo/assets"
Expand Down
Loading