From acbddc1083d5ea7608fba212bb6898ca6e224afc Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 6 Apr 2016 14:14:03 -0700 Subject: [PATCH 1/5] Add note and rule about image alt text We want our React apps to be accessible. One thing that developers can do is properly use alt text on images. Thankfully, there is an ESLint rule that will enforce these things for us. --- packages/eslint-config-airbnb/package.json | 2 ++ packages/eslint-config-airbnb/rules/react.js | 5 +++++ .../test/test-react-order.js | 4 ++-- react/README.md | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/eslint-config-airbnb/package.json b/packages/eslint-config-airbnb/package.json index aefe9a76..769c8950 100644 --- a/packages/eslint-config-airbnb/package.json +++ b/packages/eslint-config-airbnb/package.json @@ -44,6 +44,7 @@ "devDependencies": { "babel-tape-runner": "^1.3.1", "eslint": "^2.6.0", + "eslint-plugin-jsx-a11y": "^0.6.0", "eslint-plugin-react": "^4.2.3", "react": "^0.14.8", "tape": "^4.5.1", @@ -51,6 +52,7 @@ }, "peerDependencies": { "eslint": "^2.6.0", + "eslint-plugin-jsx-a11y": "^0.6.0", "eslint-plugin-react": "^4.2.3" } } diff --git a/packages/eslint-config-airbnb/rules/react.js b/packages/eslint-config-airbnb/rules/react.js index 470738b7..0b128aef 100644 --- a/packages/eslint-config-airbnb/rules/react.js +++ b/packages/eslint-config-airbnb/rules/react.js @@ -1,5 +1,6 @@ module.exports = { 'plugins': [ + 'jsx-a11y', 'react' ], 'ecmaFeatures': { @@ -8,6 +9,10 @@ module.exports = { // View link below for react rules documentation // https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules 'rules': { + // Require to have a non-empty `alt` prop, or role="presentation" + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-uses-alt.md + 'jsx-a11y/img-uses-alt': 2, + // Prevent missing displayName in a React component definition // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md 'react/display-name': [0, { 'ignoreTranspilerName': false }], diff --git a/packages/eslint-config-airbnb/test/test-react-order.js b/packages/eslint-config-airbnb/test/test-react-order.js index f5b2d452..81d8235f 100644 --- a/packages/eslint-config-airbnb/test/test-react-order.js +++ b/packages/eslint-config-airbnb/test/test-react-order.js @@ -28,9 +28,9 @@ ${body} } test('validate react prop order', t => { - t.test('make sure our eslintrc has React linting dependencies', t => { + t.test('make sure our eslintrc has React and JSX linting dependencies', t => { t.plan(1); - t.equal(reactRules.plugins[0], 'react', 'uses eslint-plugin-react'); + t.deepEqual(reactRules.plugins, ['jsx-a11y', 'react']); }); t.test('passes a good component', t => { diff --git a/react/README.md b/react/README.md index 6eddabca..29af5cf8 100644 --- a/react/README.md +++ b/react/README.md @@ -217,6 +217,22 @@ /> ``` + - Always include a non-empty `alt` prop on `` tags. If `alt` is an empty string, the `` must have `role="presentation"`. eslint: [`jsx-a11y/img-uses-alt`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-uses-alt.md) + + ```javascript + // bad + + + // bad + + + // good + Me waving hello + + // good + + ``` + ## Parentheses - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md) From f2aca29ed95dbec65590660e5e0032a00808cf4a Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 6 Apr 2016 14:21:48 -0700 Subject: [PATCH 2/5] Add note and rule about redundant alt text Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text. This will give people using assistive technologies a smoother experience. --- packages/eslint-config-airbnb/rules/react.js | 4 ++++ react/README.md | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/packages/eslint-config-airbnb/rules/react.js b/packages/eslint-config-airbnb/rules/react.js index 0b128aef..f505c75b 100644 --- a/packages/eslint-config-airbnb/rules/react.js +++ b/packages/eslint-config-airbnb/rules/react.js @@ -13,6 +13,10 @@ module.exports = { // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-uses-alt.md 'jsx-a11y/img-uses-alt': 2, + // Prevent img alt text from containing redundant words like "image", "picture", or "photo" + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/redundant-alt.md + 'jsx-a11y/redundant-alt': 2, + // Prevent missing displayName in a React component definition // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md 'react/display-name': [0, { 'ignoreTranspilerName': false }], diff --git a/react/README.md b/react/README.md index 29af5cf8..bc149b09 100644 --- a/react/README.md +++ b/react/README.md @@ -233,6 +233,18 @@ ``` + - Do not use words like "image", "photo", or "picture" in `` `alt` props. eslint: [`jsx-a11y/redundant-alt`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-uses-alt.md) + + > Why? Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text. + + ```javascript + // bad + Picture of me waving hello + + // good + Me waving hello + ``` + ## Parentheses - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md) From 0c3b13fe93e880450305e6c87a1a59f14e042bc5 Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 6 Apr 2016 14:27:21 -0700 Subject: [PATCH 3/5] Add note and rule about valid, non-abstract ARIA roles This rule will help people use only valid roles, which might save people from simple, accessibility-busting mistakes. --- packages/eslint-config-airbnb/rules/react.js | 4 ++++ react/README.md | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/eslint-config-airbnb/rules/react.js b/packages/eslint-config-airbnb/rules/react.js index f505c75b..02794495 100644 --- a/packages/eslint-config-airbnb/rules/react.js +++ b/packages/eslint-config-airbnb/rules/react.js @@ -17,6 +17,10 @@ module.exports = { // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/redundant-alt.md 'jsx-a11y/redundant-alt': 2, + // Require ARIA roles to be valid and non-abstract + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/valid-aria-role.md + 'jsx-a11y/valid-aria-role': 2, + // Prevent missing displayName in a React component definition // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md 'react/display-name': [0, { 'ignoreTranspilerName': false }], diff --git a/react/README.md b/react/README.md index bc149b09..0ac01a5b 100644 --- a/react/README.md +++ b/react/README.md @@ -245,6 +245,19 @@ Me waving hello ``` + - Use only valid, non-abstract [ARIA roles](https://www.w3.org/TR/wai-aria/roles#role_definitions). eslint: [`jsx-a11y/valid-aria-role`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/valid-aria-role.md) + + ```javascript + // bad - not an ARIA role +
+ + // bad - abstract ARIA role +
+ + // good +
+ ``` + ## Parentheses - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md) From f697a15e5036932805cb7a5160b6c0ceb2401afe Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 6 Apr 2016 14:32:55 -0700 Subject: [PATCH 4/5] Add note and rule about not using accessKey Inconsistencies between keyboard shortcuts and keyboard commands used by people using screenreaders and keyboards complicate accessibility. --- packages/eslint-config-airbnb/rules/react.js | 4 ++++ react/README.md | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/eslint-config-airbnb/rules/react.js b/packages/eslint-config-airbnb/rules/react.js index 02794495..3c05265b 100644 --- a/packages/eslint-config-airbnb/rules/react.js +++ b/packages/eslint-config-airbnb/rules/react.js @@ -9,6 +9,10 @@ module.exports = { // View link below for react rules documentation // https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules 'rules': { + // Prevent use of `accessKey` + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md + 'jsx-a11y/no-access-key': 2, + // Require to have a non-empty `alt` prop, or role="presentation" // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-uses-alt.md 'jsx-a11y/img-uses-alt': 2, diff --git a/react/README.md b/react/README.md index 0ac01a5b..4fc7c7c7 100644 --- a/react/README.md +++ b/react/README.md @@ -249,15 +249,27 @@ ```javascript // bad - not an ARIA role -
+
// bad - abstract ARIA role -
+
// good -
+
``` + - Do not use `accessKey` on elements. eslint: [`jsx-a11y/no-access-key`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md) + + > Why? Inconsistencies between keyboard shortcuts and keyboard commands used by people using screenreaders and keyboards complicate accessibility. + + ```javascript + // bad +
+ + // good +
+ ``` + ## Parentheses - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md) From 3f73e35b1874128161a97acbc6a299a801ec077b Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 6 Apr 2016 14:34:21 -0700 Subject: [PATCH 5/5] Use jsx fenced codeblocks for JSX code GitHub knows how to do JSX syntax highlighting. Since we are using JSX in this document, I figured we might as well tell GitHub to highlight the syntax as JSX here. This will lead to a better reading experience. --- react/README.md | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/react/README.md b/react/README.md index 4fc7c7c7..6db60dd1 100644 --- a/react/README.md +++ b/react/README.md @@ -29,7 +29,7 @@ - If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass` unless you have a very good reason to use mixins. eslint: [`react/prefer-es6-class`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md) - ```javascript + ```jsx // bad const Listing = React.createClass({ // ... @@ -49,8 +49,7 @@ And if you don't have state or refs, prefer normal functions (not arrow functions) over classes: - ```javascript - + ```jsx // bad class Listing extends React.Component { render() { @@ -75,7 +74,7 @@ - **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`. - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md) - ```javascript + ```jsx // bad import reservationCard from './ReservationCard'; @@ -91,7 +90,7 @@ - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name: - ```javascript + ```jsx // bad import Footer from './Footer/Footer'; @@ -106,7 +105,7 @@ - Do not use `displayName` for naming components. Instead, name the component by reference. - ```javascript + ```jsx // bad export default React.createClass({ displayName: 'ReservationCard', @@ -122,7 +121,7 @@ - Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) - ```javascript + ```jsx // bad @@ -152,7 +151,7 @@ > Why? JSX attributes [can't contain escaped quotes](http://eslint.org/docs/rules/jsx-quotes), so double quotes make conjunctions like `"don't"` easier to type. > Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention. - ```javascript + ```jsx // bad @@ -170,7 +169,7 @@ - Always include a single space in your self-closing tag. - ```javascript + ```jsx // bad @@ -189,7 +188,7 @@ - Always use camelCase for prop names. - ```javascript + ```jsx // bad