-
Notifications
You must be signed in to change notification settings - Fork 652
/
Copy pathReplaceTransition.js
81 lines (70 loc) · 2.3 KB
/
ReplaceTransition.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom'
import TransitionGroup from './TransitionGroup';
/**
* The `<ReplaceTransition>` component is a specialized `Transition` component
* that animates between two children.
*
* ```jsx
* <ReplaceTransition in>
* <Fade><div>I appear first</div></Fade>
* <Fade><div>I replace the above</div></Fade>
* </ReplaceTransition>
* ```
*/
class ReplaceTransition extends React.Component {
handleEnter = (...args) => this.handleLifecycle('onEnter', 0, args)
handleEntering = (...args) => this.handleLifecycle('onEntering', 0, args)
handleEntered = (...args) => this.handleLifecycle('onEntered', 0, args)
handleExit = (...args) => this.handleLifecycle('onExit', 1, args)
handleExiting = (...args) => this.handleLifecycle('onExiting', 1, args)
handleExited = (...args) => this.handleLifecycle('onExited', 1, args)
handleLifecycle(handler, idx, originalArgs) {
const { children } = this.props;
const child = React.Children.toArray(children)[idx];
if (child.props[handler]) child.props[handler](...originalArgs)
if (this.props[handler]) this.props[handler](ReactDOM.findDOMNode(this))
}
render() {
const {
children,
in: inProp,
...props
} = this.props;
const [first, second] = React.Children.toArray(children);
delete props.onEnter;
delete props.onEntering;
delete props.onEntered;
delete props.onExit;
delete props.onExiting;
delete props.onExited;
return (
<TransitionGroup {...props}>
{inProp ?
React.cloneElement(first, {
key: 'first',
onEnter: this.handleEnter,
onEntering: this.handleEntering,
onEntered: this.handleEntered,
}) :
React.cloneElement(second, {
key: 'second',
onEnter: this.handleExit,
onEntering: this.handleExiting,
onEntered: this.handleExited,
})
}
</TransitionGroup>
);
}
}
ReplaceTransition.propTypes = {
in: PropTypes.bool.isRequired,
children(props, propName) {
if (React.Children.count(props[propName]) !== 2)
return new Error(`"${propName}" must be exactly two transition components.`)
return null;
},
};
export default ReplaceTransition;