Theming your own components

Theming your custom components

In order to style your own components with Angular Material's tooling, the component's styles must be defined with Sass.

The advantage of using a @mixin function is that when you change your theme, every file that uses it will be automatically updated. Calling the @mixin with a different theme argument allows multiple themes within the app or component.

We can better theme our custom components by adding a @mixin function to its theme file, and then call this function to apply a theme.

All you need is to create a @mixin function in the custom-component-theme.scss

// Import all the tools needed to customize the theme and extract parts of it
@import '~@angular/material/theming';

// Define a mixin that accepts a theme and outputs the color styles for the component.
@mixin candy-carousel-theme($theme) {
  // Extract whichever individual palettes you need from the theme.
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);

  // Use mat-color to extract individual colors from a palette as necessary.
  .candy-carousel {
    background-color: mat-color($primary);
    border-color: mat-color($accent, A400);
  }
}

Now you just have to call the @mixin function to apply the theme:

// Import a pre-built theme
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
// Import your custom input theme file so you can call the custom-input-theme function
@import 'app/candy-carousel/candy-carousel-theme.scss';

// Using the $theme variable from the pre-built theme you can call the theming function
@include candy-carousel-theme($theme);

For more details about the theming functions, see the comments in the source.

When using @mixin, the theme file should only contain the definitions that are affected by the passed-in theme.

All styles that are not affected by the theme should be placed in a candy-carousel.scss file. This file should contain everything that is not affected by the theme like sizes, transitions...

Styles that are affected by the theme should be placed in a separated theming file as _candy-carousel-theme.scss and the file should have a _ before the name. This file should contain the @mixin function responsible for applying the theme to the component.

You can consume the theming functions and Material palette variables from @angular/material/theming. You can use the mat-color function to extract a specific color from a palette. For example:

// Import theming functions
@import '~@angular/material/theming';
// Import your custom theme
@import 'src/unicorn-app-theme.scss';

// Use mat-color to extract individual colors from a palette as necessary.
// The hue can be one of the standard values (500, A400, etc.), one of the three preconfigured
// hues (default, lighter, darker), or any of the aforementioned prefixed with "-contrast".
// For example a hue of "darker-contrast" gives a light color to contrast with a "darker" hue.
// Note that quotes are needed when using a numeric hue with the "-contrast" modifier.
// Available color palettes: https://material.io/design/color/
.candy-carousel {
  background-color: mat-color($candy-app-primary);
  border-color: mat-color($candy-app-accent, A400);
  color: mat-color($candy-app-primary, '100-contrast');
}