react-tooltip 5.1.0-beta.1 → 5.1.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.
@@ -1,4 +1,4 @@
1
- import require$$0, { createRef, useRef, useState, useEffect, useId } from 'react';
1
+ import require$$0, { createContext, useId, useState, useCallback, useMemo, useContext, useRef, useEffect } from 'react';
2
2
 
3
3
  var jsxRuntime = {exports: {}};
4
4
 
@@ -1384,9 +1384,7 @@ var classnames = {exports: {}};
1384
1384
 
1385
1385
  var classNames = classnames.exports;
1386
1386
 
1387
- /* eslint-disable func-names */
1388
- /* eslint-disable prefer-rest-params */
1389
- /* eslint-disable @typescript-eslint/no-this-alias */
1387
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1390
1388
  /**
1391
1389
  * This function debounce the received function
1392
1390
  * @param { function } func Function to be debounced
@@ -1394,19 +1392,17 @@ var classNames = classnames.exports;
1394
1392
  * @param { boolean } immediate Param to define if the function will be executed immediately
1395
1393
  */
1396
1394
  const debounce = (func, wait, immediate) => {
1397
- let timeout;
1398
- return function () {
1399
- // @ts-ignore
1400
- const context = this;
1401
- const args = arguments;
1395
+ let timeout = null;
1396
+ return function debounced(...args) {
1402
1397
  const later = () => {
1403
1398
  timeout = null;
1404
1399
  if (!immediate) {
1405
- func.apply(context, args);
1400
+ func.apply(this, args);
1406
1401
  }
1407
1402
  };
1408
- // @ts-ignore
1409
- clearTimeout(timeout);
1403
+ if (timeout) {
1404
+ clearTimeout(timeout);
1405
+ }
1410
1406
  timeout = setTimeout(later, wait);
1411
1407
  };
1412
1408
  };
@@ -1415,6 +1411,101 @@ const TooltipContent = ({ content }) => {
1415
1411
  return jsxRuntime.exports.jsx("span", { dangerouslySetInnerHTML: { __html: content } });
1416
1412
  };
1417
1413
 
1414
+ const defaultContextData = {
1415
+ anchorRefs: new Set(),
1416
+ activeAnchor: { current: null },
1417
+ attach: () => {
1418
+ /* attach anchor element */
1419
+ },
1420
+ detach: () => {
1421
+ /* detach anchor element */
1422
+ },
1423
+ setActiveAnchor: () => {
1424
+ /* set active anchor */
1425
+ },
1426
+ };
1427
+ const defaultContextWrapper = Object.assign(() => defaultContextData, defaultContextData);
1428
+ const TooltipContext = createContext(defaultContextWrapper);
1429
+ const TooltipProvider = ({ children }) => {
1430
+ const defaultTooltipId = useId();
1431
+ const [anchorRefMap, setAnchorRefMap] = useState({
1432
+ [defaultTooltipId]: new Set(),
1433
+ });
1434
+ const [activeAnchorMap, setActiveAnchorMap] = useState({
1435
+ [defaultTooltipId]: { current: null },
1436
+ });
1437
+ const attach = (tooltipId, ...refs) => {
1438
+ setAnchorRefMap((oldMap) => {
1439
+ var _a;
1440
+ const tooltipRefs = (_a = oldMap[tooltipId]) !== null && _a !== void 0 ? _a : new Set();
1441
+ refs.forEach((ref) => tooltipRefs.add(ref));
1442
+ // create new object to trigger re-render
1443
+ return { ...oldMap, [tooltipId]: new Set(tooltipRefs) };
1444
+ });
1445
+ };
1446
+ const detach = (tooltipId, ...refs) => {
1447
+ setAnchorRefMap((oldMap) => {
1448
+ const tooltipRefs = oldMap[tooltipId];
1449
+ if (!tooltipRefs) {
1450
+ // tooltip not found
1451
+ // maybe thow error?
1452
+ return oldMap;
1453
+ }
1454
+ refs.forEach((ref) => tooltipRefs.delete(ref));
1455
+ // create new object to trigger re-render
1456
+ return { ...oldMap };
1457
+ });
1458
+ };
1459
+ const setActiveAnchor = (tooltipId, ref) => {
1460
+ setActiveAnchorMap((oldMap) => {
1461
+ var _a;
1462
+ if (((_a = oldMap[tooltipId]) === null || _a === void 0 ? void 0 : _a.current) === ref.current) {
1463
+ return oldMap;
1464
+ }
1465
+ // create new object to trigger re-render
1466
+ return { ...oldMap, [tooltipId]: ref };
1467
+ });
1468
+ };
1469
+ const getTooltipData = useCallback((tooltipId) => {
1470
+ var _a, _b;
1471
+ return ({
1472
+ anchorRefs: (_a = anchorRefMap[tooltipId !== null && tooltipId !== void 0 ? tooltipId : defaultTooltipId]) !== null && _a !== void 0 ? _a : new Set(),
1473
+ activeAnchor: (_b = activeAnchorMap[tooltipId !== null && tooltipId !== void 0 ? tooltipId : defaultTooltipId]) !== null && _b !== void 0 ? _b : { current: null },
1474
+ attach: (...refs) => attach(tooltipId !== null && tooltipId !== void 0 ? tooltipId : defaultTooltipId, ...refs),
1475
+ detach: (...refs) => detach(tooltipId !== null && tooltipId !== void 0 ? tooltipId : defaultTooltipId, ...refs),
1476
+ setActiveAnchor: (ref) => setActiveAnchor(tooltipId !== null && tooltipId !== void 0 ? tooltipId : defaultTooltipId, ref),
1477
+ });
1478
+ }, [defaultTooltipId, anchorRefMap, activeAnchorMap, attach, detach]);
1479
+ const context = useMemo(() => {
1480
+ const contextData = getTooltipData(defaultTooltipId);
1481
+ const contextWrapper = Object.assign((tooltipId) => getTooltipData(tooltipId), contextData);
1482
+ return contextWrapper;
1483
+ }, [getTooltipData]);
1484
+ return jsxRuntime.exports.jsx(TooltipContext.Provider, { value: context, children: children });
1485
+ };
1486
+ /*
1487
+ // this will use the "global" tooltip (same as `useTooltip()()`)
1488
+ const { anchorRefs, attach, detach } = useTooltip()
1489
+
1490
+ // this will use the tooltip with id `tooltip-id`
1491
+ const { anchorRefs, attach, detach } = useTooltip()('tooltip-id')
1492
+ */
1493
+ function useTooltip() {
1494
+ return useContext(TooltipContext);
1495
+ }
1496
+
1497
+ const TooltipWrapper = ({ tooltipId, children, place, content, html, variant, offset, wrapper, events, positionStrategy, delayShow, delayHide, }) => {
1498
+ const { attach, detach } = useTooltip()(tooltipId);
1499
+ const anchorRef = useRef(null);
1500
+ useEffect(() => {
1501
+ attach(anchorRef);
1502
+ return () => {
1503
+ detach(anchorRef);
1504
+ };
1505
+ }, []);
1506
+ return (jsxRuntime.exports.jsx("span", { ref: anchorRef, "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: children }));
1507
+ };
1508
+
1418
1509
  function getSide(placement) {
1419
1510
  return placement.split('-')[0];
1420
1511
  }
@@ -2600,7 +2691,7 @@ const computePosition = (reference, floating, options) => computePosition$1(refe
2600
2691
  ...options
2601
2692
  });
2602
2693
 
2603
- const computeToolTipPosition = async ({ elementReference = null, tooltipReference = null, tooltipArrowReference = null, place = 'top', offset: offsetValue = 10, strategy = 'absolute', }) => {
2694
+ const computeTooltipPosition = async ({ elementReference = null, tooltipReference = null, tooltipArrowReference = null, place = 'top', offset: offsetValue = 10, strategy = 'absolute', }) => {
2604
2695
  if (!elementReference) {
2605
2696
  // elementReference can be null or undefined and we will not compute the position
2606
2697
  // eslint-disable-next-line no-console
@@ -2618,21 +2709,20 @@ const computeToolTipPosition = async ({ elementReference = null, tooltipReferenc
2618
2709
  strategy,
2619
2710
  middleware,
2620
2711
  }).then(({ x, y, placement, middlewareData }) => {
2712
+ var _a, _b;
2621
2713
  const styles = { left: `${x}px`, top: `${y}px` };
2622
- // @ts-ignore
2623
- const { x: arrowX, y: arrowY } = middlewareData.arrow;
2624
- const staticSide = {
2714
+ const { x: arrowX, y: arrowY } = (_a = middlewareData.arrow) !== null && _a !== void 0 ? _a : { x: 0, y: 0 };
2715
+ const staticSide = (_b = {
2625
2716
  top: 'bottom',
2626
2717
  right: 'left',
2627
2718
  bottom: 'top',
2628
2719
  left: 'right',
2629
- }[placement.split('-')[0]];
2720
+ }[placement.split('-')[0]]) !== null && _b !== void 0 ? _b : 'bottom';
2630
2721
  const arrowStyle = {
2631
2722
  left: arrowX != null ? `${arrowX}px` : '',
2632
2723
  top: arrowY != null ? `${arrowY}px` : '',
2633
2724
  right: '',
2634
2725
  bottom: '',
2635
- // @ts-ignore
2636
2726
  [staticSide]: '-4px',
2637
2727
  };
2638
2728
  return { tooltipStyles: styles, tooltipArrowStyles: arrowStyle };
@@ -2652,16 +2742,19 @@ var styles = {"tooltip":"styles-module_tooltip__mnnfp","fixed":"styles-module_fi
2652
2742
 
2653
2743
  const Tooltip = ({
2654
2744
  // props
2655
- id = useId(), className, classNameArrow, variant = 'dark', anchorId, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', wrapper: WrapperElement = 'div', children = null, delayShow = 0, delayHide = 0, style: externalStyles,
2745
+ id, className, classNameArrow, variant = 'dark', anchorId, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', wrapper: WrapperElement = 'div', children = null, delayShow = 0, delayHide = 0, style: externalStyles,
2656
2746
  // props handled by controller
2657
2747
  isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2658
- const tooltipRef = createRef();
2659
- const tooltipArrowRef = createRef();
2660
- const tooltipShowDelayTimerRef = useRef();
2661
- const tooltipHideDelayTimerRef = useRef();
2748
+ const tooltipRef = useRef(null);
2749
+ const tooltipArrowRef = useRef(null);
2750
+ const tooltipShowDelayTimerRef = useRef(null);
2751
+ const tooltipHideDelayTimerRef = useRef(null);
2662
2752
  const [inlineStyles, setInlineStyles] = useState({});
2663
2753
  const [inlineArrowStyles, setInlineArrowStyles] = useState({});
2664
2754
  const [show, setShow] = useState(false);
2755
+ const [calculatingPosition, setCalculatingPosition] = useState(false);
2756
+ const { anchorRefs, setActiveAnchor: setProviderActiveAnchor } = useTooltip()(id);
2757
+ const [activeAnchor, setActiveAnchor] = useState({ current: null });
2665
2758
  const handleShow = (value) => {
2666
2759
  if (setIsOpen) {
2667
2760
  setIsOpen(value);
@@ -2686,13 +2779,18 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2686
2779
  handleShow(false);
2687
2780
  }, delayHide);
2688
2781
  };
2689
- const handleShowTooltip = () => {
2782
+ const handleShowTooltip = (event) => {
2783
+ if (!event) {
2784
+ return;
2785
+ }
2690
2786
  if (delayShow) {
2691
2787
  handleShowTooltipDelayed();
2692
2788
  }
2693
2789
  else {
2694
2790
  handleShow(true);
2695
2791
  }
2792
+ setActiveAnchor((anchor) => anchor.current === event.target ? anchor : { current: event.target });
2793
+ setProviderActiveAnchor({ current: event.target });
2696
2794
  if (tooltipHideDelayTimerRef.current) {
2697
2795
  clearTimeout(tooltipHideDelayTimerRef.current);
2698
2796
  }
@@ -2704,16 +2802,9 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2704
2802
  else {
2705
2803
  handleShow(false);
2706
2804
  }
2707
- if (show && tooltipShowDelayTimerRef.current) {
2805
+ if (tooltipShowDelayTimerRef.current) {
2708
2806
  clearTimeout(tooltipShowDelayTimerRef.current);
2709
2807
  }
2710
- else if (!show && tooltipShowDelayTimerRef.current) {
2711
- // workaround to prevent tooltip being show forever
2712
- // when we remove the mouse before show tooltip with `delayShow`
2713
- tooltipHideDelayTimerRef.current = setTimeout(() => {
2714
- handleShow(false);
2715
- }, delayShow * 2);
2716
- }
2717
2808
  };
2718
2809
  const handleClickTooltipAnchor = () => {
2719
2810
  if (setIsOpen) {
@@ -2728,8 +2819,13 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2728
2819
  const debouncedHandleShowTooltip = debounce(handleShowTooltip, 50);
2729
2820
  const debouncedHandleHideTooltip = debounce(handleHideTooltip, 50);
2730
2821
  useEffect(() => {
2731
- const elementReference = document.querySelector(`#${anchorId}`);
2732
- if (!elementReference) {
2822
+ const elementRefs = new Set(anchorRefs);
2823
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
2824
+ if (anchorById) {
2825
+ setActiveAnchor((anchor) => anchor.current === anchorById ? anchor : { current: anchorById });
2826
+ elementRefs.add({ current: anchorById });
2827
+ }
2828
+ if (!elementRefs.size) {
2733
2829
  // eslint-disable-next-line @typescript-eslint/no-empty-function
2734
2830
  return () => { };
2735
2831
  }
@@ -2741,17 +2837,29 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2741
2837
  enabledEvents.push({ event: 'mouseenter', listener: debouncedHandleShowTooltip }, { event: 'mouseleave', listener: debouncedHandleHideTooltip }, { event: 'focus', listener: debouncedHandleShowTooltip }, { event: 'blur', listener: debouncedHandleHideTooltip });
2742
2838
  }
2743
2839
  enabledEvents.forEach(({ event, listener }) => {
2744
- elementReference === null || elementReference === void 0 ? void 0 : elementReference.addEventListener(event, listener);
2840
+ elementRefs.forEach((ref) => {
2841
+ var _a;
2842
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener(event, listener);
2843
+ });
2745
2844
  });
2746
2845
  return () => {
2747
2846
  enabledEvents.forEach(({ event, listener }) => {
2748
- elementReference === null || elementReference === void 0 ? void 0 : elementReference.removeEventListener(event, listener);
2847
+ elementRefs.forEach((ref) => {
2848
+ var _a;
2849
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, listener);
2850
+ });
2749
2851
  });
2750
2852
  };
2751
- }, [anchorId, events, delayHide, delayShow]);
2853
+ }, [anchorRefs, anchorId, events, delayHide, delayShow]);
2752
2854
  useEffect(() => {
2753
- const elementReference = document.querySelector(`#${anchorId}`);
2754
- computeToolTipPosition({
2855
+ let elementReference = activeAnchor.current;
2856
+ if (anchorId) {
2857
+ // `anchorId` element takes precedence
2858
+ elementReference = document.querySelector(`[id='${anchorId}']`);
2859
+ }
2860
+ setCalculatingPosition(true);
2861
+ let mounted = true;
2862
+ computeTooltipPosition({
2755
2863
  place,
2756
2864
  offset,
2757
2865
  elementReference,
@@ -2759,6 +2867,11 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2759
2867
  tooltipArrowReference: tooltipArrowRef.current,
2760
2868
  strategy: positionStrategy,
2761
2869
  }).then((computedStylesData) => {
2870
+ if (!mounted) {
2871
+ // invalidate computed positions after remount
2872
+ return;
2873
+ }
2874
+ setCalculatingPosition(false);
2762
2875
  if (Object.keys(computedStylesData.tooltipStyles).length) {
2763
2876
  setInlineStyles(computedStylesData.tooltipStyles);
2764
2877
  }
@@ -2767,29 +2880,26 @@ isHtmlContent = false, content, isOpen, setIsOpen, }) => {
2767
2880
  }
2768
2881
  });
2769
2882
  return () => {
2770
- tooltipShowDelayTimerRef.current = undefined;
2771
- tooltipHideDelayTimerRef.current = undefined;
2883
+ mounted = false;
2772
2884
  };
2773
- }, [show, isOpen, anchorId]);
2885
+ }, [show, isOpen, anchorId, activeAnchor, place, offset, positionStrategy]);
2886
+ useEffect(() => {
2887
+ return () => {
2888
+ if (tooltipShowDelayTimerRef.current) {
2889
+ clearTimeout(tooltipShowDelayTimerRef.current);
2890
+ }
2891
+ if (tooltipHideDelayTimerRef.current) {
2892
+ clearTimeout(tooltipHideDelayTimerRef.current);
2893
+ }
2894
+ };
2895
+ }, []);
2774
2896
  return (jsxRuntime.exports.jsxs(WrapperElement, { id: id, role: "tooltip", className: classNames(styles['tooltip'], styles[variant], className, {
2775
- [styles['show']]: isOpen || show,
2897
+ [styles['show']]: !calculatingPosition && (isOpen || show),
2776
2898
  [styles['fixed']]: positionStrategy === 'fixed',
2777
2899
  }), style: { ...externalStyles, ...inlineStyles }, ref: tooltipRef, children: [children || (isHtmlContent ? jsxRuntime.exports.jsx(TooltipContent, { content: content }) : content), jsxRuntime.exports.jsx("div", { className: classNames(styles['arrow'], classNameArrow), style: inlineArrowStyles, ref: tooltipArrowRef })] }));
2778
2900
  };
2779
2901
 
2780
- const dataAttributesKeys = [
2781
- 'place',
2782
- 'content',
2783
- 'html',
2784
- 'variant',
2785
- 'offset',
2786
- 'wrapper',
2787
- 'events',
2788
- 'delay-show',
2789
- 'delay-hide', // delay to hide tooltip
2790
- ];
2791
-
2792
- const TooltipController = ({ id, anchorId, content, html, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], positionStrategy = 'absolute', delayShow = 0, delayHide = 0, style, getContent, isOpen, setIsOpen, }) => {
2902
+ const TooltipController = ({ id, anchorId, content, html, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], positionStrategy = 'absolute', delayShow = 0, delayHide = 0, style, isOpen, setIsOpen, }) => {
2793
2903
  const [tooltipContent, setTooltipContent] = useState(content || html);
2794
2904
  const [tooltipPlace, setTooltipPlace] = useState(place);
2795
2905
  const [tooltipVariant, setTooltipVariant] = useState(variant);
@@ -2800,112 +2910,116 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
2800
2910
  const [tooltipEvents, setTooltipEvents] = useState(events);
2801
2911
  const [tooltipPositionStrategy, setTooltipPositionStrategy] = useState(positionStrategy);
2802
2912
  const [isHtmlContent, setIsHtmlContent] = useState(Boolean(html));
2913
+ const { anchorRefs, activeAnchor } = useTooltip()(id);
2803
2914
  const getDataAttributesFromAnchorElement = (elementReference) => {
2804
2915
  const dataAttributes = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttributeNames().reduce((acc, name) => {
2805
- if (name.includes('data-tooltip-')) {
2806
- acc[name] = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttribute(name);
2916
+ var _a;
2917
+ if (name.startsWith('data-tooltip-')) {
2918
+ const parsedAttribute = name.replace(/^data-tooltip-/, '');
2919
+ acc[parsedAttribute] = (_a = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttribute(name)) !== null && _a !== void 0 ? _a : null;
2807
2920
  }
2808
2921
  return acc;
2809
2922
  }, {});
2810
2923
  return dataAttributes;
2811
2924
  };
2812
2925
  const applyAllDataAttributesFromAnchorElement = (dataAttributes) => {
2813
- const keys = Object.keys(dataAttributes);
2814
- let formatedKey = null;
2815
2926
  const handleDataAttributes = {
2816
2927
  place: (value) => {
2817
- setTooltipPlace(value);
2928
+ var _a;
2929
+ setTooltipPlace((_a = value) !== null && _a !== void 0 ? _a : place);
2818
2930
  },
2819
2931
  content: (value) => {
2820
- setIsHtmlContent(true);
2821
- if (getContent) {
2822
- setTooltipContent(getContent(value));
2823
- }
2824
- else {
2825
- setTooltipContent(value);
2826
- }
2932
+ setIsHtmlContent(false);
2933
+ setTooltipContent(value !== null && value !== void 0 ? value : content);
2827
2934
  },
2828
2935
  html: (value) => {
2829
- setIsHtmlContent(true);
2830
- if (getContent) {
2831
- setTooltipContent(getContent(value));
2832
- }
2833
- else {
2834
- setTooltipContent(value);
2835
- }
2936
+ var _a;
2937
+ setIsHtmlContent(!!value);
2938
+ setTooltipContent((_a = value !== null && value !== void 0 ? value : html) !== null && _a !== void 0 ? _a : content);
2836
2939
  },
2837
2940
  variant: (value) => {
2838
- setTooltipVariant(value);
2941
+ var _a;
2942
+ setTooltipVariant((_a = value) !== null && _a !== void 0 ? _a : variant);
2839
2943
  },
2840
2944
  offset: (value) => {
2841
- setTooltipOffset(value);
2945
+ setTooltipOffset(value === null ? offset : Number(value));
2842
2946
  },
2843
2947
  wrapper: (value) => {
2844
- setTooltipWrapper(value);
2948
+ var _a;
2949
+ setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : 'div');
2845
2950
  },
2846
2951
  events: (value) => {
2847
- const parsedEvents = value.split(' ');
2848
- setTooltipEvents(parsedEvents);
2952
+ const parsed = value === null || value === void 0 ? void 0 : value.split(' ');
2953
+ setTooltipEvents(parsed !== null && parsed !== void 0 ? parsed : events);
2849
2954
  },
2850
- positionStrategy: (value) => {
2851
- setTooltipPositionStrategy(value);
2955
+ 'position-strategy': (value) => {
2956
+ var _a;
2957
+ setTooltipPositionStrategy((_a = value) !== null && _a !== void 0 ? _a : positionStrategy);
2852
2958
  },
2853
2959
  'delay-show': (value) => {
2854
- setTooltipDelayShow(Number(value));
2960
+ setTooltipDelayShow(value === null ? delayShow : Number(value));
2855
2961
  },
2856
2962
  'delay-hide': (value) => {
2857
- setTooltipDelayHide(Number(value));
2963
+ setTooltipDelayHide(value === null ? delayHide : Number(value));
2858
2964
  },
2859
2965
  };
2860
- keys.forEach((key) => {
2861
- formatedKey = key.replace('data-tooltip-', '');
2862
- if (dataAttributesKeys.includes(formatedKey)) {
2863
- // @ts-ignore
2864
- handleDataAttributes[formatedKey](dataAttributes[key]);
2865
- }
2966
+ // reset unset data attributes to default values
2967
+ // without this, data attributes from the last active anchor will still be used
2968
+ Object.values(handleDataAttributes).forEach((handler) => handler(null));
2969
+ Object.entries(dataAttributes).forEach(([key, value]) => {
2970
+ var _a;
2971
+ (_a = handleDataAttributes[key]) === null || _a === void 0 ? void 0 : _a.call(handleDataAttributes, value);
2866
2972
  });
2867
2973
  };
2868
- const getElementSpecificAttributeKeyAndValueParsed = ({ element, attributeName, }) => {
2869
- return { [attributeName]: element.getAttribute(attributeName) };
2870
- };
2871
2974
  useEffect(() => {
2872
- if (!anchorId) {
2873
- // eslint-disable-next-line @typescript-eslint/no-empty-function
2874
- return () => { };
2975
+ if (content) {
2976
+ setTooltipContent(content);
2977
+ }
2978
+ if (html) {
2979
+ setTooltipContent(html);
2980
+ }
2981
+ }, [content, html]);
2982
+ useEffect(() => {
2983
+ var _a;
2984
+ const elementRefs = new Set(anchorRefs);
2985
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
2986
+ if (anchorById) {
2987
+ elementRefs.add({ current: anchorById });
2875
2988
  }
2876
- const elementReference = document.querySelector(`#${anchorId}`);
2877
- if (!elementReference) {
2989
+ if (!elementRefs.size) {
2878
2990
  // eslint-disable-next-line @typescript-eslint/no-empty-function
2879
2991
  return () => { };
2880
2992
  }
2881
- if (content && getContent) {
2882
- setTooltipContent(getContent(content));
2883
- }
2884
- // do not check for subtree and childrens, we only want to know attribute changes
2885
- // to stay watching `data-attributes` from anchor element
2886
- const observerConfig = { attributes: true, childList: false, subtree: false };
2887
2993
  const observerCallback = (mutationList) => {
2888
2994
  mutationList.forEach((mutation) => {
2889
- if (mutation.type === 'attributes') {
2890
- const attributeKeyAndValue = getElementSpecificAttributeKeyAndValueParsed({
2891
- element: elementReference,
2892
- attributeName: mutation.attributeName,
2893
- });
2894
- applyAllDataAttributesFromAnchorElement(attributeKeyAndValue);
2995
+ var _a;
2996
+ if (!activeAnchor.current ||
2997
+ mutation.type !== 'attributes' ||
2998
+ !((_a = mutation.attributeName) === null || _a === void 0 ? void 0 : _a.startsWith('data-tooltip-'))) {
2999
+ return;
2895
3000
  }
3001
+ // make sure to get all set attributes, since all unset attributes are reset
3002
+ const dataAttributes = getDataAttributesFromAnchorElement(activeAnchor.current);
3003
+ applyAllDataAttributesFromAnchorElement(dataAttributes);
2896
3004
  });
2897
3005
  };
2898
3006
  // Create an observer instance linked to the callback function
2899
3007
  const observer = new MutationObserver(observerCallback);
2900
- // Start observing the target node for configured mutations
2901
- observer.observe(elementReference, observerConfig);
2902
- const dataAttributes = getDataAttributesFromAnchorElement(elementReference);
2903
- applyAllDataAttributesFromAnchorElement(dataAttributes);
3008
+ // do not check for subtree and childrens, we only want to know attribute changes
3009
+ // to stay watching `data-attributes-*` from anchor element
3010
+ const observerConfig = { attributes: true, childList: false, subtree: false };
3011
+ const element = (_a = activeAnchor.current) !== null && _a !== void 0 ? _a : anchorById;
3012
+ if (element) {
3013
+ const dataAttributes = getDataAttributesFromAnchorElement(element);
3014
+ applyAllDataAttributesFromAnchorElement(dataAttributes);
3015
+ // Start observing the target node for configured mutations
3016
+ observer.observe(element, observerConfig);
3017
+ }
2904
3018
  return () => {
2905
3019
  // Remove the observer when the tooltip is destroyed
2906
3020
  observer.disconnect();
2907
3021
  };
2908
- }, [anchorId]);
3022
+ }, [anchorRefs, activeAnchor, anchorId]);
2909
3023
  const props = {
2910
3024
  id,
2911
3025
  anchorId,
@@ -2928,4 +3042,4 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
2928
3042
  return children ? jsxRuntime.exports.jsx(Tooltip, { ...props, children: children }) : jsxRuntime.exports.jsx(Tooltip, { ...props });
2929
3043
  };
2930
3044
 
2931
- export { TooltipController as Tooltip };
3045
+ export { TooltipController as Tooltip, TooltipProvider, TooltipWrapper };