@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,152 @@
|
|
|
1
|
+
# jsx-a11y/label-has-associated-control
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforce that a label tag has a text label and an associated control.
|
|
8
|
+
|
|
9
|
+
There are two supported ways to associate a label with a control:
|
|
10
|
+
|
|
11
|
+
- Wrapping a control in a label tag.
|
|
12
|
+
- Adding `htmlFor` to a label and assigning it a DOM ID string that indicates an input on the page.
|
|
13
|
+
|
|
14
|
+
This rule checks that any `label` tag (or an indicated custom component that will output a `label` tag) either (1) wraps an `input` element (or an indicated custom component that will output an `input` tag) or (2) has an `htmlFor` attribute and that the `label` tag has text content.
|
|
15
|
+
|
|
16
|
+
## How do I resolve this error?
|
|
17
|
+
|
|
18
|
+
### Case: I just want a text label associated with an input.
|
|
19
|
+
|
|
20
|
+
The simplest way to achieve an association between a label and an input is to wrap the input in the label.
|
|
21
|
+
|
|
22
|
+
```jsx
|
|
23
|
+
<label>
|
|
24
|
+
Surname
|
|
25
|
+
<input type="text" />
|
|
26
|
+
</label>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
All modern browsers and assistive technology will associate the label with the control.
|
|
30
|
+
|
|
31
|
+
### Case: The label is a sibling of the control.
|
|
32
|
+
|
|
33
|
+
In this case, use `htmlFor` and an ID to associate the controls.
|
|
34
|
+
|
|
35
|
+
```jsx
|
|
36
|
+
<label htmlFor={domId}>Surname</label>
|
|
37
|
+
<input type="text" id={domId} />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Case: My label and input components are custom components.
|
|
41
|
+
|
|
42
|
+
You can configure the rule to be aware of your custom components.
|
|
43
|
+
|
|
44
|
+
```jsx
|
|
45
|
+
<CustomInputLabel label="Surname">
|
|
46
|
+
<CustomInput type="text" value={value} />
|
|
47
|
+
</CustomInputLabel>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
And the configuration:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"rules": {
|
|
55
|
+
"jsx-a11y/label-has-associated-control": [ 2, {
|
|
56
|
+
"labelComponents": ["CustomInputLabel"],
|
|
57
|
+
"labelAttributes": ["label"],
|
|
58
|
+
"controlComponents": ["CustomInput"],
|
|
59
|
+
"depth": 3,
|
|
60
|
+
}],
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Case: I have two labels for the same input
|
|
66
|
+
|
|
67
|
+
If the second `label` is in a different part of the HTML, then the second one can only contain `htmlFor` but not nesting. You will probably need eslint override comment on the second label.
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
{/* eslint jsx-a11y/label-has-associated-control: ["error", { assert: "either" } ] */}
|
|
71
|
+
<label htmlFor="a">
|
|
72
|
+
Username:
|
|
73
|
+
</label>
|
|
74
|
+
...
|
|
75
|
+
<label htmlFor="a">
|
|
76
|
+
<input id="a" />
|
|
77
|
+
</label>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## How to manage IDs of `input`
|
|
81
|
+
|
|
82
|
+
A common way to think of `id` with libraries like React is, `id`s should be avoided since it must be unique on the page, and components need to be reusable. Hence it is tempted to generate `id` during render-time if `id` is required. *However:*
|
|
83
|
+
|
|
84
|
+
IDs shouldn't be generated in the browser, so that server and client rendering are deterministic. Render-time uuids aren't just a hack, they're actually broken and should never be used.
|
|
85
|
+
|
|
86
|
+
To restate, **every ID needs to be deterministic**, on the server and the client, and guaranteed to be unique on the page. EG: For each input, a required ID prop can be passed down from as far up the tree as possible to guarantee uniqueness.
|
|
87
|
+
|
|
88
|
+
## Rule options
|
|
89
|
+
|
|
90
|
+
This rule takes one optional object argument of type object:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"rules": {
|
|
95
|
+
"jsx-a11y/label-has-associated-control": [ 2, {
|
|
96
|
+
"labelComponents": ["CustomLabel"],
|
|
97
|
+
"labelAttributes": ["inputLabel"],
|
|
98
|
+
"controlComponents": ["CustomInput"],
|
|
99
|
+
"assert": "both",
|
|
100
|
+
"depth": 3,
|
|
101
|
+
}],
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`labelComponents` is a list of custom React Component names that should be checked for an associated control.
|
|
107
|
+
|
|
108
|
+
`labelAttributes` is a list of attributes to check on the label component and its children for a label. Use this if you have a custom component that uses a string passed on a prop to render an HTML `label`, for example.
|
|
109
|
+
|
|
110
|
+
`controlComponents` is a list of custom React Components names that will output an input element. [Glob format](https://linuxhint.com/bash_globbing_tutorial/) is also supported for specifying names (e.g., `Label*` matches `LabelComponent` but not `CustomLabel`, `????Label` matches `LinkLabel` but not `CustomLabel`).
|
|
111
|
+
|
|
112
|
+
`assert` asserts that the label has htmlFor, a nested label, both or either. Available options: `'htmlFor', 'nesting', 'both', 'either'`.
|
|
113
|
+
|
|
114
|
+
`depth` (default 2, max 25) is an integer that determines how deep within a `JSXElement` label the rule should look for text content or an element with a label to determine if the `label` element will have an accessible label.
|
|
115
|
+
|
|
116
|
+
### Fail
|
|
117
|
+
```jsx
|
|
118
|
+
function Foo(props) {
|
|
119
|
+
return <label {...props} />
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Succeed
|
|
124
|
+
```jsx
|
|
125
|
+
function Foo(props) {
|
|
126
|
+
const {
|
|
127
|
+
htmlFor,
|
|
128
|
+
...otherProps
|
|
129
|
+
} = props;
|
|
130
|
+
|
|
131
|
+
return <label htmlFor={htmlFor} {...otherProps} />
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Fail
|
|
136
|
+
```jsx
|
|
137
|
+
<input type="text" />
|
|
138
|
+
<label>Surname</label>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Succeed
|
|
142
|
+
```jsx
|
|
143
|
+
<label>
|
|
144
|
+
<input type="text" />
|
|
145
|
+
Surname
|
|
146
|
+
</label>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Accessibility guidelines
|
|
150
|
+
- [WCAG 1.3.1](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships)
|
|
151
|
+
- [WCAG 3.3.2](https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions)
|
|
152
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# jsx-a11y/label-has-for
|
|
2
|
+
|
|
3
|
+
❌ This rule is deprecated. It was replaced by [`jsx-a11y/label-has-associated-control`](label-has-associated-control.md).
|
|
4
|
+
|
|
5
|
+
🚫 This rule is _disabled_ in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
6
|
+
|
|
7
|
+
<!-- end auto-generated rule header -->
|
|
8
|
+
|
|
9
|
+
_This rule was deprecated in v6.1.0. It will no longer be maintained._
|
|
10
|
+
|
|
11
|
+
Enforce label tags have associated control.
|
|
12
|
+
|
|
13
|
+
There are two supported ways to associate a label with a control:
|
|
14
|
+
|
|
15
|
+
- nesting: by wrapping a control in a label tag
|
|
16
|
+
- id: by using the prop `htmlFor` (or any configured attribute) as in `htmlFor=[ID of control]`
|
|
17
|
+
|
|
18
|
+
To fully cover 100% of assistive devices, you're encouraged to validate for both nesting and id.
|
|
19
|
+
|
|
20
|
+
## Rule options
|
|
21
|
+
|
|
22
|
+
This rule takes one optional object argument of type object:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"rules": {
|
|
27
|
+
"jsx-a11y/label-has-for": [ 2, {
|
|
28
|
+
"components": [ "Label" ],
|
|
29
|
+
"required": {
|
|
30
|
+
"every": [ "nesting", "id" ]
|
|
31
|
+
},
|
|
32
|
+
"allowChildren": false
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For the `components` option, these strings determine which JSX elements (**always including** `<label>`) should be checked for having `htmlFor` prop. This is a good use case when you have a wrapper component that simply renders a `label` element (like in React):
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
// Label.js
|
|
42
|
+
const Label = props => {
|
|
43
|
+
const {
|
|
44
|
+
htmlFor,
|
|
45
|
+
...otherProps
|
|
46
|
+
} = props;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<label htmlFor={htmlFor} {...otherProps} />
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
// CreateAccount.js (for example)
|
|
56
|
+
...
|
|
57
|
+
return (
|
|
58
|
+
<form>
|
|
59
|
+
<input id="firstName" type="text" />
|
|
60
|
+
<Label htmlFor="firstName">First Name</Label>
|
|
61
|
+
</form>
|
|
62
|
+
);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The `required` option (defaults to `"required": { "every": ["nesting", "id"] }`) determines which checks are activated. You're allowed to pass in one of the following types:
|
|
66
|
+
|
|
67
|
+
- string: must be one of the acceptable strings (`"nesting"` or `"id"`)
|
|
68
|
+
- object, must have one of the following properties:
|
|
69
|
+
|
|
70
|
+
- some: an array of acceptable strings, will pass if ANY of the requested checks passed
|
|
71
|
+
- every: an array of acceptable strings, will pass if ALL of the requested checks passed
|
|
72
|
+
|
|
73
|
+
The `allowChildren` option (defaults to `false`) determines whether `{children}` content is allowed to be passed into a `label` element. For example, the following pattern, by default, is not allowed:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
<label>{children}</label>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
However, if `allowChildren` is set to `true`, no error will be raised. If you want to pass in `{children}` content without raising an error, because you cannot be sure what `{children}` will render, then set `allowChildren` to `true`.
|
|
80
|
+
|
|
81
|
+
Note that passing props as spread attribute without `htmlFor` explicitly defined will cause this rule to fail. Explicitly pass down `htmlFor` prop for rule to pass. The prop must have an actual value to pass. Use `Label` component above as a reference. **It is a good thing to explicitly pass props that you expect to be passed for self-documentation.** For example:
|
|
82
|
+
|
|
83
|
+
#### Bad
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
function Foo(props) {
|
|
87
|
+
return <label {...props} />
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Good
|
|
92
|
+
|
|
93
|
+
```jsx
|
|
94
|
+
function Foo({ htmlFor, ...props}) {
|
|
95
|
+
return <label htmlFor={htmlFor} {...props} />
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// OR
|
|
99
|
+
|
|
100
|
+
function Foo(props) {
|
|
101
|
+
const {
|
|
102
|
+
htmlFor,
|
|
103
|
+
...otherProps
|
|
104
|
+
} = props;
|
|
105
|
+
|
|
106
|
+
return <label htmlFor={htmlFor} {...otherProps} />
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Succeed
|
|
111
|
+
|
|
112
|
+
```jsx
|
|
113
|
+
<label htmlFor="firstName">
|
|
114
|
+
<input type="text" id="firstName" />
|
|
115
|
+
First Name
|
|
116
|
+
</label>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Fail
|
|
120
|
+
|
|
121
|
+
```jsx
|
|
122
|
+
<input type="text" id="firstName" />
|
|
123
|
+
<label>First Name</label>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Accessibility guidelines
|
|
127
|
+
|
|
128
|
+
- [WCAG 1.3.1](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships)
|
|
129
|
+
- [WCAG 3.3.2](https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions)
|
|
130
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# jsx-a11y/lang
|
|
2
|
+
|
|
3
|
+
<!-- end auto-generated rule header -->
|
|
4
|
+
|
|
5
|
+
The `lang` prop on the `<html>` element must be a valid IETF's BCP 47 language tag.
|
|
6
|
+
|
|
7
|
+
## Rule details
|
|
8
|
+
|
|
9
|
+
This rule takes no arguments.
|
|
10
|
+
|
|
11
|
+
### Succeed
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<html lang="en-US">
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Fail
|
|
19
|
+
|
|
20
|
+
```jsx
|
|
21
|
+
<html>
|
|
22
|
+
<html lang="foo">
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Accessibility guidelines
|
|
26
|
+
- [WCAG 3.1.1](https://www.w3.org/WAI/WCAG21/Understanding/language-of-page)
|
|
27
|
+
|
|
28
|
+
### Resources
|
|
29
|
+
- [axe-core, valid-lang](https://dequeuniversity.com/rules/axe/3.2/valid-lang)
|
|
30
|
+
- [Language tags in HTML and XML](https://www.w3.org/International/articles/language-tags/)
|
|
31
|
+
- [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# jsx-a11y/media-has-caption
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).
|
|
8
|
+
|
|
9
|
+
The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are *not* necessary for video components with the `muted` attribute.
|
|
10
|
+
|
|
11
|
+
## Rule options
|
|
12
|
+
|
|
13
|
+
This rule takes one optional object argument of type object:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"rules": {
|
|
18
|
+
"jsx-a11y/media-has-caption": [ 2, {
|
|
19
|
+
"audio": [ "Audio" ],
|
|
20
|
+
"video": [ "Video" ],
|
|
21
|
+
"track": [ "Track" ],
|
|
22
|
+
}],
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For the `audio`, `video`, and `track` options, these strings determine which JSX elements (**always including** their corresponding DOM element) should be used for this rule. This is a good use case when you have a wrapper component that simply renders an `audio`, `video`, or `track` element (like in React):
|
|
28
|
+
|
|
29
|
+
### Succeed
|
|
30
|
+
```jsx
|
|
31
|
+
<audio><track kind="captions" {...props} /></audio>
|
|
32
|
+
<video><track kind="captions" {...props} /></video>
|
|
33
|
+
<video muted {...props} ></video>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Fail
|
|
37
|
+
```jsx
|
|
38
|
+
<audio {...props} />
|
|
39
|
+
<video {...props} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Accessibility guidelines
|
|
43
|
+
- [WCAG 1.2.2](https://www.w3.org/WAI/WCAG21/Understanding/captions-prerecorded.html)
|
|
44
|
+
- [WCAG 1.2.3](https://www.w3.org/WAI/WCAG21/Understanding/audio-description-or-media-alternative-prerecorded.html)
|
|
45
|
+
|
|
46
|
+
### Resources
|
|
47
|
+
- [axe-core, audio-caption](https://dequeuniversity.com/rules/axe/2.1/audio-caption)
|
|
48
|
+
- [axe-core, video-caption](https://dequeuniversity.com/rules/axe/2.1/video-caption)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# jsx-a11y/mouse-events-have-key-events
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforce onmouseover/onmouseout are accompanied by onfocus/onblur. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screen reader users.
|
|
8
|
+
|
|
9
|
+
## Rule options
|
|
10
|
+
|
|
11
|
+
By default, this rule checks that `onmouseover` is paired with `onfocus` and that `onmouseout` is paired with `onblur`. This rule takes an optional argument to specify other handlers to check for "hover in" and/or "hover out" events:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"rules": {
|
|
16
|
+
"jsx-a11y/mouse-events-have-key-events": [
|
|
17
|
+
"error",
|
|
18
|
+
{
|
|
19
|
+
"hoverInHandlers": [
|
|
20
|
+
"onMouseOver",
|
|
21
|
+
"onMouseEnter",
|
|
22
|
+
"onPointerOver",
|
|
23
|
+
"onPointerEnter"
|
|
24
|
+
],
|
|
25
|
+
"hoverOutHandlers": [
|
|
26
|
+
"onMouseOut",
|
|
27
|
+
"onMouseLeave",
|
|
28
|
+
"onPointerOut",
|
|
29
|
+
"onPointerLeave"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Note that while `onmouseover` and `onmouseout` are checked by default if no arguments are passed in, those are *not* included by default if you *do* provide an argument, so remember to explicitly include them if you want to check them.
|
|
38
|
+
|
|
39
|
+
### Succeed
|
|
40
|
+
```jsx
|
|
41
|
+
<div onMouseOver={ () => void 0 } onFocus={ () => void 0 } />
|
|
42
|
+
<div onMouseOut={ () => void 0 } onBlur={ () => void 0 } />
|
|
43
|
+
<div onMouseOver={ () => void 0 } onFocus={ () => void 0 } {...otherProps} />
|
|
44
|
+
<div onMouseOut={ () => void 0 } onBlur={ () => void 0 } {...otherProps} />
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Fail
|
|
48
|
+
In example 3 and 4 below, even if otherProps contains onBlur and/or onFocus, this rule will still fail. Props should be passed down explicitly for rule to pass.
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
<div onMouseOver={ () => void 0 } />
|
|
52
|
+
<div onMouseOut={ () => void 0 } />
|
|
53
|
+
<div onMouseOver={ () => void 0 } {...otherProps} />
|
|
54
|
+
<div onMouseOut={ () => void 0 } {...otherProps} />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Accessibility guidelines
|
|
58
|
+
- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# jsx-a11y/no-access-key
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforce no accessKey prop on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen readers and keyboard-only users create accessibility complications so to avoid complications, access keys should not be used.
|
|
8
|
+
|
|
9
|
+
### References
|
|
10
|
+
1. [WebAIM](https://webaim.org/techniques/keyboard/accesskey#spec)
|
|
11
|
+
|
|
12
|
+
## Rule details
|
|
13
|
+
|
|
14
|
+
This rule takes no arguments.
|
|
15
|
+
|
|
16
|
+
### Succeed
|
|
17
|
+
```jsx
|
|
18
|
+
<div />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Fail
|
|
22
|
+
```jsx
|
|
23
|
+
<div accessKey="h" />
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Accessibility guidelines
|
|
27
|
+
General best practice (reference resources)
|
|
28
|
+
|
|
29
|
+
### Resources
|
|
30
|
+
- [WebAIM, Keyboard Accessibility: Accesskey](https://webaim.org/techniques/keyboard/accesskey#spec)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# jsx-a11y/no-aria-hidden-on-focusable
|
|
2
|
+
|
|
3
|
+
<!-- end auto-generated rule header -->
|
|
4
|
+
|
|
5
|
+
Enforce that `aria-hidden="true"` is not set on focusable elements.
|
|
6
|
+
|
|
7
|
+
`aria-hidden="true"` can be used to hide purely decorative content from screen reader users. An element with `aria-hidden="true"` that can also be reached by keyboard can lead to confusion or unexpected behavior for screen reader users. Avoid using `aria-hidden="true"` on focusable elements.
|
|
8
|
+
|
|
9
|
+
## Rule details
|
|
10
|
+
|
|
11
|
+
### Succeed
|
|
12
|
+
```jsx
|
|
13
|
+
<div aria-hidden="true" />
|
|
14
|
+
<img aria-hidden="true" />
|
|
15
|
+
<a aria-hidden="false" href="#" />
|
|
16
|
+
<button aria-hidden="true" tabIndex="-1" /> // `tabIndex=-1` removes the element from sequential focus navigation so we don't flag it.
|
|
17
|
+
<a href="/" />
|
|
18
|
+
<div aria-hidden="true"><a href="#"></a></div> // This is also bad but will not be handled by this rule.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Fail
|
|
22
|
+
```jsx
|
|
23
|
+
<div aria-hidden="true" tabIndex="0" />
|
|
24
|
+
<input aria-hidden="true" />
|
|
25
|
+
<a href="/" aria-hidden="true" />
|
|
26
|
+
<button aria-hidden="true" />
|
|
27
|
+
<textarea aria-hidden="true" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Accessibility guidelines
|
|
31
|
+
General best practice (reference resources)
|
|
32
|
+
|
|
33
|
+
### Resources
|
|
34
|
+
|
|
35
|
+
- [aria-hidden elements do not contain focusable elements](https://dequeuniversity.com/rules/axe/html/4.4/aria-hidden-focus)
|
|
36
|
+
- [Element with aria-hidden has no content in sequential focus navigation](https://www.w3.org/WAI/standards-guidelines/act/rules/6cfa84/proposed/)
|
|
37
|
+
- [MDN aria-hidden](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# jsx-a11y/no-autofocus
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforce that autoFocus prop is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users, alike.
|
|
8
|
+
|
|
9
|
+
## Rule options
|
|
10
|
+
|
|
11
|
+
This rule takes one optional object argument of type object:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"rules": {
|
|
16
|
+
"jsx-a11y/no-autofocus": [ 2, {
|
|
17
|
+
"ignoreNonDOM": true
|
|
18
|
+
}],
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For the `ignoreNonDOM` option, this determines if developer created components are checked.
|
|
24
|
+
|
|
25
|
+
### Succeed
|
|
26
|
+
```jsx
|
|
27
|
+
<div />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Fail
|
|
31
|
+
```jsx
|
|
32
|
+
<div autoFocus />
|
|
33
|
+
<div autoFocus="true" />
|
|
34
|
+
<div autoFocus="false" />
|
|
35
|
+
<div autoFocus={undefined} />
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Accessibility guidelines
|
|
39
|
+
General best practice (reference resources)
|
|
40
|
+
|
|
41
|
+
### Resources
|
|
42
|
+
- [WHATWG HTML Standard, The autofocus attribute](https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus)
|
|
43
|
+
- [The accessibility of HTML 5 autofocus](https://www.brucelawson.co.uk/2009/the-accessibility-of-html-5-autofocus/)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# jsx-a11y/no-distracting-elements
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided. By default, the following elements are visually distracting: `<marquee>` and `<blink>`.
|
|
8
|
+
|
|
9
|
+
## Rule options
|
|
10
|
+
|
|
11
|
+
This rule takes one optional object argument of type object:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"rules": {
|
|
16
|
+
"jsx-a11y/no-distracting-elements": [ 2, {
|
|
17
|
+
"elements": [ "marquee", "blink" ],
|
|
18
|
+
}],
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For the `elements` option, these strings determine which JSX elements should be checked for usage. This shouldn't need to be configured unless you have a seriously compelling use case for these elements. You cannot add any additional elements than what is offered, as the schema is only valid with the provided enumerated list. If you have another element that you think may cause a11y issues due to visual impairment, please feel free to file an issue or send a PR!
|
|
24
|
+
|
|
25
|
+
### Succeed
|
|
26
|
+
```jsx
|
|
27
|
+
<div />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Fail
|
|
31
|
+
```jsx
|
|
32
|
+
<marquee />
|
|
33
|
+
<blink />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Accessibility guidelines
|
|
37
|
+
- [WCAG 2.2.2](https://www.w3.org/WAI/WCAG21/Understanding/pause-stop-hide)
|
|
38
|
+
|
|
39
|
+
### Resources
|
|
40
|
+
- [axe-core, marquee](https://dequeuniversity.com/rules/axe/3.2/marquee)
|
|
41
|
+
- [axe-core, blink](https://dequeuniversity.com/rules/axe/3.2/blink)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# jsx-a11y/no-interactive-element-to-noninteractive-role
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
Interactive HTML elements indicate _controls_ in the user interface. Interactive elements include `<a href>`, `<button>`, `<input>`, `<select>`, `<textarea>`.
|
|
8
|
+
|
|
9
|
+
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>`.
|
|
10
|
+
|
|
11
|
+
[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`.
|
|
12
|
+
|
|
13
|
+
## How do I resolve this error?
|
|
14
|
+
|
|
15
|
+
### Case: The element should be a container, like an article
|
|
16
|
+
|
|
17
|
+
Wrap your interactive element in a `<div>` with the desired role.
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
<div role="article">
|
|
21
|
+
<button>Save</button>
|
|
22
|
+
</div>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Case: The element should be content, like an image
|
|
26
|
+
|
|
27
|
+
Put the content inside your interactive element.
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
<div
|
|
31
|
+
role="button"
|
|
32
|
+
onClick={() => {}}
|
|
33
|
+
onKeyPress={() => {}}
|
|
34
|
+
tabIndex="0">
|
|
35
|
+
<div role="img" aria-label="Save" />
|
|
36
|
+
</div>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Rule options
|
|
40
|
+
|
|
41
|
+
The recommended options for this rule allow the `tr` element to be given a role of `presentation` (or its semantic equivalent `none`). Under normal circumstances, an element with an interactive role should not be semantically neutralized with `presentation` (or `none`).
|
|
42
|
+
|
|
43
|
+
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.
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
{
|
|
47
|
+
'no-interactive-element-to-noninteractive-role': [
|
|
48
|
+
'error',
|
|
49
|
+
{
|
|
50
|
+
tr: ['none', 'presentation'],
|
|
51
|
+
},
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Under the recommended options, the following code is valid. It would be invalid under the strict rules.
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<tr role="presentation" />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Accessibility guidelines
|
|
63
|
+
|
|
64
|
+
- [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|
65
|
+
|
|
66
|
+
### Resources
|
|
67
|
+
|
|
68
|
+
- [ARIA Spec, States and Properties](https://www.w3.org/TR/wai-aria/#states_and_properties)
|
|
69
|
+
- [Chrome Audit Rules, AX_ARIA_04](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_04)
|
|
70
|
+
- [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro)
|
|
71
|
+
- [WAI-ARIA Authoring Practices Guide - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex)
|
|
72
|
+
- [Fundamental Keyboard Navigation Conventions](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav)
|
|
73
|
+
- [Mozilla Developer Network - ARIA Techniques](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Keyboard_and_focus)
|