|
| 1 | +@use 'sass:map'; |
1 | 2 | @use '@angular/material' as mat;
|
2 | 3 | @use '@angular/material-experimental';
|
3 | 4 |
|
@@ -32,32 +33,84 @@ $light-theme: mat.define-light-theme((
|
32 | 33 | density: 0
|
33 | 34 | ));
|
34 | 35 |
|
35 |
| -$dark-theme: mat.define-dark-theme(( |
36 |
| - color: ( |
37 |
| - primary: mat.define-palette(mat.$blue-grey-palette), |
38 |
| - accent: mat.define-palette(mat.$amber-palette, A200, A100, A400), |
39 |
| - warn: mat.define-palette(mat.$deep-orange-palette), |
40 |
| - ), |
41 |
| - typography: mat.define-typography-config(), |
42 |
| - density: 0, |
| 36 | +// Apply all checkbox tokens (derived from `$light-theme`) to the `body` element. |
| 37 | +// This ensures that all checkboxes within the body inherit these tokens. |
| 38 | +@include material-experimental.theme($tokens: mat.m2-tokens-from-theme($light-theme), $components: ( |
| 39 | + material-experimental.checkbox(), |
43 | 40 | ));
|
44 | 41 |
|
45 |
| -// Set up light theme. |
| 42 | +// Apply tokens related to the theme type to any element with `.demo-unicorn-dark-theme`. |
| 43 | +// This ensures that checkboxes within the element inherit the new tokens for dark theme, |
| 44 | +// rather than the ones for light theme set on `body`. |
| 45 | +.demo-unicorn-dark-theme { |
| 46 | + @include material-experimental.update-theme($components: ( |
| 47 | + material-experimental.checkbox(( |
| 48 | + theme-type: dark |
| 49 | + )), |
| 50 | + )); |
| 51 | +} |
46 | 52 |
|
47 |
| -@include material-experimental.theme($tokens: mat.m2-tokens-from-theme($light-theme), $components: ( |
48 |
| - material-experimental.card(), |
49 |
| - material-experimental.checkbox(( |
50 |
| - fill-palette: mat.define-palette(mat.$purple-palette) |
51 |
| - )), |
52 |
| -)); |
| 53 | +// Apply tokens related to the color palette to any element with `.mat-primary`. |
| 54 | +// This ensures that checkboxes within the element inherit the new tokens for primary color, |
| 55 | +// rather than the any color that may have been set on an element further up the hierarchy. |
| 56 | +.mat-primary { |
| 57 | + @include material-experimental.update-theme($components: ( |
| 58 | + material-experimental.checkbox(( |
| 59 | + color-palette: map.get($light-theme, color, primary) |
| 60 | + )), |
| 61 | + )); |
| 62 | +} |
53 | 63 |
|
54 |
| -// Set up dark theme. |
| 64 | +// Apply tokens related to the color palette to any element with `.mat-accent`. |
| 65 | +// This ensures that checkboxes within the element inherit the new tokens for accent color, |
| 66 | +// rather than the any color that may have been set on an element further up the hierarchy. |
| 67 | +.mat-accent { |
| 68 | + @include material-experimental.update-theme($components: ( |
| 69 | + material-experimental.checkbox(( |
| 70 | + color-palette: map.get($light-theme, color, accent) |
| 71 | + )), |
| 72 | + )); |
| 73 | +} |
55 | 74 |
|
56 |
| -.demo-unicorn-dark-theme { |
57 |
| - @include material-experimental.theme($tokens: mat.m2-tokens-from-theme($dark-theme), $components: ( |
| 75 | +// Apply tokens related to the color palette to any element with `.mat-warn`. |
| 76 | +// This ensures that checkboxes within the element inherit the new tokens for warn color, |
| 77 | +// rather than the any color that may have been set on an element further up the hierarchy. |
| 78 | +.mat-warn { |
| 79 | + @include material-experimental.update-theme($components: ( |
58 | 80 | material-experimental.checkbox((
|
59 |
| - fill-palette: mat.define-palette(mat.$purple-palette), |
60 |
| - checkmark-color: red, |
| 81 | + color-palette: map.get($light-theme, color, warn) |
61 | 82 | )),
|
62 | 83 | ));
|
63 | 84 | }
|
| 85 | + |
| 86 | +// NOTE: |
| 87 | +// A nice feature about the theme styles defined above is that they stack well. For example: |
| 88 | +// |
| 89 | +// <body class="demo-unicorn-dark-theme"> |
| 90 | +// <mat-checkbox class="mat-primary"> |
| 91 | +// </body> |
| 92 | +// |
| 93 | +// The above checkbox will inherit its border color from `.demo-unicorn-dark-theme` and its fill |
| 94 | +// color from `.mat-primary` resulting in a checkbox with a white border and a primary colored fill. |
| 95 | +// It also works nicely with deeper nesting that used to be problematic. For example: |
| 96 | +// |
| 97 | +// <body> |
| 98 | +// <div class="mat-warn"> |
| 99 | +// <div class="mat-accent> |
| 100 | +// <div class="mat-primary"> |
| 101 | +// <mat-checkbox></mat-checkbox> |
| 102 | +// </div> |
| 103 | +// </div> |
| 104 | +// </div> |
| 105 | +// </body> |
| 106 | +// |
| 107 | +// The checkbox above is correctly colored with the primary color. This works because we don't have |
| 108 | +// to rely on rule specificity to determine which style gets applied, instead each layer of |
| 109 | +// `mat-warn`, `mat-accent`, `mat-primary` defines the custom property itself, preventing it from |
| 110 | +// being inherited from the level above. |
| 111 | +// |
| 112 | +// The key to getting this nice behavior is that the the theme mixin must not emit deeply nested |
| 113 | +// styles. It should always emit the tokens at the root selector where its `@include` is. |
| 114 | +// If the tokens were instead targeted at selectors like `body mat-checkbox`, |
| 115 | +// `.mat-primary mat-checkbox`, this would break down because we would again be depending on |
| 116 | +// specificity to decide which token value is applied. |
0 commit comments