Skip to content

Commit 3d210bf

Browse files
committed
Extract rule: template-no-attrs-in-components
1 parent 3e664f5 commit 3d210bf

4 files changed

Lines changed: 119 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ rules in templates can be disabled with eslint directives with mustache or html
254254
| [no-old-shims](docs/rules/no-old-shims.md) | disallow usage of old shims for modules || 🔧 | |
255255
| [no-string-prototype-extensions](docs/rules/no-string-prototype-extensions.md) | disallow usage of `String` prototype extensions || | |
256256
| [template-no-action](docs/rules/template-no-action.md) | disallow {{action}} helper | | | |
257+
| [template-no-attrs-in-components](docs/rules/template-no-attrs-in-components.md) | disallow attrs in component templates | | | |
257258

258259
### Ember Data
259260

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ember/template-no-attrs-in-components
2+
3+
<!-- end auto-generated rule header -->
4+
5+
This rule prevents the usage of `attrs` property to access values passed to the component since all the values can be accessed directly from the template.
6+
7+
## Examples
8+
9+
This rule **forbids** the following:
10+
11+
```hbs
12+
{{attr.foo}}
13+
```
14+
15+
This rule **allows** the following:
16+
17+
```hbs
18+
{{foo}}
19+
```
20+
21+
or if you using Ember 3.1 and above:
22+
23+
```hbs
24+
{{@foo}}
25+
```
26+
27+
## References
28+
29+
- [rfcs/named args](https://github.com/emberjs/rfcs/blob/master/text/0276-named-args.md#motivation)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow attrs in component templates',
7+
category: 'Deprecations',
8+
strictGjs: true,
9+
strictGts: true,
10+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-attrs-in-components.md',
11+
},
12+
schema: [],
13+
messages: {
14+
noAttrs: 'Component templates should not contain `attrs`. Use `@arg` syntax instead.',
15+
noThisAttrs:
16+
'Component templates should not contain `this.attrs`. Use `@arg` syntax instead.',
17+
},
18+
},
19+
create(context) {
20+
return {
21+
GlimmerPathExpression(node) {
22+
if (node.original?.startsWith('attrs.') || node.original === 'attrs') {
23+
context.report({ node, messageId: 'noAttrs' });
24+
} else if (node.original?.startsWith('this.attrs.') || node.original === 'this.attrs') {
25+
context.report({ node, messageId: 'noThisAttrs' });
26+
}
27+
},
28+
};
29+
},
30+
};
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const rule = require('../../../lib/rules/template-no-attrs-in-components');
2+
const RuleTester = require('eslint').RuleTester;
3+
4+
const ruleTester = new RuleTester({
5+
parser: require.resolve('ember-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7+
});
8+
9+
ruleTester.run('template-no-attrs-in-components', rule, {
10+
valid: [
11+
'<template>{{@value}}</template>',
12+
'<template>{{this.value}}</template>',
13+
// Class component with normal this access
14+
`import Component from '@glimmer/component';
15+
class MyComponent extends Component {
16+
<template>{{this.args.name}}</template>
17+
}`,
18+
],
19+
invalid: [
20+
{
21+
code: '<template>{{attrs.value}}</template>',
22+
output: null,
23+
errors: [{ messageId: 'noAttrs' }],
24+
},
25+
{
26+
code: '<template>{{attrs}}</template>',
27+
output: null,
28+
errors: [{ messageId: 'noAttrs' }],
29+
},
30+
{
31+
code: '<template>{{this.attrs.value}}</template>',
32+
output: null,
33+
errors: [{ messageId: 'noThisAttrs' }],
34+
},
35+
{
36+
code: '<template>{{this.attrs}}</template>',
37+
output: null,
38+
errors: [{ messageId: 'noThisAttrs' }],
39+
},
40+
// Class component using this.attrs
41+
{
42+
code: `import Component from '@glimmer/component';
43+
class MyComponent extends Component {
44+
<template>{{this.attrs.name}}</template>
45+
}`,
46+
output: null,
47+
errors: [{ messageId: 'noThisAttrs' }],
48+
},
49+
// Class component using attrs
50+
{
51+
code: `import Component from '@glimmer/component';
52+
class MyComponent extends Component {
53+
<template>{{attrs.name}}</template>
54+
}`,
55+
output: null,
56+
errors: [{ messageId: 'noAttrs' }],
57+
},
58+
],
59+
});

0 commit comments

Comments
 (0)