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