react-tooltip 5.26.4 → 6.0.0-beta.1179.rc.0

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