Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80522 views
1
/**
2
* Copyright 2013-2015, 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
var warning = require("./warning");
22
23
// We don't remove the element from the DOM until we receive an animationend or
24
// transitionend event. If the user screws up and forgets to add an animation
25
// their node will be stuck in the DOM forever, so we detect if an animation
26
// does not start and if it doesn't, we just call the end listener immediately.
27
var TICK = 17;
28
var NO_EVENT_TIMEOUT = 5000;
29
30
var noEventListener = null;
31
32
33
if ("production" !== process.env.NODE_ENV) {
34
noEventListener = function() {
35
("production" !== process.env.NODE_ENV ? warning(
36
false,
37
'transition(): tried to perform an animation without ' +
38
'an animationend or transitionend event after timeout (' +
39
'%sms). You should either disable this ' +
40
'transition in JS or add a CSS animation/transition.',
41
NO_EVENT_TIMEOUT
42
) : null);
43
};
44
}
45
46
var ReactCSSTransitionGroupChild = React.createClass({
47
displayName: 'ReactCSSTransitionGroupChild',
48
49
transition: function(animationType, finishCallback) {
50
var node = this.getDOMNode();
51
var className = this.props.name + '-' + animationType;
52
var activeClassName = className + '-active';
53
var noEventTimeout = null;
54
55
var endListener = function(e) {
56
if (e && e.target !== node) {
57
return;
58
}
59
if ("production" !== process.env.NODE_ENV) {
60
clearTimeout(noEventTimeout);
61
}
62
63
CSSCore.removeClass(node, className);
64
CSSCore.removeClass(node, activeClassName);
65
66
ReactTransitionEvents.removeEndEventListener(node, endListener);
67
68
// Usually this optional callback is used for informing an owner of
69
// a leave animation and telling it to remove the child.
70
if (finishCallback) {
71
finishCallback();
72
}
73
};
74
75
ReactTransitionEvents.addEndEventListener(node, endListener);
76
77
CSSCore.addClass(node, className);
78
79
// Need to do this to actually trigger a transition.
80
this.queueClass(activeClassName);
81
82
if ("production" !== process.env.NODE_ENV) {
83
noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT);
84
}
85
},
86
87
queueClass: function(className) {
88
this.classNameQueue.push(className);
89
90
if (!this.timeout) {
91
this.timeout = setTimeout(this.flushClassNameQueue, TICK);
92
}
93
},
94
95
flushClassNameQueue: function() {
96
if (this.isMounted()) {
97
this.classNameQueue.forEach(
98
CSSCore.addClass.bind(CSSCore, this.getDOMNode())
99
);
100
}
101
this.classNameQueue.length = 0;
102
this.timeout = null;
103
},
104
105
componentWillMount: function() {
106
this.classNameQueue = [];
107
},
108
109
componentWillUnmount: function() {
110
if (this.timeout) {
111
clearTimeout(this.timeout);
112
}
113
},
114
115
componentWillAppear: function(done) {
116
if (this.props.appear) {
117
this.transition('appear', done);
118
} else {
119
done();
120
}
121
},
122
123
componentWillEnter: function(done) {
124
if (this.props.enter) {
125
this.transition('enter', done);
126
} else {
127
done();
128
}
129
},
130
131
componentWillLeave: function(done) {
132
if (this.props.leave) {
133
this.transition('leave', done);
134
} else {
135
done();
136
}
137
},
138
139
render: function() {
140
return onlyChild(this.props.children);
141
}
142
});
143
144
module.exports = ReactCSSTransitionGroupChild;
145
146