Skip to content

Commit e481c3d

Browse files
Add template-no-autofocus-attribute rule implementation, tests, and docs
Co-authored-by: NullVoxPopuli <[email protected]>
1 parent b25ddd6 commit e481c3d

5 files changed

Lines changed: 158 additions & 0 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ rules in templates can be disabled with eslint directives with mustache or html
174174
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
175175
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
176176

177+
### Accessibility
178+
179+
| Name | Description | 💼 | 🔧 | 💡 |
180+
| :------------------------------------------------------------------------------- | :--------------------------- | :- | :- | :- |
181+
| [template-no-autofocus-attribute](docs/rules/template-no-autofocus-attribute.md) | disallow autofocus attribute | | 🔧 | |
182+
177183
### Best Practices
178184

179185
| Name | Description | 💼 | 🔧 | 💡 |
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# ember/template-no-autofocus-attribute
2+
3+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4+
5+
<!-- end auto-generated rule header -->
6+
7+
Disallows the use of `autofocus` attribute on elements.
8+
9+
The `autofocus` attribute can cause usability issues for both sighted and non-sighted users by disrupting expected behavior and screen reader announcements.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<input type="text" autofocus />
18+
</template>
19+
```
20+
21+
```gjs
22+
<template>
23+
<textarea autofocus></textarea>
24+
</template>
25+
```
26+
27+
Examples of **correct** code for this rule:
28+
29+
```gjs
30+
<template>
31+
<input type="text" />
32+
</template>
33+
```
34+
35+
```gjs
36+
<template>
37+
<textarea></textarea>
38+
</template>
39+
```
40+
41+
## When Not To Use It
42+
43+
If you need to autofocus for specific accessibility or UX requirements and have thoroughly tested with assistive technologies, you may disable this rule for those specific cases.
44+
45+
## References
46+
47+
- [ember-template-lint no-autofocus-attribute](https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/no-autofocus-attribute.md)
48+
- [MDN autofocus attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow autofocus attribute',
7+
category: 'Accessibility',
8+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-autofocus-attribute.md',
9+
},
10+
fixable: 'code',
11+
schema: [],
12+
messages: {
13+
noAutofocus:
14+
'Avoid using autofocus attribute. Autofocusing elements can cause usability issues for sighted and non-sighted users.',
15+
},
16+
},
17+
18+
create(context) {
19+
return {
20+
GlimmerElementNode(node) {
21+
const autofocusAttr = node.attributes?.find((attr) => attr.name === 'autofocus');
22+
23+
if (autofocusAttr) {
24+
context.report({
25+
node: autofocusAttr,
26+
messageId: 'noAutofocus',
27+
fix(fixer) {
28+
// Remove the attribute including preceding whitespace
29+
const sourceCode = context.sourceCode;
30+
const text = sourceCode.getText();
31+
const attrStart = autofocusAttr.range[0];
32+
const attrEnd = autofocusAttr.range[1];
33+
34+
let removeStart = attrStart;
35+
while (removeStart > 0 && /\s/.test(text[removeStart - 1])) {
36+
removeStart--;
37+
}
38+
39+
return fixer.removeRange([removeStart, attrEnd]);
40+
},
41+
});
42+
}
43+
},
44+
};
45+
},
46+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
},
6161
"dependencies": {
6262
"@ember-data/rfc395-data": "^0.0.4",
63+
"@glimmer/env": "^0.1.7",
6364
"css-tree": "^3.0.1",
6465
"ember-eslint-parser": "^0.5.9",
6566
"ember-rfc176-data": "^0.3.18",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//------------------------------------------------------------------------------
2+
// Requirements
3+
//------------------------------------------------------------------------------
4+
5+
const rule = require('../../../lib/rules/template-no-autofocus-attribute');
6+
const RuleTester = require('eslint').RuleTester;
7+
8+
//------------------------------------------------------------------------------
9+
// Tests
10+
//------------------------------------------------------------------------------
11+
12+
const ruleTester = new RuleTester({
13+
parser: require.resolve('ember-eslint-parser'),
14+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
15+
});
16+
17+
ruleTester.run('template-no-autofocus-attribute', rule, {
18+
valid: [
19+
`<template>
20+
<input type="text" />
21+
</template>`,
22+
`<template>
23+
<button>Click me</button>
24+
</template>`,
25+
],
26+
27+
invalid: [
28+
{
29+
code: `<template>
30+
<input type="text" autofocus />
31+
</template>`,
32+
output: `<template>
33+
<input type="text"/>
34+
</template>`,
35+
errors: [
36+
{
37+
message:
38+
'Avoid using autofocus attribute. Autofocusing elements can cause usability issues for sighted and non-sighted users.',
39+
type: 'GlimmerAttrNode',
40+
},
41+
],
42+
},
43+
{
44+
code: `<template>
45+
<textarea autofocus></textarea>
46+
</template>`,
47+
output: `<template>
48+
<textarea></textarea>
49+
</template>`,
50+
errors: [
51+
{
52+
type: 'GlimmerAttrNode',
53+
},
54+
],
55+
},
56+
],
57+
});

0 commit comments

Comments
 (0)