1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.propTypes = exports.default = void 0;
|
7 | var _react = _interopRequireDefault(require("react"));
|
8 | var _propTypes = _interopRequireDefault(require("prop-types"));
|
9 | var _PopperContent = _interopRequireDefault(require("./PopperContent"));
|
10 | var _utils = require("./utils");
|
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
12 | function _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); }
|
13 | const propTypes = {
|
14 | children: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
|
15 | placement: _propTypes.default.oneOf(_utils.PopperPlacements),
|
16 | target: _utils.targetPropType.isRequired,
|
17 | container: _utils.targetPropType,
|
18 | isOpen: _propTypes.default.bool,
|
19 | disabled: _propTypes.default.bool,
|
20 | hideArrow: _propTypes.default.bool,
|
21 | boundariesElement: _propTypes.default.oneOfType([_propTypes.default.string, _utils.DOMElement]),
|
22 | className: _propTypes.default.string,
|
23 | innerClassName: _propTypes.default.string,
|
24 | arrowClassName: _propTypes.default.string,
|
25 | popperClassName: _propTypes.default.string,
|
26 | cssModule: _propTypes.default.object,
|
27 | toggle: _propTypes.default.func,
|
28 | autohide: _propTypes.default.bool,
|
29 | placementPrefix: _propTypes.default.string,
|
30 | delay: _propTypes.default.oneOfType([_propTypes.default.shape({
|
31 | show: _propTypes.default.number,
|
32 | hide: _propTypes.default.number
|
33 | }), _propTypes.default.number]),
|
34 | modifiers: _propTypes.default.array,
|
35 | strategy: _propTypes.default.string,
|
36 | offset: _propTypes.default.arrayOf(_propTypes.default.number),
|
37 | innerRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string, _propTypes.default.object]),
|
38 | trigger: _propTypes.default.string,
|
39 | fade: _propTypes.default.bool,
|
40 | flip: _propTypes.default.bool
|
41 | };
|
42 | exports.propTypes = propTypes;
|
43 | const DEFAULT_DELAYS = {
|
44 | show: 0,
|
45 | hide: 50
|
46 | };
|
47 | const defaultProps = {
|
48 | isOpen: false,
|
49 | hideArrow: false,
|
50 | autohide: false,
|
51 | delay: DEFAULT_DELAYS,
|
52 | toggle: function () {},
|
53 | trigger: 'click',
|
54 | fade: true
|
55 | };
|
56 | function isInDOMSubtree(element, subtreeRoot) {
|
57 | return subtreeRoot && (element === subtreeRoot || subtreeRoot.contains(element));
|
58 | }
|
59 | function isInDOMSubtrees(element, subtreeRoots = []) {
|
60 | return subtreeRoots && subtreeRoots.length && subtreeRoots.filter(subTreeRoot => isInDOMSubtree(element, subTreeRoot))[0];
|
61 | }
|
62 | class TooltipPopoverWrapper extends _react.default.Component {
|
63 | constructor(props) {
|
64 | super(props);
|
65 | this._targets = [];
|
66 | this.currentTargetElement = null;
|
67 | this.addTargetEvents = this.addTargetEvents.bind(this);
|
68 | this.handleDocumentClick = this.handleDocumentClick.bind(this);
|
69 | this.removeTargetEvents = this.removeTargetEvents.bind(this);
|
70 | this.toggle = this.toggle.bind(this);
|
71 | this.showWithDelay = this.showWithDelay.bind(this);
|
72 | this.hideWithDelay = this.hideWithDelay.bind(this);
|
73 | this.onMouseOverTooltipContent = this.onMouseOverTooltipContent.bind(this);
|
74 | this.onMouseLeaveTooltipContent = this.onMouseLeaveTooltipContent.bind(this);
|
75 | this.show = this.show.bind(this);
|
76 | this.hide = this.hide.bind(this);
|
77 | this.onEscKeyDown = this.onEscKeyDown.bind(this);
|
78 | this.getRef = this.getRef.bind(this);
|
79 | this.state = {
|
80 | isOpen: props.isOpen
|
81 | };
|
82 | this._isMounted = false;
|
83 | }
|
84 | componentDidMount() {
|
85 | this._isMounted = true;
|
86 | this.updateTarget();
|
87 | }
|
88 | componentWillUnmount() {
|
89 | this._isMounted = false;
|
90 | this.removeTargetEvents();
|
91 | this._targets = null;
|
92 | this.clearShowTimeout();
|
93 | this.clearHideTimeout();
|
94 | }
|
95 | static getDerivedStateFromProps(props, state) {
|
96 | if (props.isOpen && !state.isOpen) {
|
97 | return {
|
98 | isOpen: props.isOpen
|
99 | };
|
100 | }
|
101 | return null;
|
102 | }
|
103 | handleDocumentClick(e) {
|
104 | const triggers = this.props.trigger.split(' ');
|
105 | if (triggers.indexOf('legacy') > -1 && (this.props.isOpen || isInDOMSubtrees(e.target, this._targets))) {
|
106 | if (this._hideTimeout) {
|
107 | this.clearHideTimeout();
|
108 | }
|
109 | if (this.props.isOpen && !isInDOMSubtree(e.target, this._popover)) {
|
110 | this.hideWithDelay(e);
|
111 | } else if (!this.props.isOpen) {
|
112 | this.showWithDelay(e);
|
113 | }
|
114 | } else if (triggers.indexOf('click') > -1 && isInDOMSubtrees(e.target, this._targets)) {
|
115 | if (this._hideTimeout) {
|
116 | this.clearHideTimeout();
|
117 | }
|
118 | if (!this.props.isOpen) {
|
119 | this.showWithDelay(e);
|
120 | } else {
|
121 | this.hideWithDelay(e);
|
122 | }
|
123 | }
|
124 | }
|
125 | onMouseOverTooltipContent() {
|
126 | if (this.props.trigger.indexOf('hover') > -1 && !this.props.autohide) {
|
127 | if (this._hideTimeout) {
|
128 | this.clearHideTimeout();
|
129 | }
|
130 | if (this.state.isOpen && !this.props.isOpen) {
|
131 | this.toggle();
|
132 | }
|
133 | }
|
134 | }
|
135 | onMouseLeaveTooltipContent(e) {
|
136 | if (this.props.trigger.indexOf('hover') > -1 && !this.props.autohide) {
|
137 | if (this._showTimeout) {
|
138 | this.clearShowTimeout();
|
139 | }
|
140 | e.persist();
|
141 | this._hideTimeout = setTimeout(this.hide.bind(this, e), this.getDelay('hide'));
|
142 | }
|
143 | }
|
144 | onEscKeyDown(e) {
|
145 | if (e.key === 'Escape') {
|
146 | this.hide(e);
|
147 | }
|
148 | }
|
149 | getRef(ref) {
|
150 | const {
|
151 | innerRef
|
152 | } = this.props;
|
153 | if (innerRef) {
|
154 | if (typeof innerRef === 'function') {
|
155 | innerRef(ref);
|
156 | } else if (typeof innerRef === 'object') {
|
157 | innerRef.current = ref;
|
158 | }
|
159 | }
|
160 | this._popover = ref;
|
161 | }
|
162 | getDelay(key) {
|
163 | const {
|
164 | delay
|
165 | } = this.props;
|
166 | if (typeof delay === 'object') {
|
167 | return isNaN(delay[key]) ? DEFAULT_DELAYS[key] : delay[key];
|
168 | }
|
169 | return delay;
|
170 | }
|
171 | getCurrentTarget(target) {
|
172 | if (!target) return null;
|
173 | const index = this._targets.indexOf(target);
|
174 | if (index >= 0) return this._targets[index];
|
175 | return this.getCurrentTarget(target.parentElement);
|
176 | }
|
177 | show(e) {
|
178 | if (!this.props.isOpen) {
|
179 | this.clearShowTimeout();
|
180 | this.currentTargetElement = e ? e.currentTarget || this.getCurrentTarget(e.target) : null;
|
181 | if (e && e.composedPath && typeof e.composedPath === 'function') {
|
182 | const path = e.composedPath();
|
183 | this.currentTargetElement = path && path[0] || this.currentTargetElement;
|
184 | }
|
185 | this.toggle(e);
|
186 | }
|
187 | }
|
188 | showWithDelay(e) {
|
189 | if (this._hideTimeout) {
|
190 | this.clearHideTimeout();
|
191 | }
|
192 | this._showTimeout = setTimeout(this.show.bind(this, e), this.getDelay('show'));
|
193 | }
|
194 | hide(e) {
|
195 | if (this.props.isOpen) {
|
196 | this.clearHideTimeout();
|
197 | this.currentTargetElement = null;
|
198 | this.toggle(e);
|
199 | }
|
200 | }
|
201 | hideWithDelay(e) {
|
202 | if (this._showTimeout) {
|
203 | this.clearShowTimeout();
|
204 | }
|
205 | this._hideTimeout = setTimeout(this.hide.bind(this, e), this.getDelay('hide'));
|
206 | }
|
207 | clearShowTimeout() {
|
208 | clearTimeout(this._showTimeout);
|
209 | this._showTimeout = undefined;
|
210 | }
|
211 | clearHideTimeout() {
|
212 | clearTimeout(this._hideTimeout);
|
213 | this._hideTimeout = undefined;
|
214 | }
|
215 | addEventOnTargets(type, handler, isBubble) {
|
216 | this._targets.forEach(target => {
|
217 | target.addEventListener(type, handler, isBubble);
|
218 | });
|
219 | }
|
220 | removeEventOnTargets(type, handler, isBubble) {
|
221 | this._targets.forEach(target => {
|
222 | target.removeEventListener(type, handler, isBubble);
|
223 | });
|
224 | }
|
225 | addTargetEvents() {
|
226 | if (this.props.trigger) {
|
227 | let triggers = this.props.trigger.split(' ');
|
228 | if (triggers.indexOf('manual') === -1) {
|
229 | if (triggers.indexOf('click') > -1 || triggers.indexOf('legacy') > -1) {
|
230 | document.addEventListener('click', this.handleDocumentClick, true);
|
231 | }
|
232 | if (this._targets && this._targets.length) {
|
233 | if (triggers.indexOf('hover') > -1) {
|
234 | this.addEventOnTargets('mouseover', this.showWithDelay, true);
|
235 | this.addEventOnTargets('mouseout', this.hideWithDelay, true);
|
236 | }
|
237 | if (triggers.indexOf('focus') > -1) {
|
238 | this.addEventOnTargets('focusin', this.show, true);
|
239 | this.addEventOnTargets('focusout', this.hide, true);
|
240 | }
|
241 | this.addEventOnTargets('keydown', this.onEscKeyDown, true);
|
242 | }
|
243 | }
|
244 | }
|
245 | }
|
246 | removeTargetEvents() {
|
247 | if (this._targets) {
|
248 | this.removeEventOnTargets('mouseover', this.showWithDelay, true);
|
249 | this.removeEventOnTargets('mouseout', this.hideWithDelay, true);
|
250 | this.removeEventOnTargets('keydown', this.onEscKeyDown, true);
|
251 | this.removeEventOnTargets('focusin', this.show, true);
|
252 | this.removeEventOnTargets('focusout', this.hide, true);
|
253 | }
|
254 | document.removeEventListener('click', this.handleDocumentClick, true);
|
255 | }
|
256 | updateTarget() {
|
257 | const newTarget = (0, _utils.getTarget)(this.props.target, true);
|
258 | if (newTarget !== this._targets) {
|
259 | this.removeTargetEvents();
|
260 | this._targets = newTarget ? Array.from(newTarget) : [];
|
261 | this.currentTargetElement = this.currentTargetElement || this._targets[0];
|
262 | this.addTargetEvents();
|
263 | }
|
264 | }
|
265 | toggle(e) {
|
266 | if (this.props.disabled || !this._isMounted) {
|
267 | return e && e.preventDefault();
|
268 | }
|
269 | return this.props.toggle(e);
|
270 | }
|
271 | render() {
|
272 | if (this.props.isOpen) {
|
273 | this.updateTarget();
|
274 | }
|
275 | const target = this.currentTargetElement || this._targets[0];
|
276 | if (!target) {
|
277 | return null;
|
278 | }
|
279 | const {
|
280 | className,
|
281 | cssModule,
|
282 | innerClassName,
|
283 | isOpen,
|
284 | hideArrow,
|
285 | boundariesElement,
|
286 | placement,
|
287 | placementPrefix,
|
288 | arrowClassName,
|
289 | popperClassName,
|
290 | container,
|
291 | modifiers,
|
292 | strategy,
|
293 | offset,
|
294 | fade,
|
295 | flip,
|
296 | children
|
297 | } = this.props;
|
298 | const attributes = (0, _utils.omit)(this.props, Object.keys(propTypes));
|
299 | const popperClasses = (0, _utils.mapToCssModules)(popperClassName, cssModule);
|
300 | const classes = (0, _utils.mapToCssModules)(innerClassName, cssModule);
|
301 | return _react.default.createElement(_PopperContent.default, {
|
302 | className: className,
|
303 | target: target,
|
304 | isOpen: isOpen,
|
305 | hideArrow: hideArrow,
|
306 | boundariesElement: boundariesElement,
|
307 | placement: placement,
|
308 | placementPrefix: placementPrefix,
|
309 | arrowClassName: arrowClassName,
|
310 | popperClassName: popperClasses,
|
311 | container: container,
|
312 | modifiers: modifiers,
|
313 | strategy: strategy,
|
314 | offset: offset,
|
315 | cssModule: cssModule,
|
316 | fade: fade,
|
317 | flip: flip
|
318 | }, ({
|
319 | update
|
320 | }) => _react.default.createElement("div", _extends({}, attributes, {
|
321 | ref: this.getRef,
|
322 | className: classes,
|
323 | role: "tooltip",
|
324 | onMouseOver: this.onMouseOverTooltipContent,
|
325 | onMouseLeave: this.onMouseLeaveTooltipContent,
|
326 | onKeyDown: this.onEscKeyDown
|
327 | }), typeof children === 'function' ? children({
|
328 | update
|
329 | }) : children));
|
330 | }
|
331 | }
|
332 | TooltipPopoverWrapper.propTypes = propTypes;
|
333 | TooltipPopoverWrapper.defaultProps = defaultProps;
|
334 | var _default = TooltipPopoverWrapper;
|
335 | exports.default = _default; |
\ | No newline at end of file |