Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9cc41d8

Browse files
authored
Merge branch 'main' into kh-bump-aria-query
2 parents 9136431 + efe4c95 commit 9cc41d8

13 files changed

+484
-108
lines changed

README.md

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ _Note: This is experimental and subject to change._
4747

4848
The `react` config includes rules which target specific HTML elements. You may provide a mapping of custom components to an HTML element in your `eslintrc` configuration to increase linter coverage.
4949

50-
For each component, you may specify a `default` and/or `props`. `default` may make sense if there's a 1:1 mapping between a component and an HTML element. However, if the HTML output of a component is dependent on a prop value, you can provide a mapping using the `props` key. To minimize conflicts and complexity, this currently only supports the mapping of a single prop type.
50+
By default, these eslint rules will check the "as" prop for underlying element changes. If your repo uses a different prop name for polymorphic components provide the prop name in your `eslintrc` configuration under `polymorphicPropName`.
5151

5252
```json
5353
{
5454
"settings": {
5555
"github": {
56+
"polymorphicPropName": "asChild",
5657
"components": {
57-
"Box": {"default": "p"},
58-
"Link": {"props": {"as": {"undefined": "a", "a": "a", "button": "button"}}}
58+
"Box": "p",
59+
"Link": "a"
5960
}
6061
}
6162
}
@@ -66,9 +67,7 @@ This config will be interpreted in the following way:
6667

6768
- All `<Box>` elements will be treated as a `p` element type.
6869
- `<Link>` without a defined `as` prop will be treated as a `a`.
69-
- `<Link as='a'>` will treated as an `a` element type.
7070
- `<Link as='button'>` will be treated as a `button` element type.
71-
- `<Link as='summary'>` will be treated as the raw `Link` type because there is no configuration set for `as='summary'`.
7271

7372
### Rules
7473

@@ -82,28 +81,30 @@ This config will be interpreted in the following way:
8281
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
8382
❌ Deprecated.
8483

85-
| Name                              | Description | 💼 | 🔧 ||
86-
| :----------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
87-
| [a11y-aria-label-is-well-formatted](docs/rules/a11y-aria-label-is-well-formatted.md) | [aria-label] text should be formatted as you would visual text. | ⚛️ | | |
88-
| [a11y-no-generic-link-text](docs/rules/a11y-no-generic-link-text.md) | disallow generic link text | | ||
89-
| [array-foreach](docs/rules/array-foreach.md) | enforce `for..of` loops over `Array.forEach` || | |
90-
| [async-currenttarget](docs/rules/async-currenttarget.md) | disallow `event.currentTarget` calls inside of async functions | 🔍 | | |
91-
| [async-preventdefault](docs/rules/async-preventdefault.md) | disallow `event.preventDefault` calls inside of async functions | 🔍 | | |
92-
| [authenticity-token](docs/rules/authenticity-token.md) | disallow usage of CSRF tokens in JavaScript | 🔐 | | |
93-
| [get-attribute](docs/rules/get-attribute.md) | disallow wrong usage of attribute names | 🔍 | 🔧 | |
94-
| [js-class-name](docs/rules/js-class-name.md) | enforce a naming convention for js- prefixed classes | 🔐 | | |
95-
| [no-blur](docs/rules/no-blur.md) | disallow usage of `Element.prototype.blur()` | 🔍 | | |
96-
| [no-d-none](docs/rules/no-d-none.md) | disallow usage the `d-none` CSS class | 🔐 | | |
97-
| [no-dataset](docs/rules/no-dataset.md) | enforce usage of `Element.prototype.getAttribute` instead of `Element.prototype.datalist` | 🔍 | | |
98-
| [no-dynamic-script-tag](docs/rules/no-dynamic-script-tag.md) | disallow creating dynamic script tags || | |
99-
| [no-implicit-buggy-globals](docs/rules/no-implicit-buggy-globals.md) | disallow implicit global variables || | |
100-
| [no-inner-html](docs/rules/no-inner-html.md) | disallow `Element.prototype.innerHTML` in favor of `Element.prototype.textContent` | 🔍 | | |
101-
| [no-innerText](docs/rules/no-innerText.md) | disallow `Element.prototype.innerText` in favor of `Element.prototype.textContent` | 🔍 | 🔧 | |
102-
| [no-then](docs/rules/no-then.md) | enforce using `async/await` syntax over Promises || | |
103-
| [no-useless-passive](docs/rules/no-useless-passive.md) | disallow marking a event handler as passive when it has no effect | 🔍 | 🔧 | |
104-
| [prefer-observers](docs/rules/prefer-observers.md) | disallow poorly performing event listeners | 🔍 | | |
105-
| [require-passive-events](docs/rules/require-passive-events.md) | enforce marking high frequency event handlers as passive | 🔍 | | |
106-
| [role-supports-aria-props](docs/rules/role-supports-aria-props.md) | Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`. | ⚛️ | | |
107-
| [unescaped-html-literal](docs/rules/unescaped-html-literal.md) | disallow unescaped HTML literals | 🔍 | | |
84+
| Name                                        | Description | 💼 | 🔧 ||
85+
| :------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
86+
| [a11y-aria-label-is-well-formatted](docs/rules/a11y-aria-label-is-well-formatted.md) | [aria-label] text should be formatted as you would visual text. | ⚛️ | | |
87+
| [a11y-no-generic-link-text](docs/rules/a11y-no-generic-link-text.md) | disallow generic link text | | ||
88+
| [a11y-no-visually-hidden-interactive-element](docs/rules/a11y-no-visually-hidden-interactive-element.md) | Ensures that interactive elements are not visually hidden | ⚛️ | | |
89+
| [a11y-svg-has-accessible-name](docs/rules/a11y-svg-has-accessible-name.md) | SVGs must have an accessible name | ⚛️ | | |
90+
| [array-foreach](docs/rules/array-foreach.md) | enforce `for..of` loops over `Array.forEach` || | |
91+
| [async-currenttarget](docs/rules/async-currenttarget.md) | disallow `event.currentTarget` calls inside of async functions | 🔍 | | |
92+
| [async-preventdefault](docs/rules/async-preventdefault.md) | disallow `event.preventDefault` calls inside of async functions | 🔍 | | |
93+
| [authenticity-token](docs/rules/authenticity-token.md) | disallow usage of CSRF tokens in JavaScript | 🔐 | | |
94+
| [get-attribute](docs/rules/get-attribute.md) | disallow wrong usage of attribute names | 🔍 | 🔧 | |
95+
| [js-class-name](docs/rules/js-class-name.md) | enforce a naming convention for js- prefixed classes | 🔐 | | |
96+
| [no-blur](docs/rules/no-blur.md) | disallow usage of `Element.prototype.blur()` | 🔍 | | |
97+
| [no-d-none](docs/rules/no-d-none.md) | disallow usage the `d-none` CSS class | 🔐 | | |
98+
| [no-dataset](docs/rules/no-dataset.md) | enforce usage of `Element.prototype.getAttribute` instead of `Element.prototype.datalist` | 🔍 | | |
99+
| [no-dynamic-script-tag](docs/rules/no-dynamic-script-tag.md) | disallow creating dynamic script tags || | |
100+
| [no-implicit-buggy-globals](docs/rules/no-implicit-buggy-globals.md) | disallow implicit global variables || | |
101+
| [no-inner-html](docs/rules/no-inner-html.md) | disallow `Element.prototype.innerHTML` in favor of `Element.prototype.textContent` | 🔍 | | |
102+
| [no-innerText](docs/rules/no-innerText.md) | disallow `Element.prototype.innerText` in favor of `Element.prototype.textContent` | 🔍 | 🔧 | |
103+
| [no-then](docs/rules/no-then.md) | enforce using `async/await` syntax over Promises || | |
104+
| [no-useless-passive](docs/rules/no-useless-passive.md) | disallow marking a event handler as passive when it has no effect | 🔍 | 🔧 | |
105+
| [prefer-observers](docs/rules/prefer-observers.md) | disallow poorly performing event listeners | 🔍 | | |
106+
| [require-passive-events](docs/rules/require-passive-events.md) | enforce marking high frequency event handlers as passive | 🔍 | | |
107+
| [role-supports-aria-props](docs/rules/role-supports-aria-props.md) | Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`. | ⚛️ | | |
108+
| [unescaped-html-literal](docs/rules/unescaped-html-literal.md) | disallow unescaped HTML literals | 🔍 | | |
108109

109110
<!-- end auto-generated rules list -->
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Ensures that interactive elements are not visually hidden (`github/a11y-no-visually-hidden-interactive-element`)
2+
3+
💼 This rule is enabled in the ⚛️ `react` config.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
## Rule Details
8+
9+
This rule guards against visually hiding interactive elements. If a sighted keyboard user navigates to an interactive element that is visually hidden they might become confused and assume that keyboard focus has been lost.
10+
11+
Note: we are not guarding against visually hidden `input` elements at this time. Some visually hidden inputs might cause a false positive (e.g. some file inputs).
12+
13+
### Why do we visually hide content?
14+
15+
Visually hiding content can be useful when you want to provide information specifically to screen reader users or other assitive technology users while keeping content hidden from sighted users.
16+
17+
Applying the following css will visually hide content while still making it accessible to screen reader users.
18+
19+
```css
20+
clip-path: inset(50%);
21+
height: 1px;
22+
overflow: hidden;
23+
position: absolute;
24+
white-space: nowrap;
25+
width: 1px;
26+
```
27+
28+
👎 Examples of **incorrect** code for this rule:
29+
30+
```jsx
31+
<button className="visually-hidden">Submit</button>
32+
```
33+
34+
```jsx
35+
<VisuallyHidden>
36+
<button>Submit</button>
37+
</VisuallyHidden>
38+
```
39+
40+
```jsx
41+
<VisuallyHidden as="button">Submit</VisuallyHidden>
42+
```
43+
44+
👍 Examples of **correct** code for this rule:
45+
46+
```jsx
47+
<h2 className="visually-hidden">Welcome to GitHub</h2>
48+
```
49+
50+
```jsx
51+
<VisuallyHidden>
52+
<h2>Welcome to GitHub</h2>
53+
</VisuallyHidden>
54+
```
55+
56+
```jsx
57+
<VisuallyHidden as="h2">Welcome to GitHub</VisuallyHidden>
58+
```
59+
60+
## Options
61+
62+
- className - A css className that visually hides content. Defaults to `sr-only`.
63+
- componentName - A react component name that visually hides content. Defaults to `VisuallyHidden`.
64+
- htmlPropName - A prop name used to replace the semantic element that is rendered. Defaults to `as`.
65+
66+
```json
67+
{
68+
"a11y-no-visually-hidden-interactive-element": [
69+
"error",
70+
{
71+
"className": "visually-hidden",
72+
"componentName": "VisuallyHidden",
73+
"htmlPropName": "as"
74+
}
75+
]
76+
}
77+
```
78+
79+
## Version
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# SVGs must have an accessible name (`github/a11y-svg-has-accessible-name`)
2+
3+
💼 This rule is enabled in the ⚛️ `react` config.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
## Rule Details
8+
9+
An `<svg>` must have an accessible name. Set `aria-label` or `aria-labelledby`, or nest a `<title>` element as the first child of the `<svg>` element.
10+
11+
However, if the `<svg>` is purely decorative, hide it with `aria-hidden="true"` or `role="presentation"`.
12+
13+
## Resources
14+
15+
- [Accessible SVGs](https://css-tricks.com/accessible-svgs/)
16+
17+
## Examples
18+
19+
### **Incorrect** code for this rule 👎
20+
21+
```html
22+
<svg height='100' width='100'>
23+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
24+
</svg>
25+
```
26+
27+
```html
28+
<svg height='100' width='100' title='Circle with a black outline and red fill'>
29+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
30+
</svg>
31+
```
32+
33+
```html
34+
<svg height='100' width='100'>
35+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
36+
<title>Circle with a black outline and red fill</title>
37+
</svg>
38+
```
39+
40+
### **Correct** code for this rule 👍
41+
42+
```html
43+
<svg height='100' width='100'>
44+
<title>Circle with a black outline and red fill</title>
45+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
46+
</svg>
47+
```
48+
49+
```html
50+
<svg aria-label='Circle with a black outline and red fill' height='100' width='100'>
51+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
52+
</svg>
53+
```
54+
55+
```html
56+
<svg aria-labelledby='circle_text' height='100' width='100'>
57+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
58+
</svg>
59+
```
60+
61+
```html
62+
<svg aria-hidden='true' height='100' width='100'>
63+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
64+
</svg>
65+
```
66+
67+
```html
68+
<svg role='presentation' height='100' width='100'>
69+
<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red'/>
70+
</svg>
71+
```
72+
73+
## Version

lib/configs/react.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ module.exports = {
1010
rules: {
1111
'jsx-a11y/role-supports-aria-props': 'off', // Override with github/role-supports-aria-props until https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/910 is resolved
1212
'github/a11y-aria-label-is-well-formatted': 'error',
13+
'github/a11y-no-visually-hidden-interactive-element': 'error',
14+
'github/a11y-svg-has-accessible-name': 'error',
1315
'github/role-supports-aria-props': 'error',
1416
'jsx-a11y/no-aria-hidden-on-focusable': 'error',
1517
'jsx-a11y/no-autofocus': 'off',

lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module.exports = {
22
rules: {
3+
'a11y-no-visually-hidden-interactive-element': require('./rules/a11y-no-visually-hidden-interactive-element'),
34
'a11y-no-generic-link-text': require('./rules/a11y-no-generic-link-text'),
45
'a11y-aria-label-is-well-formatted': require('./rules/a11y-aria-label-is-well-formatted'),
6+
'a11y-svg-has-accessible-name': require('./rules/a11y-svg-has-accessible-name'),
57
'array-foreach': require('./rules/array-foreach'),
68
'async-currenttarget': require('./rules/async-currenttarget'),
79
'async-preventdefault': require('./rules/async-preventdefault'),

0 commit comments

Comments
 (0)