Skip to content

Commit e55163d

Browse files
committed
Add new rule a11y-no-title-usage
1 parent 8441f8d commit e55163d

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

docs/rules/a11y-no-title-usage.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Rule Details
2+
3+
This rule aims to prevent the use of the `title` attribute with some components from `@primer/react`. The `title` attribute is not keyboard accessible, which results in accessibility issues. Instead, we should utilize alternatives that are accessible.
4+
5+
👎 Examples of **incorrect** code for this rule
6+
7+
```jsx
8+
import {RelativeTime} from '@primer/react'
9+
10+
<RelativeTime date={new Date('2020-01-01T00:00:00Z')} noTitle={false} />
11+
```
12+
13+
👍 Examples of **correct** code for this rule:
14+
15+
```jsx
16+
import {RelativeTime} from '@primer/react'
17+
18+
<RelativeTime date={new Date('2020-01-01T00:00:00Z')} />
19+
```
20+
21+
The `noTitle` attribute can be omitted because its default value is `true` internally.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const rule = require('../a11y-no-title-usage')
2+
const {RuleTester} = require('eslint')
3+
4+
const ruleTester = new RuleTester({
5+
languageOptions: {
6+
parserOptions: {
7+
ecmaVersion: 'latest',
8+
sourceType: 'module',
9+
ecmaFeatures: {
10+
jsx: true,
11+
},
12+
},
13+
},
14+
})
15+
16+
ruleTester.run('a11y-no-title-usage', rule, {
17+
valid: [
18+
`import {RelativeTime} from '@primer/react';
19+
<RelativeTime date={new Date('2020-01-01T00:00:00Z')} noTitle={true} />`,
20+
`import {RelativeTime} from '@primer/react';
21+
<RelativeTime date={new Date('2020-01-01T00:00:00Z')} noTitle />`,
22+
`import {RelativeTime} from '@primer/react';
23+
<RelativeTime date={new Date('2020-01-01T00:00:00Z')} />`,
24+
],
25+
invalid: [
26+
{
27+
code: `import {RelativeTime} from '@primer/react'; <RelativeTime date={new Date('2020-01-01T00:00:00Z')} noTitle={false} />`,
28+
output: `import {RelativeTime} from '@primer/react'; <RelativeTime date={new Date('2020-01-01T00:00:00Z')} />`,
29+
errors: [{messageId: 'noTitleOnRelativeTime'}],
30+
},
31+
],
32+
})

src/rules/a11y-no-title-usage.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const {getJSXOpeningElementAttribute} = require('../utils/get-jsx-opening-element-attribute')
2+
3+
module.exports = {
4+
meta: {
5+
type: 'error', // TODO: Confirm the type
6+
docs: {
7+
description: 'Disallow usage of title attribute on some components',
8+
recommended: true,
9+
url: null, // TODO: Add URL
10+
},
11+
messages: {
12+
noTitleOnRelativeTime: 'Avoid using the title attribute on RelativeTime.',
13+
},
14+
fixable: 'code',
15+
schema: [],
16+
},
17+
18+
create(context) {
19+
return {
20+
JSXOpeningElement(jsxNode) {
21+
const title = getJSXOpeningElementAttribute(jsxNode, 'noTitle')
22+
23+
if (title && title.value && title.value.expression && title.value.expression.value !== true) {
24+
context.report({
25+
node: title,
26+
messageId: 'noTitleOnRelativeTime',
27+
fix(fixer) {
28+
const start = title.range[0] - 1 // Accounts for whitespace
29+
const end = title.range[1]
30+
return fixer.removeRange([start, end])
31+
},
32+
})
33+
}
34+
},
35+
}
36+
},
37+
}

0 commit comments

Comments
 (0)