Skip to content

fix(viewport): let the Species and Interactors controls be used without a mouse - #212

Merged
adamjohnwright merged 4 commits into
mainfrom
fix/header-controls-keyboard
Sep 16, 2026
Merged

adamjohnwright merged 4 commits into
mainfrom
fix/header-controls-keyboard

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Closes #211, which I filed while reviewing #208.

Both header controls were plain <div>s with a click handler. Measured on beta:

{ "role": null, "tabindex": null, "ariaLabel": null, "focusable": false }

So neither could be focused or activated from the keyboard, and neither was
announced as anything at all. They are the way in to species filtering and to the
interactor overlay — the whole feature, closed to anyone not using a mouse.

What changed

Each carries a role, a tabindex, Enter/Space handling, a label, and an
aria-expanded that follows the panel. They keep their markup rather than
becoming <button>s: these divs carry layout the surrounding flex rules depend
on, and a button brings its own.

Space calls preventDefault() — the default action for Space on a focused
element is to scroll the page, and the test asserts it doesn't.

Verification

The e2e case drives them the way someone without a mouse does — focus, then a key
— rather than checking the attributes exist. The attributes are the mechanism;
reaching the panel is the thing.

Shown red against the old markup, failing at the first assertion: the control
would not take focus.

240 unit tests, lint 652 and dead code 145 unchanged.

🤖 Generated with Claude Code

…ut a mouse

Closes #211, found while reviewing #208.

Both were plain divs with a click handler -- measured on beta:
`{ role: null, tabindex: null, focusable: false }`. Neither could be
focused or activated from the keyboard, and neither was announced as
anything at all. They are the way in to species filtering and to the
interactor overlay, so that is the whole feature closed to anyone not
using a mouse.

Each now carries the role, the tab stop and the key handling that make it
behave as the button it already looks like, plus a label and an
aria-expanded that follows the panel. They keep their markup rather than
becoming <button> elements: these carry layout the surrounding flex rules
depend on, and a button would bring its own.

Space calls preventDefault, because the default action for Space on a
focused element is to scroll the page.

The e2e case drives them the way someone without a mouse does -- focus,
then a key -- rather than checking the attributes are present. The
attributes are the mechanism; reaching the panel is the thing. Shown red
against the old markup at the first assertion: the control would not take
focus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright enabled auto-merge (squash) September 16, 2026 16:19
adamjohnwright and others added 3 commits September 16, 2026 16:41
Found reviewing this PR before it merged.

Opening a panel with a key worked; getting out of one did not. Escape did
nothing, so the only way back was shift-tabbing to the control and
pressing it again -- a trap of a mild kind, because every other disclosure
on the page closes this way and a reader will try it.

Worse, closing from inside dropped focus to <body>, measured. A reader who
closed the panel had lost their place on the page entirely and had to tab
from the top.

Escape now closes either panel, from the control or from inside it, and
focus goes back to the control that opened it.

Both controls also gained aria-controls. Saying a thing is expanded
without saying what it expands is half an answer.

Tab order was checked and left alone: it already moves straight from the
control into the panel's buttons.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit 1258d25 into main Sep 16, 2026
6 checks passed
@adamjohnwright
adamjohnwright deleted the fix/header-controls-keyboard branch September 16, 2026 17:53
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.

The Species and Interactors controls cannot be reached by keyboard

1 participant