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
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
|
}
|
|
@@ -198,11 +176,8 @@ const debounce = (func, wait, immediate) => {
|
|
|
198
176
|
const debounced = function debounced(...args) {
|
|
199
177
|
const later = () => {
|
|
200
178
|
timeout = null;
|
|
201
|
-
if (!immediate) {
|
|
202
|
-
func.apply(this, args);
|
|
203
|
-
}
|
|
204
179
|
};
|
|
205
|
-
if (
|
|
180
|
+
if (!timeout) {
|
|
206
181
|
/**
|
|
207
182
|
* there's no need to clear the timeout
|
|
208
183
|
* since we expect it to resolve and set `timeout = null`
|
|
@@ -210,12 +185,6 @@ const debounce = (func, wait, immediate) => {
|
|
|
210
185
|
func.apply(this, args);
|
|
211
186
|
timeout = setTimeout(later, wait);
|
|
212
187
|
}
|
|
213
|
-
if (!immediate) {
|
|
214
|
-
if (timeout) {
|
|
215
|
-
clearTimeout(timeout);
|
|
216
|
-
}
|
|
217
|
-
timeout = setTimeout(later, wait);
|
|
218
|
-
}
|
|
219
188
|
};
|
|
220
189
|
debounced.cancel = () => {
|
|
221
190
|
/* c8 ignore start */
|
|
@@ -282,111 +251,13 @@ const getScrollParent = (node) => {
|
|
|
282
251
|
|
|
283
252
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
284
253
|
|
|
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
254
|
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
255
|
|
|
385
256
|
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
257
|
|
|
387
258
|
const Tooltip = ({
|
|
388
259
|
// props
|
|
389
|
-
forwardRef, id, className, classNameArrow, variant = 'dark',
|
|
260
|
+
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
261
|
// props handled by controller
|
|
391
262
|
content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, role = 'tooltip', }) => {
|
|
392
263
|
var _a;
|
|
@@ -405,79 +276,9 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
405
276
|
const [imperativeOptions, setImperativeOptions] = useState(null);
|
|
406
277
|
const wasShowing = useRef(false);
|
|
407
278
|
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
279
|
const hoveringTooltip = useRef(false);
|
|
413
|
-
const [
|
|
280
|
+
const [anchorElements, setAnchorElements] = useState([]);
|
|
414
281
|
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
282
|
/**
|
|
482
283
|
* useLayoutEffect runs before useEffect,
|
|
483
284
|
* but should be used carefully because of caveats
|
|
@@ -489,7 +290,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
489
290
|
mounted.current = false;
|
|
490
291
|
};
|
|
491
292
|
}, []);
|
|
492
|
-
const handleShow = (value) => {
|
|
293
|
+
const handleShow = useCallback((value) => {
|
|
493
294
|
if (!mounted.current) {
|
|
494
295
|
return;
|
|
495
296
|
}
|
|
@@ -509,7 +310,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
509
310
|
setShow(value);
|
|
510
311
|
}
|
|
511
312
|
}, 10);
|
|
512
|
-
};
|
|
313
|
+
}, [isOpen, setIsOpen]);
|
|
513
314
|
/**
|
|
514
315
|
* this replicates the effect from `handleShow()`
|
|
515
316
|
* when `isOpen` is changed from outside
|
|
@@ -556,13 +357,13 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
556
357
|
// +25ms just to make sure `onTransitionEnd` (if it gets fired) has time to run
|
|
557
358
|
}, transitionShowDelay + 25);
|
|
558
359
|
}
|
|
559
|
-
}, [show]);
|
|
360
|
+
}, [afterHide, afterShow, show]);
|
|
560
361
|
const handleComputedPosition = (newComputedPosition) => {
|
|
561
362
|
setComputedPosition((oldComputedPosition) => deepEqual(oldComputedPosition, newComputedPosition)
|
|
562
363
|
? oldComputedPosition
|
|
563
364
|
: newComputedPosition);
|
|
564
365
|
};
|
|
565
|
-
const handleShowTooltipDelayed = (delay = delayShow) => {
|
|
366
|
+
const handleShowTooltipDelayed = useCallback((delay = delayShow) => {
|
|
566
367
|
if (tooltipShowDelayTimerRef.current) {
|
|
567
368
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
568
369
|
}
|
|
@@ -574,8 +375,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
574
375
|
tooltipShowDelayTimerRef.current = setTimeout(() => {
|
|
575
376
|
handleShow(true);
|
|
576
377
|
}, delay);
|
|
577
|
-
};
|
|
578
|
-
const handleHideTooltipDelayed = (delay = delayHide) => {
|
|
378
|
+
}, [delayShow, handleShow, rendered]);
|
|
379
|
+
const handleHideTooltipDelayed = useCallback((delay = delayHide) => {
|
|
579
380
|
if (tooltipHideDelayTimerRef.current) {
|
|
580
381
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
581
382
|
}
|
|
@@ -585,50 +386,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
585
386
|
}
|
|
586
387
|
handleShow(false);
|
|
587
388
|
}, 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 }) => {
|
|
389
|
+
}, [delayHide, handleShow]);
|
|
390
|
+
const handleTooltipPosition = useCallback(({ x, y }) => {
|
|
632
391
|
var _a;
|
|
633
392
|
const virtualElement = {
|
|
634
393
|
getBoundingClientRect() {
|
|
@@ -656,58 +415,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
656
415
|
}).then((computedStylesData) => {
|
|
657
416
|
handleComputedPosition(computedStylesData);
|
|
658
417
|
});
|
|
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
|
-
};
|
|
418
|
+
}, [imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place, place, offset, positionStrategy, middlewares, border]);
|
|
711
419
|
const updateTooltipPosition = useCallback(() => {
|
|
712
420
|
var _a, _b;
|
|
713
421
|
const actualPosition = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position) !== null && _a !== void 0 ? _a : position;
|
|
@@ -750,33 +458,184 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
750
458
|
handleComputedPosition(computedStylesData);
|
|
751
459
|
});
|
|
752
460
|
}, [
|
|
753
|
-
|
|
461
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
|
|
462
|
+
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
463
|
+
position,
|
|
464
|
+
float,
|
|
754
465
|
activeAnchor,
|
|
755
|
-
content,
|
|
756
|
-
externalStyles,
|
|
757
466
|
place,
|
|
758
|
-
imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
|
|
759
467
|
offset,
|
|
760
468
|
positionStrategy,
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
469
|
+
middlewares,
|
|
470
|
+
border,
|
|
471
|
+
handleTooltipPosition,
|
|
764
472
|
]);
|
|
765
473
|
useEffect(() => {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
474
|
+
/**
|
|
475
|
+
* TODO(V6): break this effect down into callbacks for clarity
|
|
476
|
+
* - `handleKeyboardEvents()`
|
|
477
|
+
* - `handleMouseEvents()`
|
|
478
|
+
* - `handleGlobalCloseEvents()`
|
|
479
|
+
* - `handleAnchorEvents()`
|
|
480
|
+
* - ...
|
|
481
|
+
*/
|
|
482
|
+
const handlePointerMove = (event) => {
|
|
483
|
+
if (!event) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const mouseEvent = event;
|
|
487
|
+
const mousePosition = {
|
|
488
|
+
x: mouseEvent.clientX,
|
|
489
|
+
y: mouseEvent.clientY,
|
|
490
|
+
};
|
|
491
|
+
handleTooltipPosition(mousePosition);
|
|
492
|
+
lastFloatPosition.current = mousePosition;
|
|
493
|
+
};
|
|
494
|
+
const handleClickOutsideAnchors = (event) => {
|
|
495
|
+
var _a;
|
|
496
|
+
if (!show) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const target = event.target;
|
|
500
|
+
if (!target.isConnected) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (anchorElements.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
handleShow(false);
|
|
510
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
511
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
const handleShowTooltip = (event) => {
|
|
515
|
+
var _a;
|
|
516
|
+
if (!event) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
const target = ((_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target);
|
|
520
|
+
if (!(target === null || target === void 0 ? void 0 : target.isConnected)) {
|
|
521
|
+
/**
|
|
522
|
+
* this happens when the target is removed from the DOM
|
|
523
|
+
* at the same time the tooltip gets triggered
|
|
524
|
+
*/
|
|
525
|
+
setActiveAnchor(null);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
if (delayShow) {
|
|
529
|
+
handleShowTooltipDelayed();
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
handleShow(true);
|
|
533
|
+
}
|
|
534
|
+
setActiveAnchor(target);
|
|
535
|
+
if (tooltipHideDelayTimerRef.current) {
|
|
536
|
+
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
const handleHideTooltip = () => {
|
|
540
|
+
if (clickable) {
|
|
541
|
+
// allow time for the mouse to reach the tooltip, in case there's a gap
|
|
542
|
+
handleHideTooltipDelayed(delayHide || 100);
|
|
543
|
+
}
|
|
544
|
+
else if (delayHide) {
|
|
545
|
+
handleHideTooltipDelayed();
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
handleShow(false);
|
|
549
|
+
}
|
|
550
|
+
if (tooltipShowDelayTimerRef.current) {
|
|
551
|
+
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
// debounce handler to prevent call twice when
|
|
555
|
+
// mouse enter and focus events being triggered toggether
|
|
556
|
+
const internalDebouncedHandleShowTooltip = debounce(handleShowTooltip, 50);
|
|
557
|
+
const internalDebouncedHandleHideTooltip = debounce(handleHideTooltip, 50);
|
|
558
|
+
// If either of the functions is called while the other is still debounced,
|
|
559
|
+
// reset the timeout. Otherwise if there is a sub-50ms (leave A, enter B, leave B)
|
|
560
|
+
// sequence of events, the tooltip will stay open because the hide debounce
|
|
561
|
+
// from leave A prevented the leave B event from calling it, leaving the
|
|
562
|
+
// tooltip visible.
|
|
563
|
+
const debouncedHandleShowTooltip = (e) => {
|
|
564
|
+
internalDebouncedHandleHideTooltip.cancel();
|
|
565
|
+
internalDebouncedHandleShowTooltip(e);
|
|
566
|
+
};
|
|
567
|
+
const debouncedHandleHideTooltip = () => {
|
|
568
|
+
internalDebouncedHandleShowTooltip.cancel();
|
|
569
|
+
internalDebouncedHandleHideTooltip();
|
|
570
|
+
};
|
|
775
571
|
const handleScrollResize = () => {
|
|
776
572
|
handleShow(false);
|
|
777
573
|
};
|
|
778
|
-
const
|
|
574
|
+
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);
|
|
575
|
+
const actualOpenEvents = openEvents
|
|
576
|
+
? { ...openEvents }
|
|
577
|
+
: {
|
|
578
|
+
mouseenter: true,
|
|
579
|
+
focus: true,
|
|
580
|
+
click: false,
|
|
581
|
+
dblclick: false,
|
|
582
|
+
mousedown: false,
|
|
583
|
+
};
|
|
584
|
+
if (!openEvents && openOnClick) {
|
|
585
|
+
Object.assign(actualOpenEvents, {
|
|
586
|
+
mouseenter: false,
|
|
587
|
+
focus: false,
|
|
588
|
+
click: true,
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
const actualCloseEvents = closeEvents
|
|
592
|
+
? { ...closeEvents }
|
|
593
|
+
: {
|
|
594
|
+
mouseleave: true,
|
|
595
|
+
blur: true,
|
|
596
|
+
click: false,
|
|
597
|
+
dblclick: false,
|
|
598
|
+
mouseup: false,
|
|
599
|
+
};
|
|
600
|
+
if (!closeEvents && openOnClick) {
|
|
601
|
+
Object.assign(actualCloseEvents, {
|
|
602
|
+
mouseleave: false,
|
|
603
|
+
blur: false,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
const actualGlobalCloseEvents = globalCloseEvents
|
|
607
|
+
? { ...globalCloseEvents }
|
|
608
|
+
: {
|
|
609
|
+
escape: false,
|
|
610
|
+
scroll: false,
|
|
611
|
+
resize: false,
|
|
612
|
+
clickOutsideAnchor: hasClickEvent || false,
|
|
613
|
+
};
|
|
614
|
+
if (imperativeModeOnly) {
|
|
615
|
+
Object.assign(actualOpenEvents, {
|
|
616
|
+
mouseenter: false,
|
|
617
|
+
focus: false,
|
|
618
|
+
click: false,
|
|
619
|
+
dblclick: false,
|
|
620
|
+
mousedown: false,
|
|
621
|
+
});
|
|
622
|
+
Object.assign(actualCloseEvents, {
|
|
623
|
+
mouseleave: false,
|
|
624
|
+
blur: false,
|
|
625
|
+
click: false,
|
|
626
|
+
dblclick: false,
|
|
627
|
+
mouseup: false,
|
|
628
|
+
});
|
|
629
|
+
Object.assign(actualGlobalCloseEvents, {
|
|
630
|
+
escape: false,
|
|
631
|
+
scroll: false,
|
|
632
|
+
resize: false,
|
|
633
|
+
clickOutsideAnchor: false,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
const tooltipElement = tooltipRef.current;
|
|
779
637
|
const tooltipScrollParent = getScrollParent(tooltipRef.current);
|
|
638
|
+
const anchorScrollParent = getScrollParent(activeAnchor);
|
|
780
639
|
if (actualGlobalCloseEvents.scroll) {
|
|
781
640
|
window.addEventListener('scroll', handleScrollResize);
|
|
782
641
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
|
|
@@ -869,17 +728,15 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
869
728
|
if (clickable && !hasClickEvent) {
|
|
870
729
|
// used to keep the tooltip open when hovering content.
|
|
871
730
|
// not needed if using click events.
|
|
872
|
-
|
|
873
|
-
|
|
731
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseenter', handleMouseEnterTooltip);
|
|
732
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.addEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
874
733
|
}
|
|
875
734
|
enabledEvents.forEach(({ event, listener }) => {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener(event, listener);
|
|
735
|
+
anchorElements.forEach((anchor) => {
|
|
736
|
+
anchor.addEventListener(event, listener);
|
|
879
737
|
});
|
|
880
738
|
});
|
|
881
739
|
return () => {
|
|
882
|
-
var _a, _b;
|
|
883
740
|
if (actualGlobalCloseEvents.scroll) {
|
|
884
741
|
window.removeEventListener('scroll', handleScrollResize);
|
|
885
742
|
anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
|
|
@@ -898,13 +755,12 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
898
755
|
window.removeEventListener('keydown', handleEsc);
|
|
899
756
|
}
|
|
900
757
|
if (clickable && !hasClickEvent) {
|
|
901
|
-
|
|
902
|
-
|
|
758
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseenter', handleMouseEnterTooltip);
|
|
759
|
+
tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeEventListener('mouseleave', handleMouseLeaveTooltip);
|
|
903
760
|
}
|
|
904
761
|
enabledEvents.forEach(({ event, listener }) => {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, listener);
|
|
762
|
+
anchorElements.forEach((anchor) => {
|
|
763
|
+
anchor.removeEventListener(event, listener);
|
|
908
764
|
});
|
|
909
765
|
});
|
|
910
766
|
};
|
|
@@ -914,61 +770,62 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
914
770
|
*/
|
|
915
771
|
}, [
|
|
916
772
|
activeAnchor,
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
anchorRefs,
|
|
920
|
-
anchorsBySelect,
|
|
921
|
-
// the effect uses the `actual*Events` objects, but this should work
|
|
922
|
-
openEvents,
|
|
773
|
+
anchorElements,
|
|
774
|
+
clickable,
|
|
923
775
|
closeEvents,
|
|
924
|
-
globalCloseEvents,
|
|
925
|
-
shouldOpenOnClick,
|
|
926
|
-
delayShow,
|
|
927
776
|
delayHide,
|
|
777
|
+
delayShow,
|
|
778
|
+
float,
|
|
779
|
+
globalCloseEvents,
|
|
780
|
+
handleHideTooltipDelayed,
|
|
781
|
+
handleShow,
|
|
782
|
+
handleShowTooltipDelayed,
|
|
783
|
+
handleTooltipPosition,
|
|
784
|
+
imperativeModeOnly,
|
|
785
|
+
openEvents,
|
|
786
|
+
openOnClick,
|
|
787
|
+
setActiveAnchor,
|
|
788
|
+
show,
|
|
789
|
+
updateTooltipPosition,
|
|
928
790
|
]);
|
|
929
791
|
useEffect(() => {
|
|
930
792
|
var _a, _b;
|
|
793
|
+
/**
|
|
794
|
+
* TODO(V6): break down observer callback for clarity
|
|
795
|
+
* - `handleAddedAnchors()`
|
|
796
|
+
* - `handleRemovedAnchors()`
|
|
797
|
+
*/
|
|
931
798
|
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
799
|
if (!selector && id) {
|
|
933
800
|
selector = `[data-tooltip-id='${id.replace(/'/g, "\\'")}']`;
|
|
934
801
|
}
|
|
935
802
|
const documentObserverCallback = (mutationList) => {
|
|
936
|
-
const
|
|
937
|
-
const removedAnchors =
|
|
803
|
+
const addedAnchors = new Set();
|
|
804
|
+
const removedAnchors = new Set();
|
|
938
805
|
mutationList.forEach((mutation) => {
|
|
939
806
|
if (mutation.type === 'attributes' && mutation.attributeName === 'data-tooltip-id') {
|
|
940
|
-
const
|
|
807
|
+
const target = mutation.target;
|
|
808
|
+
const newId = target.getAttribute('data-tooltip-id');
|
|
941
809
|
if (newId === id) {
|
|
942
|
-
|
|
810
|
+
addedAnchors.add(target);
|
|
943
811
|
}
|
|
944
812
|
else if (mutation.oldValue === id) {
|
|
945
813
|
// data-tooltip-id has now been changed, so we need to remove this anchor
|
|
946
|
-
removedAnchors.
|
|
814
|
+
removedAnchors.add(target);
|
|
947
815
|
}
|
|
948
816
|
}
|
|
949
817
|
if (mutation.type !== 'childList') {
|
|
950
818
|
return;
|
|
951
819
|
}
|
|
820
|
+
const removedNodes = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
|
|
952
821
|
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) => {
|
|
822
|
+
removedNodes.some((node) => {
|
|
971
823
|
var _a;
|
|
824
|
+
/**
|
|
825
|
+
* TODO(V6)
|
|
826
|
+
* - isn't `!activeAnchor.isConnected` better?
|
|
827
|
+
* - maybe move to `handleDisconnectedAnchor()`
|
|
828
|
+
*/
|
|
972
829
|
if ((_a = node === null || node === void 0 ? void 0 : node.contains) === null || _a === void 0 ? void 0 : _a.call(node, activeAnchor)) {
|
|
973
830
|
setRendered(false);
|
|
974
831
|
handleShow(false);
|
|
@@ -988,25 +845,67 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
988
845
|
return;
|
|
989
846
|
}
|
|
990
847
|
try {
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
848
|
+
removedNodes.forEach((node) => {
|
|
849
|
+
const element = node;
|
|
850
|
+
if (element.matches(selector)) {
|
|
851
|
+
// the element itself is an anchor
|
|
852
|
+
removedAnchors.add(element);
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
/**
|
|
856
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
857
|
+
* has children which are also anchors?
|
|
858
|
+
* (i.e. should we remove `else` and always do this)
|
|
859
|
+
*/
|
|
860
|
+
// the element has children which are anchors
|
|
861
|
+
element
|
|
862
|
+
.querySelectorAll(selector)
|
|
863
|
+
.forEach((innerNode) => removedAnchors.add(innerNode));
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
catch (_a) {
|
|
868
|
+
/* c8 ignore start */
|
|
869
|
+
{
|
|
870
|
+
// eslint-disable-next-line no-console
|
|
871
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
872
|
+
}
|
|
873
|
+
/* c8 ignore end */
|
|
874
|
+
}
|
|
875
|
+
try {
|
|
876
|
+
const addedNodes = [...mutation.addedNodes].filter((node) => node.nodeType === 1);
|
|
877
|
+
addedNodes.forEach((node) => {
|
|
878
|
+
const element = node;
|
|
879
|
+
if (element.matches(selector)) {
|
|
880
|
+
// the element itself is an anchor
|
|
881
|
+
addedAnchors.add(element);
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
/**
|
|
885
|
+
* TODO(V6): do we care if an element which is an anchor,
|
|
886
|
+
* has children which are also anchors?
|
|
887
|
+
* (i.e. should we remove `else` and always do this)
|
|
888
|
+
*/
|
|
889
|
+
// the element has children which are anchors
|
|
890
|
+
element
|
|
891
|
+
.querySelectorAll(selector)
|
|
892
|
+
.forEach((innerNode) => addedAnchors.add(innerNode));
|
|
893
|
+
}
|
|
894
|
+
});
|
|
998
895
|
}
|
|
999
896
|
catch (_b) {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
897
|
+
/* c8 ignore start */
|
|
898
|
+
{
|
|
899
|
+
// eslint-disable-next-line no-console
|
|
900
|
+
console.warn(`[react-tooltip] "${selector}" is not a valid CSS selector`);
|
|
901
|
+
}
|
|
902
|
+
/* c8 ignore end */
|
|
1004
903
|
}
|
|
1005
904
|
});
|
|
1006
|
-
if (
|
|
1007
|
-
|
|
1008
|
-
...anchors.filter((anchor) => !removedAnchors.
|
|
1009
|
-
...
|
|
905
|
+
if (addedAnchors.size || removedAnchors.size) {
|
|
906
|
+
setAnchorElements((anchors) => [
|
|
907
|
+
...anchors.filter((anchor) => !removedAnchors.has(anchor)),
|
|
908
|
+
...addedAnchors,
|
|
1010
909
|
]);
|
|
1011
910
|
}
|
|
1012
911
|
};
|
|
@@ -1023,7 +922,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1023
922
|
return () => {
|
|
1024
923
|
documentObserver.disconnect();
|
|
1025
924
|
};
|
|
1026
|
-
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor]);
|
|
925
|
+
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor, handleShow, setActiveAnchor]);
|
|
1027
926
|
useEffect(() => {
|
|
1028
927
|
updateTooltipPosition();
|
|
1029
928
|
}, [updateTooltipPosition]);
|
|
@@ -1038,20 +937,18 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1038
937
|
return () => {
|
|
1039
938
|
contentObserver.disconnect();
|
|
1040
939
|
};
|
|
1041
|
-
}, [content, contentWrapperRef
|
|
940
|
+
}, [content, contentWrapperRef, updateTooltipPosition]);
|
|
1042
941
|
useEffect(() => {
|
|
1043
942
|
var _a;
|
|
1044
|
-
|
|
1045
|
-
const anchors = [...anchorsBySelect, anchorById];
|
|
1046
|
-
if (!activeAnchor || !anchors.includes(activeAnchor)) {
|
|
943
|
+
if (!activeAnchor || !anchorElements.includes(activeAnchor)) {
|
|
1047
944
|
/**
|
|
1048
945
|
* if there is no active anchor,
|
|
1049
946
|
* or if the current active anchor is not amongst the allowed ones,
|
|
1050
947
|
* reset it
|
|
1051
948
|
*/
|
|
1052
|
-
setActiveAnchor((_a =
|
|
949
|
+
setActiveAnchor((_a = anchorElements[0]) !== null && _a !== void 0 ? _a : null);
|
|
1053
950
|
}
|
|
1054
|
-
}, [
|
|
951
|
+
}, [anchorElements, activeAnchor, setActiveAnchor]);
|
|
1055
952
|
useEffect(() => {
|
|
1056
953
|
if (defaultIsOpen) {
|
|
1057
954
|
handleShow(true);
|
|
@@ -1064,7 +961,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1064
961
|
clearTimeout(tooltipHideDelayTimerRef.current);
|
|
1065
962
|
}
|
|
1066
963
|
};
|
|
1067
|
-
}, []);
|
|
964
|
+
}, [defaultIsOpen, handleShow]);
|
|
1068
965
|
useEffect(() => {
|
|
1069
966
|
var _a;
|
|
1070
967
|
let selector = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect;
|
|
@@ -1076,11 +973,11 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1076
973
|
}
|
|
1077
974
|
try {
|
|
1078
975
|
const anchors = Array.from(document.querySelectorAll(selector));
|
|
1079
|
-
|
|
976
|
+
setAnchorElements(anchors);
|
|
1080
977
|
}
|
|
1081
978
|
catch (_b) {
|
|
1082
979
|
// warning was already issued in the controller
|
|
1083
|
-
|
|
980
|
+
setAnchorElements([]);
|
|
1084
981
|
}
|
|
1085
982
|
}, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect]);
|
|
1086
983
|
useEffect(() => {
|
|
@@ -1088,7 +985,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1088
985
|
clearTimeout(tooltipShowDelayTimerRef.current);
|
|
1089
986
|
handleShowTooltipDelayed(delayShow);
|
|
1090
987
|
}
|
|
1091
|
-
}, [delayShow]);
|
|
988
|
+
}, [delayShow, handleShowTooltipDelayed]);
|
|
1092
989
|
const actualContent = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.content) !== null && _a !== void 0 ? _a : content;
|
|
1093
990
|
const canShow = show && Object.keys(computedPosition.tooltipStyles).length > 0;
|
|
1094
991
|
useImperativeHandle(forwardRef, () => ({
|
|
@@ -1125,7 +1022,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1125
1022
|
place: computedPosition.place,
|
|
1126
1023
|
isOpen: Boolean(rendered && !hidden && actualContent && canShow),
|
|
1127
1024
|
}));
|
|
1128
|
-
return rendered && !hidden && actualContent ? (React.createElement(WrapperElement, { id: id, role: role, className:
|
|
1025
|
+
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
1026
|
if (missedTransitionTimerRef.current) {
|
|
1130
1027
|
clearTimeout(missedTransitionTimerRef.current);
|
|
1131
1028
|
}
|
|
@@ -1141,7 +1038,7 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1141
1038
|
opacity: opacity !== undefined && canShow ? opacity : undefined,
|
|
1142
1039
|
}, ref: tooltipRef },
|
|
1143
1040
|
actualContent,
|
|
1144
|
-
React.createElement(WrapperElement, { className:
|
|
1041
|
+
React.createElement(WrapperElement, { className: clsx('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
|
|
1145
1042
|
...computedPosition.tooltipArrowStyles,
|
|
1146
1043
|
background: arrowColor
|
|
1147
1044
|
? `linear-gradient(to right bottom, transparent 50%, ${arrowColor} 50%)`
|
|
@@ -1149,14 +1046,8 @@ content, contentWrapperRef, isOpen, defaultIsOpen = false, setIsOpen, activeAnch
|
|
|
1149
1046
|
}, ref: tooltipArrowRef }))) : null;
|
|
1150
1047
|
};
|
|
1151
1048
|
|
|
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) => {
|
|
1049
|
+
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
1050
|
const [tooltipContent, setTooltipContent] = useState(content);
|
|
1159
|
-
const [tooltipHtml, setTooltipHtml] = useState(html);
|
|
1160
1051
|
const [tooltipPlace, setTooltipPlace] = useState(place);
|
|
1161
1052
|
const [tooltipVariant, setTooltipVariant] = useState(variant);
|
|
1162
1053
|
const [tooltipOffset, setTooltipOffset] = useState(offset);
|
|
@@ -1165,15 +1056,10 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1165
1056
|
const [tooltipFloat, setTooltipFloat] = useState(float);
|
|
1166
1057
|
const [tooltipHidden, setTooltipHidden] = useState(hidden);
|
|
1167
1058
|
const [tooltipWrapper, setTooltipWrapper] = useState(wrapper);
|
|
1168
|
-
const [tooltipEvents, setTooltipEvents] = useState(events);
|
|
1169
1059
|
const [tooltipPositionStrategy, setTooltipPositionStrategy] = useState(positionStrategy);
|
|
1170
1060
|
const [tooltipClassName, setTooltipClassName] = useState(null);
|
|
1171
1061
|
const [activeAnchor, setActiveAnchor] = useState(null);
|
|
1172
1062
|
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
1063
|
const getDataAttributesFromAnchorElement = (elementReference) => {
|
|
1178
1064
|
const dataAttributes = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttributeNames().reduce((acc, name) => {
|
|
1179
1065
|
var _a;
|
|
@@ -1185,7 +1071,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1185
1071
|
}, {});
|
|
1186
1072
|
return dataAttributes;
|
|
1187
1073
|
};
|
|
1188
|
-
const applyAllDataAttributesFromAnchorElement = (dataAttributes) => {
|
|
1074
|
+
const applyAllDataAttributesFromAnchorElement = useCallback((dataAttributes) => {
|
|
1189
1075
|
const handleDataAttributes = {
|
|
1190
1076
|
place: (value) => {
|
|
1191
1077
|
var _a;
|
|
@@ -1194,9 +1080,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1194
1080
|
content: (value) => {
|
|
1195
1081
|
setTooltipContent(value !== null && value !== void 0 ? value : content);
|
|
1196
1082
|
},
|
|
1197
|
-
html: (value) => {
|
|
1198
|
-
setTooltipHtml(value !== null && value !== void 0 ? value : html);
|
|
1199
|
-
},
|
|
1200
1083
|
variant: (value) => {
|
|
1201
1084
|
var _a;
|
|
1202
1085
|
setTooltipVariant((_a = value) !== null && _a !== void 0 ? _a : variant);
|
|
@@ -1208,10 +1091,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1208
1091
|
var _a;
|
|
1209
1092
|
setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : wrapper);
|
|
1210
1093
|
},
|
|
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
1094
|
'position-strategy': (value) => {
|
|
1216
1095
|
var _a;
|
|
1217
1096
|
setTooltipPositionStrategy((_a = value) !== null && _a !== void 0 ? _a : positionStrategy);
|
|
@@ -1239,13 +1118,21 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1239
1118
|
var _a;
|
|
1240
1119
|
(_a = handleDataAttributes[key]) === null || _a === void 0 ? void 0 : _a.call(handleDataAttributes, value);
|
|
1241
1120
|
});
|
|
1242
|
-
}
|
|
1121
|
+
}, [
|
|
1122
|
+
content,
|
|
1123
|
+
delayHide,
|
|
1124
|
+
delayShow,
|
|
1125
|
+
float,
|
|
1126
|
+
hidden,
|
|
1127
|
+
offset,
|
|
1128
|
+
place,
|
|
1129
|
+
positionStrategy,
|
|
1130
|
+
variant,
|
|
1131
|
+
wrapper,
|
|
1132
|
+
]);
|
|
1243
1133
|
useEffect(() => {
|
|
1244
1134
|
setTooltipContent(content);
|
|
1245
1135
|
}, [content]);
|
|
1246
|
-
useEffect(() => {
|
|
1247
|
-
setTooltipHtml(html);
|
|
1248
|
-
}, [html]);
|
|
1249
1136
|
useEffect(() => {
|
|
1250
1137
|
setTooltipPlace(place);
|
|
1251
1138
|
}, [place]);
|
|
@@ -1290,48 +1177,19 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1290
1177
|
},
|
|
1291
1178
|
}));
|
|
1292
1179
|
}
|
|
1180
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1293
1181
|
}, []);
|
|
1294
1182
|
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
1183
|
const observerCallback = (mutationList) => {
|
|
1326
1184
|
mutationList.forEach((mutation) => {
|
|
1327
1185
|
var _a;
|
|
1328
|
-
if (!
|
|
1186
|
+
if (!activeAnchor ||
|
|
1329
1187
|
mutation.type !== 'attributes' ||
|
|
1330
1188
|
!((_a = mutation.attributeName) === null || _a === void 0 ? void 0 : _a.startsWith('data-tooltip-'))) {
|
|
1331
1189
|
return;
|
|
1332
1190
|
}
|
|
1333
1191
|
// make sure to get all set attributes, since all unset attributes are reset
|
|
1334
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1192
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1335
1193
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1336
1194
|
});
|
|
1337
1195
|
};
|
|
@@ -1340,17 +1198,17 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1340
1198
|
// do not check for subtree and childrens, we only want to know attribute changes
|
|
1341
1199
|
// to stay watching `data-attributes-*` from anchor element
|
|
1342
1200
|
const observerConfig = { attributes: true, childList: false, subtree: false };
|
|
1343
|
-
if (
|
|
1344
|
-
const dataAttributes = getDataAttributesFromAnchorElement(
|
|
1201
|
+
if (activeAnchor) {
|
|
1202
|
+
const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor);
|
|
1345
1203
|
applyAllDataAttributesFromAnchorElement(dataAttributes);
|
|
1346
1204
|
// Start observing the target node for configured mutations
|
|
1347
|
-
observer.observe(
|
|
1205
|
+
observer.observe(activeAnchor, observerConfig);
|
|
1348
1206
|
}
|
|
1349
1207
|
return () => {
|
|
1350
1208
|
// Remove the observer when the tooltip is destroyed
|
|
1351
1209
|
observer.disconnect();
|
|
1352
1210
|
};
|
|
1353
|
-
}, [
|
|
1211
|
+
}, [activeAnchor, anchorSelect, applyAllDataAttributesFromAnchorElement]);
|
|
1354
1212
|
useEffect(() => {
|
|
1355
1213
|
/* c8 ignore end */
|
|
1356
1214
|
if (style === null || style === void 0 ? void 0 : style.border) {
|
|
@@ -1369,7 +1227,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1369
1227
|
// eslint-disable-next-line no-console
|
|
1370
1228
|
console.warn(`[react-tooltip] "${opacity}" is not a valid \`opacity\`.`);
|
|
1371
1229
|
}
|
|
1372
|
-
}, []);
|
|
1230
|
+
}, [border, opacity, style === null || style === void 0 ? void 0 : style.border, style === null || style === void 0 ? void 0 : style.opacity]);
|
|
1373
1231
|
/**
|
|
1374
1232
|
* content priority: children < render or content < html
|
|
1375
1233
|
* children should be lower priority so that it can be used as the "default" content
|
|
@@ -1384,15 +1242,11 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1384
1242
|
else if (tooltipContent) {
|
|
1385
1243
|
renderedContent = tooltipContent;
|
|
1386
1244
|
}
|
|
1387
|
-
if (tooltipHtml) {
|
|
1388
|
-
renderedContent = React.createElement(TooltipContent, { content: tooltipHtml });
|
|
1389
|
-
}
|
|
1390
1245
|
const props = {
|
|
1391
1246
|
forwardRef: ref,
|
|
1392
1247
|
id,
|
|
1393
|
-
anchorId,
|
|
1394
1248
|
anchorSelect,
|
|
1395
|
-
className:
|
|
1249
|
+
className: clsx(className, tooltipClassName),
|
|
1396
1250
|
classNameArrow,
|
|
1397
1251
|
content: renderedContent,
|
|
1398
1252
|
contentWrapperRef,
|
|
@@ -1400,7 +1254,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1400
1254
|
variant: tooltipVariant,
|
|
1401
1255
|
offset: tooltipOffset,
|
|
1402
1256
|
wrapper: tooltipWrapper,
|
|
1403
|
-
events: tooltipEvents,
|
|
1404
1257
|
openOnClick,
|
|
1405
1258
|
positionStrategy: tooltipPositionStrategy,
|
|
1406
1259
|
middlewares,
|
|
@@ -1410,9 +1263,6 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1410
1263
|
hidden: tooltipHidden,
|
|
1411
1264
|
noArrow,
|
|
1412
1265
|
clickable,
|
|
1413
|
-
closeOnEsc,
|
|
1414
|
-
closeOnScroll,
|
|
1415
|
-
closeOnResize,
|
|
1416
1266
|
openEvents,
|
|
1417
1267
|
closeEvents,
|
|
1418
1268
|
globalCloseEvents,
|
|
@@ -1428,7 +1278,7 @@ const TooltipController = React.forwardRef(({ id, anchorId, anchorSelect, conten
|
|
|
1428
1278
|
afterShow,
|
|
1429
1279
|
afterHide,
|
|
1430
1280
|
activeAnchor,
|
|
1431
|
-
setActiveAnchor
|
|
1281
|
+
setActiveAnchor,
|
|
1432
1282
|
role,
|
|
1433
1283
|
};
|
|
1434
1284
|
return React.createElement(Tooltip, { ...props });
|
|
@@ -1556,4 +1406,5 @@ if (typeof window !== 'undefined') {
|
|
|
1556
1406
|
}));
|
|
1557
1407
|
}
|
|
1558
1408
|
|
|
1559
|
-
export { TooltipController as Tooltip
|
|
1409
|
+
export { TooltipController as Tooltip };
|
|
1410
|
+
//# sourceMappingURL=react-tooltip.mjs.map
|