Repository navigation
[6.x] Keep keyboard focus inside the licensing alert - #15673
Merged
jasonvarga merged 3 commits intoOct 20, 2026
Merged
Conversation
jasonvarga
deleted the
15673-modal-focus-trap-behind-fullscreen-portals
branch
October 20, 2026 17:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of the Problem
When the licensing alert shows on page load, keyboard focus can end up in a field behind the blurred backdrop rather than in the alert. On an entry with a Bard field, for example, the cursor sits in the Title field, so typing goes into the entry and Tab moves through the page behind.
Modals only trap focus while they're the topmost portal, and "topmost" meant the last portal created. Bard, Markdown, Replicator, Grid, Group, Table and the code editor all register a portal for their fullscreen mode as soon as they load, even when they aren't fullscreen. If those fields load after the alert opens, the alert stops being "topmost", its focus trap switches off, and the Title field's autofocus takes focus.
What this PR Does
Portals now know whether they're disabled, and
portals.top()skips disabled ones. A disabled portal renders in place rather than on top of anything, so it shouldn't count. Modals usetop()to decide whether to trap focus. A field that's actually in fullscreen still counts as on top, so focus stays inside it.I went for this rather than special-casing the licensing alert or stopping the Title field autofocusing while a modal's open, as the cause is in how the top portal is worked out. Any modal that opens before those fields load would hit the same thing.
Stacks have the same "last portal created" check. I've left them alone here because changing it would start trapping focus in most entry-editing stacks, which deserves its own PR.
The new methods are
portals.top(),portals.isDisabled(id),portals.setDisabled(id, bool)andportal.setDisabled(bool). They're all additions, and nothing existing changes.How to Reproduce
localStorage.removeItem('statamic.snooze_license_banner')in the console.