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.
@@ -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 classNames = require('classnames');
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.]+)(ms|s)$/);
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 (immediate && !timeout) {
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', anchorId, anchorSelect, place = 'top', offset = 10, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly, style: externalStyles, position, afterShow, afterHide,
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 [anchorsBySelect, setAnchorsBySelect] = React.useState([]);
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 handleShowTooltip = (event) => {
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
- show,
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
- position,
771
- imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
772
- float,
471
+ middlewares,
472
+ border,
473
+ handleTooltipPosition,
773
474
  ]);
774
475
  React.useEffect(() => {
775
- var _a, _b;
776
- const elementRefs = new Set(anchorRefs);
777
- anchorsBySelect.forEach((anchor) => {
778
- elementRefs.add({ current: anchor });
779
- });
780
- const anchorById = document.querySelector(`[id='${anchorId}']`);
781
- if (anchorById) {
782
- elementRefs.add({ current: anchorById });
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 anchorScrollParent = getScrollParent(activeAnchor);
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
- (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', handleMouseEnterTooltip);
882
- (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseleave', handleMouseLeaveTooltip);
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
- elementRefs.forEach((ref) => {
886
- var _a;
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
- (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseenter', handleMouseEnterTooltip);
911
- (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', handleMouseLeaveTooltip);
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
- elementRefs.forEach((ref) => {
915
- var _a;
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
- updateTooltipPosition,
927
- rendered,
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 newAnchors = [];
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 newId = mutation.target.getAttribute('data-tooltip-id');
809
+ const target = mutation.target;
810
+ const newId = target.getAttribute('data-tooltip-id');
950
811
  if (newId === id) {
951
- newAnchors.push(mutation.target);
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.push(mutation.target);
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
- const elements = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
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
- const elements = [...mutation.addedNodes].filter((node) => node.nodeType === 1);
1001
- newAnchors.push(
1002
- // the element itself is an anchor
1003
- ...elements.filter((element) => element.matches(selector)));
1004
- newAnchors.push(
1005
- // the element has children which are anchors
1006
- ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
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
- * invalid CSS selector.
1011
- * already warned on tooltip controller
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 (newAnchors.length || removedAnchors.length) {
1016
- setAnchorsBySelect((anchors) => [
1017
- ...anchors.filter((anchor) => !removedAnchors.includes(anchor)),
1018
- ...newAnchors,
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 === null || contentWrapperRef === void 0 ? void 0 : contentWrapperRef.current]);
942
+ }, [content, contentWrapperRef, updateTooltipPosition]);
1051
943
  React.useEffect(() => {
1052
944
  var _a;
1053
- const anchorById = document.querySelector(`[id='${anchorId}']`);
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 = anchorsBySelect[0]) !== null && _a !== void 0 ? _a : anchorById);
951
+ setActiveAnchor((_a = anchorElements[0]) !== null && _a !== void 0 ? _a : null);
1062
952
  }
1063
- }, [anchorId, anchorsBySelect, activeAnchor]);
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
- setAnchorsBySelect(anchors);
978
+ setAnchorElements(anchors);
1089
979
  }
1090
980
  catch (_b) {
1091
981
  // warning was already issued in the controller
1092
- setAnchorsBySelect([]);
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 ? (React__default["default"].createElement(WrapperElement, { id: id, role: role, className: classNames__default["default"]('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) => {
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
- React__default["default"].createElement(WrapperElement, { className: classNames__default["default"]('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
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
- /* eslint-disable react/no-danger */
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 (!anchorElement ||
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(anchorElement);
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 (anchorElement) {
1353
- const dataAttributes = getDataAttributesFromAnchorElement(anchorElement);
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(anchorElement, observerConfig);
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
- }, [anchorRefs, providerActiveAnchor, activeAnchor, anchorId, anchorSelect]);
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 ? (React__default["default"].createElement("div", { ref: contentWrapperRef, className: "react-tooltip-content-wrapper" }, rendered)) : null;
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: classNames__default["default"](className, tooltipClassName),
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: (anchor) => setActiveAnchor(anchor),
1283
+ setActiveAnchor,
1441
1284
  role,
1442
1285
  };
1443
- return React__default["default"].createElement(Tooltip, { ...props });
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
- exports.TooltipProvider = TooltipProvider;
1570
- exports.TooltipWrapper = TooltipWrapper;
1571
- exports.removeStyle = removeStyle;
1412
+ //# sourceMappingURL=react-tooltip.cjs.map