@arcaauth/eslint-plugin-jsx-a11y 6.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +17 -0
- package/.eslintrc +44 -0
- package/CHANGELOG.md +774 -0
- package/LICENSE.md +8 -0
- package/README.md +423 -0
- package/__mocks__/IdentifierMock.js +15 -0
- package/__mocks__/JSXAttributeMock.js +39 -0
- package/__mocks__/JSXElementMock.js +37 -0
- package/__mocks__/JSXExpressionContainerMock.js +15 -0
- package/__mocks__/JSXSpreadAttributeMock.js +18 -0
- package/__mocks__/JSXTextMock.js +17 -0
- package/__mocks__/LiteralMock.js +17 -0
- package/__mocks__/genInteractives.js +218 -0
- package/__tests__/__util__/axeMapping.js +6 -0
- package/__tests__/__util__/helpers/getESLintCoreRule.js +9 -0
- package/__tests__/__util__/helpers/parsers.js +186 -0
- package/__tests__/__util__/parserOptionsMapper.js +53 -0
- package/__tests__/__util__/ruleOptionsMapperFactory.js +33 -0
- package/__tests__/index-test.js +40 -0
- package/__tests__/src/rules/accessible-emoji-test.js +66 -0
- package/__tests__/src/rules/alt-text-test.js +291 -0
- package/__tests__/src/rules/anchor-ambiguous-text-test.js +117 -0
- package/__tests__/src/rules/anchor-has-content-test.js +54 -0
- package/__tests__/src/rules/anchor-is-valid-test.js +532 -0
- package/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js +95 -0
- package/__tests__/src/rules/aria-props-test.js +69 -0
- package/__tests__/src/rules/aria-proptypes-test.js +311 -0
- package/__tests__/src/rules/aria-role-test.js +118 -0
- package/__tests__/src/rules/aria-unsupported-elements-test.js +75 -0
- package/__tests__/src/rules/autocomplete-valid-test.js +77 -0
- package/__tests__/src/rules/click-events-have-key-events-test.js +77 -0
- package/__tests__/src/rules/control-has-associated-label-test.js +327 -0
- package/__tests__/src/rules/heading-has-content-test.js +85 -0
- package/__tests__/src/rules/html-has-lang-test.js +42 -0
- package/__tests__/src/rules/iframe-has-title-test.js +55 -0
- package/__tests__/src/rules/img-redundant-alt-test.js +137 -0
- package/__tests__/src/rules/interactive-supports-focus-test.js +267 -0
- package/__tests__/src/rules/label-has-associated-control-test.js +243 -0
- package/__tests__/src/rules/label-has-for-test.js +235 -0
- package/__tests__/src/rules/lang-test.js +59 -0
- package/__tests__/src/rules/media-has-caption-test.js +220 -0
- package/__tests__/src/rules/mouse-events-have-key-events-test.js +154 -0
- package/__tests__/src/rules/no-access-key-test.js +48 -0
- package/__tests__/src/rules/no-aria-hidden-on-focusable-test.js +44 -0
- package/__tests__/src/rules/no-autofocus-test.js +68 -0
- package/__tests__/src/rules/no-distracting-elements-test.js +51 -0
- package/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js +405 -0
- package/__tests__/src/rules/no-noninteractive-element-interactions-test.js +502 -0
- package/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js +500 -0
- package/__tests__/src/rules/no-noninteractive-tabindex-test.js +123 -0
- package/__tests__/src/rules/no-onchange-test.js +57 -0
- package/__tests__/src/rules/no-redundant-roles-test.js +98 -0
- package/__tests__/src/rules/no-static-element-interactions-test.js +501 -0
- package/__tests__/src/rules/prefer-tag-over-role-test.js +63 -0
- package/__tests__/src/rules/role-has-required-aria-props-test.js +134 -0
- package/__tests__/src/rules/role-supports-aria-props-test.js +570 -0
- package/__tests__/src/rules/scope-test.js +50 -0
- package/__tests__/src/rules/tabindex-no-positive-test.js +55 -0
- package/__tests__/src/util/attributesComparator-test.js +91 -0
- package/__tests__/src/util/getAccessibleChildText-test.js +174 -0
- package/__tests__/src/util/getComputedRole-test.js +71 -0
- package/__tests__/src/util/getElementType-test.js +154 -0
- package/__tests__/src/util/getExplicitRole-test.js +35 -0
- package/__tests__/src/util/getImplicitRole-test.js +25 -0
- package/__tests__/src/util/getSuggestion-test.js +33 -0
- package/__tests__/src/util/getTabIndex-test.js +85 -0
- package/__tests__/src/util/hasAccessibleChild-test.js +157 -0
- package/__tests__/src/util/implicitRoles/input-test.js +87 -0
- package/__tests__/src/util/implicitRoles/menu-test.js +20 -0
- package/__tests__/src/util/implicitRoles/menuitem-test.js +38 -0
- package/__tests__/src/util/isAbstractRole-test.js +51 -0
- package/__tests__/src/util/isContentEditable-test.js +52 -0
- package/__tests__/src/util/isDOMElement-test.js +30 -0
- package/__tests__/src/util/isDisabledElement-test.js +88 -0
- package/__tests__/src/util/isFocusable-test.js +111 -0
- package/__tests__/src/util/isInteractiveElement-test.js +104 -0
- package/__tests__/src/util/isInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonInteractiveElement-test.js +97 -0
- package/__tests__/src/util/isNonInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonLiteralProperty-test.js +52 -0
- package/__tests__/src/util/isSemanticRoleElement-test.js +72 -0
- package/__tests__/src/util/mayContainChildComponent-test.js +219 -0
- package/__tests__/src/util/mayHaveAccessibleLabel-test.js +256 -0
- package/__tests__/src/util/parserOptionsMapper-test.js +93 -0
- package/__tests__/src/util/schemas-test.js +35 -0
- package/docs/rules/accessible-emoji.md +30 -0
- package/docs/rules/alt-text.md +168 -0
- package/docs/rules/anchor-ambiguous-text.md +91 -0
- package/docs/rules/anchor-has-content.md +64 -0
- package/docs/rules/anchor-is-valid.md +270 -0
- package/docs/rules/aria-activedescendant-has-tabindex.md +52 -0
- package/docs/rules/aria-props.md +29 -0
- package/docs/rules/aria-proptypes.md +30 -0
- package/docs/rules/aria-role.md +51 -0
- package/docs/rules/aria-unsupported-elements.md +30 -0
- package/docs/rules/autocomplete-valid.md +49 -0
- package/docs/rules/click-events-have-key-events.md +28 -0
- package/docs/rules/control-has-associated-label.md +113 -0
- package/docs/rules/heading-has-content.md +67 -0
- package/docs/rules/html-has-lang.md +31 -0
- package/docs/rules/iframe-has-title.md +37 -0
- package/docs/rules/img-redundant-alt.md +48 -0
- package/docs/rules/interactive-supports-focus.md +156 -0
- package/docs/rules/label-has-associated-control.md +152 -0
- package/docs/rules/label-has-for.md +130 -0
- package/docs/rules/lang.md +31 -0
- package/docs/rules/media-has-caption.md +48 -0
- package/docs/rules/mouse-events-have-key-events.md +58 -0
- package/docs/rules/no-access-key.md +30 -0
- package/docs/rules/no-aria-hidden-on-focusable.md +37 -0
- package/docs/rules/no-autofocus.md +43 -0
- package/docs/rules/no-distracting-elements.md +41 -0
- package/docs/rules/no-interactive-element-to-noninteractive-role.md +73 -0
- package/docs/rules/no-noninteractive-element-interactions.md +145 -0
- package/docs/rules/no-noninteractive-element-to-interactive-role.md +76 -0
- package/docs/rules/no-noninteractive-tabindex.md +115 -0
- package/docs/rules/no-onchange.md +36 -0
- package/docs/rules/no-redundant-roles.md +46 -0
- package/docs/rules/no-static-element-interactions.md +114 -0
- package/docs/rules/prefer-tag-over-role.md +32 -0
- package/docs/rules/role-has-required-aria-props.md +31 -0
- package/docs/rules/role-supports-aria-props.md +39 -0
- package/docs/rules/scope.md +30 -0
- package/docs/rules/tabindex-no-positive.md +32 -0
- package/lib/configs/flat-config-base.js +11 -0
- package/lib/configs/legacy-config-base.js +9 -0
- package/lib/index.js +209 -0
- package/lib/rules/accessible-emoji.js +63 -0
- package/lib/rules/alt-text.js +218 -0
- package/lib/rules/anchor-ambiguous-text.js +64 -0
- package/lib/rules/anchor-has-content.js +60 -0
- package/lib/rules/anchor-is-valid.js +122 -0
- package/lib/rules/aria-activedescendant-has-tabindex.js +66 -0
- package/lib/rules/aria-props.js +59 -0
- package/lib/rules/aria-proptypes.js +114 -0
- package/lib/rules/aria-role.js +89 -0
- package/lib/rules/aria-unsupported-elements.js +64 -0
- package/lib/rules/autocomplete-valid.js +67 -0
- package/lib/rules/click-events-have-key-events.js +68 -0
- package/lib/rules/control-has-associated-label.js +103 -0
- package/lib/rules/heading-has-content.js +61 -0
- package/lib/rules/html-has-lang.js +50 -0
- package/lib/rules/iframe-has-title.js +50 -0
- package/lib/rules/img-redundant-alt.js +88 -0
- package/lib/rules/interactive-supports-focus.js +87 -0
- package/lib/rules/label-has-associated-control.js +127 -0
- package/lib/rules/label-has-for.js +150 -0
- package/lib/rules/lang.js +68 -0
- package/lib/rules/media-has-caption.js +96 -0
- package/lib/rules/mouse-events-have-key-events.js +94 -0
- package/lib/rules/no-access-key.js +43 -0
- package/lib/rules/no-aria-hidden-on-focusable.js +47 -0
- package/lib/rules/no-autofocus.js +62 -0
- package/lib/rules/no-distracting-elements.js +54 -0
- package/lib/rules/no-interactive-element-to-noninteractive-role.js +81 -0
- package/lib/rules/no-noninteractive-element-interactions.js +95 -0
- package/lib/rules/no-noninteractive-element-to-interactive-role.js +80 -0
- package/lib/rules/no-noninteractive-tabindex.js +109 -0
- package/lib/rules/no-onchange.js +52 -0
- package/lib/rules/no-redundant-roles.js +86 -0
- package/lib/rules/no-static-element-interactions.js +102 -0
- package/lib/rules/prefer-tag-over-role.js +75 -0
- package/lib/rules/role-has-required-aria-props.js +88 -0
- package/lib/rules/role-supports-aria-props.js +78 -0
- package/lib/rules/scope.js +58 -0
- package/lib/rules/tabindex-no-positive.js +53 -0
- package/lib/util/attributesComparator.js +34 -0
- package/lib/util/getAccessibleChildText.js +55 -0
- package/lib/util/getComputedRole.js +19 -0
- package/lib/util/getElementType.js +30 -0
- package/lib/util/getExplicitRole.js +27 -0
- package/lib/util/getImplicitRole.js +24 -0
- package/lib/util/getSuggestion.js +32 -0
- package/lib/util/getTabIndex.js +34 -0
- package/lib/util/hasAccessibleChild.js +30 -0
- package/lib/util/implicitRoles/a.js +17 -0
- package/lib/util/implicitRoles/area.js +17 -0
- package/lib/util/implicitRoles/article.js +13 -0
- package/lib/util/implicitRoles/aside.js +13 -0
- package/lib/util/implicitRoles/body.js +13 -0
- package/lib/util/implicitRoles/button.js +13 -0
- package/lib/util/implicitRoles/datalist.js +13 -0
- package/lib/util/implicitRoles/details.js +13 -0
- package/lib/util/implicitRoles/dialog.js +13 -0
- package/lib/util/implicitRoles/form.js +13 -0
- package/lib/util/implicitRoles/h1.js +13 -0
- package/lib/util/implicitRoles/h2.js +13 -0
- package/lib/util/implicitRoles/h3.js +13 -0
- package/lib/util/implicitRoles/h4.js +13 -0
- package/lib/util/implicitRoles/h5.js +13 -0
- package/lib/util/implicitRoles/h6.js +13 -0
- package/lib/util/implicitRoles/hr.js +13 -0
- package/lib/util/implicitRoles/img.js +31 -0
- package/lib/util/implicitRoles/index.js +82 -0
- package/lib/util/implicitRoles/input.js +38 -0
- package/lib/util/implicitRoles/li.js +13 -0
- package/lib/util/implicitRoles/link.js +17 -0
- package/lib/util/implicitRoles/menu.js +19 -0
- package/lib/util/implicitRoles/menuitem.js +28 -0
- package/lib/util/implicitRoles/meter.js +13 -0
- package/lib/util/implicitRoles/nav.js +13 -0
- package/lib/util/implicitRoles/ol.js +13 -0
- package/lib/util/implicitRoles/option.js +13 -0
- package/lib/util/implicitRoles/output.js +13 -0
- package/lib/util/implicitRoles/progress.js +13 -0
- package/lib/util/implicitRoles/section.js +13 -0
- package/lib/util/implicitRoles/select.js +13 -0
- package/lib/util/implicitRoles/tbody.js +13 -0
- package/lib/util/implicitRoles/textarea.js +13 -0
- package/lib/util/implicitRoles/tfoot.js +13 -0
- package/lib/util/implicitRoles/thead.js +13 -0
- package/lib/util/implicitRoles/ul.js +13 -0
- package/lib/util/isAbstractRole.js +23 -0
- package/lib/util/isContentEditable.js +13 -0
- package/lib/util/isDOMElement.js +15 -0
- package/lib/util/isDisabledElement.js +23 -0
- package/lib/util/isFocusable.js +23 -0
- package/lib/util/isHiddenFromScreenReader.js +26 -0
- package/lib/util/isInteractiveElement.js +116 -0
- package/lib/util/isInteractiveRole.js +54 -0
- package/lib/util/isNonInteractiveElement.js +131 -0
- package/lib/util/isNonInteractiveRole.js +55 -0
- package/lib/util/isNonLiteralProperty.js +29 -0
- package/lib/util/isPresentationRole.js +13 -0
- package/lib/util/isSemanticRoleElement.js +54 -0
- package/lib/util/mayContainChildComponent.js +50 -0
- package/lib/util/mayHaveAccessibleLabel.js +95 -0
- package/lib/util/schemas.js +52 -0
- package/package.json +120 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# jsx-a11y/no-noninteractive-element-interactions
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
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), `<p>`, `<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`.
|
|
8
|
+
|
|
9
|
+
## How do I resolve this error?
|
|
10
|
+
|
|
11
|
+
### Case: This element acts like a button, link, menuitem, etc
|
|
12
|
+
|
|
13
|
+
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.
|
|
14
|
+
|
|
15
|
+
Common interactive roles include:
|
|
16
|
+
|
|
17
|
+
1. `button`
|
|
18
|
+
1. `link`
|
|
19
|
+
1. `checkbox`
|
|
20
|
+
1. `menuitem`
|
|
21
|
+
1. `menuitemcheckbox`
|
|
22
|
+
1. `menuitemradio`
|
|
23
|
+
1. `option`
|
|
24
|
+
1. `radio`
|
|
25
|
+
1. `searchbox`
|
|
26
|
+
1. `switch`
|
|
27
|
+
1. `textbox`
|
|
28
|
+
|
|
29
|
+
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.
|
|
30
|
+
see [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex).
|
|
31
|
+
|
|
32
|
+
### Case: This element is catching bubbled events from elements that it contains
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
```jsx
|
|
37
|
+
<div role="article">
|
|
38
|
+
<div
|
|
39
|
+
onClick="onClickHandler"
|
|
40
|
+
onKeyPress={onKeyPressHandler}
|
|
41
|
+
role="presentation">
|
|
42
|
+
{this.props.children}
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
### Case: This is a heading that expands/collapses content on the package
|
|
50
|
+
|
|
51
|
+
Headers often double as expand/collapse controls for the content they headline. An accordion component is a common example of this pattern. Rather than assign the interaction handling code to the heading itself, put a button inside the heading instead. This pattern retains the role of the heading and the role of the button.
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
<h3>
|
|
55
|
+
<button onClick={this._expandSection}>News</button>
|
|
56
|
+
</h3>
|
|
57
|
+
<ul id="articles-list">
|
|
58
|
+
<li>...</li>
|
|
59
|
+
</ul>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Case: This element is a table cell
|
|
63
|
+
|
|
64
|
+
Table cells (and tables in general) are meant to contain data. ARIA provides us with a construct called a [Grid](https://w3c.github.io/aria-practices/#grid) that is essentially a 2 dimensional logical container for content and interactive elements.
|
|
65
|
+
|
|
66
|
+
You have two options in this case.
|
|
67
|
+
|
|
68
|
+
#### Option 1, move the interactive content inside the table cells
|
|
69
|
+
|
|
70
|
+
For instance, move the button inside the cell:
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<table>
|
|
74
|
+
<tr>
|
|
75
|
+
<td><button>Sort</button></td>
|
|
76
|
+
</tr>
|
|
77
|
+
</table>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This preserves the table cell semantics and the button semantics; the two are not conflated on the cell.
|
|
81
|
+
|
|
82
|
+
#### Option 2, convert the table into an ARIA grid
|
|
83
|
+
|
|
84
|
+
If your user interface has a table-like layout, but is filled with interactive components in the cells, consider converting the table into a grid.
|
|
85
|
+
|
|
86
|
+
```jsx
|
|
87
|
+
<table role="grid">
|
|
88
|
+
<tr>
|
|
89
|
+
<td role="gridcell" onClick={this.sort}>Sort</td>
|
|
90
|
+
</tr>
|
|
91
|
+
</table>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You can also put the interactive content inside the grid cell. This maintains the semantic distinction between the cell and the interaction content, although a grid cell can be interactive.
|
|
95
|
+
|
|
96
|
+
## Rule options
|
|
97
|
+
|
|
98
|
+
You may configure which handler props should be taken into account when applying this rule. The recommended configuration includes the following 6 handlers.
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
'jsx-a11y/no-noninteractive-element-interactions': [
|
|
102
|
+
'error',
|
|
103
|
+
{
|
|
104
|
+
handlers: [
|
|
105
|
+
'onClick',
|
|
106
|
+
'onMouseDown',
|
|
107
|
+
'onMouseUp',
|
|
108
|
+
'onKeyPress',
|
|
109
|
+
'onKeyDown',
|
|
110
|
+
'onKeyUp',
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Adjust the list of handler prop names in the handlers array to increase or decrease the coverage surface of this rule in your codebase.
|
|
117
|
+
|
|
118
|
+
### Succeed
|
|
119
|
+
|
|
120
|
+
```jsx
|
|
121
|
+
<div onClick={() => void 0} role="button" />
|
|
122
|
+
<div onClick={() => void 0} role="presentation" />
|
|
123
|
+
<input type="text" onClick={() => void 0} /> // Interactive element does not require role.
|
|
124
|
+
<button onClick={() => void 0} className="foo" /> // button is interactive.
|
|
125
|
+
<div onClick={() => void 0} role="button" aria-hidden /> // This is hidden from screen reader.
|
|
126
|
+
<Input onClick={() => void 0} type="hidden" /> // This is a higher-level DOM component
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Fail
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
<li onClick={() => void 0} />
|
|
133
|
+
<div onClick={() => void 0} role="listitem" />
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Accessibility guidelines
|
|
137
|
+
|
|
138
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
139
|
+
|
|
140
|
+
### Resources
|
|
141
|
+
|
|
142
|
+
- [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
|
|
143
|
+
- [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
|
|
144
|
+
- [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
|
|
145
|
+
- [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# jsx-a11y/no-noninteractive-element-to-interactive-role
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
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>`.
|
|
8
|
+
|
|
9
|
+
Interactive HTML elements indicate _controls_ in the user interface. Interactive elements include `<a href>`, `<button>`, `<input>`, `<select>`, `<textarea>`.
|
|
10
|
+
|
|
11
|
+
[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`.
|
|
12
|
+
|
|
13
|
+
## How do I resolve this error?
|
|
14
|
+
|
|
15
|
+
### Case: This element should be a control, like a button
|
|
16
|
+
|
|
17
|
+
Put the control inside the non-interactive container element.
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
<li>
|
|
21
|
+
<div
|
|
22
|
+
role="button"
|
|
23
|
+
onClick={() => {}}
|
|
24
|
+
onKeyPress={() => {}}>
|
|
25
|
+
Save
|
|
26
|
+
</div>
|
|
27
|
+
</li>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or wrap the content inside your interactive element.
|
|
31
|
+
|
|
32
|
+
```jsx
|
|
33
|
+
<div
|
|
34
|
+
role="button"
|
|
35
|
+
onClick={() => {}}
|
|
36
|
+
onKeyPress={() => {}}
|
|
37
|
+
tabIndex="0">
|
|
38
|
+
<img src="some/file.png" alt="Save" />
|
|
39
|
+
</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Rule options
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
{
|
|
48
|
+
'no-noninteractive-element-to-interactive-role': [
|
|
49
|
+
'error',
|
|
50
|
+
{
|
|
51
|
+
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
|
52
|
+
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
|
53
|
+
li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
|
|
54
|
+
table: ['grid'],
|
|
55
|
+
td: ['gridcell'],
|
|
56
|
+
},
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Under the recommended options, the following code is valid. It would be invalid under the strict rules.
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
<ul role="menu" />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Accessibility guidelines
|
|
68
|
+
|
|
69
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
70
|
+
|
|
71
|
+
### Resources
|
|
72
|
+
|
|
73
|
+
- [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
|
|
74
|
+
- [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
|
|
75
|
+
- [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
|
|
76
|
+
- [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# jsx-a11y/no-noninteractive-tabindex
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Tab key navigation should be limited to elements on the page that can be interacted with. Thus it is not necessary to add a tabindex to items in an unordered list, for example, to make them navigable through assistive technology. These applications already afford page traversal mechanisms based on the HTML of the page. Generally, we should try to reduce the size of the page's tab ring rather than increasing it.
|
|
8
|
+
|
|
9
|
+
## How do I resolve this error?
|
|
10
|
+
|
|
11
|
+
### Case: I am using an `<a>` tag. Isn't that interactive?
|
|
12
|
+
|
|
13
|
+
The `<a>` tag is tricky. Consider the following:
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
<a>Edit</a>
|
|
17
|
+
<a href="#">Edit</a>
|
|
18
|
+
<a role="button">Edit</a>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The bare `<a>` tag is an _anchor_. It has no semantic AX API mapping in either ARIA or the AXObject model. It's as meaningful as `<div>`, which is to say it has no meaning. An `<a>` tag with an `href` attribute has an inherent role of `link`. An `<a>` tag with an explicit role obtains the designated role. In the example above, this role is `button`.
|
|
22
|
+
|
|
23
|
+
### Case: I am using "semantic" HTML. Isn't that interactive?
|
|
24
|
+
|
|
25
|
+
If we take a step back into the field of linguistics for a moment, let's consider what it means for something to be "semantic". Nothing, in and of itself, has meaning. Meaning is constructed through dialogue. A speaker intends a meaning and a listener/observer interprets a meaning. Each participant constructs their own meaning through dialogue. There is no intrinsic or isolated meaning outside of interaction. Thus, we must ask, given that we have a "speaker" who communicates via "semantic" HTML, who is listening/observing?
|
|
26
|
+
|
|
27
|
+
In our case, the observer is the Accessibility (AX) API. Browsers interpret HTML (inflected at times by ARIA) to construct a meaning (AX Tree) of the page. Whatever the semantic HTML intends has only the force of suggestion to the AX API. Therefore, we have inconsistencies. For example, there is not yet an ARIA role for `text` or `label` and thus no way to change a `<label>` into plain text or a `<span>` into a label via ARIA. `<div>` has an AXObject correpondant `DivRole`, but no such object maps to `<span>`.
|
|
28
|
+
|
|
29
|
+
What this lint rule endeavors to do is apply the AX API understanding of the semantics of an HTML document back onto your code. The concept of interactivity boils down to whether a user can do something with the indicated or focused component.
|
|
30
|
+
|
|
31
|
+
Common interactive roles include:
|
|
32
|
+
|
|
33
|
+
1. `button`
|
|
34
|
+
1. `link`
|
|
35
|
+
1. `checkbox`
|
|
36
|
+
1. `menuitem`
|
|
37
|
+
1. `menuitemcheckbox`
|
|
38
|
+
1. `menuitemradio`
|
|
39
|
+
1. `option`
|
|
40
|
+
1. `radio`
|
|
41
|
+
1. `searchbox`
|
|
42
|
+
1. `switch`
|
|
43
|
+
1. `textbox`
|
|
44
|
+
|
|
45
|
+
Endeavor to limit tabbable elements to those that a user can act upon.
|
|
46
|
+
|
|
47
|
+
### Case: Shouldn't I add a tabindex so that users can navigate to this item?
|
|
48
|
+
|
|
49
|
+
It is not necessary to put a tabindex on an `<article>`, for instance or on `<li>` items; assistive technologies provide affordances to users to find and traverse these containers. Most elements that require a tabindex -- `<a href>`, `<button>`, `<input>`, `<textarea>` -- have it already.
|
|
50
|
+
|
|
51
|
+
Your application might require an exception to this rule in the case of an element that captures incoming tab traversal for a composite widget. In that case, turn off this rule on a per instance basis. This is an uncommon case.
|
|
52
|
+
|
|
53
|
+
If you know that a particular element will be scrollable, you might want to add `tabindex="0"` if your website supports browsers that don't make these containers keyboard-focusable. The current status for this platform feature can be tracked in [Chrome Platform Status "Feature: Keyboard-focusable scroll containers"](https://www.chromestatus.com/feature/5231964663578624).
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
// eslint-disable-next-line no-noninteractive-tabindex
|
|
57
|
+
<pre tabIndex="0">
|
|
58
|
+
<code>{someLongCode}</code>
|
|
59
|
+
</pre>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Rule options
|
|
63
|
+
|
|
64
|
+
The recommended options for this rule allow `tabIndex` on elements with the noninteractive `tabpanel` role. Adding `tabIndex` to a tabpanel is a recommended practice in some instances.
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
'jsx-a11y/no-noninteractive-tabindex': [
|
|
68
|
+
'error',
|
|
69
|
+
{
|
|
70
|
+
tags: [],
|
|
71
|
+
roles: ['tabpanel'],
|
|
72
|
+
allowExpressionValues: true,
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The `allowExpressionValues` option determines whether the `role` attribute is allowed to be assigned using an expression. For example, the following would pass in recommended mode if `allowExpressionValues` is set to be `true`:
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
<div role={ROLE_BUTTON} onClick={() => {}} tabIndex="0" />;
|
|
81
|
+
// In case of a conditional expression, there should be literals on both sides of ternary operator
|
|
82
|
+
<div role={isButton ? "button" : "link"} onClick={() => {}} tabIndex="0" />;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Succeed
|
|
86
|
+
|
|
87
|
+
```jsx
|
|
88
|
+
<div />
|
|
89
|
+
<MyButton tabIndex={0} />
|
|
90
|
+
<button />
|
|
91
|
+
<button tabIndex="0" />
|
|
92
|
+
<button tabIndex={0} />
|
|
93
|
+
<div />
|
|
94
|
+
<div tabIndex="-1" />
|
|
95
|
+
<div role="button" tabIndex="0" />
|
|
96
|
+
<div role="article" tabIndex="-1" />
|
|
97
|
+
<article tabIndex="-1" />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Fail
|
|
101
|
+
|
|
102
|
+
```jsx
|
|
103
|
+
<div tabIndex="0" />
|
|
104
|
+
<div role="article" tabIndex="0" />
|
|
105
|
+
<article tabIndex="0" />
|
|
106
|
+
<article tabIndex={0} />
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Accessibility guidelines
|
|
110
|
+
|
|
111
|
+
- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)
|
|
112
|
+
|
|
113
|
+
### Resources
|
|
114
|
+
|
|
115
|
+
- [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# jsx-a11y/no-onchange
|
|
2
|
+
|
|
3
|
+
❌ This rule is deprecated.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
⚠️ **Deprecated:** This rule is based on reports of behavior of [old browsers (eg. IE 10 and below)](https://www.quirksmode.org/dom/events/change.html#t05). In the meantime, this behavior has been corrected, both in newer versions of browsers as well as [in the DOM spec](https://bugzilla.mozilla.org/show_bug.cgi?id=969068#c2).
|
|
8
|
+
|
|
9
|
+
Enforce usage of `onBlur` over/in parallel with `onChange` on select menu elements for accessibility. `onBlur` **should** be used instead of `onChange`, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users. `onBlur` is a more declarative action by the user: for instance in a dropdown, using the arrow keys to toggle between options will trigger the `onChange` event in some browsers. Regardless, when a change of context results from an `onBlur` event or an `onChange` event, the user should be notified of the change unless it occurs below the currently focused element.
|
|
10
|
+
|
|
11
|
+
## Rule details
|
|
12
|
+
|
|
13
|
+
This rule takes no arguments.
|
|
14
|
+
|
|
15
|
+
### Succeed
|
|
16
|
+
```jsx
|
|
17
|
+
<select onBlur={updateModel}>
|
|
18
|
+
<option/>
|
|
19
|
+
</select>
|
|
20
|
+
|
|
21
|
+
<select>
|
|
22
|
+
<option onBlur={handleOnBlur} onChange={handleOnChange} />
|
|
23
|
+
</select>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Fail
|
|
27
|
+
```jsx
|
|
28
|
+
<select onChange={updateModel} />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Accessibility guidelines
|
|
32
|
+
- [WCAG 3.2.2](https://www.w3.org/WAI/WCAG21/Understanding/on-input)
|
|
33
|
+
|
|
34
|
+
### Resources
|
|
35
|
+
- [onChange Event Accessibility Issues](https://web.archive.org/web/20191207202425/http://cita.disability.uiuc.edu/html-best-practices/auto/onchange.php)
|
|
36
|
+
- [onChange Select Menu](https://www.themaninblue.com/writing/perspective/2004/10/19/)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# jsx-a11y/no-redundant-roles
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Some HTML elements have native semantics that are implemented by the browser. This includes default/implicit ARIA roles. Setting an ARIA role that matches its default/implicit role is redundant since it is already set by the browser.
|
|
8
|
+
|
|
9
|
+
## Rule options
|
|
10
|
+
|
|
11
|
+
The default options for this rule allow an implicit role of `navigation` to be applied to a `nav` element as is [advised by w3](https://www.w3.org/WAI/GL/wiki/Using_HTML5_nav_element#Example:The_.3Cnav.3E_element). The options are provided as an object keyed by HTML element name; the value is an array of implicit ARIA roles that are allowed on the specified element.
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
{
|
|
15
|
+
'jsx-a11y/no-redundant-roles': [
|
|
16
|
+
'error',
|
|
17
|
+
{
|
|
18
|
+
nav: ['navigation'],
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Succeed
|
|
25
|
+
|
|
26
|
+
```jsx
|
|
27
|
+
<div />
|
|
28
|
+
<button role="presentation" />
|
|
29
|
+
<MyComponent role="main" />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Fail
|
|
33
|
+
|
|
34
|
+
```jsx
|
|
35
|
+
<button role="button" />
|
|
36
|
+
<img role="img" src="foo.jpg" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Accessibility guidelines
|
|
40
|
+
|
|
41
|
+
General best practice (reference resources)
|
|
42
|
+
|
|
43
|
+
### Resources
|
|
44
|
+
|
|
45
|
+
- [ARIA Spec, ARIA Adds Nothing to Default Semantics of Most HTML Elements](https://www.w3.org/TR/using-aria/#aria-does-nothing)
|
|
46
|
+
- [Identifying SVG as an image](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#identifying_svg_as_an_image)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# jsx-a11y/no-static-element-interactions
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
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>`.
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
## How do I resolve this error?
|
|
14
|
+
|
|
15
|
+
### Case: This element acts like a button, link, menuitem, etc
|
|
16
|
+
|
|
17
|
+
Indicate the element's role with the `role` attribute:
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
<div
|
|
21
|
+
onClick={onClickHandler}
|
|
22
|
+
onKeyPress={onKeyPressHandler}
|
|
23
|
+
role="button"
|
|
24
|
+
tabindex="0">
|
|
25
|
+
Save
|
|
26
|
+
</div>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Common interactive roles include:
|
|
30
|
+
|
|
31
|
+
1. `button`
|
|
32
|
+
1. `link`
|
|
33
|
+
1. `checkbox`
|
|
34
|
+
1. `menuitem`
|
|
35
|
+
1. `menuitemcheckbox`
|
|
36
|
+
1. `menuitemradio`
|
|
37
|
+
1. `option`
|
|
38
|
+
1. `radio`
|
|
39
|
+
1. `searchbox`
|
|
40
|
+
1. `switch`
|
|
41
|
+
1. `textbox`
|
|
42
|
+
|
|
43
|
+
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.
|
|
44
|
+
|
|
45
|
+
### Case: The event handler is only being used to capture bubbled events
|
|
46
|
+
|
|
47
|
+
If your element is catching bubbled click or key events from descendant elements, there are no appropriate roles for your element: you will have to deactivate the rule. Consider explaining the reason for disabling the rule as well.
|
|
48
|
+
|
|
49
|
+
```jsx
|
|
50
|
+
{/* The <div> element has a child <button> element that allows keyboard interaction */}
|
|
51
|
+
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
|
52
|
+
<div onClick={this.handleButtonClick}>
|
|
53
|
+
<button>Save</button>
|
|
54
|
+
<button>Cancel</button>
|
|
55
|
+
</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Do not use the role `presentation` on the element: it removes the element's semantics, and may also remove its children's semantics, creating big issues with assistive technology.
|
|
59
|
+
|
|
60
|
+
## Rule options
|
|
61
|
+
|
|
62
|
+
You may configure which handler props should be taken into account when applying this rule. The recommended configuration includes the following 6 handlers and the `allowExpressionValues` option.
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
'jsx-a11y/no-static-element-interactions': [
|
|
66
|
+
'error',
|
|
67
|
+
{
|
|
68
|
+
handlers: [
|
|
69
|
+
'onClick',
|
|
70
|
+
'onMouseDown',
|
|
71
|
+
'onMouseUp',
|
|
72
|
+
'onKeyPress',
|
|
73
|
+
'onKeyDown',
|
|
74
|
+
'onKeyUp',
|
|
75
|
+
],
|
|
76
|
+
allowExpressionValues: true,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Adjust the list of handler prop names in the handlers array to increase or decrease the coverage surface of this rule in your codebase.
|
|
82
|
+
|
|
83
|
+
The `allowExpressionValues` option determines whether the `role` attribute is allowed to be assigned using an expression. For example, the following would pass in recommended mode if `allowExpressionValues` is set to be `true`:
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
<div role={ROLE_BUTTON} onClick={() => {}} />;
|
|
87
|
+
// In case of a conditional expression, there should be literals on both sides of ternary operator
|
|
88
|
+
<div role={isButton ? "button" : "link"} onClick={() => {}} />;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Succeed
|
|
92
|
+
|
|
93
|
+
```jsx
|
|
94
|
+
<button onClick={() => {}} className="foo" />
|
|
95
|
+
<div className="foo" onClick={() => {}} role="button" />
|
|
96
|
+
<input type="text" onClick={() => {}} />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Fail
|
|
100
|
+
|
|
101
|
+
```jsx
|
|
102
|
+
<div onClick={() => {}} />
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Accessibility guidelines
|
|
106
|
+
|
|
107
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
108
|
+
|
|
109
|
+
### Resources
|
|
110
|
+
|
|
111
|
+
- [WAI-ARIA `role` attribute](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
|
|
112
|
+
- [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
|
|
113
|
+
- [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
|
|
114
|
+
- [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# jsx-a11y/prefer-tag-over-role
|
|
2
|
+
|
|
3
|
+
<!-- end auto-generated rule header -->
|
|
4
|
+
|
|
5
|
+
Enforces using semantic DOM elements over the ARIA `role` property.
|
|
6
|
+
|
|
7
|
+
## Rule details
|
|
8
|
+
|
|
9
|
+
This rule takes no arguments.
|
|
10
|
+
|
|
11
|
+
### Succeed
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<div>...</div>
|
|
15
|
+
<header>...</header>
|
|
16
|
+
<img alt="" src="image.jpg" />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Fail
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
<div role="checkbox">
|
|
23
|
+
<div role="img">
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Accessibility guidelines
|
|
27
|
+
|
|
28
|
+
- [WAI-ARIA Roles model](https://www.w3.org/TR/wai-aria-1.0/roles)
|
|
29
|
+
|
|
30
|
+
### Resources
|
|
31
|
+
|
|
32
|
+
- [MDN WAI-ARIA Roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# jsx-a11y/role-has-required-aria-props
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Elements with ARIA roles must have all required attributes for that role.
|
|
8
|
+
|
|
9
|
+
## Rule details
|
|
10
|
+
|
|
11
|
+
This rule takes no arguments.
|
|
12
|
+
|
|
13
|
+
### Succeed
|
|
14
|
+
```jsx
|
|
15
|
+
<!-- Good: the checkbox role requires the aria-checked state -->
|
|
16
|
+
<span role="checkbox" aria-checked="false" aria-labelledby="foo" tabindex="0"></span>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Fail
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
<!-- Bad: the checkbox role requires the aria-checked state -->
|
|
23
|
+
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Accessibility guidelines
|
|
27
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
28
|
+
|
|
29
|
+
### Resources
|
|
30
|
+
- [ARIA Spec, Roles](https://www.w3.org/TR/wai-aria/#roles)
|
|
31
|
+
- [Chrome Audit Rules, AX_ARIA_03](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_03)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# jsx-a11y/role-supports-aria-props
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`. Many ARIA attributes (states and properties) can only be used on elements with particular roles. Some elements have implicit roles, such as `<a href="#" />`, which will resolve to `role="link"`.
|
|
8
|
+
|
|
9
|
+
## Rule details
|
|
10
|
+
|
|
11
|
+
This rule takes no arguments.
|
|
12
|
+
|
|
13
|
+
### Succeed
|
|
14
|
+
```jsx
|
|
15
|
+
<!-- Good: the radiogroup role does support the aria-required property -->
|
|
16
|
+
<ul role="radiogroup" aria-required aria-labelledby="foo">
|
|
17
|
+
<li tabIndex="-1" role="radio" aria-checked="false">Rainbow Trout</li>
|
|
18
|
+
<li tabIndex="-1" role="radio" aria-checked="false">Brook Trout</li>
|
|
19
|
+
<li tabIndex="0" role="radio" aria-checked="true">Lake Trout</li>
|
|
20
|
+
</ul>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Fail
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
<!-- Bad: the radio role does not support the aria-required property -->
|
|
27
|
+
<ul role="radiogroup" aria-labelledby="foo">
|
|
28
|
+
<li aria-required tabIndex="-1" role="radio" aria-checked="false">Rainbow Trout</li>
|
|
29
|
+
<li aria-required tabIndex="-1" role="radio" aria-checked="false">Brook Trout</li>
|
|
30
|
+
<li aria-required tabIndex="0" role="radio" aria-checked="true">Lake Trout</li>
|
|
31
|
+
</ul>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Accessibility guidelines
|
|
35
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
36
|
+
|
|
37
|
+
### Resources
|
|
38
|
+
- [ARIA Spec, States and Properties](https://www.w3.org/TR/wai-aria/#states_and_properties)
|
|
39
|
+
- [Chrome Audit Rules, AX_ARIA_10](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_10)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# jsx-a11y/scope
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
The `scope` prop should be used only on `<th>` elements.
|
|
8
|
+
|
|
9
|
+
## Rule details
|
|
10
|
+
|
|
11
|
+
This rule takes no arguments.
|
|
12
|
+
|
|
13
|
+
### Succeed
|
|
14
|
+
```jsx
|
|
15
|
+
<th scope="col" />
|
|
16
|
+
<th scope={scope} />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Fail
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
<div scope />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Accessibility guidelines
|
|
26
|
+
- [WCAG 1.3.1](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships)
|
|
27
|
+
- [WCAG 4.1.1](https://www.w3.org/WAI/WCAG21/Understanding/parsing)
|
|
28
|
+
|
|
29
|
+
### Resources
|
|
30
|
+
- [axe-core, scope-attr-valid](https://dequeuniversity.com/rules/axe/3.5/scope-attr-valid)
|