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