Reputation: 2684
I would like to have access to more than 3 colors for my material theme.
For example, I would like to add in $theme-success: mat-pallete($mat-green) to have a green success color in my Material components like md-checkbox color="success"
.
@import '~@angular/material/theming';
@include mat-core();
$theme-primary: mat-palette($mat-blue);
$theme-accent: mat-palette($mat-yellow, A400, A200, A600);
$theme-warn: mat-palette($mat-red);
$theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);
.body-light {
@include angular-material-theme($theme);
}
Is this possible?
Upvotes: 3
Views: 8221
Reputation: 5040
With angular 15 in 2023 you can use next mixin for applying color="success"
and color="info"
:
mat-button-variants.scss
@use 'sass:map';
@use 'sass:meta';
@use '@angular/material' as mat;
$_ripple-opacity: 0.1;
// Applies a focus style to an mat-button element for each of the supported palettes.
@mixin _focus-overlay-color($config-or-theme, $variants) {
$config: mat.get-color-config($config-or-theme);
@each $variant, $variant-palette in $variants {
&.mat-#{$variant} .mat-button-focus-overlay {
background-color: mat.get-color-from-palette($variant-palette);
}
}
}
@mixin _ripple-background($palette, $hue, $opacity) {
$background-color: mat.get-color-from-palette($palette, $hue, $opacity);
background-color: $background-color;
@if (meta.type-of($background-color) != color) {
opacity: $opacity;
}
}
@mixin _ripple-color($theme, $hue, $opacity, $variants) {
@each $variant, $variant-palette in $variants {
&.mat-#{$variant} .mat-ripple-element {
@include _ripple-background($variant-palette, $hue, $opacity);
}
}
}
// Applies a property to an mat-button element for each of the supported palettes.
@mixin _theme-property($theme, $property, $hue, $variants) {
$background: map.get($theme, background);
$foreground: map.get($theme, foreground);
@each $variant, $variant-palette in $variants {
&.mat-#{$variant} {
#{$property}: mat.get-color-from-palette($variant-palette, $hue);
}
&.mat-#{$variant} {
&.mat-button-disabled {
$palette: if($property == 'color', $foreground, $background);
#{$property}: mat.get-color-from-palette($palette, disabled-button);
}
}
}
}
@mixin color($config-or-theme, $variants) {
$config: mat.get-color-config($config-or-theme);
$foreground: map.get($config, foreground);
$background: map.get($config, background);
.mdc-button:not(:disabled),
.mat-mdc-icon-button:not(:disabled),
.mat-mdc-stroked-button:not(:disabled) {
@include _theme-property($config, 'color', text, $variants);
@include _focus-overlay-color($config, $variants);
}
.mat-mdc-flat-button:not(:disabled),
.mat-mdc-raised-button:not(:disabled),
.mat-mdc-unelevated-button:not(:disabled),
.mat-mdc-fab:not(:disabled),
.mat-mdc-mini-fab:not(:disabled) {
@include _theme-property($config, 'color', default-contrast, $variants);
@include _theme-property($config, 'background-color', default, $variants);
@include _ripple-color($config, default-contrast, $_ripple-opacity, $variants);
}
}
you should define a scss map object with palettes for success and info:
material-theme-index.scss:
@use './mat-button-variants' as button-variants;
...
$theme-success: mat.define-palette($palette-success);
$theme-info: mat.define-palette($palette-info);
$variants-theme: (
success: $theme-success,
info: $theme-info,
);
// and include mixin above
@include button-variants.color($main-theme, $variants-theme);
and now it will work as should in
<button mat-raised-button color="success">Click me</button>
PS: if you use material lower versions like 14 and below please rename mdc
to mat
in classes due to latest breaking changes in material v15 with extra classes prefixes mdc
. Current example works for angular 15+.
Upvotes: 1
Reputation: 1503
I did the following to make full use of the button features
@import '~@angular/material/theming';
// Plus imports for other components in your app.
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$my-app-primary: mat-palette($mat-deep-purple);
$my-app-accent: mat-palette($mat-amber, A200, A100, A400);
$my-app-green: mat-palette($mat-green); // <------ My new palette
// The warn palette is optional (defaults to red).
$my-app-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($my-app-theme);
@import './buttons';
.mat-raised-button {
&.mat-green {
color: mat-color($my-app-green, darker-contrast);
background-color: mat-color($my-app-green, default);
&[disabled] {
color: mat-color($mat-light-theme-foreground, disabled-button);
background-color: mat-color($mat-light-theme-background, disabled-button);
}
.mat-ripple-element {
@include _mat-button-ripple-background($my-app-green, darker-contrast, $_mat-button-ripple-opacity);
}
}
}
Everything I needed to figure these out are in \node_modules\@angular\material\_theming.scss
And a starting point from here
Upvotes: 1
Reputation: 86
Also, if you really need an extra color you can create class in styles.scss (or.css) or anywhere in your style sheets.
.mat-buttonSuccess{
background-color: #ffff00;
color: #000;
}
and then call it as color same way as primary, accent and warn.
<button mat-raised-button color="buttonSuccess">Success</button>
Upvotes: 4
Reputation: 3715
The color
bindings only support primary, accent, and warn.
If the coloring is simple (for checkbox, it's just .mat-checkbox-background
and .mat-ripple-element
), you can use the palette yourself:
$theme-success: mat-palette($mat-green);
.mat-checkbox-ripple .mat-ripple-element {
background-color: mat-color($theme-success, 0.26);
}
You could probably also get away with making 2 themes, where the second one uses your success color for primary
$theme-primary: mat-palette($mat-blue);
$theme-accent: mat-palette($mat-yellow, A400, A200, A600);
$theme-warn: mat-palette($mat-red);
$theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);
$theme-success: mat-palette($mat-green);
$theme2: mat-light-theme($theme-success, $theme-accent, $theme-warn);
.body-light {
@include angular-material-theme($theme);
}
.component-success {
@include angular-material-theme($theme2);
}
Upvotes: 6