feat(a11y): expose the outline panel as an ARIA tree#210
Merged
Conversation
The document outline was a flat <ul>/<li>/<button> list with no tree semantics, so screen readers announced a plain button list — heading hierarchy, current position, and collapsed-subtree state were not conveyed. Add role=tree on the list and role=treeitem on each row, with aria-level from the render depth (skipped heading levels collapse to contiguous nesting), aria-expanded on parent rows, and aria-selected tracking the active heading. Expand state moves off the twistie onto the treeitem as the single source of truth; the twistie stays a keyboard-operable disclosure control. Bump 0.1.45 -> 0.1.46.
Adds three regression-guard tests for the outline panel's ARIA tree semantics: a nested row's own collapse state survives an unrelated ancestor's re-expand; aria-expanded is removed (not left stale) when an edit turns a parent heading into a leaf; and the empty-state role=none transition fires live when the last heading is deleted, not just at mount time.
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.
Summary
Expose the document outline as an ARIA tree so screen readers convey the heading hierarchy, the current position, and each section's collapsed/expanded state instead of announcing a flat list of buttons. Semantics/quality gap from the 2026-07-12 editor-surface a11y audit (L2, severity Low); the panel was already fully operable.
Changes
ul.quoll-outline-list→role="tree"+aria-label="Document outline".<li>→role="treeitem"witharia-level(1-based off the render depth, so a skipped heading level e.g. h1→h3 collapses to contiguous tree nesting),aria-expandedon parent rows only, andaria-selectedtracking the active heading.aria-expandedmoved off the twistie onto the treeitem (single source of truth); the twistie stays a keyboard-operable disclosure control and keeps its action label.role="none"so it never masquerades as a treeitem inside the tree.aria-levelmodel chosen (the DOM is a flat list, not nestedrole="group") — the spec-sanctioned pattern for a flat tree.Related
Test Plan
pnpm compilegreen.pnpm test:unitgreen (3343 tests) — 5 new tests pin the tree role, aria-level from depth (incl. skipped levels), parent-only aria-expanded, aria-selected tracking selection, and the empty-staterole="none"; 3 existing collapse tests updated to assertaria-expandedon the treeitem row.pnpm lintclean on the changed files.