diff --git a/.jules/palette.md b/.jules/palette.md index ea004e2d2..25de26c9c 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -81,3 +81,7 @@ ## 2026-08-12 - Skip to Content Accessibility **Learning:** Screen reader and keyboard-only users experience significant friction when forced to navigate through repetitive header controls on every page load. **Action:** Keep a visible-on-focus skip link as the first interactive element, target a programmatically focusable main container, and give the focused link a high-contrast outline. + +## 2024-05-24 - Keyboard Shortcut Tooltips +**Learning:** Icon-only buttons that map to keyboard shortcuts (like Escape to close details) need both a visual hint (`title="... (Key)"`) and a programmatic hint (`aria-keyshortcuts="Key"`) to fully support mouse and screen reader accessibility. +**Action:** Always include both attributes alongside `aria-label` when adding keyboard listeners to UI action buttons. diff --git a/scanner/dashboard/console.html b/scanner/dashboard/console.html index 7ec262af4..3c8d425db 100644 --- a/scanner/dashboard/console.html +++ b/scanner/dashboard/console.html @@ -158,7 +158,7 @@

AppGuardrail Console

const rows=(s.findings||[]).map(f=>`${esc(f.severity)} ${esc(f.rule_id)}${esc((f.message||"").split("\n")[0].slice(0,120))} ${esc(f.file)}:${esc(f.line)}`).join(""); - d.innerHTML=`Scan #${esc(s.id)} ${esc(s.created_at)} · ${esc(s.repo||"—")} + d.innerHTML=`Scan #${esc(s.id)} ${esc(s.created_at)} · ${esc(s.repo||"—")} ${rows||''}
SeverityRuleFindingLocation
No findings.
`; d.querySelector(".close-btn").addEventListener("click",closeDetail); @@ -166,7 +166,7 @@

AppGuardrail Console

d.focus({preventScroll:true}); }catch(e){ if(requestId!==currentDetailRequest)return; - d.innerHTML=''; + d.innerHTML=''; d.querySelector(".close-btn").addEventListener("click",closeDetail); scrollDetailIntoView(d); d.focus({preventScroll:true}); diff --git a/tests/test_console_accessibility_contract.py b/tests/test_console_accessibility_contract.py index da45fdc5e..0e8002d1b 100644 --- a/tests/test_console_accessibility_contract.py +++ b/tests/test_console_accessibility_contract.py @@ -23,3 +23,10 @@ def test_console_rows_preserve_cell_content_for_screen_readers(): assert 'role="button" title="View scan details"' in html assert 'aria-label="View scan details"' not in html + +def test_console_close_button_exposes_shortcut(): + """The close button must expose its Escape key shortcut.""" + html = _console_html() + + assert 'title="Close (Esc)"' in html + assert 'aria-keyshortcuts="Escape"' in html