Accessibility Audit (EXPERIMENTAL)
auditAccessibility(agent.describe({ styles: true })) turns the affordance
map into findings. It is the lint the map made obvious: every element with
handlers should have a name, a role, and enough contrast and size to use —
and because the map is the framework's own record of its wiring, a finding
here is a real defect, not a scraper's guess.
import { enableAgentInterface, auditAccessibility } from 'tosijs'
const agent = enableAgentInterface()
const report = auditAccessibility(agent.describe({ styles: true }))
report.failed // 0 when clean
report.findings // [{ rule, severity, message, record, index }]
Pure over the description — no DOM, so it runs on a map that arrived over a
wire, in a test, or in CI. Pass styles: true to describe() or the
contrast rule has nothing to measure and skips itself (it says so).
The rules
| rule | what it catches | why |
|---|---|---|
anonymous-affordance |
a wired element with no accessible name, text, or value | a screen reader announces "button"; an agent sees <div> |
unnameable-action |
a handler that is an anonymous function (ƒ) |
nothing can invoke or describe it but a click |
missing-role |
a non-semantic tag (div/span) wired to act | assistive tech has no idea it is a control |
contrast |
text/background below the WCAG AA ratio | measured with tosijs's own Color; needs styles: true |
target-size |
interactive element below 24×24 (WCAG 2.5.8) | too small to hit reliably; toggles exempt |
label-hidden-by-placeholder |
a control whose only name is its placeholder | the name vanishes the moment the user types |
Findings carry the record and its index, so a caller can jump straight to
the element — or hand the pair to schematicSVG's flags to draw them.
The divergence is closed, and as of 1.10.2 there is no carve-out either (tosijs-floorplan #4, then #7/#8/#9 and #13).
target-sizeand "is this interactive" were once implemented twice — here and in the vendored renderer — and had drifted into contradicting each other on real elements. 0.4.0 shared the implementation; 0.5.0 removed the need for this module to adjust it.Three adjustments used to live here, as
auditView: strip producerflags(a lint never drew them), exempt0×0(hidden is not small), and treat a list-bound element carrying its own evidence as a control. All three are now in the rule itself, soauditViewis deleted and this module contains no definition of what evidence is — not a copy, not an adjustment, nothing. The audit suite passes unchanged across the deletion, which is the only evidence that the retirement is real rather than nominal.What this module still owns is what it uniquely knows: the accessible name, the contrast math, and the wording of each finding.
EXPERIMENTAL. Ships with the agent surface; rules and shapes may change.