fix: restore visible focus-visible outline on CommandPalette input - #802
Merged
greatest0fallt1me merged 1 commit intoJul 28, 2026
Conversation
Closes CalloraOrg#699 Note on scope: the issue references src/pages/OnboardingTour.tsx and does not exist anywhere in this repo (confirmed via full-text and git history search) — there is no tour/walkthrough/spotlight feature of any kind in this codebase. The literal, universal requirement ("visible keyboard-only focus outlines on every interactive element") is already substantially satisfied globally: src/index.css defines a single @layer focus with *:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px }, reinforced per-component across most existing pages (see src/styles/focus.css and the extensive focus-layer.test.ts suite this repo already maintains for exactly this kind of regression). Since there's no OnboardingTour to fix, I audited every remaining unconditional `outline: none` in the codebase for the one bug class this repo's own focus-layer.test.ts already tests for (see e.g. "Dropdown trigger no longer overrides :focus-visible with inline outline:none"). Two were legitimate design choices with an equally-visible substitute indicator (ParamsBuilder / RequestBodyEditor raw-body textareas use a `.pb-raw-shell:focus-within` / `.rbe-shell:focus-within` wrapper border + box-shadow instead of an outline on the textarea itself — not a bug). One was real: CommandPalette.css is imported directly (unlayered — never wrapped in @layer focus), and `.command-palette-input { outline: none; }` was unconditional, with no :focus-visible restoration anywhere in the file. Per CSS cascade layer rules, an unlayered declaration always beats a layered one regardless of specificity, so nothing in @layer focus could ever restore this input's outline. Every keyboard user tabbing into or typing in the command palette's primary search field (Cmd/Ctrl+K) got zero visible focus indicator — a real WCAG 2.4.7 violation. Fixed by splitting the unconditional outline:none into the same suppress-on-:focus / restore-on-:focus-visible pattern used by the global reset, so it's correct standalone regardless of layer/cascade context. Also added explicit :focus-visible reinforcement for the clear/close buttons, matching this repo's established convention of stating per-component coverage explicitly for audits even where the global rule already technically applies (see focus.css's own header comment). Tests: 4 new source-assertion cases in focus-layer.test.ts, following this repo's own established convention for this exact class of bug (regex assertions against the CSS source — see the existing Dropdown test). Confirms the unconditional outline:none is gone, the :focus-visible restoration exists with the correct accent token, the :focus suppression is conditional not blanket, and the clear/close buttons have explicit reinforcement. npx vitest run src/focus-layer.test.ts src/components/CommandPalette.test.tsx Test Files 2 passed (2) Tests 28 passed (28)
|
@16navigabraham Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
Merged into main via admin resolver (-X theirs). |
Contributor
|
Nice work, everything checks out. Merged 🎉 |
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.
Closes #699
Note on scope
The issue references
src/pages/OnboardingTour.tsx, which does not exist anywhere in this repo (confirmed via full-text search and git history) — there is no tour/walkthrough/spotlight feature of any kind in this codebase. The literal, universal requirement ("visible keyboard-only focus outlines on every interactive element") is already substantially satisfied globally:src/index.cssdefines a single@layer focuswith*:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px }, reinforced per-component across most existing pages (seesrc/styles/focus.cssand the extensivefocus-layer.test.tssuite this repo already maintains for exactly this kind of regression).What I did instead
Since there's no OnboardingTour to fix, I audited every remaining unconditional
outline: nonein the codebase for the one bug class this repo's ownfocus-layer.test.tsalready tests for (see e.g. "Dropdown trigger no longer overrides :focus-visible with inline outline:none").ParamsBuilder/RequestBodyEditor's raw-body textareas use a.pb-raw-shell:focus-within/.rbe-shell:focus-withinwrapper (border-color + box-shadow) instead of an outline on the textarea itself — not a bug, left alone.CommandPalette.cssis imported directly (unlayered — never wrapped in@layer focus), and.command-palette-input { outline: none; }was unconditional, with no:focus-visiblerestoration anywhere in the file. Per CSS cascade layer rules, an unlayered declaration always beats a layered one regardless of specificity, so nothing in@layer focuscould ever restore this input's outline. Every keyboard user tabbing into or typing in the command palette's primary search field (Cmd/Ctrl+K) got zero visible focus indicator — a real WCAG 2.4.7 violation.Fix
Split the unconditional
outline: noneinto the same suppress-on-:focus/ restore-on-:focus-visiblepattern used by the global reset, so it's correct standalone regardless of layer/cascade context. Also added explicit:focus-visiblereinforcement for the clear/close buttons, matching this repo's established convention of stating per-component coverage explicitly for audits even where the global rule already technically applies (seefocus.css's own header comment).Tests
4 new source-assertion cases in
focus-layer.test.ts, following this repo's own established convention for this exact class of bug (regex assertions against the CSS source — see the existing Dropdown test). Confirms the unconditionaloutline:noneis gone, the:focus-visiblerestoration exists with the correct accent token, the:focussuppression is conditional not blanket, and the clear/close buttons have explicit reinforcement.Repo-wide
npx vitest runhas 68 pre-existing failures across 13 files (confirmed unrelated — none touchCommandPalette.css/focus-layer.test.ts).