angularangular-material

How to keep colors and buttons design in Angular switching from M2 to M3 theme


Angular crashed my whole layout with the new theming in version 19.

Before with the M2 theming my buttons looked like:

enter image description here

This is the M2 code for the normal colors:

$my-app-primary: mat.m2-define-palette(mat.$m2-blue-palette, 500);
$my-app-accent: mat.m2-define-palette(mat.$m2-deep-orange-palette, 500, 900, A100);
$my-app-warn: mat.m2-define-palette(mat.$m2-red-palette);

$my-app-theme: mat.m2-define-light-theme((
    color: (primary: $my-app-primary,
            accent: $my-app-accent,
            warn: $my-app-warn,
        ),
    typography: mat.m2-define-typography-config(),
    density: 0,
));

Now with M3 and the mat.$blue-palette as base it looks complete different (no blue buttons anymore e.g.):

enter image description here

I tried to create a _theme_colors.scss file with

ng generate @angular/material:theme-color

and entered the old primary color blue, the orange and the red as primary, secondary (why not accent?) etc. But that may change the color of the text but not the buttons as whole.

This is my new M3 code:

@use '@angular/material' as mat;
@use './theme-colors.scss' as my-colors; //My generated color palette file
@include mat.core();

.global-light-theme {
   @include mat.theme(
   (
      color: (
        //primary: my-colors.$primary-palette, 
        primary: mat.$blue-palette,
      )    
   ));
}

This is the code I have as an example to create 3 test buttons:

<button mat-raised-button color="primary">Primary</button>
<button mat-raised-button color="accent">Accent</button>
<button mat-raised-button color="warn">Warning</button>

I really want to use the new M3 theming stuff - but I don't want to change it my whole look and feel of my app/website.

And we're only talking about the colors that are broken and not the corners that are far too round. That's another issue.


Solution

  • What you need to understand

    There is absolutely no way you're going to be able to used the "color" variant the old way UNLESS you go for the backward compatibility option.

    Why

    Because Material 3 justifies it by separation of concerns principle: Colors should not be part of components, they should be defined outside of components and used in a non invasive way, like the "color" variant.

    For backward compatibility

    I believe this documentation is what you could be looking for:

    Now, I was exactly in your situation a few days ago, and after a LOT of digging, this is how i managed to things:

    Use a Color Map instead of a single color. Consider that "accent" is now "tertiary" (at least this is how it is presented in the official docs, as they push you to use it as an accent color).

    Color Map

    @use "styles/theme-colors-light" as theme-light;
    
    html {
      color-scheme: light;
      @include mat.theme(
          (
            color: (
              primary: theme-light.$primary-palette,
              tertiary: theme-light.$tertiary-palette, // No idea how to use this one, i personaly got rid of it.
              theme-type: light,
            ),
            density: 0,
            typography: (
              plain-family: "Open Sans",
              brand-family: "Josefin Sans, sans-serif",
              bold-weight: 700,
              medium-weight: 500,
              regular-weight: 300,
            )
          )
      );
    
      .mat-tertiary {
        @include mat.theme(
            (
              color: (
                primary: theme-light.$tertiary-palette,
                theme-type: light,
              ),
            )
        );
      }
    
      .mat-error {
        @include mat.theme(
            (
              color: (
                primary: theme-light.$error-palette,
                theme-type: light,
              ),
            )
        );
      }
    

    Whenever you'll want to use an equivalent to color="warn", use: class="mat-error". Whatever angular component is under a container with class "mat-error", will have the specified theme.

    Whenever you'll want to use an equivalent to color="accent", use: "mat-tertiary".

    Elevation

    here is what i personaly use (forget about the .mat-elevation-z[0..24] classes, unless once again you go for the M2 backward compatibility option)

    .mat-elevation-z0 {
      box-shadow: var(--mat-sys-level0)
    }
    
    .mat-elevation-z1 {
      box-shadow: var(--mat-sys-level1)
    }
    
    .mat-elevation-z2 {
      box-shadow: var(--mat-sys-level2)
    }
    
    .mat-elevation-z3 {
      box-shadow: var(--mat-sys-level3)
    }
    
    .mat-elevation-z4 {
      box-shadow: var(--mat-sys-level4)
    }
    
    .mat-elevation-z5 {
      box-shadow: var(--mat-sys-level5)
    }