Skip to content

Commit d61ec17

Browse files
committed
feat(lint): improve deprecated api migration rules
- New deprecated CSS imports in the no-deprecated-css-imports rule - Updated the no-deprecated-packages - Updated no-missing-slotted-elements for nve-logo Signed-off-by: Cory Rylan <crylan@nvidia.com>
1 parent 36473c1 commit d61ec17

6 files changed

Lines changed: 159 additions & 14 deletions

projects/lint/src/eslint/rules/no-deprecated-css-imports.test.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest';
55
import { RuleTester } from 'eslint';
66
import type { JSRuleDefinition } from 'eslint';
77
import css from '@eslint/css';
8-
import noDeprecatedCssImports from './no-deprecated-css-imports.js';
8+
import noDeprecatedCssImports, { deprecatedImports } from './no-deprecated-css-imports.js';
99

1010
const rule = noDeprecatedCssImports as unknown as JSRuleDefinition;
1111

@@ -54,6 +54,13 @@ describe('noDeprecatedCssImports', () => {
5454
});
5555
});
5656

57+
it('should cover CSS entrypoints documented in the migration guide', () => {
58+
expect(deprecatedImports['@maglev/elements/index.css']).toContain(
59+
`@import '@nvidia-elements/styles/view-transitions.css';`
60+
);
61+
expect(deprecatedImports['@maglev/elements/inter.css']).toBe(`@import '@nvidia-elements/themes/fonts/inter.css';`);
62+
});
63+
5764
it('should not allow use of deprecated CSS import paths', () => {
5865
tester.run('should not allow use of deprecated CSS import paths', rule, {
5966
valid: [],
@@ -62,9 +69,14 @@ describe('noDeprecatedCssImports', () => {
6269
code: `@import '@maglev/elements/index.css';`,
6370
output: `@import '@nvidia-elements/themes/fonts/inter.css';
6471
@import '@nvidia-elements/themes/index.css';
72+
@import '@nvidia-elements/themes/high-contrast.css';
73+
@import '@nvidia-elements/themes/reduced-motion.css';
74+
@import '@nvidia-elements/themes/compact.css';
6575
@import '@nvidia-elements/themes/dark.css';
76+
@import '@nvidia-elements/themes/debug.css';
6677
@import '@nvidia-elements/styles/typography.css';
67-
@import '@nvidia-elements/styles/layout.css';`,
78+
@import '@nvidia-elements/styles/layout.css';
79+
@import '@nvidia-elements/styles/view-transitions.css';`,
6880
errors: [
6981
{
7082
messageId: 'deprecated-css-import',
@@ -73,9 +85,27 @@ describe('noDeprecatedCssImports', () => {
7385
alternative: `
7486
@import '@nvidia-elements/themes/fonts/inter.css';
7587
@import '@nvidia-elements/themes/index.css';
88+
@import '@nvidia-elements/themes/high-contrast.css';
89+
@import '@nvidia-elements/themes/reduced-motion.css';
90+
@import '@nvidia-elements/themes/compact.css';
7691
@import '@nvidia-elements/themes/dark.css';
92+
@import '@nvidia-elements/themes/debug.css';
7793
@import '@nvidia-elements/styles/typography.css';
78-
@import '@nvidia-elements/styles/layout.css';`.trim()
94+
@import '@nvidia-elements/styles/layout.css';
95+
@import '@nvidia-elements/styles/view-transitions.css';`.trim()
96+
}
97+
}
98+
]
99+
},
100+
{
101+
code: `@import '@maglev/elements/inter.css';`,
102+
output: `@import '@nvidia-elements/themes/fonts/inter.css';`,
103+
errors: [
104+
{
105+
messageId: 'deprecated-css-import',
106+
data: {
107+
value: '@maglev/elements/inter.css',
108+
alternative: `@import '@nvidia-elements/themes/fonts/inter.css';`
79109
}
80110
}
81111
]

projects/lint/src/eslint/rules/no-deprecated-css-imports.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@ import type { Rule } from 'eslint';
55
import type { CssAtRuleNode } from '../rule-types.js';
66

77
declare const __ELEMENTS_PAGES_BASE_URL__: string;
8-
const deprecatedImports: Record<string, string> = {
9-
'@nvidia-elements/core/index.css': `@import '@nvidia-elements/themes/fonts/inter.css';\n@import '@nvidia-elements/themes/index.css';\n@import '@nvidia-elements/themes/dark.css';\n@import '@nvidia-elements/styles/typography.css';\n@import '@nvidia-elements/styles/layout.css';`,
8+
const themeAndStyleImports = `@import '@nvidia-elements/themes/fonts/inter.css';
9+
@import '@nvidia-elements/themes/index.css';
10+
@import '@nvidia-elements/themes/high-contrast.css';
11+
@import '@nvidia-elements/themes/reduced-motion.css';
12+
@import '@nvidia-elements/themes/compact.css';
13+
@import '@nvidia-elements/themes/dark.css';
14+
@import '@nvidia-elements/themes/debug.css';
15+
@import '@nvidia-elements/styles/typography.css';
16+
@import '@nvidia-elements/styles/layout.css';
17+
@import '@nvidia-elements/styles/view-transitions.css';`;
18+
19+
export const deprecatedImports: Record<string, string> = {
20+
'@nvidia-elements/core/index.css': themeAndStyleImports,
1021
'@nvidia-elements/core/css/module.layout.css': `@import '@nvidia-elements/styles/layout.css';`,
1122
'@nvidia-elements/core/css/module.typography.css': `@import '@nvidia-elements/styles/typography.css';`,
12-
'@maglev/elements/index.css': `@import '@nvidia-elements/themes/fonts/inter.css';\n@import '@nvidia-elements/themes/index.css';\n@import '@nvidia-elements/themes/dark.css';\n@import '@nvidia-elements/styles/typography.css';\n@import '@nvidia-elements/styles/layout.css';`,
23+
'@maglev/elements/index.css': themeAndStyleImports,
24+
'@maglev/elements/inter.css': `@import '@nvidia-elements/themes/fonts/inter.css';`,
1325
'@maglev/elements/css/module.layout.css': `@import '@nvidia-elements/styles/layout.css';`,
1426
'@maglev/elements/css/module.typography.css': `@import '@nvidia-elements/styles/typography.css';`
1527
};

projects/lint/src/eslint/rules/no-deprecated-packages.test.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { beforeEach, describe, expect, it } from 'vitest';
55
import { RuleTester } from 'eslint';
66
import json from '@eslint/json';
77
import type { JSRuleDefinition } from 'eslint';
8-
import noDeprecatedPackages from './no-deprecated-packages.js';
8+
import noDeprecatedPackages, { DEPRECATED_PACKAGES } from './no-deprecated-packages.js';
99

1010
const rule = noDeprecatedPackages as unknown as JSRuleDefinition;
1111

@@ -46,6 +46,24 @@ describe('noUnexpectedLibraryDependencies', () => {
4646
});
4747
});
4848

49+
it('should cover every package documented in the migration guide', () => {
50+
expect(DEPRECATED_PACKAGES['@nve/elements']).toBe('@nvidia-elements/core');
51+
expect(DEPRECATED_PACKAGES['@nve/styles']).toBe('@nvidia-elements/styles');
52+
expect(DEPRECATED_PACKAGES['@nve/themes']).toBe('@nvidia-elements/themes');
53+
expect(DEPRECATED_PACKAGES['@nve/monaco']).toBe('@nvidia-elements/monaco');
54+
expect(DEPRECATED_PACKAGES['@nve-labs/forms']).toBe('@nvidia-elements/forms');
55+
expect(DEPRECATED_PACKAGES['@nve-labs/cli']).toBe('@nvidia-elements/cli');
56+
expect(DEPRECATED_PACKAGES['@nve-labs/code']).toBe('@nvidia-elements/code');
57+
expect(DEPRECATED_PACKAGES['@nve-labs/create']).toBe('@nvidia-elements/create');
58+
expect(DEPRECATED_PACKAGES['@nve-labs/markdown']).toBe('@nvidia-elements/markdown');
59+
expect(DEPRECATED_PACKAGES['@nve-labs/media']).toBe('@nvidia-elements/media');
60+
expect(DEPRECATED_PACKAGES['@nve-labs/lint']).toBe('@nvidia-elements/lint');
61+
expect(DEPRECATED_PACKAGES['@maglev/elements']).toBe(
62+
'@nvidia-elements/core + @nvidia-elements/themes + @nvidia-elements/styles'
63+
);
64+
expect(DEPRECATED_PACKAGES['@nve/testing']).toBe('project-supported test utilities');
65+
});
66+
4967
it('should not allow deprecated dependencies', () => {
5068
tester.run('should not allow deprecated dependencies', rule, {
5169
valid: [],
@@ -83,4 +101,49 @@ describe('noUnexpectedLibraryDependencies', () => {
83101
]
84102
});
85103
});
104+
105+
it('should not allow deprecated packages from the migration guide', () => {
106+
tester.run('should not allow deprecated packages from the migration guide', rule, {
107+
valid: [],
108+
invalid: [
109+
{
110+
code: `{ "dependencies": { "@nve/elements": "1.0.0", "@nve-labs/forms": "1.0.0" } }`,
111+
filename: 'package.json',
112+
errors: [
113+
{
114+
messageId: 'unexpected-deprecated-package',
115+
data: { package: '@nve/elements', alternative: '@nvidia-elements/core' }
116+
},
117+
{
118+
messageId: 'unexpected-deprecated-package',
119+
data: { package: '@nve-labs/forms', alternative: '@nvidia-elements/forms' }
120+
}
121+
]
122+
},
123+
{
124+
code: `{ "devDependencies": { "@nve/testing": "1.0.0" } }`,
125+
filename: 'package.json',
126+
errors: [
127+
{
128+
messageId: 'unexpected-deprecated-package',
129+
data: { package: '@nve/testing', alternative: 'project-supported test utilities' }
130+
}
131+
]
132+
},
133+
{
134+
code: `{ "peerDependencies": { "@maglev/elements": "1.0.0" } }`,
135+
filename: 'package.json',
136+
errors: [
137+
{
138+
messageId: 'unexpected-deprecated-package',
139+
data: {
140+
package: '@maglev/elements',
141+
alternative: '@nvidia-elements/core + @nvidia-elements/themes + @nvidia-elements/styles'
142+
}
143+
}
144+
]
145+
}
146+
]
147+
});
148+
});
86149
});

projects/lint/src/eslint/rules/no-deprecated-packages.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ import type { Rule } from 'eslint';
55
import type { HtmlTagNode } from '../rule-types.js';
66

77
declare const __ELEMENTS_PAGES_BASE_URL__: string;
8+
export const DEPRECATED_PACKAGES: Record<string, string> = {
9+
'@nve/elements': '@nvidia-elements/core',
10+
'@nve/styles': '@nvidia-elements/styles',
11+
'@nve/themes': '@nvidia-elements/themes',
12+
'@nve/monaco': '@nvidia-elements/monaco',
13+
'@nve-labs/forms': '@nvidia-elements/forms',
14+
'@nve-labs/cli': '@nvidia-elements/cli',
15+
'@nve-labs/code': '@nvidia-elements/code',
16+
'@nve-labs/create': '@nvidia-elements/create',
17+
'@nve-labs/markdown': '@nvidia-elements/markdown',
18+
'@nve-labs/media': '@nvidia-elements/media',
19+
'@nve-labs/lint': '@nvidia-elements/lint',
20+
'@maglev/elements': '@nvidia-elements/core + @nvidia-elements/themes + @nvidia-elements/styles',
21+
'@mlv/elements': '@nvidia-elements/core',
22+
'@nve/testing': 'project-supported test utilities'
23+
};
24+
825
const rule = {
926
meta: {
1027
type: 'problem' as const,
@@ -26,20 +43,20 @@ const rule = {
2643
const dependencies = Object.keys(packageJson.dependencies ?? {});
2744
const devDependencies = Object.keys(packageJson.devDependencies ?? {});
2845
const peerDependencies = Object.keys(packageJson.peerDependencies ?? {});
29-
const hasDeprecatedDevDependencies = devDependencies.find(dependency => dependency === '@mlv/elements');
30-
const hasDeprecatedDependencies = dependencies.find(dependency => dependency === '@mlv/elements');
31-
const hasDeprecatedPeerDependencies = peerDependencies.find(dependency => dependency === '@mlv/elements');
46+
const deprecatedDependencies = [...dependencies, ...devDependencies, ...peerDependencies].filter(
47+
dependency => dependency in DEPRECATED_PACKAGES
48+
);
3249

33-
if (hasDeprecatedPeerDependencies || hasDeprecatedDependencies || hasDeprecatedDevDependencies) {
50+
deprecatedDependencies.forEach(dependency => {
3451
context.report({
3552
messageId: 'unexpected-deprecated-package',
3653
loc: node.loc!,
3754
data: {
38-
package: '@mlv/elements',
39-
alternative: '@nvidia-elements/core'
55+
package: dependency,
56+
alternative: DEPRECATED_PACKAGES[dependency]
4057
}
4158
});
42-
}
59+
});
4360
}
4461
}
4562
};

projects/lint/src/eslint/rules/no-missing-slotted-elements.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ describe('noMissingSlottedElements', () => {
5555
`<nve-button>
5656
button
5757
</nve-button>`,
58+
`<nve-logo>
59+
<img src="./logo.svg" alt="NVIDIA" />
60+
</nve-logo>`,
61+
`<nve-logo>NV</nve-logo>`,
5862
`<nve-input>\${}</nve-input>`,
5963
`<nve-input>{{ }}</nve-input>`,
6064
`<nve-input>{% %}</nve-input>`,
@@ -139,6 +143,22 @@ describe('noMissingSlottedElements', () => {
139143
});
140144
});
141145

146+
it('should report logos missing default slot content', () => {
147+
tester.run('logos missing default slot content', rule, {
148+
valid: [],
149+
invalid: [
150+
{
151+
code: `<nve-logo></nve-logo>`,
152+
errors: [{ messageId: 'missing-default-slot-content', data: { tagName: 'nve-logo' } }]
153+
},
154+
{
155+
code: `<nve-logo><span slot="prefix">NV</span></nve-logo>`,
156+
errors: [{ messageId: 'missing-default-slot-content', data: { tagName: 'nve-logo' } }]
157+
}
158+
]
159+
});
160+
});
161+
142162
it('should report custom required elements', () => {
143163
tester.run('unexpected use of missing slotted elements', rule, {
144164
valid: [],

projects/lint/src/eslint/rules/no-missing-slotted-elements.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ const REQUIRED_SLOTTED_ELEMENTS: Record<string, RequiredSlotConfig> = {
4747
'nve-file': {
4848
required: ['input[type="file"]']
4949
},
50+
'nve-logo': {
51+
requiresDefaultSlotContent: true
52+
},
5053
'nve-password': {
5154
required: ['input[type="password"]']
5255
},

0 commit comments

Comments
 (0)