react-spectrum icon indicating copy to clipboard operation
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.

Open GuoXiaoyang opened this issue 1 year ago โ€ข 3 comments

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

  1. It seems the closeOpenTooltips function in packages/@react-stately/tooltip/src/useTooltipTriggerState.ts is not working properly when the isOpen prop is controlled, when the close handler is called, the currentValue(open) in useControlledState is still false thus not trigger the onOpenChange handler 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

  1. 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

GuoXiaoyang avatar Apr 19 '24 03:04 GuoXiaoyang

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

snowystinger avatar Apr 19 '24 03:04 snowystinger

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

igorman007 avatar May 17 '24 20:05 igorman007

Thanks for the analysis, would you like to open a PR for it?

snowystinger avatar May 18 '24 00:05 snowystinger