Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/material/schematics/ng-update/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ts_project(
jasmine_test(
name = "test",
data = [
":ng_update_index",
":schematics_test_cases",
":test_lib",
"//src/material/schematics:collection_assets",
Expand Down
74 changes: 66 additions & 8 deletions src/material/schematics/ng-update/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {Rule, SchematicContext} from '@angular-devkit/schematics';
import {chain, Rule, SchematicContext} from '@angular-devkit/schematics';
import {
createMigrationSchematicRule,
NullableDevkitMigration,
Expand All @@ -22,14 +22,72 @@ const materialMigrations: NullableDevkitMigration[] = [
ExplicitSystemVariablePrefixMigration,
];

/** Entry point for the migration schematics with target of Angular Material v19 */
/** Entry point for the migration schematics with target of Angular Material v20 */
export function updateToV20(): Rule {
return createMigrationSchematicRule(
TargetVersion.V20,
materialMigrations,
materialUpgradeData,
onMigrationComplete,
);
return chain([
createMigrationSchematicRule(
TargetVersion.V20,
materialMigrations,
materialUpgradeData,
onMigrationComplete,
),
renameMdcTokens(),
renameComponentTokens(),
]);
}

// Renames any CSS variables beginning with "--mdc-" to be "--mat-". These CSS variables
// refer to tokens that used to be derived from a mix of MDC and Angular. Now all the tokens
// are converged on being prefixed "--mat-".
function renameMdcTokens(): Rule {
return tree => {
tree.visit(path => {
const content = tree.readText(path);
const updatedContent = content.replace('--mdc-', '--mat-');
tree.overwrite(path, updatedContent);
});
};
}

// Renames Angular Material component token CSS variables that were renamed so that the base
// component's name came first or otherwise renamed to match our terminology instead of MDC's.
function renameComponentTokens(): Rule {
const replacements = [
{oldStr: '--mat-circular-progress', newStr: '--mat-progress-spinner'},
{oldStr: '--mat-elevated-card', newStr: '--mat-card-elevated'},
{oldStr: '--mat-extended-fab', newStr: '--mat-fab-extended'},
{oldStr: '--mat-filled-button', newStr: '--mat-button-filled'},
{oldStr: '--mat-filled-text-field', newStr: '--mat-form-field-filled'},
{oldStr: '--mat-full-pseudo-checkbox', newStr: '--mat-pseudo-checkbox-full'},
{oldStr: '--mat-legacy-button-toggle', newStr: '--mat-button-toggle-legacy'},
{oldStr: '--mat-linear-progress', newStr: '--mat-progress-bar'},
{oldStr: '--mat-minimal-pseudo-checkbox', newStr: '--mat-pseudo-checkbox-minimal'},
{oldStr: '--mat-outlined-button', newStr: '--mat-button-outlined'},
{oldStr: '--mat-outlined-card', newStr: '--mat-card-outlined'},
{oldStr: '--mat-outlined-text-field', newStr: '--mat-form-field-outlined'},
{oldStr: '--mat-plain-tooltip', newStr: '--mat-tooltip'},
{oldStr: '--mat-protected-button', newStr: '--mat-button-protected'},
{oldStr: '--mat-secondary-navigation-tab', newStr: '--mat-tab'},
{oldStr: '--mat-standard-button-toggle', newStr: '--mat-button-toggle'},
{oldStr: '--mat-switch', newStr: '--mat-slide-toggle'},
{oldStr: '--mat-tab-header', newStr: '--mat-tab'},
{oldStr: '--mat-tab-header-with-background', newStr: '--mat-tab'},
{oldStr: '--mat-tab-indicator', newStr: '--mat-tab'},
{oldStr: '--mat-text-button', newStr: '--mat-button-text'},
{oldStr: '--mat-tonal-button', newStr: '--mat-button-tonal'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bit deal, but I think we can skip the tonal button since it's new in v20.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah true...Ill leave it just for completeness but I think youre right

];
return tree => {
tree.visit(path => {
const content = tree.readText(path);
let updatedContent = content;
for (const replacement of replacements) {
updatedContent = updatedContent.replace(replacement.oldStr, replacement.newStr);
}
if (content !== updatedContent) {
tree.overwrite(path, updatedContent);
}
});
};
}

/** Function that will be called when the migration completed. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {UnitTestTree} from '@angular-devkit/schematics/testing';
import {createTestCaseSetup} from '../../../../cdk/schematics/testing';
import {MIGRATION_PATH} from '../../paths';

const THEME_FILE_PATH = '/projects/cdk-testing/src/theme.scss';

describe('v20 rename tokens migration', () => {
let tree: UnitTestTree;
let writeFile: (filename: string, content: string) => void;
let runMigration: () => Promise<unknown>;

function stripWhitespace(content: string): string {
return content.replace(/\s/g, '');
}

beforeEach(async () => {
const testSetup = await createTestCaseSetup('migration-v20', MIGRATION_PATH, []);
tree = testSetup.appTree;
writeFile = testSetup.writeFile;
runMigration = testSetup.runFixers;
});

it('should rename mdc tokens to mat and change component ordering', async () => {
writeFile(
THEME_FILE_PATH,
`
html {
--mdc-icon-button-icon-size: 24px;
--mat-filled-button-color: red;
--mat-filled-text-field-color: red;
--mat-full-pseudo-checkbox-color: red;
--mat-legacy-button-toggle-color: red;
}
`,
);

await runMigration();

expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
stripWhitespace(`
html {
--mat-icon-button-icon-size: 24px;
--mat-button-filled-color: red;
--mat-form-field-filled-color: red;
--mat-pseudo-checkbox-full-color: red;
--mat-button-toggle-legacy-color: red;
}
`),
);
});
});
Loading