# jsx-a11y/no-interactive-element-to-noninteractive-role

> Disallow non-interactive ARIA roles on interactive elements

A `role` replaces what a screen reader says about an element. A `<button role="heading">` is announced as a heading, so the user never finds out they can press it, even though it still takes focus and reacts to clicks.

Interactive elements include `<button>`, `<input>`, `<select>`, `<textarea>` and `<a>` with an `href`. Non-interactive roles include `article`, `heading`, `img`, `list` and `listitem`, and also `presentation` and `none`. Only a `role` written as a string is checked.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"jsx-a11y/no-interactive-element-to-noninteractive-role" = "error" # or "warn"
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 2} */}
```jsx
const title = <button role="heading" onClick={toggle}>Details</button>;
const item = <a href="/settings" role="listitem">Settings</a>;
```

Not reported:

{/* good */}
```jsx
const title = (
  <h2>
    <button onClick={toggle}>Details</button>
  </h2>
);

const item = (
  <li>
    <a href="/settings">Settings</a>
  </li>
);
```

An interactive role on an interactive element is fine:

{/* good */}
```jsx
const tab = <button role="tab">Profile</button>;
```

## Options

The option is an object that maps an element to the roles it's allowed to have. The default is:

```json
{
  "tr": ["none", "presentation"],
  "canvas": ["img"]
}
```

Your object replaces the default, so repeat the entries you want to keep.

{/* good */}
```jsx
const chart = <canvas role="img" aria-label="Sales by month" />;
```

{/* bad {"options": [{"input": ["img"]}]} */}
```jsx
const chart = <canvas role="img" aria-label="Sales by month" />;
```

{/* good {"options": [{"input": ["img"]}]} */}
```jsx
const logo = <input type="image" role="img" alt="Logo" />;
```
