Skip to content

Commit dcc9829

Browse files
amysortommalerba
authored andcommitted
feat(material/schematics): add form-field styles migrator and tests
1 parent 7b5bb76 commit dcc9829

File tree

4 files changed

+344
-0
lines changed

4 files changed

+344
-0
lines changed

integration/mdc-migration/golden/src/styles.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ $sample-project-theme: mat.define-light-theme((
5454
@include mat.mdc-menu-typography($sample-project-theme);
5555
@include mat.mdc-list-theme($sample-project-theme);
5656
@include mat.mdc-list-typography($sample-project-theme);
57+
@include mat.mdc-form-field-theme($sample-project-theme);
58+
@include mat.mdc-form-field-typography($sample-project-theme);
5759
@include mat.mdc-dialog-theme($sample-project-theme);
5860
@include mat.mdc-dialog-typography($sample-project-theme);
5961
@include mat.mdc-chips-theme($sample-project-theme);
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
import {createTestApp, patchDevkitTreeToExposeTypeScript} from '@angular/cdk/schematics/testing';
2+
import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
3+
import {createNewTestRunner, migrateComponents, THEME_FILE} from '../test-setup-helper';
4+
5+
describe('form-field styles', () => {
6+
let runner: SchematicTestRunner;
7+
let cliAppTree: UnitTestTree;
8+
9+
async function runMigrationTest(oldFileContent: string, newFileContent: string) {
10+
cliAppTree.create(THEME_FILE, oldFileContent);
11+
const tree = await migrateComponents(['form-field'], runner, cliAppTree);
12+
expect(tree.readContent(THEME_FILE)).toBe(newFileContent);
13+
}
14+
15+
beforeEach(async () => {
16+
runner = createNewTestRunner();
17+
cliAppTree = patchDevkitTreeToExposeTypeScript(await createTestApp(runner));
18+
});
19+
20+
describe('mixin migrations', () => {
21+
it('should replace the old theme with the new ones', async () => {
22+
await runMigrationTest(
23+
`
24+
@use '@angular/material' as mat;
25+
$theme: ();
26+
@include mat.form-field-theme($theme);
27+
`,
28+
`
29+
@use '@angular/material' as mat;
30+
$theme: ();
31+
@include mat.mdc-form-field-theme($theme);
32+
@include mat.mdc-form-field-typography($theme);
33+
`,
34+
);
35+
});
36+
37+
it('should use the correct namespace', async () => {
38+
await runMigrationTest(
39+
`
40+
@use '@angular/material' as arbitrary;
41+
$theme: ();
42+
@include arbitrary.form-field-theme($theme);
43+
`,
44+
`
45+
@use '@angular/material' as arbitrary;
46+
$theme: ();
47+
@include arbitrary.mdc-form-field-theme($theme);
48+
@include arbitrary.mdc-form-field-typography($theme);
49+
`,
50+
);
51+
});
52+
53+
it('should handle updating multiple themes', async () => {
54+
await runMigrationTest(
55+
`
56+
@use '@angular/material' as mat;
57+
$light-theme: ();
58+
$dark-theme: ();
59+
@include mat.form-field-theme($light-theme);
60+
@include mat.form-field-theme($dark-theme);
61+
`,
62+
`
63+
@use '@angular/material' as mat;
64+
$light-theme: ();
65+
$dark-theme: ();
66+
@include mat.mdc-form-field-theme($light-theme);
67+
@include mat.mdc-form-field-typography($light-theme);
68+
@include mat.mdc-form-field-theme($dark-theme);
69+
@include mat.mdc-form-field-typography($dark-theme);
70+
`,
71+
);
72+
});
73+
74+
it('should add correct theme if all-component-themes mixin included', async () => {
75+
await runMigrationTest(
76+
`
77+
@use '@angular/material' as mat;
78+
$theme: ();
79+
@include mat.all-component-themes($theme);
80+
`,
81+
`
82+
@use '@angular/material' as mat;
83+
$theme: ();
84+
@include mat.all-component-themes($theme);
85+
@include mat.mdc-select-theme($theme);
86+
@include mat.mdc-select-typography($theme);
87+
@include mat.mdc-core-theme($theme);
88+
@include mat.mdc-core-typography($theme);
89+
@include mat.mdc-input-theme($theme);
90+
@include mat.mdc-input-typography($theme);
91+
@include mat.mdc-form-field-theme($theme);
92+
@include mat.mdc-form-field-typography($theme);
93+
@include mat.mdc-autocomplete-theme($theme);
94+
@include mat.mdc-autocomplete-typography($theme);
95+
`,
96+
);
97+
});
98+
99+
it('should add multiple themes for multiple all-component-themes mixins', async () => {
100+
await runMigrationTest(
101+
`
102+
@use '@angular/material' as mat;
103+
$light-theme: ();
104+
$dark-theme: ();
105+
@include mat.all-component-themes($light-theme);
106+
@include mat.all-component-themes($dark-theme);
107+
`,
108+
`
109+
@use '@angular/material' as mat;
110+
$light-theme: ();
111+
$dark-theme: ();
112+
@include mat.all-component-themes($light-theme);
113+
@include mat.mdc-select-theme($light-theme);
114+
@include mat.mdc-select-typography($light-theme);
115+
@include mat.mdc-core-theme($light-theme);
116+
@include mat.mdc-core-typography($light-theme);
117+
@include mat.mdc-input-theme($light-theme);
118+
@include mat.mdc-input-typography($light-theme);
119+
@include mat.mdc-form-field-theme($light-theme);
120+
@include mat.mdc-form-field-typography($light-theme);
121+
@include mat.mdc-autocomplete-theme($light-theme);
122+
@include mat.mdc-autocomplete-typography($light-theme);
123+
@include mat.all-component-themes($dark-theme);
124+
@include mat.mdc-select-theme($dark-theme);
125+
@include mat.mdc-select-typography($dark-theme);
126+
@include mat.mdc-core-theme($dark-theme);
127+
@include mat.mdc-core-typography($dark-theme);
128+
@include mat.mdc-input-theme($dark-theme);
129+
@include mat.mdc-input-typography($dark-theme);
130+
@include mat.mdc-form-field-theme($dark-theme);
131+
@include mat.mdc-form-field-typography($dark-theme);
132+
@include mat.mdc-autocomplete-theme($dark-theme);
133+
@include mat.mdc-autocomplete-typography($dark-theme);
134+
`,
135+
);
136+
});
137+
138+
it('should preserve whitespace', async () => {
139+
await runMigrationTest(
140+
`
141+
@use '@angular/material' as mat;
142+
$theme: ();
143+
144+
145+
@include mat.form-field-theme($theme);
146+
147+
148+
`,
149+
`
150+
@use '@angular/material' as mat;
151+
$theme: ();
152+
153+
154+
@include mat.mdc-form-field-theme($theme);
155+
@include mat.mdc-form-field-typography($theme);
156+
157+
158+
`,
159+
);
160+
});
161+
});
162+
163+
describe('selector migrations', () => {
164+
it('should update the legacy mat-form-field classname', async () => {
165+
await runMigrationTest(
166+
`
167+
.mat-form-field {
168+
padding: 16px;
169+
}
170+
`,
171+
`
172+
.mat-mdc-form-field {
173+
padding: 16px;
174+
}
175+
`,
176+
);
177+
});
178+
179+
it('should update multiple legacy classnames', async () => {
180+
await runMigrationTest(
181+
`
182+
.mat-form-field {
183+
padding: 16px;
184+
}
185+
.mat-hint {
186+
color: red;
187+
}
188+
`,
189+
`
190+
.mat-mdc-form-field {
191+
padding: 16px;
192+
}
193+
.mat-mdc-form-field-hint {
194+
color: red;
195+
}
196+
`,
197+
);
198+
});
199+
200+
it('should update a legacy classname w/ multiple selectors', async () => {
201+
await runMigrationTest(
202+
`
203+
.some-class.mat-form-field, .another-class {
204+
padding: 16px;
205+
}
206+
`,
207+
`
208+
.some-class.mat-mdc-form-field, .another-class {
209+
padding: 16px;
210+
}
211+
`,
212+
);
213+
});
214+
215+
it('should preserve the whitespace of multiple selectors', async () => {
216+
await runMigrationTest(
217+
`
218+
.some-class,
219+
.mat-form-field,
220+
.another-class { padding: 16px; }
221+
`,
222+
`
223+
.some-class,
224+
.mat-mdc-form-field,
225+
.another-class { padding: 16px; }
226+
`,
227+
);
228+
});
229+
230+
it('should add comment for potentially deprecated selector', async () => {
231+
await runMigrationTest(
232+
`
233+
.mat-form-field-wrapper {
234+
padding: 16px;
235+
}
236+
`,
237+
`
238+
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
239+
240+
.mat-form-field-wrapper {
241+
padding: 16px;
242+
}
243+
`,
244+
);
245+
});
246+
247+
it('should add comment for potentially deprecated multi-line selector', async () => {
248+
await runMigrationTest(
249+
`
250+
.some-class
251+
.mat-form-field-wrapper {
252+
padding: 16px;
253+
}
254+
`,
255+
`
256+
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
257+
258+
.some-class
259+
.mat-form-field-wrapper {
260+
padding: 16px;
261+
}
262+
`,
263+
);
264+
});
265+
266+
it('should update the legacy mat-form-field class and add comment for potentially deprecated selector', async () => {
267+
await runMigrationTest(
268+
`
269+
.mat-form-field.some-class, .mat-form-field-wrapper {
270+
padding: 16px;
271+
}
272+
`,
273+
`
274+
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
275+
276+
.mat-mdc-form-field.some-class, .mat-form-field-wrapper {
277+
padding: 16px;
278+
}
279+
`,
280+
);
281+
});
282+
});
283+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {ClassNameChange, StyleMigrator} from '../../style-migrator';
10+
11+
export class FormFieldStylesMigrator extends StyleMigrator {
12+
component = 'form-field';
13+
14+
deprecatedPrefixes = [
15+
'.mat-form-field-can-float',
16+
'.mat-form-field-should-float',
17+
'.mat-form-field-has-label',
18+
'.mat-form-field-wrapper',
19+
'.mat-form-field-flex',
20+
'.mat-form-field-outline',
21+
'.mat-form-field-prefix',
22+
'.mat-form-field-infix',
23+
'.mat-form-field-suffix',
24+
'.mat-form-field-label',
25+
'.mat-form-field-required-marker',
26+
'.mat-form-field-underline',
27+
'.mat-form-field-ripple',
28+
'.mat-form-field-subscript-wrapper',
29+
'.mat-form-field-hint-wrapper',
30+
'.mat-form-field-hint-hint-spacer',
31+
];
32+
33+
mixinChanges = [
34+
{
35+
old: 'form-field-theme',
36+
new: ['mdc-form-field-theme', 'mdc-form-field-typography'],
37+
},
38+
];
39+
40+
classChanges: ClassNameChange[] = [
41+
{
42+
old: '.mat-form-field',
43+
new: '.mat-mdc-form-field',
44+
},
45+
{
46+
old: '.mat-hint',
47+
new: '.mat-mdc-form-field-hint',
48+
},
49+
{
50+
old: '.mat-error',
51+
new: '.mat-mdc-form-field-error',
52+
},
53+
];
54+
}

src/material/schematics/ng-generate/mdc-migration/rules/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {CardTemplateMigrator} from './components/card/card-template';
1717
import {CheckboxStylesMigrator} from './components/checkbox/checkbox-styles';
1818
import {ChipsStylesMigrator} from './components/chips/chips-styles';
1919
import {DialogStylesMigrator} from './components/dialog/dialog-styles';
20+
import {FormFieldStylesMigrator} from './components/form-field/form-field-styles';
2021
import {ListStylesMigrator} from './components/list/list-styles';
2122
import {MenuStylesMigrator} from './components/menu/menu-styles';
2223
import {PaginatorStylesMigrator} from './components/paginator/paginator-styles';
@@ -65,6 +66,10 @@ export const MIGRATORS: ComponentMigrator[] = [
6566
component: 'dialog',
6667
styles: new DialogStylesMigrator(),
6768
},
69+
{
70+
component: 'form-field',
71+
styles: new FormFieldStylesMigrator(),
72+
},
6873
{
6974
component: 'list',
7075
styles: new ListStylesMigrator(),

0 commit comments

Comments
 (0)