adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.9k stars 1.12k forks source link

useHover not affected by Popup #4951

Open rschoenbichler opened 1 year ago

rschoenbichler commented 1 year ago

Provide a general summary of the issue here

useHover is not affected by overlays/popups

๐Ÿค” Expected Behavior?

When a popup is triggered from within an element which has useHover wired to it, isHovered should get set to false once the popup is visible.

๐Ÿ˜ฏ Current Behavior

isHovered is only set to false when the popup is closed, the element is hovered again and then left again with the mouse

๐Ÿ’ Possible Solution

No response

๐Ÿ”ฆ Context

No response

๐Ÿ–ฅ๏ธ Steps to Reproduce

https://codesandbox.io/s/naughty-neumann-llqllg?file=/src/App.js

Version

3.18

What browsers are you seeing the problem on?

Chrome

If other, please specify.

No response

What operating system are you using?

linux

๐Ÿงข Your Company/Team

No response

๐Ÿ•ท Tracking Issue

No response

snowystinger commented 1 year ago

Seems like a bug. I suspect that the hover is coming through the portal thanks to React, so we could do like we do for keyboard events when there is a portal https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/actiongroup/src/useActionGroup.ts#L45 in order to stop the hover.

There's another issue I think, which is that when an element is removed, it doesn't fire pointer out or any of that. This is why currently you have to hover back over the original button before it clears. This should become a non-issue if we fix the hover coming through the portal.

rschoenbichler commented 1 year ago

I can't follow this line of thought @snowystinger as the overlay is not even an descendant of the hover. Further, the hover state still remains after closing the overlay which also seems to contradict your assumption.

I would think that the overlay stops propagation of the mouse events as well as default behavior. As a side note: I've created this issue which seems to be related imo: https://github.com/adobe/react-spectrum/issues/4961

snowystinger commented 1 year ago

In the React tree, it's a descendant of the element you placed the hoverProps on.

Here is a reduced version of what is happening https://codesandbox.io/s/serene-butterfly-4tlrp3?file=/src/App.js

As a result, I think we can make the fix I pointed out in useHover itself. We might also need to unhover at the same time as we block the portaled descendant hover, just to get cleanup to happen as well.