forked from react-bootstrap/react-bootstrap
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCarouselItem.js
More file actions
114 lines (91 loc) · 2.45 KB
/
CarouselItem.js
File metadata and controls
114 lines (91 loc) · 2.45 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import classNames from 'classnames';
import React from 'react';
import ReactDOM from 'react-dom';
import TransitionEvents from './utils/TransitionEvents';
// TODO: This should use a timeout instead of TransitionEvents, or else just
// not wait until transition end to trigger continuing animations.
const propTypes = {
direction: React.PropTypes.oneOf(['prev', 'next']),
onAnimateOutEnd: React.PropTypes.func,
active: React.PropTypes.bool,
animateIn: React.PropTypes.bool,
animateOut: React.PropTypes.bool,
index: React.PropTypes.number,
};
const defaultProps = {
active: false,
animateIn: false,
animateOut: false,
};
class CarouselItem extends React.Component {
constructor(props, context) {
super(props, context);
this.handleAnimateOutEnd = this.handleAnimateOutEnd.bind(this);
this.state = {
direction: null,
};
this.isUnmounted = false;
}
componentWillReceiveProps(nextProps) {
if (this.props.active !== nextProps.active) {
this.setState({ direction: null });
}
}
componentDidUpdate(prevProps) {
const { active } = this.props;
const prevActive = prevProps.active;
if (!active && prevActive) {
TransitionEvents.addEndEventListener(
ReactDOM.findDOMNode(this), this.handleAnimateOutEnd
);
}
if (active !== prevActive) {
setTimeout(() => this.startAnimation(), 20);
}
}
componentWillUnmount() {
this.isUnmounted = true;
}
handleAnimateOutEnd() {
if (this.isUnmounted) {
return;
}
if (this.props.onAnimateOutEnd) {
this.props.onAnimateOutEnd(this.props.index);
}
}
startAnimation() {
if (this.isUnmounted) {
return;
}
this.setState({
direction: this.props.direction === 'prev' ? 'right' : 'left',
});
}
render() {
const {
direction, active, animateIn, animateOut, className, ...props
} = this.props;
delete props.onAnimateOutEnd;
delete props.index;
const classes = {
item: true,
active: active && !animateIn || animateOut,
};
if (direction && active && animateIn) {
classes[direction] = true;
}
if (this.state.direction && (animateIn || animateOut)) {
classes[this.state.direction] = true;
}
return (
<div
{...props}
className={classNames(className, classes)}
/>
);
}
}
CarouselItem.propTypes = propTypes;
CarouselItem.defaultProps = defaultProps;
export default CarouselItem;