feat(a11y): dismiss transient outline overlay on focus-out (A11Y-03) - #245
Merged
Conversation
The outline sidebar is a non-modal role=tree, so it deliberately does not trap Tab (pinned mode is a persistent pane where Tab must flow between the sidebar and editor). To resolve the one wart — a transient overlay left floating over the editor with keyboard focus behind it — the overlay now self-dismisses when focus leaves the sidebar, mirroring the footer settings popover's click-outside close. Pinned mode never closes on focus-out; window blur (null relatedTarget) and intra-sidebar focus moves are guarded out.
…ader onSidebarFocusOut is modality-agnostic (reads only relatedTarget), so the overlay dismisses on any focus leaving the sidebar, not just keyboard Tab-out. The other three comments describing this path already omit "keyboard"; align the module header with them. (PR #245 review, comment-analyzer HIGH/88.)
The sidebarEl.contains() guard's JSDoc calls out the footer settings popover as the fragile branch (any future portal-out would break it). Add a test asserting focus moving into the DOM-descended popover does NOT dismiss the overlay. (PR #245 review, code-quality MEDIUM/83.)
…width Review-cycle SIMPLIFY: the A11Y-03 header edit left one ~110-char comment line breaking the file's ~76-char wrap rhythm. Reflow into evenly-wrapped lines; wording byte-preserved.
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.
Summary
Resolves a11y finding A11Y-03 (LOW). Records a deliberate decision — the outline sidebar is a non-modal
role=tree, not a modal dialog, so it does not trap Tab — and fixes the one real wart: a transient overlay left floating over the editor with keyboard focus behind it.Decision (non-modal, no Tab trap)
aria-modal/ obscured background) the panel does not have, and break the module's CSS-only overlay/pinned distinction.focusoutwhen focus leaves the sidebar, mirroring the footer settings-popover's click-outside close. Pinned mode never closes on focus-out.Design validated by Codex (endorsed non-modal + overlay focus-out dismiss over a hard trap).
Changes
outline-panel.ts: addonSidebarFocusOut+ afocusoutlistener on the sidebar. Guards:!open(mid-close no-op),pinned(persistent pane stays open),relatedTarget === null(window blur / cross-context keeps it open),sidebarEl.contains(relatedTarget)(intra-sidebar moves, incl. into the DOM-descended footer popover, are not leaves). Updated module header + "Closing paths" comments.outline-panel.test.ts: newdescribe("quollOutline overlay focus-out dismiss")pinning all four behaviours (overlay dismisses to editor; pinned stays open; intra-sidebar move stays open; null relatedTarget stays open). Non-vacuity verified (neutering the handler makes the dismiss test go red).Related
Test Plan
pnpm compilegreenpnpm test:unitgreen (3816 passed; 4 new)