Skip to content

feat(focus-scope): Take shadow DOM elements in consideration for focus management#3838

Open
fbouquet wants to merge 22 commits intoradix-ui:mainfrom
fbouquet:focus-scope-shadow-dom
Open

feat(focus-scope): Take shadow DOM elements in consideration for focus management#3838
fbouquet wants to merge 22 commits intoradix-ui:mainfrom
fbouquet:focus-scope-shadow-dom

Conversation

@fbouquet
Copy link
Copy Markdown

@fbouquet fbouquet commented Apr 2, 2026

This extends @cpsoinos's PR (#3674) with an additional fix to ensure that shadow DOM elements are properly handled in the context of container with trapped focus.

Before my additional changes, the focus edges in a trapped context were not properly determined, resulting in the user not being able to focus on elements within a shadow DOM if they are after the last interactive element that is not in a shadow DOM. See the screen recording below for an example.

Also adding tests to prevent regression, and a story to showcase the changes.

Before (frenetically hitting Tab just keeps the focus on the "Close" button):

Screen.Recording.2026-04-02.at.19.21.18.mov

After:

Screen.Recording.2026-04-02.at.19.21.56.mov

cpsoinos and others added 22 commits April 2, 2026 19:27
- Add data-radix-menu-sub-trigger attribute to MenuSubTrigger for proper identification
- Implement custom event system for explicit submenu closure in shadow DOM contexts
- Disable automatic grace timer closure in shadow DOM to prevent premature submenu closing
- Use native event coordinates for improved accuracy in shadow DOM environments
- Extend grace period to 800ms in shadow DOM to account for coordinate detection limitations
- Ensure only one submenu remains open when navigating between multiple subtriggers

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unnecessary empty lines and unused variables
- Extract shadow DOM detection into reusable utility function
- Simplify coordinate handling by removing unused adjustments
- Revert isPointerInGraceArea changes that weren't needed for the fix
- Reduce code duplication in shadow DOM detection logic

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
… DOM

The logic was unnecessary, and infact, was incorrect, as it was running when _not_ in a shadow DOM
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 2, 2026

⚠️ No Changeset found

Latest commit: 5b154e5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@fbouquet
Copy link
Copy Markdown
Author

fbouquet commented Apr 7, 2026

@chaance, are you the right person to ping for reviewing this PR, or should I ping someone else? 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants