Skip to content

Commit a1f78a0

Browse files
committed
fix(#33): address round-2 Copilot review (link/name isPresentationRole; clarify escape-hatch scope)
1 parent e343262 commit a1f78a0

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

docs/rules/template-no-invalid-interactive.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ Examples of **correct** code for this rule:
5151
An element opts out of this rule's handler-on-non-interactive check in two cases:
5252

5353
- **`aria-hidden="true"`** (including valueless / empty / `{{true}}` / `{{"true"}}` forms) — the author has explicitly removed the element from the accessibility tree, so a "non-interactive element with handler" is moot; AT users won't encounter it either way. Explicit `aria-hidden="false"` / `{{false}}` still flags.
54-
- **`role="presentation"` / `role="none"`** — the author asserts the element is decorative. We accept `role="presentation"` and `role="none"` (case-insensitive, first-token of a space-separated role list) — a deliberate superset of [jsx-a11y's exact-match `hasPresentationRole`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/hasPresentationRole.js) for consistency with [WAI-ARIA 1.2 §4.1](https://www.w3.org/TR/wai-aria-1.2/#host_general_role) role-fallback semantics.
54+
- **`role="presentation"` / `role="none"`** — the author asserts the element is decorative. We accept `role="presentation"` and `role="none"` (case-insensitive, first-token of a space-separated role list) — a deliberate superset of [jsx-a11y's exact-match `isPresentationRole`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/isPresentationRole.js) for consistency with [WAI-ARIA 1.2 §4.1](https://www.w3.org/TR/wai-aria-1.2/#host_general_role) role-fallback semantics.
5555

5656
The valueless `aria-hidden` case (e.g. `<div aria-hidden>`) is [genuinely contested](https://www.scottohara.me/blog/2018/05/05/hidden-vs-none.html) — jsx-a11y, vue-a11y, axe-core, and the WAI-ARIA spec take four different positions on whether it counts as "hidden". This rule leans toward fewer false positives: flagging a handler on an author-decorated element creates friction more often than it catches real bugs.
5757

5858
### Related checks outside this rule's scope
5959

60-
- **`role="presentation"` on focusable elements** — per [WAI-ARIA 1.2 §4.6 Conflict Resolution](https://www.w3.org/TR/wai-aria-1.2/#conflict_resolution_presentation_none), browsers ignore `role="presentation"` on focusable elements. [axe-core's `presentation-role-conflict`](https://dequeuniversity.com/rules/axe/4.10/presentation-role-conflict) flags this pattern as an authoring error. This rule does not detect the conflict: the escape hatch check runs before `isInteractive(node)`, so a focusable element with `role="presentation"` returns early and is silently exempted. Interactive-handler cases on plain `<button>` / `<a href>` etc. are still flagged normally when they lack the presentation/none opt-out. If you want to catch the authoring error itself (role=presentation on a focusable element, which has no effect at runtime), layer axe-core or a dedicated rule on top.
60+
- **`role="presentation"` on focusable elements** — per [WAI-ARIA 1.2 §4.6 Conflict Resolution](https://www.w3.org/TR/wai-aria-1.2/#conflict_resolution_presentation_none), browsers ignore `role="presentation"` on focusable elements. [axe-core's `presentation-role-conflict`](https://dequeuniversity.com/rules/axe/4.10/presentation-role-conflict) flags this pattern as an authoring error. This rule does not detect the conflict: the escape hatch only affects elements that would otherwise be considered non-interactive, so a non-interactive element decorated with `role="presentation"` is silently exempted even if it is focusable via `tabindex`. Natively-interactive elements such as `<button>` / `<a href>` are already recognized by `isInteractive(node)` independent of the escape hatch; the rule doesn't report them in the first place, and it doesn't enforce presentation-role conflict checks. If you want to catch that authoring error itself (role=presentation on a focusable element, which has no effect at runtime), layer axe-core or a dedicated rule on top.
6161
- **Click handler on a non-focusable decorated element** — e.g. `<div role="presentation" {{on "click"}}>`. Our escape hatch silences this by design (jsx-a11y-compat). [axe-core's `click-events-have-key-events`](https://dequeuniversity.com/rules/axe/4.10/click-events-have-key-events) is the complementary check. If you want strictness, layer it on top.
6262

6363
## Options

0 commit comments

Comments
 (0)