Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81155 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @typechecks
10
* @providesModule ReactCSSTransitionGroupChild
11
*/
12
13
"use strict";
14
15
var React = require('React');
16
17
var CSSCore = require('CSSCore');
18
var ReactTransitionEvents = require('ReactTransitionEvents');
19
20
var onlyChild = require('onlyChild');
21
22
// We don't remove the element from the DOM until we receive an animationend or
23
// transitionend event. If the user screws up and forgets to add an animation
24
// their node will be stuck in the DOM forever, so we detect if an animation
25
// does not start and if it doesn't, we just call the end listener immediately.
26
var TICK = 17;
27
var NO_EVENT_TIMEOUT = 5000;
28
29
var noEventListener = null;
30
31
32
if (__DEV__) {
33
noEventListener = function() {
34
console.warn(
35
'transition(): tried to perform an animation without ' +
36
'an animationend or transitionend event after timeout (' +
37
NO_EVENT_TIMEOUT + 'ms). You should either disable this ' +
38
'transition in JS or add a CSS animation/transition.'
39
);
40
};
41
}
42
43
var ReactCSSTransitionGroupChild = React.createClass({
44
displayName: 'ReactCSSTransitionGroupChild',
45
46
transition: function(animationType, finishCallback) {
47
var node = this.getDOMNode();
48
var className = this.props.name + '-' + animationType;
49
var activeClassName = className + '-active';
50
var noEventTimeout = null;
51
52
var endListener = function(e) {
53
if (e && e.target !== node) {
54
return;
55
}
56
if (__DEV__) {
57
clearTimeout(noEventTimeout);
58
}
59
60
CSSCore.removeClass(node, className);
61
CSSCore.removeClass(node, activeClassName);
62
63
ReactTransitionEvents.removeEndEventListener(node, endListener);
64
65
// Usually this optional callback is used for informing an owner of
66
// a leave animation and telling it to remove the child.
67
finishCallback && finishCallback();
68
};
69
70
ReactTransitionEvents.addEndEventListener(node, endListener);
71
72
CSSCore.addClass(node, className);
73
74
// Need to do this to actually trigger a transition.
75
this.queueClass(activeClassName);
76
77
if (__DEV__) {
78
noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT);
79
}
80
},
81
82
queueClass: function(className) {
83
this.classNameQueue.push(className);
84
85
if (!this.timeout) {
86
this.timeout = setTimeout(this.flushClassNameQueue, TICK);
87
}
88
},
89
90
flushClassNameQueue: function() {
91
if (this.isMounted()) {
92
this.classNameQueue.forEach(
93
CSSCore.addClass.bind(CSSCore, this.getDOMNode())
94
);
95
}
96
this.classNameQueue.length = 0;
97
this.timeout = null;
98
},
99
100
componentWillMount: function() {
101
this.classNameQueue = [];
102
},
103
104
componentWillUnmount: function() {
105
if (this.timeout) {
106
clearTimeout(this.timeout);
107
}
108
},
109
110
componentWillEnter: function(done) {
111
if (this.props.enter) {
112
this.transition('enter', done);
113
} else {
114
done();
115
}
116
},
117
118
componentWillLeave: function(done) {
119
if (this.props.leave) {
120
this.transition('leave', done);
121
} else {
122
done();
123
}
124
},
125
126
render: function() {
127
return onlyChild(this.props.children);
128
}
129
});
130
131
module.exports = ReactCSSTransitionGroupChild;
132
133