@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.
Files changed (229) hide show
  1. package/.babelrc +17 -0
  2. package/.eslintrc +44 -0
  3. package/CHANGELOG.md +774 -0
  4. package/LICENSE.md +8 -0
  5. package/README.md +423 -0
  6. package/__mocks__/IdentifierMock.js +15 -0
  7. package/__mocks__/JSXAttributeMock.js +39 -0
  8. package/__mocks__/JSXElementMock.js +37 -0
  9. package/__mocks__/JSXExpressionContainerMock.js +15 -0
  10. package/__mocks__/JSXSpreadAttributeMock.js +18 -0
  11. package/__mocks__/JSXTextMock.js +17 -0
  12. package/__mocks__/LiteralMock.js +17 -0
  13. package/__mocks__/genInteractives.js +218 -0
  14. package/__tests__/__util__/axeMapping.js +6 -0
  15. package/__tests__/__util__/helpers/getESLintCoreRule.js +9 -0
  16. package/__tests__/__util__/helpers/parsers.js +186 -0
  17. package/__tests__/__util__/parserOptionsMapper.js +53 -0
  18. package/__tests__/__util__/ruleOptionsMapperFactory.js +33 -0
  19. package/__tests__/index-test.js +40 -0
  20. package/__tests__/src/rules/accessible-emoji-test.js +66 -0
  21. package/__tests__/src/rules/alt-text-test.js +291 -0
  22. package/__tests__/src/rules/anchor-ambiguous-text-test.js +117 -0
  23. package/__tests__/src/rules/anchor-has-content-test.js +54 -0
  24. package/__tests__/src/rules/anchor-is-valid-test.js +532 -0
  25. package/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js +95 -0
  26. package/__tests__/src/rules/aria-props-test.js +69 -0
  27. package/__tests__/src/rules/aria-proptypes-test.js +311 -0
  28. package/__tests__/src/rules/aria-role-test.js +118 -0
  29. package/__tests__/src/rules/aria-unsupported-elements-test.js +75 -0
  30. package/__tests__/src/rules/autocomplete-valid-test.js +77 -0
  31. package/__tests__/src/rules/click-events-have-key-events-test.js +77 -0
  32. package/__tests__/src/rules/control-has-associated-label-test.js +327 -0
  33. package/__tests__/src/rules/heading-has-content-test.js +85 -0
  34. package/__tests__/src/rules/html-has-lang-test.js +42 -0
  35. package/__tests__/src/rules/iframe-has-title-test.js +55 -0
  36. package/__tests__/src/rules/img-redundant-alt-test.js +137 -0
  37. package/__tests__/src/rules/interactive-supports-focus-test.js +267 -0
  38. package/__tests__/src/rules/label-has-associated-control-test.js +243 -0
  39. package/__tests__/src/rules/label-has-for-test.js +235 -0
  40. package/__tests__/src/rules/lang-test.js +59 -0
  41. package/__tests__/src/rules/media-has-caption-test.js +220 -0
  42. package/__tests__/src/rules/mouse-events-have-key-events-test.js +154 -0
  43. package/__tests__/src/rules/no-access-key-test.js +48 -0
  44. package/__tests__/src/rules/no-aria-hidden-on-focusable-test.js +44 -0
  45. package/__tests__/src/rules/no-autofocus-test.js +68 -0
  46. package/__tests__/src/rules/no-distracting-elements-test.js +51 -0
  47. package/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js +405 -0
  48. package/__tests__/src/rules/no-noninteractive-element-interactions-test.js +502 -0
  49. package/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js +500 -0
  50. package/__tests__/src/rules/no-noninteractive-tabindex-test.js +123 -0
  51. package/__tests__/src/rules/no-onchange-test.js +57 -0
  52. package/__tests__/src/rules/no-redundant-roles-test.js +98 -0
  53. package/__tests__/src/rules/no-static-element-interactions-test.js +501 -0
  54. package/__tests__/src/rules/prefer-tag-over-role-test.js +63 -0
  55. package/__tests__/src/rules/role-has-required-aria-props-test.js +134 -0
  56. package/__tests__/src/rules/role-supports-aria-props-test.js +570 -0
  57. package/__tests__/src/rules/scope-test.js +50 -0
  58. package/__tests__/src/rules/tabindex-no-positive-test.js +55 -0
  59. package/__tests__/src/util/attributesComparator-test.js +91 -0
  60. package/__tests__/src/util/getAccessibleChildText-test.js +174 -0
  61. package/__tests__/src/util/getComputedRole-test.js +71 -0
  62. package/__tests__/src/util/getElementType-test.js +154 -0
  63. package/__tests__/src/util/getExplicitRole-test.js +35 -0
  64. package/__tests__/src/util/getImplicitRole-test.js +25 -0
  65. package/__tests__/src/util/getSuggestion-test.js +33 -0
  66. package/__tests__/src/util/getTabIndex-test.js +85 -0
  67. package/__tests__/src/util/hasAccessibleChild-test.js +157 -0
  68. package/__tests__/src/util/implicitRoles/input-test.js +87 -0
  69. package/__tests__/src/util/implicitRoles/menu-test.js +20 -0
  70. package/__tests__/src/util/implicitRoles/menuitem-test.js +38 -0
  71. package/__tests__/src/util/isAbstractRole-test.js +51 -0
  72. package/__tests__/src/util/isContentEditable-test.js +52 -0
  73. package/__tests__/src/util/isDOMElement-test.js +30 -0
  74. package/__tests__/src/util/isDisabledElement-test.js +88 -0
  75. package/__tests__/src/util/isFocusable-test.js +111 -0
  76. package/__tests__/src/util/isInteractiveElement-test.js +104 -0
  77. package/__tests__/src/util/isInteractiveRole-test.js +59 -0
  78. package/__tests__/src/util/isNonInteractiveElement-test.js +97 -0
  79. package/__tests__/src/util/isNonInteractiveRole-test.js +59 -0
  80. package/__tests__/src/util/isNonLiteralProperty-test.js +52 -0
  81. package/__tests__/src/util/isSemanticRoleElement-test.js +72 -0
  82. package/__tests__/src/util/mayContainChildComponent-test.js +219 -0
  83. package/__tests__/src/util/mayHaveAccessibleLabel-test.js +256 -0
  84. package/__tests__/src/util/parserOptionsMapper-test.js +93 -0
  85. package/__tests__/src/util/schemas-test.js +35 -0
  86. package/docs/rules/accessible-emoji.md +30 -0
  87. package/docs/rules/alt-text.md +168 -0
  88. package/docs/rules/anchor-ambiguous-text.md +91 -0
  89. package/docs/rules/anchor-has-content.md +64 -0
  90. package/docs/rules/anchor-is-valid.md +270 -0
  91. package/docs/rules/aria-activedescendant-has-tabindex.md +52 -0
  92. package/docs/rules/aria-props.md +29 -0
  93. package/docs/rules/aria-proptypes.md +30 -0
  94. package/docs/rules/aria-role.md +51 -0
  95. package/docs/rules/aria-unsupported-elements.md +30 -0
  96. package/docs/rules/autocomplete-valid.md +49 -0
  97. package/docs/rules/click-events-have-key-events.md +28 -0
  98. package/docs/rules/control-has-associated-label.md +113 -0
  99. package/docs/rules/heading-has-content.md +67 -0
  100. package/docs/rules/html-has-lang.md +31 -0
  101. package/docs/rules/iframe-has-title.md +37 -0
  102. package/docs/rules/img-redundant-alt.md +48 -0
  103. package/docs/rules/interactive-supports-focus.md +156 -0
  104. package/docs/rules/label-has-associated-control.md +152 -0
  105. package/docs/rules/label-has-for.md +130 -0
  106. package/docs/rules/lang.md +31 -0
  107. package/docs/rules/media-has-caption.md +48 -0
  108. package/docs/rules/mouse-events-have-key-events.md +58 -0
  109. package/docs/rules/no-access-key.md +30 -0
  110. package/docs/rules/no-aria-hidden-on-focusable.md +37 -0
  111. package/docs/rules/no-autofocus.md +43 -0
  112. package/docs/rules/no-distracting-elements.md +41 -0
  113. package/docs/rules/no-interactive-element-to-noninteractive-role.md +73 -0
  114. package/docs/rules/no-noninteractive-element-interactions.md +145 -0
  115. package/docs/rules/no-noninteractive-element-to-interactive-role.md +76 -0
  116. package/docs/rules/no-noninteractive-tabindex.md +115 -0
  117. package/docs/rules/no-onchange.md +36 -0
  118. package/docs/rules/no-redundant-roles.md +46 -0
  119. package/docs/rules/no-static-element-interactions.md +114 -0
  120. package/docs/rules/prefer-tag-over-role.md +32 -0
  121. package/docs/rules/role-has-required-aria-props.md +31 -0
  122. package/docs/rules/role-supports-aria-props.md +39 -0
  123. package/docs/rules/scope.md +30 -0
  124. package/docs/rules/tabindex-no-positive.md +32 -0
  125. package/lib/configs/flat-config-base.js +11 -0
  126. package/lib/configs/legacy-config-base.js +9 -0
  127. package/lib/index.js +209 -0
  128. package/lib/rules/accessible-emoji.js +63 -0
  129. package/lib/rules/alt-text.js +218 -0
  130. package/lib/rules/anchor-ambiguous-text.js +64 -0
  131. package/lib/rules/anchor-has-content.js +60 -0
  132. package/lib/rules/anchor-is-valid.js +122 -0
  133. package/lib/rules/aria-activedescendant-has-tabindex.js +66 -0
  134. package/lib/rules/aria-props.js +59 -0
  135. package/lib/rules/aria-proptypes.js +114 -0
  136. package/lib/rules/aria-role.js +89 -0
  137. package/lib/rules/aria-unsupported-elements.js +64 -0
  138. package/lib/rules/autocomplete-valid.js +67 -0
  139. package/lib/rules/click-events-have-key-events.js +68 -0
  140. package/lib/rules/control-has-associated-label.js +103 -0
  141. package/lib/rules/heading-has-content.js +61 -0
  142. package/lib/rules/html-has-lang.js +50 -0
  143. package/lib/rules/iframe-has-title.js +50 -0
  144. package/lib/rules/img-redundant-alt.js +88 -0
  145. package/lib/rules/interactive-supports-focus.js +87 -0
  146. package/lib/rules/label-has-associated-control.js +127 -0
  147. package/lib/rules/label-has-for.js +150 -0
  148. package/lib/rules/lang.js +68 -0
  149. package/lib/rules/media-has-caption.js +96 -0
  150. package/lib/rules/mouse-events-have-key-events.js +94 -0
  151. package/lib/rules/no-access-key.js +43 -0
  152. package/lib/rules/no-aria-hidden-on-focusable.js +47 -0
  153. package/lib/rules/no-autofocus.js +62 -0
  154. package/lib/rules/no-distracting-elements.js +54 -0
  155. package/lib/rules/no-interactive-element-to-noninteractive-role.js +81 -0
  156. package/lib/rules/no-noninteractive-element-interactions.js +95 -0
  157. package/lib/rules/no-noninteractive-element-to-interactive-role.js +80 -0
  158. package/lib/rules/no-noninteractive-tabindex.js +109 -0
  159. package/lib/rules/no-onchange.js +52 -0
  160. package/lib/rules/no-redundant-roles.js +86 -0
  161. package/lib/rules/no-static-element-interactions.js +102 -0
  162. package/lib/rules/prefer-tag-over-role.js +75 -0
  163. package/lib/rules/role-has-required-aria-props.js +88 -0
  164. package/lib/rules/role-supports-aria-props.js +78 -0
  165. package/lib/rules/scope.js +58 -0
  166. package/lib/rules/tabindex-no-positive.js +53 -0
  167. package/lib/util/attributesComparator.js +34 -0
  168. package/lib/util/getAccessibleChildText.js +55 -0
  169. package/lib/util/getComputedRole.js +19 -0
  170. package/lib/util/getElementType.js +30 -0
  171. package/lib/util/getExplicitRole.js +27 -0
  172. package/lib/util/getImplicitRole.js +24 -0
  173. package/lib/util/getSuggestion.js +32 -0
  174. package/lib/util/getTabIndex.js +34 -0
  175. package/lib/util/hasAccessibleChild.js +30 -0
  176. package/lib/util/implicitRoles/a.js +17 -0
  177. package/lib/util/implicitRoles/area.js +17 -0
  178. package/lib/util/implicitRoles/article.js +13 -0
  179. package/lib/util/implicitRoles/aside.js +13 -0
  180. package/lib/util/implicitRoles/body.js +13 -0
  181. package/lib/util/implicitRoles/button.js +13 -0
  182. package/lib/util/implicitRoles/datalist.js +13 -0
  183. package/lib/util/implicitRoles/details.js +13 -0
  184. package/lib/util/implicitRoles/dialog.js +13 -0
  185. package/lib/util/implicitRoles/form.js +13 -0
  186. package/lib/util/implicitRoles/h1.js +13 -0
  187. package/lib/util/implicitRoles/h2.js +13 -0
  188. package/lib/util/implicitRoles/h3.js +13 -0
  189. package/lib/util/implicitRoles/h4.js +13 -0
  190. package/lib/util/implicitRoles/h5.js +13 -0
  191. package/lib/util/implicitRoles/h6.js +13 -0
  192. package/lib/util/implicitRoles/hr.js +13 -0
  193. package/lib/util/implicitRoles/img.js +31 -0
  194. package/lib/util/implicitRoles/index.js +82 -0
  195. package/lib/util/implicitRoles/input.js +38 -0
  196. package/lib/util/implicitRoles/li.js +13 -0
  197. package/lib/util/implicitRoles/link.js +17 -0
  198. package/lib/util/implicitRoles/menu.js +19 -0
  199. package/lib/util/implicitRoles/menuitem.js +28 -0
  200. package/lib/util/implicitRoles/meter.js +13 -0
  201. package/lib/util/implicitRoles/nav.js +13 -0
  202. package/lib/util/implicitRoles/ol.js +13 -0
  203. package/lib/util/implicitRoles/option.js +13 -0
  204. package/lib/util/implicitRoles/output.js +13 -0
  205. package/lib/util/implicitRoles/progress.js +13 -0
  206. package/lib/util/implicitRoles/section.js +13 -0
  207. package/lib/util/implicitRoles/select.js +13 -0
  208. package/lib/util/implicitRoles/tbody.js +13 -0
  209. package/lib/util/implicitRoles/textarea.js +13 -0
  210. package/lib/util/implicitRoles/tfoot.js +13 -0
  211. package/lib/util/implicitRoles/thead.js +13 -0
  212. package/lib/util/implicitRoles/ul.js +13 -0
  213. package/lib/util/isAbstractRole.js +23 -0
  214. package/lib/util/isContentEditable.js +13 -0
  215. package/lib/util/isDOMElement.js +15 -0
  216. package/lib/util/isDisabledElement.js +23 -0
  217. package/lib/util/isFocusable.js +23 -0
  218. package/lib/util/isHiddenFromScreenReader.js +26 -0
  219. package/lib/util/isInteractiveElement.js +116 -0
  220. package/lib/util/isInteractiveRole.js +54 -0
  221. package/lib/util/isNonInteractiveElement.js +131 -0
  222. package/lib/util/isNonInteractiveRole.js +55 -0
  223. package/lib/util/isNonLiteralProperty.js +29 -0
  224. package/lib/util/isPresentationRole.js +13 -0
  225. package/lib/util/isSemanticRoleElement.js +54 -0
  226. package/lib/util/mayContainChildComponent.js +50 -0
  227. package/lib/util/mayHaveAccessibleLabel.js +95 -0
  228. package/lib/util/schemas.js +52 -0
  229. 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)