Commit e0e293da authored by Robert Knight's avatar Robert Knight

Add eslint-plugin-jsx-a11y to the lint configuration

This helps detect accessibility errors in markup as part of `make lint`.

Flag the current set of known errors with a `FIXME-A11Y` comment and
suppress them temporarily, so that we can fix them incrementally while guarding
against new errors.

Part of #1727
parent ea9a9cf9
{
"extends": ["hypothesis"],
"extends": [
"hypothesis",
"plugin:jsx-a11y/recommended"
],
"globals": {
"Set": false
},
......
......@@ -50,6 +50,7 @@
"escape-string-regexp": "^1.0.5",
"eslint": "^6.0.1",
"eslint-config-hypothesis": "^2.0.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-mocha": "^5.2.1",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^1.6.0",
......
......@@ -32,6 +32,8 @@ export default function AnnotationHeader({
<div className="annotation-header__row">
<AnnotationUser annotation={annotation} />
<div className="annotation-collapsed-replies">
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events, jsx-a11y/anchor-is-valid */}
<a className="annotation-link" onClick={onReplyCountClick}>
{replyCount} {replyPluralized}
</a>
......
......@@ -20,6 +20,8 @@ function InlineControls({ isCollapsed, setCollapsed, linkStyle = {} }) {
return (
<div className="excerpt__inline-controls">
<span className="excerpt__toggle-link">
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
href="#"
onClick={() => setCollapsed(!isCollapsed)}
......@@ -111,6 +113,8 @@ function Excerpt({
<div className="excerpt__content" ref={contentElement}>
{children}
</div>
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}
<div
onClick={() => setCollapsed(false)}
className={classnames({
......
......@@ -89,6 +89,8 @@ function GroupListItem({
onToggleSubmenu={toggleSubmenu}
submenu={
<Fragment>
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */}
<ul onClick={collapseSubmenu}>
{activityUrl && (
<li>
......
......@@ -63,6 +63,8 @@ function GroupList({ serviceUrl, settings }) {
const icon = focusedGroup.organization.logo;
label = (
<span className="group-list__menu-label">
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<img
className="group-list__menu-icon"
src={icon || publisherProvidedIcon(settings)}
......
......@@ -105,6 +105,8 @@ function HelpPanel({ auth, session }) {
</h3>
<div className="help-panel__footer">
{activeSubPanel === 'versionInfo' && (
// FIXME-A11Y
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a
href="#"
className="help-panel__sub-panel-link"
......@@ -118,6 +120,8 @@ function HelpPanel({ auth, session }) {
</a>
)}
{activeSubPanel === 'tutorial' && (
// FIXME-A11Y
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a
href="#"
className="help-panel__sub-panel-link"
......
......@@ -24,7 +24,8 @@ function LoggedOutMessage({ onLogin, serviceUrl }) {
>
create a free account
</a>{' '}
or{' '}
or {/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a className="logged-out-message__link" href="" onClick={onLogin}>
log in
</a>
......
......@@ -60,6 +60,8 @@ export default function MenuItem({
// Wrapper element is a `<div>` rather than a `Fragment` to work around
// limitations of Enzyme's shallow rendering.
<div>
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}
<div
aria-checked={isSelected}
className={classnames('menu-item', {
......
......@@ -105,6 +105,8 @@ export default function Menu({
};
return (
// FIXME-A11Y
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div
className="menu"
ref={menuRef}
......@@ -143,6 +145,8 @@ export default function Menu({
{isOpen && (
<Fragment>
{menuArrow(arrowClass)}
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
<div
className={classnames(
'menu__content',
......
......@@ -22,6 +22,8 @@ function Tab({
type,
}) {
return (
// FIXME-A11Y
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a
className={classnames('selection-tabs__type', {
'is-selected': selected,
......
......@@ -18,7 +18,8 @@ export default function SidebarContentError({
<Fragment>
{loggedOutErrorMessage}
<br />
You may need to{' '}
You may need to {/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
className="loggedout-message__link"
href=""
......
......@@ -72,10 +72,13 @@ function TopBar({
)}
{auth.status === 'logged-out' && (
<span className="top-bar__login-links">
{/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a href="#" onClick={onSignUp} target="_blank" style={loginLinkStyle}>
Sign up
</a>{' '}
/{' '}
/ {/* FIXME-A11Y */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a href="#" onClick={onLogin} style={loginLinkStyle}>
Log in
</a>
......
......@@ -733,6 +733,21 @@
"@babel/plugin-transform-react-jsx-self" "^7.8.3"
"@babel/plugin-transform-react-jsx-source" "^7.8.3"
"@babel/runtime-corejs3@^7.7.4":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.8.3.tgz#a2445836d0699e5ba77eea2c790ad9ea51e2cd27"
integrity sha512-lrIU4aVbmlM/wQPzhEvzvNJskKyYptuXb0fGC0lTQTupTOYtR2Vqbu6/jf8vTr4M8Wt1nIzxVrSvPI5qESa/xA==
dependencies:
core-js-pure "^3.0.0"
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.4.5", "@babel/runtime@^7.7.4":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
dependencies:
regenerator-runtime "^0.13.2"
"@babel/template@^7.4.0", "@babel/template@^7.7.4", "@babel/template@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8"
......@@ -1176,6 +1191,14 @@ argv@^0.0.2:
resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab"
integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=
aria-query@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
dependencies:
ast-types-flow "0.0.7"
commander "^2.11.0"
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
......@@ -1339,6 +1362,11 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
ast-types-flow@0.0.7, ast-types-flow@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
astral-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
......@@ -1436,6 +1464,14 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axobject-query@^2.0.2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.1.tgz#2a3b1271ec722d48a4cd4b3fcc20c853326a49a7"
integrity sha512-lF98xa/yvy6j3fBHAgQXIYl+J4eZadOSqsPojemUqClzNbBV38wWGpUbQbVEyf4eUF5yF7eHmGgGA2JiHyjeqw==
dependencies:
"@babel/runtime" "^7.7.4"
"@babel/runtime-corejs3" "^7.7.4"
babel-plugin-angularjs-annotate@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/babel-plugin-angularjs-annotate/-/babel-plugin-angularjs-annotate-0.10.0.tgz#4213b3aaae494a087aad0b8237c5d0716d22ca76"
......@@ -2215,7 +2251,7 @@ commander@2.9.x:
dependencies:
graceful-readlink ">= 1.0.0"
commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
......@@ -2357,6 +2393,11 @@ core-js-compat@^3.6.2:
browserslist "^4.8.3"
semver "7.0.0"
core-js-pure@^3.0.0:
version "3.6.4"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
core-js@^2.4.0:
version "2.6.10"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f"
......@@ -2480,6 +2521,11 @@ d@1:
es5-ext "^0.10.50"
type "^1.0.1"
damerau-levenshtein@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791"
integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==
dash-ast@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37"
......@@ -2897,7 +2943,7 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
emoji-regex@^7.0.1:
emoji-regex@^7.0.1, emoji-regex@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
......@@ -3158,6 +3204,21 @@ eslint-config-hypothesis@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-config-hypothesis/-/eslint-config-hypothesis-2.0.0.tgz#18c185401d2f9c49cc455861b6a8add7675a1a63"
integrity sha512-B1lR2AAmdMixKePtoXDnbOqsdsI+AtNprdsRkN3K82hZvi4vvdAhZMwMCUJlg5EZK64kQV71/TbdqhPd+0ieJw==
eslint-plugin-jsx-a11y@^6.2.3:
version "6.2.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa"
integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==
dependencies:
"@babel/runtime" "^7.4.5"
aria-query "^3.0.0"
array-includes "^3.0.3"
ast-types-flow "^0.0.7"
axobject-query "^2.0.2"
damerau-levenshtein "^1.0.4"
emoji-regex "^7.0.2"
has "^1.0.3"
jsx-ast-utils "^2.2.1"
eslint-plugin-mocha@^5.2.1:
version "5.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.3.0.tgz#cf3eb18ae0e44e433aef7159637095a7cb19b15b"
......@@ -4994,7 +5055,7 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
jsx-ast-utils@^2.2.3:
jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f"
integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==
......@@ -6787,6 +6848,11 @@ regenerator-runtime@^0.11.0:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
regenerator-runtime@^0.13.2:
version "0.13.3"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
regenerator-transform@^0.14.0:
version "0.14.1"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment