react-tooltip 5.7.4 → 5.8.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,9 +46,12 @@ yarn add react-tooltip
46
46
 
47
47
  ## Usage
48
48
 
49
- ### Using NPM
49
+ > :warning: If you were already using `react-tooltip<=5.7.5`, you'll be getting some deprecation warnings regarding the `anchorId` prop and some other features.
50
+ In versions >=5.8.0, we've introduced the `data-tooltip-id` attribute, and the `anchorSelect` prop, which are our recommended methods of using the tooltip moving forward. Check [the docs](https://react-tooltip.com/docs/getting-started) for more details.
50
51
 
51
- 1 . Import the CSS file to set default styling
52
+ ### Using NPM package
53
+
54
+ 1 . Import the CSS file to set default styling.
52
55
 
53
56
  ```js
54
57
  import 'react-tooltip/dist/react-tooltip.css'
@@ -56,7 +59,7 @@ import 'react-tooltip/dist/react-tooltip.css'
56
59
 
57
60
  This needs to be done only once. We suggest you do it on your `src/index.js` or equivalent file.
58
61
 
59
- 2 . Import `react-tooltip` after installation
62
+ 2 . Import `react-tooltip` after installation.
60
63
 
61
64
  ```js
62
65
  import { Tooltip } from 'react-tooltip'
@@ -68,20 +71,41 @@ or if you want to still use the name ReactTooltip as V4:
68
71
  import { Tooltip as ReactTooltip } from 'react-tooltip'
69
72
  ```
70
73
 
71
- 3 . Add `data-tooltip-content="your placeholder"` to your element
74
+ 3 . Add `data-tooltip-id="<tooltip id>"` and `data-tooltip-content="<your placeholder>"` to your element.
75
+
76
+ > `data-tooltip-id` is the equivalent of V4's `data-for`.
72
77
 
73
78
  ```jsx
74
- <p id="my-element" data-tooltip-content="hello world">
75
- Tooltip
76
- </p>
79
+ <a data-tooltip-id="my-tooltip" data-tooltip-content="Hello world!">
80
+ ◕‿‿◕
81
+ </a>
77
82
  ```
78
83
 
79
- 4 . Include react-tooltip component
84
+ 4 . Include the `<Tooltip />` element.
85
+
86
+ > Don't forget to set the id, it won't work without it!
80
87
 
81
88
  ```jsx
82
- <ReactTooltip anchorId="my-element" />
89
+ <Tooltip id="my-tooltip" />
83
90
  ```
84
91
 
92
+ #### Using multiple anchor elements
93
+
94
+ You can also set the `anchorSelect` tooltip prop to use the tooltip with multiple anchor elements without having to set `data-tooltip-id` on each of them.
95
+ `anchorSelect` must be a valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).
96
+
97
+ ```jsx
98
+ <a className="my-anchor-element" data-tooltip-content="Hello world!">
99
+ ◕‿‿◕
100
+ </a>
101
+ <a className="my-anchor-element" data-tooltip-content="Hello to you too!">
102
+ ◕‿‿◕
103
+ </a>
104
+ <Tooltip anchorSelect=".my-anchor-element" />
105
+ ```
106
+
107
+ Check [the V5 docs](https://react-tooltip.com/docs/getting-started) for more complex use cases.
108
+
85
109
  ### Standalone
86
110
 
87
111
  You can import `node_modules/react-tooltip/dist/react-tooltip.[mode].js` into your page. Please make sure that you have already imported `react` and `react-dom` into your page.
@@ -98,27 +122,26 @@ PS: all the files have a minified version and a non-minified version.
98
122
 
99
123
  For all available options, please check [React Tooltip Options](https://react-tooltip.com/docs/options)
100
124
 
101
- ### Security Note
125
+ ### Security note
102
126
 
103
127
  The `html` option allows a tooltip to directly display raw HTML. This is a security risk if any of that content is supplied by the user. Any user-supplied content must be sanitized, using a package like [sanitize-html](https://www.npmjs.com/package/sanitize-html). We chose not to include sanitization after discovering it [increased our package size](https://github.com/wwayne/react-tooltip/issues/429) too much - we don't want to penalize people who don't use the `html` option.
104
128
 
105
- #### JSX Note
129
+ #### JSX note
106
130
 
107
- You can use React's [`renderToStaticMarkup`-function](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) to use JSX instead of HTML.
131
+ You can use [`React.renderToStaticMarkup()` function](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) to use JSX instead of HTML.
108
132
  **Example:**
109
133
 
110
134
  ```jsx
111
135
  import ReactDOMServer from 'react-dom/server';
112
136
  [...]
113
- <p id="my-element" data-tooltip-html={ReactDOMServer.renderToString(<div>I am <b>JSX</b> content</div>)}>
114
- Hover me
115
- </p>
137
+ <a
138
+ data-tooltip-id="my-tooltip"
139
+ data-tooltip-html={ReactDOMServer.renderToStaticMarkup(<div>I am <b>JSX</b> content</div>)}
140
+ >
141
+ ◕‿‿◕
142
+ </a>
116
143
  ```
117
144
 
118
- #### Note
119
-
120
- - **id** is necessary, because `<ReactTooltip anchorId="my-element" />` finds the tooltip via this attribute
121
-
122
145
  ## Article
123
146
 
124
147
  [How I insert sass into react component](https://medium.com/@wwayne_me/how-i-insert-sass-into-my-npm-react-component-b46b9811c226#.gi4hxu44a)
@@ -2543,6 +2543,10 @@ const DEFAULT_CONTEXT_DATA_WRAPPER = {
2543
2543
  getTooltipData: () => DEFAULT_CONTEXT_DATA,
2544
2544
  };
2545
2545
  const TooltipContext = require$$0.createContext(DEFAULT_CONTEXT_DATA_WRAPPER);
2546
+ /**
2547
+ * @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
2548
+ * See https://react-tooltip.com/docs/getting-started
2549
+ */
2546
2550
  const TooltipProvider = ({ children }) => {
2547
2551
  const [anchorRefMap, setAnchorRefMap] = require$$0.useState({
2548
2552
  [DEFAULT_TOOLTIP_ID]: new Set(),
@@ -2603,6 +2607,10 @@ function useTooltip(tooltipId = DEFAULT_TOOLTIP_ID) {
2603
2607
  return require$$0.useContext(TooltipContext).getTooltipData(tooltipId);
2604
2608
  }
2605
2609
 
2610
+ /**
2611
+ * @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead.
2612
+ * See https://react-tooltip.com/docs/getting-started
2613
+ */
2606
2614
  const TooltipWrapper = ({ tooltipId, children, className, place, content, html, variant, offset, wrapper, events, positionStrategy, delayShow, delayHide, }) => {
2607
2615
  const { attach, detach } = useTooltip(tooltipId);
2608
2616
  const anchorRef = require$$0.useRef(null);
@@ -2666,9 +2674,9 @@ var styles = {"tooltip":"styles-module_tooltip__mnnfp","fixed":"styles-module_fi
2666
2674
 
2667
2675
  const Tooltip = ({
2668
2676
  // props
2669
- id, className, classNameArrow, variant = 'dark', anchorId, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, children = null, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style: externalStyles, position, afterShow, afterHide,
2677
+ id, className, classNameArrow, variant = 'dark', anchorId, anchorSelect, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, children = null, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style: externalStyles, position, afterShow, afterHide,
2670
2678
  // props handled by controller
2671
- content, html, isOpen, setIsOpen, }) => {
2679
+ content, html, isOpen, setIsOpen, activeAnchor, setActiveAnchor, }) => {
2672
2680
  const tooltipRef = require$$0.useRef(null);
2673
2681
  const tooltipArrowRef = require$$0.useRef(null);
2674
2682
  const tooltipShowDelayTimerRef = require$$0.useRef(null);
@@ -2676,20 +2684,98 @@ content, html, isOpen, setIsOpen, }) => {
2676
2684
  const [inlineStyles, setInlineStyles] = require$$0.useState({});
2677
2685
  const [inlineArrowStyles, setInlineArrowStyles] = require$$0.useState({});
2678
2686
  const [show, setShow] = require$$0.useState(false);
2687
+ const [rendered, setRendered] = require$$0.useState(false);
2679
2688
  const wasShowing = require$$0.useRef(false);
2680
- const [calculatingPosition, setCalculatingPosition] = require$$0.useState(false);
2681
2689
  const lastFloatPosition = require$$0.useRef(null);
2690
+ /**
2691
+ * @todo Remove this in a future version (provider/wrapper method is deprecated)
2692
+ */
2682
2693
  const { anchorRefs, setActiveAnchor: setProviderActiveAnchor } = useTooltip(id);
2683
- const [activeAnchor, setActiveAnchor] = require$$0.useState({ current: null });
2684
2694
  const hoveringTooltip = require$$0.useRef(false);
2685
- const handleShow = (value) => {
2686
- if (setIsOpen) {
2687
- setIsOpen(value);
2695
+ const [anchorsBySelect, setAnchorsBySelect] = require$$0.useState([]);
2696
+ const mounted = require$$0.useRef(false);
2697
+ require$$0.useEffect(() => {
2698
+ let selector = anchorSelect;
2699
+ if (!selector && id) {
2700
+ selector = `[data-tooltip-id='${id}']`;
2701
+ }
2702
+ if (!selector) {
2703
+ return;
2688
2704
  }
2689
- else if (isOpen === undefined) {
2690
- setShow(value);
2705
+ try {
2706
+ const anchors = Array.from(document.querySelectorAll(selector));
2707
+ setAnchorsBySelect(anchors);
2708
+ }
2709
+ catch (_a) {
2710
+ // warning was already issued in the controller
2711
+ setAnchorsBySelect([]);
2712
+ }
2713
+ }, [anchorSelect]);
2714
+ /**
2715
+ * useLayoutEffect runs before useEffect,
2716
+ * but should be used carefully because of caveats
2717
+ * https://beta.reactjs.org/reference/react/useLayoutEffect#caveats
2718
+ */
2719
+ require$$0.useLayoutEffect(() => {
2720
+ mounted.current = true;
2721
+ return () => {
2722
+ mounted.current = false;
2723
+ };
2724
+ }, []);
2725
+ require$$0.useEffect(() => {
2726
+ if (!show) {
2727
+ /**
2728
+ * this fixes weird behavior when switching between two anchor elements very quickly
2729
+ * remove the timeout and switch quickly between two adjancent anchor elements to see it
2730
+ *
2731
+ * in practice, this means the tooltip is not immediately removed from the DOM on hide
2732
+ */
2733
+ const timeout = setTimeout(() => {
2734
+ setRendered(false);
2735
+ }, 150);
2736
+ return () => {
2737
+ clearTimeout(timeout);
2738
+ };
2691
2739
  }
2740
+ return () => null;
2741
+ }, [show]);
2742
+ const handleShow = (value) => {
2743
+ if (!mounted.current) {
2744
+ return;
2745
+ }
2746
+ setRendered(true);
2747
+ /**
2748
+ * wait for the component to render and calculate position
2749
+ * before actually showing
2750
+ */
2751
+ setTimeout(() => {
2752
+ if (!mounted.current) {
2753
+ return;
2754
+ }
2755
+ setIsOpen === null || setIsOpen === void 0 ? void 0 : setIsOpen(value);
2756
+ if (isOpen === undefined) {
2757
+ setShow(value);
2758
+ }
2759
+ }, 10);
2692
2760
  };
2761
+ /**
2762
+ * this replicates the effect from `handleShow()`
2763
+ * when `isOpen` is changed from outside
2764
+ */
2765
+ require$$0.useEffect(() => {
2766
+ if (isOpen === undefined) {
2767
+ return () => null;
2768
+ }
2769
+ if (isOpen) {
2770
+ setRendered(true);
2771
+ }
2772
+ const timeout = setTimeout(() => {
2773
+ setShow(isOpen);
2774
+ }, 10);
2775
+ return () => {
2776
+ clearTimeout(timeout);
2777
+ };
2778
+ }, [isOpen]);
2693
2779
  require$$0.useEffect(() => {
2694
2780
  if (show === wasShowing.current) {
2695
2781
  return;
@@ -2733,7 +2819,7 @@ content, html, isOpen, setIsOpen, }) => {
2733
2819
  handleShow(true);
2734
2820
  }
2735
2821
  const target = (_a = event.currentTarget) !== null && _a !== void 0 ? _a : event.target;
2736
- setActiveAnchor((anchor) => anchor.current === target ? anchor : { current: target });
2822
+ setActiveAnchor(target);
2737
2823
  setProviderActiveAnchor({ current: target });
2738
2824
  if (tooltipHideDelayTimerRef.current) {
2739
2825
  clearTimeout(tooltipHideDelayTimerRef.current);
@@ -2742,7 +2828,7 @@ content, html, isOpen, setIsOpen, }) => {
2742
2828
  const handleHideTooltip = () => {
2743
2829
  if (clickable) {
2744
2830
  // allow time for the mouse to reach the tooltip, in case there's a gap
2745
- handleHideTooltipDelayed(delayHide || 50);
2831
+ handleHideTooltipDelayed(delayHide || 100);
2746
2832
  }
2747
2833
  else if (delayHide) {
2748
2834
  handleHideTooltipDelayed();
@@ -2769,7 +2855,6 @@ content, html, isOpen, setIsOpen, }) => {
2769
2855
  };
2770
2856
  },
2771
2857
  };
2772
- setCalculatingPosition(true);
2773
2858
  computeTooltipPosition({
2774
2859
  place,
2775
2860
  offset,
@@ -2779,7 +2864,6 @@ content, html, isOpen, setIsOpen, }) => {
2779
2864
  strategy: positionStrategy,
2780
2865
  middlewares,
2781
2866
  }).then((computedStylesData) => {
2782
- setCalculatingPosition(false);
2783
2867
  if (Object.keys(computedStylesData.tooltipStyles).length) {
2784
2868
  setInlineStyles(computedStylesData.tooltipStyles);
2785
2869
  }
@@ -2806,9 +2890,12 @@ content, html, isOpen, setIsOpen, }) => {
2806
2890
  handleHideTooltipDelayed();
2807
2891
  }
2808
2892
  };
2809
- const handleClickOutsideAnchor = (event) => {
2810
- var _a;
2811
- if ((_a = activeAnchor.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) {
2893
+ const handleClickOutsideAnchors = (event) => {
2894
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
2895
+ if (anchorById === null || anchorById === void 0 ? void 0 : anchorById.contains(event.target)) {
2896
+ return;
2897
+ }
2898
+ if (anchorsBySelect.some((anchor) => anchor.contains(event.target))) {
2812
2899
  return;
2813
2900
  }
2814
2901
  handleShow(false);
@@ -2826,9 +2913,11 @@ content, html, isOpen, setIsOpen, }) => {
2826
2913
  require$$0.useEffect(() => {
2827
2914
  var _a, _b;
2828
2915
  const elementRefs = new Set(anchorRefs);
2916
+ anchorsBySelect.forEach((anchor) => {
2917
+ elementRefs.add({ current: anchor });
2918
+ });
2829
2919
  const anchorById = document.querySelector(`[id='${anchorId}']`);
2830
2920
  if (anchorById) {
2831
- setActiveAnchor((anchor) => anchor.current === anchorById ? anchor : { current: anchorById });
2832
2921
  elementRefs.add({ current: anchorById });
2833
2922
  }
2834
2923
  if (!elementRefs.size) {
@@ -2839,7 +2928,7 @@ content, html, isOpen, setIsOpen, }) => {
2839
2928
  }
2840
2929
  const enabledEvents = [];
2841
2930
  if (events.find((event) => event === 'click')) {
2842
- window.addEventListener('click', handleClickOutsideAnchor);
2931
+ window.addEventListener('click', handleClickOutsideAnchors);
2843
2932
  enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor });
2844
2933
  }
2845
2934
  if (events.find((event) => event === 'hover')) {
@@ -2868,9 +2957,8 @@ content, html, isOpen, setIsOpen, }) => {
2868
2957
  (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener(event, listener);
2869
2958
  });
2870
2959
  });
2871
- const anchorElement = anchorById !== null && anchorById !== void 0 ? anchorById : activeAnchor.current;
2872
2960
  const parentObserverCallback = (mutationList) => {
2873
- if (!anchorElement) {
2961
+ if (!activeAnchor) {
2874
2962
  return;
2875
2963
  }
2876
2964
  mutationList.some((mutation) => {
@@ -2878,7 +2966,7 @@ content, html, isOpen, setIsOpen, }) => {
2878
2966
  return false;
2879
2967
  }
2880
2968
  return [...mutation.removedNodes].some((node) => {
2881
- if (node.contains(anchorElement)) {
2969
+ if (node.contains(activeAnchor)) {
2882
2970
  handleShow(false);
2883
2971
  return true;
2884
2972
  }
@@ -2892,7 +2980,7 @@ content, html, isOpen, setIsOpen, }) => {
2892
2980
  return () => {
2893
2981
  var _a, _b;
2894
2982
  if (events.find((event) => event === 'click')) {
2895
- window.removeEventListener('click', handleClickOutsideAnchor);
2983
+ window.removeEventListener('click', handleClickOutsideAnchors);
2896
2984
  }
2897
2985
  if (closeOnEsc) {
2898
2986
  window.removeEventListener('keydown', handleEsc);
@@ -2909,12 +2997,16 @@ content, html, isOpen, setIsOpen, }) => {
2909
2997
  });
2910
2998
  parentObserver.disconnect();
2911
2999
  };
2912
- }, [anchorRefs, activeAnchor, closeOnEsc, anchorId, events, delayHide, delayShow]);
3000
+ /**
3001
+ * rendered is also a dependency to ensure anchor observers are re-registered
3002
+ * since `tooltipRef` becomes stale after removing/adding the tooltip to the DOM
3003
+ */
3004
+ }, [rendered, anchorRefs, activeAnchor, closeOnEsc, events, delayHide, delayShow]);
2913
3005
  require$$0.useEffect(() => {
2914
3006
  if (position) {
2915
3007
  // if `position` is set, override regular and `float` positioning
2916
3008
  handleTooltipPosition(position);
2917
- return () => null;
3009
+ return;
2918
3010
  }
2919
3011
  if (float) {
2920
3012
  if (lastFloatPosition.current) {
@@ -2928,29 +3020,21 @@ content, html, isOpen, setIsOpen, }) => {
2928
3020
  handleTooltipPosition(lastFloatPosition.current);
2929
3021
  }
2930
3022
  // if `float` is set, override regular positioning
2931
- return () => null;
2932
- }
2933
- let elementReference = activeAnchor.current;
2934
- if (anchorId) {
2935
- // `anchorId` element takes precedence
2936
- elementReference = document.querySelector(`[id='${anchorId}']`);
3023
+ return;
2937
3024
  }
2938
- setCalculatingPosition(true);
2939
- let mounted = true;
2940
3025
  computeTooltipPosition({
2941
3026
  place,
2942
3027
  offset,
2943
- elementReference,
3028
+ elementReference: activeAnchor,
2944
3029
  tooltipReference: tooltipRef.current,
2945
3030
  tooltipArrowReference: tooltipArrowRef.current,
2946
3031
  strategy: positionStrategy,
2947
3032
  middlewares,
2948
3033
  }).then((computedStylesData) => {
2949
- if (!mounted) {
3034
+ if (!mounted.current) {
2950
3035
  // invalidate computed positions after remount
2951
3036
  return;
2952
3037
  }
2953
- setCalculatingPosition(false);
2954
3038
  if (Object.keys(computedStylesData.tooltipStyles).length) {
2955
3039
  setInlineStyles(computedStylesData.tooltipStyles);
2956
3040
  }
@@ -2958,21 +3042,20 @@ content, html, isOpen, setIsOpen, }) => {
2958
3042
  setInlineArrowStyles(computedStylesData.tooltipArrowStyles);
2959
3043
  }
2960
3044
  });
2961
- return () => {
2962
- mounted = false;
2963
- };
2964
- }, [
2965
- show,
2966
- isOpen,
2967
- anchorId,
2968
- activeAnchor,
2969
- content,
2970
- html,
2971
- place,
2972
- offset,
2973
- positionStrategy,
2974
- position,
2975
- ]);
3045
+ }, [show, activeAnchor, content, html, place, offset, positionStrategy, position]);
3046
+ require$$0.useEffect(() => {
3047
+ var _a;
3048
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
3049
+ const anchors = [...anchorsBySelect, anchorById];
3050
+ if (!activeAnchor || !anchors.includes(activeAnchor)) {
3051
+ /**
3052
+ * if there is no active anchor,
3053
+ * or if the current active anchor is not amongst the allowed ones,
3054
+ * reset it
3055
+ */
3056
+ setActiveAnchor((_a = anchorsBySelect[0]) !== null && _a !== void 0 ? _a : anchorById);
3057
+ }
3058
+ }, [anchorId, anchorsBySelect, activeAnchor]);
2976
3059
  require$$0.useEffect(() => {
2977
3060
  return () => {
2978
3061
  if (tooltipShowDelayTimerRef.current) {
@@ -2984,16 +3067,17 @@ content, html, isOpen, setIsOpen, }) => {
2984
3067
  };
2985
3068
  }, []);
2986
3069
  const hasContentOrChildren = Boolean(html || content || children);
2987
- return (jsxRuntime.exports.jsxs(WrapperElement, { id: id, role: "tooltip", className: classNames('react-tooltip', styles['tooltip'], styles[variant], className, {
2988
- [styles['show']]: hasContentOrChildren && !calculatingPosition && (isOpen || show),
3070
+ const canShow = hasContentOrChildren && show && Object.keys(inlineStyles).length > 0;
3071
+ return rendered ? (jsxRuntime.exports.jsxs(WrapperElement, { id: id, role: "tooltip", className: classNames('react-tooltip', styles['tooltip'], styles[variant], className, {
3072
+ [styles['show']]: canShow,
2989
3073
  [styles['fixed']]: positionStrategy === 'fixed',
2990
3074
  [styles['clickable']]: clickable,
2991
- }), style: { ...externalStyles, ...inlineStyles }, ref: tooltipRef, children: [children || (html && jsxRuntime.exports.jsx(TooltipContent, { content: html })) || content, jsxRuntime.exports.jsx(WrapperElement, { className: classNames('react-tooltip-arrow', styles['arrow'], classNameArrow, {
3075
+ }), style: { ...externalStyles, ...inlineStyles }, ref: tooltipRef, children: [(html && jsxRuntime.exports.jsx(TooltipContent, { content: html })) || content || children, jsxRuntime.exports.jsx(WrapperElement, { className: classNames('react-tooltip-arrow', styles['arrow'], classNameArrow, {
2992
3076
  [styles['no-arrow']]: noArrow,
2993
- }), style: inlineArrowStyles, ref: tooltipArrowRef })] }));
3077
+ }), style: inlineArrowStyles, ref: tooltipArrowRef })] })) : null;
2994
3078
  };
2995
3079
 
2996
- const TooltipController = ({ id, anchorId, content, html, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style, position, isOpen, setIsOpen, afterShow, afterHide, }) => {
3080
+ const TooltipController = ({ id, anchorId, anchorSelect, content, html, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style, position, isOpen, setIsOpen, afterShow, afterHide, }) => {
2997
3081
  const [tooltipContent, setTooltipContent] = require$$0.useState(content);
2998
3082
  const [tooltipHtml, setTooltipHtml] = require$$0.useState(html);
2999
3083
  const [tooltipPlace, setTooltipPlace] = require$$0.useState(place);
@@ -3005,7 +3089,11 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3005
3089
  const [tooltipWrapper, setTooltipWrapper] = require$$0.useState(wrapper);
3006
3090
  const [tooltipEvents, setTooltipEvents] = require$$0.useState(events);
3007
3091
  const [tooltipPositionStrategy, setTooltipPositionStrategy] = require$$0.useState(positionStrategy);
3008
- const { anchorRefs, activeAnchor } = useTooltip(id);
3092
+ const [activeAnchor, setActiveAnchor] = require$$0.useState(null);
3093
+ /**
3094
+ * @todo Remove this in a future version (provider/wrapper method is deprecated)
3095
+ */
3096
+ const { anchorRefs, activeAnchor: providerActiveAnchor } = useTooltip(id);
3009
3097
  const getDataAttributesFromAnchorElement = (elementReference) => {
3010
3098
  const dataAttributes = elementReference === null || elementReference === void 0 ? void 0 : elementReference.getAttributeNames().reduce((acc, name) => {
3011
3099
  var _a;
@@ -3072,9 +3160,30 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3072
3160
  require$$0.useEffect(() => {
3073
3161
  setTooltipHtml(html);
3074
3162
  }, [html]);
3163
+ require$$0.useEffect(() => {
3164
+ setTooltipPlace(place);
3165
+ }, [place]);
3075
3166
  require$$0.useEffect(() => {
3076
3167
  var _a;
3077
3168
  const elementRefs = new Set(anchorRefs);
3169
+ let selector = anchorSelect;
3170
+ if (!selector && id) {
3171
+ selector = `[data-tooltip-id='${id}']`;
3172
+ }
3173
+ if (selector) {
3174
+ try {
3175
+ const anchorsBySelect = document.querySelectorAll(selector);
3176
+ anchorsBySelect.forEach((anchor) => {
3177
+ elementRefs.add({ current: anchor });
3178
+ });
3179
+ }
3180
+ catch (_b) {
3181
+ {
3182
+ // eslint-disable-next-line no-console
3183
+ console.warn(`[react-tooltip] "${anchorSelect}" is not a valid CSS selector`);
3184
+ }
3185
+ }
3186
+ }
3078
3187
  const anchorById = document.querySelector(`[id='${anchorId}']`);
3079
3188
  if (anchorById) {
3080
3189
  elementRefs.add({ current: anchorById });
@@ -3082,7 +3191,7 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3082
3191
  if (!elementRefs.size) {
3083
3192
  return () => null;
3084
3193
  }
3085
- const anchorElement = (_a = activeAnchor.current) !== null && _a !== void 0 ? _a : anchorById;
3194
+ const anchorElement = (_a = activeAnchor !== null && activeAnchor !== void 0 ? activeAnchor : anchorById) !== null && _a !== void 0 ? _a : providerActiveAnchor.current;
3086
3195
  const observerCallback = (mutationList) => {
3087
3196
  mutationList.forEach((mutation) => {
3088
3197
  var _a;
@@ -3111,10 +3220,11 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3111
3220
  // Remove the observer when the tooltip is destroyed
3112
3221
  observer.disconnect();
3113
3222
  };
3114
- }, [anchorRefs, activeAnchor, anchorId]);
3223
+ }, [anchorRefs, providerActiveAnchor, activeAnchor, anchorId, anchorSelect]);
3115
3224
  const props = {
3116
3225
  id,
3117
3226
  anchorId,
3227
+ anchorSelect,
3118
3228
  className,
3119
3229
  classNameArrow,
3120
3230
  content: tooltipContent,
@@ -3138,6 +3248,8 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3138
3248
  setIsOpen,
3139
3249
  afterShow,
3140
3250
  afterHide,
3251
+ activeAnchor,
3252
+ setActiveAnchor: (anchor) => setActiveAnchor(anchor),
3141
3253
  };
3142
3254
  return children ? jsxRuntime.exports.jsx(Tooltip, { ...props, children: children }) : jsxRuntime.exports.jsx(Tooltip, { ...props });
3143
3255
  };