Skip to content
This repository was archived by the owner on Mar 7, 2019. It is now read-only.

Commit 57b0ed0

Browse files
Petr Hanákrobertrossmann
authored andcommitted
setup jsx-a11y plugin
1 parent f88121f commit 57b0ed0

File tree

6 files changed

+283
-2
lines changed

6 files changed

+283
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ See the [tutorial](tutorial) directory for lots of example config files.
4444
4545
- @strv/javascript/environments/react/v15
4646
- @strv/javascript/environments/react/optional
47+
- @strv/javascript/environments/react/accessibility
4748

4849
> This one includes rules which deal with how the code looks like and not how it works. It helps keep the code clean and consistent.
4950

environments/react/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[a11y-repo]: https://github.com/evcohen/eslint-plugin-jsx-a11y
2+
13
# React
24

35
These configuration files are suitable to lint React components.
@@ -6,10 +8,14 @@ These configuration files are suitable to lint React components.
68

79
### @strv/javascript/environments/react/v15
810

9-
Suitable for React v15. This ruleset configures ESLint to recognise JSX syntax and enables some rules that make the linting process more natural.
11+
Suitable for React v15. This ruleset configures ESLint to recognise JSX syntax and enables some rules that make the linting process more natural. Some accesssibility rules are also included to keep users happy even if they are using screen readers, braile devices or just keyboard.
1012

1113
### @strv/javascript/environments/react/optional
1214

1315
Use this ruleset in conjunction with any of the above version-specific rulesets. Provides additional insights into potential inconsistencies in the project.
1416

1517
> For new projects, it is recommended to enable this ruleset. For existing projects, it is only recommended for the brave.
18+
19+
### @strv/javascript/environment/react/accessibility
20+
21+
Use this ruleset to enable the [`a11y`][a11y-repo] rules which provide checks for writing accessible JSX components.

environments/react/accessibility.js

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// JSX accessibility rules
2+
3+
'use strict'
4+
5+
module.exports = {
6+
plugins: [
7+
'jsx-a11y',
8+
],
9+
rules: {
10+
// Emojis have become a common way of communicating content to the end user. To a person using
11+
// a screenreader, however, he/she may not be aware that this content is there at all. By
12+
// wrapping the emoji in a <span>, giving it the role="img", and providing a useful description
13+
// in aria-label, the screenreader will treat the emoji as an image in the accessibility tree
14+
// with an accessible name for the end user.
15+
'jsx-a11y/accessible-emoji': 'warn',
16+
17+
// Enforce that all elements that require alternative text have meaningful information to relay
18+
// back to the end user. This is a critical component of accessibility for screenreader users
19+
// in order for them to understand the content's purpose on the page. By default, this rule
20+
// checks for alternative text on the following elements: <img>, <area>, <input type="image">,
21+
// and <object>.
22+
'jsx-a11y/alt-text': 'warn',
23+
24+
// Enforce that anchors have content and that the content is accessible to screen readers.
25+
// Accessible means that it is not hidden using the aria-hidden prop. Refer to the references
26+
// to learn about why this is important.
27+
'jsx-a11y/anchor-has-content': 'warn',
28+
29+
// The HTML <a> element, with a valid href attribute, is formally defined as representing a
30+
// hyperlink. That is, a link between one HTML document and another, or between one location
31+
// inside an HTML document and another location inside the same document. In fact, the
32+
// interactive, underlined <a> element has become so synonymous with web navigation that this
33+
// expectation has become entrenched inside browsers, assistive technologies such as screen
34+
// readers and in how people generally expect the internet to behave. In short, anchors should
35+
// navigate. The use of JavaScript frameworks and libraries, like React, has made it very easy
36+
// to add or subtract functionality from the standard HTML elements. This has led to anchors
37+
// often being used in applications based on how they look and function instead of what they
38+
// represent. Whilst it is possible, for example, to turn the <a> element into a fully
39+
// functional <button> element with ARIA, the native user agent implementations of HTML
40+
// elements are to be preferred over custom ARIA solutions.
41+
'jsx-a11y/anchor-is-valid': 'warn',
42+
43+
// aria-activedescendant is used to manage focus within a composite widget. The element with
44+
// the attribute aria-activedescendant retains the active document focus; it indicates which of
45+
// its child elements has secondary focus by assigning the ID of that element to the value of
46+
// aria-activedescendant. This pattern is used to build a widget like a search typeahead select
47+
// list. The search input box retains document focus so that the user can type in the input. If
48+
// the down arrow key is pressed and a search suggestion is highlighted, the ID of the
49+
// suggestion element will be applied as the value of aria-activedescendant on the input
50+
// element. Because an element with aria-activedescendant must be tabbable, it must either
51+
// have an inherent tabIndex of zero or declare a tabIndex of zero with the tabIndex attribute.
52+
'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
53+
54+
// Elements cannot use an invalid ARIA attribute. This will fail if it finds an aria-* property
55+
// that is not listed in WAI-ARIA States and Properties spec.
56+
// (https://www.w3.org/TR/wai-aria/states_and_properties#state_prop_def) ARIA state and
57+
// property values must be valid.
58+
'jsx-a11y/aria-props': 'warn',
59+
'jsx-a11y/aria-proptypes': 'warn',
60+
61+
// Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role
62+
// defintions can be found at WAI-ARIA site.
63+
// (https://www.w3.org/TR/wai-aria/roles#role_definitions)
64+
'jsx-a11y/aria-role': 'warn',
65+
66+
// Certain reserved DOM elements do not support ARIA roles, states and properties. This is
67+
// often because they are not visible, for example meta, html, script, style. This rule
68+
// enforces that these DOM elements do not contain the role and/or aria-* props.
69+
'jsx-a11y/aria-unsupported-elements': 'warn',
70+
71+
// Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown,
72+
// onKeyPress. Coding for the keyboard is important for users with physical disabilities who
73+
// cannot use a mouse, AT compatibility, and screenreader users.
74+
'jsx-a11y/click-events-have-key-events': 'warn',
75+
76+
// Enforce that heading elements (h1, h2, etc.) have content and that the content is accessible
77+
// to screen readers. Accessible means that it is not hidden using the aria-hidden prop. Refer
78+
// to the references to learn about why this is important.
79+
'jsx-a11y/heading-has-content': 'warn',
80+
81+
// elements must have the lang prop.
82+
'jsx-a11y/html-has-lang': 'warn',
83+
84+
// <iframe> elements must have a unique title property to indicate its content to the user.
85+
'jsx-a11y/iframe-has-title': 'warn',
86+
87+
// Enforce img alt attribute does not contain the word image, picture, or photo. Screenreaders
88+
// already announce img elements as an image. There is no need to use words such as image,
89+
// photo, and/or picture.
90+
'jsx-a11y/img-redundant-alt': 'warn',
91+
92+
// Elements with an interactive role and interaction handlers (mouse or key press) must be
93+
// focusable.
94+
'jsx-a11y/interactive-supports-focus': ['warn', {
95+
tabbable: ['button', 'checkbox', 'link', 'searchbox', 'spinbutton', 'switch', 'textbox'],
96+
}],
97+
98+
// Enforce label tags have associated control.
99+
'jsx-a11y/label-has-for': 'warn',
100+
101+
// Providing captions for media is essential for deaf users to follow along. Captions should be
102+
// a transcription or translation of the dialogue, sound effects, relevant musical cues, and
103+
// other relevant audio information. Not only is this important for accessibility, but can also
104+
// be useful for all users in the case that the media is unavailable (similar to alt text on an
105+
// image when an image is unable to load). The captions should contain all important and
106+
// relevant information to understand the corresponding media. This may mean that the captions
107+
// are not a 1:1 mapping of the dialogue in the media content.
108+
'jsx-a11y/media-has-caption': 'warn',
109+
110+
// Enforce onmouseover/onmouseout are accompanied by onfocus/onblur. Coding for the keyboard is
111+
// important for users with physical disabilities who cannot use a mouse, AT compatibility, and
112+
// screenreader users.
113+
'jsx-a11y/mouse-events-have-key-events': 'warn',
114+
115+
// Enforce no accessKey prop on element. Access keys are HTML attributes that allow web
116+
// developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard
117+
// shortcuts and keyboard commands used by screenreader and keyboard only users create
118+
// accessibility complications so to avoid complications, access keys should not be used.
119+
'jsx-a11y/no-access-key': 'warn',
120+
121+
// Enforce that autoFocus prop is not used on elements. Autofocusing elements can cause
122+
// usability issues for sighted and non-sighted users, alike.
123+
'jsx-a11y/no-autofocus': 'warn',
124+
125+
// Enforces that no distracting elements are used. Elements that can be visually distracting
126+
// can cause accessibility issues with visually impaired users. Such elements are most likely
127+
// deprecated, and should be avoided. By default, the following elements are visually
128+
// distracting: <marquee> and <blink>.
129+
'jsx-a11y/no-distracting-elements': 'warn',
130+
131+
// Interactive HTML elements indicate controls in the user interface. Interactive elements
132+
// include <a href>, <button>, <input>, <select>, <textarea>. Non-interactive HTML elements
133+
// and non-interactive ARIA roles indicate content and containers in the user interface.
134+
// Non-interactive elements include <main>, <area>, <h1> (,<h2>, etc), <img>, <li>, <ul> and
135+
// <ol>. WAI-ARIA roles should not be used to convert an interactive element to a
136+
// non-interactive element. Non-interactive ARIA roles include article, banner, complementary,
137+
// img, listitem, main, region and tooltip.
138+
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['warn', {
139+
tr: ['none', 'presentation'],
140+
}],
141+
142+
// Non-interactive HTML elements and non-interactive ARIA roles indicate content and containers
143+
// in the user interface. A non-interactive element does not support event handlers (mouse and
144+
// key handlers). Non-interactive elements include <main>, <area>, <h1> (,<h2>, etc), <img>,
145+
// <li>, <ul> and <ol>. Non-interactive WAI-ARIA roles include article, banner, complementary,
146+
// img, listitem, main, region and tooltip.
147+
'jsx-a11y/no-noninteractive-element-interactions': ['warn', {
148+
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
149+
}],
150+
151+
// Non-interactive HTML elements indicate content and containers in the user interface.
152+
// Non-interactive elements include <main>, <area>, <h1> (,<h2>, etc), <img>, <li>, <ul> and
153+
// <ol>. Interactive HTML elements indicate controls in the user interface. Interactive
154+
// elements include <a href>, <button>, <input>, <select>, <textarea>. WAI-ARIA roles should
155+
// not be used to convert a non-interactive element to an interactive element. Interactive ARIA
156+
// roles include button, link, checkbox, menuitem, menuitemcheckbox, menuitemradio, option,
157+
// radio, searchbox, switch and textbox.
158+
'jsx-a11y/no-noninteractive-element-to-interactive-role': ['warn', {
159+
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
160+
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
161+
li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
162+
table: ['grid'],
163+
td: ['gridcell'],
164+
}],
165+
166+
// Tab key navigation should be limited to elements on the page that can be interacted with.
167+
// Thus it is not necessary to add a tabindex to items in an unordered list, for example, to
168+
// make them navigable through assistive technology. These applications already afford page
169+
// traversal mechanisms based on the HTML of the page. Generally, we should try to reduce the
170+
// size of the page's tab ring rather than increasing it.
171+
'jsx-a11y/no-noninteractive-tabindex': ['warn', {
172+
tags: [],
173+
roles: ['tabpanel'],
174+
}],
175+
176+
// Enforce usage of onBlur over/in parallel with onChange on select menu elements for
177+
// accessibility. onBlur should be used instead of onChange, unless absolutely necessary and it
178+
// causes no negative consequences for keyboard only or screen reader users. onBlur is a more
179+
// declarative action by the user: for instance in a dropdown, using the arrow keys to toggle
180+
// between options will trigger the onChange event in some browsers. Regardless, when a change
181+
// of context results from an onBlur event or an onChange event, the user should be notified of
182+
// the change unless it occurs below the currently focused element.
183+
'jsx-a11y/no-onchange': 'error',
184+
185+
// Some HTML elements have native semantics that are implemented by the browser. This includes
186+
// default/implicit ARIA roles. Setting an ARIA role that matches its default/implicit role is
187+
// redundant since it is already set by the browser.
188+
'jsx-a11y/no-redundant-roles': 'warn',
189+
190+
// Static HTML elements do not have semantic meaning. This is clear in the case of <div> and
191+
// <span>. It is less so clear in the case of elements that seem semantic, but that do not have
192+
// a semantic mapping in the accessibility layer. For example <a>, <big>, <blockquote>,
193+
// <footer>, <picture>, <strike> and <time> -- to name a few -- have no semantic layer mapping.
194+
// They are as void of meaning as <div>. The WAI-ARIA role attribute confers a semantic
195+
// mapping to an element. The semantic value can then be expressed to a user via assistive
196+
// technology. In order to add interactivity such as a mouse or key event listener to a static
197+
// element, that element must be given a role value as well.
198+
'jsx-a11y/no-static-element-interactions': ['warn', {
199+
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
200+
}],
201+
202+
// Elements with ARIA roles must have all required attributes for that role.
203+
'jsx-a11y/role-has-required-aria-props': 'warn',
204+
205+
// Enforce that elements with explicit or implicit roles defined contain only aria-* properties
206+
// supported by that role. Many ARIA attributes (states and properties) can only be used on
207+
// elements with particular roles. Some elements have implicit roles, such as <a href="#" />,
208+
// which will resolve to role="link".
209+
'jsx-a11y/role-supports-aria-props': 'warn',
210+
211+
// The scope scope should be used only on <th> elements.
212+
'jsx-a11y/scope': 'warn',
213+
214+
// Avoid positive tabIndex property values to synchronize the flow of the page with keyboard
215+
// tab order.
216+
'jsx-a11y/tabindex-no-positive': 'warn',
217+
},
218+
}

environments/react/v15.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
module.exports = {
1212

13-
extends: './recommended.js',
13+
extends: [
14+
'./recommended.js',
15+
'./accessibility.js',
16+
],
1417

1518
env: {
1619
es6: true,

package-lock.json

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"contributors": [],
1010
"dependencies": {
1111
"eslint-plugin-import": "^2.7.0",
12+
"eslint-plugin-jsx-a11y": "^6.0.2",
1213
"eslint-plugin-react": "^7.3.0"
1314
},
1415
"devDependencies": {

0 commit comments

Comments
 (0)