Skip to content

Commit 579981e

Browse files
authored
Merge branch 'master' into ariaPropsCasing
2 parents 2529ad3 + de76184 commit 579981e

15 files changed

+215
-39
lines changed

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Add `plugin:jsx-a11y/recommended` or `plugin:jsx-a11y/strict` in `extends`:
103103
- [aria-proptypes](docs/rules/aria-proptypes.md): Enforce ARIA state and property values are valid.
104104
- [aria-role](docs/rules/aria-role.md): Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role.
105105
- [aria-unsupported-elements](docs/rules/aria-unsupported-elements.md): Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes.
106+
- [autocomplete-valid](docs/rules/autocomplete-valid.md): Enforce that autocomplete attributes are used correctly.
106107
- [click-events-have-key-events](docs/rules/click-events-have-key-events.md): Enforce a clickable non-interactive element has at least one keyboard event listener.
107108
- [heading-has-content](docs/rules/heading-has-content.md): Enforce heading (`h1`, `h2`, etc) elements contain accessible content.
108109
- [html-has-lang](docs/rules/html-has-lang.md): Enforce `<html>` element has `lang` prop.
@@ -141,6 +142,7 @@ Rule | Recommended | Strict
141142
[aria-proptypes](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md) | error | error
142143
[aria-role](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md) | error | error
143144
[aria-unsupported-elements](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md) | error | error
145+
[autocomplete-valid](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/autocomplete-valid.md) | error | error
144146
[click-events-have-key-events](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/click-events-have-key-events.md) | error | error
145147
[heading-has-content](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md) | error | error
146148
[html-has-lang](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md) | error | error
@@ -169,7 +171,7 @@ Rule | Recommended | Strict
169171
The following rules have extra options when in *recommended* mode:
170172

171173
#### no-interactive-element-to-noninteractive-role
172-
```
174+
```js
173175
'jsx-a11y/no-interactive-element-to-noninteractive-role': [
174176
'error',
175177
{
@@ -179,7 +181,7 @@ The following rules have extra options when in *recommended* mode:
179181
```
180182

181183
#### no-noninteractive-element-interactions
182-
```
184+
```js
183185
'jsx-a11y/no-noninteractive-element-interactions': [
184186
'error',
185187
{
@@ -196,7 +198,7 @@ The following rules have extra options when in *recommended* mode:
196198
```
197199

198200
#### no-noninteractive-element-to-interactive-role
199-
```
201+
```js
200202
'jsx-a11y/no-noninteractive-element-to-interactive-role': [
201203
'error',
202204
{
@@ -226,7 +228,7 @@ The following rules have extra options when in *recommended* mode:
226228
```
227229

228230
#### no-noninteractive-tabindex
229-
```
231+
```js
230232
'jsx-a11y/no-noninteractive-tabindex': [
231233
'error',
232234
{
@@ -237,7 +239,7 @@ The following rules have extra options when in *recommended* mode:
237239
```
238240

239241
#### no-static-element-interactions
240-
```
242+
```js
241243
'jsx-a11y/no-noninteractive-element-interactions': [
242244
'error',
243245
{

__tests__/__util__/axeMapping.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* eslint-disable import/prefer-default-export, no-underscore-dangle */
2+
import * as axe from 'axe-core';
3+
4+
export function axeFailMessage(checkId, data) {
5+
return axe._audit.data.checks[checkId].messages.fail(data);
6+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* eslint-env jest */
2+
/**
3+
* @fileoverview Ensure autocomplete attribute is correct.
4+
* @author Wilco Fiers
5+
*/
6+
7+
// -----------------------------------------------------------------------------
8+
// Requirements
9+
// -----------------------------------------------------------------------------
10+
11+
import { RuleTester } from 'eslint';
12+
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
13+
import { axeFailMessage } from '../../__util__/axeMapping';
14+
import rule from '../../../src/rules/autocomplete-valid';
15+
16+
// -----------------------------------------------------------------------------
17+
// Tests
18+
// -----------------------------------------------------------------------------
19+
20+
const ruleTester = new RuleTester();
21+
22+
const invalidAutocomplete = [{
23+
message: axeFailMessage('autocomplete-valid'),
24+
type: 'JSXOpeningElement',
25+
}];
26+
27+
const inappropriateAutocomplete = [{
28+
message: axeFailMessage('autocomplete-appropriate'),
29+
type: 'JSXOpeningElement',
30+
}];
31+
32+
ruleTester.run('autocomplete-valid', rule, {
33+
valid: [
34+
// INAPPLICABLE
35+
{ code: '<input type="text" />;' },
36+
// // PASSED AUTOCOMPLETE
37+
{ code: '<input type="text" autocomplete="name" />;' },
38+
{ code: '<input type="text" autocomplete="" />;' },
39+
{ code: '<input type="text" autocomplete="off" />;' },
40+
{ code: '<input type="text" autocomplete="on" />;' },
41+
{ code: '<input type="text" autocomplete="billing family-name" />;' },
42+
{ code: '<input type="text" autocomplete="section-blue shipping street-address" />;' },
43+
{ code: '<input type="text" autocomplete="section-somewhere shipping work email" />;' },
44+
{ code: '<input type="text" autocomplete />;' },
45+
{ code: '<input type="text" autocomplete={autocompl} />;' },
46+
{ code: '<input type="text" autocomplete={autocompl || "name"} />;' },
47+
{ code: '<input type="text" autocomplete={autocompl || "foo"} />;' },
48+
{ code: '<Foo autocomplete="bar"></Foo>;' },
49+
].map(parserOptionsMapper),
50+
invalid: [
51+
// FAILED "autocomplete-valid"
52+
{ code: '<input type="text" autocomplete="foo" />;', errors: invalidAutocomplete },
53+
{ code: '<input type="text" autocomplete="name invalid" />;', errors: invalidAutocomplete },
54+
{ code: '<input type="text" autocomplete="invalid name" />;', errors: invalidAutocomplete },
55+
{ code: '<input type="text" autocomplete="home url" />;', errors: invalidAutocomplete },
56+
{ code: '<Bar autocomplete="baz"></Bar>;', errors: invalidAutocomplete, options: [{ inputComponents: ['Bar'] }] },
57+
58+
// FAILED "autocomplete-appropriate"
59+
{ code: '<input type="date" autocomplete="email" />;', errors: inappropriateAutocomplete },
60+
{ code: '<input type="number" autocomplete="url" />;', errors: inappropriateAutocomplete },
61+
{ code: '<input type="month" autocomplete="tel" />;', errors: inappropriateAutocomplete },
62+
{ code: '<Foo type="month" autocomplete="tel"></Foo>;', errors: inappropriateAutocomplete, options: [{ inputComponents: ['Foo'] }] },
63+
].map(parserOptionsMapper),
64+
});

docs/rules/aria-role.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference t
99

1010
This rule takes one optional object argument of type object:
1111

12-
```
12+
```json
1313
{
1414
"rules": {
1515
"jsx-a11y/aria-role": [ 2, {

docs/rules/autocomplete-valid.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# autocomplete-valid
2+
3+
Ensure the autocomplete attribute is correct and suitable for the form field it is used with.
4+
5+
#### References
6+
1. [axe-core, autocomplete-valid](https://dequeuniversity.com/rules/axe/3.2/autocomplete-valid)
7+
2. [HTML 5.2, Autocomplete requirements](https://www.w3.org/TR/html52/sec-forms.html#autofilling-form-controls-the-autocomplete-attribute)
8+
9+
## Rule details
10+
11+
This rule takes one optional object argument of type object:
12+
13+
```
14+
{
15+
"rules": {
16+
"jsx-a11y/autocomplete-valid": [ 2, {
17+
"inputComponents": ["Input", "FormField"]
18+
}],
19+
}
20+
}
21+
```
22+
23+
### Succeed
24+
```jsx
25+
<!-- Good: the autocomplete attribute is used according to the HTML specification -->
26+
<input type="text" autocomplete="name" />
27+
28+
<!-- Good: MyInput is not listed in inputComponents -->
29+
<MyInput autocomplete="incorrect" />
30+
```
31+
32+
### Fail
33+
```jsx
34+
<!-- Bad: the autocomplete attribute has an invalid value -->
35+
<input type="text" autocomplete="incorrect" />
36+
37+
<!-- Bad: the autocomplete attribute is on an inappropriate input element -->
38+
<input type="email" autocomplete="url" />
39+
40+
<!-- Bad: MyInput is listed in inputComponents -->
41+
<MyInput autocomplete="incorrect" />
42+
```

docs/rules/interactive-supports-focus.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This element is a stand-alone control like a button, a link or a form element. A
1010

1111
Add the `tabIndex` property to your component. A value of zero indicates that this element can be tabbed to.
1212

13-
```
13+
```jsx
1414
<div
1515
role="button"
1616
tabIndex={0} />
@@ -26,7 +26,7 @@ Generally buttons, links and form elements should be reachable via tab key press
2626

2727
This element is part of a group of buttons, links, menu items, etc. Or this element is part of a composite widget. Composite widgets prescribe standard [keyboard interaction patterns](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav). Within a group of similar elements -- like a button bar -- or within a composite widget, elements that can be focused are given a tabindex of -1. This makes the element *focusable* but not *tabbable*. Generally one item in a group should have a tabindex of zero so that a user can tab to the component. Once an element in the component has focus, your key management behaviors will control traversal within the component's pieces. As the UI author, you will need to implement the key handling behaviors such as listening for traversal key (up/down/left/right) presses and moving the page focus between the focusable elements in your widget.
2828

29-
```
29+
```jsx
3030
<div role="menu">
3131
<div role="menuitem" tabIndex="0">Open</div>
3232
<div role="menuitem" tabIndex="-1">Save</div>
@@ -40,7 +40,7 @@ In the example above, the first item in the group can be tabbed to. The develope
4040

4141
If your element is catching bubbled click or key events from descendant elements, then the proper role for this element is `presentation`.
4242

43-
```
43+
```jsx
4444
<div
4545
onClick={onClickHandler}
4646
role="presentation">
@@ -60,28 +60,30 @@ Marking an element with the role `presentation` indicates to assistive technolog
6060

6161
This rule takes an options object with the key `tabbable`. The value is an array of interactive ARIA roles that should be considered tabbable, not just focusable. Any interactive role not included in this list will be flagged as needing to be focusable (tabindex of -1).
6262

63-
```
64-
'jsx-a11y/interactive-supports-focus': [
65-
'error',
66-
{
67-
tabbable: [
68-
'button',
69-
'checkbox',
70-
'link',
71-
'searchbox',
72-
'spinbutton',
73-
'switch',
74-
'textbox',
75-
],
76-
},
77-
]
63+
```js
64+
{
65+
'jsx-a11y/interactive-supports-focus': [
66+
'error',
67+
{
68+
tabbable: [
69+
'button',
70+
'checkbox',
71+
'link',
72+
'searchbox',
73+
'spinbutton',
74+
'switch',
75+
'textbox',
76+
],
77+
},
78+
]
79+
}
7880
```
7981

8082
The recommended options list interactive roles that act as form elements. Generally, elements with a role like `menuitem` are a part of a composite widget. Focus in a composite widget is controlled and moved programmatically to satisfy the prescribed [keyboard interaction pattern](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav) for the widget.
8183

8284
The list of possible values includes:
8385

84-
```
86+
```js
8587
[
8688
'button',
8789
'checkbox',

docs/rules/no-autofocus.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Enforce that autoFocus prop is not used on elements. Autofocusing elements can c
99

1010
This rule takes one optional object argument of type object:
1111

12-
```
12+
```json
1313
{
1414
"rules": {
1515
"jsx-a11y/no-autofocus": [ 2, {

docs/rules/no-interactive-element-to-noninteractive-role.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Non-interactive HTML elements and non-interactive ARIA roles indicate _content_
1212

1313
Wrap your interactive element in a `<div>` with the desired role.
1414

15-
```
15+
```jsx
1616
<div role="article">
1717
<button>Save</button>
1818
</div>
@@ -22,7 +22,7 @@ Wrap your interactive element in a `<div>` with the desired role.
2222

2323
Put the content inside your interactive element.
2424

25-
```
25+
```jsx
2626
<div
2727
role="button"
2828
onClick={() => {}}
@@ -45,7 +45,7 @@ The recommended options for this rule allow the `tr` element to be given a role
4545

4646
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.
4747

48-
```
48+
```js
4949
{
5050
'no-interactive-element-to-noninteractive-role': [
5151
'error',
@@ -58,6 +58,6 @@ Options are provided as an object keyed by HTML element name; the value is an ar
5858

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

61-
```
61+
```jsx
6262
<tr role="presentation" />
6363
```

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ see [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://w
2929

3030
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.
3131

32-
```
32+
```jsx
3333
<div role="article">
3434
<div
3535
onClick="onClickHandler"
@@ -65,7 +65,7 @@ You have two options in this case.
6565

6666
For instance, move the button inside the cell:
6767

68-
```
68+
```jsx
6969
<table>
7070
<tr>
7171
<td><button>Sort</button></td>
@@ -79,7 +79,7 @@ This preserves the table cell semantics and the button semantics; the two are no
7979

8080
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.
8181

82-
```
82+
```jsx
8383
<table role="grid">
8484
<tr>
8585
<td role="gridcell" onClick={this.sort}>Sort</td>

docs/rules/no-noninteractive-element-to-interactive-role.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Interactive HTML elements indicate _controls_ in the user interface. Interactive
1313

1414
Put the control inside the non-interactive container element.
1515

16-
```
16+
```jsx
1717
<li>
1818
<div
1919
role="button"
@@ -26,7 +26,7 @@ Put the control inside the non-interactive container element.
2626

2727
Or wrap the content inside your interactive element.
2828

29-
```
29+
```jsx
3030
<div
3131
role="button"
3232
onClick={() => {}}
@@ -47,7 +47,7 @@ Or wrap the content inside your interactive element.
4747

4848
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.
4949

50-
```
50+
```js
5151
{
5252
'no-noninteractive-element-to-interactive-role': [
5353
'error',
@@ -64,6 +64,6 @@ The recommended options for this rule allow several common interactive roles to
6464

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

67-
```
67+
```jsx
6868
<ul role="menu" />
6969
```

0 commit comments

Comments
 (0)