1 | import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
2 | import _extends from 'babel-runtime/helpers/extends';
|
3 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
4 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
5 | import _inherits from 'babel-runtime/helpers/inherits';
|
6 |
|
7 | var _class, _temp;
|
8 |
|
9 | import React, { Component, Children } from 'react';
|
10 | import { findDOMNode } from 'react-dom';
|
11 | import { polyfill } from 'react-lifecycles-compat';
|
12 | import PropTypes from 'prop-types';
|
13 | import { func, KEYCODE } from '../util';
|
14 | import Overlay from './overlay';
|
15 |
|
16 | var noop = func.noop,
|
17 | makeChain = func.makeChain,
|
18 | bindCtx = func.bindCtx;
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | var Popup = (_temp = _class = function (_Component) {
|
26 | _inherits(Popup, _Component);
|
27 |
|
28 | function Popup(props) {
|
29 | _classCallCheck(this, Popup);
|
30 |
|
31 | var _this = _possibleConstructorReturn(this, _Component.call(this, props));
|
32 |
|
33 | _this.state = {
|
34 | visible: typeof props.visible === 'undefined' ? props.defaultVisible : props.visible
|
35 | };
|
36 |
|
37 | bindCtx(_this, ['handleTriggerClick', 'handleTriggerKeyDown', 'handleTriggerMouseEnter', 'handleTriggerMouseLeave', 'handleTriggerFocus', 'handleTriggerBlur', 'handleContentMouseEnter', 'handleContentMouseLeave', 'handleContentMouseDown', 'handleRequestClose', 'handleMaskMouseEnter', 'handleMaskMouseLeave']);
|
38 | return _this;
|
39 | }
|
40 |
|
41 | Popup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
|
42 | if ('visible' in nextProps) {
|
43 | return _extends({}, prevState, {
|
44 | visible: nextProps.visible
|
45 | });
|
46 | }
|
47 |
|
48 | return null;
|
49 | };
|
50 |
|
51 | Popup.prototype.componentWillUnmount = function componentWillUnmount() {
|
52 | var _this2 = this;
|
53 |
|
54 | ['_timer', '_hideTimer', '_showTimer'].forEach(function (time) {
|
55 | _this2[time] && clearTimeout(_this2[time]);
|
56 | });
|
57 | };
|
58 |
|
59 | Popup.prototype.handleVisibleChange = function handleVisibleChange(visible, type, e) {
|
60 | if (!('visible' in this.props)) {
|
61 | this.setState({
|
62 | visible: visible
|
63 | });
|
64 | }
|
65 |
|
66 | this.props.onVisibleChange(visible, type, e);
|
67 | };
|
68 |
|
69 | Popup.prototype.handleTriggerClick = function handleTriggerClick(e) {
|
70 | if (this.state.visible && !this.props.canCloseByTrigger) {
|
71 | return;
|
72 | }
|
73 |
|
74 | this.handleVisibleChange(!this.state.visible, 'fromTrigger', e);
|
75 | };
|
76 |
|
77 | Popup.prototype.handleTriggerKeyDown = function handleTriggerKeyDown(e) {
|
78 | var triggerClickKeycode = this.props.triggerClickKeycode;
|
79 |
|
80 | var keycodes = Array.isArray(triggerClickKeycode) ? triggerClickKeycode : [triggerClickKeycode];
|
81 | if (keycodes.includes(e.keyCode)) {
|
82 | e.preventDefault();
|
83 | this.handleTriggerClick(e);
|
84 | }
|
85 | };
|
86 |
|
87 | Popup.prototype.handleTriggerMouseEnter = function handleTriggerMouseEnter(e) {
|
88 | var _this3 = this;
|
89 |
|
90 | this._mouseNotFirstOnMask = false;
|
91 |
|
92 | if (this._hideTimer) {
|
93 | clearTimeout(this._hideTimer);
|
94 | this._hideTimer = null;
|
95 | }
|
96 | if (this._showTimer) {
|
97 | clearTimeout(this._showTimer);
|
98 | this._showTimer = null;
|
99 | }
|
100 | if (!this.state.visible) {
|
101 | this._showTimer = setTimeout(function () {
|
102 | _this3.handleVisibleChange(true, 'fromTrigger', e);
|
103 | }, this.props.delay);
|
104 | }
|
105 | };
|
106 |
|
107 | Popup.prototype.handleTriggerMouseLeave = function handleTriggerMouseLeave(e, type) {
|
108 | var _this4 = this;
|
109 |
|
110 | if (this._showTimer) {
|
111 | clearTimeout(this._showTimer);
|
112 | this._showTimer = null;
|
113 | }
|
114 | if (this.state.visible) {
|
115 | this._hideTimer = setTimeout(function () {
|
116 | _this4.handleVisibleChange(false, type || 'fromTrigger', e);
|
117 | }, this.props.delay);
|
118 | }
|
119 | };
|
120 |
|
121 | Popup.prototype.handleTriggerFocus = function handleTriggerFocus(e) {
|
122 | this.handleVisibleChange(true, 'fromTrigger', e);
|
123 | };
|
124 |
|
125 | Popup.prototype.handleTriggerBlur = function handleTriggerBlur(e) {
|
126 | if (!this._isForwardContent) {
|
127 | this.handleVisibleChange(false, 'fromTrigger', e);
|
128 | }
|
129 | this._isForwardContent = false;
|
130 | };
|
131 |
|
132 | Popup.prototype.handleContentMouseDown = function handleContentMouseDown() {
|
133 | this._isForwardContent = true;
|
134 | };
|
135 |
|
136 | Popup.prototype.handleContentMouseEnter = function handleContentMouseEnter() {
|
137 | clearTimeout(this._hideTimer);
|
138 | };
|
139 |
|
140 | Popup.prototype.handleContentMouseLeave = function handleContentMouseLeave(e) {
|
141 | this.handleTriggerMouseLeave(e, 'fromContent');
|
142 | };
|
143 |
|
144 | Popup.prototype.handleMaskMouseEnter = function handleMaskMouseEnter() {
|
145 | if (!this._mouseNotFirstOnMask) {
|
146 | clearTimeout(this._hideTimer);
|
147 | this._hideTimer = null;
|
148 | this._mouseNotFirstOnMask = false;
|
149 | }
|
150 | };
|
151 |
|
152 | Popup.prototype.handleMaskMouseLeave = function handleMaskMouseLeave() {
|
153 | this._mouseNotFirstOnMask = true;
|
154 | };
|
155 |
|
156 | Popup.prototype.handleRequestClose = function handleRequestClose(type, e) {
|
157 | this.handleVisibleChange(false, type, e);
|
158 | };
|
159 |
|
160 | Popup.prototype.renderTrigger = function renderTrigger() {
|
161 | var _this5 = this;
|
162 |
|
163 | var _props = this.props,
|
164 | trigger = _props.trigger,
|
165 | disabled = _props.disabled;
|
166 |
|
167 | var props = {
|
168 | key: 'trigger',
|
169 | 'aria-haspopup': true,
|
170 | 'aria-expanded': this.state.visible
|
171 | };
|
172 |
|
173 | if (!this.state.visible) {
|
174 | props['aria-describedby'] = undefined;
|
175 | }
|
176 |
|
177 | if (!disabled) {
|
178 | var triggerType = this.props.triggerType;
|
179 |
|
180 | var triggerTypes = Array.isArray(triggerType) ? triggerType : [triggerType];
|
181 |
|
182 | var _ref = trigger && trigger.props || {},
|
183 | onClick = _ref.onClick,
|
184 | onKeyDown = _ref.onKeyDown,
|
185 | onMouseEnter = _ref.onMouseEnter,
|
186 | onMouseLeave = _ref.onMouseLeave,
|
187 | onFocus = _ref.onFocus,
|
188 | onBlur = _ref.onBlur;
|
189 |
|
190 | triggerTypes.forEach(function (triggerType) {
|
191 | switch (triggerType) {
|
192 | case 'click':
|
193 | props.onClick = makeChain(_this5.handleTriggerClick, onClick);
|
194 | props.onKeyDown = makeChain(_this5.handleTriggerKeyDown, onKeyDown);
|
195 | break;
|
196 | case 'hover':
|
197 | props.onMouseEnter = makeChain(_this5.handleTriggerMouseEnter, onMouseEnter);
|
198 | props.onMouseLeave = makeChain(_this5.handleTriggerMouseLeave, onMouseLeave);
|
199 | break;
|
200 | case 'focus':
|
201 | props.onFocus = makeChain(_this5.handleTriggerFocus, onFocus);
|
202 | props.onBlur = makeChain(_this5.handleTriggerBlur, onBlur);
|
203 | break;
|
204 | default:
|
205 | break;
|
206 | }
|
207 | });
|
208 | }
|
209 |
|
210 | return trigger && React.cloneElement(trigger, props);
|
211 | };
|
212 |
|
213 | Popup.prototype.renderContent = function renderContent() {
|
214 | var _this6 = this;
|
215 |
|
216 | var _props2 = this.props,
|
217 | children = _props2.children,
|
218 | triggerType = _props2.triggerType;
|
219 |
|
220 | var triggerTypes = Array.isArray(triggerType) ? triggerType : [triggerType];
|
221 | var content = Children.only(children);
|
222 | var _content$props = content.props,
|
223 | onMouseDown = _content$props.onMouseDown,
|
224 | onMouseEnter = _content$props.onMouseEnter,
|
225 | onMouseLeave = _content$props.onMouseLeave;
|
226 |
|
227 | var props = {
|
228 | key: 'portal'
|
229 | };
|
230 |
|
231 | triggerTypes.forEach(function (triggerType) {
|
232 | switch (triggerType) {
|
233 | case 'focus':
|
234 | props.onMouseDown = makeChain(_this6.handleContentMouseDown, onMouseDown);
|
235 | break;
|
236 | case 'hover':
|
237 | props.onMouseEnter = makeChain(_this6.handleContentMouseEnter, onMouseEnter);
|
238 | props.onMouseLeave = makeChain(_this6.handleContentMouseLeave, onMouseLeave);
|
239 | break;
|
240 | default:
|
241 | break;
|
242 | }
|
243 | });
|
244 |
|
245 | return React.cloneElement(content, props);
|
246 | };
|
247 |
|
248 | Popup.prototype.renderPortal = function renderPortal() {
|
249 | var _this7 = this;
|
250 |
|
251 | var _props3 = this.props,
|
252 | target = _props3.target,
|
253 | safeNode = _props3.safeNode,
|
254 | followTrigger = _props3.followTrigger,
|
255 | triggerType = _props3.triggerType,
|
256 | hasMask = _props3.hasMask,
|
257 | wrapperStyle = _props3.wrapperStyle,
|
258 | others = _objectWithoutProperties(_props3, ['target', 'safeNode', 'followTrigger', 'triggerType', 'hasMask', 'wrapperStyle']);
|
259 |
|
260 | var container = this.props.container;
|
261 |
|
262 | var findTriggerNode = function findTriggerNode() {
|
263 | return findDOMNode(_this7);
|
264 | };
|
265 | var safeNodes = Array.isArray(safeNode) ? [].concat(safeNode) : [safeNode];
|
266 | safeNodes.unshift(findTriggerNode);
|
267 |
|
268 | var newWrapperStyle = wrapperStyle || {};
|
269 |
|
270 | if (followTrigger) {
|
271 | container = function container(trigger) {
|
272 | return trigger && trigger.parentNode || trigger;
|
273 | };
|
274 | newWrapperStyle.position = 'relative';
|
275 | }
|
276 |
|
277 | if (triggerType === 'hover' && hasMask) {
|
278 | others.onMaskMouseEnter = this.handleMaskMouseEnter;
|
279 | others.onMaskMouseLeave = this.handleMaskMouseLeave;
|
280 | }
|
281 |
|
282 | return React.createElement(
|
283 | Overlay,
|
284 | _extends({}, others, {
|
285 | key: 'overlay',
|
286 | ref: function ref(overlay) {
|
287 | return _this7.overlay = overlay;
|
288 | },
|
289 | visible: this.state.visible,
|
290 | target: target || findTriggerNode,
|
291 | container: container,
|
292 | safeNode: safeNodes,
|
293 | wrapperStyle: newWrapperStyle,
|
294 | triggerType: triggerType,
|
295 | hasMask: hasMask,
|
296 | onRequestClose: this.handleRequestClose
|
297 | }),
|
298 | this.props.children && this.renderContent()
|
299 | );
|
300 | };
|
301 |
|
302 | Popup.prototype.render = function render() {
|
303 | return [this.renderTrigger(), this.renderPortal()];
|
304 | };
|
305 |
|
306 | return Popup;
|
307 | }(Component), _class.propTypes = {
|
308 | |
309 |
|
310 |
|
311 | children: PropTypes.node,
|
312 | |
313 |
|
314 |
|
315 | trigger: PropTypes.element,
|
316 | |
317 |
|
318 |
|
319 | triggerType: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
320 | |
321 |
|
322 |
|
323 | triggerClickKeycode: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),
|
324 | |
325 |
|
326 |
|
327 | visible: PropTypes.bool,
|
328 | |
329 |
|
330 |
|
331 | defaultVisible: PropTypes.bool,
|
332 | |
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 | onVisibleChange: PropTypes.func,
|
339 | |
340 |
|
341 |
|
342 | disabled: PropTypes.bool,
|
343 | autoFit: PropTypes.bool,
|
344 | |
345 |
|
346 |
|
347 | delay: PropTypes.number,
|
348 | |
349 |
|
350 |
|
351 | canCloseByTrigger: PropTypes.bool,
|
352 | |
353 |
|
354 |
|
355 |
|
356 | target: PropTypes.any,
|
357 | safeNode: PropTypes.any,
|
358 | |
359 |
|
360 |
|
361 | followTrigger: PropTypes.bool,
|
362 | container: PropTypes.any,
|
363 | hasMask: PropTypes.bool,
|
364 | wrapperStyle: PropTypes.object,
|
365 | rtl: PropTypes.bool,
|
366 | |
367 |
|
368 |
|
369 | v2: PropTypes.bool,
|
370 | |
371 |
|
372 |
|
373 | placement: PropTypes.string,
|
374 | |
375 |
|
376 |
|
377 | placementOffset: PropTypes.number
|
378 | }, _class.defaultProps = {
|
379 | triggerType: 'hover',
|
380 | triggerClickKeycode: [KEYCODE.SPACE, KEYCODE.ENTER],
|
381 | defaultVisible: false,
|
382 | onVisibleChange: noop,
|
383 | disabled: false,
|
384 | autoFit: false,
|
385 | delay: 200,
|
386 | canCloseByTrigger: true,
|
387 | followTrigger: false,
|
388 | container: function container() {
|
389 | return document.body;
|
390 | },
|
391 | rtl: false
|
392 | }, _temp);
|
393 | Popup.displayName = 'Popup';
|
394 |
|
395 |
|
396 | export default polyfill(Popup); |
\ | No newline at end of file |