Skip to content

Commit 8af89be

Browse files
andrewseguinAndrew Seguin
and
Andrew Seguin
authored
fix(material/schematics): add schematic to rename tokens (angular#31051)
* fix(material/schematics): add schematic to rename tokens * fix(material/schematics): add schematic to rename tokens * fix(material/schematics): fix rename tests * fix(material/schematic): rename variables --------- Co-authored-by: Andrew Seguin <[email protected]>
1 parent f8ccab7 commit 8af89be

File tree

3 files changed

+118
-8
lines changed

3 files changed

+118
-8
lines changed

src/material/schematics/ng-update/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ ts_project(
6868
jasmine_test(
6969
name = "test",
7070
data = [
71+
":ng_update_index",
7172
":schematics_test_cases",
7273
":test_lib",
7374
"//src/material/schematics:collection_assets",

src/material/schematics/ng-update/index.ts

+66-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Rule, SchematicContext} from '@angular-devkit/schematics';
9+
import {chain, Rule, SchematicContext} from '@angular-devkit/schematics';
1010
import {
1111
createMigrationSchematicRule,
1212
NullableDevkitMigration,
@@ -22,14 +22,72 @@ const materialMigrations: NullableDevkitMigration[] = [
2222
ExplicitSystemVariablePrefixMigration,
2323
];
2424

25-
/** Entry point for the migration schematics with target of Angular Material v19 */
25+
/** Entry point for the migration schematics with target of Angular Material v20 */
2626
export function updateToV20(): Rule {
27-
return createMigrationSchematicRule(
28-
TargetVersion.V20,
29-
materialMigrations,
30-
materialUpgradeData,
31-
onMigrationComplete,
32-
);
27+
return chain([
28+
createMigrationSchematicRule(
29+
TargetVersion.V20,
30+
materialMigrations,
31+
materialUpgradeData,
32+
onMigrationComplete,
33+
),
34+
renameMdcTokens(),
35+
renameComponentTokens(),
36+
]);
37+
}
38+
39+
// Renames any CSS variables beginning with "--mdc-" to be "--mat-". These CSS variables
40+
// refer to tokens that used to be derived from a mix of MDC and Angular. Now all the tokens
41+
// are converged on being prefixed "--mat-".
42+
function renameMdcTokens(): Rule {
43+
return tree => {
44+
tree.visit(path => {
45+
const content = tree.readText(path);
46+
const updatedContent = content.replace('--mdc-', '--mat-');
47+
tree.overwrite(path, updatedContent);
48+
});
49+
};
50+
}
51+
52+
// Renames Angular Material component token CSS variables that were renamed so that the base
53+
// component's name came first or otherwise renamed to match our terminology instead of MDC's.
54+
function renameComponentTokens(): Rule {
55+
const tokenPrefixes = [
56+
{old: '--mat-circular-progress', replacement: '--mat-progress-spinner'},
57+
{old: '--mat-elevated-card', replacement: '--mat-card-elevated'},
58+
{old: '--mat-extended-fab', replacement: '--mat-fab-extended'},
59+
{old: '--mat-filled-button', replacement: '--mat-button-filled'},
60+
{old: '--mat-filled-text-field', replacement: '--mat-form-field-filled'},
61+
{old: '--mat-full-pseudo-checkbox', replacement: '--mat-pseudo-checkbox-full'},
62+
{old: '--mat-legacy-button-toggle', replacement: '--mat-button-toggle-legacy'},
63+
{old: '--mat-linear-progress', replacement: '--mat-progress-bar'},
64+
{old: '--mat-minimal-pseudo-checkbox', replacement: '--mat-pseudo-checkbox-minimal'},
65+
{old: '--mat-outlined-button', replacement: '--mat-button-outlined'},
66+
{old: '--mat-outlined-card', replacement: '--mat-card-outlined'},
67+
{old: '--mat-outlined-text-field', replacement: '--mat-form-field-outlined'},
68+
{old: '--mat-plain-tooltip', replacement: '--mat-tooltip'},
69+
{old: '--mat-protected-button', replacement: '--mat-button-protected'},
70+
{old: '--mat-secondary-navigation-tab', replacement: '--mat-tab'},
71+
{old: '--mat-standard-button-toggle', replacement: '--mat-button-toggle'},
72+
{old: '--mat-switch', replacement: '--mat-slide-toggle'},
73+
{old: '--mat-tab-header', replacement: '--mat-tab'},
74+
{old: '--mat-tab-header-with-background', replacement: '--mat-tab'},
75+
{old: '--mat-tab-indicator', replacement: '--mat-tab'},
76+
{old: '--mat-text-button', replacement: '--mat-button-text'},
77+
{old: '--mat-tonal-button', replacement: '--mat-button-tonal'},
78+
];
79+
return tree => {
80+
tree.visit(path => {
81+
const content = tree.readText(path);
82+
let updatedContent = content;
83+
for (const tokenPrefix of tokenPrefixes) {
84+
updatedContent = updatedContent.replace(tokenPrefix.old, tokenPrefix.replacement);
85+
}
86+
if (content !== updatedContent) {
87+
tree.overwrite(path, updatedContent);
88+
}
89+
});
90+
};
3391
}
3492

3593
/** Function that will be called when the migration completed. */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {UnitTestTree} from '@angular-devkit/schematics/testing';
2+
import {createTestCaseSetup} from '../../../../cdk/schematics/testing';
3+
import {MIGRATION_PATH} from '../../paths';
4+
5+
const THEME_FILE_PATH = '/projects/cdk-testing/src/theme.scss';
6+
7+
describe('v20 rename tokens migration', () => {
8+
let tree: UnitTestTree;
9+
let writeFile: (filename: string, content: string) => void;
10+
let runMigration: () => Promise<unknown>;
11+
12+
function stripWhitespace(content: string): string {
13+
return content.replace(/\s/g, '');
14+
}
15+
16+
beforeEach(async () => {
17+
const testSetup = await createTestCaseSetup('migration-v20', MIGRATION_PATH, []);
18+
tree = testSetup.appTree;
19+
writeFile = testSetup.writeFile;
20+
runMigration = testSetup.runFixers;
21+
});
22+
23+
it('should rename mdc tokens to mat and change component ordering', async () => {
24+
writeFile(
25+
THEME_FILE_PATH,
26+
`
27+
html {
28+
--mdc-icon-button-icon-size: 24px;
29+
--mat-filled-button-color: red;
30+
--mat-filled-text-field-color: red;
31+
--mat-full-pseudo-checkbox-color: red;
32+
--mat-legacy-button-toggle-color: red;
33+
}
34+
`,
35+
);
36+
37+
await runMigration();
38+
39+
expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
40+
stripWhitespace(`
41+
html {
42+
--mat-icon-button-icon-size: 24px;
43+
--mat-button-filled-color: red;
44+
--mat-form-field-filled-color: red;
45+
--mat-pseudo-checkbox-full-color: red;
46+
--mat-button-toggle-legacy-color: red;
47+
}
48+
`),
49+
);
50+
});
51+
});

0 commit comments

Comments
 (0)