Demo in Angular Material 18
I am going to use the same demo as in the previous course, you can clone it from here.
Updating Angular Material 18 to 19
1. Checking for updates
ng update
2. Update Angular CLI
ng update @angular/cli
3. Update Angular Material
ng update @angular/material
Style changes for Angular Material 19
1. Updates in main theme file
We will start with making changes in main theme file at src/styles.scss
.
1.1 Remove redundant mixin usages
As we already have them outside, remove usage of mat.elevation-classes
and mat.app-background
mixins from withing :root
selector.
@include mat.elevation-classes();@include mat.app-background();
:root { @include mat.elevation-classes(themes.$my-app-theme); @include mat.app-background(themes.$my-app-theme);}
1.2 Remove individual component themes
:root { @include mat.button-theme(themes.$my-app-theme); @include mat.icon-theme(themes.$my-app-theme); @include mat.menu-theme(themes.$my-app-theme); @include mat.form-field-theme(themes.$my-app-theme); @include mat.input-theme(themes.$my-app-theme);}
1.3 Changes for typography
Move typography mixin outside of :root
and remove usage of themes.$my-app-theme
in it.
@include mat.typography-hierarchy( mat.define-theme( ( typography: ( use-system-variables: true, system-variables-prefix: mat-sys, ), ) ));
:root { @include mat.typography-hierarchy(themes.$my-app-theme);}
1.4 Use new theme mixin
:root { @include mat.theme( ( color: ( primary: mat.$azure-palette, tertiary: mat.$blue-palette, ), typography: Roboto, density: 0, ) );}
We will modify the theme colors in next section.
1.5 Remove usage of system-level mixins
:root { @include mat.system-level-colors(themes.$my-app-theme); @include mat.system-level-typography(themes.$my-app-theme);}
1.6 Changes in button-overrides
As some properties from v18 of button-overrides
mixin are deprecated in v19, we need to use the new properties. Replace code of .overrides-example
with the following:
// Customizing the button appearance using overrides API.overrides-example { button { @include mat.button-overrides( ( filled-container-color: #00ff00, protected-container-color: #00ff00, filled-container-height: 64px, outlined-container-height: 64px, protected-container-height: 64px, text-container-height: 64px, filled-container-shape: 32px, outlined-container-shape: 32px, protected-container-shape: 32px, text-container-shape: 32px, filled-label-text-color: orange, outlined-label-text-color: orange, protected-label-text-color: orange, text-label-text-color: orange, filled-ripple-color: #ff0000, protected-ripple-color: #ff0000, outlined-ripple-color: #ff0000, text-ripple-color: #ff0000, outlined-outline-color: #0000ff, ) ); }}
2. Updates in dark theme
We will make similar changes in dark theme file at src/styles/themes/dark.scss
.
2.1 Remove redundant mixin usages
.dark-theme { @include mat.elevation-classes(); @include mat.app-background();}
2.2 Remove individual component colors
.dark-theme { @include mat.button-color(themes.$my-app-dark-theme); @include mat.icon-color(themes.$my-app-dark-theme); @include mat.menu-color(themes.$my-app-dark-theme); @include mat.form-field-color(themes.$my-app-dark-theme); @include mat.input-color(themes.$my-app-dark-theme);}
2.3 Use color-scheme
.dark-theme { color-scheme: dark;}
2.4 Remove usage of system-level mixins
.dark-theme { @include mat.system-level-colors(themes.$my-app-dark-theme); @include mat.system-level-typography(themes.$my-app-dark-theme);}
3. Custom component style changes
3.1 Changes in component styles barrel file
Let’s clean up the barrel file at src/styles/components/_index.scss
and keep only single line:
@forward "../../app/shared/components/alert/alert-theme.css";
3.2 Remove usage of theme mixin
Remove usage of components.theme
mixin from src/styles.scss
and src/styles/themes/dark.scss
files.
3.3 Using correct tokens
Simply find --sys
and replace it with --mat-sys
in whole project.
4. Changes for custom theme
We will make changes in src/styles/themes/_custom-theme.scss
file.
4.1 Remove usage of define-theme function
$custom-theme: mat.define-theme( ( color: ( primary: mat.$rose-palette, tertiary: mat.$red-palette, use-system-variables: false, ), typography: ( plain-family: sans-serif, brand-family: monospace, use-system-variables: false, ), density: ( scale: -3, ), ));
4.2 Remove component themes
.custom-theme { @include mat.button-color($custom-theme); @include mat.button-typography($custom-theme); @include mat.button-density($custom-theme);}
4.3 Use new theme mixin
.custom-theme { @include mat.theme( ( color: ( primary: mat.$rose-palette, tertiary: mat.$red-palette, ), typography: ( plain-family: sans-serif, brand-family: monospace, ), density: -3, ) );}
5. Remove usage of M3 theme file
We want to remove usage of m3-theme.scss
file.
- Delete
m3-theme.scss
file. - Delete
src/styles/themes/_all.scss
file.
6. Create and use new palette file
6.1 Create new palette file
We will create new palette file at src/styles/themes/
.
ng generate @angular/material:theme-color --primary-color 6750a4 --directory src/styles/themes/ --interactive false
6.2 Use new palette file
We will use this palette in src/styles.scss
file.
@use "./styles/themes/theme-colors";
:root { @include mat.theme( ( color: ( primary: mat.$azure-palette, primary: theme-colors.$primary-palette, tertiary: mat.$blue-palette, tertiary: theme-colors.$tertiary-palette, ), typography: Roboto, density: 0, ) );}
6.2.1 Changes for button color variants
For button color variants, we need to remove usage of button-color
mixin and use theme-overrides
mixin instead. Note that buttons in Angular Material relies heavily on primary color, so we need to simply override it.
@each $variant in $color-variants { .mat-#{$variant} { @include mat.button-color(themes.$my-app-theme, $color-variant: $variant); @include mat.theme-overrides( ( primary: var(--mat-sys-#{$variant}), on-primary: var(--mat-sys-on-#{$variant}), ) ); }}
Changes for color picker
If you change the color from color picker, you will see that the colors are not updated on the UI. This is because the color picker generates CSS variables with --sys
prefix, but we are using --mat-sys
prefix in our project.
We need to update the color picker to use --mat-sys
prefix. Simply add below at the end of generateDynamicTheme
function in src/app/shared/components/color-picker/color-picker.component.ts
:
generateDynamicTheme(isDark?: boolean) { // rest remains same
const styles = targetElement.style; for (const key in styles) { if (Object.prototype.hasOwnProperty.call(styles, key)) { const propName = styles[key]; if (propName.indexOf('--md-sys') === 0) { const sysPropName = '--mat-sys' + propName.replace('--md-sys-color', ''); targetElement.style.setProperty( sysPropName, targetElement.style.getPropertyValue(propName) ); } } } }
Changes for density
As of Angular Material 19.1, there is no API available from which we can get density. So, we need to manually pass the density value to alert component.
Let’s clean up src/app/shared/components/alert/_alert-theme.scss
file, and keep only below content:
@use "sass:map";@use "@angular/material" as mat;
@mixin density($density) { $spacing: ( 0: 16px, -1: 12px, -2: 10px, -3: 8px, -4: 6px, -5: 4px, ); $scale-spacing: map.get($spacing, $density); .alert { padding: $scale-spacing; margin-bottom: $scale-spacing;
hr { margin: $scale-spacing 0; } }}
Next, add forward this file from src/styles/components/_index.scss
file.
@forward "../../app/shared/components/alert/alert-theme.css";@forward "../../app/shared/components/alert/alert-theme" as alert-theme-*;
Lastly, go to main styles file at src/styles.scss
and update the code include alert-theme-density
mixin.
// rest remains same
:root { $density: 0; @include mat.theme( ( color: ( primary: theme-colors.$primary-palette, tertiary: theme-colors.$tertiary-palette, ), typography: Roboto, density: 0, density: $density, ) );
@include components.alert-theme-density($density);}
Summary of changes for Angular Material Theming API
# | Old API | New API |
---|---|---|
1 | mat.define-theme function | mat.theme mixin |
2 | mat.get-theme-color function | --mat-sys-<color> system variable |
2.1 (Example) | color: mat.get-theme-color($theme, primary); | color: var(--mat-sys-primary); |
2.2 (Example) | color: mat.get-theme-color($theme, on-primary-container); | color: var(--mat-sys-on-primary-container); |
3 | mat.get-theme-typography function | --mat-sys-<level>-<size>-<token> system variable |
3.1 (Example) | font: mat.get-theme-typography($theme, "display-large"); | font: var(--mat-sys-display-large); |
3.2 (Example) | letter-spacing: mat.get-theme-typography($theme, "body-medium", "letter-spacing"); | letter-spacing: var(--mat-sys-body-medium-tracking); |
4 | mat.get-theme-density function | No equivalent new API, manually pass density |
5 | mat.typography-hierarchy mixin | Still available in new API, but not recommended to use. Instead, manually use typography system variables. |