Scenario
We want to create a SASS mixin
for the for extending the colors of the Fab Button with success
, danger
, and info
colors following a simple repeatable pattern.
Approach
We will extend the theming of Angular Material per component allowing us to import theme extensions in a minimal fashion when creating light weight applications.
In order to do this we will implement a theming template like this one for the Fab Button component.
@use "sass:map";
@use "@angular/material" as mat;
@mixin structure($theme) {}
@mixin color($theme) {}
@mixin typography($theme) {}
@mixin density($theme) {}
@mixin theme($theme) {
$color: mat.get-color-config($theme);
$density: mat.get-density-config($theme);
$typography: mat.get-typography-config($theme);
@if $color != null {
//==========================================
// Note that we pass in $theme
// to avoid any restructing that
// mat.get-color-config might do.
//==========================================
@include color($theme);
}
@if $density != null {
@include density($density);
}
@if $typography != null {
@include typography($typography);
}
@include structure($theme);
}
Note themes that call the theme
mixin for a specific component will get the components structure
style included automatically (No if check) .
This is fine since calling the theme
function should be done for the default style only, and all other themes that are non default, should change colors only, since styles like structure
and typography
should be defined in the default theme.
Here’s the implementation. We delegate styling for each color variation to fab-variant
.
@use "sass:map";
@use "@angular/material" as mat;
@use "@material/theme/theme-color" as mdc-theme-color;
@use "./fab-variant" as *;
@use "../common/colors" as *;
@mixin color($theme) {
$colors: colors($theme);
//==========================================
// Use the same approach that
// _fab-theme.scss uses.
//==========================================
.mat-mdc-fab {
@include fab-variant(
mat-success,
map.get($colors, on-success),
map.get($colors, success)
);
@include fab-variant(
mat-danger,
map.get($colors, on-danger),
map.get($colors, danger)
);
@include fab-variant(
mat-info,
map.get($colors, on-info),
map.get($colors, info)
);
}
}
@mixin structure($theme) {}
@mixin typography($theme) {}
@mixin density($theme) {}
@mixin theme($theme) {
$color: mat.get-color-config($theme);
$density: mat.get-density-config($theme);
$typography: mat.get-typography-config($theme);
@if $color != null {
//==========================================
// Note that we pass in $theme
// to avoid any restructing that
// mat.get-color-config might do.
//==========================================
@include color($theme);
}
@if $density != null {
@include density($density);
}
@if $typography != null {
@include typography($typography);
}
}
Applications that want to extend the theming colors for the Fab button only need to import this SASS module.
The fab-variant
mixin
delegates to the Material Component Web @material/fab/fab-theme
mixin
to generate the CSS variables for the color context and calls the locally defined ripple-color
, which creates the variables for the ripple color.
@use '@material/fab/fab-theme' as mdc-fab-theme;
@use '../common/' as *;
@mixin fab-variant($color-class, $foreground, $background) {
&.#{ $color-class } {
@include mdc-fab-theme.theme(
(
container-color: $background,
icon-color: $foreground,
)
);
background-color: var(--mdc-fab-container-color, transparent);
color: var(--mdc-fab-icon-color, inherit);
@include ripple-color($foreground);
}
}
The ripple color mixin
is defined like this.
/**
* Define the ripple color variables.
*/
@mixin ripple-color($color) {
--mat-mdc-button-persistent-ripple-color: #{$color};
--mat-mdc-button-ripple-color: #{rgba($color, 0.1)};
}
Demo
The fab-variant
code is contained in the foldersrc/fab-variant
.
There’s also a el-theme.scss
used to extend the Angular Material defined theme with success
, danger
, and info
colors.