George Edwards
George Edwards

Reputation: 9229

Using a custom Material Design theme to control standard component colours?

I have an angular 7 project with Angular Material. I am using one of the standard themes. I am trying to control the progress bar component to be able to set it to change colour from red to green depending on it's value.

The only way I can see to control it's colour is to pass in one of primary / accent / warn.

However, I don't want to interfere with my main theme. I thought maybe I could approach this by creating a custom theme which extends the one I am currently using, e.g. :

@import '~@angular/material/theming';
@include mat-core();

$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);

$candy-app-warn:    mat-palette($mat-red);

$candy-app-green:  mat-palette($mat-green); // MY CUSTOM NAMED THEME ATTRIBUTE
$candy-app-red:    mat-palette($mat-red);  // MY CUSTOM NAMED THEME ATTRIBUTE

$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

// that you are using.
@include angular-material-theme($candy-app-theme);

and then controlling my component like this:

<mat-progress-bar mode="determinate" value="40" color="green"></mat-progress-bar>

I appreciate that the progress bar doesn't seem to support any other colour aliases, so not sure that I can make this approach work> Any ideas for how I could achieve this result. i.e. I want to change the colour of the progress bar without disrupting the rest of my app which relies on the existing theme.

Upvotes: 1

Views: 294

Answers (2)

Nenad Radak
Nenad Radak

Reputation: 3678

Create custom theme classes in theme file

  .red {
    $red-theme-primary: mat-palette($mat-red);
    $red-theme-accent:  mat-palette($mat-yellow, 400);
    $red-theme: mat-light-theme($red-theme-primary, $red-theme-accent);

    @include angular-material-theme($red-theme);
   }

  .green {
    $green-theme-primary: mat-palette($mat-green);
    $green-theme-accent:  mat-palette($mat-yellow, 400);
    $green-theme: mat-light-theme($green-theme-primary, $green-theme-accent);

    @include angular-material-theme($green-theme);
  }

Wrap mat tag with example div and add theme class with ngClass as dynamic parameter

  <div [ngClass]="progressColor">
   <!--wrap mat tag in div use class as defined in theme file -->
    <mat-progress-bar mode="determinate" value="progressValue" color="primary"></mat- 
    progress-bar>
  </div>

In ts file change values in conditions

  export class ProgressComponent implements OnInit {
     progressColor = "red";
     progressValue = 0;
     constructor() { }

    ngOnInit() {
      this.progressValue = this.getProgress(51);
    }
    getProgress(value: number): number {

      if (value <= 50) {
       this.progressColor = "red";
      }
      else {
       this.progressColor = "green";
      }
   return value;
  }
 }

example to get hint of changing color by using secondary themes.

Here is one example from previous answer also with secondary theme.

How to change color of angular material stepper step icons

Upvotes: 1

J. S.
J. S.

Reputation: 2376

You can have multiple material themes e.g:

    @import '~@angular/material/theming';
    @include mat-core();

    $candy-app-primary: mat-palette($mat-indigo);
    $candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);

    $candy-app-warn:    mat-palette($mat-red);

    $candy-app-green:  mat-palette($mat-green); // MY CUSTOM NAMED THEME ATTRIBUTE
    $candy-app-red:    mat-palette($mat-red);  // MY CUSTOM NAMED THEME ATTRIBUTE

    $candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

    // that you are using.
    @include angular-material-theme($candy-app-theme);

    .my-second-theme {

     $second-theme-primary: mat-palette($mat-indigo);
     $second-theme-accent:  mat-palette($mat-pink, A200, A100, A400);

     $second-theme-warn:    mat-palette($mat-red);

     $second-theme: mat-light-theme($second-theme-primary, $second-theme-accent, $second-theme-warn);
     @include angular-material-theme($second-theme);
    }

So everything wrapped inside a element with the class my-second-theme uses primary,accent and warn from your second theme without affecting your main app.

But if you just want to customize one specific color, you have to override the css classes from your component e.g:

.mat-progress-spinner {
    color: green
}

To get the class names you need to debug the elements in your browser and do a little try and error. It is better to have multiple themes with different color combinations and use them throughout your app.

Upvotes: 0

Related Questions