Skip to content

fix: add command palette keyboard navigation - #50

Merged
smiggleworth merged 5 commits into
mainfrom
fix/49-command-palette-keyboard
Aug 15, 2026
Merged

fix: add command palette keyboard navigation#50
smiggleworth merged 5 commits into
mainfrom
fix/49-command-palette-keyboard

Conversation

@smiggleworth

@smiggleworth smiggleworth commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Closes #49.

Summary

  • add an accessible combobox/listbox active-result contract to documentation search
  • support wrapping ArrowDown/ArrowUp selection while focus remains in the search input
  • activate the selected result with Enter through the real router link
  • run the reported keyboard path in a real Chromium browser during normal CI and deployment validation
  • release the website as 0.1.2

TDD evidence

  • Red 1674a687bfcbca9ca119c804465933409121050a: a real Chromium test opened the palette, typed createSPA, and pressed ArrowDown; focus remained in the input but aria-activedescendant stayed absent and no result became active.
  • Green 71de82cbb91f8f15cb81998f45564ce39eb1a1df: the same real-keyboard flow selects the first result, wraps ArrowUp to the last result and ArrowDown back to the first, then Enter performs a real route navigation to the selected destination.
  • Test-pool guard 972133d18bb2dbad02d28ac33c958755791a81fe: browser regressions are excluded from the unit worker pool by a quoted cross-platform glob and run only through the browser-mode configuration.
  • Cold-cache guard e64880e132a3417ca5bf4e3e48c975160e4af4c9: hosted run 31915052863 proved the dependency scanner could transform JSX in the test before the Askr plugin was active. The destination fixture now uses Askr's public jsx runtime without JSX syntax, and the browser regression passes after moving the entire local Vite optimizer cache aside.
  • Full local gate at release commit 843c4fe7c3809090323190595209c8979c9c883f: format, lint, types, 37 unit tests, the Chromium interaction regression, production client build, 276 generated Markdown pages, 286/286 successful SSG routes, and static-output contracts all passed; npm audit --omit=dev reported 0 vulnerabilities.

Root cause and permanent guardrails

  • The search field and result links had no shared active-result state or keyboard dispatcher, so the visual command-palette treatment did not have command-palette behavior. The input now owns a bounded active index, resets it on every query, wraps only across live results, exposes the active option through aria-activedescendant, and invokes only that live result on Enter.
  • Result rows have stable list-local IDs, role="option", aria-selected, and a visible data-active state; the surrounding input/list use the combobox/listbox relationship while DOM focus remains in the input for uninterrupted typing.
  • The regression uses public rendered behavior, real userEvent keyboard input, and an actual registered destination. It asserts focus ownership, active-result semantics, visual state, wrapping in both directions, and final URL navigation.
  • npm test includes browser mode, and both CI and deployment workflows install Chromium before validation. Quoted pool exclusion prevents the browser file from silently falling into a non-browser worker on any shell; the JSX-free test fixture makes the dependency scan cold-cache safe instead of depending on a prior local optimization pass.

Acceptance audit

  • Reporter ownership and the issue contract were read back from GitHub.
  • The real browser regression was committed red before implementation.
  • The same regression passes green for ArrowDown, ArrowUp, active-result state, focus retention, and Enter navigation.
  • Permanent semantic, behavioral, visual, routing, and workflow guardrails cover the bug class.
  • Full local build, SSG, static-output, and production-audit gates pass at the release commit.
  • Exact-head hosted CI succeeds.
  • Every issue acceptance checkbox is checked with evidence before ready-for-review and squash merge.
  • The exact squash-merged main SHA deploys successfully to GitHub Pages and the live production keyboard flow passes.

@smiggleworth
smiggleworth marked this pull request as ready for review August 15, 2026 23:42
Copilot AI lite review requested due to automatic review settings August 15, 2026 23:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@smiggleworth
smiggleworth merged commit a8912f0 into main Aug 15, 2026
1 check passed
@smiggleworth
smiggleworth deleted the fix/49-command-palette-keyboard branch August 15, 2026 23:43
@smiggleworth

Copy link
Copy Markdown
Contributor Author

Post-merge production proof is complete. Deploy run 31915463739 succeeded at squash-merged main a8912f013d5045b2534ecb9fc7bf92e06b7ee61e. On the live https://askrjs.com/ deployment, I opened Search docs, entered createSPA, and verified the real combobox retained focus while ArrowDown set aria-activedescendant=docs-search-result-0; the matching option exposed the same ID plus aria-selected=true and data-active=true. ArrowUp wrapped to the same sole live result without moving focus, and Enter navigated to https://askrjs.com/docs/reference/api/askr/boot#create-spa, where the createSPA destination is visible.

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.

Command-palette search doesn't support arrow-key navigation between results

2 participants