├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── plugins.md └── rules │ ├── aria-role.md │ ├── aria-unsupported-elements.md │ ├── click-events-have-key-events.md │ ├── deprecated │ ├── avoid-positive-index.md │ ├── button-role-space.md │ ├── label-uses-for.md │ ├── mouse-events-map-to-key-events.md │ ├── no-unsupported-elements-use-aria.md │ ├── onclick-uses-tabindex.md │ ├── redundant-alt.md │ ├── use-onblur-not-onchange.md │ └── valid-aria-role.md │ ├── hidden-uses-tabindex.md │ ├── img-redundant-alt.md │ ├── img-uses-alt.md │ ├── interactive-supports-focus.md │ ├── label-has-for.md │ ├── mouse-events-have-key-events.md │ ├── no-access-key.md │ ├── no-hash-ref.md │ ├── no-onchange.md │ ├── onclick-uses-role.md │ ├── tabindex-no-positive.md │ └── tabindex-uses-button.md ├── karma.conf.js ├── mkdocs.js ├── package-lock.json ├── package.json ├── src ├── a11y.js ├── after.js ├── index.js ├── options.js ├── rules │ ├── aria-role.js │ ├── aria-unsupported-elements.js │ ├── avoid-positive-index.js │ ├── button-role-space.js │ ├── click-events-have-key-events.js │ ├── hidden-uses-tabindex.js │ ├── img-redundant-alt.js │ ├── img-uses-alt.js │ ├── index.js │ ├── interactive-supports-focus.js │ ├── label-has-for.js │ ├── label-uses-for.js │ ├── mouse-events-have-key-events.js │ ├── mouse-events-map-to-key-events.js │ ├── no-access-key.js │ ├── no-hash-ref.js │ ├── no-onchange.js │ ├── no-unsupported-elements-use-aria.js │ ├── onclick-uses-role.js │ ├── onclick-uses-tabindex.js │ ├── redundant-alt.js │ ├── tabindex-no-positive.js │ ├── tabindex-uses-button.js │ ├── use-onblur-not-onchange.js │ └── valid-aria-role.js ├── test.js └── util │ ├── DOM.js │ ├── aria.js │ ├── browser.js │ ├── has-prop.js │ ├── hidden-from-at.js │ ├── index.js │ ├── is-interactive.js │ ├── listens-to.js │ ├── role.js │ ├── test-rules.js │ └── trueish.js ├── test ├── a11y.js ├── browser │ ├── a11y.js │ ├── reporter.js │ └── util.js ├── node │ ├── reporter.js │ └── util.js ├── options.js ├── rules.js └── util.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0", 5 | "react" 6 | ], 7 | "plugins": [ 8 | "transform-runtime" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | webpack.config.js -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es6": true, 6 | "mocha": true 7 | }, 8 | "parserOptions": { 9 | "ecmaVersion": 2017, 10 | "sourceType": "module", 11 | "ecmaFeatures": { 12 | "jsx": true, 13 | "modules": true 14 | } 15 | }, 16 | "extends": [ 17 | "airbnb" 18 | ], 19 | "plugins": [ 20 | "babel", 21 | "mocha", 22 | "react" 23 | ], 24 | "rules": { 25 | "babel/new-cap": 1, 26 | "comma-dangle": ["error", "never"], 27 | "complexity": ["warn", { "max": 7 }], 28 | "generator-star-spacing": 1, 29 | "id-length": ["error", { "exceptions": ["_", "x", "y", "z", "i", "e", "t"] }], 30 | "import/no-named-as-default": 0, // connected/test-only components 31 | "import/no-extraneous-dependencies": ["error", {"devDependencies": true}], // tests 32 | "indent": ["error", 4, {"SwitchCase": 2}], 33 | "max-len": [1, 120, 2, {"ignoreComments": true}], 34 | "no-await-in-loop": 1, 35 | "no-param-reassign": ["error", { "props": false }], 36 | "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }], 37 | "no-underscore-dangle": "off", 38 | "no-use-before-define": [2, "nofunc"], 39 | "no-unused-vars": "warn", 40 | "object-shorthand": 1, 41 | "quotes": [2, "single", { "allowTemplateLiterals": true }], 42 | "react/forbid-prop-types": [1, { "forbid": ["any"] }], // used in conjunction with the transform-react-remove-prop-types babel plugin 43 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 44 | "react/jsx-indent": ["error", 4], 45 | "react/jsx-indent-props": ["error", 4], 46 | "react/jsx-uses-react": 2, 47 | "react/jsx-uses-vars": 2, 48 | "react/no-find-dom-node": "warn", // TODO: change this to error and fix findings 49 | "react/prop-types": "error", 50 | "react/react-in-jsx-scope": 2, 51 | "strict": [2, "never"], 52 | "vars-on-top": "error" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | lib/ 3 | node_modules/ 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | test 3 | karma.conf.js 4 | webpack.config.js 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "stable" 5 | - "8" 6 | - "7" 7 | - "6" 8 | 9 | before_script: 10 | - export DISPLAY=:99.0 11 | - sh -e /etc/init.d/xvfb start 12 | 13 | sudo: required 14 | addons: 15 | chrome: stable 16 | 17 | matrix: 18 | fast_finish: true 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v1.1.0 - Sat, 03 Nov 2018 14:08:56 GMT 2 | -------------------------------------- 3 | 4 | - [c45ed13](../../commit/c45ed13) Fixed issue with ref props created with React.createRef() 5 | - [9acfd3f](../../commit/9acfd3f) Added back in all of the previous rules that had been renamed with deprecation warnings to allow for a smoother transition for consuming applications. 6 | - [72e593a](../../commit/72e593a) Remove babel-register from dependencies as this pulls in babel-core 6 which means that babel 7 can't be used cleanly 7 | - [ce7f037](../../commit/ce7f037) Renamed and modified button-role-space to click-events-have-key-events to be more consistent with the rule in the the eslint-plugin-jsx-a11y library 8 | - [3e9e4b5](../../commit/3e9e4b5) Renamed a number of rules that were equivalent to existing rules in the eslint-plugin-jsx-a11y library for consistency between the two libs 9 | - [58e525f](../../commit/58e525f) Changed documentation reference to ENV to process.env.NODE_ENV 10 | - [73c69e6](../../commit/73c69e6) Renamed rule avoid-positive-tabindex to tabindex-no-positive to be more inline with the rule naming in eslint-plugin-jsx-a11y 11 | - [4bcb769](../../commit/4bcb769) Removed yarn from Travis yaml so npm will be used with package-lock.json and use npm ci 12 | - [ba57e2e](../../commit/ba57e2e) Added package-lock.json and fixed npm audit findings 13 | - [26b2772](../../commit/26b2772) Fixed a dead link pointing to the W3's aria role definitions document 14 | 15 | 16 | v1.0.1 - Sat, 01 Sep 2018 15:53:33 GMT 17 | -------------------------------------- 18 | 19 | - [d4b2256](../../commit/d4b2256) Changed the format of the reporter to use a default prefix of '[react-a11y]' to aid with identification and filtering in the console 20 | - [6471b17](../../commit/6471b17) Updated Travis config to solve for issue with headless Chrome tests failing 21 | - [5a08e10](../../commit/5a08e10) Add missing "o" 22 | - [ee6a99e](../../commit/ee6a99e) docs: fix typos 23 | 24 | 25 | v1.0.0 - Tue, 14 Nov 2017 12:19:00 GMT 26 | ----------------------------------------- 27 | 28 | - [94573c1](../../commit/94573c1) Revamp the API and configuration to allow for more modular rules to be added. 29 | 30 | **API Changes:** 31 | 32 | An options object can now be passed in to the `a11y()` function where you can specify a rules configuration, a 33 | reporter function allowing modification of how warnings are displayed, a filter function for filtering all failures, 34 | and finally a plugins array listing the names of any plugin modules to be used. 35 | See [Usage](../README.md#usage) for details. 36 | 37 | **Plugins!** 38 | 39 | react-a11y is now pluggable! See [writing plugins](docs/plugins.md) to learn how to write your own plugin. 40 | 41 | 42 | v0.3.6 - Thu, 12 Oct 2017 12:50:02 GMT 43 | ------------------------------------- 44 | 45 | - [b8f4e58](../../commit/b8f4e58) Update ReactDOM for react v16 compatibility 46 | 47 | 48 | v0.3.5 - Tue, 30 May 2017 14:23:58 GMT 49 | ----------------------------------------- 50 | 51 | - [a7eb16f](../../commit/a7eb16f) Fixed [#16](https://github.com/romeovs/react-a11y/issues/16) inappropriately referencing this in a context where this is actually undefined. 52 | 53 | 54 | v0.3.4 - Sun, 30 Apr 2017 20:48:28 GMT 55 | -------------------------------------- 56 | 57 | - [e41ba68](../../commit/e41ba68) Fixed [#11](https://github.com/romeovs/react-a11y/issues/11) from being too strict testing for use-onblur-not-onchange. Now it should pass if onChange is used in addition to onBlur. 58 | - [3173a1d](../../commit/3173a1d) Fixed [#10](https://github.com/romeovs/react-a11y/issues/10) where if a tagName is being checked for reserved in the DOM object but does not exist in the DOM object an exception was being thrown 59 | - [d0401be](../../commit/d0401be) 1. Updated eslint and plugin versions 2. Added the AirBnB eslint config to inherit 3. Fixed all linter findings 60 | 61 | 62 | v0.3.3 - Mon, 3 Apr 2017 23:01:39 GMT 63 | -------------------------------------- 64 | 65 | - [d85328e](../../commit/d85328e) Added some more scripts for helping with the version and publish process and added descriptions of the scripts in the CONTRIBUTING.md 66 | - [2ffa8ac](../../commit/2ffa8ac) Added a CONTRIBUTING page and linked to it from the README. 67 | - [c715c45](../../commit/c715c45) Updated urls to point to this repo instead of the forked from repo 68 | - [fa32346](../../commit/fa32346) Added the bundle script to the prepublish script so that the webpack bundle gets included in the npm package. Also disabled the release script and removed the rf-release package as this does not seem to be tagging or publishing to npm properly. 69 | - [8bff3fe](../../commit/8bff3fe) Added/removed dirs and files from npmignore 70 | - [be6f51e](../../commit/be6f51e) Adding some tags! Added and 71 | 72 | 73 | v0.3.2 - Tue, 15 Mar 2016 00:16:50 GMT 74 | -------------------------------------- 75 | 76 | - 77 | 78 | 79 | v0.3.1 - Wed, 09 Mar 2016 19:19:52 GMT 80 | -------------------------------------- 81 | 82 | - [2e59bba](../../commit/2e59bba) [fixed] Move object.assign from devDeps to deps (resolves #115) 83 | 84 | 85 | v0.3.0 - Tue, 08 Mar 2016 05:15:59 GMT 86 | -------------------------------------- 87 | 88 | - [78eb833](../../commit/78eb833) [fixed] correctly accounting for aria-labelledby (resolves #99) 89 | - [f43b546](../../commit/f43b546) [fixed] Spelling error 90 | - [26afd1e](../../commit/26afd1e) [fixed] correctly accounting for aria-labelledby (resolves #87) 91 | - [0e6bb84](../../commit/0e6bb84) [added] includeSrcNode takes "asString" as option. 92 | - [2f5f942](../../commit/2f5f942) [added] warningPrefix option 93 | - [bdc24df](../../commit/bdc24df) [added] "picture" to the list of redundant words in img[alt] 94 | - [598c8f8](../../commit/598c8f8) [fixed] Label test should require a label for placeholder anchors (resolves #68) [fixed] Label assertion errors if label is a number (resolves #67) 95 | - [4d1f885](../../commit/4d1f885) [fixed] bug where placeholder links required a tabindex and an ARIA role (closes #62) [fixed] bug where elements with role=none required a label (closes #63) [fixed] bug where elements with aria-hidden required a label (closes #64) [added] test to ensure interactive elements hidden using aria-hidden are removed from the tab flow 96 | - [66aea56](../../commit/66aea56) [added] docs for excluding tests to the README (resolves #60) 97 | - [8f2a22a](../../commit/8f2a22a) [fixed] bug where label assertion didn't account for the label being an image created by a custom component (resolves #52) [fixed] bug where label assertion wouldn't fail when none of the child Components have label text (resolves #53) 98 | - [2c47c8d](../../commit/2c47c8d) [fixed] issue where elements with the presentation role required a label. resolves #50 99 | - [8c6a7ce](../../commit/8c6a7ce) [fixed] bug where the label assertion can return a false failure #48 100 | - [c4d52fc](../../commit/c4d52fc) [fixed] Issue where label assertion returns a false negative when label is inside a child Component (fixes #44) [added] Tests to ensure anchors with a tabIndex but without an href require an ARIA button role (fixes #45) [added] selection and option to the list of interactive elements that require labels [removed] getFailures() method since all failures are now logged asynchronously 101 | 102 | 103 | v0.2.8 - Fri, 30 Oct 2015 17:01:59 GMT 104 | -------------------------------------- 105 | 106 | - [78eb833](../../commit/78eb833) [fixed] correctly accounting for aria-labelledby (resolves #99) 107 | 108 | 109 | v0.2.7 - Fri, 30 Oct 2015 15:46:37 GMT 110 | -------------------------------------- 111 | 112 | - [f43b546](../../commit/f43b546) [fixed] Spelling error 113 | - [26afd1e](../../commit/26afd1e) [fixed] correctly accounting for aria-labelledby (resolves #87) 114 | - [0e6bb84](../../commit/0e6bb84) [added] includeSrcNode takes "asString" as option. 115 | - [2f5f942](../../commit/2f5f942) [added] warningPrefix option 116 | - [bdc24df](../../commit/bdc24df) [added] "picture" to the list of redundant words in img[alt] 117 | 118 | 119 | v0.2.6 - Fri, 12 Jun 2015 22:28:58 GMT 120 | -------------------------------------- 121 | 122 | - [598c8f8](../../commit/598c8f8) [fixed] Label test should require a label for placeholder anchors (resolves #68) [fixed] Label assertion errors if label is a number (resolves #67) 123 | 124 | 125 | v0.2.5 - Thu, 11 Jun 2015 06:05:16 GMT 126 | -------------------------------------- 127 | 128 | - [4d1f885](../../commit/4d1f885) [fixed] bug where placeholder links required a tabindex and an ARIA role (closes #62) [fixed] bug where elements with role=none required a label (closes #63) [fixed] bug where elements with aria-hidden required a label (closes #64) [added] test to ensure interactive elements hidden using aria-hidden are removed from the tab flow 129 | 130 | 131 | v0.2.4 - Wed, 10 Jun 2015 20:33:32 GMT 132 | -------------------------------------- 133 | 134 | - [66aea56](../../commit/66aea56) [added] docs for excluding tests to the README (resolves #60) 135 | 136 | 137 | v0.2.3 - Wed, 10 Jun 2015 17:07:25 GMT 138 | -------------------------------------- 139 | 140 | - [6f38fe8](../../commit/6f38fe8) [Added] Ability to exclude tests (resolves #57) 141 | 142 | 143 | v0.2.2 - Tue, 09 Jun 2015 18:06:39 GMT 144 | -------------------------------------- 145 | 146 | - [8f2a22a](../../commit/8f2a22a) [fixed] bug where label assertion didn't account for the label being an image created by a custom component (resolves #52) [fixed] bug where label assertion wouldn't fail when none of the child Components have label text (resolves #53) 147 | - [2c47c8d](../../commit/2c47c8d) [fixed] issue where elements with the presentation role required a label. resolves #50 148 | 149 | 150 | v0.2.1 - Mon, 08 Jun 2015 23:02:25 GMT 151 | -------------------------------------- 152 | 153 | - [8c6a7ce](../../commit/8c6a7ce) [fixed] bug where the label assertion can return a false failure #48 154 | 155 | 156 | v0.2.0 - Mon, 08 Jun 2015 19:27:33 GMT 157 | -------------------------------------- 158 | 159 | - [c4d52fc](../../commit/c4d52fc) [fixed] Issue where label assertion returns a false negative when label is inside a child Component (fixes #44) [added] Tests to ensure anchors with a tabIndex but without an href require an ARIA button role (fixes #45) [added] selection and option to the list of interactive elements that require labels [removed] getFailures() method since all failures are now logged asynchronously 160 | 161 | 162 | v0.1.1 - Thu, 21 May 2015 17:25:45 GMT 163 | -------------------------------------- 164 | 165 | - [7c16747](../../commit/7c16747) Add filtering for different device types. 166 | 167 | 168 | v0.1.0 - Thu, 21 May 2015 03:41:08 GMT 169 | -------------------------------------- 170 | 171 | - [6475a4a](../../commit/6475a4a) Add a means of filtering failures on a per-component basis 172 | - [9c0f970](../../commit/9c0f970) Add Travis build status 173 | - [34533d7](../../commit/34533d7) Drop React from peerDependency and rely on passing it in 174 | - [803325d](../../commit/803325d) Mark all failing tags with an ID and include it in the message 175 | - [3af4d51](../../commit/3af4d51) Use Babel for prepublish 176 | - [870237a](../../commit/870237a) Ensure elements with a tabIndex is set to 0 are considered interactive 177 | - [069ab87](../../commit/069ab87) Add support for React 0.13. Switch from 6to5 to Babel 178 | - [e7d1373](../../commit/e7d1373) Skip processing props that are null or undefined 179 | - [b6f1d81](../../commit/b6f1d81) Ensure buttons have onKeyDown event listeners that trigger a click event for Spacebar and Enter keys 180 | 181 | 182 | v0.0.6 - Wed, 25 Feb 2015 16:47:21 GMT 183 | -------------------------------------- 184 | 185 | - 186 | 187 | 188 | v0.0.5 - Wed, 28 Jan 2015 19:37:34 GMT 189 | -------------------------------------- 190 | 191 | - 192 | 193 | 194 | v0.0.4 - Mon, 19 Jan 2015 15:57:06 GMT 195 | -------------------------------------- 196 | 197 | - [3b7f988](../../commit/3b7f988) [fixed] missing interactive tags 198 | 199 | 200 | v0.0.3 - Mon, 19 Jan 2015 15:36:02 GMT 201 | -------------------------------------- 202 | 203 | - [2d0c081](../../commit/2d0c081) [added] ability to throw instead of warn 204 | 205 | 206 | v0.0.2 - Mon, 19 Jan 2015 15:23:50 GMT 207 | -------------------------------------- 208 | 209 | - [109bd94](../../commit/109bd94) [added] button role but no keydown handler 210 | 211 | 212 | v0.0.1 - Mon, 19 Jan 2015 07:50:25 GMT 213 | -------------------------------------- 214 | 215 | - 216 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to react-a11y 2 | 3 | ## Setting up the workspace 4 | 5 | Before you can submit a Pull Request you'll need to do the following: 6 | 7 | 1. Fork the repository on GitHub 8 | 9 | 2. Clone your fork 10 | 11 | ```bash 12 | git clone https://github.com//react-a11y.git 13 | cd react-a11y 14 | ``` 15 | 16 | 3. Install for development 17 | 18 | ```bash 19 | npm install 20 | ``` 21 | 22 | ## Workflow 23 | 24 | Lint the code: 25 | 26 | ```bash 27 | npm run lint 28 | ``` 29 | 30 | Run the tests: 31 | 32 | ```bash 33 | npm run mocha // run tests using mocha only 34 | npm run karma // run tests using karma only 35 | npm run test // run tests using both mocha and karma 36 | ``` 37 | 38 | Build the code: 39 | 40 | ```bash 41 | npm run build 42 | ``` 43 | 44 | ## Making changes 45 | 46 | 1. Checkout a new branch and name it accordingly to what you intend to do 47 | 48 | ```bash 49 | git checkout -b 50 | ``` 51 | 52 | 2. Make your intended changes, being sure to run the tests and lint the code. 53 | 54 | ## Submitting a Pull Request 55 | 56 | 1. Commit your changes (please make commits small and commit messages descriptive): 57 | 58 | ```bash 59 | git commit -m "..." 60 | ``` 61 | 62 | 2. Push to _your_ github repo: 63 | ```bash 64 | git push origin 65 | ``` 66 | 67 | 3. Go to the GitHub page and click "New Pull request". 68 | 4. Write a good description of the change. 69 | 70 | After sending a pull request, other developers will review and discuss your change. Please address all the comments. Once everything is all right, one of the maintainers will merge your changes in. 71 | 72 | ## Publishing (for maintainers) 73 | _These steps are for maintainers only and can be disregarded by contributors._ 74 | 75 | For publishing use the following workflow: 76 | 77 | 1. Make sure all code changes for this new version have already been committed. 78 | 79 | 2. Update the CHANGELOG.md by using the following command, double check the content and save (don't commit): 80 | ```bash 81 | npm run changelog -- -t 82 | ``` 83 | where `` refers to the version number that you are preparing to publish 84 | 85 | 3. Update the version and publish. This is done by running _one_ of the following scripts: 86 | 87 | ```bash 88 | npm version:patch # for a patch version update i.e. v1.0.0 -> v1.0.1 89 | npm version:minor # for a minor version update i.e. v1.0.0 -> v1.1.0 90 | npm version:major # for a major version update i.e. v.1.0.0 -> v2.0.0 91 | ``` 92 | 93 | ### The publishing scripts 94 | After running one of the above `version:*` scripts the following things will take place in this order: 95 | 96 | 1. the `preversion` script will run which does the following: 97 | 98 | 1. The tests will be run and the entire process will halt if they do not all pass 99 | 100 | 2. A check will be performed to validate that the `CHANGELOG.md` has been updated and it is the only uncommitted change in the repo. If this check fails the process will be halted. 101 | 102 | 2. the selected `version:*` script will run which does the following: 103 | 104 | 1. The version in `package.json` will be incremented as requested (patch, minor, major). _Because the `--no-git-tag-version` flag is specified this script will not yet include tagging and committing in the github repo._ 105 | 106 | 3. the `postversion` script will be run which does the following: 107 | 108 | 1. A `git commit` will be made including only the `package.json` and `CHANGELOG.md` files. It will include a commit comment in the format of: "Version $npm_package_version" 109 | 110 | 2. Performs a `git tag` in the format of "v$npm_package_version" 111 | 112 | 3. Performs a `git push` and `git push --tags` 113 | 114 | 4. Runs `npm publish` 115 | 116 | 117 | ## Additional Resources 118 | * [GitHub pull request help](https://help.github.com/categories/collaborating-with-issues-and-pull-requests/) 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Ryan Florence 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | React A11y 2 | ========== 3 | 4 | [![build status](https://img.shields.io/travis/reactjs/react-a11y/master.svg?style=flat-square)](https://travis-ci.org/reactjs/react-a11y) 5 | 6 | Identifies accessibility issues in your React.js elements 7 | 8 | ![screenshot](http://i.imgur.com/naQTETB.png) 9 | 10 | 11 | # ⛔️DEPRECATION NOTICE ⛔️ 12 | This library is being deprecated in favor of [@axe-core/react](https://github.com/dequelabs/axe-core-npm/tree/develop/packages/react). 13 | Deque Systems are one of the top authorities on web accessibility. Their auditing tools based on their axe-core 14 | engine are unrivaled and have become the gold standard for auditing web accessibility issues. Now that they have 15 | developed a runtime React DOM auditing tool, that does what react-a11y attempts to do but better, it seems 16 | counterproductive to continue to maintain react-a11y. Let's pool our resources and energies into the best product and 17 | I believe any accessibility tool backed by the experts at Deque Systems is bound to be one we can trust and depend on. 18 | Please go check out and install [@axe-core/react](https://github.com/dequelabs/axe-core-npm/tree/develop/packages/react) today! 19 | 20 | ## Installation 21 | 22 | Run: 23 | 24 | ```bash 25 | npm install react-a11y 26 | ``` 27 | 28 | ## Usage 29 | 30 | In your main application file, require the module and call it, you'll start 31 | getting warnings in the console as your app renders. Note that by default all 32 | rules are turned `off` so you need to turn them on first (by setting them to 33 | `"warn"` or `"error"`). 34 | 35 | ```javascript 36 | import React from 'react'; 37 | import ReactDOM from 'react-dom'; 38 | 39 | if (process.env.NODE_ENV === 'development') { 40 | const a11y = require('react-a11y').default; 41 | a11y(React, ReactDOM, { 42 | rules: { 43 | 'img-uses-alt': 'warn', 44 | 'img-redundant-alt': [ 'warn', [ 'image', 'photo', 'foto', 'bild' ]] 45 | // ... 46 | } 47 | }); 48 | } 49 | ``` 50 | 51 | You probably don't want to call it if you're in production, since it patches the 52 | React rendering functions and this might make this slower. 53 | 54 | ## Migrating to v1.1.0 55 | A number of the rule names have changed and the previous rule names have been deprecated. These deprecated rules will 56 | be removed in v2.0.0. The following is the mapping of old to new rules: 57 | 58 | | Old Rule | New Rule | 59 | | ------------- | ----------- | 60 | | avoid-positive-tabindex | tabindex-no-positive | 61 | | button-role-space | click-events-have-key-events | 62 | | label-uses-for | label-has-for | 63 | | mouse-events-map-to-key-events | mouse-events-have-key-events | 64 | | no-unsupported-elements-use-aria | aria-unsupported-elements | 65 | | onclick-uses-tabindex | interactive-supports-focus | 66 | | redundant-alt | img-redundant-alt | 67 | | use-onblur-not-onchange | no-onchange | 68 | | valid-aria-role | aria-role | 69 | 70 | ## Options 71 | 72 | These are the supported configuration options, annotated using [flow][] type 73 | annotations 74 | 75 | ```flow js 76 | a11y(React : React, ReactDOM : ReactDOM, opts : object? ); 77 | ``` 78 | 79 | `React` is the React object you want to shim to allow the 80 | accessibility tests. 81 | 82 | `ReactDOM` is the ReactDOM object you're using to render the 83 | React components. This is only used on the client side, so you 84 | can safely omit it when using `react-a11y` in node. 85 | 86 | ### `options`: 87 | - `plugins : [string]` 88 | An array of strings corresponding to names of plugins to be used. 89 | Eg. if the array contains `'aria-wai'` it would include the rules 90 | in a (yet to be written) `react-a11y-plugin-aria-wai` module. You 91 | are responsible for installing this module. 92 | 93 | - `rules : object` 94 | The configuration options for each of the rules. This uses the same format 95 | as [eslint][] does: 96 | 97 | ```javascript 98 | const rules = { 99 | 'img-uses-alt': 'off', 100 | 'redundant-alt': [ 101 | 'warn', 102 | // other options to pass to the rule: 103 | [ 104 | 'foto' 105 | ] 106 | ] 107 | }; 108 | ``` 109 | 110 | Refer to the [rule docs](docs/rules) 111 | to see what options are defined for each rule. 112 | 113 | - `reporter : object => undefined` 114 | Use this to modify how the warnings are displayed. 115 | The reporter is a function that accepts an object with 116 | the following keys: 117 | - `msg : string` - the error message 118 | - `tagName : string` - the tagName of the violating element (eg. `'img'`) 119 | - `severity : string` - the severity as configured by the user in the 120 | corresponding rule configuration (one of `'off'`, `'warn'`, or `'error'`) 121 | - `props : object` - the props as passed to the element 122 | - `displayName : string?` - the `displayName` of the owner, if any 123 | - `DOMNode : object?` - the violating DOMNode as rendered to the browser 124 | DOM, this is only available on when `react-a11y` is running in the 125 | browser. 126 | - `url : string?` - The url to a webpage explaining why this rule 127 | is important 128 | 129 | The default reporter displays all the information it can, but listens 130 | to the deprecated options `includeSrcNode`, `warningPrefix` and 131 | `throwErro` and `throwError`. 132 | 133 | - `filterFn : (string, string, string) => boolean` 134 | You can filter failures by passing a function to the `filterFn` option. The 135 | filter function will receive three arguments: the name of the Component 136 | instance or ReactElement, the id of the violating element, and the failure 137 | message. 138 | 139 | Note: If it is a ReactElement, the name will be the node type (eg. `div`) 140 | 141 | ```javascript 142 | // only show errors on CommentList 143 | const commentListFailures = function (name, id, msg) { 144 | return name === "CommentList"; 145 | }; 146 | 147 | a11y(React, ReactDOM, { filterFn: commentListFailures }); 148 | ``` 149 | 150 | ## Cleaning Up In Tests 151 | 152 | Use the `restoreAll()` method to clean up mutations made to `React`. 153 | Useful if you are using `react-a11y` in your test suite: 154 | 155 | ```javascript 156 | beforeEach(() => a11y(React)); 157 | afterEach(() => a11y.restoreAll()); 158 | ``` 159 | 160 | ## Writing plugins 161 | 162 | The rules in this version of `react-a11y` are pluggable! 163 | You can write your own plugin to add more rules. Have a look at 164 | [writing plugins](docs/plugins.md) in the 165 | docs to get started! 166 | 167 | ## Contributing 168 | 169 | Interested in contributing? Great! Look here for more info: [CONTRIBUTING.md](CONTRIBUTING.md). 170 | 171 | [react-a11y]: https://github.com/reactjs/react-a11y 172 | [eslint]: http://eslint.org 173 | [flow]: http://flowtype.org 174 | [eslint-plugin]: https://github.com/evcohen/eslint-plugin-jsx-a11y 175 | [AX]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules 176 | -------------------------------------------------------------------------------- /docs/plugins.md: -------------------------------------------------------------------------------- 1 | 2 | # Writing plugins 3 | 4 | Writing a plugin is really simple. 5 | 6 | All you need to expose in your entry point is an object with the 7 | following format: 8 | 9 | ```js 10 | export default { 11 | rules: { 12 | 'rule-name': // rule definition 13 | , 'other-rule-name': // other rule definitions... 14 | } 15 | } 16 | ``` 17 | And publish that as a package `react-a11y-plugin-{plugin-name}`. 18 | 19 | The rules will be accessible to for configuration by the end-user as: 20 | 21 | ```js 22 | { 23 | plugins: [ 24 | // ... 25 | '{plugin-name}' 26 | ] 27 | , rules: { 28 | 'plugin-name/rule-name': [ 'warn', /* other options */ ] 29 | , 'plugin-name/other-rule-name': 'off' 30 | } 31 | } 32 | ``` 33 | 34 | A rule definition is an array of tests, where each test looks like: 35 | ```js 36 | { 37 | msg: 'This is the error message explaining what is wrong' 38 | , affects: [ 39 | // this is an array of affected devices, undefined means all devices 40 | // eg. A11y.devices.screenReaders 41 | ] 42 | 43 | , test (tagName, props, children, ctx) { 44 | // this test returns true if an element passes, false if otherwise 45 | // ctx contains: React, ReactDOM, and the options passed to the test 46 | } 47 | 48 | , tagName: 'img' // a string or array of strings with the element names 49 | // which this test applies to (undefined means all elements) 50 | 51 | , url: 'http://www.w3.org/article-that/explains/it-all' 52 | , AX: 'AX_ARIA_02' // the google chrome accessibility code (if applicable) 53 | } 54 | ``` 55 | 56 | The affected devices array is not used for the moment but will be in the future 57 | so users can filter based on them. The possible devices are available in: 58 | 59 | ``` 60 | require('react-a11y/util').devices 61 | // == { 62 | // screenReaders: ... 63 | // , keyboardOnly: ... 64 | // } 65 | ``` 66 | 67 | Look at [the rules included in `react-a11y`](../src/rules) for examples. 68 | -------------------------------------------------------------------------------- /docs/rules/aria-role.md: -------------------------------------------------------------------------------- 1 | # aria-role 2 | 3 | The ARIA roles model requires that elements with a role attribute use a valid, 4 | non-abstract ARIA role. Each non-abstract ARIA role is mapped on to a known set 5 | of behavior by the user agent or assistive technology, so using an unknown role 6 | will result in the desired behavior not being available to the user. 7 | 8 | You can find a list of valid ARIA roles, along with descriptions and information 9 | on additional required attributes, on the 10 | [WAI-ARIA](http://www.w3.org/WAI/PF/aria/roles#roles_categorization) site. 11 | 12 | 13 | ## options 14 | 15 | *This rule takes no options* 16 | 17 | ## Passes 18 | 19 | ```jsx harmony 20 | // passes when there is a role and it is valid 21 |
22 | 23 | // passes when there is no `role` 24 |
25 | ``` 26 | 27 | ## Fails 28 | 29 | ```jsx harmony 30 | // fails when there is an invalid `role` 31 |
32 | ``` 33 | 34 | ## See also 35 | 36 | - [This document](https://www.w3.org/WAI/PF/aria/roles) from w3.org - Google Audit defs [AX_ARIA_01](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-rules#ax_aria_01) 37 | -------------------------------------------------------------------------------- /docs/rules/aria-unsupported-elements.md: -------------------------------------------------------------------------------- 1 | # aria-unsupported-elements 2 | 3 | 4 | Certain reserved DOM elements do not support ARIA roles, states and properties. 5 | This is often because they are not visible, for example `meta`, `html`, `script`, 6 | `style`. This rule enforces that these DOM elements do not contain the `role` and/or 7 | `aria-*` props. 8 | 9 | 10 | ## Options 11 | 12 | *This rule takes no options* 13 | 14 | ## Passes 15 | 16 | These elements are passed by this rule 17 | ```jsx harmony 18 | // no problem when the reserved element is not given an illegal prop 19 | 20 | 21 | // no problem when an illegal props is given to a non-reserved element 22 | 23 | ``` 24 | 25 | ## Fails 26 | 27 | These elements are *not* passed by this rule 28 | ```jsx harmony 29 | // warns when the element should not be given any ARIA attributes 30 | 31 | ``` 32 | 33 | ## See also 34 | 35 | - Google Audit defs [AX_ARIA_12](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-rules#ax_aria_12) 36 | -------------------------------------------------------------------------------- /docs/rules/click-events-have-key-events.md: -------------------------------------------------------------------------------- 1 | # click-events-have-key-events 2 | 3 | Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, 4 | onKeyPress. Coding for the keyboard is important for users with physical disabilities 5 | who cannot use a mouse, AT compatibility, and screenreader users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when there is an `onClick` handler and there is an `onKey*` handler. 16 |
17 |
18 |
19 | 20 | // passes when the element is aria-hidden 21 | 22 | ``` 23 | 24 | ## Fails 25 | 26 | ```jsx harmony 27 | // fails when there is an `onClick` handler and no `onKey*` is present 28 |
29 | ``` 30 | 31 | ## See also 32 | 33 | - [This document](https://www.w3.org/WAI/GL/wiki/Making_actions_keyboard_accessible_by_using_keyboard_event_handlers_with_WAI-ARIA_controls) from w3.org 34 | -------------------------------------------------------------------------------- /docs/rules/deprecated/avoid-positive-index.md: -------------------------------------------------------------------------------- 1 | # tabindex-no-positive (deprecated - use tabindex-no-positive) 2 | 3 | It is recommended that authors avoid positive values for the `tabindex` attribute because it is 4 | brittle (any focusable elements added to the page without an explicit `tabindex` value greater than 5 | zero will come last in the tab order) and can easily result in a page which is extremely difficult 6 | to navigate, causing accessibility problems. Only use a `tabindex` of 0 for focusable elements. 7 | 8 | 9 | ## options 10 | 11 | *This rule takes no options* 12 | 13 | ## Passes 14 | 15 | ```jsx harmony 16 |
17 |
18 |
19 | ``` 20 | 21 | ## Fails 22 | 23 | ```jsx harmony 24 |
25 |
26 |
27 | ``` 28 | 29 | ## See also 30 | 31 | - [This document](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_03) 32 | from Chrome Accessibility Developer Tools. 33 | -------------------------------------------------------------------------------- /docs/rules/deprecated/button-role-space.md: -------------------------------------------------------------------------------- 1 | # button-role-space (deprecated - use click-events-have-key-events) 2 | 3 | Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, 4 | onKeyPress. Coding for the keyboard is important for users with physical disabilities 5 | who cannot use a mouse, AT compatibility, and screenreader users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when there is an `onClick` handler and there is an `onKey*` handler. 16 |
17 |
18 |
19 | 20 | // passes when the element is aria-hidden 21 | 22 | ``` 23 | 24 | ## Fails 25 | 26 | ```jsx harmony 27 | // fails when there is an `onClick` handler and no `onKey*` is present 28 |
29 | ``` 30 | 31 | ## See also 32 | 33 | - [This document](https://www.w3.org/WAI/GL/wiki/Making_actions_keyboard_accessible_by_using_keyboard_event_handlers_with_WAI-ARIA_controls) from w3.org 34 | -------------------------------------------------------------------------------- /docs/rules/deprecated/label-uses-for.md: -------------------------------------------------------------------------------- 1 | # label-uses-for (deprecated - use label-has-for) 2 | 3 | Enforce label tags have `htmlFor` attribute. Form controls using a `label` to 4 | identify them must have only one label that is programmatically associated with 5 | the control using: ``. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when the label is hidden 16 | 17 | 18 | // passes when the label has a valid `htmlFor` prop 19 | 20 | 21 | // passes when it is not a label 22 |
23 | ``` 24 | 25 | ## Fails 26 | 27 | ```jsx harmony 28 | // fails when a label is not hidden and has no `htmlFor` 29 | 30 | ``` 31 | 32 | ## See also 33 | 34 | - [This document](https://www.w3.org/WAI/tutorials/forms/labels) from w3.org 35 | -------------------------------------------------------------------------------- /docs/rules/deprecated/mouse-events-map-to-key-events.md: -------------------------------------------------------------------------------- 1 | # mouse-events-map-to-key-events (deprecated - use mouse-events-have-key-events) 2 | 3 | Enforce `onMouseOver`/`onMouseOut` are accompanied by 4 | `onFocus`/`onBlur`. Coding for the keyboard is important for users with 5 | physical disabilities who cannot use a mouse, AT compatibility, and screenreader 6 | users. 7 | 8 | 9 | ## options 10 | 11 | *This rule takes no options* 12 | 13 | ## Passes 14 | 15 | ```jsx harmony 16 | // passes when there is no `onMouseOver` or `onMouseOut` 17 |
18 | 19 | // passes when there is `onMouseOver` and `onFocus` 20 |
21 | 22 | // passes when there is `onMouseOut` and `onBlur` 23 |
24 | ``` 25 | 26 | ## Fails 27 | 28 | ```jsx harmony 29 | // fails when there is `onMouseOver` but no `onFocus` 30 |
31 | 32 | // fails when there is `onMouseOut` but no `onBlur` 33 |
34 | ``` 35 | 36 | ## See also 37 | 38 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onmouseover) from webaim.org 39 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onmouseover) from webaim.org 40 | -------------------------------------------------------------------------------- /docs/rules/deprecated/no-unsupported-elements-use-aria.md: -------------------------------------------------------------------------------- 1 | # no-unsupported-elements-use-aria (deprecated - use aria-unsupported-elements) 2 | 3 | 4 | Certain reserved DOM elements do not support ARIA roles, states and properties. 5 | This is often because they are not visible, for example `meta`, `html`, `script`, 6 | `style`. This rule enforces that these DOM elements do not contain the `role` and/or 7 | `aria-*` props. 8 | 9 | 10 | ## Options 11 | 12 | *This rule takes no options* 13 | 14 | ## Passes 15 | 16 | These elements are passed by this rule 17 | ```jsx harmony 18 | // no problem when the reserved element is not given an illegal prop 19 | 20 | 21 | // no problem when an illegal props is given to a non-reserved elemeent 22 | 23 | ``` 24 | 25 | ## Fails 26 | 27 | These elements are *not* passed by this rule 28 | ```jsx harmony 29 | // warns when the element should not be given any ARIA attributes 30 | 31 | ``` 32 | 33 | ## See also 34 | 35 | - Google Audit defs [AX_ARIA_12](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-rules#ax_aria_12) 36 | -------------------------------------------------------------------------------- /docs/rules/deprecated/onclick-uses-tabindex.md: -------------------------------------------------------------------------------- 1 | # onclick-uses-tabindex (deprecated - use interactive-supports-focus) 2 | 3 | Enforce that elements that have an `onClick` handler also have 4 | a `tabIndex` property. If not, they will not be navigable by 5 | keyboard users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when when there is an `onClick` with a `tabIndex` 16 | 17 | 18 | // passes when the element is hidden from aria 19 | 20 | 21 | // passes when the element is interactive 22 | 23 | ``` 24 | 25 | ## Fails 26 | 27 | ```jsx harmony 28 | // fails when there is an `onClick` with no `tabIndex` 29 | 30 | ``` 31 | 32 | ## See also 33 | 34 | - [This document](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02) from github.com/GoogleChrome 35 | - [This document](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav) from w3.org -------------------------------------------------------------------------------- /docs/rules/deprecated/redundant-alt.md: -------------------------------------------------------------------------------- 1 | # redundant-alt (deprecated - use img-redundant-alt) 2 | 3 | Enforce img alt attribute does not contain the word image, picture, or photo. 4 | Screenreaders already announce `img` elements as an image. There is no need to use 5 | words such as *image*, *photo*, and/or *picture*. 6 | 7 | 8 | ## options 9 | 10 | This rule takes the following options: 11 | 1. Words to look for when looking for redundant words. (**Array(String)**) 12 | default: `["image","picture","photo"]` 13 | 14 | ## Passes 15 | 16 | ```jsx harmony 17 | // passes when the `alt` does not contain redundant words 18 | nice 19 | 20 | // passes when the `alt` does not contain redundant words (different opts) 21 | // (using options: ["warn",["foto"]]) 22 | image 23 | 24 | // passes when the element is aria-hidden 25 | 26 | ``` 27 | 28 | ## Fails 29 | 30 | ```jsx harmony 31 | // fails when is a redundant alt message 32 | bar image foo 33 | 34 | // fails when is a redundant alt message (different opts) 35 | // (using options: ["warn",["foto"]]) 36 | bar foto 37 | ``` 38 | 39 | ## See also 40 | 41 | - [This document](http://webaim.org/techniques/alttext) from webaim.org 42 | -------------------------------------------------------------------------------- /docs/rules/deprecated/use-onblur-not-onchange.md: -------------------------------------------------------------------------------- 1 | # use-onblur-not-onchange (deprecated - use no-onchange) 2 | 3 | Enforce usage of onBlur over onChange for accessibility. onBlur must be used 4 | instead of onChange, unless absolutely necessary and it causes no negative 5 | consequences for keyboard only or screen reader users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when there is no `onChange` prop 16 | 17 | 18 | // passes when the element is aria-hidden 19 | 20 | 21 | // passes when the element is aria-disabled 22 | 23 | 24 | // passes when the element is aria-readonly 25 | 26 | 27 | // passes when there is an `onChange` prop and an `onBlur` prop 28 | 29 | ``` 30 | 31 | ## Fails 32 | 33 | ```jsx harmony 34 | // fails when the `onChange` prop is present without an `onBlur` prop 35 | 36 | ``` 37 | 38 | ## See also 39 | 40 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onchange) from webaim.org 41 | -------------------------------------------------------------------------------- /docs/rules/deprecated/valid-aria-role.md: -------------------------------------------------------------------------------- 1 | # valid-aria-role (deprecated - use aria-role) 2 | 3 | The ARIA roles model requires that elements with a role attribute use a valid, 4 | non-abstract ARIA role. Each non-abstract ARIA role is mapped on to a known set 5 | of behavior by the user agent or assistive technology, so using an unknown role 6 | will result in the desired behavior not being available to the user. 7 | 8 | You can find a list of valid ARIA roles, along with descriptions and information 9 | on additional required attributes, on the 10 | [WAI-ARIA](http://www.w3.org/WAI/PF/aria/roles#roles_categorization) site. 11 | 12 | 13 | ## options 14 | 15 | *This rule takes no options* 16 | 17 | ## Passes 18 | 19 | ```jsx harmony 20 | // passes when there is a role and it is valid 21 |
22 | 23 | // passes when there is no `role` 24 |
25 | ``` 26 | 27 | ## Fails 28 | 29 | ```jsx harmony 30 | // fails when there is an invalid `role` 31 |
32 | ``` 33 | 34 | ## See also 35 | 36 | - [This document](https://www.w3.org/WAI/PF/aria/roles) from w3.org - Google Audit defs [AX_ARIA_01](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-rules#ax_aria_01) 37 | -------------------------------------------------------------------------------- /docs/rules/hidden-uses-tabindex.md: -------------------------------------------------------------------------------- 1 | # hidden-uses-tabindex 2 | 3 | Enforce that interactive elements that have been removed from 4 | the accessibility tree using `aria-hidden` are also removed from 5 | the tab flow by setting `tabIndex={-1}`. If not, this could result 6 | in a hidden tab stop for screen reader users. 7 | 8 | 9 | ## options 10 | 11 | *This rule takes no options* 12 | 13 | ## Passes 14 | 15 | ```jsx harmony 16 | // passes when an interactive element is aria-hidden and has tabindex="-1" 17 | 18 | 19 | // passes when the element is not interactive 20 | 21 | 22 | // passes when an interactive element is not aria-hidden 23 | 24 | ``` 25 | 26 | ## Fails 27 | 28 | ```jsx harmony 29 | // fails when an interactive element is hidden but has no tabindex 30 | 31 | 32 | // fails when an interactive element is hidden but has a bad tabindex 33 | 34 | ``` 35 | 36 | ## See also 37 | 38 | - [This document](http://john.foliot.ca/aria-hidden) from john.foliot.ca 39 | -------------------------------------------------------------------------------- /docs/rules/img-redundant-alt.md: -------------------------------------------------------------------------------- 1 | # img-redundant-alt 2 | 3 | Enforce img alt attribute does not contain the word image, picture, or photo. 4 | Screenreaders already announce `img` elements as an image. There is no need to use 5 | words such as *image*, *photo*, and/or *picture*. 6 | 7 | 8 | ## options 9 | 10 | This rule takes the following options: 11 | 1. Words to look for when looking for redundant words. (**Array(String)**) 12 | default: `["image","picture","photo"]` 13 | 14 | ## Passes 15 | 16 | ```jsx harmony 17 | // passes when the `alt` does not contain redundant words 18 | nice 19 | 20 | // passes when the `alt` does not contain redundant words (different opts) 21 | // (using options: ["warn",["foto"]]) 22 | image 23 | 24 | // passes when the element is aria-hidden 25 | 26 | ``` 27 | 28 | ## Fails 29 | 30 | ```jsx harmony 31 | // fails when is a redundant alt message 32 | bar image foo 33 | 34 | // fails when is a redundant alt message (different opts) 35 | // (using options: ["warn",["foto"]]) 36 | bar foto 37 | ``` 38 | 39 | ## See also 40 | 41 | - [This document](http://webaim.org/techniques/alttext) from webaim.org 42 | -------------------------------------------------------------------------------- /docs/rules/img-uses-alt.md: -------------------------------------------------------------------------------- 1 | # img-uses-alt 2 | 3 | Enforce that an `img` element contains the `alt` prop. The `alt` attribute specifies 4 | an alternate text for an image, if the image cannot be displayed. 5 | 6 | 7 | ## options 8 | 9 | *This rule takes no options* 10 | 11 | ## Passes 12 | 13 | ```js 14 | // passes when the img has an `alt` 15 | nice 16 | 17 | // passes when the img has an empty `alt` and role="presentation" 18 | 19 | 20 | // passes when the img is aria-hidden 21 | 22 | ``` 23 | 24 | ## Fails 25 | 26 | ```js 27 | // fails when the img doesn't have an `alt` 28 | 29 | 30 | // fails when the img has alt="" but no role="presentation" 31 | 32 | ``` 33 | 34 | ## See also 35 | 36 | - [This document](https://dequeuniversity.com/rules/axe/2.1/image-alt) from dequeuniversity.com 37 | - [This document](https://www.w3.org/WAI/PF/aria/roles#presentation) from w3.org 38 | -------------------------------------------------------------------------------- /docs/rules/interactive-supports-focus.md: -------------------------------------------------------------------------------- 1 | # interactive-supports-focus 2 | 3 | Enforce that elements that have an `onClick` handler also have 4 | a `tabIndex` property. If not, they will not be navigable by 5 | keyboard users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when when there is an `onClick` with a `tabIndex` 16 | 17 | 18 | // passes when the element is hidden from aria 19 | 20 | 21 | // passes when the element is interactive 22 | 23 | ``` 24 | 25 | ## Fails 26 | 27 | ```jsx harmony 28 | // fails when there is an `onClick` with no `tabIndex` 29 | 30 | ``` 31 | 32 | ## See also 33 | 34 | - [This document](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02) from github.com/GoogleChrome 35 | - [This document](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_generalnav) from w3.org 36 | -------------------------------------------------------------------------------- /docs/rules/label-has-for.md: -------------------------------------------------------------------------------- 1 | # label-has-for 2 | 3 | Enforce label tags have `htmlFor` attribute. Form controls using a `label` to 4 | identify them must have only one label that is programmatically associated with 5 | the control using: ``. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when the label is hidden 16 | 17 | 18 | // passes when the label has a valid `htmlFor` prop 19 | 20 | 21 | // passes when it is not a label 22 |
23 | ``` 24 | 25 | ## Fails 26 | 27 | ```jsx harmony 28 | // fails when a label is not hidden and has no `htmlFor` 29 | 30 | ``` 31 | 32 | ## See also 33 | 34 | - [This document](https://www.w3.org/WAI/tutorials/forms/labels) from w3.org 35 | -------------------------------------------------------------------------------- /docs/rules/mouse-events-have-key-events.md: -------------------------------------------------------------------------------- 1 | # mouse-events-have-key-events 2 | 3 | Enforce `onMouseOver`/`onMouseOut` are accompanied by 4 | `onFocus`/`onBlur`. Coding for the keyboard is important for users with 5 | physical disabilities who cannot use a mouse, AT compatibility, and screenreader 6 | users. 7 | 8 | 9 | ## options 10 | 11 | *This rule takes no options* 12 | 13 | ## Passes 14 | 15 | ```jsx harmony 16 | // passes when there is no `onMouseOver` or `onMouseOut` 17 |
18 | 19 | // passes when there is `onMouseOver` and `onFocus` 20 |
21 | 22 | // passes when there is `onMouseOut` and `onBlur` 23 |
24 | ``` 25 | 26 | ## Fails 27 | 28 | ```jsx harmony 29 | // fails when there is `onMouseOver` but no `onFocus` 30 |
31 | 32 | // fails when there is `onMouseOut` but no `onBlur` 33 |
34 | ``` 35 | 36 | ## See also 37 | 38 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onmouseover) from webaim.org 39 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onmouseover) from webaim.org 40 | -------------------------------------------------------------------------------- /docs/rules/no-access-key.md: -------------------------------------------------------------------------------- 1 | # no-access-key 2 | 3 | Enforce no accessKey prop on element. Access keys are HTML elements that allow 4 | web developers to assign keyboard shortcuts to elements. Inconsistencies between 5 | keyboard shortcuts and keyboard commands used by screenreader and keyboard only 6 | users create accessibility complications so to avoid complications, access keys 7 | should not be used. 8 | 9 | 10 | ## options 11 | 12 | *This rule takes no options* 13 | 14 | ## Passes 15 | 16 | ```js 17 | // passes when there is an no `accessKey` prop 18 |
19 | ``` 20 | 21 | ## Fails 22 | 23 | ```js 24 | // fails when there is an `accessKey` prop 25 |
26 | ``` 27 | 28 | ## See also 29 | 30 | - [This document](http://webaim.org/techniques/keyboard/accesskey#spec) from webaim.org 31 | -------------------------------------------------------------------------------- /docs/rules/no-hash-ref.md: -------------------------------------------------------------------------------- 1 | # no-hash-ref 2 | 3 | Enforce an anchor element's href prop value is not just `"#"`. You should use 4 | something more descriptive, or use a button instead. 5 | 6 | 7 | ## options 8 | 9 | *This rule takes no options* 10 | 11 | ## Passes 12 | 13 | ```js 14 | // passes when the `href` is not `#` 15 | 16 | ``` 17 | 18 | ## Fails 19 | 20 | ```js 21 | // fails when the `href` is `#` 22 | 23 | ``` 24 | 25 | ## See also 26 | 27 | - [This document](http://webaim.org/techniques/hypertext/) from webaim.org 28 | -------------------------------------------------------------------------------- /docs/rules/no-onchange.md: -------------------------------------------------------------------------------- 1 | # no-onchange 2 | 3 | Enforce usage of onBlur over onChange for accessibility. onBlur must be used 4 | instead of onChange, unless absolutely necessary and it causes no negative 5 | consequences for keyboard only or screen reader users. 6 | 7 | 8 | ## options 9 | 10 | *This rule takes no options* 11 | 12 | ## Passes 13 | 14 | ```jsx harmony 15 | // passes when there is no `onChange` prop 16 | 17 | 18 | // passes when the element is aria-hidden 19 | 20 | 21 | // passes when the element is aria-disabled 22 | 23 | 24 | // passes when the element is aria-readonly 25 | 26 | 27 | // passes when there is an `onChange` prop and an `onBlur` prop 28 | 29 | ``` 30 | 31 | ## Fails 32 | 33 | ```jsx harmony 34 | // fails when the `onChange` prop is present without an `onBlur` prop 35 | 36 | ``` 37 | 38 | ## See also 39 | 40 | - [This document](http://webaim.org/techniques/javascript/eventhandlers#onchange) from webaim.org 41 | -------------------------------------------------------------------------------- /docs/rules/onclick-uses-role.md: -------------------------------------------------------------------------------- 1 | # onclick-uses-role 2 | 3 | Enforce visible, non-interactive elements with click handlers use role 4 | attribute. Visible means that it is not hidden from a screen reader. Examples of 5 | non-interactive elements are `div`, `section`, and a elements without a `href` 6 | prop. The purpose of the role attribute is to identify to screenreaders the exact 7 | function of an element. 8 | 9 | 10 | ## options 11 | 12 | *This rule takes no options* 13 | 14 | ## Passes 15 | 16 | ```js 17 | // passes when the element is hidden from aria 18 | 19 | 20 | // passes when there is an `onClick` with a `role` 21 | 22 | 23 | // passes when the element is interactive 24 | 25 | ``` 26 | 27 | ## Fails 28 | 29 | ```js 30 | // fails when there is an `onClick` with no `role` 31 | 32 | ``` 33 | 34 | ## See also 35 | 36 | - [This document](https://www.w3.org/WAI/PF/aria/roles#role_definitions) from w3.org 37 | -------------------------------------------------------------------------------- /docs/rules/tabindex-no-positive.md: -------------------------------------------------------------------------------- 1 | # tabindex-no-positive 2 | 3 | It is recommended that authors avoid positive values for the `tabindex` attribute because it is 4 | brittle (any focusable elements added to the page without an explicit `tabindex` value greater than 5 | zero will come last in the tab order) and can easily result in a page which is extremely difficult 6 | to navigate, causing accessibility problems. Only use a `tabindex` of 0 for focusable elements. 7 | 8 | 9 | ## options 10 | 11 | *This rule takes no options* 12 | 13 | ## Passes 14 | 15 | ```jsx harmony 16 |
17 |
18 |
19 | ``` 20 | 21 | ## Fails 22 | 23 | ```jsx harmony 24 |
25 |
26 |
27 | ``` 28 | 29 | ## See also 30 | 31 | - [This document](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_03) 32 | from Chrome Accessibility Developer Tools. 33 | -------------------------------------------------------------------------------- /docs/rules/tabindex-uses-button.md: -------------------------------------------------------------------------------- 1 | # tabindex-uses-button 2 | 3 | When an anchor has a `tabIndex`, but no `href` and no `role` properties, 4 | it is likely you are using it to emulate a `button`. Prefer using `role="button"` 5 | or just use the `