New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add accessibility rule and React config #282
Conversation
lib/index.js
Outdated
@@ -9,6 +9,7 @@ module.exports = { | |||
'no-blur': require('./rules/no-blur'), | |||
'no-d-none': require('./rules/no-d-none'), | |||
'no-dataset': require('./rules/no-dataset'), | |||
'no-generic-link-text': require('./rules/no-generic-link-text'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want this to be prefixed so I can pattern match the code base specifically for accessibility rules. What should I do??? Thoughts on just prefixing all accessibility rules like:
a11y-no-generic-link-text
Related Slack thread on prefixing eslint rules (GitHub Staff only)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the name to a11y-
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the a11y!
browser: true | ||
}, | ||
plugins: ['github', 'jsx-a11y'], | ||
extends: ['plugin:jsx-a11y/recommended'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming that any config we want to recommend as part of "react" belongs here, so I added the jsx-a11y
plugin. does this look right?
👋 Hello and thanks for pinging us! An accessibility first responder will review this soon.
|
docs/rules/no-generic-link-text.md
Outdated
@@ -0,0 +1,83 @@ | |||
# No Generic Link Text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty much copied from our erblint-github
docs though the examples were changed to .jsx
instead of .erb
.
The two behave nearly exactly the same so why not 🤷🏻♀️
"eslint-plugin-no-only-tests": "^2.6.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"eslint-rule-documentation": ">=1.0.0", | ||
"jsx-ast-utils": "^3.3.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This provides utility methods that make parsing JSX elements much more pleasant. I found it through jsx-a11y-plugin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do u also need to use the typescript ast?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I am asking does this rule work for tsx files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems yes, as long as the .eslintrc.json
wherever the linters get run is configured with the typescript parser:
"parser": "@typescript-eslint/parser",
I tested this branch out in dotcom by running:
npm i git://github.com/github/eslint-plugin-github.git#kh-add-a11y --save
(^today I learned how to install a package from a GitHub branch!!!)
I see the lint error show up as expected in my editor!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕺 ! YAY thanks for checking
@@ -0,0 +1,10 @@ | |||
module.exports = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I should distinguish this config as being accessibility rules for react....like github/jsx-a11y
. (We don't currently have any other React rules so it's currently just github/react
.)
thoughts? @github/accessibility-reviewers . also open to other suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for future rules github/react is kinda nice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like having a11y-specific rules! But if it's too early to make that distinction until there are more react rules & accessibility rules, I am fine with this for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not sure either... I'm down to keep this for now and revisit later!
Hi 👋 This is ready for review. @github/web-systems-reviewers. I plan to follow up on this with a separate PR where we introduce a config that allows mapping Primer components to a tag, allowing them to be linted. So ultimately we want this lint to also catch |
@@ -0,0 +1,68 @@ | |||
const {elementType, getProp, getPropValue} = require('jsx-ast-utils') | |||
|
|||
const bannedLinkText = ['read more', 'here', 'click here', 'learn more', 'more', 'here'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: 'here'
is in this list twice.
create(context) { | ||
return { | ||
JSXOpeningElement: node => { | ||
if (elementType(node) !== 'a') return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general we will probably use the Link
component from @primer/react
more often than raw anchor tags, and this check would miss those.
I don't think we can catch all of the possible cases just using a linter, but it might be more thorough to apply this check to any element with an href
prop. That will at least catch the cases where we have components that are thin wrappers around anchor tags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a follow up PR to address this lack of support for linting custom components. I'd love your feedback there -- #283.
Relates to: github/accessibility#1403 (GitHub staff only)
CC: @github/accessibility-reviewers too for any thoughts
Motivation
We want to start creating and sharing custom accessibility rules for React projects. While there is a
jsx-plugin-a11y
, GitHub also has some opinionated stances when it comes to accessibility which we want to codify with a linter.I noticed that GitHub already owns a couple open-source eslint repos so I decided to start adding accessibility rules in this repo rather than starting from scratch. I am thinking that non Primer-specific accessibility rules belong in this repo, while Primer-specific accessibility rules can go in eslint-plugin-primer-react. GitHub staff should check out the following links for more context:
Changes
I am trying to set up a foundation for more accessibility rules to be added and shared between GitHub React projects.
New accessibility rule
I am adding an accessibility rule that discourages use of generic link text in JSX elements. This is the equivalent of an existing ERB lint rule we have (avoid-generic-link-text-counter.md). We want to flag when a link element has an
aria-label
with generic link text, or when there is noaria-label
set but it has a text content of a generic link text.This is the first time I am writing an eslint rule so please review carefully.
New config
Should I name this to something specific to JSX accessibility linting like
jsx-a11y
so the config is:github/jsx-a11y
?Or is generic
react
fine?Note to reviewer 📣
I'm pretty new to eslint and eslint best practices so if any of this organization seems really funky, please let me know.
Also if you think accessibility rulesets should be organized in a different way or should be in its own repo talk to me! I am in spike phase right now and very open to suggestions/iteration.