# `a11y/keyboard-bindings` _(no submodules)_ ## Purpose Pure-value table mapping keyboard keys to parameter-control actions (`fine-decrement`, `coarse-increment`, `page-decrement`, `min`, `max`, `enter-value`). Phase-2 components — knobs, sliders, the parameter inspector — consume this table directly so the keymap is declared in exactly one place and easy to audit for accessibility compliance. The module is React-free; it exports a frozen array, two factor constants (`KEY_MODIFIER_FACTOR_SHIFT` = 10, `KEY_MODIFIER_FACTOR_ALT` = 0.1), and a helper `matchKeyBinding(event)` that resolves a `KeyboardEvent`-shaped value into `{ binding, compositeFactor }` or `undefined` for a no-match. ## Features - `PARAMETER_KEY_BINDINGS` — frozen `ReadonlyArray`. - `KEY_MODIFIER_FACTOR_SHIFT`, `KEY_MODIFIER_FACTOR_ALT` — composable multipliers. - `matchKeyBinding(event)` — pure function, no DOM imports. - Standard a11y keymap (arrows, page-up/down, home, end, enter). ## Usage: Basic ```ts import { matchKeyBinding } from "@suaveplan/react-audio/a11y"; function onKey(event: KeyboardEvent) { const match = matchKeyBinding(event); if (match === undefined) return; console.log(match.binding.action, match.compositeFactor); } ``` ## Usage: Advanced ```tsx import { matchKeyBinding, PARAMETER_KEY_BINDINGS, } from "@suaveplan/react-audio/a11y"; function Knob({ value, min, max, step, onChange, }: { value: number; min: number; max: number; step: number; onChange: (next: number) => void; }) { return (
{ const match = matchKeyBinding(event); if (match === undefined) return; event.preventDefault(); const delta = step * match.compositeFactor; switch (match.binding.action) { case "fine-decrement": case "coarse-decrement": case "page-decrement": onChange(Math.max(min, value - delta)); return; case "fine-increment": case "coarse-increment": case "page-increment": onChange(Math.min(max, value + delta)); return; case "min": onChange(min); return; case "max": onChange(max); return; default: return; } }} > {value}
); } ``` ## API Reference - `KeyBinding` — `{ key, action, factor, modifiers? }`. - `PARAMETER_KEY_BINDINGS: ReadonlyArray`. - `KEY_MODIFIER_FACTOR_SHIFT: 10`. - `KEY_MODIFIER_FACTOR_ALT: 0.1`. - `matchKeyBinding(event): { binding, compositeFactor } | undefined`. ## Implementation Notes The keymap conventions (`←` fine, `↓` coarse, `Shift` ×10, `Alt` ×0.1) match the design.md accessibility section so the upstream behaviour carries forward. The `matchKeyBinding` helper takes an event-shaped object rather than a `KeyboardEvent` so it is callable from test harnesses with plain object literals — and zero DOM types are imported into this file. The factor multiplication order is `binding.factor * shift * alt`; with both modifiers pressed the net effect is `factor × 10 × 0.1 = factor`, which is the intended "shift cancels alt" semantics.