feat(voyage): implement J/K keyboard navigation + Esc + aria-live announces
Step 20 of v4.3 playground plan. Document-level keydown handler: - J = next annotation (next sorted-by-line draft, wraps) - K = prev annotation (wraps) - ] = toggle sidebar visibility - Escape = clear active anchor + sidebar list selection Active annotation gets yellow-tint (Step 18 setActiveAnchor) and the matching gutter-badge receives focus + scrollIntoView. Aria-live region announces position + target: "Annotering 3 av 7: <target> — <snippet>". Skips input/textarea/select/contenteditable so playground never steals keystrokes from form fields. Modifier keys (Ctrl/Alt/Meta) pass through to browser shortcuts. Wired in init() after dashboard nav. Trace: SC2 (WCAG AA keyboard), SC6, research/04 Dim 2 + Insight 5 + Recommendation keyboard-navigation.
This commit is contained in:
parent
6db7c72511
commit
224517f205
2 changed files with 81 additions and 0 deletions
|
|
@ -279,3 +279,23 @@ test('voyage-playground.html declares renderAnnotationList JS function (v4.3 Ste
|
|||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /function\s+renderAnnotationList\s*\(\s*\)/, 'renderAnnotationList() function required');
|
||||
});
|
||||
|
||||
test('voyage-playground.html declares wireKeyboardNav with j/k/]/Escape (v4.3 Step 20)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /function\s+wireKeyboardNav\s*\(\s*\)/, 'wireKeyboardNav() function required');
|
||||
assert.match(text, /e\.key === 'j'/, "'j' key handler required");
|
||||
assert.match(text, /e\.key === 'k'/, "'k' key handler required");
|
||||
assert.match(text, /e\.key === '\]'/, "']' key (toggle-sidebar) required");
|
||||
assert.match(text, /e\.key === 'Escape'/, "'Escape' key handler required");
|
||||
});
|
||||
|
||||
test('voyage-playground.html keyboard nav skips inputs/textareas (v4.3 Step 20)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /matches\([^)]*input[^)]*textarea/, 'input/textarea matches() guard required');
|
||||
});
|
||||
|
||||
test('voyage-playground.html keyboard nav announces via aria-live region (v4.3 Step 20)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
// The wireKeyboardNav body contains announce(... ' av ' ...) for nav-position announce
|
||||
assert.match(text, /announce\('Annotering '/, 'aria-live announce on annotation navigation required');
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue