How To Access Angular Material Colors In Components?

Issue

In angular material, we can pass colors to angular material components as attribute, for example

<button mat-raised-button color="primary">Example</button>

I’m using multiple angular material themes, which changes dynamically.

Required Behaviour:
Changing color of my custom components dynamically with theme change.

I want something like this:

<app-footer color="primary"></app-footer>

How to get color in my custom component?

What I tried

I had a input property in my component

@Input() color;

and tried to pass color in component

<app-footer color="primary"></app-footer>

But it didn’t worked for me.

How to achieve this?

==UPDATE==

Explanation: Below lines of code are from button.ts file of angular material from its github repository

/**
 * Material design button.
 */
@Component({
  moduleId: module.id,
  selector: `button[mat-button], button[mat-raised-button], button[mat-icon-button],
             button[mat-fab], button[mat-mini-fab], button[mat-stroked-button],
             button[mat-flat-button]`,
  exportAs: 'matButton',
  host: {
    '[attr.disabled]': 'disabled || null',
    '[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"',
  },
  templateUrl: 'button.html',
  styleUrls: ['button.css'],
  inputs: ['disabled', 'disableRipple', 'color'],
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
})

Link to file: Button.ts

Here you can see, it takes color as input. Similarly, I have also taken color as input in my footer component. Now with <app-footer color="primary"></app-footer> I got primary string as input in my footer component.
How to get color hex from this to set background color of my footer component. Please note, primary color changes dynamically with theme change, therefore, I cannot hard-code color.

Solution

I found its solution. I’m posting it here so that if someone else requires similar behavior in their angular app, they can get it, in the following way.

I created a mixin for footer

 @mixin footer-theme($theme) {
        $primary: map-get($theme, primary);
        $accent: map-get($theme, accent);
        $warn: map-get($theme, warn);
        $background: map-get($theme, background);
        $foreground: map-get($theme, foreground);

        app-footer {
          .footer-primary {
              background-color: mat-color($primary);
          }
         .footer-accent {
              background-color: mat-color($accent);
          }
        }
      }

app-footer is a component selector and .footer-* is a class of footer component to whom I want to apply the primary/accent background color.

In the footer component, color is an input. We need to pass color value while embedding the footer component in the following way.

For the primary background color:

<app-footer color="primary"></app-footer>

For the accent background color:

<app-footer color="accent"></app-footer>

In the footer HTML file:

<div [ngClass]="{'footer-primary': color === 'primary', 'footer-accent': color === 'accent'}">
      /*footer code here...*/
</div>

Then I included footer mixin in app_theme.scss file which has multiple themes

@import '~@angular/material/theming';
@import './app/shared/footer/footer-theme';

@include mat-core();


$primary1: mat-palette($mat-teal, 500);
$accent1:  mat-palette($mat-green, A200, A100, A400);

$warn1:    mat-palette($mat-red);

$theme1: mat-light-theme($primary1, $accent1, $warn1);

@include angular-material-theme($theme1);
@include footer-theme($theme1);

// SECOND THEME
$primary2: mat-palette($mat-indigo, 500);

$accent2:  mat-palette($mat-blue, A200, A100, A400);

$warn2:    mat-palette($mat-red);

$theme2: mat-light-theme($primary2, $accent2, $warn2);

.second-theme {
    @include angular-material-theme($theme2);
    @include footer-theme($theme2);
}

In app.component.html

<div [ngClass]="{'second-theme' : isSecondTheme}">
    <div class="mat-app-background">
        <router-outlet></router-outlet>
    </div>
</div>

Here isSecondTheme is a boolean, when true second theme is applied, otherwise default theme. Just change boolean at runtime.

You can modify it to have more than two themes.

Answered By – Harinder Singh

Answer Checked By – David Goodson (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.