# jsx-a11y/no-static-element-interactions

> Require a `role` on `<div>`, `<span>` and similar elements that have event handlers

A `<div>` or a `<span>` says nothing about what it is. With a click handler, it works like a button for mouse users, but a screen reader only announces its text, so nobody else knows they can press it.

Use the real element, such as `<button>` or `<a href>`. If you can't, give the element a `role` that says what it is. An `<a>` without an `href` counts as static too.

Not reported:

- components
- elements with `aria-hidden`
- elements with `role="presentation"` or `role="none"`. Use one of these for a handler that only catches events from children.

For elements that describe content, such as `<li>` or `<p>`, see `jsx-a11y/no-noninteractive-element-interactions`.

{/* 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-static-element-interactions" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"jsx-a11y/no-static-element-interactions" = ["error", {
  handlers = [
    "onClick",
    "onMouseDown",
    "onMouseUp",
    "onKeyPress",
    "onKeyDown",
    "onKeyUp",
  ],
  allowExpressionValues = false,
}]
```

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

## Examples

Reported:

{/* bad {"count": 2} */}
```jsx
const close = <div className="close" onClick={closeDialog}>Close</div>;
const more = <a onClick={loadMore}>Show more</a>;
```

Not reported:

{/* good */}
```jsx
const close = <button className="close" onClick={closeDialog}>Close</button>;
const more = <button onClick={loadMore}>Show more</button>;

const custom = (
  <div role="button" tabIndex={0} onClick={closeDialog} onKeyDown={closeOnEnter}>
    Close
  </div>
);

const backdrop = <div role="presentation" onClick={closeDialog} />;
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `handlers` | `["onClick", "onMouseDown", "onMouseUp", "onKeyPress", "onKeyDown", "onKeyUp"]` | The handlers to report. Your list replaces the default. |
| `allowExpressionValues` | `false` | Accept a `role` that's only known at run time, such as `role={role}`. |

{/* good */}
```jsx
const card = <div onMouseEnter={showPreview} />;
```

{/* bad {"options": [{"handlers": ["onClick", "onMouseEnter"]}]} */}
```jsx
const card = <div onMouseEnter={showPreview} />;
```

{/* bad */}
```jsx
const cell = <div role={cellRole} onClick={selectCell} />;
```

{/* good {"options": [{"allowExpressionValues": true}]} */}
```jsx
const cell = <div role={cellRole} onClick={selectCell} />;
```
