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
13.08k stars 1.14k forks source link

Toggle Popover on click and hover #5535

Open alekseykurylev opened 11 months ago

alekseykurylev commented 11 months ago

Provide a general summary of the feature here

Add the ability to display Popover simultaneously on hover and on click

๐Ÿค” Expected Behavior?

Displayed by click and hover

๐Ÿ˜ฏ Current Behavior

It is displayed only by click

๐Ÿ’ Possible Solution

No response

๐Ÿ”ฆ Context

In conventional js frameworks such as Bootstrap or UIKit, it has always been possible to open Popover or Tooltip or Dropdow simultaneously using a hover and a click. And it works great on all devices. I don't understand why you decided that opening Popover is possible only by clicking, and opening Tooltip only by hover, which makes it useless on a mobile device.

๐Ÿ’ป Examples

https://getbootstrap.com/docs/5.3/components/popovers/ https://getuikit.com/docs/drop

A great example of a Popover reaction component from Mantine https://mantine.dev/core/popover/

๐Ÿงข Your Company/Team

No response

๐Ÿ•ท Tracking Issue

No response

snowystinger commented 11 months ago

Thanks for the issue. You can do this by controlling the open state https://codesandbox.io/p/sandbox/wandering-star-5ncllz?file=%2Fsrc%2FApp.js%3A13%2C32 (you could further clean it up to ignore a press on the button if it's already open)

Tooltips are definitely not meant for touch, and we say that in our docs https://react-spectrum.adobe.com/react-aria/Tooltip.html#accessibility This is because people frequently put both tooltips and some other popover (menu/dialog/etc) on the same element OR they have an action which should happen on press. So we can't support opening Tooltips on touch. Instead, as the docs recommend, a popover should be used.

As for why Popovers don't open by default for mouse hover, we don't want people to target hover as an interaction because it excludes so many users. So if you're going to do it, it should be very intentional. It also runs the risk of colliding with Tooltips.

Hopefully that answers your questions.

alekseykurylev commented 11 months ago

You can do this by controlling the open state https://codesandbox.io/p/sandbox/wandering-star-5ncllz?file=%2Fsrc%2FApp.js%3A13%2C32 (you could further clean it up to ignore a press on the button if it's already open)

Thanks! I agree with you on Tooltips. But let's go back to Popover, how can I control the state of the Popover when it opens on the hover, for example, automatic hiding if the cursor is removed from the Popover?

devongovett commented 11 months ago

Button has onHoverStart and onHoverEnd events you could probably use

alekseykurylev commented 11 months ago

It seemed to me that this was an obvious UI element of the interface. I don't understand why many UI libraries for React skip it. For example, many sites have a drop-down menu or drop-down content (an authorization form or a list of products in the shopping cart) that is displayed when the cursor is hovered over. Check out this great example of a similar component https://getuikit.com/docs/drop or https://www.naiveui.com/en-US/os-theme/components/dropdown

Popover in 'react-aria-components' is a great component, but it lacks trigger hover with additional behavior options.

Button has onHoverStart and onHoverEnd events you could probably use

@devongovett, I meant when the cursor is removed from the Popover. Have you tried to do what you recommend to me?

snowystinger commented 11 months ago

You could add a pointerLeave to the div inside the popover, though keep in mind some people do not have fine control over a mouse and may leave accidentally, thereby closing the popover unintentionally.

Trying to do it for the trigger button is a bit more difficult because there is an invisible underlay which sits over the trigger blocking interactions with the background. This is intentional for several reasons: focus, scrolling, and unintentional interactions, to name a few.

So to handle the unhover for the button, you'd probably want to track the position of the mouse and the button's bounding box to do your own hit testing.