UNPKG

16.6 kBJavaScriptView Raw
1function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
3function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
5function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
6function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
7function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
8function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
9function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
10function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
11function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
13import React from 'react';
14import PropTypes from 'prop-types';
15import PopperContent from './PopperContent';
16import { getTarget, targetPropType, omit, PopperPlacements, mapToCssModules, DOMElement } from './utils';
17export var propTypes = {
18 children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
19 placement: PropTypes.oneOf(PopperPlacements),
20 target: targetPropType.isRequired,
21 container: targetPropType,
22 isOpen: PropTypes.bool,
23 disabled: PropTypes.bool,
24 hideArrow: PropTypes.bool,
25 boundariesElement: PropTypes.oneOfType([PropTypes.string, DOMElement]),
26 className: PropTypes.string,
27 innerClassName: PropTypes.string,
28 arrowClassName: PropTypes.string,
29 popperClassName: PropTypes.string,
30 cssModule: PropTypes.object,
31 toggle: PropTypes.func,
32 autohide: PropTypes.bool,
33 placementPrefix: PropTypes.string,
34 delay: PropTypes.oneOfType([PropTypes.shape({
35 show: PropTypes.number,
36 hide: PropTypes.number
37 }), PropTypes.number]),
38 modifiers: PropTypes.array,
39 strategy: PropTypes.string,
40 offset: PropTypes.arrayOf(PropTypes.number),
41 innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.string, PropTypes.object]),
42 trigger: PropTypes.string,
43 fade: PropTypes.bool,
44 flip: PropTypes.bool
45};
46var DEFAULT_DELAYS = {
47 show: 0,
48 hide: 50
49};
50var defaultProps = {
51 isOpen: false,
52 hideArrow: false,
53 autohide: false,
54 delay: DEFAULT_DELAYS,
55 toggle: function toggle() {},
56 trigger: 'click',
57 fade: true
58};
59function isInDOMSubtree(element, subtreeRoot) {
60 return subtreeRoot && (element === subtreeRoot || subtreeRoot.contains(element));
61}
62function isInDOMSubtrees(element) {
63 var subtreeRoots = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
64 return subtreeRoots && subtreeRoots.length && subtreeRoots.filter(function (subTreeRoot) {
65 return isInDOMSubtree(element, subTreeRoot);
66 })[0];
67}
68var TooltipPopoverWrapper = /*#__PURE__*/function (_React$Component) {
69 _inherits(TooltipPopoverWrapper, _React$Component);
70 var _super = _createSuper(TooltipPopoverWrapper);
71 function TooltipPopoverWrapper(props) {
72 var _this;
73 _classCallCheck(this, TooltipPopoverWrapper);
74 _this = _super.call(this, props);
75 _this._targets = [];
76 _this.currentTargetElement = null;
77 _this.addTargetEvents = _this.addTargetEvents.bind(_assertThisInitialized(_this));
78 _this.handleDocumentClick = _this.handleDocumentClick.bind(_assertThisInitialized(_this));
79 _this.removeTargetEvents = _this.removeTargetEvents.bind(_assertThisInitialized(_this));
80 _this.toggle = _this.toggle.bind(_assertThisInitialized(_this));
81 _this.showWithDelay = _this.showWithDelay.bind(_assertThisInitialized(_this));
82 _this.hideWithDelay = _this.hideWithDelay.bind(_assertThisInitialized(_this));
83 _this.onMouseOverTooltipContent = _this.onMouseOverTooltipContent.bind(_assertThisInitialized(_this));
84 _this.onMouseLeaveTooltipContent = _this.onMouseLeaveTooltipContent.bind(_assertThisInitialized(_this));
85 _this.show = _this.show.bind(_assertThisInitialized(_this));
86 _this.hide = _this.hide.bind(_assertThisInitialized(_this));
87 _this.onEscKeyDown = _this.onEscKeyDown.bind(_assertThisInitialized(_this));
88 _this.getRef = _this.getRef.bind(_assertThisInitialized(_this));
89 _this.state = {
90 isOpen: props.isOpen
91 };
92 _this._isMounted = false;
93 return _this;
94 }
95 _createClass(TooltipPopoverWrapper, [{
96 key: "componentDidMount",
97 value: function componentDidMount() {
98 this._isMounted = true;
99 this.updateTarget();
100 }
101 }, {
102 key: "componentWillUnmount",
103 value: function componentWillUnmount() {
104 this._isMounted = false;
105 this.removeTargetEvents();
106 this._targets = null;
107 this.clearShowTimeout();
108 this.clearHideTimeout();
109 }
110 }, {
111 key: "handleDocumentClick",
112 value: function handleDocumentClick(e) {
113 var triggers = this.props.trigger.split(' ');
114 if (triggers.indexOf('legacy') > -1 && (this.props.isOpen || isInDOMSubtrees(e.target, this._targets))) {
115 if (this._hideTimeout) {
116 this.clearHideTimeout();
117 }
118 if (this.props.isOpen && !isInDOMSubtree(e.target, this._popover)) {
119 this.hideWithDelay(e);
120 } else if (!this.props.isOpen) {
121 this.showWithDelay(e);
122 }
123 } else if (triggers.indexOf('click') > -1 && isInDOMSubtrees(e.target, this._targets)) {
124 if (this._hideTimeout) {
125 this.clearHideTimeout();
126 }
127 if (!this.props.isOpen) {
128 this.showWithDelay(e);
129 } else {
130 this.hideWithDelay(e);
131 }
132 }
133 }
134 }, {
135 key: "onMouseOverTooltipContent",
136 value: function onMouseOverTooltipContent() {
137 if (this.props.trigger.indexOf('hover') > -1 && !this.props.autohide) {
138 if (this._hideTimeout) {
139 this.clearHideTimeout();
140 }
141 if (this.state.isOpen && !this.props.isOpen) {
142 this.toggle();
143 }
144 }
145 }
146 }, {
147 key: "onMouseLeaveTooltipContent",
148 value: function onMouseLeaveTooltipContent(e) {
149 if (this.props.trigger.indexOf('hover') > -1 && !this.props.autohide) {
150 if (this._showTimeout) {
151 this.clearShowTimeout();
152 }
153 e.persist();
154 this._hideTimeout = setTimeout(this.hide.bind(this, e), this.getDelay('hide'));
155 }
156 }
157 }, {
158 key: "onEscKeyDown",
159 value: function onEscKeyDown(e) {
160 if (e.key === 'Escape') {
161 this.hide(e);
162 }
163 }
164 }, {
165 key: "getRef",
166 value: function getRef(ref) {
167 var innerRef = this.props.innerRef;
168 if (innerRef) {
169 if (typeof innerRef === 'function') {
170 innerRef(ref);
171 } else if (_typeof(innerRef) === 'object') {
172 innerRef.current = ref;
173 }
174 }
175 this._popover = ref;
176 }
177 }, {
178 key: "getDelay",
179 value: function getDelay(key) {
180 var delay = this.props.delay;
181 if (_typeof(delay) === 'object') {
182 return isNaN(delay[key]) ? DEFAULT_DELAYS[key] : delay[key];
183 }
184 return delay;
185 }
186 }, {
187 key: "getCurrentTarget",
188 value: function getCurrentTarget(target) {
189 if (!target) return null;
190 var index = this._targets.indexOf(target);
191 if (index >= 0) return this._targets[index];
192 return this.getCurrentTarget(target.parentElement);
193 }
194 }, {
195 key: "show",
196 value: function show(e) {
197 if (!this.props.isOpen) {
198 this.clearShowTimeout();
199 this.currentTargetElement = e ? e.currentTarget || this.getCurrentTarget(e.target) : null;
200 if (e && e.composedPath && typeof e.composedPath === 'function') {
201 var path = e.composedPath();
202 this.currentTargetElement = path && path[0] || this.currentTargetElement;
203 }
204 this.toggle(e);
205 }
206 }
207 }, {
208 key: "showWithDelay",
209 value: function showWithDelay(e) {
210 if (this._hideTimeout) {
211 this.clearHideTimeout();
212 }
213 this._showTimeout = setTimeout(this.show.bind(this, e), this.getDelay('show'));
214 }
215 }, {
216 key: "hide",
217 value: function hide(e) {
218 if (this.props.isOpen) {
219 this.clearHideTimeout();
220 this.currentTargetElement = null;
221 this.toggle(e);
222 }
223 }
224 }, {
225 key: "hideWithDelay",
226 value: function hideWithDelay(e) {
227 if (this._showTimeout) {
228 this.clearShowTimeout();
229 }
230 this._hideTimeout = setTimeout(this.hide.bind(this, e), this.getDelay('hide'));
231 }
232 }, {
233 key: "clearShowTimeout",
234 value: function clearShowTimeout() {
235 clearTimeout(this._showTimeout);
236 this._showTimeout = undefined;
237 }
238 }, {
239 key: "clearHideTimeout",
240 value: function clearHideTimeout() {
241 clearTimeout(this._hideTimeout);
242 this._hideTimeout = undefined;
243 }
244 }, {
245 key: "addEventOnTargets",
246 value: function addEventOnTargets(type, handler, isBubble) {
247 this._targets.forEach(function (target) {
248 target.addEventListener(type, handler, isBubble);
249 });
250 }
251 }, {
252 key: "removeEventOnTargets",
253 value: function removeEventOnTargets(type, handler, isBubble) {
254 this._targets.forEach(function (target) {
255 target.removeEventListener(type, handler, isBubble);
256 });
257 }
258 }, {
259 key: "addTargetEvents",
260 value: function addTargetEvents() {
261 if (this.props.trigger) {
262 var triggers = this.props.trigger.split(' ');
263 if (triggers.indexOf('manual') === -1) {
264 if (triggers.indexOf('click') > -1 || triggers.indexOf('legacy') > -1) {
265 document.addEventListener('click', this.handleDocumentClick, true);
266 }
267 if (this._targets && this._targets.length) {
268 if (triggers.indexOf('hover') > -1) {
269 this.addEventOnTargets('mouseover', this.showWithDelay, true);
270 this.addEventOnTargets('mouseout', this.hideWithDelay, true);
271 }
272 if (triggers.indexOf('focus') > -1) {
273 this.addEventOnTargets('focusin', this.show, true);
274 this.addEventOnTargets('focusout', this.hide, true);
275 }
276 this.addEventOnTargets('keydown', this.onEscKeyDown, true);
277 }
278 }
279 }
280 }
281 }, {
282 key: "removeTargetEvents",
283 value: function removeTargetEvents() {
284 if (this._targets) {
285 this.removeEventOnTargets('mouseover', this.showWithDelay, true);
286 this.removeEventOnTargets('mouseout', this.hideWithDelay, true);
287 this.removeEventOnTargets('keydown', this.onEscKeyDown, true);
288 this.removeEventOnTargets('focusin', this.show, true);
289 this.removeEventOnTargets('focusout', this.hide, true);
290 }
291 document.removeEventListener('click', this.handleDocumentClick, true);
292 }
293 }, {
294 key: "updateTarget",
295 value: function updateTarget() {
296 var newTarget = getTarget(this.props.target, true);
297 if (newTarget !== this._targets) {
298 this.removeTargetEvents();
299 this._targets = newTarget ? Array.from(newTarget) : [];
300 this.currentTargetElement = this.currentTargetElement || this._targets[0];
301 this.addTargetEvents();
302 }
303 }
304 }, {
305 key: "toggle",
306 value: function toggle(e) {
307 if (this.props.disabled || !this._isMounted) {
308 return e && e.preventDefault();
309 }
310 return this.props.toggle(e);
311 }
312 }, {
313 key: "render",
314 value: function render() {
315 var _this2 = this;
316 if (this.props.isOpen) {
317 this.updateTarget();
318 }
319 var target = this.currentTargetElement || this._targets[0];
320 if (!target) {
321 return null;
322 }
323 var _this$props = this.props,
324 className = _this$props.className,
325 cssModule = _this$props.cssModule,
326 innerClassName = _this$props.innerClassName,
327 isOpen = _this$props.isOpen,
328 hideArrow = _this$props.hideArrow,
329 boundariesElement = _this$props.boundariesElement,
330 placement = _this$props.placement,
331 placementPrefix = _this$props.placementPrefix,
332 arrowClassName = _this$props.arrowClassName,
333 popperClassName = _this$props.popperClassName,
334 container = _this$props.container,
335 modifiers = _this$props.modifiers,
336 strategy = _this$props.strategy,
337 offset = _this$props.offset,
338 fade = _this$props.fade,
339 flip = _this$props.flip,
340 children = _this$props.children;
341 var attributes = omit(this.props, Object.keys(propTypes));
342 var popperClasses = mapToCssModules(popperClassName, cssModule);
343 var classes = mapToCssModules(innerClassName, cssModule);
344 return /*#__PURE__*/React.createElement(PopperContent, {
345 className: className,
346 target: target,
347 isOpen: isOpen,
348 hideArrow: hideArrow,
349 boundariesElement: boundariesElement,
350 placement: placement,
351 placementPrefix: placementPrefix,
352 arrowClassName: arrowClassName,
353 popperClassName: popperClasses,
354 container: container,
355 modifiers: modifiers,
356 strategy: strategy,
357 offset: offset,
358 cssModule: cssModule,
359 fade: fade,
360 flip: flip
361 }, function (_ref) {
362 var update = _ref.update;
363 return /*#__PURE__*/React.createElement("div", _extends({}, attributes, {
364 ref: _this2.getRef,
365 className: classes,
366 role: "tooltip",
367 onMouseOver: _this2.onMouseOverTooltipContent,
368 onMouseLeave: _this2.onMouseLeaveTooltipContent,
369 onKeyDown: _this2.onEscKeyDown
370 }), typeof children === 'function' ? children({
371 update: update
372 }) : children);
373 });
374 }
375 }], [{
376 key: "getDerivedStateFromProps",
377 value: function getDerivedStateFromProps(props, state) {
378 if (props.isOpen && !state.isOpen) {
379 return {
380 isOpen: props.isOpen
381 };
382 }
383 return null;
384 }
385 }]);
386 return TooltipPopoverWrapper;
387}(React.Component);
388TooltipPopoverWrapper.propTypes = propTypes;
389TooltipPopoverWrapper.defaultProps = defaultProps;
390export default TooltipPopoverWrapper;
\No newline at end of file