@angular-eslint/eslint-plugin-template 20.5.2 → 20.5.3-alpha.1
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/dist/rules/alt-text.d.ts +3 -0
- package/dist/rules/alt-text.d.ts.map +1 -1
- package/dist/rules/alt-text.js +4 -1
- package/dist/rules/attributes-order.d.ts +3 -0
- package/dist/rules/attributes-order.d.ts.map +1 -1
- package/dist/rules/attributes-order.js +4 -1
- package/dist/rules/banana-in-box.d.ts +3 -0
- package/dist/rules/banana-in-box.d.ts.map +1 -1
- package/dist/rules/banana-in-box.js +4 -1
- package/dist/rules/click-events-have-key-events.d.ts +3 -0
- package/dist/rules/click-events-have-key-events.d.ts.map +1 -1
- package/dist/rules/click-events-have-key-events.js +4 -1
- package/dist/rules/conditional-complexity.d.ts +3 -0
- package/dist/rules/conditional-complexity.d.ts.map +1 -1
- package/dist/rules/conditional-complexity.js +4 -1
- package/dist/rules/cyclomatic-complexity.d.ts +3 -0
- package/dist/rules/cyclomatic-complexity.d.ts.map +1 -1
- package/dist/rules/cyclomatic-complexity.js +4 -1
- package/dist/rules/elements-content.d.ts +3 -0
- package/dist/rules/elements-content.d.ts.map +1 -1
- package/dist/rules/elements-content.js +4 -1
- package/dist/rules/eqeqeq.d.ts +3 -0
- package/dist/rules/eqeqeq.d.ts.map +1 -1
- package/dist/rules/eqeqeq.js +4 -1
- package/dist/rules/i18n.d.ts +3 -0
- package/dist/rules/i18n.d.ts.map +1 -1
- package/dist/rules/i18n.js +4 -1
- package/dist/rules/interactive-supports-focus.d.ts +3 -0
- package/dist/rules/interactive-supports-focus.d.ts.map +1 -1
- package/dist/rules/interactive-supports-focus.js +4 -1
- package/dist/rules/label-has-associated-control.d.ts +3 -0
- package/dist/rules/label-has-associated-control.d.ts.map +1 -1
- package/dist/rules/label-has-associated-control.js +4 -1
- package/dist/rules/mouse-events-have-key-events.d.ts +3 -0
- package/dist/rules/mouse-events-have-key-events.d.ts.map +1 -1
- package/dist/rules/mouse-events-have-key-events.js +4 -1
- package/dist/rules/no-any.d.ts +3 -0
- package/dist/rules/no-any.d.ts.map +1 -1
- package/dist/rules/no-any.js +4 -1
- package/dist/rules/no-autofocus.d.ts +3 -0
- package/dist/rules/no-autofocus.d.ts.map +1 -1
- package/dist/rules/no-autofocus.js +4 -1
- package/dist/rules/no-call-expression.d.ts +3 -0
- package/dist/rules/no-call-expression.d.ts.map +1 -1
- package/dist/rules/no-call-expression.js +4 -1
- package/dist/rules/no-distracting-elements.d.ts +3 -0
- package/dist/rules/no-distracting-elements.d.ts.map +1 -1
- package/dist/rules/no-distracting-elements.js +4 -1
- package/dist/rules/no-duplicate-attributes.d.ts +3 -0
- package/dist/rules/no-duplicate-attributes.d.ts.map +1 -1
- package/dist/rules/no-duplicate-attributes.js +4 -1
- package/dist/rules/no-empty-control-flow.d.ts +3 -0
- package/dist/rules/no-empty-control-flow.d.ts.map +1 -1
- package/dist/rules/no-empty-control-flow.js +4 -1
- package/dist/rules/no-inline-styles.d.ts +3 -0
- package/dist/rules/no-inline-styles.d.ts.map +1 -1
- package/dist/rules/no-inline-styles.js +4 -1
- package/dist/rules/no-interpolation-in-attributes.d.ts +3 -0
- package/dist/rules/no-interpolation-in-attributes.d.ts.map +1 -1
- package/dist/rules/no-interpolation-in-attributes.js +4 -1
- package/dist/rules/no-nested-tags.d.ts +3 -0
- package/dist/rules/no-nested-tags.d.ts.map +1 -1
- package/dist/rules/no-nested-tags.js +4 -1
- package/dist/rules/no-positive-tabindex.d.ts +3 -0
- package/dist/rules/no-positive-tabindex.d.ts.map +1 -1
- package/dist/rules/no-positive-tabindex.js +4 -1
- package/dist/rules/prefer-at-else.d.ts +3 -0
- package/dist/rules/prefer-at-else.d.ts.map +1 -1
- package/dist/rules/prefer-at-else.js +4 -1
- package/dist/rules/prefer-at-empty.d.ts +3 -0
- package/dist/rules/prefer-at-empty.d.ts.map +1 -1
- package/dist/rules/prefer-at-empty.js +4 -1
- package/dist/rules/prefer-built-in-pipes.d.ts +3 -0
- package/dist/rules/prefer-built-in-pipes.d.ts.map +1 -1
- package/dist/rules/prefer-built-in-pipes.js +4 -1
- package/dist/rules/prefer-contextual-for-variables.d.ts +3 -0
- package/dist/rules/prefer-contextual-for-variables.d.ts.map +1 -1
- package/dist/rules/prefer-contextual-for-variables.js +4 -1
- package/dist/rules/prefer-control-flow.d.ts +3 -0
- package/dist/rules/prefer-control-flow.d.ts.map +1 -1
- package/dist/rules/prefer-control-flow.js +4 -1
- package/dist/rules/prefer-ngsrc.d.ts +3 -0
- package/dist/rules/prefer-ngsrc.d.ts.map +1 -1
- package/dist/rules/prefer-ngsrc.js +4 -1
- package/dist/rules/prefer-self-closing-tags.d.ts +3 -0
- package/dist/rules/prefer-self-closing-tags.d.ts.map +1 -1
- package/dist/rules/prefer-self-closing-tags.js +4 -1
- package/dist/rules/prefer-static-string-properties.d.ts +3 -0
- package/dist/rules/prefer-static-string-properties.d.ts.map +1 -1
- package/dist/rules/prefer-static-string-properties.js +4 -1
- package/dist/rules/prefer-template-literal.d.ts +3 -0
- package/dist/rules/prefer-template-literal.d.ts.map +1 -1
- package/dist/rules/prefer-template-literal.js +4 -1
- package/dist/rules/role-has-required-aria.d.ts +3 -0
- package/dist/rules/role-has-required-aria.d.ts.map +1 -1
- package/dist/rules/role-has-required-aria.js +4 -1
- package/dist/rules/table-scope.d.ts +3 -0
- package/dist/rules/table-scope.d.ts.map +1 -1
- package/dist/rules/table-scope.js +4 -1
- package/dist/rules/use-track-by-function.d.ts +3 -0
- package/dist/rules/use-track-by-function.d.ts.map +1 -1
- package/dist/rules/use-track-by-function.js +4 -1
- package/dist/rules/valid-aria.d.ts +3 -0
- package/dist/rules/valid-aria.d.ts.map +1 -1
- package/dist/rules/valid-aria.js +4 -1
- package/package.json +5 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
6
|
const DEFAULT_OPTIONS = {
|
|
@@ -101,3 +101,6 @@ function isNgStyle(name) {
|
|
|
101
101
|
function isStyleBound(keySpan) {
|
|
102
102
|
return keySpan?.details ? keySpan.details.includes('style.') : false;
|
|
103
103
|
}
|
|
104
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
105
|
+
rationale: 'Inline styles in templates (style attribute, ngStyle directive, or [style.property] bindings) make it difficult to maintain consistent styling across an application and can violate Content Security Policy (CSP) restrictions. Styles should be defined in component stylesheets or CSS classes where they can be managed centrally, reused, cached by browsers, and easily modified. Inline styles also mix presentation concerns with template structure, making templates harder to read. Using CSS classes with [class] or [ngClass] bindings provides the same dynamic styling capabilities while keeping styles organized and maintainable. This rule can be configured to allow ngStyle or style bindings if needed for specific use cases.',
|
|
106
|
+
};
|
|
@@ -5,4 +5,7 @@ export type MessageIds = 'noInterpolationInAttributes';
|
|
|
5
5
|
export declare const RULE_NAME = "no-interpolation-in-attributes";
|
|
6
6
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInterpolationInAttributes", Options, import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
7
|
export default _default;
|
|
8
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
9
|
+
rationale: string;
|
|
10
|
+
};
|
|
8
11
|
//# sourceMappingURL=no-interpolation-in-attributes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-interpolation-in-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-interpolation-in-attributes.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,2BAA2B,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACvD,eAAO,MAAM,SAAS,mCAAmC,CAAC;;AAY1D,wBAmFG"}
|
|
1
|
+
{"version":3,"file":"no-interpolation-in-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-interpolation-in-attributes.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,2BAA2B,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACvD,eAAO,MAAM,SAAS,mCAAmC,CAAC;;AAY1D,wBAmFG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
5
5
|
exports.RULE_NAME = 'no-interpolation-in-attributes';
|
|
6
6
|
const allowSubstringInterpolationDescription = `\
|
|
@@ -80,3 +80,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
80
80
|
};
|
|
81
81
|
},
|
|
82
82
|
});
|
|
83
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
84
|
+
rationale: 'Property binding syntax [attribute]="value" is more efficient and clearer than interpolation {{ value }} for setting attribute values in templates. Interpolation converts the expression to a string and then Angular parses it back, whereas property binding directly passes the value without string conversion. This makes property binding faster and avoids potential issues with type coercion. Property binding also makes it immediately obvious that the attribute value is dynamic rather than static. For substring interpolation (like alt="Image of {{ name }}"), the performance difference is minimal and interpolation may be more readable, so the rule can optionally allow these cases while still catching full interpolation patterns that should use property binding.',
|
|
85
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'noNestedTags';
|
|
|
3
3
|
export declare const RULE_NAME = "no-nested-tags";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noNestedTags", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=no-nested-tags.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-nested-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-tags.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;AAM1C,wBAqCG"}
|
|
1
|
+
{"version":3,"file":"no-nested-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-tags.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;AAM1C,wBAqCG;AAmBH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -48,3 +48,6 @@ function hasAncestorOfSameType(node) {
|
|
|
48
48
|
}
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
|
+
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.',
|
|
53
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'noPositiveTabindex' | 'suggestNonNegativeTabindex';
|
|
|
3
3
|
export declare const RULE_NAME = "no-positive-tabindex";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=no-positive-tabindex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-positive-tabindex.d.ts","sourceRoot":"","sources":["../../src/rules/no-positive-tabindex.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,oBAAoB,GAAG,4BAA4B,CAAC;AAC7E,eAAO,MAAM,SAAS,yBAAyB,CAAC;;AAEhD,wBAkDG"}
|
|
1
|
+
{"version":3,"file":"no-positive-tabindex.d.ts","sourceRoot":"","sources":["../../src/rules/no-positive-tabindex.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,oBAAoB,GAAG,4BAA4B,CAAC;AAC7E,eAAO,MAAM,SAAS,yBAAyB,CAAC;;AAEhD,wBAkDG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
6
|
const get_dom_elements_1 = require("../utils/get-dom-elements");
|
|
@@ -45,3 +45,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
45
45
|
};
|
|
46
46
|
},
|
|
47
47
|
});
|
|
48
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
49
|
+
rationale: 'Using positive tabindex values (like tabindex="1" or tabindex="5") disrupts the natural tab order and creates a confusing navigation experience. The natural tab order follows the DOM structure, which users expect. Positive tabindex values create a complex focus order where lower numbers are focused first, then tabindex="0" elements, then remaining interactive elements. This makes the tab order unpredictable and hard to maintain. Users with motor disabilities who rely on keyboard navigation will struggle with illogical focus orders. Instead, use tabindex="0" to add elements to the natural tab order, tabindex="-1" to remove them, and structure your DOM in a logical order. This is a WCAG Level A requirement.',
|
|
50
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'preferAtElse';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-at-else";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferAtElse", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-at-else.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-at-else.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-else.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;AAe1C,wBA+HG"}
|
|
1
|
+
{"version":3,"file":"prefer-at-else.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-else.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;AAe1C,wBA+HG;AAoGH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -190,3 +190,6 @@ function isNonEmptyLength(node) {
|
|
|
190
190
|
}
|
|
191
191
|
return false;
|
|
192
192
|
}
|
|
193
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
194
|
+
rationale: 'When two consecutive @if blocks test opposite conditions (like @if (isLoggedIn) and @if (!isLoggedIn)), the second should be replaced with @else for clarity and maintainability. Using @else makes it immediately obvious that exactly one of the two branches will execute, whereas two separate @if statements require readers to mentally verify that the conditions are opposites. The @else pattern is more concise, eliminates duplication, and prevents bugs that could occur if the conditions drift out of sync during maintenance. This rule automatically detects opposite conditions including negation (!), comparison operators (<, >, ==, !=, etc.), and special cases like array.length === 0 versus array.length > 0.',
|
|
195
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'preferAtEmpty';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-at-empty";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferAtEmpty", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-at-empty.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-at-empty.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-empty.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AACzC,eAAO,MAAM,SAAS,oBAAoB,CAAC;;AAE3C,wBAwaG"}
|
|
1
|
+
{"version":3,"file":"prefer-at-empty.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-empty.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AACzC,eAAO,MAAM,SAAS,oBAAoB,CAAC;;AAE3C,wBAwaG;AA2LH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -490,3 +490,6 @@ function getEmptyTestCollection(node) {
|
|
|
490
490
|
}
|
|
491
491
|
return undefined;
|
|
492
492
|
}
|
|
493
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
494
|
+
rationale: 'The @for loop has a built-in @empty block for displaying content when the collection is empty. Using this feature is clearer and more concise than separate @if blocks that check collection.length === 0 or collection.length > 0. When @if and @for blocks check the same collection, combining them with @empty eliminates duplication, reduces nesting, and makes the template intent immediately obvious. For example, @for (item of items) {...} @empty {No items} is more readable than @if (items.length > 0) { @for (item of items) {...} } @else {No items}. The @empty pattern is the idiomatic Angular way to handle empty collections and should be preferred wherever applicable.',
|
|
495
|
+
};
|
|
@@ -8,4 +8,7 @@ export type MessageIds = 'preferBuiltInPipes';
|
|
|
8
8
|
export declare const RULE_NAME = "prefer-built-in-pipes";
|
|
9
9
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferBuiltInPipes", Options, import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
10
|
export default _default;
|
|
11
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
12
|
+
rationale: string;
|
|
13
|
+
};
|
|
11
14
|
//# sourceMappingURL=prefer-built-in-pipes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-built-in-pipes.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-built-in-pipes.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC1C;CACF,CAAC;AASF,MAAM,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAC9C,eAAO,MAAM,SAAS,0BAA0B,CAAC;;AAEjD,wBA6EG"}
|
|
1
|
+
{"version":3,"file":"prefer-built-in-pipes.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-built-in-pipes.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC1C;CACF,CAAC;AASF,MAAM,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAC9C,eAAO,MAAM,SAAS,0BAA0B,CAAC;;AAEjD,wBA6EG;AAiBH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -88,3 +88,6 @@ function isDisallowedMethod(ast, disallowList) {
|
|
|
88
88
|
function getMethodName(ast) {
|
|
89
89
|
return (0, is_ast_with_name_1.isASTWithName)(ast) ? ast.name : 'unknown';
|
|
90
90
|
}
|
|
91
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
92
|
+
rationale: 'Angular provides built-in pipes for common string transformations (lowercase, uppercase, titlecase) that are more efficient than calling JavaScript methods directly in templates. Pipes are pure by default, meaning Angular only recalculates them when inputs change, whereas method calls in templates run on every change detection cycle. For example, {{ name.toLowerCase() }} runs toLowerCase() repeatedly during change detection, while {{ name | lowercase }} only transforms the string when name changes. Using pipes also makes templates more declarative and idiomatic. The rule can be configured to allow method calls in event handlers like (click) where purity is not a concern. By default, the rule flags toLowerCase, toUpperCase, toLocaleLowerCase, and toLocaleUpperCase, but can be extended to other methods.',
|
|
93
|
+
};
|
|
@@ -14,4 +14,7 @@ export type MessageIds = 'preferContextualVariable' | 'preferCount' | 'preferFir
|
|
|
14
14
|
export declare const RULE_NAME = "prefer-contextual-for-variables";
|
|
15
15
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
16
16
|
export default _default;
|
|
17
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
18
|
+
rationale: string;
|
|
19
|
+
};
|
|
17
20
|
//# sourceMappingURL=prefer-contextual-for-variables.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-contextual-for-variables.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-contextual-for-variables.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,cAAc,CAAC,EAAE;YACxB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,0BAA0B,GAC1B,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,WAAW,CAAC;AAChB,eAAO,MAAM,SAAS,oCAAoC,CAAC;;AAc3D,wBAkaG"}
|
|
1
|
+
{"version":3,"file":"prefer-contextual-for-variables.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-contextual-for-variables.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,cAAc,CAAC,EAAE;YACxB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,0BAA0B,GAC1B,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,WAAW,CAAC;AAChB,eAAO,MAAM,SAAS,oCAAoC,CAAC;;AAc3D,wBAkaG;AAyOH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const are_equivalent_asts_1 = require("../utils/are-equivalent-asts");
|
|
@@ -549,3 +549,6 @@ function isTwo(node) {
|
|
|
549
549
|
function isLiteralNumber(node, value) {
|
|
550
550
|
return node instanceof bundled_angular_compiler_1.LiteralPrimitive && node.value === value;
|
|
551
551
|
}
|
|
552
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
553
|
+
rationale: 'Angular\'s @for loop provides built-in contextual variables ($index, $count, $first, $last, $even, $odd) that are more efficient and clearer than manual calculations. Using these variables eliminates redundant logic like @for (item of items; let i = $index) { @if (i === 0) } when $first would suffice. The built-in variables are optimized by Angular and make template intent explicit. For example, $first immediately communicates "first item in the loop" whereas i === 0 requires mental translation. Similarly, using $even/$odd is clearer than i % 2 === 0 for alternating row styling. The rule can be configured to allow specific custom alias names if your team has established naming conventions, but by default encourages using Angular\'s standard contextual variables for consistency across the ecosystem.',
|
|
554
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'preferControlFlow';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-control-flow";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferControlFlow", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-control-flow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-control-flow.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-control-flow.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAC7C,eAAO,MAAM,SAAS,wBAAwB,CAAC;;AAE/C,wBA+BG"}
|
|
1
|
+
{"version":3,"file":"prefer-control-flow.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-control-flow.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAC7C,eAAO,MAAM,SAAS,wBAAwB,CAAC;;AAE/C,wBA+BG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
6
|
exports.RULE_NAME = 'prefer-control-flow';
|
|
@@ -31,3 +31,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
31
31
|
};
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
35
|
+
rationale: 'Angular v17 introduced built-in control flow (@if, @for, @switch) as a replacement for the structural directives (*ngIf, *ngFor, *ngSwitch). The new syntax is more readable, performant, and type-safe. Built-in control flow has better syntax highlighting in editors, clearer nesting behavior, built-in features like @empty for loops and @else for conditionals, and improved tree-shaking. The new syntax also enables better compile-time optimizations and runtime performance. While the old structural directives remain supported for backward compatibility, new code should use the modern built-in control flow. Teams migrating to v17+ are encouraged to adopt this syntax for consistency and to benefit from ongoing performance improvements.',
|
|
36
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'missingAttribute' | 'invalidDoubleSource';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-ngsrc";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-ngsrc.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-ngsrc.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-ngsrc.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AACpE,eAAO,MAAM,SAAS,iBAAiB,CAAC;;AAExC,wBA4CG"}
|
|
1
|
+
{"version":3,"file":"prefer-ngsrc.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-ngsrc.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AACpE,eAAO,MAAM,SAAS,iBAAiB,CAAC;;AAExC,wBA4CG;AAqDH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -70,3 +70,6 @@ function isDataStringPrimitive(primitive) {
|
|
|
70
70
|
typeof primitive.value === 'string' &&
|
|
71
71
|
primitive.value.trim().startsWith('data:'));
|
|
72
72
|
}
|
|
73
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
74
|
+
rationale: "The ngSrc directive (part of Angular's Image directive introduced in v15) provides significant performance and user experience benefits over the standard src attribute for images. Using ngSrc enables automatic lazy loading, responsive images with srcset generation, optimized loading priority hints, prevention of layout shift by enforcing width and height attributes, and automatic image optimization when using an image loader. These features dramatically improve Largest Contentful Paint (LCP) and other Core Web Vitals metrics. The directive also provides warnings for common mistakes like missing width/height. The rule allows data: URIs with src since those are inline base64 images that don't benefit from ngSrc optimizations. For best performance and user experience, all external images should use ngSrc.",
|
|
75
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'preferSelfClosingTags';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-self-closing-tags";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferSelfClosingTags", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-self-closing-tags.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-self-closing-tags.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-self-closing-tags.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,uBAAuB,CAAC;AACjD,eAAO,MAAM,SAAS,6BAA6B,CAAC;;AAEpD,wBA+JG"}
|
|
1
|
+
{"version":3,"file":"prefer-self-closing-tags.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-self-closing-tags.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,uBAAuB,CAAC;AACjD,eAAO,MAAM,SAAS,6BAA6B,CAAC;;AAEpD,wBA+JG;AAuCH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -166,3 +166,6 @@ function getClosingTagPrefix(openingTagLastChar) {
|
|
|
166
166
|
const hasOwnWhitespace = openingTagLastChar.trim() === '';
|
|
167
167
|
return hasOwnWhitespace ? '' : ' ';
|
|
168
168
|
}
|
|
169
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
170
|
+
rationale: 'Self-closing tags like <app-component /> are more concise and eliminate visual clutter when elements have no content. This pattern is familiar from HTML void elements (like <img /> and <br />) and from JSX/React. Using self-closing syntax makes it immediately obvious that an element is empty, whereas <app-component></app-component> requires scanning to the closing tag to confirm there is no content. The shorter syntax also reduces the chance of accidentally nesting content where none was intended. Angular v15.1+ supports self-closing tags for components and structural elements. The rule automatically skips native HTML elements (div, span, etc.) and index.html files since browser support varies. For Angular components and directives, self-closing tags improve template readability.',
|
|
171
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'preferStaticStringProperties';
|
|
|
3
3
|
export declare const RULE_NAME = "prefer-static-string-properties";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferStaticStringProperties", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=prefer-static-string-properties.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-static-string-properties.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-static-string-properties.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,8BAA8B,CAAC;AACxD,eAAO,MAAM,SAAS,oCAAoC,CAAC;;AAE3D,wBA0DG"}
|
|
1
|
+
{"version":3,"file":"prefer-static-string-properties.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-static-string-properties.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,8BAA8B,CAAC;AACxD,eAAO,MAAM,SAAS,oCAAoC,CAAC;;AAE3D,wBA0DG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -48,3 +48,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
48
48
|
};
|
|
49
49
|
},
|
|
50
50
|
});
|
|
51
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
52
|
+
rationale: 'When binding a static string literal to a property, using attribute syntax (property="value") is more efficient and simpler than property binding syntax ([property]="\'value\'"). Property binding with a static string creates unnecessary overhead because Angular evaluates it as an expression during change detection, even though the value never changes. Attribute syntax makes it immediately clear that the value is static and will never be updated. For example, [alt]="\'Profile image\'" should be alt="Profile image". This rule helps identify performance opportunities and makes templates more readable by distinguishing truly dynamic bindings from static values. The rule excludes animation bindings (@xxx), style/class sub-properties (style.color), and structural directives (*ngIf) where property binding syntax is required.',
|
|
53
|
+
};
|
|
@@ -4,4 +4,7 @@ export type MessageIds = typeof messageId;
|
|
|
4
4
|
export declare const RULE_NAME = "prefer-template-literal";
|
|
5
5
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferTemplateLiteral", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
6
6
|
export default _default;
|
|
7
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
8
|
+
rationale: string;
|
|
9
|
+
};
|
|
7
10
|
//# sourceMappingURL=prefer-template-literal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAkBA,QAAA,MAAM,SAAS,0BAA0B,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,OAAO,SAAS,CAAC;AAC1C,eAAO,MAAM,SAAS,4BAA4B,CAAC;;AAEnD,wBAsKG"}
|
|
1
|
+
{"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAkBA,QAAA,MAAM,SAAS,0BAA0B,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,OAAO,SAAS,CAAC;AAC1C,eAAO,MAAM,SAAS,4BAA4B,CAAC;;AAEnD,wBAsKG;AAkJH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -219,3 +219,6 @@ function getRightSideFixesForParenthesized(fixer, innerExpression, parenthesized
|
|
|
219
219
|
fixer.replaceTextRange([innerEnd, parenthesizedEnd], `}${quote}`), // Replace closing paren with }quote
|
|
220
220
|
];
|
|
221
221
|
}
|
|
222
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
223
|
+
rationale: 'Template literals (backticks with ${} syntax) are more modern, readable, and maintainable than string concatenation with the + operator. String concatenation like "Hello " + name + "!" is harder to read and error-prone (easy to forget spaces or quotes) compared to the template literal `Hello ${name}!`. Template literals make string composition clearer, especially with multiple expressions. This is a widely accepted JavaScript/TypeScript best practice that should be followed in Angular templates for consistency. Angular templates have supported template literal syntax since v19.2. Using template literals throughout your codebase creates a consistent style and makes complex string building much more readable.',
|
|
224
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'roleHasRequiredAria' | 'suggestRemoveRole';
|
|
|
3
3
|
export declare const RULE_NAME = "role-has-required-aria";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=role-has-required-aria.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-has-required-aria.d.ts","sourceRoot":"","sources":["../../src/rules/role-has-required-aria.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;AACrE,eAAO,MAAM,SAAS,2BAA2B,CAAC;;AAElD,wBAkFG"}
|
|
1
|
+
{"version":3,"file":"role-has-required-aria.d.ts","sourceRoot":"","sources":["../../src/rules/role-has-required-aria.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;AACrE,eAAO,MAAM,SAAS,2BAA2B,CAAC;;AAElD,wBAkFG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const aria_query_1 = require("aria-query");
|
|
6
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
@@ -75,3 +75,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
75
75
|
};
|
|
76
76
|
},
|
|
77
77
|
});
|
|
78
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
79
|
+
rationale: 'ARIA roles define what an element is and how it should behave for assistive technologies, but many roles require specific ARIA properties to be meaningful and functional. For example, a role="slider" must have aria-valuemin, aria-valuemax, and aria-valuenow to communicate its state to screen readers. Without these required properties, the role is incomplete and may confuse or mislead users of assistive technologies. The ARIA specification defines which properties are required for each role, and this rule enforces those requirements based on the official aria-query library. Ensuring required ARIA properties are present is critical for making interactive elements accessible. This is a WCAG Level A requirement for proper ARIA implementation.',
|
|
80
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'tableScope';
|
|
|
3
3
|
export declare const RULE_NAME = "table-scope";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"tableScope", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=table-scope.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-scope.d.ts","sourceRoot":"","sources":["../../src/rules/table-scope.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC;AACtC,eAAO,MAAM,SAAS,gBAAgB,CAAC;;AAEvC,wBA8CG"}
|
|
1
|
+
{"version":3,"file":"table-scope.d.ts","sourceRoot":"","sources":["../../src/rules/table-scope.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC;AACtC,eAAO,MAAM,SAAS,gBAAgB,CAAC;;AAEvC,wBA8CG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
6
|
const get_dom_elements_1 = require("../utils/get-dom-elements");
|
|
@@ -43,3 +43,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
43
43
|
};
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
47
|
+
rationale: 'The scope attribute on table headers (<th>) tells screen readers whether a header applies to a column or row, enabling more efficient table navigation. When screen reader users navigate table cells, the screen reader announces the associated headers. Without proper scope attributes, users must manually explore the table structure to understand what each cell represents. Use scope="col" for column headers and scope="row" for row headers. For simple tables, screen readers can often infer the scope, but explicit scope attributes ensure reliable accessibility across all screen readers.',
|
|
48
|
+
};
|
|
@@ -5,4 +5,7 @@ export type MessageIds = 'useTrackByFunction';
|
|
|
5
5
|
export declare const RULE_NAME = "use-track-by-function";
|
|
6
6
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"useTrackByFunction", Options, import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
7
|
export default _default;
|
|
8
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
9
|
+
rationale: string;
|
|
10
|
+
};
|
|
8
11
|
//# sourceMappingURL=use-track-by-function.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-track-by-function.d.ts","sourceRoot":"","sources":["../../src/rules/use-track-by-function.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAC9C,eAAO,MAAM,SAAS,0BAA0B,CAAC;;AAIjD,wBAyEG"}
|
|
1
|
+
{"version":3,"file":"use-track-by-function.d.ts","sourceRoot":"","sources":["../../src/rules/use-track-by-function.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAC9C,eAAO,MAAM,SAAS,0BAA0B,CAAC;;AAIjD,wBAyEG;AAUH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
6
|
exports.RULE_NAME = 'use-track-by-function';
|
|
@@ -74,3 +74,6 @@ function isNgForTrackByFactory(alias) {
|
|
|
74
74
|
const names = [...alias, DEFAULT_NG_FOR_TRACK_BY_ATTRIBUTE_NAME];
|
|
75
75
|
return (attribute) => names.includes(attribute.name);
|
|
76
76
|
}
|
|
77
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
78
|
+
rationale: "When using *ngFor to render lists, Angular needs to track which items are added, removed, or moved to efficiently update the DOM. Without a trackBy function, Angular tracks items by object identity, meaning any change to the array (like sorting, filtering, or fetching fresh data from an API) causes Angular to destroy and recreate all DOM elements, even for items that haven't changed. This is inefficient and causes problems like: (1) poor performance with large lists, (2) loss of component state (like form input values), and (3) loss of CSS animations or focus. A trackBy function tells Angular how to identify unique items (usually by an id property), allowing Angular to reuse DOM elements for unchanged items. Use trackBy for all lists, especially those that update frequently or contain components with state.",
|
|
79
|
+
};
|
|
@@ -3,4 +3,7 @@ export type MessageIds = 'validAria' | 'validAriaValue' | 'suggestRemoveInvalidA
|
|
|
3
3
|
export declare const RULE_NAME = "valid-aria";
|
|
4
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
export default _default;
|
|
6
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
7
|
+
rationale: string;
|
|
8
|
+
};
|
|
6
9
|
//# sourceMappingURL=valid-aria.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valid-aria.d.ts","sourceRoot":"","sources":["../../src/rules/valid-aria.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,gBAAgB,GAChB,0BAA0B,CAAC;AAC/B,eAAO,MAAM,SAAS,eAAe,CAAC;;AAEtC,wBA8EG"}
|
|
1
|
+
{"version":3,"file":"valid-aria.d.ts","sourceRoot":"","sources":["../../src/rules/valid-aria.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,gBAAgB,GAChB,0BAA0B,CAAC;AAC/B,eAAO,MAAM,SAAS,eAAe,CAAC;;AAEtC,wBA8EG;AA0FH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
package/dist/rules/valid-aria.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RULE_NAME = void 0;
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
6
6
|
const aria_query_1 = require("aria-query");
|
|
@@ -134,3 +134,6 @@ function isValidAriaPropertyValue({ allowundefined, type, values }, attributeVal
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
138
|
+
rationale: "ARIA (Accessible Rich Internet Applications) attributes must be valid and used correctly for screen readers to interpret them. Using invalid or misspelled ARIA attributes (like 'aria-labeledby' instead of 'aria-labelledby', or using ARIA attributes that don't exist) causes screen readers to ignore them, breaking accessibility. Each HTML element only supports specific ARIA attributes based on its role. Invalid ARIA is worse than no ARIA because it gives developers false confidence that they've made something accessible when they haven't. Use a reference like the ARIA specification or MDN to verify attribute names and valid usage.",
|
|
139
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/eslint-plugin-template",
|
|
3
|
-
"version": "20.5.
|
|
3
|
+
"version": "20.5.3-alpha.1",
|
|
4
4
|
"description": "ESLint plugin for Angular Templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,19 +20,19 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"aria-query": "5.3.2",
|
|
22
22
|
"axobject-query": "4.1.0",
|
|
23
|
-
"@angular-eslint/
|
|
24
|
-
"@angular-eslint/
|
|
23
|
+
"@angular-eslint/utils": "20.5.3-alpha.1",
|
|
24
|
+
"@angular-eslint/bundled-angular-compiler": "20.5.3-alpha.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/aria-query": "5.0.4",
|
|
28
|
-
"@angular-eslint/test-utils": "20.5.
|
|
28
|
+
"@angular-eslint/test-utils": "20.5.3-alpha.1"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@typescript-eslint/types": "^7.11.0 || ^8.0.0",
|
|
32
32
|
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
|
|
33
33
|
"eslint": "^8.57.0 || ^9.0.0",
|
|
34
34
|
"typescript": "*",
|
|
35
|
-
"@angular-eslint/template-parser": "20.5.
|
|
35
|
+
"@angular-eslint/template-parser": "20.5.3-alpha.1"
|
|
36
36
|
},
|
|
37
37
|
"gitHead": "e2006e5e9c99e5a943d1a999e0efa5247d29ec24"
|
|
38
38
|
}
|