diff --git a/src/compiler/compile/utils/a11y.ts b/src/compiler/compile/utils/a11y.ts index b96386a3b0..d51125fa92 100644 --- a/src/compiler/compile/utils/a11y.ts +++ b/src/compiler/compile/utils/a11y.ts @@ -7,17 +7,17 @@ import { import { AXObjects, AXObjectRoles, elementAXObjects } from 'axobject-query'; import Attribute from '../nodes/Attribute'; -const roles = [...roles_map.keys()]; +const non_abstract_roles = [...roles_map.keys()].filter((name) => !roles_map.get(name).abstract); const non_interactive_roles = new Set( - roles + non_abstract_roles .filter((name) => { const role = roles_map.get(name); return ( - !roles_map.get(name).abstract && // 'toolbar' does not descend from widget, but it does support // aria-activedescendant, thus in practice we treat it as a widget. - name !== 'toolbar' && + // focusable tabpanel elements are recommended if any panels in a set contain content where the first element in the panel is not focusable. + !['toolbar', 'tabpanel'].includes(name) && !role.superClass.some((classes) => classes.includes('widget')) ); }) @@ -29,22 +29,7 @@ const non_interactive_roles = new Set( ); const interactive_roles = new Set( - roles - .filter((name) => { - const role = roles_map.get(name); - return ( - !role.abstract && - // The `progressbar` is descended from `widget`, but in practice, its - // value is always `readonly`, so we treat it as a non-interactive role. - name !== 'progressbar' && - role.superClass.some((classes) => classes.includes('widget')) - ); - }) - .concat( - // 'toolbar' does not descend from widget, but it does support - // aria-activedescendant, thus in practice we treat it as a widget. - 'toolbar' - ) + non_abstract_roles.filter((name) => !non_interactive_roles.has(name)) ); export function is_non_interactive_roles(role: ARIARoleDefintionKey) { diff --git a/test/validator/samples/a11y-no-nointeractive-tabindex/input.svelte b/test/validator/samples/a11y-no-nointeractive-tabindex/input.svelte index e9ac0d3c9f..9efed4d879 100644 --- a/test/validator/samples/a11y-no-nointeractive-tabindex/input.svelte +++ b/test/validator/samples/a11y-no-nointeractive-tabindex/input.svelte @@ -7,6 +7,7 @@
+
diff --git a/test/validator/samples/a11y-no-nointeractive-tabindex/warnings.json b/test/validator/samples/a11y-no-nointeractive-tabindex/warnings.json index 740d9b346c..b2c3ec4168 100644 --- a/test/validator/samples/a11y-no-nointeractive-tabindex/warnings.json +++ b/test/validator/samples/a11y-no-nointeractive-tabindex/warnings.json @@ -2,61 +2,61 @@ { "code": "a11y-no-noninteractive-tabindex", "end": { - "character": 241, + "character": 278, "column": 20, - "line": 11 + "line": 12 }, "message": "A11y: noninteractive element cannot have positive tabIndex value", - "pos": 221, + "pos": 258, "start": { - "character": 221, + "character": 258, "column": 0, - "line": 11 + "line": 12 } }, { "code": "a11y-no-noninteractive-tabindex", "end": { - "character": 277, + "character": 314, "column": 35, - "line": 12 + "line": 13 }, "message": "A11y: noninteractive element cannot have positive tabIndex value", - "pos": 242, + "pos": 279, "start": { - "character": 242, + "character": 279, "column": 0, - "line": 12 + "line": 13 } }, { "code": "a11y-no-noninteractive-tabindex", "end": { - "character": 302, + "character": 339, "column": 24, - "line": 13 + "line": 14 }, "message": "A11y: noninteractive element cannot have positive tabIndex value", - "pos": 278, + "pos": 315, "start": { - "character": 278, + "character": 315, "column": 0, - "line": 13 + "line": 14 } }, { "code": "a11y-no-noninteractive-tabindex", "end": { - "character": 329, + "character": 366, "column": 26, - "line": 14 + "line": 15 }, "message": "A11y: noninteractive element cannot have positive tabIndex value", - "pos": 303, + "pos": 340, "start": { - "character": 303, + "character": 340, "column": 0, - "line": 14 + "line": 15 } } ]