react-tooltip 5.26.4 → 6.0.0-beta.1179.rc.0
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 +317 -467
- 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 +317 -457
- package/dist/react-tooltip.mjs.map +1 -1
- package/dist/react-tooltip.umd.js +320 -470
- 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 +49 -47
- package/rollup.config.dev.mjs +88 -0
- package/rollup.config.prod.mjs +126 -0
- package/rollup.config.types.mjs +21 -0
package/dist/react-tooltip.mjs
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* @copyright ReactTooltip Team
|
|
6
6
|
* @license MIT
|
|
7
7
|
*/
|
|
8
|
-
import React, { useLayoutEffect, useEffect,
|
|
8
|
+
import React, { useLayoutEffect, useEffect, useRef, useState, useCallback, useImperativeHandle } from 'react';
|
|
9
9
|
import { arrow, computePosition, offset, flip, shift, autoUpdate } from '@floating-ui/dom';
|
|
10
|
-
import
|
|
10
|
+
import clsx from 'clsx';
|
|
11
11
|
|
|
12
12
|
// This is the ID for the core styles of ReactTooltip
|
|
13
13
|
const REACT_TOOLTIP_CORE_STYLES_ID = 'react-tooltip-core-styles';
|
|
@@ -73,28 +73,6 @@ function injectStyle({ css, id = REACT_TOOLTIP_BASE_STYLES_ID, type = 'base', re
|
|
|
73
73
|
}
|
|
74
74
|
injected[type] = true;
|
|
75
75
|
}
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated Use the `disableStyleInjection` tooltip prop instead.
|
|
78
|
-
* See https://react-tooltip.com/docs/examples/styling#disabling-reacttooltip-css
|
|
79
|
-
*/
|
|
80
|
-
function removeStyle({ type = 'base', id = REACT_TOOLTIP_BASE_STYLES_ID, } = {}) {
|
|
81
|
-
if (!injected[type]) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (type === 'core') {
|
|
85
|
-
// eslint-disable-next-line no-param-reassign
|
|
86
|
-
id = REACT_TOOLTIP_CORE_STYLES_ID;
|
|
87
|
-
}
|
|
88
|
-
const style = document.getElementById(id);
|
|
89
|
-
if ((style === null || style === void 0 ? void 0 : style.tagName) === 'style') {
|
|
90
|
-
style === null || style === void 0 ? void 0 : style.remove();
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
// eslint-disable-next-line no-console
|
|
94
|
-
console.warn(`[react-tooltip] Failed to remove 'style' element with id '${id}'. Call \`injectStyle()\` first`);
|
|
95
|
-
}
|
|
96
|
-
injected[type] = false;
|
|
97
|
-
}
|
|
98
76
|
|
|
99
77
|
const computeTooltipPosition = async ({ elementReference = null, tooltipReference = null, tooltipArrowReference = null, place = 'top', offset: offsetValue = 10, strategy = 'absolute', middlewares = [
|
|
100
78
|
offset(Number(offsetValue)),
|
|
@@ -178,7 +156,7 @@ const cssSupports = (property, value) => {
|
|
|
178
156
|
};
|
|
179
157
|
|
|
180
158
|
const cssTimeToMs = (time) => {
|
|
181
|
-
const match = time.match(/^([\d.]+)(
|
|
159
|
+
const match = time.match(/^([\d.]+)(m?s)$/);
|
|
182
160
|
if (!match) {
|
|
183
161
|
return 0;
|
|
184
162
|
}
|
|
@@ -282,111 +260,13 @@ const getScrollParent = (node) => {
|
|
|
282
260
|
|
|
283
261
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
284
262
|
|
|
285
|
-
const DEFAULT_TOOLTIP_ID = 'DEFAULT_TOOLTIP_ID';
|
|
286
|
-
const DEFAULT_CONTEXT_DATA = {
|
|
287
|
-
anchorRefs: new Set(),
|
|
288
|
-
activeAnchor: { current: null },
|
|
289
|
-
attach: () => {
|
|
290
|
-
/* attach anchor element */
|
|
291
|
-
},
|
|
292
|
-
detach: () => {
|
|
293
|
-
/* detach anchor element */
|
|
294
|
-
},
|
|
295
|
-
setActiveAnchor: () => {
|
|
296
|
-
/* set active anchor */
|
|
297
|
-
},
|
|
298
|
-
};
|
|
299
|
-
const DEFAULT_CONTEXT_DATA_WRAPPER = {
|
|
300
|
-
getTooltipData: () => DEFAULT_CONTEXT_DATA,
|
|
301
|
-
};
|
|
302
|
-
const TooltipContext = createContext(DEFAULT_CONTEXT_DATA_WRAPPER);
|
|
303
|
-
/**
|
|
304
|
-
* @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
|
|
305
|
-
* See https://react-tooltip.com/docs/getting-started
|
|
306
|
-
*/
|
|
307
|
-
const TooltipProvider = ({ children }) => {
|
|
308
|
-
const [anchorRefMap, setAnchorRefMap] = useState({
|
|
309
|
-
[DEFAULT_TOOLTIP_ID]: new Set(),
|
|
310
|
-
});
|
|
311
|
-
const [activeAnchorMap, setActiveAnchorMap] = useState({
|
|
312
|
-
[DEFAULT_TOOLTIP_ID]: { current: null },
|
|
313
|
-
});
|
|
314
|
-
const attach = (tooltipId, ...refs) => {
|
|
315
|
-
setAnchorRefMap((oldMap) => {
|
|
316
|
-
var _a;
|
|
317
|
-
const tooltipRefs = (_a = oldMap[tooltipId]) !== null && _a !== void 0 ? _a : new Set();
|
|
318
|
-
refs.forEach((ref) => tooltipRefs.add(ref));
|
|
319
|
-
// create new object to trigger re-render
|
|
320
|
-
return { ...oldMap, [tooltipId]: new Set(tooltipRefs) };
|
|
321
|
-
});
|
|
322
|
-
};
|
|
323
|
-
const detach = (tooltipId, ...refs) => {
|
|
324
|
-
setAnchorRefMap((oldMap) => {
|
|
325
|
-
const tooltipRefs = oldMap[tooltipId];
|
|
326
|
-
if (!tooltipRefs) {
|
|
327
|
-
// tooltip not found
|
|
328
|
-
// maybe thow error?
|
|
329
|
-
return oldMap;
|
|
330
|
-
}
|
|
331
|
-
refs.forEach((ref) => tooltipRefs.delete(ref));
|
|
332
|
-
// create new object to trigger re-render
|
|
333
|
-
return { ...oldMap };
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
|
-
const setActiveAnchor = (tooltipId, ref) => {
|
|
337
|
-
setActiveAnchorMap((oldMap) => {
|
|
338
|
-
var _a;
|
|
339
|
-
if (((_a = oldMap[tooltipId]) === null || _a === void 0 ? void 0 : _a.current) === ref.current) {
|
|
340
|
-
return oldMap;
|
|
341
|
-
}
|
|
342
|
-
// create new object to trigger re-render
|
|
343
|
-
return { ...oldMap, [tooltipId]: ref };
|
|
344
|
-
});
|
|
345
|
-
};
|
|
346
|
-
const getTooltipData = useCallback((tooltipId = DEFAULT_TOOLTIP_ID) => {
|
|
347
|
-
var _a, _b;
|
|
348
|
-
return ({
|
|
349
|
-
anchorRefs: (_a = anchorRefMap[tooltipId]) !== null && _a !== void 0 ? _a : new Set(),
|
|
350
|
-
activeAnchor: (_b = activeAnchorMap[tooltipId]) !== null && _b !== void 0 ? _b : { current: null },
|
|
351
|
-
attach: (...refs) => attach(tooltipId, ...refs),
|
|
352
|
-
detach: (...refs) => detach(tooltipId, ...refs),
|
|
353
|
-
setActiveAnchor: (ref) => setActiveAnchor(tooltipId, ref),
|
|
354
|
-
});
|
|
355
|
-
}, [anchorRefMap, activeAnchorMap, attach, detach]);
|
|
356
|
-
const context = useMemo(() => {
|
|
357
|
-
return {
|
|
358
|
-
getTooltipData,
|
|
359
|
-
};
|
|
360
|
-
}, [getTooltipData]);
|
|
361
|
-
return React.createElement(TooltipContext.Provider, { value: context }, children);
|
|
362
|
-
};
|
|
363
|
-
function useTooltip(tooltipId = DEFAULT_TOOLTIP_ID) {
|
|
364
|
-
return useContext(TooltipContext).getTooltipData(tooltipId);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
|
|
369
|
-
* See https://react-tooltip.com/docs/getting-started
|
|
370
|
-
*/
|
|
371
|
-
const TooltipWrapper = ({ tooltipId, children, className, place, content, html, variant, offset, wrapper, events, positionStrategy, delayShow, delayHide, }) => {
|
|
372
|
-
const { attach, detach } = useTooltip(tooltipId);
|
|
373
|
-
const anchorRef = useRef(null);
|
|
374
|
-
useEffect(() => {
|
|
375
|
-
attach(anchorRef);
|
|
376
|
-
return () => {
|
|
377
|
-
detach(anchorRef);
|
|
378
|
-
};
|
|
379
|
-
}, []);
|
|
380
|
-
return (React.createElement("span", { ref: anchorRef, className: classNames('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));
|
|
381
|
-
};
|
|
382
|
-
|
|
383
263
|
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"};
|
|
384
264
|
|
|
385
265
|
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"};
|
|
386
266
|
|
|
387
267
|
const Tooltip = ({
|
|
388
268
|
// props
|
|
389
|
-
forwardRef, id, className, classNameArrow, variant = 'dark',
|
|
269
|
+
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,
|
|
390
270
|
// props handled by controller
|
|
391
271
|
content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, role = 'tooltip', }) => {
|
|
392
272
|
var _a;
|
|
@@ -405,79 +285,9 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
405
285
|
const [imperativeOptions, setImperativeOptions] = useState(null);
|
|
406
286
|
const wasShowing = useRef(false);
|
|
407
287
|
const lastFloatPosition = useRef(null);
|
|
408
|
-
/**
|
|
409
|
-
* @todo Remove this in a future version (provider/wrapper method is deprecated)
|
|
410
|
-
*/
|
|
411
|
-
const { anchorRefs, setActiveAnchor: setProviderActiveAnchor } = useTooltip(id);
|
|
412
288
|
const hoveringTooltip = useRef(false);
|
|
413
|
-
const [
|
|
289
|
+
const [anchorElements, setAnchorElements] = useState([]);
|
|
414
290
|
const mounted = useRef(false);
|
|
415
|
-
/**
|
|
416
|
-
* @todo Update when deprecated stuff gets removed.
|
|
417
|
-
*/
|
|
418
|
-
const shouldOpenOnClick = openOnClick || events.includes('click');
|
|
419
|
-
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);
|
|
420
|
-
const actualOpenEvents = openEvents
|
|
421
|
-
? { ...openEvents }
|
|
422
|
-
: {
|
|
423
|
-
mouseenter: true,
|
|
424
|
-
focus: true,
|
|
425
|
-
click: false,
|
|
426
|
-
dblclick: false,
|
|
427
|
-
mousedown: false,
|
|
428
|
-
};
|
|
429
|
-
if (!openEvents && shouldOpenOnClick) {
|
|
430
|
-
Object.assign(actualOpenEvents, {
|
|
431
|
-
mouseenter: false,
|
|
432
|
-
focus: false,
|
|
433
|
-
click: true,
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
const actualCloseEvents = closeEvents
|
|
437
|
-
? { ...closeEvents }
|
|
438
|
-
: {
|
|
439
|
-
mouseleave: true,
|
|
440
|
-
blur: true,
|
|
441
|
-
click: false,
|
|
442
|
-
dblclick: false,
|
|
443
|
-
mouseup: false,
|
|
444
|
-
};
|
|
445
|
-
if (!closeEvents && shouldOpenOnClick) {
|
|
446
|
-
Object.assign(actualCloseEvents, {
|
|
447
|
-
mouseleave: false,
|
|
448
|
-
blur: false,
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
const actualGlobalCloseEvents = globalCloseEvents
|
|
452
|
-
? { ...globalCloseEvents }
|
|
453
|
-
: {
|
|
454
|
-
escape: closeOnEsc || false,
|
|
455
|
-
scroll: closeOnScroll || false,
|
|
456
|
-
resize: closeOnResize || false,
|
|
457
|
-
clickOutsideAnchor: hasClickEvent || false,
|
|
458
|
-
};
|
|
459
|
-
if (imperativeModeOnly) {
|
|
460
|
-
Object.assign(actualOpenEvents, {
|
|
461
|
-
mouseenter: false,
|
|
462
|
-
focus: false,
|
|
463
|
-
click: false,
|
|
464
|
-
dblclick: false,
|
|
465
|
-
mousedown: false,
|
|
466
|
-
});
|
|
467
|
-
Object.assign(actualCloseEvents, {
|
|
468
|
-
mouseleave: false,
|
|
469
|
-
blur: false,
|
|
470
|
-
click: false,
|
|
471
|
-
dblclick: false,
|
|
472
|
-
mouseup: false,
|
|
473
|
-
});
|
|
474
|
-
Object.assign(actualGlobalCloseEvents, {
|
|
475
|
-
escape: false,
|
|
476
|
-
scroll: false,
|
|
477
|
-
resize: false,
|
|
478
|
-
clickOutsideAnchor: false,
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
291
|
/**
|
|
482
292
|
* useLayoutEffect runs before useEffect,
|
|
483
293
|
* but should be used carefully because of caveats
|
|
@@ -489,7 +299,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
489
299
|
mounted.current = false;
|
|
490
300
|
};
|
|
491
301
|
}, []);
|
|
492
|
-
const handleShow = (value) => {
|
|
302
|
+
const handleShow = useCallback((value) => {
|
|
493
303
|
if (!mounted.current) {
|
|
494
304
|
return;
|
|
495
305
|
}
|
|
@@ -509,7 +319,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
509
319
|
setShow(value);
|
|
510
320
|
}
|
|
511
321
|
}, 10);
|
|
512
|
-
};
|
|
322
|
+
}, [isOpen, setIsOpen]);
|
|
513
323
|
/**
|
|
514
324
|
* this replicates the effect from `handleShow()`
|
|
515
325
|
* when `isOpen` is changed from outside
|
|
@@ -556,13 +366,13 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
556
366
|
// +25ms just to make sure `onTransitionEnd` (if it gets fired) has time to run
|
|
557
367
|
}, transitionShowDelay + 25);
|
|
558
368
|
}
|
|
559
|
-
}, [show]);
|
|
369
|
+
}, [afterHide, afterShow, show]);
|
|
560
370
|
const handleComputedPosition = (newComputedPosition) => {
|
|
561
371
|
setComputedPosition((oldComputedPosition) => deepEqual(oldComputedPosition, newComputedPosition)
|
|
562
372
|
? oldComputedPosition
|
|
563
373
|
: newComputedPosition);
|
|
564
374
|
};
|
|
565
|
-
const handleShowTooltipDelayed = (delay = delayShow) => {
|
|
375
|
+
const handleShowTooltipDelayed = useCallback((delay = delayShow) => {
|
|
566
376
|
if (tooltipShowDelayTimerRef.current) {
|
|
567
377
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
568
378
|
}
|
|
@@ -574,8 +384,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
574
384
|
tooltipShowDelayTimerRef.current = setTimeout(() => {
|
|
575
385
|
handleShow(true);
|
|
576
386
|
}, delay);
|
|
577
|
-
};
|
|
578
|
-
const handleHideTooltipDelayed = (delay = delayHide) => {
|
|
387
|
+
}, [delayShow, handleShow, rendered]);
|
|
388
|
+
const handleHideTooltipDelayed = useCallback((delay = delayHide) => {
|
|
579
389
|
if (tooltipHideDelayTimerRef.current) {
|
|
580
390
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
581
391
|
}
|
|
@@ -585,50 +395,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
585
395
|
}
|
|
586
396
|
handleShow(false);
|
|
587
397
|
}, delay);
|
|
588
|
-
};
|
|
589
|
-
const
|
|
590
|
-
var _a;
|
|
591
|
-
if (!event) {
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
const target = ((_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target);
|
|
595
|
-
if (!(target === null || target === void 0 ? void 0 : target.isConnected)) {
|
|
596
|
-
/**
|
|
597
|
-
* this happens when the target is removed from the DOM
|
|
598
|
-
* at the same time the tooltip gets triggered
|
|
599
|
-
*/
|
|
600
|
-
setActiveAnchor(null);
|
|
601
|
-
setProviderActiveAnchor({ current: null });
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
if (delayShow) {
|
|
605
|
-
handleShowTooltipDelayed();
|
|
606
|
-
}
|
|
607
|
-
else {
|
|
608
|
-
handleShow(true);
|
|
609
|
-
}
|
|
610
|
-
setActiveAnchor(target);
|
|
611
|
-
setProviderActiveAnchor({ current: target });
|
|
612
|
-
if (tooltipHideDelayTimerRef.current) {
|
|
613
|
-
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
const handleHideTooltip = () => {
|
|
617
|
-
if (clickable) {
|
|
618
|
-
// allow time for the mouse to reach the tooltip, in case there's a gap
|
|
619
|
-
handleHideTooltipDelayed(delayHide || 100);
|
|
620
|
-
}
|
|
621
|
-
else if (delayHide) {
|
|
622
|
-
handleHideTooltipDelayed();
|
|
623
|
-
}
|
|
624
|
-
else {
|
|
625
|
-
handleShow(false);
|
|
626
|
-
}
|
|
627
|
-
if (tooltipShowDelayTimerRef.current) {
|
|
628
|
-
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
const handleTooltipPosition = ({ x, y }) => {
|
|
398
|
+
}, [delayHide, handleShow]);
|
|
399
|
+
const handleTooltipPosition = useCallback(({ x, y }) => {
|
|
632
400
|
var _a;
|
|
633
401
|
const virtualElement = {
|
|
634
402
|
getBoundingClientRect() {
|
|
@@ -656,58 +424,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
656
424
|
}).then((computedStylesData) => {
|
|
657
425
|
handleComputedPosition(computedStylesData);
|
|
658
426
|
});
|
|
659
|
-
};
|
|
660
|
-
const handlePointerMove = (event) => {
|
|
661
|
-
if (!event) {
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
const mouseEvent = event;
|
|
665
|
-
const mousePosition = {
|
|
666
|
-
x: mouseEvent.clientX,
|
|
667
|
-
y: mouseEvent.clientY,
|
|
668
|
-
};
|
|
669
|
-
handleTooltipPosition(mousePosition);
|
|
670
|
-
lastFloatPosition.current = mousePosition;
|
|
671
|
-
};
|
|
672
|
-
const handleClickOutsideAnchors = (event) => {
|
|
673
|
-
var _a;
|
|
674
|
-
if (!show) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
const target = event.target;
|
|
678
|
-
if (!target.isConnected) {
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
const anchorById = document.querySelector(`[id='${anchorId}']`);
|
|
685
|
-
const anchors = [anchorById, ...anchorsBySelect];
|
|
686
|
-
if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
handleShow(false);
|
|
690
|
-
if (tooltipShowDelayTimerRef.current) {
|
|
691
|
-
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
// debounce handler to prevent call twice when
|
|
695
|
-
// mouse enter and focus events being triggered toggether
|
|
696
|
-
const internalDebouncedHandleShowTooltip = debounce(handleShowTooltip, 50, true);
|
|
697
|
-
const internalDebouncedHandleHideTooltip = debounce(handleHideTooltip, 50, true);
|
|
698
|
-
// If either of the functions is called while the other is still debounced,
|
|
699
|
-
// reset the timeout. Otherwise if there is a sub-50ms (leave A, enter B, leave B)
|
|
700
|
-
// sequence of events, the tooltip will stay open because the hide debounce
|
|
701
|
-
// from leave A prevented the leave B event from calling it, leaving the
|
|
702
|
-
// tooltip visible.
|
|
703
|
-
const debouncedHandleShowTooltip = (e) => {
|
|
704
|
-
internalDebouncedHandleHideTooltip.cancel();
|
|
705
|
-
internalDebouncedHandleShowTooltip(e);
|
|
706
|
-
};
|
|
707
|
-
const debouncedHandleHideTooltip = () => {
|
|
708
|
-
internalDebouncedHandleShowTooltip.cancel();
|
|
709
|
-
internalDebouncedHandleHideTooltip();
|
|
710
|
-
};
|
|
427
|
+
}, [imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place, place, offset, positionStrategy, middlewares, border]);
|
|
711
428
|
const updateTooltipPosition = useCallback(() => {
|
|
712
429
|
var _a, _b;
|
|
713
430
|
const actualPosition = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position) !== null && _a !== void 0 ? _a : position;
|
|
@@ -750,33 +467,184 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
750
467
|
handleComputedPosition(computedStylesData);
|
|
751
468
|
});
|
|
752
469
|
}, [
|
|
753
|
-
|
|
470
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
|
|
471
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
472
|
+
position,
|
|
473
|
+
float,
|
|
754
474
|
activeAnchor,
|
|
755
|
-
content,
|
|
756
|
-
externalStyles,
|
|
757
475
|
place,
|
|
758
|
-
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
759
476
|
offset,
|
|
760
477
|
positionStrategy,
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
478
|
+
middlewares,
|
|
479
|
+
border,
|
|
480
|
+
handleTooltipPosition,
|
|
764
481
|
]);
|
|
765
482
|
useEffect(() => {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
483
|
+
/**
|
|
484
|
+
* TODO(V6): break this effect down into callbacks for clarity
|
|
485
|
+
* - `handleKeyboardEvents()`
|
|
486
|
+
* - `handleMouseEvents()`
|
|
487
|
+
* - `handleGlobalCloseEvents()`
|
|
488
|
+
* - `handleAnchorEvents()`
|
|
489
|
+
* - ...
|
|
490
|
+
*/
|
|
491
|
+
const handlePointerMove = (event) => {
|
|
492
|
+
if (!event) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const mouseEvent = event;
|
|
496
|
+
const mousePosition = {
|
|
497
|
+
x: mouseEvent.clientX,
|
|
498
|
+
y: mouseEvent.clientY,
|
|
499
|
+
};
|
|
500
|
+
handleTooltipPosition(mousePosition);
|
|
501
|
+
lastFloatPosition.current = mousePosition;
|
|
502
|
+
};
|
|
503
|
+
const handleClickOutsideAnchors = (event) => {
|
|
504
|
+
var _a;
|
|
505
|
+
if (!show) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const target = event.target;
|
|
509
|
+
if (!target.isConnected) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (anchorElements.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
handleShow(false);
|
|
519
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
520
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
const handleShowTooltip = (event) => {
|
|
524
|
+
var _a;
|
|
525
|
+
if (!event) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
const target = ((_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target);
|
|
529
|
+
if (!(target === null || target === void 0 ? void 0 : target.isConnected)) {
|
|
530
|
+
/**
|
|
531
|
+
* this happens when the target is removed from the DOM
|
|
532
|
+
* at the same time the tooltip gets triggered
|
|
533
|
+
*/
|
|
534
|
+
setActiveAnchor(null);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
if (delayShow) {
|
|
538
|
+
handleShowTooltipDelayed();
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
handleShow(true);
|
|
542
|
+
}
|
|
543
|
+
setActiveAnchor(target);
|
|
544
|
+
if (tooltipHideDelayTimerRef.current) {
|
|
545
|
+
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
const handleHideTooltip = () => {
|
|
549
|
+
if (clickable) {
|
|
550
|
+
// allow time for the mouse to reach the tooltip, in case there's a gap
|
|
551
|
+
handleHideTooltipDelayed(delayHide || 100);
|
|
552
|
+
}
|
|
553
|
+
else if (delayHide) {
|
|
554
|
+
handleHideTooltipDelayed();
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
handleShow(false);
|
|
558
|
+
}
|
|
559
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
560
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
// debounce handler to prevent call twice when
|
|
564
|
+
// mouse enter and focus events being triggered toggether
|
|
565
|
+
const internalDebouncedHandleShowTooltip = debounce(handleShowTooltip, 50, true);
|
|
566
|
+
const internalDebouncedHandleHideTooltip = debounce(handleHideTooltip, 50, true);
|
|
567
|
+
// If either of the functions is called while the other is still debounced,
|
|
568
|
+
// reset the timeout. Otherwise if there is a sub-50ms (leave A, enter B, leave B)
|
|
569
|
+
// sequence of events, the tooltip will stay open because the hide debounce
|
|
570
|
+
// from leave A prevented the leave B event from calling it, leaving the
|
|
571
|
+
// tooltip visible.
|
|
572
|
+
const debouncedHandleShowTooltip = (e) => {
|
|
573
|
+
internalDebouncedHandleHideTooltip.cancel();
|
|
574
|
+
internalDebouncedHandleShowTooltip(e);
|
|
575
|
+
};
|
|
576
|
+
const debouncedHandleHideTooltip = () => {
|
|
577
|
+
internalDebouncedHandleShowTooltip.cancel();
|
|
578
|
+
internalDebouncedHandleHideTooltip();
|
|
579
|
+
};
|
|
775
580
|
const handleScrollResize = () => {
|
|
776
581
|
handleShow(false);
|
|
777
582
|
};
|
|
778
|
-
const
|
|
583
|
+
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);
|
|
584
|
+
const actualOpenEvents = openEvents
|
|
585
|
+
? { ...openEvents }
|
|
586
|
+
: {
|
|
587
|
+
mouseenter: true,
|
|
588
|
+
focus: true,
|
|
589
|
+
click: false,
|
|
590
|
+
dblclick: false,
|
|
591
|
+
mousedown: false,
|
|
592
|
+
};
|
|
593
|
+
if (!openEvents && openOnClick) {
|
|
594
|
+
Object.assign(actualOpenEvents, {
|
|
595
|
+
mouseenter: false,
|
|
596
|
+
focus: false,
|
|
597
|
+
click: true,
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
const actualCloseEvents = closeEvents
|
|
601
|
+
? { ...closeEvents }
|
|
602
|
+
: {
|
|
603
|
+
mouseleave: true,
|
|
604
|
+
blur: true,
|
|
605
|
+
click: false,
|
|
606
|
+
dblclick: false,
|
|
607
|
+
mouseup: false,
|
|
608
|
+
};
|
|
609
|
+
if (!closeEvents && openOnClick) {
|
|
610
|
+
Object.assign(actualCloseEvents, {
|
|
611
|
+
mouseleave: false,
|
|
612
|
+
blur: false,
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
const actualGlobalCloseEvents = globalCloseEvents
|
|
616
|
+
? { ...globalCloseEvents }
|
|
617
|
+
: {
|
|
618
|
+
escape: false,
|
|
619
|
+
scroll: false,
|
|
620
|
+
resize: false,
|
|
621
|
+
clickOutsideAnchor: hasClickEvent || false,
|
|
622
|
+
};
|
|
623
|
+
if (imperativeModeOnly) {
|
|
624
|
+
Object.assign(actualOpenEvents, {
|
|
625
|
+
mouseenter: false,
|
|
626
|
+
focus: false,
|
|
627
|
+
click: false,
|
|
628
|
+
dblclick: false,
|
|
629
|
+
mousedown: false,
|
|
630
|
+
});
|
|
631
|
+
Object.assign(actualCloseEvents, {
|
|
632
|
+
mouseleave: false,
|
|
633
|
+
blur: false,
|
|
634
|
+
click: false,
|
|
635
|
+
dblclick: false,
|
|
636
|
+
mouseup: false,
|
|
637
|
+
});
|
|
638
|
+
Object.assign(actualGlobalCloseEvents, {
|
|
639
|
+
escape: false,
|
|
640
|
+
scroll: false,
|
|
641
|
+
resize: false,
|
|
642
|
+
clickOutsideAnchor: false,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
const tooltipElement = tooltipRef.current;
|
|
779
646
|
const tooltipScrollParent = getScrollParent(tooltipRef.current);
|
|
647
|
+
const anchorScrollParent = getScrollParent(activeAnchor);
|
|
780
648
|
if (actualGlobalCloseEvents.scroll) {
|
|
781
649
|
window.addEventListener('scroll', handleScrollResize);
|
|
782
650
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
|
|
@@ -869,17 +737,15 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
869
737
|
if (clickable && !hasClickEvent) {
|
|
870
738
|
// used to keep the tooltip open when hovering content.
|
|
871
739
|
// not needed if using click events.
|
|
872
|
-
|
|
873
|
-
|
|
740
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseenter', handleMouseEnterTooltip);
|
|
741
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
874
742
|
}
|
|
875
743
|
enabledEvents.forEach(({ event, listener }) => {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener(event, listener);
|
|
744
|
+
anchorElements.forEach((anchor) => {
|
|
745
|
+
anchor.addEventListener(event, listener);
|
|
879
746
|
});
|
|
880
747
|
});
|
|
881
748
|
return () => {
|
|
882
|
-
var _a, _b;
|
|
883
749
|
if (actualGlobalCloseEvents.scroll) {
|
|
884
750
|
window.removeEventListener('scroll', handleScrollResize);
|
|
885
751
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
|
|
@@ -898,13 +764,12 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
898
764
|
window.removeEventListener('keydown', handleEsc);
|
|
899
765
|
}
|
|
900
766
|
if (clickable && !hasClickEvent) {
|
|
901
|
-
|
|
902
|
-
|
|
767
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseenter', handleMouseEnterTooltip);
|
|
768
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
903
769
|
}
|
|
904
770
|
enabledEvents.forEach(({ event, listener }) => {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, listener);
|
|
771
|
+
anchorElements.forEach((anchor) => {
|
|
772
|
+
anchor.removeEventListener(event, listener);
|
|
908
773
|
});
|
|
909
774
|
});
|
|
910
775
|
};
|
|
@@ -914,61 +779,62 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
914
779
|
*/
|
|
915
780
|
}, [
|
|
916
781
|
activeAnchor,
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
anchorRefs,
|
|
920
|
-
anchorsBySelect,
|
|
921
|
-
// the effect uses the `actual*Events` objects, but this should work
|
|
922
|
-
openEvents,
|
|
782
|
+
anchorElements,
|
|
783
|
+
clickable,
|
|
923
784
|
closeEvents,
|
|
924
|
-
globalCloseEvents,
|
|
925
|
-
shouldOpenOnClick,
|
|
926
|
-
delayShow,
|
|
927
785
|
delayHide,
|
|
786
|
+
delayShow,
|
|
787
|
+
float,
|
|
788
|
+
globalCloseEvents,
|
|
789
|
+
handleHideTooltipDelayed,
|
|
790
|
+
handleShow,
|
|
791
|
+
handleShowTooltipDelayed,
|
|
792
|
+
handleTooltipPosition,
|
|
793
|
+
imperativeModeOnly,
|
|
794
|
+
openEvents,
|
|
795
|
+
openOnClick,
|
|
796
|
+
setActiveAnchor,
|
|
797
|
+
show,
|
|
798
|
+
updateTooltipPosition,
|
|
928
799
|
]);
|
|
929
800
|
useEffect(() => {
|
|
930
801
|
var _a, _b;
|
|
802
|
+
/**
|
|
803
|
+
* TODO(V6): break down observer callback for clarity
|
|
804
|
+
* - `handleAddedAnchors()`
|
|
805
|
+
* - `handleRemovedAnchors()`
|
|
806
|
+
*/
|
|
931
807
|
let selector = (_b = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect) !== null && _b !== void 0 ? _b : '';
|
|
932
808
|
if (!selector && id) {
|
|
933
809
|
selector = `[data-tooltip-id='${id.replace(/'/g, "\\'")}']`;
|
|
934
810
|
}
|
|
935
811
|
const documentObserverCallback = (mutationList) => {
|
|
936
|
-
const
|
|
937
|
-
const removedAnchors =
|
|
812
|
+
const addedAnchors = new Set();
|
|
813
|
+
const removedAnchors = new Set();
|
|
938
814
|
mutationList.forEach((mutation) => {
|
|
939
815
|
if (mutation.type === 'attributes' && mutation.attributeName === 'data-tooltip-id') {
|
|
940
|
-
const
|
|
816
|
+
const target = mutation.target;
|
|
817
|
+
const newId = target.getAttribute('data-tooltip-id');
|
|
941
818
|
if (newId === id) {
|
|
942
|
-
|
|
819
|
+
addedAnchors.add(target);
|
|
943
820
|
}
|
|
944
821
|
else if (mutation.oldValue === id) {
|
|
945
822
|
// data-tooltip-id has now been changed, so we need to remove this anchor
|
|
946
|
-
removedAnchors.
|
|
823
|
+
removedAnchors.add(target);
|
|
947
824
|
}
|
|
948
825
|
}
|
|
949
826
|
if (mutation.type !== 'childList') {
|
|
950
827
|
return;
|
|
951
828
|
}
|
|
829
|
+
const removedNodes = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
|
|
952
830
|
if (activeAnchor) {
|
|
953
|
-
|
|
954
|
-
if (selector) {
|
|
955
|
-
try {
|
|
956
|
-
removedAnchors.push(
|
|
957
|
-
// the element itself is an anchor
|
|
958
|
-
...elements.filter((element) => element.matches(selector)));
|
|
959
|
-
removedAnchors.push(
|
|
960
|
-
// the element has children which are anchors
|
|
961
|
-
...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
|
|
962
|
-
}
|
|
963
|
-
catch (_a) {
|
|
964
|
-
/**
|
|
965
|
-
* invalid CSS selector.
|
|
966
|
-
* already warned on tooltip controller
|
|
967
|
-
*/
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
elements.some((node) => {
|
|
831
|
+
removedNodes.some((node) => {
|
|
971
832
|
var _a;
|
|
833
|
+
/**
|
|
834
|
+
* TODO(V6)
|
|
835
|
+
* - isn't `!activeAnchor.isConnected` better?
|
|
836
|
+
* - maybe move to `handleDisconnectedAnchor()`
|
|
837
|
+
*/
|
|
972
838
|
if ((_a = node === null || node === void 0 ? void 0 : node.contains) === null || _a === void 0 ? void 0 : _a.call(node, activeAnchor)) {
|
|
973
839
|
setRendered(false);
|
|
974
840
|
handleShow(false);
|
|
@@ -988,25 +854,67 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
988
854
|
return;
|
|
989
855
|
}
|
|
990
856
|
try {
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
857
|
+
removedNodes.forEach((node) => {
|
|
858
|
+
const element = node;
|
|
859
|
+
if (element.matches(selector)) {
|
|
860
|
+
// the element itself is an anchor
|
|
861
|
+
removedAnchors.add(element);
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
/**
|
|
865
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
866
|
+
* has children which are also anchors?
|
|
867
|
+
* (i.e. should we remove `else` and always do this)
|
|
868
|
+
*/
|
|
869
|
+
// the element has children which are anchors
|
|
870
|
+
element
|
|
871
|
+
.querySelectorAll(selector)
|
|
872
|
+
.forEach((innerNode) => removedAnchors.add(innerNode));
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
catch (_a) {
|
|
877
|
+
/* c8 ignore start */
|
|
878
|
+
{
|
|
879
|
+
// eslint-disable-next-line no-console
|
|
880
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
881
|
+
}
|
|
882
|
+
/* c8 ignore end */
|
|
883
|
+
}
|
|
884
|
+
try {
|
|
885
|
+
const addedNodes = [...mutation.addedNodes].filter((node) => node.nodeType === 1);
|
|
886
|
+
addedNodes.forEach((node) => {
|
|
887
|
+
const element = node;
|
|
888
|
+
if (element.matches(selector)) {
|
|
889
|
+
// the element itself is an anchor
|
|
890
|
+
addedAnchors.add(element);
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
/**
|
|
894
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
895
|
+
* has children which are also anchors?
|
|
896
|
+
* (i.e. should we remove `else` and always do this)
|
|
897
|
+
*/
|
|
898
|
+
// the element has children which are anchors
|
|
899
|
+
element
|
|
900
|
+
.querySelectorAll(selector)
|
|
901
|
+
.forEach((innerNode) => addedAnchors.add(innerNode));
|
|
902
|
+
}
|
|
903
|
+
});
|
|
998
904
|
}
|
|
999
905
|
catch (_b) {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
906
|
+
/* c8 ignore start */
|
|
907
|
+
{
|
|
908
|
+
// eslint-disable-next-line no-console
|
|
909
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
910
|
+
}
|
|
911
|
+
/* c8 ignore end */
|
|
1004
912
|
}
|
|
1005
913
|
});
|
|
1006
|
-
if (
|
|
1007
|
-
|
|
1008
|
-
...anchors.filter((anchor) => !removedAnchors.
|
|
1009
|
-
...
|
|
914
|
+
if (addedAnchors.size || removedAnchors.size) {
|
|
915
|
+
setAnchorElements((anchors) => [
|
|
916
|
+
...anchors.filter((anchor) => !removedAnchors.has(anchor)),
|
|
917
|
+
...addedAnchors,
|
|
1010
918
|
]);
|
|
1011
919
|
}
|
|
1012
920
|
};
|
|
@@ -1023,7 +931,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1023
931
|
return () => {
|
|
1024
932
|
documentObserver.disconnect();
|
|
1025
933
|
};
|
|
1026
|
-
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor]);
|
|
934
|
+
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor, handleShow, setActiveAnchor]);
|
|
1027
935
|
useEffect(() => {
|
|
1028
936
|
updateTooltipPosition();
|
|
1029
937
|
}, [updateTooltipPosition]);
|
|
@@ -1038,20 +946,18 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1038
946
|
return () => {
|
|
1039
947
|
contentObserver.disconnect();
|
|
1040
948
|
};
|
|
1041
|
-
}, [content, contentWrapperRef
|
|
949
|
+
}, [content, contentWrapperRef, updateTooltipPosition]);
|
|
1042
950
|
useEffect(() => {
|
|
1043
951
|
var _a;
|
|
1044
|
-
|
|
1045
|
-
const anchors = [...anchorsBySelect, anchorById];
|
|
1046
|
-
if (!activeAnchor || !anchors.includes(activeAnchor)) {
|
|
952
|
+
if (!activeAnchor || !anchorElements.includes(activeAnchor)) {
|
|
1047
953
|
/**
|
|
1048
954
|
* if there is no active anchor,
|
|
1049
955
|
* or if the current active anchor is not amongst the allowed ones,
|
|
1050
956
|
* reset it
|
|
1051
957
|
*/
|
|
1052
|
-
setActiveAnchor((_a =
|
|
958
|
+
setActiveAnchor((_a = anchorElements[0]) !== null && _a !== void 0 ? _a : null);
|
|
1053
959
|
}
|
|
1054
|
-
}, [
|
|
960
|
+
}, [anchorElements, activeAnchor, setActiveAnchor]);
|
|
1055
961
|
useEffect(() => {
|
|
1056
962
|
if (defaultIsOpen) {
|
|
1057
963
|
handleShow(true);
|
|
@@ -1064,7 +970,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1064
970
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
1065
971
|
}
|
|
1066
972
|
};
|
|
1067
|
-
}, []);
|
|
973
|
+
}, [defaultIsOpen, handleShow]);
|
|
1068
974
|
useEffect(() => {
|
|
1069
975
|
var _a;
|
|
1070
976
|
let selector = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect;
|
|
@@ -1076,11 +982,11 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1076
982
|
}
|
|
1077
983
|
try {
|
|
1078
984
|
const anchors = Array.from(document.querySelectorAll(selector));
|
|
1079
|
-
|
|
985
|
+
setAnchorElements(anchors);
|
|
1080
986
|
}
|
|
1081
987
|
catch (_b) {
|
|
1082
988
|
// warning was already issued in the controller
|
|
1083
|
-
|
|
989
|
+
setAnchorElements([]);
|
|
1084
990
|
}
|
|
1085
991
|
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect]);
|
|
1086
992
|
useEffect(() => {
|
|
@@ -1088,7 +994,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1088
994
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
1089
995
|
handleShowTooltipDelayed(delayShow);
|
|
1090
996
|
}
|
|
1091
|
-
}, [delayShow]);
|
|
997
|
+
}, [delayShow, handleShowTooltipDelayed]);
|
|
1092
998
|
const actualContent = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.content) !== null && _a !== void 0 ? _a : content;
|
|
1093
999
|
const canShow = show && Object.keys(computedPosition.tooltipStyles).length > 0;
|
|
1094
1000
|
useImperativeHandle(forwardRef, () => ({
|
|
@@ -1125,7 +1031,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1125
1031
|
place: computedPosition.place,
|
|
1126
1032
|
isOpen: Boolean(rendered && !hidden && actualContent && canShow),
|
|
1127
1033
|
}));
|
|
1128
|
-
return rendered && !hidden && actualContent ? (React.createElement(WrapperElement, { id: id, role: role, className:
|
|
1034
|
+
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) => {
|
|
1129
1035
|
if (missedTransitionTimerRef.current) {
|
|
1130
1036
|
clearTimeout(missedTransitionTimerRef.current);
|
|
1131
1037
|
}
|
|
@@ -1141,7 +1047,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1141
1047
|
opacity: opacity !== undefined && canShow ? opacity : undefined,
|
|
1142
1048
|
}, ref: tooltipRef },
|
|
1143
1049
|
actualContent,
|
|
1144
|
-
React.createElement(WrapperElement, { className:
|
|
1050
|
+
React.createElement(WrapperElement, { className: clsx('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
|
|
1145
1051
|
...computedPosition.tooltipArrowStyles,
|
|
1146
1052
|
background: arrowColor
|
|
1147
1053
|
? `linear-gradient(to right bottom, transparent 50%, ${arrowColor} 50%)`
|
|
@@ -1149,14 +1055,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1149
1055
|
}, ref: tooltipArrowRef }))) : null;
|
|
1150
1056
|
};
|
|
1151
1057
|
|
|
1152
|
-
|
|
1153
|
-
const TooltipContent = ({ content }) => {
|
|
1154
|
-
return React.createElement("span", { dangerouslySetInnerHTML: { __html: content } });
|
|
1155
|
-
};
|
|
1156
|
-
|
|
1157
|
-
const TooltipController = React.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) => {
|
|
1058
|
+
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) => {
|
|
1158
1059
|
const [tooltipContent, setTooltipContent] = useState(content);
|
|
1159
|
-
const [tooltipHtml, setTooltipHtml] = useState(html);
|
|
1160
1060
|
const [tooltipPlace, setTooltipPlace] = useState(place);
|
|
1161
1061
|
const [tooltipVariant, setTooltipVariant] = useState(variant);
|
|
1162
1062
|
const [tooltipOffset, setTooltipOffset] = useState(offset);
|
|
@@ -1165,15 +1065,10 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1165
1065
|
const [tooltipFloat, setTooltipFloat] = useState(float);
|
|
1166
1066
|
const [tooltipHidden, setTooltipHidden] = useState(hidden);
|
|
1167
1067
|
const [tooltipWrapper, setTooltipWrapper] = useState(wrapper);
|
|
1168
|
-
const [tooltipEvents, setTooltipEvents] = useState(events);
|
|
1169
1068
|
const [tooltipPositionStrategy, setTooltipPositionStrategy] = useState(positionStrategy);
|
|
1170
1069
|
const [tooltipClassName, setTooltipClassName] = useState(null);
|
|
1171
1070
|
const [activeAnchor, setActiveAnchor] = useState(null);
|
|
1172
1071
|
const styleInjectionRef = useRef(disableStyleInjection);
|
|
1173
|
-
/**
|
|
1174
|
-
* @todo Remove this in a future version (provider/wrapper method is deprecated)
|
|
1175
|
-
*/
|
|
1176
|
-
const { anchorRefs, activeAnchor: providerActiveAnchor } = useTooltip(id);
|
|
1177
1072
|
const getDataAttributesFromAnchorElement = (elementReference) => {
|
|
1178
1073
|
const dataAttributes = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttributeNames().reduce((acc, name) => {
|
|
1179
1074
|
var _a;
|
|
@@ -1185,7 +1080,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1185
1080
|
}, {});
|
|
1186
1081
|
return dataAttributes;
|
|
1187
1082
|
};
|
|
1188
|
-
const applyAllDataAttributesFromAnchorElement = (dataAttributes) => {
|
|
1083
|
+
const applyAllDataAttributesFromAnchorElement = useCallback((dataAttributes) => {
|
|
1189
1084
|
const handleDataAttributes = {
|
|
1190
1085
|
place: (value) => {
|
|
1191
1086
|
var _a;
|
|
@@ -1194,9 +1089,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1194
1089
|
content: (value) => {
|
|
1195
1090
|
setTooltipContent(value !== null && value !== void 0 ? value : content);
|
|
1196
1091
|
},
|
|
1197
|
-
html: (value) => {
|
|
1198
|
-
setTooltipHtml(value !== null && value !== void 0 ? value : html);
|
|
1199
|
-
},
|
|
1200
1092
|
variant: (value) => {
|
|
1201
1093
|
var _a;
|
|
1202
1094
|
setTooltipVariant((_a = value) !== null && _a !== void 0 ? _a : variant);
|
|
@@ -1208,10 +1100,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1208
1100
|
var _a;
|
|
1209
1101
|
setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : wrapper);
|
|
1210
1102
|
},
|
|
1211
|
-
events: (value) => {
|
|
1212
|
-
const parsed = value === null || value === void 0 ? void 0 : value.split(' ');
|
|
1213
|
-
setTooltipEvents(parsed !== null && parsed !== void 0 ? parsed : events);
|
|
1214
|
-
},
|
|
1215
1103
|
'position-strategy': (value) => {
|
|
1216
1104
|
var _a;
|
|
1217
1105
|
setTooltipPositionStrategy((_a = value) !== null && _a !== void 0 ? _a : positionStrategy);
|
|
@@ -1239,13 +1127,21 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1239
1127
|
var _a;
|
|
1240
1128
|
(_a = handleDataAttributes[key]) === null || _a === void 0 ? void 0 : _a.call(handleDataAttributes, value);
|
|
1241
1129
|
});
|
|
1242
|
-
}
|
|
1130
|
+
}, [
|
|
1131
|
+
content,
|
|
1132
|
+
delayHide,
|
|
1133
|
+
delayShow,
|
|
1134
|
+
float,
|
|
1135
|
+
hidden,
|
|
1136
|
+
offset,
|
|
1137
|
+
place,
|
|
1138
|
+
positionStrategy,
|
|
1139
|
+
variant,
|
|
1140
|
+
wrapper,
|
|
1141
|
+
]);
|
|
1243
1142
|
useEffect(() => {
|
|
1244
1143
|
setTooltipContent(content);
|
|
1245
1144
|
}, [content]);
|
|
1246
|
-
useEffect(() => {
|
|
1247
|
-
setTooltipHtml(html);
|
|
1248
|
-
}, [html]);
|
|
1249
1145
|
useEffect(() => {
|
|
1250
1146
|
setTooltipPlace(place);
|
|
1251
1147
|
}, [place]);
|
|
@@ -1290,48 +1186,19 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1290
1186
|
},
|
|
1291
1187
|
}));
|
|
1292
1188
|
}
|
|
1189
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1293
1190
|
}, []);
|
|
1294
1191
|
useEffect(() => {
|
|
1295
|
-
var _a;
|
|
1296
|
-
const elementRefs = new Set(anchorRefs);
|
|
1297
|
-
let selector = anchorSelect;
|
|
1298
|
-
if (!selector && id) {
|
|
1299
|
-
selector = `[data-tooltip-id='${id.replace(/'/g, "\\'")}']`;
|
|
1300
|
-
}
|
|
1301
|
-
if (selector) {
|
|
1302
|
-
try {
|
|
1303
|
-
const anchorsBySelect = document.querySelectorAll(selector);
|
|
1304
|
-
anchorsBySelect.forEach((anchor) => {
|
|
1305
|
-
elementRefs.add({ current: anchor });
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1308
|
-
catch (_b) {
|
|
1309
|
-
/* c8 ignore start */
|
|
1310
|
-
{
|
|
1311
|
-
// eslint-disable-next-line no-console
|
|
1312
|
-
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
1313
|
-
}
|
|
1314
|
-
/* c8 ignore end */
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
const anchorById = document.querySelector(`[id='${anchorId}']`);
|
|
1318
|
-
if (anchorById) {
|
|
1319
|
-
elementRefs.add({ current: anchorById });
|
|
1320
|
-
}
|
|
1321
|
-
if (!elementRefs.size) {
|
|
1322
|
-
return () => null;
|
|
1323
|
-
}
|
|
1324
|
-
const anchorElement = (_a = activeAnchor !== null && activeAnchor !== void 0 ? activeAnchor : anchorById) !== null && _a !== void 0 ? _a : providerActiveAnchor.current;
|
|
1325
1192
|
const observerCallback = (mutationList) => {
|
|
1326
1193
|
mutationList.forEach((mutation) => {
|
|
1327
1194
|
var _a;
|
|
1328
|
-
if (!
|
|
1195
|
+
if (!activeAnchor ||
|
|
1329
1196
|
mutation.type !== 'attributes' ||
|
|
1330
1197
|
!((_a = mutation.attributeName) === null || _a === void 0 ? void 0 : _a.startsWith('data-tooltip-'))) {
|
|
1331
1198
|
return;
|
|
1332
1199
|
}
|
|
1333
1200
|
// make sure to get all set attributes, since all unset attributes are reset
|
|
1334
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1201
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1335
1202
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1336
1203
|
});
|
|
1337
1204
|
};
|
|
@@ -1340,17 +1207,17 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1340
1207
|
// do not check for subtree and childrens, we only want to know attribute changes
|
|
1341
1208
|
// to stay watching `data-attributes-*` from anchor element
|
|
1342
1209
|
const observerConfig = { attributes: true, childList: false, subtree: false };
|
|
1343
|
-
if (
|
|
1344
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1210
|
+
if (activeAnchor) {
|
|
1211
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1345
1212
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1346
1213
|
// Start observing the target node for configured mutations
|
|
1347
|
-
observer.observe(
|
|
1214
|
+
observer.observe(activeAnchor, observerConfig);
|
|
1348
1215
|
}
|
|
1349
1216
|
return () => {
|
|
1350
1217
|
// Remove the observer when the tooltip is destroyed
|
|
1351
1218
|
observer.disconnect();
|
|
1352
1219
|
};
|
|
1353
|
-
}, [
|
|
1220
|
+
}, [activeAnchor, anchorSelect, applyAllDataAttributesFromAnchorElement]);
|
|
1354
1221
|
useEffect(() => {
|
|
1355
1222
|
/* c8 ignore end */
|
|
1356
1223
|
if (style === null || style === void 0 ? void 0 : style.border) {
|
|
@@ -1369,7 +1236,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1369
1236
|
// eslint-disable-next-line no-console
|
|
1370
1237
|
console.warn(`[react-tooltip] "${opacity}" is not a valid \`opacity\`.`);
|
|
1371
1238
|
}
|
|
1372
|
-
}, []);
|
|
1239
|
+
}, [border, opacity, style === null || style === void 0 ? void 0 : style.border, style === null || style === void 0 ? void 0 : style.opacity]);
|
|
1373
1240
|
/**
|
|
1374
1241
|
* content priority: children < render or content < html
|
|
1375
1242
|
* children should be lower priority so that it can be used as the "default" content
|
|
@@ -1384,15 +1251,11 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1384
1251
|
else if (tooltipContent) {
|
|
1385
1252
|
renderedContent = tooltipContent;
|
|
1386
1253
|
}
|
|
1387
|
-
if (tooltipHtml) {
|
|
1388
|
-
renderedContent = React.createElement(TooltipContent, { content: tooltipHtml });
|
|
1389
|
-
}
|
|
1390
1254
|
const props = {
|
|
1391
1255
|
forwardRef: ref,
|
|
1392
1256
|
id,
|
|
1393
|
-
anchorId,
|
|
1394
1257
|
anchorSelect,
|
|
1395
|
-
className:
|
|
1258
|
+
className: clsx(className, tooltipClassName),
|
|
1396
1259
|
classNameArrow,
|
|
1397
1260
|
content: renderedContent,
|
|
1398
1261
|
contentWrapperRef,
|
|
@@ -1400,7 +1263,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1400
1263
|
variant: tooltipVariant,
|
|
1401
1264
|
offset: tooltipOffset,
|
|
1402
1265
|
wrapper: tooltipWrapper,
|
|
1403
|
-
events: tooltipEvents,
|
|
1404
1266
|
openOnClick,
|
|
1405
1267
|
positionStrategy: tooltipPositionStrategy,
|
|
1406
1268
|
middlewares,
|
|
@@ -1410,9 +1272,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1410
1272
|
hidden: tooltipHidden,
|
|
1411
1273
|
noArrow,
|
|
1412
1274
|
clickable,
|
|
1413
|
-
closeOnEsc,
|
|
1414
|
-
closeOnScroll,
|
|
1415
|
-
closeOnResize,
|
|
1416
1275
|
openEvents,
|
|
1417
1276
|
closeEvents,
|
|
1418
1277
|
globalCloseEvents,
|
|
@@ -1428,7 +1287,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1428
1287
|
afterShow,
|
|
1429
1288
|
afterHide,
|
|
1430
1289
|
activeAnchor,
|
|
1431
|
-
setActiveAnchor
|
|
1290
|
+
setActiveAnchor,
|
|
1432
1291
|
role,
|
|
1433
1292
|
};
|
|
1434
1293
|
return React.createElement(Tooltip, { ...props });
|
|
@@ -1556,4 +1415,5 @@ if (typeof window !== 'undefined') {
|
|
|
1556
1415
|
}));
|
|
1557
1416
|
}
|
|
1558
1417
|
|
|
1559
|
-
export { TooltipController as Tooltip
|
|
1418
|
+
export { TooltipController as Tooltip };
|
|
1419
|
+
//# sourceMappingURL=react-tooltip.mjs.map
|