angularsassangular-materialmaterial3angular-theming

How to define 6 palettes in Angular Material 3?


I have Angular Material 3 project and I need to define 6 custom palettes:

primary
secondary
tertiary
error
neutral
neutral-variant

But, according to docs, when defining a theme, in color section we can only define 2 options: primary and tertiary.

How to add all 6 palettes to a theme?


Solution

  • There is no inputs to supply for secondary, etc. You can check the source code

    I would suggest the below approach to theming your code.

    First create a custom m3 theme, then you will be asked a bunch of questions.

    ng generate @angular/material:m3-theme
    

    After answering that, you will get a file, that contains the color definitions for each of the types you want. Style these as per your requirements. It will look like shown below.

    // This file was generated by running 'ng generate @angular/material:m3-theme'.
    // Proceed with caution if making changes to this file.
    
    @use 'sass:map';
    @use '@angular/material' as mat;
    
    // Note: Color palettes are generated from primary: #eeeeee, secondary: #fefefe, tertiary: #000000, neutral: #ffffff
    $_palettes: (
      primary: (
        0: #000000,
        10: #001f24,
        20: #00363d,
        25: #00424a,
        30: #004f58,
        35: #005b66,
        40: #006874,
        50: #008391,
        60: #00a0b0,
        70: #22bccf,
        80: #4fd8eb,
        90: #97f0ff,
        95: #d0f8ff,
        98: #edfcff,
        99: #f6feff,
        100: #ffffff,
      ),
      secondary: (
        0: #000000,
        10: #001f24,
        20: #00363d,
        25: #00424a,
        30: #004f58,
        35: #005b66,
        40: #006874,
        50: #008391,
        60: #00a0b0,
        70: #22bccf,
        80: #4fd8eb,
        90: #97f0ff,
        95: #d0f8ff,
        98: #edfcff,
        99: #f6feff,
        100: #ffffff,
      ),
      tertiary: (
        0: #000000,
        10: #3e001d,
        20: #5e1133,
        25: #6c1d3e,
        30: #7b2949,
        35: #893455,
        40: #984061,
        50: #b6587a,
        60: #d57193,
        70: #f48bae,
        80: #ffb1c8,
        90: #ffd9e2,
        95: #ffecf0,
        98: #fff8f8,
        99: #fffbff,
        100: #ffffff,
      ),
      neutral: (
        0: #000000,
        4: #000c0e,
        6: #001316,
        10: #001f24,
        12: #002429,
        17: #002f35,
        20: #00363d,
        22: #003b42,
        24: #004047,
        25: #00424a,
        30: #004f58,
        35: #005b66,
        40: #006874,
        50: #008391,
        60: #00a0b0,
        70: #22bccf,
        80: #4fd8eb,
        87: #81e9f9,
        90: #97f0ff,
        92: #aef3ff,
        94: #c5f6ff,
        95: #d0f8ff,
        96: #daf9ff,
        98: #edfcff,
        99: #f6feff,
        100: #ffffff,
      ),
      neutral-variant: (
        0: #000000,
        10: #141d1f,
        20: #293234,
        25: #343d3f,
        30: #3f484a,
        35: #4b5456,
        40: #576062,
        50: #6f797a,
        60: #899294,
        70: #a3adaf,
        80: #bfc8ca,
        90: #dbe4e6,
        95: #e9f2f4,
        98: #f2fbfd,
        99: #f6feff,
        100: #ffffff,
      ),
      error: (
        0: #000000,
        10: #410002,
        20: #690005,
        25: #7e0007,
        30: #93000a,
        35: #a80710,
        40: #ba1a1a,
        50: #de3730,
        60: #ff5449,
        70: #ff897d,
        80: #ffb4ab,
        90: #ffdad6,
        95: #ffedea,
        98: #fff8f7,
        99: #fffbff,
        100: #ffffff,
      ),
    );
    
    $_rest: (
      secondary: map.get($_palettes, secondary),
      neutral: map.get($_palettes, neutral),
      neutral-variant: map.get($_palettes,  neutral-variant),
      error: map.get($_palettes, error),
    );
    $_primary: map.merge(map.get($_palettes, primary), $_rest);
    $_tertiary: map.merge(map.get($_palettes, tertiary), $_rest);
    
    $light-theme: mat.define-theme((
      color: (
        theme-type: light,
        primary: $_primary,
        tertiary: $_tertiary,
      ),
    ));
    

    Then finally, apply this theme to your project and it will get applied using the below code, so you can notice that tertiary styles certain palette types are discarded. So there is no need to specify this.

    /// Defines an Angular Material theme object with color settings.
    /// @param {Map} $config The color configuration
    /// @return {Map} A theme object
    @function define-colors($config: ()) {
      $err: config-validation.validate-color-config($config);
      @if $err {
        @error $err;
      }
    
      $type: map.get($config, theme-type) or light;
      $primary: map.get($config, primary) or palettes.$violet-palette;
      $tertiary: map.get($config, tertiary) or $primary;
      $system-variables-prefix: map.get($config, system-variables-prefix) or sys;
      sass-utils.$use-system-color-variables: map.get($config, use-system-variables) or false;
    
      @return (
        $internals: (
          theme-version: $theme-version,
          theme-type: $type,
          palettes: (
            primary: map.remove($primary, neutral, neutral-variant, secondary),
            secondary: map.get($primary, secondary),
            tertiary: map.remove($tertiary, neutral, neutral-variant, secondary),
            neutral: map.get($primary, neutral),
            neutral-variant: map.get($primary, neutral-variant),
            error: map.get($primary, error),
          ),
          color-tokens: m3-tokens.generate-color-tokens(
              $type, $primary, $tertiary, map.get($primary, error), $system-variables-prefix)
        )
      );
    }