Skip to content

Commit 3d3656a

Browse files
amysortommalerba
authored andcommitted
fix(material/schematics): add comment for potentially deprecated styles after a migration
1 parent ee5a836 commit 3d3656a

File tree

6 files changed

+183
-6
lines changed

6 files changed

+183
-6
lines changed

src/material/schematics/ng-generate/mdc-migration/rules/components/button/button-styles.spec.ts

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,15 @@ describe('button styles', () => {
138138
.mat-button {
139139
padding: 50px;
140140
}
141-
.mat-button-base {
141+
.mat-raised-button {
142142
padding: 25px;
143143
}
144144
`,
145145
`
146146
.mat-mdc-button {
147147
padding: 50px;
148148
}
149-
.mat-mdc-button-base {
149+
.mat-mdc-raised-button {
150150
padding: 25px;
151151
}
152152
`,
@@ -182,5 +182,73 @@ describe('button styles', () => {
182182
`,
183183
);
184184
});
185+
186+
it('should add comment for potentially deprecated selector', async () => {
187+
await runMigrationTest(
188+
`
189+
.mat-button-focus-overlay {
190+
background-color: transparent;
191+
}
192+
`,
193+
`
194+
/* TODO: The following rule targets internal classes of button that may no longer apply for the MDC version. */
195+
196+
.mat-button-focus-overlay {
197+
background-color: transparent;
198+
}
199+
`,
200+
);
201+
});
202+
203+
it('should not add comment for legacy selector that also starts with deprecated prefix', async () => {
204+
await runMigrationTest(
205+
`
206+
.mat-button-base {
207+
padding: 12px;
208+
}
209+
`,
210+
`
211+
.mat-mdc-button-base {
212+
padding: 12px;
213+
}
214+
`,
215+
);
216+
});
217+
218+
it('should add comment for potentially deprecated multi-line selector', async () => {
219+
await runMigrationTest(
220+
`
221+
.some-class
222+
.mat-button-focus-overlay {
223+
background-color: transparent;
224+
}
225+
`,
226+
`
227+
/* TODO: The following rule targets internal classes of button that may no longer apply for the MDC version. */
228+
229+
.some-class
230+
.mat-button-focus-overlay {
231+
background-color: transparent;
232+
}
233+
`,
234+
);
235+
});
236+
237+
it('should update the legacy mat-button class and add comment for potentially deprecated selector', async () => {
238+
await runMigrationTest(
239+
`
240+
.mat-fab.some-class, .mat-button-focus-overlay {
241+
background-color: transparent;
242+
}
243+
`,
244+
`
245+
/* TODO: The following rule targets internal classes of button that may no longer apply for the MDC version. */
246+
247+
.mat-mdc-fab.some-class, .mat-button-focus-overlay {
248+
background-color: transparent;
249+
}
250+
`,
251+
);
252+
});
185253
});
186254
});

src/material/schematics/ng-generate/mdc-migration/rules/components/button/button-styles.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {ClassNameChange, StyleMigrator} from '../../style-migrator';
1111
export class ButtonStylesMigrator extends StyleMigrator {
1212
component = 'button';
1313

14+
deprecatedPrefix = 'mat-button';
15+
1416
mixinChanges = [
1517
{
1618
old: 'button-theme',

src/material/schematics/ng-generate/mdc-migration/rules/components/checkbox/checkbox-styles.spec.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,58 @@ describe('checkbox styles', () => {
111111
`,
112112
);
113113
});
114+
115+
it('should add comment for potentially deprecated selector', async () => {
116+
await runMigrationTest(
117+
`
118+
.mat-checkbox-label {
119+
font-size: 16px;
120+
}
121+
`,
122+
`
123+
/* TODO: The following rule targets internal classes of checkbox that may no longer apply for the MDC version. */
124+
125+
.mat-checkbox-label {
126+
font-size: 16px;
127+
}
128+
`,
129+
);
130+
});
131+
132+
it('should add comment for potentially deprecated multi-line selector', async () => {
133+
await runMigrationTest(
134+
`
135+
.some-class
136+
.mat-checkbox-label {
137+
font-size: 16px;
138+
}
139+
`,
140+
`
141+
/* TODO: The following rule targets internal classes of checkbox that may no longer apply for the MDC version. */
142+
143+
.some-class
144+
.mat-checkbox-label {
145+
font-size: 16px;
146+
}
147+
`,
148+
);
149+
});
150+
151+
it('should update the legacy mat-checkbox class and add comment for potentially deprecated selector', async () => {
152+
await runMigrationTest(
153+
`
154+
.mat-checkbox.some-class, .mat-checkbox-label {
155+
background-color: transparent;
156+
}
157+
`,
158+
`
159+
/* TODO: The following rule targets internal classes of checkbox that may no longer apply for the MDC version. */
160+
161+
.mat-mdc-checkbox.some-class, .mat-checkbox-label {
162+
background-color: transparent;
163+
}
164+
`,
165+
);
166+
});
114167
});
115168
});

src/material/schematics/ng-generate/mdc-migration/rules/components/checkbox/checkbox-styles.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {ClassNameChange, StyleMigrator} from '../../style-migrator';
1111
export class CheckboxStylesMigrator extends StyleMigrator {
1212
component = 'checkbox';
1313

14+
deprecatedPrefix = 'mat-checkbox';
15+
1416
mixinChanges = [
1517
{
1618
old: 'checkbox-theme',

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

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import * as postcss from 'postcss';
1010

11+
const END_OF_SELECTOR_REGEX = '(?!-)';
12+
1113
/** The changes to a class names. */
1214
export interface ClassNameChange {
1315
/** The legacy class name. */
@@ -37,6 +39,9 @@ export abstract class StyleMigrator {
3739
/** The old mixins and their replacements. */
3840
abstract mixinChanges: MixinChange[];
3941

42+
/** The prefix of classes that are specific to the old components */
43+
abstract deprecatedPrefix: string;
44+
4045
/**
4146
* Returns whether the given at-include at-rule is a use of a legacy mixin for this component.
4247
*
@@ -91,7 +96,11 @@ export abstract class StyleMigrator {
9196
* @returns `true` if the given Rule uses a legacy selector of this component.
9297
*/
9398
isLegacySelector(rule: postcss.Rule): boolean {
94-
return this.classChanges.some(change => rule.selector.includes(change.old));
99+
// Since a legacy class can also have the deprecated prefix, we also
100+
// check that a match isn't actually a longer deprecated class.
101+
return this.classChanges.some(
102+
change => rule.selector.match(change.old + END_OF_SELECTOR_REGEX) !== null,
103+
);
95104
}
96105

97106
/**
@@ -102,9 +111,42 @@ export abstract class StyleMigrator {
102111
replaceLegacySelector(rule: postcss.Rule): void {
103112
for (let i = 0; i < this.classChanges.length; i++) {
104113
const change = this.classChanges[i];
105-
if (rule.selector.includes(change.old)) {
114+
if (rule.selector.match(change.old + END_OF_SELECTOR_REGEX)) {
106115
rule.selector = rule.selector.replace(change.old, change.new);
107116
}
108117
}
109118
}
119+
120+
/**
121+
* Returns whether the given postcss rule uses a potentially deprecated
122+
* selector of the old component.
123+
*
124+
* @param rule a postcss rule.
125+
* @returns `true` if the given Rule uses a selector with the deprecated prefix.
126+
*/
127+
isDeprecatedSelector(rule: postcss.Rule): boolean {
128+
return rule.selector.includes(this.deprecatedPrefix);
129+
}
130+
131+
/**
132+
* Adds comment before declaration that says the following rule may not apply
133+
* in the MDC version for that component
134+
*
135+
* @param rule a postcss rule.
136+
*/
137+
addDeprecatedSelectorComment(rule: postcss.Rule): void {
138+
let comment = postcss.comment({
139+
text:
140+
'TODO: The following rule targets internal classes of ' +
141+
this.component +
142+
' that may no longer apply for the MDC version.',
143+
});
144+
// We need to manually adjust the indentation and add new lines between the
145+
// comment and declaration
146+
const indentation = rule.raws.before?.split('\n').pop();
147+
comment.raws.before = '\n' + indentation;
148+
// Since node is parsed and not a copy, will always have a parent node
149+
rule.parent!.insertBefore(rule, comment);
150+
rule.raws.before = '\n\n' + indentation;
151+
}
110152
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,20 @@ export class ThemingStylesMigration extends Migration<StyleMigrator[], Schematic
4646
}
4747

4848
ruleHandler(rule: postcss.Rule) {
49+
let isLegacySelector;
50+
let isDeprecatedSelector;
51+
4952
const migrator = this.upgradeData.find(m => {
50-
return m.isLegacySelector(rule);
53+
isLegacySelector = m.isLegacySelector(rule);
54+
isDeprecatedSelector = m.isDeprecatedSelector(rule);
55+
return isLegacySelector || isDeprecatedSelector;
5156
});
52-
migrator?.replaceLegacySelector(rule);
57+
58+
if (isLegacySelector) {
59+
migrator?.replaceLegacySelector(rule);
60+
} else if (isDeprecatedSelector) {
61+
migrator?.addDeprecatedSelectorComment(rule);
62+
}
5363
}
5464
}
5565

0 commit comments

Comments
 (0)