Skip to content

fix(a11y): make click-only controls keyboard operable - #741

Open
beruro wants to merge 4 commits into
developfrom
junyu/fix-a11y-keyboard-controls
Open

fix(a11y): make click-only controls keyboard operable#741
beruro wants to merge 4 commits into
developfrom
junyu/fix-a11y-keyboard-controls

Conversation

@beruro

@beruro beruro commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Problem

Seven visible frontend controls were mouse-only: non-semantic click targets had no focus stop, keyboard activation, or exposed state. Keyboard and assistive-technology users could not operate collapsed diff rows, JSON nodes, the replace disclosure, the date trigger, simulator rows, or the primary BrowseCard action.

Solution

  • Use native buttons for the SearchInput and DateRangeSelector triggers.
  • Retain specialized diff/tree/list row elements only where their layout or nested controls rule out a generic button, and add role, focusability, Enter/Space activation, ARIA state/name, and focus-visible treatment.
  • Make JSON row click and keyboard handlers conditional so primitive rows remain inert.
  • Represent BrowseCard's primary hit area as a named stretched sibling button, keeping the secondary action non-nested and independently operable.
  • Reuse the existing createKeyboardActivationHandler; no new behavior abstraction was introduced.

The frontend UI audit is recorded in docs/frontend-ui-audit-2026-08-07/KeyboardOperability.md: 7 accessibility fixes, 7 raw-element decisions kept with documented design-system reasons, and 0 abstraction candidates.

Potential risks

  • BrowseCard secondary-action clicks no longer bubble into the primary card action. No current caller uses that branch, but future callers must treat the actions as independent.
  • Simulator and expandable JSON rows add intentional tab stops; primitive JSON rows remain inert, and existing virtualization bounds rendered list rows.
  • Two trigger elements changed from div to native button; repository CSS resets cover native defaults, but untracked downstream structure selectors could differ.
  • Focus-visible styling has not yet been captured inside the real Tauri desktop shell. The plain browser dev server cannot initialize getCurrentWindow() without Tauri window metadata; desktop visual QA/screenshots remain a manual review follow-up.
  • No Effect was added or modified. Rollback is a normal revert; there is no data, API, dependency, or persistence migration.

Verification

Current published head da4d7e818 includes the shared SSR test stabilization from develop. GitHub CI run 31462512942 passed frontend typecheck, lint, unit tests, and Rust Clippy; the attribution check also passed.

  • ./node_modules/.bin/vitest run src/util/dom/__tests__/keyboardActivation.test.ts src/engines/ChatPanel/components/DebugJsonViewer/DebugJsonViewer.test.tsPASS, 2 files / 7 tests.
  • git diff --name-only origin/develop...HEAD -- '*.ts' '*.tsx' | xargs ./node_modules/.bin/eslintPASS, no errors or warnings.
  • ./node_modules/.bin/tsc --noEmit --pretty falsePASS.
  • git diff --check origin/developPASS.
  • npm run dev:frontend:light and browser navigation to the local app — frontend compiled, but desktop visual QA was NOT COMPLETED because the non-Tauri browser host fails at Tauri window metadata initialization.
  • Merge of current origin/developPASS, no conflicts; automated checks were run after integration.

@beruro
beruro force-pushed the junyu/fix-a11y-keyboard-controls branch from a7498af to 873ffd8 Compare August 10, 2026 04:04
@beruro
beruro force-pushed the junyu/fix-a11y-keyboard-controls branch from ea19c80 to 87ae079 Compare August 10, 2026 05:47
@beruro
beruro marked this pull request as ready for review August 11, 2026 05:16
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