Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ and the new component animated in. During this process:

This provides many possibilities for animating the replacement as illustrated in the examples below.

Additionally, `changeWidth` can be used to animate changing the width of the component. This change
will happen at the same time as changing the height. Animating this change should be done using
the same class name as is used for animating the change of height.

It is also possible to remove the child component (i.e. leave `ReactCSSTransitionReplace` with no children)
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.
Expand Down
35 changes: 26 additions & 9 deletions src/ReactCSSTransitionReplace.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ export default class ReactCSSTransitionReplace extends React.Component {
transitionAppearTimeout: createTransitionTimeoutPropValidator('Appear'),
transitionEnterTimeout: createTransitionTimeoutPropValidator('Enter'),
transitionLeaveTimeout: createTransitionTimeoutPropValidator('Leave'),
overflowHidden: React.PropTypes.bool
overflowHidden: React.PropTypes.bool,
changeWidth: React.PropTypes.bool
};

static defaultProps = {
transitionAppear: false,
transitionEnter: true,
transitionLeave: true,
overflowHidden: true,
component: 'span'
component: 'span',
changeWidth: false
};

state = {
Expand All @@ -80,6 +82,7 @@ export default class ReactCSSTransitionReplace extends React.Component {
nextChild: undefined,
nextChildKey: '',
height: null,
width: null,
isLeaving: false
};

Expand Down Expand Up @@ -118,7 +121,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
this.setState({
nextChild,
nextChildKey: state.currentChildKey ? String(Number(state.currentChildKey) + 1) : '1',
height: state.currentChild ? ReactDOM.findDOMNode(this.refs.curr).offsetHeight : 0
height: state.currentChild ? ReactDOM.findDOMNode(this.refs.curr).offsetHeight : 0,
width: state.currentChild && this.props.changeWidth ? ReactDOM.findDOMNode(this.refs.curr).offsetWidth : null
});

// Enqueue setting the next height to trigger the height transition.
Expand All @@ -141,12 +145,18 @@ export default class ReactCSSTransitionReplace extends React.Component {
enqueueHeightTransition(nextChild, tickCount = 0) {
this.timeout = setTimeout(() => {
if (!nextChild) {
return this.setState({height: 0});
return this.setState({
height: 0,
width: this.props.changeWidth ? 0 : null
});
}

const nextNode = ReactDOM.findDOMNode(this.refs.next);
if (nextNode) {
this.setState({height: nextNode.offsetHeight});
this.setState({
height: nextNode.offsetHeight,
width: this.props.changeWidth ? nextNode.offsetWidth : null
});
}
else {
// The DOM hasn't rendered the entering element yet, so wait another tick.
Expand Down Expand Up @@ -181,7 +191,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
currentChildKey: state.nextChildKey,
nextChild: undefined,
nextChildKey: '',
height: null
height: null,
width: null
});
}

Expand All @@ -200,6 +211,7 @@ export default class ReactCSSTransitionReplace extends React.Component {
if (!this.state.nextChild) {
this.isTransitioning = false;
state.height = null;
state.width = null;
}

this.setState(state);
Expand All @@ -212,7 +224,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
return this.setState({
nextChild: undefined,
nextChildKey: '',
height: null
height: null,
width: null
});
}

Expand Down Expand Up @@ -240,11 +253,11 @@ export default class ReactCSSTransitionReplace extends React.Component {
}

render() {
const { currentChild, currentChildKey, nextChild, nextChildKey, height, isLeaving } = this.state;
const { currentChild, currentChildKey, nextChild, nextChildKey, height, width, isLeaving } = this.state;
const childrenToRender = [];

const { overflowHidden, transitionName, component,
transitionAppear, transitionEnter, transitionLeave,
transitionAppear, transitionEnter, transitionLeave, changeWidth,
transitionAppearTimeout, transitionEnterTimeout, transitionLeaveTimeout,
...containerProps } = this.props;

Expand Down Expand Up @@ -277,6 +290,10 @@ export default class ReactCSSTransitionReplace extends React.Component {
if (overflowHidden) {
containerProps.style.overflow = 'hidden';
}

if (changeWidth) {
containerProps.style.width = width;
}
}

if (nextChild) {
Expand Down