Skip to content

Commit 278a07b

Browse files
committed
Update and add docs for new rules
1 parent 307e4e8 commit 278a07b

5 files changed

+228
-56
lines changed
Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,59 @@
11
# interactive-supports-focus
22

3-
Enforce that visible elements with onClick handlers must be focusable. Visible means that it is not hidden from a screen reader. Examples of non-interactive elements are `div`, `section`, and `a` elements without a href prop. Elements which have click handlers but are not focusable can not be used by keyboard-only users.
3+
Elements with an interactive role and interaction handlers (mouse or key press) must be focusable.
44

5-
To make an element focusable, you can either set the tabIndex property, or use an element type which is inherently focusable.
5+
## How do I resolve this error?
66

7-
Elements that are inherently focusable are as follows:
8-
- `<input>`, `<button>`, `<select>` and `<textarea>` elements which are not disabled
9-
- `<a>` or `<area>` elements with an `href` attribute.
7+
### Case: This element is a stand-alone control like a button, a link or a form element
108

11-
This rule will only test low-level DOM components, as we can not deterministically map wrapper JSX components to their correct DOM element.
9+
Add this prop to your component:
1210

13-
## `tabIndex` of an element with role `gridcell`
11+
```
12+
<div
13+
role="button"
14+
tabIndex={0} />
15+
```
16+
17+
-- or --
18+
19+
Replace the component with one that renders semantic html element like `<button>`, `<a href>` or `<input>` -- whichever fits your purpose.
1420

15-
Within a grid, a grid cell may itself be tabbable if it contains text content.
16-
In this case apply a `tabIndex` of 0.
21+
Generally buttons, links and form elements should be reachable via tab key presses.
22+
An element that can be tabbed to is said to be in the _tab ring_.
23+
24+
### Case: This element is part of a group of buttons, links, menu items, etc
25+
26+
One item in a group should have a tabindex of zero, the rest should have a tabindex of -1. A value of zero makes the element _tabbable_. A value of -1 makes the element _focusable_.
27+
28+
```
29+
<div role="men">
30+
<div role="menuitem" tabIndex="0">Open</div>
31+
<div role="menuitem" tabIndex="-1">Save</div>
32+
<div role="menuitem" tabIndex="-1">Close</div>
33+
</div>
34+
```
35+
36+
In the example above, the first item in the group can be tabbed to. The developer provides the ability to traverse to the subsequent items via the up/down/left/right arrow keys. Traversing via arrow keys is not provided by the browser or the assistive technology. See [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav) for information about established traversal behaviors for various UI widgets.
37+
38+
### Case: This element is not a button, link, menuitem, etc. It is catching bubbled events from elements that it contains
39+
40+
If your element is catching bubbled click or key events from descendant elements, then the proper role for this element is `presentation`.
41+
42+
```
43+
<div
44+
onClick="onClickHandler"
45+
role="presentation">
46+
<button>Save</button>
47+
</div>
48+
```
1749

18-
If the content of the grid cell is tabbable -- for example a button or link --
19-
then apply a `tabIndex` of -1.
50+
Marking an element with the role `presentation` indicates to assistive technology that this element should be ignored; it exists to support the web application and is not meant for humans to interact with directly.
2051

21-
#### References
22-
1. [AX_FOCUS_02](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02)
23-
2. [MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
52+
### References
53+
1. [AX_FOCUS_02](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02)
54+
1. [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
55+
1. [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
56+
1. [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
2457

2558
## Rule details
2659

@@ -31,9 +64,9 @@ This rule takes no arguments.
3164
<!-- Good: div with onClick attribute is hidden from screen reader -->
3265
<div aria-hidden onClick={() => void 0} />
3366
<!-- Good: span with onClick attribute is in the tab order -->
34-
<span onClick="doSomething();" tabIndex="0">Click me!</span>
67+
<span onClick="doSomething();" tabIndex="0" role="button">Click me!</span>
3568
<!-- Good: span with onClick attribute may be focused programmatically -->
36-
<span onClick="doSomething();" tabIndex="-1">Click me too!</span>
69+
<span onClick="doSomething();" tabIndex="-1" role="menuitem">Click me too!</span>
3770
<!-- Good: anchor element with href is inherently focusable -->
3871
<a href="javascript:void(0);" onClick="doSomething();">Click ALL the things!</a>
3972
<!-- Good: buttons are inherently focusable -->
@@ -43,7 +76,7 @@ This rule takes no arguments.
4376
### Fail
4477
```jsx
4578
<!-- Bad: span with onClick attribute has no tabindex -->
46-
<span onclick="submitForm();">Submit</span>
79+
<span onclick="submitForm();" role="button">Submit</span>
4780
<!-- Bad: anchor element without href is not focusable -->
48-
<a onclick="showNextPage();">Next page</a>
81+
<a onclick="showNextPage();" role="button">Next page</a>
4982
```
Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,44 @@
11
# no-interactive-element-to-noninteractive-role
22

3-
Write a useful explanation here!
3+
Interactive HTML elements indicate _controls_ in the user interface. Interactive elements include `<a href>`, `<button>`, `<input>`, `<select>`, `<textarea>`.
44

5-
#### References
6-
1.
5+
Non-interactive HTML elements and non-interactive ARIA roles indicate _content_ and _containers_ in the user interface. Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<img>`, `<li>`, `<ul>` and `<ol>`.
76

8-
## Rule details
7+
[WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
98

10-
This rule takes no arguments.
9+
## How do I resolve this error?
10+
11+
### Case: The element should be a container, like an article
12+
13+
Wrap your interactive element in a `<div>` with the desired role.
1114

12-
### Succeed
13-
```jsx
14-
<div />
1515
```
16+
<div role="article">
17+
<button>Save</button>
18+
</div>
19+
```
20+
21+
### Case: The element should be content, like an image
1622

17-
### Fail
18-
```jsx
23+
Put the content inside your interactive element.
1924

2025
```
26+
<div
27+
role="button"
28+
onClick={() => {}}
29+
onKeyPress={() => {}}
30+
tabIndex="0">
31+
<div role="img" aria-label="Save" />
32+
</div>
33+
```
34+
35+
### References
36+
37+
1. [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
38+
1. [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
39+
1. [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
40+
1. [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
41+
42+
## Rule details
43+
44+
This rule takes no arguments.
Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
11
# no-noninteractive-element-handlers
22

3-
Enforce visible, non-interactive elements with click handlers use role attribute. Visible means that it is not hidden from a screen reader. Examples of non-interactive elements are `div`, `section`, and `a` elements without a href prop. The purpose of the role attribute is to identify to screenreaders the exact function of an element. This rule will only test low-level DOM components, as we can not deterministically map wrapper JSX components to their correct DOM element.
3+
Non-interactive HTML elements and non-interactive ARIA roles indicate _content_ and _containers_ in the user interface. A non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
44

5-
In cases where a non-interactive element has a handler, but does not map to an interactive role such as `button` or `link` -- for example a `div` container that catches bubbled click events -- `onclick-has-role` may be satisfied by providing a role value of `presentation`. This indicates that the element has no semantic value. A role like `button` or `link` should only be applied when the non-interactive element truly represents such a UI element.
5+
## How do I resolve this error?
66

7-
#### References
8-
1. [MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
7+
### Case: This element acts like a button, link, menuitem, etc.
8+
9+
Move the event handler function to an inner element that is either a semantically interactive element (`<button>`, `<a href>`) or that has an interactive role. This leaves the _content_ or _container_ semantic value of this element intact.
10+
11+
Common interactive roles include:
12+
13+
1. `button`
14+
1. `link`
15+
1. `checkbox`
16+
1. `menuitem`
17+
1. `menuitemcheckbox`
18+
1. `menuitemradio`
19+
1. `option`
20+
1. `radio`
21+
1. `searchbox`
22+
1. `switch`
23+
1. `textbox`
24+
25+
Note: Adding a role to your element does **not** add behavior. When a semantic HTML element like `<button>` is used, then it will also respond to Enter key presses when it has focus. The developer is responsible for providing the expected behavior of an element that the role suggests it would have: focusability and key press support.
26+
see [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex).
27+
28+
### Case: This element is catching bubbled events from elements that it contains
29+
30+
Move the event handler function to an inner element like `<div>` and give that element a role of `presentation`. This leaves the _content_ or _container_ semantic value of this element intact.
31+
32+
```
33+
<div role="article">
34+
<div
35+
onClick="onClickHandler"
36+
onKeyPress={onKeyPressHandler}
37+
role="presentation">
38+
{this.props.children}
39+
</div>
40+
</div>
41+
```
42+
43+
Marking an element with the role `presentation` indicates to assistive technology that this element should be ignored; it exists to support the web application and is not meant for humans to interact with directly.
44+
45+
### References
46+
47+
1. [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
48+
1. [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
49+
1. [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
50+
1. [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
951

1052
## Rule details
1153

@@ -16,16 +58,13 @@ This rule takes no arguments.
1658
<div onClick={() => void 0} role="button" />
1759
<div onClick={() => void 0} role="presentation" />
1860
<input type="text" onClick={() => void 0} /> // Interactive element does not require role.
19-
<a tabIndex="0" onClick={() => void 0} /> // tabIndex makes this interactive.
2061
<button onClick={() => void 0} className="foo" /> // button is interactive.
2162
<div onClick={() => void 0} role="button" aria-hidden /> // This is hidden from screenreader.
2263
<Input onClick={() => void 0} type="hidden" /> // This is a higher-level DOM component
2364
```
2465

2566
### Fail
2667
```jsx
27-
<div onClick={() => void 0} />
28-
<div onClick={() => void 0} {...props} />
29-
<div onClick={() => void 0} aria-hidden={false} />
30-
<a onClick={() => void 0} />
68+
<li onClick={() => void 0} />
69+
<div onClick={() => void 0} role="listitem" />
3170
```
Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
# no-noninteractive-element-to-interactive-role
22

3-
Write a useful explanation here!
3+
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>`.
44

5-
#### References
6-
1.
5+
Interactive HTML elements indicate _controls_ in the user interface. Interactive elements include `<a href>`, `<button>`, `<input>`, `<select>`, `<textarea>`.
76

8-
## Rule details
97

10-
This rule takes no arguments.
8+
[WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) 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`.
9+
10+
## How do I resolve this error?
11+
12+
### Case: This element should be a control, like a button
1113

12-
### Succeed
13-
```jsx
14-
<div />
14+
Put the control inside the non-interactive container element.
15+
16+
```
17+
<li>
18+
<div
19+
role="button"
20+
onClick={() => {}}
21+
onKeyPress={() => {}}>
22+
Save
23+
</div>
24+
</li>
1525
```
1626

17-
### Fail
18-
```jsx
27+
Or wrap the content inside your interactive element.
1928

2029
```
30+
<div
31+
role="button"
32+
onClick={() => {}}
33+
onKeyPress={() => {}}
34+
tabIndex="0">
35+
<img src="some/file.png" alt="Save" />
36+
</div>
37+
```
38+
39+
### References
40+
41+
1. [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
42+
1. [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
43+
1. [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
44+
1. [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
45+
46+
## Rule details
47+
48+
This rule takes no arguments.

docs/rules/no-static-element-interactions.md

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,62 @@
11
# no-static-element-interactions
22

3-
Enforce non-interactive DOM elements have no interactive handlers. Static elements such as `<div>` and `<span>` should not have mouse/keyboard event listeners. Instead use something more semantic, such as a button or a link.
3+
Static HTML elements do not have semantic meaning. This is clear in the case of `<div>` and `<span>`. It is less so clear in the case of elements that _seem_ semantic, but that do not have a semantic mapping in the accessibility layer. For example `<a>`, `<big>`, `<blockquote>`, `<footer>`, `<picture>`, `<strike>` and `<time>` -- to name a few -- have no semantic layer mapping. They are as void of meaning as `<div>`.
44

5-
Valid interactive elements are:
6-
- `<a>` elements with `href` or `tabIndex` props
7-
- `<button>` elements
8-
- `<input>` elements that are not `hidden`
9-
- `<select>` and `<option>` elements
10-
- `<textarea>` elements
11-
- `<area>` elements
5+
The [WAI-ARIA `role` attribute](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) confers a semantic mapping to an element. The semantic value can then be expressed to a user via assistive technology.
6+
7+
In order to add interactivity such as a mouse or key event listener to a static element, that element must be given a role value as well.
8+
9+
## How do I resolve this error?
10+
11+
### Case: This element acts like a button, link, menuitem, etc.
12+
13+
Indicate the element's role with the `role` attribute:
14+
15+
```
16+
<div
17+
onClick={onClickHandler}
18+
onKeyPress={onKeyPressHandler}
19+
role="button"
20+
tabIndex="0">
21+
Save
22+
</div>
23+
```
24+
25+
Common interactive roles include:
26+
27+
1. `button`
28+
1. `link`
29+
1. `checkbox`
30+
1. `menuitem`
31+
1. `menuitemcheckbox`
32+
1. `menuitemradio`
33+
1. `option`
34+
1. `radio`
35+
1. `searchbox`
36+
1. `switch`
37+
1. `textbox`
38+
39+
Note: Adding a role to your element does **not** add behavior. When a semantic HTML element like `<button>` is used, then it will also respond to Enter key presses when it has focus. The developer is responsible for providing the expected behavior of an element that the role suggests it would have: focusability and key press support.
40+
41+
### Case: This element is not a button, link, menuitem, etc. It is catching bubbled events from elements that it contains
42+
43+
If your element is catching bubbled click or key events from descendant elements, then the proper role for this element is `presentation`.
44+
45+
```
46+
<div
47+
onClick="onClickHandler"
48+
role="presentation">
49+
<button>Save</button>
50+
</div>
51+
```
52+
53+
Marking an element with the role `presentation` indicates to assistive technology that this element should be ignored; it exists to support the web application and is not meant for humans to interact with directly.
54+
55+
### References
56+
1. [WAI-ARIA `role` attribute](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
57+
1. [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
58+
1. [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
59+
1. [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
1260

1361
## Rule details
1462

@@ -17,7 +65,7 @@ This rule takes no arguments.
1765
### Succeed
1866
```jsx
1967
<button onClick={() => {}} className="foo" />
20-
<div className="foo" {...props} />
68+
<div className="foo" onClick={() => {}} role="button" />
2169
<input type="text" onClick={() => {}} />
2270
```
2371

0 commit comments

Comments
 (0)