|
1 | | -# Theming your custom components |
2 | | -In order to style your own components with Angular Material's tooling, the component's styles must be defined with Sass. |
| 1 | +### Theming your custom component with Angular Material's theming system |
| 2 | +In order to style your own components with Angular Material's tooling, the component's styles must |
| 3 | +be defined with Sass. |
3 | 4 |
|
4 | | -### Using `@mixin` to automatically apply a theme |
5 | | - |
6 | | -#### Why using `@mixin` |
7 | | -The advantage of using a `@mixin` function is that when you change your theme, every file that uses it will be automatically updated. |
8 | | -Calling the `@mixin` with a different theme argument allows multiple themes within the app or component. |
9 | | - |
10 | | -#### How to use `@mixin` |
11 | | -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. |
12 | | - |
13 | | -All you need is to create a `@mixin` function in the custom-component-theme.scss |
| 5 | +#### 1. Define all color and typography styles in a "theme file" for the component |
| 6 | +First, create a Sass mixin that accepts an Angular Material theme and outputs the color-specific |
| 7 | +styles for the component. An Angular Material theme definition is a Sass map. |
14 | 8 |
|
| 9 | +For example, if building a custom carousel component: |
15 | 10 | ```scss |
16 | | -// Import all the tools needed to customize the theme and extract parts of it |
| 11 | +// Import library functions for theme creation. |
17 | 12 | @import '~@angular/material/theming'; |
18 | 13 |
|
19 | | -// Define a mixin that accepts a theme and outputs the color styles for the component. |
| 14 | +// Define a mixin that accepts a theme and outputs the theme-specific styles. |
20 | 15 | @mixin candy-carousel-theme($theme) { |
21 | | - // Extract whichever individual palettes you need from the theme. |
| 16 | + // Extract the palettes you need from the theme definition. |
22 | 17 | $primary: map-get($theme, primary); |
23 | 18 | $accent: map-get($theme, accent); |
24 | | - |
25 | | - // Use mat-color to extract individual colors from a palette as necessary. |
| 19 | + |
| 20 | + // Define any styles affected by the theme. |
26 | 21 | .candy-carousel { |
| 22 | + // Use mat-color to extract individual colors a palette. |
27 | 23 | background-color: mat-color($primary); |
28 | 24 | border-color: mat-color($accent, A400); |
29 | 25 | } |
30 | 26 | } |
31 | 27 | ``` |
32 | | -Now you just have to call the `@mixin` function to apply the theme: |
33 | 28 |
|
34 | | -```scss |
35 | | -// Import a pre-built theme |
36 | | -@import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; |
37 | | -// Import your custom input theme file so you can call the custom-input-theme function |
38 | | -@import 'app/candy-carousel/candy-carousel-theme.scss'; |
| 29 | +Second, create another Sass mixin that accepts an Angular Material typography definition and outputs |
| 30 | +typographic styles. For example: |
39 | 31 |
|
40 | | -// Using the $theme variable from the pre-built theme you can call the theming function |
41 | | -@include candy-carousel-theme($theme); |
| 32 | +```scss |
| 33 | +@mixin candy-caroursel-typography($config) { |
| 34 | + .candy-carousel { |
| 35 | + font: { |
| 36 | + family: mat-font-family($config, body-1); |
| 37 | + size: mat-font-size($config, body-1); |
| 38 | + weight: mat-font-weight($config, body-1); |
| 39 | + } |
| 40 | + } |
| 41 | +} |
42 | 42 | ``` |
43 | 43 |
|
44 | | -For more details about the theming functions, see the comments in the |
45 | | -[source](https://github.com/angular/material2/blob/master/src/lib/core/theming/_theming.scss). |
| 44 | +See the [typography guide](https://material.angular.io/guide/typography) for more information on |
| 45 | +typographic customization. |
46 | 46 |
|
47 | | -#### Best practices using `@mixin` |
48 | | -When using `@mixin`, the theme file should only contain the definitions that are affected by the passed-in theme. |
| 47 | +#### 2. Define all remaining styles in a normal component stylesheet. |
| 48 | +Define all styles unaffected by the theme in a separate file referenced directly in the component's |
| 49 | +`styleUrl`. This generally includes everything except for color and typography styles. |
49 | 50 |
|
50 | | -All styles that are not affected by the theme should be placed in a `candy-carousel.scss` file. |
51 | | -This file should contain everything that is not affected by the theme like sizes, transitions... |
52 | 51 |
|
53 | | -Styles that are affected by the theme should be placed in a separated theming file as |
54 | | -`_candy-carousel-theme.scss` and the file should have a `_` before the name. This file should |
55 | | -contain the `@mixin` function responsible for applying the theme to the component. |
| 52 | +#### 3. Include the theme mixin in your application |
| 53 | +Use the Sass `@include` keyword to include a component's theme mixin wherever you're already |
| 54 | +including Angular Material's built-in theme mixins. |
56 | 55 |
|
| 56 | +```scss |
| 57 | +// Import library functions for theme creation. |
| 58 | +@import '~@angular/material/theming'; |
| 59 | + |
| 60 | +// Include non-theme styles for core. |
| 61 | +@include mat-core(); |
| 62 | + |
| 63 | +// Define your application's custom theme. |
| 64 | +$primary: mat-palette($mat-indigo); |
| 65 | +$accent: mat-palette($mat-pink, A200, A100, A400); |
| 66 | +$theme: mat-light-theme($primary, $accent); |
| 67 | + |
| 68 | +// Include theme styles for Angular Material components. |
| 69 | +@include angular-material-theme($theme); |
| 70 | + |
| 71 | +// Include theme styles for your custom components. |
| 72 | +@include candy-carousel-theme($theme); |
| 73 | +``` |
57 | 74 |
|
58 | | -### Using colors from a palette |
59 | | -You can consume the theming functions and Material palette variables from |
60 | | -`@angular/material/theming`. You can use the `mat-color` function to extract a specific color |
61 | | -from a palette. For example: |
| 75 | + |
| 76 | +#### Note: using the `mat-color` function to extract colors from a palette |
| 77 | +You can consume the theming functions and Material Design color palettes from |
| 78 | +`@angular/material/theming`. The `mat-color` Sass function extracts a specific color from a palette. |
| 79 | +For example: |
62 | 80 |
|
63 | 81 | ```scss |
64 | 82 | // Import theming functions |
65 | 83 | @import '~@angular/material/theming'; |
66 | | -// Import your custom theme |
67 | | -@import 'src/unicorn-app-theme.scss'; |
68 | | - |
69 | | -// Use mat-color to extract individual colors from a palette as necessary. |
70 | | -// The hue can be one of the standard values (500, A400, etc.), one of the three preconfigured |
71 | | -// hues (default, lighter, darker), or any of the aforementioned prefixed with "-contrast". |
72 | | -// For example a hue of "darker-contrast" gives a light color to contrast with a "darker" hue. |
73 | | -// Note that quotes are needed when using a numeric hue with the "-contrast" modifier. |
74 | | -// Available color palettes: https://material.io/design/color/ |
| 84 | + |
75 | 85 | .candy-carousel { |
76 | | - background-color: mat-color($candy-app-primary); |
77 | | - border-color: mat-color($candy-app-accent, A400); |
78 | | - color: mat-color($candy-app-primary, '100-contrast'); |
| 86 | + // Get the default hue for a palette. |
| 87 | + color: mat-color($primary); |
| 88 | + |
| 89 | + // Get a specific hue for a palette. |
| 90 | + // See https://material.io/archive/guidelines/style/color.html#color-color-palette for hues. |
| 91 | + background-color: mat-color($accent, 300); |
| 92 | + |
| 93 | + // Get a relative color for a hue ('lighter' or 'darker') |
| 94 | + outline-color: mat-color($accent, lighter); |
| 95 | + |
| 96 | + // Get a constrast color for a hue by adding `-contrast` to any other key. |
| 97 | + border-color: mat-color($primary, '100-constrast'); |
79 | 98 | } |
80 | 99 | ``` |
0 commit comments