arm
arm

Reputation: 186

Setting Mat-Button color in Angular Material 19 (M3)

I'm using angular material 19.0.3 and the m3 theming mechanism here's my style.scss

html {
  color-scheme: light dark;
  @include mat.theme((color: (
        primary: ft-green-theme.$primary-palette,
        tertiary: ft-green-theme.$tertiary-palette,
      ),
      typography: InterVariable,
      density: 0));

  &[dir='rtl'] {
    @include mat.theme((typography: IranSans,
      ));
  }
}

body.light {
  color-scheme: light;
}

body.dark {
  color-scheme: dark;
}

Now I have a button

<button mat-flat-button >click me</button>

I used to be able to do this

<button mat-flat-button color='danger'>click me</button>

and the button would be red.

But in the new version of angular material (19) they've changed things. I tried to read the documentation but I don't understand a thing.

In mat-button documentation it says:

Theme color of the button. This API is supported in M2 themes only, it has no effect in M3 themes.

For information on applying color variants in M3, see https://material.angular.io/guide/theming#using-component-color-variants.

And in the link provided there's just an explanation about how to give a color pallette as a theme.

But suppose, I'm gonna have a confirmation dialog and the yes button will be green and the cancel button will be red.

How am I supposed to color individual mat-buttons in angular material 19??

Upvotes: 2

Views: 814

Answers (2)

Zoaib Ahmed Khan
Zoaib Ahmed Khan

Reputation: 11

Easy way to create accent and other colored buttons in Angular Material v19 is simply to create another theme with your specific colors in a specific CSS selector. E.g.

.accent {
    @include mat.theme(
        (
          color: mat.$magenta-palette,
        )
      );
    }
    
 .warn {
      @include mat.theme(
        (
          color: mat.$red-palette,
        )
      );
    }

And then just simply apply the class to your button when you want.

<button class="accent" mat-flat-button>Accent button</button>

<button class="warn" mat-flat-button>Warn button</button>

I discussed all of this in a recent video, if you'd like more details.

https://youtu.be/5NSH8VvJH5o

Upvotes: 1

Naren Murali
Naren Murali

Reputation: 57986

When you use @include mat.theme(...) everything is taken care of internally, so there is no way to access the theme (to my knowledge) so you need to set the overrides manually using @include mat.button-overrides(( ... )).

This method could be a problem, since you just want to theme the button based on whether it's primary, secondary, etc.


As far as I know, the available options of types are 'primary', 'secondary', 'tertiary', 'error'.

We can define our own theme button by using mat.button-color, this mixin takes two arguments.

/// Outputs color theme styles for the mat-button.
/// @param {Map} $theme The theme to generate color styles for.
/// @param {ArgList} Additional optional arguments (only supported for M3 themes):
///   $color-variant: The color variant to use for the button: primary, secondary, tertiary,
///      or error (If not specified, default primary color will be used).
@mixin color($theme, $options...) {

The first is the theme, but when we use @include mat.theme(...) we do not have this theme stored in a SCSS property, hence we can use the previous method of using mat.define-theme, Which provides the theme for use to customize.

$theme: mat.define-theme(
  (
    color: (
      theme-type: light,
      primary: mat.$azure-palette,
      tertiary: mat.$magenta-palette,
    ),
    density: (
      scale: 0,
    ),
  )
);

After this, it is simply a matter of inputting this theme to the function and setting the color variant.

body {
  font-family: Roboto, 'Helvetica Neue', sans-serif;
  margin: 0;
  padding: 30px;
  height: 100%;
  @include mat.all-component-themes($theme);

  .primary {
    @include mat.button-color($theme: $theme, $color-variant: 'primary');
  }

  .secondary {
    @include mat.button-theme($theme: $theme, $color-variant: 'secondary');
  }

  .tertiary {
    @include mat.button-theme($theme: $theme, $color-variant: 'tertiary');
  }

  .error {
    @include mat.button-theme($theme: $theme, $color-variant: 'error');
  }
}

Full Code:

SCSS:

@use '@angular/material' as mat;

$theme: mat.define-theme(
  (
    color: (
      theme-type: light,
      primary: mat.$azure-palette,
      tertiary: mat.$magenta-palette,
    ),
    density: (
      scale: 0,
    ),
  )
);

body {
  font-family: Roboto, 'Helvetica Neue', sans-serif;
  margin: 0;
  padding: 30px;
  height: 100%;
  @include mat.all-component-themes($theme);

  .primary {
    @include mat.button-color($theme: $theme, $color-variant: 'primary');
  }

  .secondary {
    @include mat.button-theme($theme: $theme, $color-variant: 'secondary');
  }

  .tertiary {
    @include mat.button-theme($theme: $theme, $color-variant: 'tertiary');
  }

  .error {
    @include mat.button-theme($theme: $theme, $color-variant: 'error');
  }
}

html {
  height: 100%;
}

@include mat.typography-hierarchy($theme);

TS:

import { Component } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { MatDividerModule } from '@angular/material/divider';
import { MatButtonModule } from '@angular/material/button';
import { CommonModule } from '@angular/common';

/**
 * @title Basic buttons
 */
@Component({
  selector: 'button-overview-example',
  templateUrl: 'button-overview-example.html',
  styleUrl: 'button-overview-example.css',
  imports: [MatButtonModule, MatDividerModule, MatIconModule, CommonModule],
})
export class ButtonOverviewExample {
  types = ['primary', 'secondary', 'tertiary', 'error'];
}

HTML:

@for(type of types; track $index) {
<section>
  <div class="example-label">Basic {{type}}</div>
  <div class="example-button-row">
    <button mat-button [ngClass]="type">Basic</button>
    <button mat-button disabled [ngClass]="type">Disabled</button>
    <a
      mat-button
      href="https://www.google.com/"
      target="_blank"
      [ngClass]="type"
      >Link</a
    >
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Raised {{type}}</div>
  <div class="example-button-row">
    <button mat-raised-button [ngClass]="type">Basic</button>
    <button mat-raised-button disabled [ngClass]="type">Disabled</button>
    <a
      mat-raised-button
      href="https://www.google.com/"
      target="_blank"
      [ngClass]="type"
      >Link</a
    >
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Stroked {{type}}</div>
  <div class="example-button-row">
    <button mat-stroked-button [ngClass]="type">Basic</button>
    <button mat-stroked-button disabled [ngClass]="type">Disabled</button>
    <a
      mat-stroked-button
      href="https://www.google.com/"
      target="_blank"
      [ngClass]="type"
      >Link</a
    >
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Flat {{type}}</div>
  <div class="example-button-row">
    <button mat-flat-button [ngClass]="type">Basic</button>
    <button mat-flat-button disabled [ngClass]="type">Disabled</button>
    <a
      mat-flat-button
      href="https://www.google.com/"
      target="_blank"
      [ngClass]="type"
      >Link</a
    >
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Icon {{type}}</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <button
        mat-icon-button
        aria-label="Example icon button with a vertical three dot icon"
        [ngClass]="type"
      >
        <mat-icon>more_vert</mat-icon>
      </button>
      <button
        mat-icon-button
        disabled
        aria-label="Example icon button with a open in new tab icon"
        [ngClass]="type"
      >
        <mat-icon>open_in_new</mat-icon>
      </button>
    </div>
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">FAB {{type}}</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <div class="example-button-container">
        <button
          mat-fab
          aria-label="Example icon button with a delete icon"
          [ngClass]="type"
        >
          <mat-icon>delete</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-fab
          disabled
          aria-label="Example icon button with a heart icon"
          [ngClass]="type"
        >
          <mat-icon>favorite</mat-icon>
        </button>
      </div>
    </div>
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Mini FAB {{type}}</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <div class="example-button-container">
        <button
          mat-mini-fab
          aria-label="Example icon button with a menu icon"
          [ngClass]="type"
        >
          <mat-icon>menu</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-mini-fab
          disabled
          [ngClass]="type"
          aria-label="Example icon button with a home icon"
        >
          <mat-icon>home</mat-icon>
        </button>
      </div>
    </div>
  </div>
</section>
}
<mat-divider></mat-divider>
@for(type of types; track $index) {
<section>
  <div class="example-label">Extended Fab {{type}}</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <div class="example-button-container">
        <button mat-fab extended [ngClass]="type">
          <mat-icon>favorite</mat-icon>
          Basic
        </button>
      </div>
      <div class="example-button-container">
        <button mat-fab extended disabled [ngClass]="type">
          <mat-icon>favorite</mat-icon>
          Disabled
        </button>
      </div>
      <div class="example-button-container">
        <a mat-fab extended routerLink="." [ngClass]="type">
          <mat-icon>favorite</mat-icon>
          Link
        </a>
      </div>
    </div>
  </div>
</section>
}

Stackblitz Demo

Upvotes: 2

Related Questions