react-spectrum
react-spectrum copied to clipboard
When multiple tooltips are open controlled, the first tooltip would not close after the cursor hovers on the second tooltip.
Provide a general summary of the issue here
When multiple tooltips are open controlled, the first tooltip would not close after the cursor hovers on the second tooltip.
๐ค Expected Behavior?
The first tooltip would close after the cursor hovers on the second tooltip.
๐ฏ Current Behavior
http://localhost:9003/?path=/story/tooltiptrigger--controlled-multiple-tooltips&providerSwitcher-express=false&strict=true
https://github.com/adobe/react-spectrum/assets/8994590/3e45b13d-f286-4b77-b684-2824c21272a5
๐ Possible Solution
- It seems the
closeOpenTooltipsfunction inpackages/@react-stately/tooltip/src/useTooltipTriggerState.tsis not working properly when theisOpenprop is controlled, when the close handler is called, the currentValue(open) inuseControlledStateis still false thus not trigger theonOpenChangehandler in the Tooltip.
let closeOpenTooltips = () => {
for (let hideTooltipId in tooltips) {
if (hideTooltipId !== id) {
tooltips[hideTooltipId](true);
delete tooltips[hideTooltipId];
}
}
};
๐ฆ Context
No response
๐ฅ๏ธ Steps to Reproduce
- The story in the react-spectrum repo can reproduce this issue: http://localhost:9003/?path=/story/tooltiptrigger--controlled-multiple-tooltips&providerSwitcher-express=false&strict=true
Version
3.32.1
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
MacOS
๐งข Your Company/Team
No response
๐ท Tracking Issue
No response
Thanks for the issue, looks like a regression was introduced at some point. This story used to work.
Found the PR where it broke https://github.com/adobe/react-spectrum/pull/4564
We also found this bug.
Seems, that the problem takes place in this line of code https://github.com/adobe/react-spectrum/blob/main/packages/%40react-stately/tooltip/src/useTooltipTriggerState.ts#L84
When the function closeOpenTooltips is called, it calls the open variable (function) I linked to. But the function instance inside open variable is the wrong instance, because it has been created when props.isOpened was false (the function memoize false value in it's closure).
So this line of check https://github.com/adobe/react-spectrum/blob/main/packages/%40react-stately/utils/src/useControlledState.ts#L34 returns false.
currenValue (props.isOpened inside closure) is false (while the actual value inside props.isOpened is true)
value is false
That's why we missing the call of onChange and the actual value inside props.isOpened remains true.
Fastfix: set the closeDelay prop to 0
Simple fix: I think we can use the same idea, that is used in this line of code https://github.com/adobe/react-spectrum/blob/main/packages/%40react-stately/tooltip/src/useTooltipTriggerState.ts#L48
We can make one more useRef and saves the correct instance of close function inside it. And call it instead of calling the wrong close function on line 84
Thanks for the analysis, would you like to open a PR for it?