Skip to content

Commit 060e310

Browse files
rbell517rajsite
andauthored
Update @angular-eslint/template/i18n to ignore common nimble and sl-lib attributes (#140)
## Justification Update `@angular-eslint/template/i18n` to ignore common nimble and sl-lib attributes (and excludes tests of the name `*.spec.ts` with inline templates). fixes #83 ## Implementation A new file `template/options.js` is added to list all well-known attributes that should not be localized for using in NI javascript codebases. This includes common nimble attributes, systemlink-lib-angular attributes, and attributes from commonly used third-party libraries. This list is used to modify the `@angular-eslint/template/i18n` eslint rule to ignore any attribute in the list by default. If apps need to change this to ignore only nimble attributes, they have the option to do that by overriding the rule's config in their app's eslintrc. ## Testing - I have made modifications to the angular test project to include attributes on the two sample templates that should either be ignored or not ignored and verified the eslint rule modification is being correctly applied in each. - Added a test to verify custom attributes can be added to ignore lists by apps. --------- Co-authored-by: rajsite <[email protected]>
1 parent e7ee489 commit 060e310

14 files changed

+189
-12
lines changed

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ The goal of the smoke tests is basic validation that the eslint configurations c
4242
1. Create a fork of the repository.
4343
2. (optional, but recommended) On the Actions tab of your repository enable actions for the repo. This allows the tests to run in the branches of your fork.
4444
3. Create and edit a branch in your fork.
45-
4. Open a pull request to Nimble for the branch.
45+
4. Open a pull request to `@ni/javascript-styleguide` for the branch.
4646
- (optional, but recommended) While creating the pull request enable the "Allow edits and access to secrets by maintainers" option. This will allow maintainers to push small changes to the branch to resolve needed changes quicker.
4747
5. Create a beachball change file for your project by doing one of the following:
4848
1. Follow the [Beachball change file](#beachball-change-file) instructions below to create a change file and push to your branch.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Update @angular-eslint/template/i18n to ignore common nimble and sl-lib attributes",
4+
"packageName": "@ni/eslint-config-angular",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

packages/eslint-config-angular/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
"access": "public"
2828
},
2929
"files": [
30-
"/*.js",
31-
"!/.*.js"
30+
"**/*.js",
31+
"!/.*.js",
32+
"!/tools"
3233
],
3334
"peerDependencies": {
3435
"@angular-eslint/builder": "^16.3.1",

packages/eslint-config-angular/template.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const { ignoreAttributes } = require('./template/options');
2+
13
module.exports = {
24
extends: [
35
'plugin:@angular-eslint/template/recommended'
@@ -68,7 +70,13 @@ module.exports = {
6870
and new applications in the chance that they'll need to be localized in the future. Disable this rule
6971
if an application will never be localized.
7072
*/
71-
'@angular-eslint/template/i18n': ['error', { checkId: false }],
73+
'@angular-eslint/template/i18n': [
74+
'error',
75+
{
76+
checkId: false,
77+
ignoreAttributes: [...ignoreAttributes.all]
78+
}
79+
],
7280

7381
'@angular-eslint/template/no-any': 'error',
7482

@@ -86,5 +94,18 @@ module.exports = {
8694
Providing a `trackBy` function in `ngFor` loops can improve performance in specific cases where Angular can't track references, but it's overkill to require it for every `ngFor` so this rule is disabled.
8795
*/
8896
'@angular-eslint/template/use-track-by-function': 'off'
89-
}
97+
},
98+
overrides: [
99+
{
100+
// Ignore inline templates in tests using the inline template naming convention
101+
// See naming details: https://github.com/angular-eslint/angular-eslint/releases/tag/v14.0.0
102+
files: ['*.spec.ts*.html'],
103+
rules: {
104+
/*
105+
Tests often define helper components that don't need to be marked for i18n.
106+
*/
107+
'@angular-eslint/template/i18n': 'off'
108+
}
109+
},
110+
]
90111
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// This is a list of standard element attributes to ignore
2+
// when applying the @angular-eslint/template/i18n rule
3+
// that requires attributes to be tagged as localizable.
4+
//
5+
// New attributes can be added here that are for element
6+
// configuration and not for display, where localizing
7+
// the attribute value would result in broken functionality.
8+
//
9+
// In cases of attribute collisions, the rule supports
10+
// CSS selector style element[attribute] ignore entries
11+
// which can be used to scope attribute ignores to specific
12+
// elements.
13+
const ignoreAttributeSets = {
14+
nimble: [
15+
'action-menu-slot',
16+
'activeid',
17+
'appearance',
18+
'appearance-variant',
19+
'autocomplete',
20+
'column-id',
21+
'field-name',
22+
'format',
23+
'icon',
24+
'id-field-name',
25+
'key',
26+
'key-type',
27+
'nimbleRouterLink',
28+
'orientation',
29+
'queryParamsHandling',
30+
'resize',
31+
'selection-mode',
32+
'severity',
33+
'slot',
34+
'theme'
35+
],
36+
systemlink: [
37+
// sl-workspace-selector
38+
'action',
39+
40+
// sl-table
41+
'columnId',
42+
'decimalDigits',
43+
'fieldName',
44+
'format',
45+
'hrefFieldName',
46+
'idFieldName',
47+
'keyType',
48+
'labelFieldName',
49+
'selectionMode',
50+
'slTableColumnId',
51+
52+
// sl-grid
53+
'columnSizeMode',
54+
'dataRowId',
55+
'dataSourceFingerprint',
56+
'gridId',
57+
'loadColumnStateBehavior',
58+
'parentDataField',
59+
60+
// sl-query-builder
61+
'dropdownWidth',
62+
],
63+
jqx: [
64+
// smart-table
65+
'sortMode',
66+
67+
// smart-query-builder
68+
'applyMode',
69+
'fieldsMode'
70+
],
71+
material: [
72+
'cdkDragPreviewContainer',
73+
'floatLabel',
74+
'fontIcon',
75+
'fontSet',
76+
'matColumnDef',
77+
'matTooltipClass',
78+
]
79+
};
80+
81+
const ignoreAttributes = {
82+
...ignoreAttributeSets,
83+
all: Object.values(ignoreAttributeSets).flat()
84+
};
85+
86+
module.exports = {
87+
ignoreAttributes
88+
};

tests/angular/.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Test TypeScript and templates together to process inline templates.
22
module.exports = {
3+
ignorePatterns: ['*.js'],
34
overrides: [{
45
extends: [
56
'@ni/eslint-config-angular',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const {ignoreAttributes} = require('@ni/eslint-config-angular/template/options');
2+
3+
module.exports = {
4+
overrides: [{
5+
files: ['*.html'],
6+
rules: {
7+
'@angular-eslint/template/i18n': [
8+
'error',
9+
{
10+
checkId: false,
11+
ignoreAttributes: [...ignoreAttributes.all, 'custom-field']
12+
}
13+
],
14+
}
15+
}, {
16+
files: ['*.spec.ts*.html'],
17+
rules: {
18+
'@angular-eslint/template/i18n': 'off'
19+
}
20+
}]
21+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!-- Angular Template Custom Ignore Attributes Test -->
2+
<span i18n custom-field="test-custom-field">Hello {{name}}</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Angular Test Spec Custom Ignore Attributes Test
2+
import { Component, Input, ViewChild } from '@angular/core';
3+
import { ComponentFixture } from '@angular/core/testing';
4+
5+
@Component({
6+
template: '<div custom-attribute="i18n-should-be-ignored-in-test">missing i18n should be ignored</div>'
7+
})
8+
class MyComponent {
9+
@Input() public attr = false;
10+
@ViewChild('div') public div: HTMLDivElement;
11+
public myMethod(): void {}
12+
}
13+
14+
describe('MyComponent', () => {
15+
let hostComponent: MyComponent;
16+
let fixture: ComponentFixture<MyComponent>;
17+
18+
it('should have a div', async () => {
19+
await fixture.whenStable();
20+
21+
expect(hostComponent.div).toBeDefined();
22+
expect(hostComponent.myMethod).not.toHaveBeenCalled();
23+
});
24+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Angular TypeScript and Inline Template Custom Ignore Attributes Test
2+
import { Component, Input } from '@angular/core';
3+
4+
@Component({
5+
selector: 'app-root',
6+
template: '<span i18n custom-field="test-custom-field">Hello {{name}}</span>!',
7+
styles: [`
8+
span {
9+
font-weight: bold;
10+
}
11+
`]
12+
})
13+
export class AppComponent {
14+
@Input() public name = 'Angular';
15+
}

tests/angular/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<!-- Angular Template Smoke Test -->
2-
<span i18n [(id)]="name">Hello {{ name }}</span>!
2+
<span i18n [(id)]="name" theme="non-localized-theme-id" title="This title should be localized." i18n-title>Hello {{name}}</span>

tests/angular/index.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Component, Input, ViewChild } from '@angular/core';
33
import { ComponentFixture } from '@angular/core/testing';
44

55
@Component({
6-
template: '<div [(attr)] = true></div>'
6+
template: '<div custom-attribute="i18n-should-be-ignored-in-test">missing i18n should be ignored</div>'
77
})
88
class MyComponent {
99
@Input() public attr = false;

tests/angular/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Component, Input } from '@angular/core';
33

44
@Component({
55
selector: 'app-root',
6-
template: '<span i18n [(id)]="name">Hello {{name}}</span>!',
6+
template: '<span i18n [(id)]="name" theme="non-localized-theme-id" title="This title should be localized." i18n-title>Hello {{name}}</span>!',
77
styles: [`
88
span {
99
font-weight: bold;

tests/angular/tsconfig.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@
22
"compilerOptions": {
33
"experimentalDecorators": true
44
},
5-
"files": [
6-
"index.ts",
7-
"index.spec.ts"
8-
]
5+
"include": ["."]
96
}

0 commit comments

Comments
 (0)