Skip to content

Hover Popover / more robust Tooltip #8905

@selrond

Description

@selrond

Provide your feedback here.

There are a couple of issues where people (myself included) were confused to find that tooltip position is off when focusable content is used inside of it:

The reason I was doing it was that I needed to display some content on hover, and Tooltip seemed like the most straightforward option.
There was some discussion about wiring up a controlled popover with hover detection, but it’s not trivial to set up.

In my understanding, the reason why the tooltip appears incorrectly positioned is roughly as follows:

  1. TooltipTrigger provides ref to the FocusableProvider, which is consumed by all elements that use the useFocusable hook here.
  2. That ref is then used in useOverlayPosition for calculating the tooltip position
  3. After the tooltip opens, given there’s some focusable content within it, that content replaces the correct ref of the trigger, and eventually the tooltip tries to reposition based on the newfound ref. It happens fast, so most of the time one sees only the end result, even though it can go through multiple repositionings based on how many interactive elements are within it & how they render.

What I had to do to "fix" it, is implement a context barrier, to prevent nested focusable elements from replacing the tooltip trigger ref. It works by setting the ref to null for all its children, effectively making the original trigger ref inaccessible down the tree.

import { FocusableProvider } from '@react-aria/interactions';

<TooltipTrigger>
  <Button>
    Hover me
  </Button>
  <Tooltip>
    // The context barrier
    <FocusableProvider ref={null}>
      <Button>Click me</Button>
    </FocusableProvider>
  </Tooltip>
</TooltipTrigger>

Now I get that it’s inaccessible, but the tooltip is already inaccessible for touch devices, so it serves just as a UX improvement for mouse users anyway.

In any way, I think it could be made more robust (prevent ref leaking to its content for instance), or — better yet — there could be a new component for such behavior (hover popover — an overlay element positioned relative to a trigger triggered by hover). Aria APG recommends using non-modal dialogs for that, so I guess it can be made accessible.

Based on previous discussions, there seems to be a real demand for it:

🔦 Context

No response

💻 Code Sample

No response

Version

No response

What browsers are you seeing the problem on?

No response

If other, please specify

No response

What operating system are you using?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions