react-tooltip 5.26.4 → 6.0.0-beta.1179.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +3 -1
- package/beta-release.js +81 -0
- package/dist/react-tooltip.cjs +318 -477
- package/dist/react-tooltip.cjs.map +1 -1
- package/dist/react-tooltip.d.ts +5 -82
- package/dist/react-tooltip.min.cjs +3 -2
- package/dist/react-tooltip.min.cjs.map +1 -1
- package/dist/react-tooltip.min.mjs +3 -2
- package/dist/react-tooltip.min.mjs.map +1 -1
- package/dist/react-tooltip.mjs +318 -467
- package/dist/react-tooltip.mjs.map +1 -1
- package/dist/react-tooltip.umd.js +321 -480
- package/dist/react-tooltip.umd.js.map +1 -1
- package/dist/react-tooltip.umd.min.js +3 -2
- package/dist/react-tooltip.umd.min.js.map +1 -1
- package/package.json +51 -49
- package/rollup.config.dev.mjs +88 -0
- package/rollup.config.prod.mjs +126 -0
- package/rollup.config.types.mjs +21 -0
|
@@ -6,15 +6,10 @@
|
|
|
6
6
|
* @license MIT
|
|
7
7
|
*/
|
|
8
8
|
(function (global, factory) {
|
|
9
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@floating-ui/dom'), require('
|
|
10
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@floating-ui/dom', '
|
|
11
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactTooltip = {}, global.React, global.FloatingUIDOM, global.
|
|
12
|
-
})(this, (function (exports, React, dom,
|
|
13
|
-
|
|
14
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
|
-
|
|
16
|
-
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
17
|
-
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
9
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@floating-ui/dom'), require('clsx')) :
|
|
10
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', '@floating-ui/dom', 'clsx'], factory) :
|
|
11
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactTooltip = {}, global.React, global.FloatingUIDOM, global.clsx));
|
|
12
|
+
})(this, (function (exports, React, dom, clsx) { 'use strict';
|
|
18
13
|
|
|
19
14
|
// This is the ID for the core styles of ReactTooltip
|
|
20
15
|
const REACT_TOOLTIP_CORE_STYLES_ID = 'react-tooltip-core-styles';
|
|
@@ -80,28 +75,6 @@
|
|
|
80
75
|
}
|
|
81
76
|
injected[type] = true;
|
|
82
77
|
}
|
|
83
|
-
/**
|
|
84
|
-
* @deprecated Use the `disableStyleInjection` tooltip prop instead.
|
|
85
|
-
* See https://react-tooltip.com/docs/examples/styling#disabling-reacttooltip-css
|
|
86
|
-
*/
|
|
87
|
-
function removeStyle({ type = 'base', id = REACT_TOOLTIP_BASE_STYLES_ID, } = {}) {
|
|
88
|
-
if (!injected[type]) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (type === 'core') {
|
|
92
|
-
// eslint-disable-next-line no-param-reassign
|
|
93
|
-
id = REACT_TOOLTIP_CORE_STYLES_ID;
|
|
94
|
-
}
|
|
95
|
-
const style = document.getElementById(id);
|
|
96
|
-
if ((style === null || style === void 0 ? void 0 : style.tagName) === 'style') {
|
|
97
|
-
style === null || style === void 0 ? void 0 : style.remove();
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// eslint-disable-next-line no-console
|
|
101
|
-
console.warn(`[react-tooltip] Failed to remove 'style' element with id '${id}'. Call \`injectStyle()\` first`);
|
|
102
|
-
}
|
|
103
|
-
injected[type] = false;
|
|
104
|
-
}
|
|
105
78
|
|
|
106
79
|
const computeTooltipPosition = async ({ elementReference = null, tooltipReference = null, tooltipArrowReference = null, place = 'top', offset: offsetValue = 10, strategy = 'absolute', middlewares = [
|
|
107
80
|
dom.offset(Number(offsetValue)),
|
|
@@ -185,7 +158,7 @@
|
|
|
185
158
|
};
|
|
186
159
|
|
|
187
160
|
const cssTimeToMs = (time) => {
|
|
188
|
-
const match = time.match(/^([\d.]+)(
|
|
161
|
+
const match = time.match(/^([\d.]+)(m?s)$/);
|
|
189
162
|
if (!match) {
|
|
190
163
|
return 0;
|
|
191
164
|
}
|
|
@@ -205,11 +178,8 @@
|
|
|
205
178
|
const debounced = function debounced(...args) {
|
|
206
179
|
const later = () => {
|
|
207
180
|
timeout = null;
|
|
208
|
-
if (!immediate) {
|
|
209
|
-
func.apply(this, args);
|
|
210
|
-
}
|
|
211
181
|
};
|
|
212
|
-
if (
|
|
182
|
+
if (!timeout) {
|
|
213
183
|
/**
|
|
214
184
|
* there's no need to clear the timeout
|
|
215
185
|
* since we expect it to resolve and set `timeout = null`
|
|
@@ -217,12 +187,6 @@
|
|
|
217
187
|
func.apply(this, args);
|
|
218
188
|
timeout = setTimeout(later, wait);
|
|
219
189
|
}
|
|
220
|
-
if (!immediate) {
|
|
221
|
-
if (timeout) {
|
|
222
|
-
clearTimeout(timeout);
|
|
223
|
-
}
|
|
224
|
-
timeout = setTimeout(later, wait);
|
|
225
|
-
}
|
|
226
190
|
};
|
|
227
191
|
debounced.cancel = () => {
|
|
228
192
|
/* c8 ignore start */
|
|
@@ -289,111 +253,13 @@
|
|
|
289
253
|
|
|
290
254
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
291
255
|
|
|
292
|
-
const DEFAULT_TOOLTIP_ID = 'DEFAULT_TOOLTIP_ID';
|
|
293
|
-
const DEFAULT_CONTEXT_DATA = {
|
|
294
|
-
anchorRefs: new Set(),
|
|
295
|
-
activeAnchor: { current: null },
|
|
296
|
-
attach: () => {
|
|
297
|
-
/* attach anchor element */
|
|
298
|
-
},
|
|
299
|
-
detach: () => {
|
|
300
|
-
/* detach anchor element */
|
|
301
|
-
},
|
|
302
|
-
setActiveAnchor: () => {
|
|
303
|
-
/* set active anchor */
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
const DEFAULT_CONTEXT_DATA_WRAPPER = {
|
|
307
|
-
getTooltipData: () => DEFAULT_CONTEXT_DATA,
|
|
308
|
-
};
|
|
309
|
-
const TooltipContext = React.createContext(DEFAULT_CONTEXT_DATA_WRAPPER);
|
|
310
|
-
/**
|
|
311
|
-
* @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
|
|
312
|
-
* See https://react-tooltip.com/docs/getting-started
|
|
313
|
-
*/
|
|
314
|
-
const TooltipProvider = ({ children }) => {
|
|
315
|
-
const [anchorRefMap, setAnchorRefMap] = React.useState({
|
|
316
|
-
[DEFAULT_TOOLTIP_ID]: new Set(),
|
|
317
|
-
});
|
|
318
|
-
const [activeAnchorMap, setActiveAnchorMap] = React.useState({
|
|
319
|
-
[DEFAULT_TOOLTIP_ID]: { current: null },
|
|
320
|
-
});
|
|
321
|
-
const attach = (tooltipId, ...refs) => {
|
|
322
|
-
setAnchorRefMap((oldMap) => {
|
|
323
|
-
var _a;
|
|
324
|
-
const tooltipRefs = (_a = oldMap[tooltipId]) !== null && _a !== void 0 ? _a : new Set();
|
|
325
|
-
refs.forEach((ref) => tooltipRefs.add(ref));
|
|
326
|
-
// create new object to trigger re-render
|
|
327
|
-
return { ...oldMap, [tooltipId]: new Set(tooltipRefs) };
|
|
328
|
-
});
|
|
329
|
-
};
|
|
330
|
-
const detach = (tooltipId, ...refs) => {
|
|
331
|
-
setAnchorRefMap((oldMap) => {
|
|
332
|
-
const tooltipRefs = oldMap[tooltipId];
|
|
333
|
-
if (!tooltipRefs) {
|
|
334
|
-
// tooltip not found
|
|
335
|
-
// maybe thow error?
|
|
336
|
-
return oldMap;
|
|
337
|
-
}
|
|
338
|
-
refs.forEach((ref) => tooltipRefs.delete(ref));
|
|
339
|
-
// create new object to trigger re-render
|
|
340
|
-
return { ...oldMap };
|
|
341
|
-
});
|
|
342
|
-
};
|
|
343
|
-
const setActiveAnchor = (tooltipId, ref) => {
|
|
344
|
-
setActiveAnchorMap((oldMap) => {
|
|
345
|
-
var _a;
|
|
346
|
-
if (((_a = oldMap[tooltipId]) === null || _a === void 0 ? void 0 : _a.current) === ref.current) {
|
|
347
|
-
return oldMap;
|
|
348
|
-
}
|
|
349
|
-
// create new object to trigger re-render
|
|
350
|
-
return { ...oldMap, [tooltipId]: ref };
|
|
351
|
-
});
|
|
352
|
-
};
|
|
353
|
-
const getTooltipData = React.useCallback((tooltipId = DEFAULT_TOOLTIP_ID) => {
|
|
354
|
-
var _a, _b;
|
|
355
|
-
return ({
|
|
356
|
-
anchorRefs: (_a = anchorRefMap[tooltipId]) !== null && _a !== void 0 ? _a : new Set(),
|
|
357
|
-
activeAnchor: (_b = activeAnchorMap[tooltipId]) !== null && _b !== void 0 ? _b : { current: null },
|
|
358
|
-
attach: (...refs) => attach(tooltipId, ...refs),
|
|
359
|
-
detach: (...refs) => detach(tooltipId, ...refs),
|
|
360
|
-
setActiveAnchor: (ref) => setActiveAnchor(tooltipId, ref),
|
|
361
|
-
});
|
|
362
|
-
}, [anchorRefMap, activeAnchorMap, attach, detach]);
|
|
363
|
-
const context = React.useMemo(() => {
|
|
364
|
-
return {
|
|
365
|
-
getTooltipData,
|
|
366
|
-
};
|
|
367
|
-
}, [getTooltipData]);
|
|
368
|
-
return React__default["default"].createElement(TooltipContext.Provider, { value: context }, children);
|
|
369
|
-
};
|
|
370
|
-
function useTooltip(tooltipId = DEFAULT_TOOLTIP_ID) {
|
|
371
|
-
return React.useContext(TooltipContext).getTooltipData(tooltipId);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
|
|
376
|
-
* See https://react-tooltip.com/docs/getting-started
|
|
377
|
-
*/
|
|
378
|
-
const TooltipWrapper = ({ tooltipId, children, className, place, content, html, variant, offset, wrapper, events, positionStrategy, delayShow, delayHide, }) => {
|
|
379
|
-
const { attach, detach } = useTooltip(tooltipId);
|
|
380
|
-
const anchorRef = React.useRef(null);
|
|
381
|
-
React.useEffect(() => {
|
|
382
|
-
attach(anchorRef);
|
|
383
|
-
return () => {
|
|
384
|
-
detach(anchorRef);
|
|
385
|
-
};
|
|
386
|
-
}, []);
|
|
387
|
-
return (React__default["default"].createElement("span", { ref: anchorRef, className: classNames__default["default"]('react-tooltip-wrapper', className), "data-tooltip-place": place, "data-tooltip-content": content, "data-tooltip-html": html, "data-tooltip-variant": variant, "data-tooltip-offset": offset, "data-tooltip-wrapper": wrapper, "data-tooltip-events": events, "data-tooltip-position-strategy": positionStrategy, "data-tooltip-delay-show": delayShow, "data-tooltip-delay-hide": delayHide }, children));
|
|
388
|
-
};
|
|
389
|
-
|
|
390
256
|
var coreStyles = {"tooltip":"core-styles-module_tooltip__3vRRp","fixed":"core-styles-module_fixed__pcSol","arrow":"core-styles-module_arrow__cvMwQ","noArrow":"core-styles-module_noArrow__xock6","clickable":"core-styles-module_clickable__ZuTTB","show":"core-styles-module_show__Nt9eE","closing":"core-styles-module_closing__sGnxF"};
|
|
391
257
|
|
|
392
258
|
var styles = {"tooltip":"styles-module_tooltip__mnnfp","arrow":"styles-module_arrow__K0L3T","dark":"styles-module_dark__xNqje","light":"styles-module_light__Z6W-X","success":"styles-module_success__A2AKt","warning":"styles-module_warning__SCK0X","error":"styles-module_error__JvumD","info":"styles-module_info__BWdHW"};
|
|
393
259
|
|
|
394
260
|
const Tooltip = ({
|
|
395
261
|
// props
|
|
396
|
-
forwardRef, id, className, classNameArrow, variant = 'dark',
|
|
262
|
+
forwardRef, id, className, classNameArrow, variant = 'dark', anchorSelect, place = 'top', offset = 10, openOnClick = false, positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly, style: externalStyles, position, afterShow, afterHide,
|
|
397
263
|
// props handled by controller
|
|
398
264
|
content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, role = 'tooltip', }) => {
|
|
399
265
|
var _a;
|
|
@@ -412,79 +278,9 @@
|
|
|
412
278
|
const [imperativeOptions, setImperativeOptions] = React.useState(null);
|
|
413
279
|
const wasShowing = React.useRef(false);
|
|
414
280
|
const lastFloatPosition = React.useRef(null);
|
|
415
|
-
/**
|
|
416
|
-
* @todo Remove this in a future version (provider/wrapper method is deprecated)
|
|
417
|
-
*/
|
|
418
|
-
const { anchorRefs, setActiveAnchor: setProviderActiveAnchor } = useTooltip(id);
|
|
419
281
|
const hoveringTooltip = React.useRef(false);
|
|
420
|
-
const [
|
|
282
|
+
const [anchorElements, setAnchorElements] = React.useState([]);
|
|
421
283
|
const mounted = React.useRef(false);
|
|
422
|
-
/**
|
|
423
|
-
* @todo Update when deprecated stuff gets removed.
|
|
424
|
-
*/
|
|
425
|
-
const shouldOpenOnClick = openOnClick || events.includes('click');
|
|
426
|
-
const hasClickEvent = shouldOpenOnClick || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.click) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.dblclick) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.mousedown);
|
|
427
|
-
const actualOpenEvents = openEvents
|
|
428
|
-
? { ...openEvents }
|
|
429
|
-
: {
|
|
430
|
-
mouseenter: true,
|
|
431
|
-
focus: true,
|
|
432
|
-
click: false,
|
|
433
|
-
dblclick: false,
|
|
434
|
-
mousedown: false,
|
|
435
|
-
};
|
|
436
|
-
if (!openEvents && shouldOpenOnClick) {
|
|
437
|
-
Object.assign(actualOpenEvents, {
|
|
438
|
-
mouseenter: false,
|
|
439
|
-
focus: false,
|
|
440
|
-
click: true,
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
const actualCloseEvents = closeEvents
|
|
444
|
-
? { ...closeEvents }
|
|
445
|
-
: {
|
|
446
|
-
mouseleave: true,
|
|
447
|
-
blur: true,
|
|
448
|
-
click: false,
|
|
449
|
-
dblclick: false,
|
|
450
|
-
mouseup: false,
|
|
451
|
-
};
|
|
452
|
-
if (!closeEvents && shouldOpenOnClick) {
|
|
453
|
-
Object.assign(actualCloseEvents, {
|
|
454
|
-
mouseleave: false,
|
|
455
|
-
blur: false,
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
const actualGlobalCloseEvents = globalCloseEvents
|
|
459
|
-
? { ...globalCloseEvents }
|
|
460
|
-
: {
|
|
461
|
-
escape: closeOnEsc || false,
|
|
462
|
-
scroll: closeOnScroll || false,
|
|
463
|
-
resize: closeOnResize || false,
|
|
464
|
-
clickOutsideAnchor: hasClickEvent || false,
|
|
465
|
-
};
|
|
466
|
-
if (imperativeModeOnly) {
|
|
467
|
-
Object.assign(actualOpenEvents, {
|
|
468
|
-
mouseenter: false,
|
|
469
|
-
focus: false,
|
|
470
|
-
click: false,
|
|
471
|
-
dblclick: false,
|
|
472
|
-
mousedown: false,
|
|
473
|
-
});
|
|
474
|
-
Object.assign(actualCloseEvents, {
|
|
475
|
-
mouseleave: false,
|
|
476
|
-
blur: false,
|
|
477
|
-
click: false,
|
|
478
|
-
dblclick: false,
|
|
479
|
-
mouseup: false,
|
|
480
|
-
});
|
|
481
|
-
Object.assign(actualGlobalCloseEvents, {
|
|
482
|
-
escape: false,
|
|
483
|
-
scroll: false,
|
|
484
|
-
resize: false,
|
|
485
|
-
clickOutsideAnchor: false,
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
284
|
/**
|
|
489
285
|
* useLayoutEffect runs before useEffect,
|
|
490
286
|
* but should be used carefully because of caveats
|
|
@@ -496,7 +292,7 @@
|
|
|
496
292
|
mounted.current = false;
|
|
497
293
|
};
|
|
498
294
|
}, []);
|
|
499
|
-
const handleShow = (value) => {
|
|
295
|
+
const handleShow = React.useCallback((value) => {
|
|
500
296
|
if (!mounted.current) {
|
|
501
297
|
return;
|
|
502
298
|
}
|
|
@@ -516,7 +312,7 @@
|
|
|
516
312
|
setShow(value);
|
|
517
313
|
}
|
|
518
314
|
}, 10);
|
|
519
|
-
};
|
|
315
|
+
}, [isOpen, setIsOpen]);
|
|
520
316
|
/**
|
|
521
317
|
* this replicates the effect from `handleShow()`
|
|
522
318
|
* when `isOpen` is changed from outside
|
|
@@ -563,13 +359,13 @@
|
|
|
563
359
|
// +25ms just to make sure `onTransitionEnd` (if it gets fired) has time to run
|
|
564
360
|
}, transitionShowDelay + 25);
|
|
565
361
|
}
|
|
566
|
-
}, [show]);
|
|
362
|
+
}, [afterHide, afterShow, show]);
|
|
567
363
|
const handleComputedPosition = (newComputedPosition) => {
|
|
568
364
|
setComputedPosition((oldComputedPosition) => deepEqual(oldComputedPosition, newComputedPosition)
|
|
569
365
|
? oldComputedPosition
|
|
570
366
|
: newComputedPosition);
|
|
571
367
|
};
|
|
572
|
-
const handleShowTooltipDelayed = (delay = delayShow) => {
|
|
368
|
+
const handleShowTooltipDelayed = React.useCallback((delay = delayShow) => {
|
|
573
369
|
if (tooltipShowDelayTimerRef.current) {
|
|
574
370
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
575
371
|
}
|
|
@@ -581,8 +377,8 @@
|
|
|
581
377
|
tooltipShowDelayTimerRef.current = setTimeout(() => {
|
|
582
378
|
handleShow(true);
|
|
583
379
|
}, delay);
|
|
584
|
-
};
|
|
585
|
-
const handleHideTooltipDelayed = (delay = delayHide) => {
|
|
380
|
+
}, [delayShow, handleShow, rendered]);
|
|
381
|
+
const handleHideTooltipDelayed = React.useCallback((delay = delayHide) => {
|
|
586
382
|
if (tooltipHideDelayTimerRef.current) {
|
|
587
383
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
588
384
|
}
|
|
@@ -592,50 +388,8 @@
|
|
|
592
388
|
}
|
|
593
389
|
handleShow(false);
|
|
594
390
|
}, delay);
|
|
595
|
-
};
|
|
596
|
-
const
|
|
597
|
-
var _a;
|
|
598
|
-
if (!event) {
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
const target = ((_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target);
|
|
602
|
-
if (!(target === null || target === void 0 ? void 0 : target.isConnected)) {
|
|
603
|
-
/**
|
|
604
|
-
* this happens when the target is removed from the DOM
|
|
605
|
-
* at the same time the tooltip gets triggered
|
|
606
|
-
*/
|
|
607
|
-
setActiveAnchor(null);
|
|
608
|
-
setProviderActiveAnchor({ current: null });
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
if (delayShow) {
|
|
612
|
-
handleShowTooltipDelayed();
|
|
613
|
-
}
|
|
614
|
-
else {
|
|
615
|
-
handleShow(true);
|
|
616
|
-
}
|
|
617
|
-
setActiveAnchor(target);
|
|
618
|
-
setProviderActiveAnchor({ current: target });
|
|
619
|
-
if (tooltipHideDelayTimerRef.current) {
|
|
620
|
-
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
621
|
-
}
|
|
622
|
-
};
|
|
623
|
-
const handleHideTooltip = () => {
|
|
624
|
-
if (clickable) {
|
|
625
|
-
// allow time for the mouse to reach the tooltip, in case there's a gap
|
|
626
|
-
handleHideTooltipDelayed(delayHide || 100);
|
|
627
|
-
}
|
|
628
|
-
else if (delayHide) {
|
|
629
|
-
handleHideTooltipDelayed();
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
handleShow(false);
|
|
633
|
-
}
|
|
634
|
-
if (tooltipShowDelayTimerRef.current) {
|
|
635
|
-
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
const handleTooltipPosition = ({ x, y }) => {
|
|
391
|
+
}, [delayHide, handleShow]);
|
|
392
|
+
const handleTooltipPosition = React.useCallback(({ x, y }) => {
|
|
639
393
|
var _a;
|
|
640
394
|
const virtualElement = {
|
|
641
395
|
getBoundingClientRect() {
|
|
@@ -663,58 +417,7 @@
|
|
|
663
417
|
}).then((computedStylesData) => {
|
|
664
418
|
handleComputedPosition(computedStylesData);
|
|
665
419
|
});
|
|
666
|
-
};
|
|
667
|
-
const handlePointerMove = (event) => {
|
|
668
|
-
if (!event) {
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
const mouseEvent = event;
|
|
672
|
-
const mousePosition = {
|
|
673
|
-
x: mouseEvent.clientX,
|
|
674
|
-
y: mouseEvent.clientY,
|
|
675
|
-
};
|
|
676
|
-
handleTooltipPosition(mousePosition);
|
|
677
|
-
lastFloatPosition.current = mousePosition;
|
|
678
|
-
};
|
|
679
|
-
const handleClickOutsideAnchors = (event) => {
|
|
680
|
-
var _a;
|
|
681
|
-
if (!show) {
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
const target = event.target;
|
|
685
|
-
if (!target.isConnected) {
|
|
686
|
-
return;
|
|
687
|
-
}
|
|
688
|
-
if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
|
|
689
|
-
return;
|
|
690
|
-
}
|
|
691
|
-
const anchorById = document.querySelector(`[id='${anchorId}']`);
|
|
692
|
-
const anchors = [anchorById, ...anchorsBySelect];
|
|
693
|
-
if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
handleShow(false);
|
|
697
|
-
if (tooltipShowDelayTimerRef.current) {
|
|
698
|
-
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
// debounce handler to prevent call twice when
|
|
702
|
-
// mouse enter and focus events being triggered toggether
|
|
703
|
-
const internalDebouncedHandleShowTooltip = debounce(handleShowTooltip, 50, true);
|
|
704
|
-
const internalDebouncedHandleHideTooltip = debounce(handleHideTooltip, 50, true);
|
|
705
|
-
// If either of the functions is called while the other is still debounced,
|
|
706
|
-
// reset the timeout. Otherwise if there is a sub-50ms (leave A, enter B, leave B)
|
|
707
|
-
// sequence of events, the tooltip will stay open because the hide debounce
|
|
708
|
-
// from leave A prevented the leave B event from calling it, leaving the
|
|
709
|
-
// tooltip visible.
|
|
710
|
-
const debouncedHandleShowTooltip = (e) => {
|
|
711
|
-
internalDebouncedHandleHideTooltip.cancel();
|
|
712
|
-
internalDebouncedHandleShowTooltip(e);
|
|
713
|
-
};
|
|
714
|
-
const debouncedHandleHideTooltip = () => {
|
|
715
|
-
internalDebouncedHandleShowTooltip.cancel();
|
|
716
|
-
internalDebouncedHandleHideTooltip();
|
|
717
|
-
};
|
|
420
|
+
}, [imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place, place, offset, positionStrategy, middlewares, border]);
|
|
718
421
|
const updateTooltipPosition = React.useCallback(() => {
|
|
719
422
|
var _a, _b;
|
|
720
423
|
const actualPosition = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position) !== null && _a !== void 0 ? _a : position;
|
|
@@ -757,33 +460,184 @@
|
|
|
757
460
|
handleComputedPosition(computedStylesData);
|
|
758
461
|
});
|
|
759
462
|
}, [
|
|
760
|
-
|
|
463
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
|
|
464
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
465
|
+
position,
|
|
466
|
+
float,
|
|
761
467
|
activeAnchor,
|
|
762
|
-
content,
|
|
763
|
-
externalStyles,
|
|
764
468
|
place,
|
|
765
|
-
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
766
469
|
offset,
|
|
767
470
|
positionStrategy,
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
471
|
+
middlewares,
|
|
472
|
+
border,
|
|
473
|
+
handleTooltipPosition,
|
|
771
474
|
]);
|
|
772
475
|
React.useEffect(() => {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
476
|
+
/**
|
|
477
|
+
* TODO(V6): break this effect down into callbacks for clarity
|
|
478
|
+
* - `handleKeyboardEvents()`
|
|
479
|
+
* - `handleMouseEvents()`
|
|
480
|
+
* - `handleGlobalCloseEvents()`
|
|
481
|
+
* - `handleAnchorEvents()`
|
|
482
|
+
* - ...
|
|
483
|
+
*/
|
|
484
|
+
const handlePointerMove = (event) => {
|
|
485
|
+
if (!event) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const mouseEvent = event;
|
|
489
|
+
const mousePosition = {
|
|
490
|
+
x: mouseEvent.clientX,
|
|
491
|
+
y: mouseEvent.clientY,
|
|
492
|
+
};
|
|
493
|
+
handleTooltipPosition(mousePosition);
|
|
494
|
+
lastFloatPosition.current = mousePosition;
|
|
495
|
+
};
|
|
496
|
+
const handleClickOutsideAnchors = (event) => {
|
|
497
|
+
var _a;
|
|
498
|
+
if (!show) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const target = event.target;
|
|
502
|
+
if (!target.isConnected) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (anchorElements.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
handleShow(false);
|
|
512
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
513
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const handleShowTooltip = (event) => {
|
|
517
|
+
var _a;
|
|
518
|
+
if (!event) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const target = ((_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target);
|
|
522
|
+
if (!(target === null || target === void 0 ? void 0 : target.isConnected)) {
|
|
523
|
+
/**
|
|
524
|
+
* this happens when the target is removed from the DOM
|
|
525
|
+
* at the same time the tooltip gets triggered
|
|
526
|
+
*/
|
|
527
|
+
setActiveAnchor(null);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
if (delayShow) {
|
|
531
|
+
handleShowTooltipDelayed();
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
handleShow(true);
|
|
535
|
+
}
|
|
536
|
+
setActiveAnchor(target);
|
|
537
|
+
if (tooltipHideDelayTimerRef.current) {
|
|
538
|
+
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
const handleHideTooltip = () => {
|
|
542
|
+
if (clickable) {
|
|
543
|
+
// allow time for the mouse to reach the tooltip, in case there's a gap
|
|
544
|
+
handleHideTooltipDelayed(delayHide || 100);
|
|
545
|
+
}
|
|
546
|
+
else if (delayHide) {
|
|
547
|
+
handleHideTooltipDelayed();
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
handleShow(false);
|
|
551
|
+
}
|
|
552
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
553
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
// debounce handler to prevent call twice when
|
|
557
|
+
// mouse enter and focus events being triggered toggether
|
|
558
|
+
const internalDebouncedHandleShowTooltip = debounce(handleShowTooltip, 50);
|
|
559
|
+
const internalDebouncedHandleHideTooltip = debounce(handleHideTooltip, 50);
|
|
560
|
+
// If either of the functions is called while the other is still debounced,
|
|
561
|
+
// reset the timeout. Otherwise if there is a sub-50ms (leave A, enter B, leave B)
|
|
562
|
+
// sequence of events, the tooltip will stay open because the hide debounce
|
|
563
|
+
// from leave A prevented the leave B event from calling it, leaving the
|
|
564
|
+
// tooltip visible.
|
|
565
|
+
const debouncedHandleShowTooltip = (e) => {
|
|
566
|
+
internalDebouncedHandleHideTooltip.cancel();
|
|
567
|
+
internalDebouncedHandleShowTooltip(e);
|
|
568
|
+
};
|
|
569
|
+
const debouncedHandleHideTooltip = () => {
|
|
570
|
+
internalDebouncedHandleShowTooltip.cancel();
|
|
571
|
+
internalDebouncedHandleHideTooltip();
|
|
572
|
+
};
|
|
782
573
|
const handleScrollResize = () => {
|
|
783
574
|
handleShow(false);
|
|
784
575
|
};
|
|
785
|
-
const
|
|
576
|
+
const hasClickEvent = openOnClick || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.click) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.dblclick) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.mousedown);
|
|
577
|
+
const actualOpenEvents = openEvents
|
|
578
|
+
? { ...openEvents }
|
|
579
|
+
: {
|
|
580
|
+
mouseenter: true,
|
|
581
|
+
focus: true,
|
|
582
|
+
click: false,
|
|
583
|
+
dblclick: false,
|
|
584
|
+
mousedown: false,
|
|
585
|
+
};
|
|
586
|
+
if (!openEvents && openOnClick) {
|
|
587
|
+
Object.assign(actualOpenEvents, {
|
|
588
|
+
mouseenter: false,
|
|
589
|
+
focus: false,
|
|
590
|
+
click: true,
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
const actualCloseEvents = closeEvents
|
|
594
|
+
? { ...closeEvents }
|
|
595
|
+
: {
|
|
596
|
+
mouseleave: true,
|
|
597
|
+
blur: true,
|
|
598
|
+
click: false,
|
|
599
|
+
dblclick: false,
|
|
600
|
+
mouseup: false,
|
|
601
|
+
};
|
|
602
|
+
if (!closeEvents && openOnClick) {
|
|
603
|
+
Object.assign(actualCloseEvents, {
|
|
604
|
+
mouseleave: false,
|
|
605
|
+
blur: false,
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
const actualGlobalCloseEvents = globalCloseEvents
|
|
609
|
+
? { ...globalCloseEvents }
|
|
610
|
+
: {
|
|
611
|
+
escape: false,
|
|
612
|
+
scroll: false,
|
|
613
|
+
resize: false,
|
|
614
|
+
clickOutsideAnchor: hasClickEvent || false,
|
|
615
|
+
};
|
|
616
|
+
if (imperativeModeOnly) {
|
|
617
|
+
Object.assign(actualOpenEvents, {
|
|
618
|
+
mouseenter: false,
|
|
619
|
+
focus: false,
|
|
620
|
+
click: false,
|
|
621
|
+
dblclick: false,
|
|
622
|
+
mousedown: false,
|
|
623
|
+
});
|
|
624
|
+
Object.assign(actualCloseEvents, {
|
|
625
|
+
mouseleave: false,
|
|
626
|
+
blur: false,
|
|
627
|
+
click: false,
|
|
628
|
+
dblclick: false,
|
|
629
|
+
mouseup: false,
|
|
630
|
+
});
|
|
631
|
+
Object.assign(actualGlobalCloseEvents, {
|
|
632
|
+
escape: false,
|
|
633
|
+
scroll: false,
|
|
634
|
+
resize: false,
|
|
635
|
+
clickOutsideAnchor: false,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
const tooltipElement = tooltipRef.current;
|
|
786
639
|
const tooltipScrollParent = getScrollParent(tooltipRef.current);
|
|
640
|
+
const anchorScrollParent = getScrollParent(activeAnchor);
|
|
787
641
|
if (actualGlobalCloseEvents.scroll) {
|
|
788
642
|
window.addEventListener('scroll', handleScrollResize);
|
|
789
643
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
|
|
@@ -876,17 +730,15 @@
|
|
|
876
730
|
if (clickable && !hasClickEvent) {
|
|
877
731
|
// used to keep the tooltip open when hovering content.
|
|
878
732
|
// not needed if using click events.
|
|
879
|
-
|
|
880
|
-
|
|
733
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseenter', handleMouseEnterTooltip);
|
|
734
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
881
735
|
}
|
|
882
736
|
enabledEvents.forEach(({ event, listener }) => {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener(event, listener);
|
|
737
|
+
anchorElements.forEach((anchor) => {
|
|
738
|
+
anchor.addEventListener(event, listener);
|
|
886
739
|
});
|
|
887
740
|
});
|
|
888
741
|
return () => {
|
|
889
|
-
var _a, _b;
|
|
890
742
|
if (actualGlobalCloseEvents.scroll) {
|
|
891
743
|
window.removeEventListener('scroll', handleScrollResize);
|
|
892
744
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
|
|
@@ -905,13 +757,12 @@
|
|
|
905
757
|
window.removeEventListener('keydown', handleEsc);
|
|
906
758
|
}
|
|
907
759
|
if (clickable && !hasClickEvent) {
|
|
908
|
-
|
|
909
|
-
|
|
760
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseenter', handleMouseEnterTooltip);
|
|
761
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
910
762
|
}
|
|
911
763
|
enabledEvents.forEach(({ event, listener }) => {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, listener);
|
|
764
|
+
anchorElements.forEach((anchor) => {
|
|
765
|
+
anchor.removeEventListener(event, listener);
|
|
915
766
|
});
|
|
916
767
|
});
|
|
917
768
|
};
|
|
@@ -921,61 +772,62 @@
|
|
|
921
772
|
*/
|
|
922
773
|
}, [
|
|
923
774
|
activeAnchor,
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
anchorRefs,
|
|
927
|
-
anchorsBySelect,
|
|
928
|
-
// the effect uses the `actual*Events` objects, but this should work
|
|
929
|
-
openEvents,
|
|
775
|
+
anchorElements,
|
|
776
|
+
clickable,
|
|
930
777
|
closeEvents,
|
|
931
|
-
globalCloseEvents,
|
|
932
|
-
shouldOpenOnClick,
|
|
933
|
-
delayShow,
|
|
934
778
|
delayHide,
|
|
779
|
+
delayShow,
|
|
780
|
+
float,
|
|
781
|
+
globalCloseEvents,
|
|
782
|
+
handleHideTooltipDelayed,
|
|
783
|
+
handleShow,
|
|
784
|
+
handleShowTooltipDelayed,
|
|
785
|
+
handleTooltipPosition,
|
|
786
|
+
imperativeModeOnly,
|
|
787
|
+
openEvents,
|
|
788
|
+
openOnClick,
|
|
789
|
+
setActiveAnchor,
|
|
790
|
+
show,
|
|
791
|
+
updateTooltipPosition,
|
|
935
792
|
]);
|
|
936
793
|
React.useEffect(() => {
|
|
937
794
|
var _a, _b;
|
|
795
|
+
/**
|
|
796
|
+
* TODO(V6): break down observer callback for clarity
|
|
797
|
+
* - `handleAddedAnchors()`
|
|
798
|
+
* - `handleRemovedAnchors()`
|
|
799
|
+
*/
|
|
938
800
|
let selector = (_b = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect) !== null && _b !== void 0 ? _b : '';
|
|
939
801
|
if (!selector && id) {
|
|
940
802
|
selector = `[data-tooltip-id='${id.replace(/'/g, "\\'")}']`;
|
|
941
803
|
}
|
|
942
804
|
const documentObserverCallback = (mutationList) => {
|
|
943
|
-
const
|
|
944
|
-
const removedAnchors =
|
|
805
|
+
const addedAnchors = new Set();
|
|
806
|
+
const removedAnchors = new Set();
|
|
945
807
|
mutationList.forEach((mutation) => {
|
|
946
808
|
if (mutation.type === 'attributes' && mutation.attributeName === 'data-tooltip-id') {
|
|
947
|
-
const
|
|
809
|
+
const target = mutation.target;
|
|
810
|
+
const newId = target.getAttribute('data-tooltip-id');
|
|
948
811
|
if (newId === id) {
|
|
949
|
-
|
|
812
|
+
addedAnchors.add(target);
|
|
950
813
|
}
|
|
951
814
|
else if (mutation.oldValue === id) {
|
|
952
815
|
// data-tooltip-id has now been changed, so we need to remove this anchor
|
|
953
|
-
removedAnchors.
|
|
816
|
+
removedAnchors.add(target);
|
|
954
817
|
}
|
|
955
818
|
}
|
|
956
819
|
if (mutation.type !== 'childList') {
|
|
957
820
|
return;
|
|
958
821
|
}
|
|
822
|
+
const removedNodes = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
|
|
959
823
|
if (activeAnchor) {
|
|
960
|
-
|
|
961
|
-
if (selector) {
|
|
962
|
-
try {
|
|
963
|
-
removedAnchors.push(
|
|
964
|
-
// the element itself is an anchor
|
|
965
|
-
...elements.filter((element) => element.matches(selector)));
|
|
966
|
-
removedAnchors.push(
|
|
967
|
-
// the element has children which are anchors
|
|
968
|
-
...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
|
|
969
|
-
}
|
|
970
|
-
catch (_a) {
|
|
971
|
-
/**
|
|
972
|
-
* invalid CSS selector.
|
|
973
|
-
* already warned on tooltip controller
|
|
974
|
-
*/
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
elements.some((node) => {
|
|
824
|
+
removedNodes.some((node) => {
|
|
978
825
|
var _a;
|
|
826
|
+
/**
|
|
827
|
+
* TODO(V6)
|
|
828
|
+
* - isn't `!activeAnchor.isConnected` better?
|
|
829
|
+
* - maybe move to `handleDisconnectedAnchor()`
|
|
830
|
+
*/
|
|
979
831
|
if ((_a = node === null || node === void 0 ? void 0 : node.contains) === null || _a === void 0 ? void 0 : _a.call(node, activeAnchor)) {
|
|
980
832
|
setRendered(false);
|
|
981
833
|
handleShow(false);
|
|
@@ -995,25 +847,67 @@
|
|
|
995
847
|
return;
|
|
996
848
|
}
|
|
997
849
|
try {
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
850
|
+
removedNodes.forEach((node) => {
|
|
851
|
+
const element = node;
|
|
852
|
+
if (element.matches(selector)) {
|
|
853
|
+
// the element itself is an anchor
|
|
854
|
+
removedAnchors.add(element);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
/**
|
|
858
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
859
|
+
* has children which are also anchors?
|
|
860
|
+
* (i.e. should we remove `else` and always do this)
|
|
861
|
+
*/
|
|
862
|
+
// the element has children which are anchors
|
|
863
|
+
element
|
|
864
|
+
.querySelectorAll(selector)
|
|
865
|
+
.forEach((innerNode) => removedAnchors.add(innerNode));
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
catch (_a) {
|
|
870
|
+
/* c8 ignore start */
|
|
871
|
+
{
|
|
872
|
+
// eslint-disable-next-line no-console
|
|
873
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
874
|
+
}
|
|
875
|
+
/* c8 ignore end */
|
|
876
|
+
}
|
|
877
|
+
try {
|
|
878
|
+
const addedNodes = [...mutation.addedNodes].filter((node) => node.nodeType === 1);
|
|
879
|
+
addedNodes.forEach((node) => {
|
|
880
|
+
const element = node;
|
|
881
|
+
if (element.matches(selector)) {
|
|
882
|
+
// the element itself is an anchor
|
|
883
|
+
addedAnchors.add(element);
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
/**
|
|
887
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
888
|
+
* has children which are also anchors?
|
|
889
|
+
* (i.e. should we remove `else` and always do this)
|
|
890
|
+
*/
|
|
891
|
+
// the element has children which are anchors
|
|
892
|
+
element
|
|
893
|
+
.querySelectorAll(selector)
|
|
894
|
+
.forEach((innerNode) => addedAnchors.add(innerNode));
|
|
895
|
+
}
|
|
896
|
+
});
|
|
1005
897
|
}
|
|
1006
898
|
catch (_b) {
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
899
|
+
/* c8 ignore start */
|
|
900
|
+
{
|
|
901
|
+
// eslint-disable-next-line no-console
|
|
902
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
903
|
+
}
|
|
904
|
+
/* c8 ignore end */
|
|
1011
905
|
}
|
|
1012
906
|
});
|
|
1013
|
-
if (
|
|
1014
|
-
|
|
1015
|
-
...anchors.filter((anchor) => !removedAnchors.
|
|
1016
|
-
...
|
|
907
|
+
if (addedAnchors.size || removedAnchors.size) {
|
|
908
|
+
setAnchorElements((anchors) => [
|
|
909
|
+
...anchors.filter((anchor) => !removedAnchors.has(anchor)),
|
|
910
|
+
...addedAnchors,
|
|
1017
911
|
]);
|
|
1018
912
|
}
|
|
1019
913
|
};
|
|
@@ -1030,7 +924,7 @@
|
|
|
1030
924
|
return () => {
|
|
1031
925
|
documentObserver.disconnect();
|
|
1032
926
|
};
|
|
1033
|
-
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor]);
|
|
927
|
+
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor, handleShow, setActiveAnchor]);
|
|
1034
928
|
React.useEffect(() => {
|
|
1035
929
|
updateTooltipPosition();
|
|
1036
930
|
}, [updateTooltipPosition]);
|
|
@@ -1045,20 +939,18 @@
|
|
|
1045
939
|
return () => {
|
|
1046
940
|
contentObserver.disconnect();
|
|
1047
941
|
};
|
|
1048
|
-
}, [content, contentWrapperRef
|
|
942
|
+
}, [content, contentWrapperRef, updateTooltipPosition]);
|
|
1049
943
|
React.useEffect(() => {
|
|
1050
944
|
var _a;
|
|
1051
|
-
|
|
1052
|
-
const anchors = [...anchorsBySelect, anchorById];
|
|
1053
|
-
if (!activeAnchor || !anchors.includes(activeAnchor)) {
|
|
945
|
+
if (!activeAnchor || !anchorElements.includes(activeAnchor)) {
|
|
1054
946
|
/**
|
|
1055
947
|
* if there is no active anchor,
|
|
1056
948
|
* or if the current active anchor is not amongst the allowed ones,
|
|
1057
949
|
* reset it
|
|
1058
950
|
*/
|
|
1059
|
-
setActiveAnchor((_a =
|
|
951
|
+
setActiveAnchor((_a = anchorElements[0]) !== null && _a !== void 0 ? _a : null);
|
|
1060
952
|
}
|
|
1061
|
-
}, [
|
|
953
|
+
}, [anchorElements, activeAnchor, setActiveAnchor]);
|
|
1062
954
|
React.useEffect(() => {
|
|
1063
955
|
if (defaultIsOpen) {
|
|
1064
956
|
handleShow(true);
|
|
@@ -1071,7 +963,7 @@
|
|
|
1071
963
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
1072
964
|
}
|
|
1073
965
|
};
|
|
1074
|
-
}, []);
|
|
966
|
+
}, [defaultIsOpen, handleShow]);
|
|
1075
967
|
React.useEffect(() => {
|
|
1076
968
|
var _a;
|
|
1077
969
|
let selector = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect;
|
|
@@ -1083,11 +975,11 @@
|
|
|
1083
975
|
}
|
|
1084
976
|
try {
|
|
1085
977
|
const anchors = Array.from(document.querySelectorAll(selector));
|
|
1086
|
-
|
|
978
|
+
setAnchorElements(anchors);
|
|
1087
979
|
}
|
|
1088
980
|
catch (_b) {
|
|
1089
981
|
// warning was already issued in the controller
|
|
1090
|
-
|
|
982
|
+
setAnchorElements([]);
|
|
1091
983
|
}
|
|
1092
984
|
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect]);
|
|
1093
985
|
React.useEffect(() => {
|
|
@@ -1095,7 +987,7 @@
|
|
|
1095
987
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
1096
988
|
handleShowTooltipDelayed(delayShow);
|
|
1097
989
|
}
|
|
1098
|
-
}, [delayShow]);
|
|
990
|
+
}, [delayShow, handleShowTooltipDelayed]);
|
|
1099
991
|
const actualContent = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.content) !== null && _a !== void 0 ? _a : content;
|
|
1100
992
|
const canShow = show && Object.keys(computedPosition.tooltipStyles).length > 0;
|
|
1101
993
|
React.useImperativeHandle(forwardRef, () => ({
|
|
@@ -1132,7 +1024,7 @@
|
|
|
1132
1024
|
place: computedPosition.place,
|
|
1133
1025
|
isOpen: Boolean(rendered && !hidden && actualContent && canShow),
|
|
1134
1026
|
}));
|
|
1135
|
-
return rendered && !hidden && actualContent ? (
|
|
1027
|
+
return rendered && !hidden && actualContent ? (React.createElement(WrapperElement, { id: id, role: role, className: clsx('react-tooltip', coreStyles['tooltip'], styles['tooltip'], styles[variant], className, `react-tooltip__place-${computedPosition.place}`, coreStyles[canShow ? 'show' : 'closing'], canShow ? 'react-tooltip__show' : 'react-tooltip__closing', positionStrategy === 'fixed' && coreStyles['fixed'], clickable && coreStyles['clickable']), onTransitionEnd: (event) => {
|
|
1136
1028
|
if (missedTransitionTimerRef.current) {
|
|
1137
1029
|
clearTimeout(missedTransitionTimerRef.current);
|
|
1138
1030
|
}
|
|
@@ -1148,7 +1040,7 @@
|
|
|
1148
1040
|
opacity: opacity !== undefined && canShow ? opacity : undefined,
|
|
1149
1041
|
}, ref: tooltipRef },
|
|
1150
1042
|
actualContent,
|
|
1151
|
-
|
|
1043
|
+
React.createElement(WrapperElement, { className: clsx('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
|
|
1152
1044
|
...computedPosition.tooltipArrowStyles,
|
|
1153
1045
|
background: arrowColor
|
|
1154
1046
|
? `linear-gradient(to right bottom, transparent 50%, ${arrowColor} 50%)`
|
|
@@ -1156,14 +1048,8 @@
|
|
|
1156
1048
|
}, ref: tooltipArrowRef }))) : null;
|
|
1157
1049
|
};
|
|
1158
1050
|
|
|
1159
|
-
|
|
1160
|
-
const TooltipContent = ({ content }) => {
|
|
1161
|
-
return React__default["default"].createElement("span", { dangerouslySetInnerHTML: { __html: content } });
|
|
1162
|
-
};
|
|
1163
|
-
|
|
1164
|
-
const TooltipController = React__default["default"].forwardRef(({ id, anchorId, anchorSelect, content, html, render, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly = false, style, position, isOpen, defaultIsOpen = false, disableStyleInjection = false, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, role = 'tooltip', }, ref) => {
|
|
1051
|
+
const TooltipController = React.forwardRef(({ id, anchorSelect, content, render, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, openOnClick = false, positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly = false, style, position, isOpen, defaultIsOpen = false, disableStyleInjection = false, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, role = 'tooltip', }, ref) => {
|
|
1165
1052
|
const [tooltipContent, setTooltipContent] = React.useState(content);
|
|
1166
|
-
const [tooltipHtml, setTooltipHtml] = React.useState(html);
|
|
1167
1053
|
const [tooltipPlace, setTooltipPlace] = React.useState(place);
|
|
1168
1054
|
const [tooltipVariant, setTooltipVariant] = React.useState(variant);
|
|
1169
1055
|
const [tooltipOffset, setTooltipOffset] = React.useState(offset);
|
|
@@ -1172,15 +1058,10 @@
|
|
|
1172
1058
|
const [tooltipFloat, setTooltipFloat] = React.useState(float);
|
|
1173
1059
|
const [tooltipHidden, setTooltipHidden] = React.useState(hidden);
|
|
1174
1060
|
const [tooltipWrapper, setTooltipWrapper] = React.useState(wrapper);
|
|
1175
|
-
const [tooltipEvents, setTooltipEvents] = React.useState(events);
|
|
1176
1061
|
const [tooltipPositionStrategy, setTooltipPositionStrategy] = React.useState(positionStrategy);
|
|
1177
1062
|
const [tooltipClassName, setTooltipClassName] = React.useState(null);
|
|
1178
1063
|
const [activeAnchor, setActiveAnchor] = React.useState(null);
|
|
1179
1064
|
const styleInjectionRef = React.useRef(disableStyleInjection);
|
|
1180
|
-
/**
|
|
1181
|
-
* @todo Remove this in a future version (provider/wrapper method is deprecated)
|
|
1182
|
-
*/
|
|
1183
|
-
const { anchorRefs, activeAnchor: providerActiveAnchor } = useTooltip(id);
|
|
1184
1065
|
const getDataAttributesFromAnchorElement = (elementReference) => {
|
|
1185
1066
|
const dataAttributes = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttributeNames().reduce((acc, name) => {
|
|
1186
1067
|
var _a;
|
|
@@ -1192,7 +1073,7 @@
|
|
|
1192
1073
|
}, {});
|
|
1193
1074
|
return dataAttributes;
|
|
1194
1075
|
};
|
|
1195
|
-
const applyAllDataAttributesFromAnchorElement = (dataAttributes) => {
|
|
1076
|
+
const applyAllDataAttributesFromAnchorElement = React.useCallback((dataAttributes) => {
|
|
1196
1077
|
const handleDataAttributes = {
|
|
1197
1078
|
place: (value) => {
|
|
1198
1079
|
var _a;
|
|
@@ -1201,9 +1082,6 @@
|
|
|
1201
1082
|
content: (value) => {
|
|
1202
1083
|
setTooltipContent(value !== null && value !== void 0 ? value : content);
|
|
1203
1084
|
},
|
|
1204
|
-
html: (value) => {
|
|
1205
|
-
setTooltipHtml(value !== null && value !== void 0 ? value : html);
|
|
1206
|
-
},
|
|
1207
1085
|
variant: (value) => {
|
|
1208
1086
|
var _a;
|
|
1209
1087
|
setTooltipVariant((_a = value) !== null && _a !== void 0 ? _a : variant);
|
|
@@ -1215,10 +1093,6 @@
|
|
|
1215
1093
|
var _a;
|
|
1216
1094
|
setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : wrapper);
|
|
1217
1095
|
},
|
|
1218
|
-
events: (value) => {
|
|
1219
|
-
const parsed = value === null || value === void 0 ? void 0 : value.split(' ');
|
|
1220
|
-
setTooltipEvents(parsed !== null && parsed !== void 0 ? parsed : events);
|
|
1221
|
-
},
|
|
1222
1096
|
'position-strategy': (value) => {
|
|
1223
1097
|
var _a;
|
|
1224
1098
|
setTooltipPositionStrategy((_a = value) !== null && _a !== void 0 ? _a : positionStrategy);
|
|
@@ -1246,13 +1120,21 @@
|
|
|
1246
1120
|
var _a;
|
|
1247
1121
|
(_a = handleDataAttributes[key]) === null || _a === void 0 ? void 0 : _a.call(handleDataAttributes, value);
|
|
1248
1122
|
});
|
|
1249
|
-
}
|
|
1123
|
+
}, [
|
|
1124
|
+
content,
|
|
1125
|
+
delayHide,
|
|
1126
|
+
delayShow,
|
|
1127
|
+
float,
|
|
1128
|
+
hidden,
|
|
1129
|
+
offset,
|
|
1130
|
+
place,
|
|
1131
|
+
positionStrategy,
|
|
1132
|
+
variant,
|
|
1133
|
+
wrapper,
|
|
1134
|
+
]);
|
|
1250
1135
|
React.useEffect(() => {
|
|
1251
1136
|
setTooltipContent(content);
|
|
1252
1137
|
}, [content]);
|
|
1253
|
-
React.useEffect(() => {
|
|
1254
|
-
setTooltipHtml(html);
|
|
1255
|
-
}, [html]);
|
|
1256
1138
|
React.useEffect(() => {
|
|
1257
1139
|
setTooltipPlace(place);
|
|
1258
1140
|
}, [place]);
|
|
@@ -1297,48 +1179,19 @@
|
|
|
1297
1179
|
},
|
|
1298
1180
|
}));
|
|
1299
1181
|
}
|
|
1182
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1300
1183
|
}, []);
|
|
1301
1184
|
React.useEffect(() => {
|
|
1302
|
-
var _a;
|
|
1303
|
-
const elementRefs = new Set(anchorRefs);
|
|
1304
|
-
let selector = anchorSelect;
|
|
1305
|
-
if (!selector && id) {
|
|
1306
|
-
selector = `[data-tooltip-id='${id.replace(/'/g, "\\'")}']`;
|
|
1307
|
-
}
|
|
1308
|
-
if (selector) {
|
|
1309
|
-
try {
|
|
1310
|
-
const anchorsBySelect = document.querySelectorAll(selector);
|
|
1311
|
-
anchorsBySelect.forEach((anchor) => {
|
|
1312
|
-
elementRefs.add({ current: anchor });
|
|
1313
|
-
});
|
|
1314
|
-
}
|
|
1315
|
-
catch (_b) {
|
|
1316
|
-
/* c8 ignore start */
|
|
1317
|
-
{
|
|
1318
|
-
// eslint-disable-next-line no-console
|
|
1319
|
-
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
1320
|
-
}
|
|
1321
|
-
/* c8 ignore end */
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
const anchorById = document.querySelector(`[id='${anchorId}']`);
|
|
1325
|
-
if (anchorById) {
|
|
1326
|
-
elementRefs.add({ current: anchorById });
|
|
1327
|
-
}
|
|
1328
|
-
if (!elementRefs.size) {
|
|
1329
|
-
return () => null;
|
|
1330
|
-
}
|
|
1331
|
-
const anchorElement = (_a = activeAnchor !== null && activeAnchor !== void 0 ? activeAnchor : anchorById) !== null && _a !== void 0 ? _a : providerActiveAnchor.current;
|
|
1332
1185
|
const observerCallback = (mutationList) => {
|
|
1333
1186
|
mutationList.forEach((mutation) => {
|
|
1334
1187
|
var _a;
|
|
1335
|
-
if (!
|
|
1188
|
+
if (!activeAnchor ||
|
|
1336
1189
|
mutation.type !== 'attributes' ||
|
|
1337
1190
|
!((_a = mutation.attributeName) === null || _a === void 0 ? void 0 : _a.startsWith('data-tooltip-'))) {
|
|
1338
1191
|
return;
|
|
1339
1192
|
}
|
|
1340
1193
|
// make sure to get all set attributes, since all unset attributes are reset
|
|
1341
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1194
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1342
1195
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1343
1196
|
});
|
|
1344
1197
|
};
|
|
@@ -1347,17 +1200,17 @@
|
|
|
1347
1200
|
// do not check for subtree and childrens, we only want to know attribute changes
|
|
1348
1201
|
// to stay watching `data-attributes-*` from anchor element
|
|
1349
1202
|
const observerConfig = { attributes: true, childList: false, subtree: false };
|
|
1350
|
-
if (
|
|
1351
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1203
|
+
if (activeAnchor) {
|
|
1204
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1352
1205
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1353
1206
|
// Start observing the target node for configured mutations
|
|
1354
|
-
observer.observe(
|
|
1207
|
+
observer.observe(activeAnchor, observerConfig);
|
|
1355
1208
|
}
|
|
1356
1209
|
return () => {
|
|
1357
1210
|
// Remove the observer when the tooltip is destroyed
|
|
1358
1211
|
observer.disconnect();
|
|
1359
1212
|
};
|
|
1360
|
-
}, [
|
|
1213
|
+
}, [activeAnchor, anchorSelect, applyAllDataAttributesFromAnchorElement]);
|
|
1361
1214
|
React.useEffect(() => {
|
|
1362
1215
|
/* c8 ignore end */
|
|
1363
1216
|
if (style === null || style === void 0 ? void 0 : style.border) {
|
|
@@ -1376,7 +1229,7 @@
|
|
|
1376
1229
|
// eslint-disable-next-line no-console
|
|
1377
1230
|
console.warn(`[react-tooltip] "${opacity}" is not a valid \`opacity\`.`);
|
|
1378
1231
|
}
|
|
1379
|
-
}, []);
|
|
1232
|
+
}, [border, opacity, style === null || style === void 0 ? void 0 : style.border, style === null || style === void 0 ? void 0 : style.opacity]);
|
|
1380
1233
|
/**
|
|
1381
1234
|
* content priority: children < render or content < html
|
|
1382
1235
|
* children should be lower priority so that it can be used as the "default" content
|
|
@@ -1386,20 +1239,16 @@
|
|
|
1386
1239
|
if (render) {
|
|
1387
1240
|
const actualContent = (activeAnchor === null || activeAnchor === void 0 ? void 0 : activeAnchor.getAttribute('data-tooltip-content')) || tooltipContent || null;
|
|
1388
1241
|
const rendered = render({ content: actualContent, activeAnchor });
|
|
1389
|
-
renderedContent = rendered ? (
|
|
1242
|
+
renderedContent = rendered ? (React.createElement("div", { ref: contentWrapperRef, className: "react-tooltip-content-wrapper" }, rendered)) : null;
|
|
1390
1243
|
}
|
|
1391
1244
|
else if (tooltipContent) {
|
|
1392
1245
|
renderedContent = tooltipContent;
|
|
1393
1246
|
}
|
|
1394
|
-
if (tooltipHtml) {
|
|
1395
|
-
renderedContent = React__default["default"].createElement(TooltipContent, { content: tooltipHtml });
|
|
1396
|
-
}
|
|
1397
1247
|
const props = {
|
|
1398
1248
|
forwardRef: ref,
|
|
1399
1249
|
id,
|
|
1400
|
-
anchorId,
|
|
1401
1250
|
anchorSelect,
|
|
1402
|
-
className:
|
|
1251
|
+
className: clsx(className, tooltipClassName),
|
|
1403
1252
|
classNameArrow,
|
|
1404
1253
|
content: renderedContent,
|
|
1405
1254
|
contentWrapperRef,
|
|
@@ -1407,7 +1256,6 @@
|
|
|
1407
1256
|
variant: tooltipVariant,
|
|
1408
1257
|
offset: tooltipOffset,
|
|
1409
1258
|
wrapper: tooltipWrapper,
|
|
1410
|
-
events: tooltipEvents,
|
|
1411
1259
|
openOnClick,
|
|
1412
1260
|
positionStrategy: tooltipPositionStrategy,
|
|
1413
1261
|
middlewares,
|
|
@@ -1417,9 +1265,6 @@
|
|
|
1417
1265
|
hidden: tooltipHidden,
|
|
1418
1266
|
noArrow,
|
|
1419
1267
|
clickable,
|
|
1420
|
-
closeOnEsc,
|
|
1421
|
-
closeOnScroll,
|
|
1422
|
-
closeOnResize,
|
|
1423
1268
|
openEvents,
|
|
1424
1269
|
closeEvents,
|
|
1425
1270
|
globalCloseEvents,
|
|
@@ -1435,10 +1280,10 @@
|
|
|
1435
1280
|
afterShow,
|
|
1436
1281
|
afterHide,
|
|
1437
1282
|
activeAnchor,
|
|
1438
|
-
setActiveAnchor
|
|
1283
|
+
setActiveAnchor,
|
|
1439
1284
|
role,
|
|
1440
1285
|
};
|
|
1441
|
-
return
|
|
1286
|
+
return React.createElement(Tooltip, { ...props });
|
|
1442
1287
|
});
|
|
1443
1288
|
|
|
1444
1289
|
// those content will be replaced in build time with the `react-tooltip.css` builded content
|
|
@@ -1564,10 +1409,6 @@
|
|
|
1564
1409
|
}
|
|
1565
1410
|
|
|
1566
1411
|
exports.Tooltip = TooltipController;
|
|
1567
|
-
exports.TooltipProvider = TooltipProvider;
|
|
1568
|
-
exports.TooltipWrapper = TooltipWrapper;
|
|
1569
|
-
exports.removeStyle = removeStyle;
|
|
1570
|
-
|
|
1571
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1572
1412
|
|
|
1573
1413
|
}));
|
|
1414
|
+
//# sourceMappingURL=react-tooltip.umd.js.map
|