a11y: make 2D keycap grid keyboard/screen-reader operable - #432
Open
fla-rion wants to merge 2 commits into
Open
Conversation
Each keycap in the 2D render mode was a plain div with only mouse
handlers - no role, no tabIndex, no aria-label (the visible legend is
canvas-painted pixels, not text), and no way to activate it from a
keyboard or screen reader.
- Give interactive keycaps role="button", tabIndex, aria-label sourced
from the same label data used for the canvas paint, and aria-pressed
for the selection state.
- Handle Enter/Space via onKeyDown to activate the same selection path
as a click.
- Replace the blanket `*:focus { outline: none }` with a
`:focus-visible`-based reset so keyboard focus is visible again
without affecting mouse interaction.
Scoped to the primary keycap render path for this first pass; the
ComboKeycap/EncoderKey variants and arrow-key grid navigation are
tracked as follow-ups in via-app#431.
- KeyGroup now tracks a roving tabindex across the 2D key grid and handles ArrowUp/Down/Left/Right by finding the nearest key in that direction (weighted towards staying in the same row/column, since the physical layout isn't a strict grid), keeping only one keycap in the Tab order at a time and moving DOM focus programmatically. - Extends the role/tabIndex/aria-label/onKeyDown treatment from the previous commit to the ComboKeycap and EncoderKey variants, which were left out of the first pass. Still open (see via-app#431): 3D render mode, and the app-wide Button component being a styled.div instead of a native <button>.
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.
Fixes #431 (first step, scoped to the 2D keycap grid).
What
unit-key/keycap.tsx) now getsrole="button",tabIndex,aria-pressed, and anaria-labelbuilt from the same label data that's already used to paint the canvas legend.Enter/Spaceon a focused keycap now triggers the same selection path as a click.*:focus { outline: none }reset is replaced with a:focus-visible-based one, so keyboard focus is visible again without adding an outline on mouse clicks.Why
VIA configures keyboards built specifically for open, hackable firmware, but the remapping UI can't be operated by a screen reader today: keys are unlabeled, unfocusable divs, and the visible legend is drawn to a
<canvas>(pixels, not text) — see #431 for the full breakdown of both render modes.Scope / follow-ups
This PR only touches the primary keycap path in 2D mode, since it's already plain DOM and the smallest correct increment. Not yet covered (tracked as follow-ups):
ComboKeycap/EncoderKeyvariantstabIndex, just not spatial arrow nav yet)Buttoncomponent (inputs/button.tsx) is astyled.divapp-wide, not a native<button>— separate, bigger changeTesting
npx tsc --noEmitpasses with no new errors.aria-label/role/tabIndex/onKeyDownwiring reuses existing, already-computed label/selection state rather than introducing new state.