Skip to content

Commit cc51b62

Browse files
authored
feat: role-supports-aria-props rule (no aria-label-misuse)
2 parents 3b7aefa + cd0a526 commit cc51b62

18 files changed

+1369
-83
lines changed

.devcontainer/devcontainer.json

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
22
// https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/javascript-node
33
{
4-
"name": "Node.js",
5-
"build": {
6-
"dockerfile": "Dockerfile",
7-
// Update 'VARIANT' to pick a Node version: 16, 14, 12.
8-
// Append -bullseye or -buster to pin to an OS version.
9-
// Use -bullseye variants on local arm64/Apple Silicon.
10-
"args": { "VARIANT": "16" }
11-
},
4+
"name": "Node.js",
5+
"build": {
6+
"dockerfile": "Dockerfile",
7+
// Update 'VARIANT' to pick a Node version: 16, 14, 12.
8+
// Append -bullseye or -buster to pin to an OS version.
9+
// Use -bullseye variants on local arm64/Apple Silicon.
10+
"args": {"VARIANT": "16"}
11+
},
1212

13-
// Set *default* container specific settings.json values on container create.
14-
"settings": {},
13+
// Set *default* container specific settings.json values on container create.
14+
"settings": {},
1515

16-
// Add the IDs of extensions you want installed when the container is created.
17-
"extensions": [
18-
"dbaeumer.vscode-eslint"
19-
],
16+
// Add the IDs of extensions you want installed when the container is created.
17+
"extensions": ["dbaeumer.vscode-eslint"],
2018

21-
// Use 'forwardPorts' to make a list of ports inside the container available locally.
22-
// "forwardPorts": [],
19+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
20+
// "forwardPorts": [],
2321

24-
// Use 'postCreateCommand' to run commands after the container is created.
25-
// "postCreateCommand": "yarn install",
22+
// Use 'postCreateCommand' to run commands after the container is created.
23+
// "postCreateCommand": "yarn install",
2624

27-
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
28-
"remoteUser": "node",
29-
"features": {
30-
"git": "latest"
31-
}
25+
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
26+
"remoteUser": "node",
27+
"features": {
28+
"git": "latest"
29+
}
3230
}

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
root: true,
33
parserOptions: {
4-
ecmaVersion: 2020,
4+
ecmaVersion: 13,
55
},
66
env: {
77
es6: true,

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ For each component, you may specify a `default` and/or `props`. `default` may ma
5454
"settings": {
5555
"github": {
5656
"components": {
57-
"Box": { "default": "p" },
58-
"Link": { "props": {"as": { "undefined": "a", "a": "a", "button": "button"}}},
57+
"Box": {"default": "p"},
58+
"Link": {"props": {"as": {"undefined": "a", "a": "a", "button": "button"}}}
5959
}
6060
}
6161
}
@@ -94,3 +94,4 @@ This config will be interpreted in the following way:
9494
#### Accessibility-focused rules (prefixed with a11y)
9595

9696
- [No Generic Link Text](./docs/rules/a11y-no-generic-link-text.md)
97+
- [Role Supports ARIA Props](./docs/rules/role-supports-aria-props.md)

docs/rules/a11y-no-generic-link-text.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,18 @@ Please perform browser tests and spot checks:
6363
```
6464

6565
```jsx
66-
<a href="github.com/about" aria-label="Why dogs are awesome">Read more</a>
66+
<a href="github.com/about" aria-label="Why dogs are awesome">
67+
Read more
68+
</a>
6769
```
6870

6971
```jsx
70-
<a href="github.com/about" aria-describedby="element123">Read more</a>
72+
<a href="github.com/about" aria-describedby="element123">
73+
Read more
74+
</a>
7175
```
7276

73-
### **Correct** code for this rule 👍
77+
### **Correct** code for this rule 👍
7478

7579
```jsx
7680
<a href="github.com/about">Learn more about GitHub</a>

docs/rules/array-foreach.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ for (const el of els) {
9393
```
9494

9595
Use [`entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries) to get access to the index:
96+
9697
```js
9798
for (const [i, el] of els.entries()) {
9899
el.name = `Element ${i}`

docs/rules/authenticity-token.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ on('click', '.js-my-button', function (e) {
3333

3434
fetch(form.action, {
3535
method: form.method,
36-
body: new FormData(form)
36+
body: new FormData(form),
3737
}).then(function () {
3838
alert('Success!')
3939
})
@@ -52,7 +52,7 @@ An alternate, but less preferred approach is to include the a signed CSRF url in
5252
on('click', '.js-my-button', function (e) {
5353
csrfRequest(this.getAttribute('data-url'), {
5454
method: 'PUT',
55-
body: data
55+
body: data,
5656
}).then(function () {
5757
alert('Success!')
5858
})

docs/rules/no-useless-passive.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ window.addEventListener(
2121
() => {
2222
console.log('Scroll event fired!')
2323
},
24-
{passive: true}
24+
{passive: true},
2525
)
2626
```
2727

docs/rules/prefer-observers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ window.addEventListener('scroll', () => {
3434
const isIntersecting = checkIfElementIntersects(
3535
element.getBoundingClientRect(),
3636
window.innerHeight,
37-
document.clientHeight
37+
document.clientHeight,
3838
)
3939
element.classList.toggle('intersecting', isIntersecting)
4040
})

docs/rules/require-passive-events.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ window.addEventListener(
2828
() => {
2929
/* ... */
3030
},
31-
{passive: true}
31+
{passive: true},
3232
)
3333
```
3434

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Role Supports ARIA Props
2+
3+
## Rule Details
4+
5+
This rule enforces that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`.
6+
7+
For example, this rule aims to discourage common misuse of the `aria-label` and `aria-labelledby` attribute. `aria-label` and `aria-labelledby` support is only guaranteed on interactive elements like `button` or `a`, or on static elements like `div` and `span` with a permitted `role`. This rule will allow `aria-label` and `aria-labelledby` usage on `div` and `span` elements if it set to a role other than the ones listed in [WSC: a list of ARIA roles which cannot be named](https://w3c.github.io/aria/#namefromprohibited). This rule will never permit usage of `aria-label` and `aria-labelledby` on `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `strong`, `i`, `p`, `b`, or `code`.
8+
9+
### "Help! I'm trying to set a tooltip on a static element and this rule flagged it!"
10+
11+
Please do not use tooltips on static elements. It is a highly discouraged, inaccessible pattern.
12+
See [Primer: Tooltip alternatives](https://primer.style/design/accessibility/tooltip-alternatives) for what to do instead.
13+
14+
### Resources
15+
16+
- [w3c/aria Consider prohibiting author naming certain roles #833](https://github.com/w3c/aria/issues/833)
17+
- [Not so short note on aria-label usage - Big Table Edition](https://html5accessibility.com/stuff/2020/11/07/not-so-short-note-on-aria-label-usage-big-table-edition/)
18+
- [Your tooltips are bogus](https://heydonworks.com/article/your-tooltips-are-bogus/)
19+
- [Primer: Tooltip alternatives](https://primer.style/design/accessibility/tooltip-alternatives)
20+
21+
### Disclaimer
22+
23+
There are conflicting resources and opinions on what elements should support these naming attributes. For now, this rule will operate under a relatively simple heuristic aimed to minimize false positives. This may have room for future improvements. Learn more at [W3C Name Calcluation](https://w3c.github.io/aria/#namecalculation).
24+
25+
### **Incorrect** code for this rule 👎
26+
27+
```erb
28+
<span class="tooltipped" aria-label="This is a tooltip">I am some text.</span>
29+
```
30+
31+
```erb
32+
<span aria-label="This is some content that will completely override the button content">Please be careful of the following.</span>
33+
```
34+
35+
```erb
36+
<div aria-labelledby="heading1">Goodbye</div>
37+
```
38+
39+
```erb
40+
<h1 aria-label="This will override the page title completely">Page title</h1>
41+
```
42+
43+
### **Correct** code for this rule 👍
44+
45+
```erb
46+
<button aria-label="Close">
47+
<svg src="closeIcon"></svg>
48+
</button>
49+
```
50+
51+
```erb
52+
<button aria-label="Bold" aria-describedby="tooltip1">
53+
<svg src="boldIcon"></svg>
54+
</button>
55+
<p id="tooltip1" class="tooltip">Add bold text or turn selection into bold text</p>
56+
```
57+
58+
```erb
59+
<span>Hello</span>
60+
```
61+
62+
```erb
63+
<div>Goodbye</div>
64+
```
65+
66+
```erb
67+
<h1>Page title</h1>
68+
```
69+
70+
```erb
71+
<div role="dialog" aria-labelledby="dialogHeading">
72+
<h1 id="dialogHeading">Heading</h1>
73+
</div>
74+
```

0 commit comments

Comments
 (0)