Angular Material MDC Migration
After migrating to the latest Material Design Components (MDC), many projects, including ours, have encountered style-related issues. In this write-up, we will explain how we resolved them.
We acknowledge that the core problem lies in creating components based on Material Components and modifying them to suit our specific use cases.
Here are the steps we followed to migrate from Material Components to Material MDC Components.
Note: You can Choose legacy components, but anyways we decided to go with MDC Migration.
Steps for MDC Migration
Upgrade Angular, Material, and run the mdc-migration script provided by the Material team.
You can either copy this code and create a batch file to run it or execute each step individually.
@ECHO OFF
call npm i typescript@4.8.x --force
call npm i zone.js @angular/flex-layout@15.0.0-beta.42 @angular-eslint/builder@15.x @angular-eslint/eslint-plugin@15.x @angular-eslint/eslint-plugin-template@15.x @angular-eslint/schematics@15.x @angular-eslint/template-parser@15.x --force
call npx ng update @angular/core@15 @angular/cli@15 --allow-dirty --force
call npx ng update @angular/material@15 --allow-dirty --force
call npx ng generate @angular/material:mdc-migration
PAUSE
Update your theme file
@use '@angular/material' as mat;
$ec--mat-typography: mat.define-typography-config(
$font-family: $aal-font-family,
$headline-4: mat.define-typography-level($aal-font-h1...),
$headline-3: mat.define-typography-level($aal-font-h2...),
...more settings
);
/* This is the new way of defining a theme from Angular 15 */
$ec--mat-light-theme: mat.define-light-theme((
color: (
primary: $aal--mat-primary-color,
accent: $aal--mat-accent-color,
warn: $aal--mat-warn-color
),
typography: $aal--mat-typography,
density: -1, // you can experiment with densities that suit your application
));
@include mat.typography-hierarchy($ec--mat-typography);
@include mat.core();
/**
It is important to include all component themes in the body
*/
body {
@include mat.all-component-themes($aal--mat-light-theme);
@include mat.button-density(-2); // these densities make more sense for my project, feel free to experiment
@include mat.icon-button-density(-2); // these densities make more sense for my project, feel free to experiment
}
Search throughout your application and replace the following classes, if you have used them.
Here is a comprehensive list of classes that are not automatically migrated by "ng generate @angular/material:mdc-migration"
Component | Old Class | New Class |
---|---|---|
mat-tab | mat-tab-label-active | mdc-tab--active |
mat-tab-label-content | mdc-tab__content | |
mat-tab-label-container | mat-mdc-tab-label-container | |
mat-tab-list | mat-mdc-tab-list | |
mat-tab-body-wrapper | mat-mdc-tab-body-wrapper | |
mat-tab-label | mat-mdc-tab | |
mat-tab-header-pagination-controls-enabled | mat-mdc-tab-header-pagination-controls-enabled | |
mat-tab-header-pagination | mat-mdc-tab-header-pagination | |
mat-tab-labels | mat-mdc-tab-labels | |
mat-chip | mat-chip-list | mat-mdc-chip-list |
mat-chip-list-wrapper | mat-chip-list-wrapper | |
mat-checkbox | mat-checkbox-frame | mdc-checkbox__checkmark |
mat-checkbox-label | mdc-label | |
mat-checkbox-checked | mat-mdc-checkbox-checked | |
mat-checkbox-label | mdc-label | |
mat-checkbox-layout | - | |
mat-button | mat-button-focus-overlay | mat-mdc-focus-indicator |
mat-radio | mat-radio-outer-circle | mdc-radio__outer-circle |
mat-radio-inner-circle | mdc-radio__inner-circle | |
mat-radio-checked | mat-mdc-radio-checked | |
mat-radio-label-content | mdc-label | |
mat-radio-label | mdc -label | |
mat-progress-bar | mat-progress-bar-buffer | mdc-linear-progress__buffer |
mat-form-field | mat-form-field-flex | mat-mdc-form-field-flex |
mat-form-field-wrapper | mat-mdc-text-field-wrapper | |
mat-form-field-underline | mdc-line-ripple | |
mat-form-field-subscript-wrapper | mat-mdc-form-field-subscript-wrapper | |
mat-form-field-prefix | mat-mdc-form-field-text-prefix | |
mat-form-field-suffix | mat-mdc-form-field-text-suffix | |
mat-form-field-infix | mat-mdc-form-text-infix | |
mat-form-field-label | mat-mdc-floating-label | |
mat-dialog | mat-dialog-container | mdc-dialog__container |
mat-dialog-content | mat-mdc-dialog-content | |
No Change | ||
mat-button-toggle | ||
mat-button-toggle-checked | ||
mat-button-toggle-disabled | ||
mat-button-toggle-focus-overlay |
Final Thoughts
It is highly likely that this setup may not be entirely comprehensive and depends on your project's settings. However, please feel free to add comments about your upgrades, as they may assist other projects.
Top comments (5)
mat-form-field-infix should be converted to mat-mdc-form-field-infix , because I couldn't find mat-mdc-form-text-infix in the new forms
I was comparing it to the markup in the migrated forms in our website, not any docs as such, I made a mistake in the comment before, the class I couldn't find was mat-mdc-form-text-infix not mat-mdc-text-field-wrapper, I have updated my comment.
I had to compare the migrated material forms with pages before migration in our other environment, and add padding etc to fix a lot of issues, check TODOs one by one, because we do custom styling on material forms.
If you start doing it, you will figure out the changed classes but it is a lot of work
I made that list for my project. It was really painfully to migrate it completely.
You can do it in phases:
Just migrate to higher version and check is everything working how it was, as Migrating to mdc is not mandatory, you can rollback your changes and still use non mdc version for now.
MDC migration: keys areas you need to look at is ng:deep and global mat classes.