UNPKG

8.96 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
5import _inherits from 'babel-runtime/helpers/inherits';
6
7var _class, _temp;
8
9import React, { Component } from 'react';
10import PropTypes from 'prop-types';
11import { Transition } from 'react-transition-group';
12import { func, support, events, dom, guid } from '../util';
13
14var noop = function noop() {};
15var on = events.on,
16 off = events.off;
17var addClass = dom.addClass,
18 removeClass = dom.removeClass;
19
20var prefixes = ['-webkit-', '-moz-', '-o-', 'ms-', ''];
21
22function getStyleProperty(node, name) {
23 var style = window.getComputedStyle(node);
24 var ret = '';
25 for (var i = 0; i < prefixes.length; i++) {
26 ret = style.getPropertyValue(prefixes[i] + name);
27 if (ret) {
28 break;
29 }
30 }
31 return ret;
32}
33
34var AnimateChild = (_temp = _class = function (_Component) {
35 _inherits(AnimateChild, _Component);
36
37 function AnimateChild(props) {
38 _classCallCheck(this, AnimateChild);
39
40 var _this2 = _possibleConstructorReturn(this, _Component.call(this, props));
41
42 func.bindCtx(_this2, ['handleEnter', 'handleEntering', 'handleEntered', 'handleExit', 'handleExiting', 'handleExited', 'addEndListener']);
43 _this2.endListeners = {
44 transitionend: [],
45 animationend: []
46 };
47 _this2.timeoutMap = {};
48 return _this2;
49 }
50
51 AnimateChild.prototype.componentWillUnmount = function componentWillUnmount() {
52 var _this3 = this;
53
54 Object.keys(this.endListeners).forEach(function (eventName) {
55 _this3.endListeners[eventName].forEach(function (listener) {
56 off(_this3.node, eventName, listener);
57 });
58 });
59 this.endListeners = {
60 transitionend: [],
61 animationend: []
62 };
63 };
64
65 AnimateChild.prototype.generateEndListener = function generateEndListener(node, done, eventName, id) {
66 var _this = this;
67 return function endListener(e) {
68 if (e && e.target === node) {
69 if (_this.timeoutMap[id]) {
70 clearTimeout(_this.timeoutMap[id]);
71 delete _this.timeoutMap[id];
72 }
73
74 done();
75 off(node, eventName, endListener);
76 var listeners = _this.endListeners[eventName];
77 var index = listeners.indexOf(endListener);
78 index > -1 && listeners.splice(index, 1);
79 }
80 };
81 };
82
83 AnimateChild.prototype.addEndListener = function addEndListener(node, done) {
84 var _this4 = this;
85
86 if (support.transition || support.animation) {
87 var id = guid();
88
89 this.node = node;
90 if (support.transition) {
91 var transitionEndListener = this.generateEndListener(node, done, 'transitionend', id);
92 on(node, 'transitionend', transitionEndListener);
93 this.endListeners.transitionend.push(transitionEndListener);
94 }
95 if (support.animation) {
96 var animationEndListener = this.generateEndListener(node, done, 'animationend', id);
97 on(node, 'animationend', animationEndListener);
98 this.endListeners.animationend.push(animationEndListener);
99 }
100
101 setTimeout(function () {
102 var transitionDelay = parseFloat(getStyleProperty(node, 'transition-delay')) || 0;
103 var transitionDuration = parseFloat(getStyleProperty(node, 'transition-duration')) || 0;
104 var animationDelay = parseFloat(getStyleProperty(node, 'animation-delay')) || 0;
105 var animationDuration = parseFloat(getStyleProperty(node, 'animation-duration')) || 0;
106 var time = Math.max(transitionDuration + transitionDelay, animationDuration + animationDelay);
107 if (time) {
108 _this4.timeoutMap[id] = setTimeout(function () {
109 done();
110 }, time * 1000 + 200);
111 }
112 }, 15);
113 } else {
114 done();
115 }
116 };
117
118 AnimateChild.prototype.removeEndtListener = function removeEndtListener() {
119 this.transitionOff && this.transitionOff();
120 this.animationOff && this.animationOff();
121 };
122
123 AnimateChild.prototype.removeClassNames = function removeClassNames(node, names) {
124 Object.keys(names).forEach(function (key) {
125 removeClass(node, names[key]);
126 });
127 };
128
129 AnimateChild.prototype.handleEnter = function handleEnter(node, isAppearing) {
130 var names = this.props.names;
131
132 if (names) {
133 this.removeClassNames(node, names);
134 var className = isAppearing ? 'appear' : 'enter';
135 addClass(node, names[className]);
136 }
137
138 var hook = isAppearing ? this.props.onAppear : this.props.onEnter;
139 hook(node);
140 };
141
142 AnimateChild.prototype.handleEntering = function handleEntering(node, isAppearing) {
143 var _this5 = this;
144
145 setTimeout(function () {
146 var names = _this5.props.names;
147
148 if (names) {
149 var className = isAppearing ? 'appearActive' : 'enterActive';
150 addClass(node, names[className]);
151 }
152
153 var hook = isAppearing ? _this5.props.onAppearing : _this5.props.onEntering;
154 hook(node);
155 }, 10);
156 };
157
158 AnimateChild.prototype.handleEntered = function handleEntered(node, isAppearing) {
159 var names = this.props.names;
160
161 if (names) {
162 var classNames = isAppearing ? [names.appear, names.appearActive] : [names.enter, names.enterActive];
163 classNames.forEach(function (className) {
164 removeClass(node, className);
165 });
166 }
167
168 var hook = isAppearing ? this.props.onAppeared : this.props.onEntered;
169 hook(node);
170 };
171
172 AnimateChild.prototype.handleExit = function handleExit(node) {
173 var names = this.props.names;
174
175 if (names) {
176 this.removeClassNames(node, names);
177 addClass(node, names.leave);
178 }
179
180 this.props.onExit(node);
181 };
182
183 AnimateChild.prototype.handleExiting = function handleExiting(node) {
184 var _this6 = this;
185
186 setTimeout(function () {
187 var names = _this6.props.names;
188
189 if (names) {
190 addClass(node, names.leaveActive);
191 }
192 _this6.props.onExiting(node);
193 }, 10);
194 };
195
196 AnimateChild.prototype.handleExited = function handleExited(node) {
197 var names = this.props.names;
198
199 if (names) {
200 [names.leave, names.leaveActive].forEach(function (className) {
201 removeClass(node, className);
202 });
203 }
204
205 this.props.onExited(node);
206 };
207
208 AnimateChild.prototype.render = function render() {
209 /* eslint-disable no-unused-vars */
210 var _props = this.props,
211 names = _props.names,
212 onAppear = _props.onAppear,
213 onAppeared = _props.onAppeared,
214 onAppearing = _props.onAppearing,
215 onEnter = _props.onEnter,
216 onEntering = _props.onEntering,
217 onEntered = _props.onEntered,
218 onExit = _props.onExit,
219 onExiting = _props.onExiting,
220 onExited = _props.onExited,
221 others = _objectWithoutProperties(_props, ['names', 'onAppear', 'onAppeared', 'onAppearing', 'onEnter', 'onEntering', 'onEntered', 'onExit', 'onExiting', 'onExited']);
222 /* eslint-enable no-unused-vars */
223
224 return React.createElement(Transition, _extends({}, others, {
225 onEnter: this.handleEnter,
226 onEntering: this.handleEntering,
227 onEntered: this.handleEntered,
228 onExit: this.handleExit,
229 onExiting: this.handleExiting,
230 onExited: this.handleExited,
231 addEndListener: this.addEndListener
232 }));
233 };
234
235 return AnimateChild;
236}(Component), _class.propTypes = {
237 names: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
238 onAppear: PropTypes.func,
239 onAppearing: PropTypes.func,
240 onAppeared: PropTypes.func,
241 onEnter: PropTypes.func,
242 onEntering: PropTypes.func,
243 onEntered: PropTypes.func,
244 onExit: PropTypes.func,
245 onExiting: PropTypes.func,
246 onExited: PropTypes.func
247}, _class.defaultProps = {
248 onAppear: noop,
249 onAppearing: noop,
250 onAppeared: noop,
251 onEnter: noop,
252 onEntering: noop,
253 onEntered: noop,
254 onExit: noop,
255 onExiting: noop,
256 onExited: noop
257}, _temp);
258AnimateChild.displayName = 'AnimateChild';
259export { AnimateChild as default };
\No newline at end of file