Skip to content

Fix modal focus trapping for elements excluded from tab order - #2864

Open
huytdps13400 wants to merge 1 commit into
necolas:masterfrom
huytdps13400:fix/modal-reverse-focus
Open

huytdps13400 wants to merge 1 commit into
necolas:masterfrom
huytdps13400:fix/modal-reverse-focus

Conversation

@huytdps13400

Copy link
Copy Markdown
Contributor

When a modal contains a ScrollView with focusable={false} or tabIndex={-1}, reverse keyboard navigation can get stuck on the scroll container. The trap calls .focus() on candidates, which succeeds even for elements explicitly excluded from the tab order. Its first/last focus comparison therefore never reaches the buttons inside the scroll view.

Skip candidates with an explicit negative tabindex when choosing a focus-trap destination, while continuing to search their descendants. This also avoids selecting excluded buttons at the edges of a modal. Explicit programmatic focus inside the modal remains allowed, and the existing trap fallback still handles content with no eligible descendants.

Fixes #2823 for the reported focusable={false} / tabIndex={-1} configuration.

Validation

  • Added five regression/control tests. On the base, the Modal suite has 4 failures and 33 passes; after the change, all 37 tests pass.
  • Chrome 153, React 18.3.1, rendered Modal + overflowing ScrollView: four consecutive Shift+Tab presses previously focused the excluded scroll container every time. After the change, both Tab and Shift+Tab alternate between the first and last buttons for both supported prop configurations.
  • Browser controls cover contenteditable without an explicit tabindex, fallback when all descendants are excluded, and restoring focus to the trigger after Escape closes each modal.
  • Full DOM and Node suites: 726 tests passed, 6 skipped, 220 snapshots passed. Full lint, formatting and library build pass.
  • Flow 0.148 cannot run on this ARM host: its bundled macOS binary is x86_64 and exits with spawn error −86. Flow checking is unverified locally.

The browser can also programmatically focus a scroll container with no explicit tabindex. That existing behavior remains unchanged; this patch specifically honors elements explicitly excluded from the tab order.

@codesandbox-ci

codesandbox-ci Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 6f9902f:

Sandbox Source
react-native-web-examples Configuration

@huytdps13400
huytdps13400 force-pushed the fix/modal-reverse-focus branch from 510d3ce to 6f9902f Compare October 5, 2026 06:54

This branch has not been deployed

No deployments
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.

ScrollView accessibility issue - focusable items not accessible with keyboard, when using Shift+Tab key

1 participant