Rendered from specs/S06-accessibility.md — edit it there, not here.
S06 — Accessibility
Overview
The extension surfaces two custom webviews (the schema preview and the visual editor) and several status-bar / notification affordances. Webviews render outside VS Code's own accessible widgets, so their accessibility is the extension's responsibility. These requirements set a floor for keyboard operability and screen-reader support.
Decision (2026-07-04): accessibility is specced now, before the surface grows, because retrofitting it into webview markup later is expensive.
Requirements
Keyboard Operability
- S06-SR-01 Every interactive control the extension injects into a webview (e.g. the preview Download button) MUST be reachable and operable by keyboard alone — it MUST be a natively focusable element (
<button>,<a href>) or carry an explicittabindex, and MUST activate on bothEnterandSpacewhere the native element does not already. - S06-SR-02 The extension MUST NOT trap keyboard focus inside a webview; standard VS Code focus-cycling (
F6,Tab) MUST continue to work.
Screen Reader Semantics
- S06-SR-03 Injected interactive controls MUST expose an accessible name (visible text,
aria-label, ortitle) so assistive technology can announce them. Icon-only controls MUST carry anaria-label. - S06-SR-04 The fallback renderer (see F01) MUST emit a single top-level
<h1>for the schema title and use semantic heading levels for nested sections, so the document is navigable by screen-reader heading commands. - S06-SR-05 Decorative glyphs (e.g. the
↓on the Download button) MUST NOT be the control's only accessible name; a text label oraria-labelMUST accompany them.
Contrast and Motion
- S06-SR-06 Text the extension renders in its own pages (loading page, error page, fallback renderer) SHOULD meet WCAG 2.1 AA contrast (≥ 4.5:1 for body text) against its background in both light and dark themes.
- S06-SR-07 The extension MUST NOT rely on colour alone to convey state (e.g. validation errors); a text label or icon MUST accompany any colour cue.
Acceptance Criteria
- With the preview open, pressing
Tabmoves focus to the Download button andEnter/Spacetriggers the save dialog, with no mouse involved. - A screen reader announces the Download button by an accessible name, not just "button".
- The fallback-rendered page exposes the schema title as an
<h1>and nested property groups as lower-level headings.
Requirement traceability
Status of each requirement in specs/traceability.json. Test coverage is auto-discovered from [ID] tags in test titles and is not listed here.
| Requirement | Status | Implementation | Note |
|---|---|---|---|
S06-SR-01 | manual | src/PreviewWebPanel.ts, src/SchemaEditorPanel.ts | all injected controls are native <button>/<a href>/form elements (audit 2026-07); Enter/Space native |
S06-SR-02 | manual | src/PreviewWebPanel.ts, src/SchemaEditorPanel.ts | no keydown handlers or focus traps in any webview script (audit 2026-07); F6/Tab cycling verified manually |
S06-SR-03 | manual | src/PreviewWebPanel.ts, src/SchemaEditorPanel.ts | no icon-only controls; every button carries visible text (Download HTML, Save, Open file) |
S06-SR-04 | implemented | src/fallbackRenderer.ts | fallback renderer emits semantic headings; unit-tested |
S06-SR-05 | manual | src/PreviewWebPanel.ts | Download button carries a text label alongside the down-arrow glyph |
S06-SR-06 | manual | src/webviewUtils.ts, src/fallbackRenderer.ts | loading #9d9d9d, error #d4d4d4, fallback #d4d4d4 on #1e1e1e all >=4.5:1; pages are fixed-dark so ratio holds in both themes |
S06-SR-07 | implemented | src/fallbackRenderer.ts | required column uses textual Yes/—, not colour alone; unit-tested |