no-noninteractive-element-to-interactive-role

Non-interactive HTML elements indicate content and containers in the user interface. Non-interactive elements include <main>, <area>, <h1> (,<h2>, etc), <img>, <li>, <ul> and <ol>.

Interactive HTML elements indicate controls in the user interface. Interactive elements include <a href>, <button>, <input>, <select>, <textarea>.

WAI-ARIA roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include button, link, checkbox, menuitem, menuitemcheckbox, menuitemradio, option, radio, searchbox, switch and textbox.

How do I resolve this error?

Case: This element should be a control, like a button

Put the control inside the non-interactive container element.

<li>
  <div
    role="button"
    onClick={() => {}}
    onKeyPress={() => {}}>
    Save
  </div>
</li>

Or wrap the content inside your interactive element.

<div
  role="button"
  onClick={() => {}}
  onKeyPress={() => {}}
  tabIndex="0">
  <img src="some/file.png" alt="Save" />
</div>

References

  1. WAI-ARIA roles
  2. WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets
  3. Fundamental Keyboard Navigation Conventions
  4. Mozilla Developer Network - ARIA Techniques

Rule details

The recommended options for this rule allow several common interactive roles to be applied to a non-interactive element. The options are provided as an object keyed by HTML element name; the value is an array of interactive roles that are allowed on the specified element.

{
  'no-noninteractive-element-to-interactive-role': [
    'error',
    {
      ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
      ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
      li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
      table: ['grid'],
      td: ['gridcell'],
    },
  ]
}

Under the recommended options, the following code is valid. It would be invalid under the strict rules.

<ul role="menu" />