Description
The error-message rule flags elements that are clearly interactive UI widgets (disclosure panels, popup menus) as potential unassociated error messages, because it only excludes elements by tag name (structuralSelector) or ARIA widget roles (widgetRoles).
Elements that are referenced by aria-controls on a button/trigger should also be excluded, since they are interactive widget targets — not error message containers.
Example
A disclosure button that toggles a filter panel:
<form>
<button type="button"
aria-expanded="false"
aria-controls="dropdown-menu-filters">
Filters
</button>
<div id="dropdown-menu-filters"
aria-labelledby="dropdown-button-filters">
<ul>
<li>
<input type="checkbox" id="filter-1" />
<label for="filter-1">Option 1</label>
</li>
<li>
<input type="checkbox" id="filter-2" />
<label for="filter-2">Option 2</label>
</li>
</ul>
</div>
</form>
The div#dropdown-menu-filters gets flagged by the error-message rule because:
- It has an
id
- It has text content
- It's inside a
<form>
- It doesn't match
structuralSelector or have a widget role
- It isn't referenced by
aria-describedby or aria-errormessage
But it IS referenced by aria-controls on the button, which clearly indicates it's an interactive widget target.
Suggested fix
In findCandidateErrorElements, also collect IDs referenced by aria-controls and exclude those elements:
function collectControlledIds(container: Element): Set<string> {
const ids = new Set<string>();
const allElements = querySelectorAll("[aria-controls]", container);
for (const el of allElements) {
const value = el.getAttribute("aria-controls");
if (value) {
for (const token of value.split(/\s+/)) {
if (token) ids.add(token);
}
}
}
return ids;
}
Then in the main function, exclude candidates whose ID appears in the controlled set.
Related
This is a follow-up to #389 which added widget role exclusions. This addresses the remaining case where the element doesn't have a widget role but is clearly an interactive target.
Description
The
error-messagerule flags elements that are clearly interactive UI widgets (disclosure panels, popup menus) as potential unassociated error messages, because it only excludes elements by tag name (structuralSelector) or ARIA widget roles (widgetRoles).Elements that are referenced by
aria-controlson a button/trigger should also be excluded, since they are interactive widget targets — not error message containers.Example
A disclosure button that toggles a filter panel:
The
div#dropdown-menu-filtersgets flagged by theerror-messagerule because:id<form>structuralSelectoror have a widget rolearia-describedbyoraria-errormessageBut it IS referenced by
aria-controlson the button, which clearly indicates it's an interactive widget target.Suggested fix
In
findCandidateErrorElements, also collect IDs referenced byaria-controlsand exclude those elements:Then in the main function, exclude candidates whose ID appears in the controlled set.
Related
This is a follow-up to #389 which added widget role exclusions. This addresses the remaining case where the element doesn't have a widget role but is clearly an interactive target.