Skip to content

Latest commit

 

History

History
49 lines (35 loc) · 2.7 KB

File metadata and controls

49 lines (35 loc) · 2.7 KB

ember/template-no-noninteractive-element-to-interactive-role

Disallow non-interactive HTML elements from being assigned interactive ARIA roles.

Assigning an interactive role (button, checkbox, menuitem, ...) to an element with inherent non-interactive semantics (headings, landmarks, text structure, lists, tables, forms) creates a widget with no supporting behavior — focus, keyboard activation, and state handling must all be added manually, and the mismatch is easy to get wrong.

Scope

The set of non-interactive elements is sourced from axobject-query — the same AX-tree-derived data used by eslint-plugin-jsx-a11y, @angular-eslint/eslint-plugin-template, and others. It includes headings (<h1><h6>), landmarks (<article>, <aside>, <nav>, <main>, etc.), text structure (<p>, <figure>, <blockquote>, etc.), lists (<ul>, <ol>, <li>, <dl>, <dt>, <dd>), tables (<table>, <tbody>, <tr>, etc.), forms (<form>, <fieldset>, <legend>), <img>, and similar.

<div> and <span> are not covered — ARIA 1.2 assigns them the generic role with no inherent semantics to mismatch. <div role="button"> is covered by the related template-require-aria-activedescendant-tabindex and template-no-noninteractive-tabindex rules.

Examples

This rule forbids the following:

<template>
  <h1 role="button">Click</h1>
  <article role="button">Story</article>
  <li role="tab">Tab</li>
  <img role="link" src="/x.png" alt="link" />
  <form role="checkbox"></form>
  <p role="button">Click me</p>
</template>

This rule allows the following:

<template>
  <h1 role="heading" aria-level="1">Title</h1>
  <article role="article">Story</article>
  <ul role="list"></ul>

  {{! <div>/<span> are "generic" — not covered by this rule }}
  <div role="button" tabindex="0"></div>
  <span role="checkbox" aria-checked="false" tabindex="0"></span>
</template>

References