Skip to content

Commit 38b9cd2

Browse files
committed
Add changeWidth param to allow animating width
Previously it was only possible to animate the height of the component. This adds the possiblity to animate width together with height. Width change animation can be enabled by passing in `changeWidth: true` in props for the component. This change is backwards compatible.
1 parent b80520c commit 38b9cd2

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ and the new component animated in. During this process:
4848

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

51+
Additionally, `changeWidth` can be used to animate changing the width of the component. This change
52+
will happen at the same time as changing the height. Animating this change should be done using
53+
the same class name as is used for animating the change of height.
54+
5155
It is also possible to remove the child component (i.e. leave `ReactCSSTransitionReplace` with no children)
5256
which will animate the `height` going to zero along with the `leave` transition. Similarly, a single child
5357
can be added to an empty `ReactCSSTransitionReplace`, triggering the inverse animation.

src/ReactCSSTransitionReplace.jsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,17 @@ export default class ReactCSSTransitionReplace extends React.Component {
6363
transitionAppearTimeout: createTransitionTimeoutPropValidator('Appear'),
6464
transitionEnterTimeout: createTransitionTimeoutPropValidator('Enter'),
6565
transitionLeaveTimeout: createTransitionTimeoutPropValidator('Leave'),
66-
overflowHidden: React.PropTypes.bool
66+
overflowHidden: React.PropTypes.bool,
67+
changeWidth: React.PropTypes.bool
6768
};
6869

6970
static defaultProps = {
7071
transitionAppear: false,
7172
transitionEnter: true,
7273
transitionLeave: true,
7374
overflowHidden: true,
74-
component: 'span'
75+
component: 'span',
76+
changeWidth: false
7577
};
7678

7779
state = {
@@ -80,6 +82,7 @@ export default class ReactCSSTransitionReplace extends React.Component {
8082
nextChild: undefined,
8183
nextChildKey: '',
8284
height: null,
85+
width: null,
8386
isLeaving: false
8487
};
8588

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

124128
// Enqueue setting the next height to trigger the height transition.
@@ -141,12 +145,18 @@ export default class ReactCSSTransitionReplace extends React.Component {
141145
enqueueHeightTransition(nextChild, tickCount = 0) {
142146
this.timeout = setTimeout(() => {
143147
if (!nextChild) {
144-
return this.setState({height: 0});
148+
return this.setState({
149+
height: 0,
150+
width: this.props.changeWidth ? 0 : null
151+
});
145152
}
146153

147154
const nextNode = ReactDOM.findDOMNode(this.refs.next);
148155
if (nextNode) {
149-
this.setState({height: nextNode.offsetHeight});
156+
this.setState({
157+
height: nextNode.offsetHeight,
158+
width: this.props.changeWidth ? nextNode.offsetWidth : null
159+
});
150160
}
151161
else {
152162
// The DOM hasn't rendered the entering element yet, so wait another tick.
@@ -181,7 +191,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
181191
currentChildKey: state.nextChildKey,
182192
nextChild: undefined,
183193
nextChildKey: '',
184-
height: null
194+
height: null,
195+
width: null
185196
});
186197
}
187198

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

205217
this.setState(state);
@@ -212,7 +224,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
212224
return this.setState({
213225
nextChild: undefined,
214226
nextChildKey: '',
215-
height: null
227+
height: null,
228+
width: null
216229
});
217230
}
218231

@@ -240,11 +253,11 @@ export default class ReactCSSTransitionReplace extends React.Component {
240253
}
241254

242255
render() {
243-
const { currentChild, currentChildKey, nextChild, nextChildKey, height, isLeaving } = this.state;
256+
const { currentChild, currentChildKey, nextChild, nextChildKey, height, width, isLeaving } = this.state;
244257
const childrenToRender = [];
245258

246259
const { overflowHidden, transitionName, component,
247-
transitionAppear, transitionEnter, transitionLeave,
260+
transitionAppear, transitionEnter, transitionLeave, changeWidth,
248261
transitionAppearTimeout, transitionEnterTimeout, transitionLeaveTimeout,
249262
...containerProps } = this.props;
250263

@@ -277,6 +290,10 @@ export default class ReactCSSTransitionReplace extends React.Component {
277290
if (overflowHidden) {
278291
containerProps.style.overflow = 'hidden';
279292
}
293+
294+
if (changeWidth) {
295+
containerProps.style.width = width;
296+
}
280297
}
281298

282299
if (nextChild) {

0 commit comments

Comments
 (0)