@angular-eslint/eslint-plugin-template 22.3.1-alpha.4 → 22.3.1-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/rules/no-nested-tags.d.ts.map +1 -1
- package/dist/rules/no-nested-tags.js +12 -1
- package/dist/rules/prefer-style-binding.d.ts +10 -0
- package/dist/rules/prefer-style-binding.d.ts.map +1 -0
- package/dist/rules/prefer-style-binding.js +35 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ The premade flat configs that combine these rules are provided by the umbrella [
|
|
|
72
72
|
| [`prefer-contextual-for-variables`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-contextual-for-variables.md) | Ensures that contextual variables are used in @for blocks where possible instead of aliasing them. | | :wrench: | | |
|
|
73
73
|
| [`prefer-control-flow`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-control-flow.md) | Ensures that the built-in control flow is used. | :white_check_mark: | | | |
|
|
74
74
|
| [`prefer-ngsrc`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-ngsrc.md) | Ensures ngSrc is used instead of src for img elements | | | :bulb: | |
|
|
75
|
+
| [`prefer-style-binding`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-style-binding.md) | Suggests using [style] bindings over ngStyle where applicable | | | | |
|
|
75
76
|
| [`prefer-template-literal`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-template-literal.md) | Ensure that template literals are used instead of concatenating strings or expressions. | | :wrench: | | |
|
|
76
77
|
| [`require-switch-default`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/require-switch-default.md) | Requires a `@default` block on every `@switch` to ensure all cases are handled. This is the template equivalent of the `@typescript-eslint/switch-exhaustiveness-check` rule. | | | | |
|
|
77
78
|
| [`role-has-required-aria`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/role-has-required-aria.md) | [Accessibility] Ensures elements with ARIA roles have all required properties for that role. | | | :bulb: | :accessibility: |
|
package/dist/index.d.ts
CHANGED
|
@@ -115,6 +115,9 @@ declare const _default: {
|
|
|
115
115
|
"prefer-static-string-properties": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferStaticStringProperties", import("./rules/prefer-static-string-properties").Options, import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
116
116
|
name: string;
|
|
117
117
|
};
|
|
118
|
+
"prefer-style-binding": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferStyleBinding", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
119
|
+
name: string;
|
|
120
|
+
};
|
|
118
121
|
"prefer-template-literal": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferTemplateLiteral", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
119
122
|
name: string;
|
|
120
123
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHA,kBA8CE"}
|
package/dist/index.js
CHANGED
|
@@ -71,6 +71,7 @@ const prefer_contextual_for_variables_1 = __importStar(require("./rules/prefer-c
|
|
|
71
71
|
const prefer_control_flow_1 = __importStar(require("./rules/prefer-control-flow"));
|
|
72
72
|
const prefer_self_closing_tags_1 = __importStar(require("./rules/prefer-self-closing-tags"));
|
|
73
73
|
const prefer_static_string_properties_1 = __importStar(require("./rules/prefer-static-string-properties"));
|
|
74
|
+
const prefer_style_binding_1 = __importStar(require("./rules/prefer-style-binding"));
|
|
74
75
|
const prefer_template_literal_1 = __importStar(require("./rules/prefer-template-literal"));
|
|
75
76
|
const require_switch_default_1 = __importStar(require("./rules/require-switch-default"));
|
|
76
77
|
const role_has_required_aria_1 = __importStar(require("./rules/role-has-required-aria"));
|
|
@@ -115,6 +116,7 @@ module.exports = {
|
|
|
115
116
|
[prefer_ngsrc_1.RULE_NAME]: prefer_ngsrc_1.default,
|
|
116
117
|
[prefer_self_closing_tags_1.RULE_NAME]: prefer_self_closing_tags_1.default,
|
|
117
118
|
[prefer_static_string_properties_1.RULE_NAME]: prefer_static_string_properties_1.default,
|
|
119
|
+
[prefer_style_binding_1.RULE_NAME]: prefer_style_binding_1.default,
|
|
118
120
|
[prefer_template_literal_1.RULE_NAME]: prefer_template_literal_1.default,
|
|
119
121
|
[require_switch_default_1.RULE_NAME]: require_switch_default_1.default,
|
|
120
122
|
[role_has_required_aria_1.RULE_NAME]: role_has_required_aria_1.default,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-nested-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-tags.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-nested-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-tags.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;;;AAM1C,wBAqCG;AAkCH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -40,6 +40,12 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
40
40
|
function hasAncestorOfSameType(node) {
|
|
41
41
|
let parent = node.parent;
|
|
42
42
|
while (parent) {
|
|
43
|
+
// Explicit <ng-template> is not rendered in-place, so tags inside it
|
|
44
|
+
// are not nested in the parent element's DOM. Structural directives
|
|
45
|
+
// like *ngFor compile to implicit templates and must still be reported.
|
|
46
|
+
if (isExplicitNgTemplate(parent)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
43
49
|
if (parent instanceof bundled_angular_compiler_1.TmplAstElement &&
|
|
44
50
|
parent.name.toLowerCase() === node.name.toLowerCase()) {
|
|
45
51
|
return true;
|
|
@@ -48,6 +54,11 @@ function hasAncestorOfSameType(node) {
|
|
|
48
54
|
}
|
|
49
55
|
return false;
|
|
50
56
|
}
|
|
57
|
+
function isExplicitNgTemplate(node) {
|
|
58
|
+
return (node instanceof bundled_angular_compiler_1.TmplAstTemplate &&
|
|
59
|
+
typeof node.tagName === 'string' &&
|
|
60
|
+
/^(:svg:)?ng-template$/i.test(node.tagName));
|
|
61
|
+
}
|
|
51
62
|
exports.RULE_DOCS_EXTENSION = {
|
|
52
|
-
rationale: "Nesting `<p>` tags inside other `<p>` tags, or `<a>` tags inside other `<a>` tags, is invalid HTML and causes serious issues with Angular hydration. All browsers automatically close the outer tag when they encounter the inner tag, transforming `<p>1<p>2</p>3</p>` into `<p>1</p><p>2</p>3` in the DOM. This creates a mismatch between the server-rendered HTML and what Angular expects during hydration, breaking incremental hydration and potentially causing runtime errors. The browser's automatic correction of invalid HTML happens before Angular processes the template, so Angular cannot fix or work around it. Always use different elements (like `<p>` and `<span>`, or nested `<div>` tags) or restructure your template to avoid nesting these specific tags.",
|
|
63
|
+
rationale: "Nesting `<p>` tags inside other `<p>` tags, or `<a>` tags inside other `<a>` tags, is invalid HTML and causes serious issues with Angular hydration. All browsers automatically close the outer tag when they encounter the inner tag, transforming `<p>1<p>2</p>3</p>` into `<p>1</p><p>2</p>3` in the DOM. This creates a mismatch between the server-rendered HTML and what Angular expects during hydration, breaking incremental hydration and potentially causing runtime errors. The browser's automatic correction of invalid HTML happens before Angular processes the template, so Angular cannot fix or work around it. Always use different elements (like `<p>` and `<span>`, or nested `<div>` tags) or restructure your template to avoid nesting these specific tags. Explicit `<ng-template>` elements are an exception because they are not rendered in-place; tags inside them are not nested in the parent element's DOM.",
|
|
53
64
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type MessageIds = 'preferStyleBinding';
|
|
2
|
+
export declare const RULE_NAME = "prefer-style-binding";
|
|
3
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferStyleBinding", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
4
|
+
name: string;
|
|
5
|
+
};
|
|
6
|
+
export default _default;
|
|
7
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
8
|
+
rationale: string;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=prefer-style-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-style-binding.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-style-binding.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAC9C,eAAO,MAAM,SAAS,yBAAyB,CAAC;;;;AAEhD,wBA4BG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
|
+
const utils_1 = require("@angular-eslint/utils");
|
|
5
|
+
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
|
+
exports.RULE_NAME = 'prefer-style-binding';
|
|
7
|
+
exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
8
|
+
name: exports.RULE_NAME,
|
|
9
|
+
meta: {
|
|
10
|
+
type: 'suggestion',
|
|
11
|
+
docs: {
|
|
12
|
+
description: 'Suggests using [style] bindings over ngStyle where applicable',
|
|
13
|
+
},
|
|
14
|
+
schema: [],
|
|
15
|
+
messages: {
|
|
16
|
+
preferStyleBinding: 'Consider using [style] or [style.property] bindings instead of [ngStyle] where applicable.',
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
const parserServices = (0, utils_1.getTemplateParserServices)(context);
|
|
22
|
+
return {
|
|
23
|
+
'BoundAttribute[name="ngStyle"]'(node) {
|
|
24
|
+
const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan);
|
|
25
|
+
context.report({
|
|
26
|
+
messageId: 'preferStyleBinding',
|
|
27
|
+
loc,
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
34
|
+
rationale: 'For simple cases, [style] and [style.property] bindings offer a more straightforward syntax with better performance than ngStyle, and the Angular style guide recommends them over the NgStyle directive. However, ngStyle should still be used when you need mutations on objects, as style bindings compare the bound object by reference and only apply updates when a new object instance is provided. Note that ngStyle also accepts unit suffixes on object keys (for example `{ "max-width.px": width }`), which [style] object bindings do not support; express these as [style.max-width.px] bindings instead. See https://angular.dev/style-guide#prefer-class-and-style-over-ngclass-and-ngstyle and https://angular.dev/guide/templates/binding#css-class-and-style-property-bindings for more information. This rule helps identify potential simplification opportunities but should be applied judiciously based on your specific needs.',
|
|
35
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/eslint-plugin-template",
|
|
3
|
-
"version": "22.3.1-alpha.
|
|
3
|
+
"version": "22.3.1-alpha.5",
|
|
4
4
|
"description": "ESLint plugin for Angular Templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@angular-eslint/bundled-angular-compiler": "22.3.1-alpha.
|
|
23
|
-
"@angular-eslint/utils": "22.3.1-alpha.
|
|
22
|
+
"@angular-eslint/bundled-angular-compiler": "22.3.1-alpha.5",
|
|
23
|
+
"@angular-eslint/utils": "22.3.1-alpha.5",
|
|
24
24
|
"aria-query": "5.3.2",
|
|
25
25
|
"axobject-query": "4.1.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@angular-eslint/test-utils": "22.3.1-alpha.
|
|
28
|
+
"@angular-eslint/test-utils": "22.3.1-alpha.5",
|
|
29
29
|
"@types/aria-query": "5.0.4"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@angular-eslint/template-parser": "22.3.1-alpha.
|
|
32
|
+
"@angular-eslint/template-parser": "22.3.1-alpha.5",
|
|
33
33
|
"@typescript-eslint/types": "^8.0.0",
|
|
34
34
|
"@typescript-eslint/utils": "^8.0.0",
|
|
35
35
|
"eslint": "^9.0.0 || ^10.0.0",
|