Skip to content

Commit dddb5e5

Browse files
committed
lint: narrow INTERACTIVE_ROLES util to match jsx-a11y/lit-a11y
1 parent e9a73e4 commit dddb5e5

1 file changed

Lines changed: 18 additions & 25 deletions

File tree

lib/utils/interactive-roles.js

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,31 @@
11
const { roles } = require('aria-query');
22

3-
// Interactive ARIA roles — the set of concrete roles whose taxonomy in WAI-ARIA
4-
// includes a widget / command / composite / input / range ancestor. Derived from
5-
// aria-query so the list stays current with ARIA spec updates (including
6-
// DPUB-ARIA and Graphics-ARIA additions) without hand maintenance.
3+
// Interactive ARIA roles — concrete roles whose taxonomy descends from `widget`
4+
// in aria-query. This is the same derivation jsx-a11y and lit-a11y use (they
5+
// define the canonical peer-plugin behavior here):
6+
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/isInteractiveRole.js
7+
// https://github.com/open-wc/open-wc/blob/main/packages/eslint-plugin-lit-a11y/lib/utils/isInteractiveElement.js
78
//
8-
// `tooltip` and `toolbar` are added explicitly:
9-
// - `tooltip`: ARIA 1.2 §5.4 lists tooltip among widget roles, but aria-query's
10-
// superClass chain doesn't include `widget` for it. Practitioner convention
11-
// (and jsx-a11y/vuejs-accessibility) treats it as interactive.
12-
// - `toolbar`: does not descend from `widget` in aria-query, but supports
13-
// `aria-activedescendant` and is widget-like in practice. jsx-a11y adds it
14-
// with the same rationale.
9+
// `toolbar` is added explicitly — it does not descend from `widget` per
10+
// aria-query's taxonomy, but supports `aria-activedescendant` and is widget-
11+
// like in practice. jsx-a11y and lit-a11y add it for the same reason.
12+
//
13+
// `tooltip` is also added — ARIA 1.2 doesn't cleanly categorize tooltip under
14+
// the widget taxonomy (aria-query's superClass is `structure/section`), but
15+
// tooltips with interactive content (close buttons, links) are common and our
16+
// existing test suite treats them as interactive.
1517
module.exports.INTERACTIVE_ROLES = buildInteractiveRoleSet();
1618

1719
function buildInteractiveRoleSet() {
18-
const result = new Set(['tooltip', 'toolbar']);
20+
const result = new Set(['toolbar', 'tooltip']);
1921
for (const [role, def] of roles) {
2022
if (def.abstract) {
2123
continue;
2224
}
23-
const ancestors = new Set();
24-
for (const chain of def.superClass || []) {
25-
for (const cls of chain) {
26-
ancestors.add(cls);
27-
}
28-
}
29-
if (
30-
ancestors.has('widget') ||
31-
ancestors.has('command') ||
32-
ancestors.has('composite') ||
33-
ancestors.has('input') ||
34-
ancestors.has('range')
35-
) {
25+
const descendsFromWidget = (def.superClass || []).some((chain) =>
26+
chain.includes('widget')
27+
);
28+
if (descendsFromWidget) {
3629
result.add(role);
3730
}
3831
}

0 commit comments

Comments
 (0)