radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.95k stars 834 forks source link

Bug: Tabbing away from a Tooltip inside a Dialog moves focus to the Dialog root #3185

Open airjp73 opened 1 month ago

airjp73 commented 1 month ago

Bug report

Current Behavior

When a tooltip is inside a dialog, tabbing away from the tooltip button moves focus back to the dialog root instead of the next focusable element in the dialog.

In this video made using the reproduction below you can see that, when I tab away from the Tooltip button, focus skips After tooltip entirely and goes straight to the dialog root.

At the end of the video, I press Escape before tabbing away from the tooltip. This closes the tooltip and then focus moves as expected.

https://github.com/user-attachments/assets/60f6d249-ca24-43f8-a612-7ec937326f43

Expected behavior

When you press tab while focused on a tooltip button, focus should move to the next focusable element.

Reproducible example

Reproduction in code sandbox

Suggested solution

I'm not familiar enough with the codebase to make a definite suggestion here. It might have something to do with react-focus-lock?

Additional context

When tabbing away from the tooltip button, the focusout event that fires does indeed have a relatedTarget set to the next element in the tab order. So something in the Dialog component is likely listening to that and manually changing the focus.

Your environment

Software Name(s) Version
Radix Package(s) react-dialog, react-tooltip 1.1.2, 1.1.3
React n/a 18.3
Browser Arc Version 1.65.0 (54911) -- Chromium Engine Version 130.0.6723.59
Assistive tech n/a n/a
Node n/a 20.9
npm/yarn bun 1.0.7
Operating System MacOS Sonoma 14.4.1
trajce commented 1 week ago

We have the same issue, instead of tabbing through the focusable elements it tabs through the first two elements (like in the video) and then tabs out to the dialog root. In our case we just use the dialog component - no tooltip.