Skip to content

Commit 7ae4a9e

Browse files
committed
refactor: ensure theme is backwards compatible for custom themes
With the new theming API refactor, the theme object is no longer simply about the color configuration. Instead it now contains configurations for other parts of the system (i.e. density, typography). To ensure that this doesn't break custom themes for consumers, we ensure that theme objects still contain the color configuration at the top-level of the `$theme` object. In the future, we can remove this if this is denoted as a breaking change after deprecation period (TBD).
1 parent c522351 commit 7ae4a9e

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

src/material/core/theming/_theming.scss

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@
8282
@return $theme;
8383
}
8484

85+
// Creates a backwards compatible theme. Previously in Angular Material, theme objects
86+
// contained the color configuration directly. With the recent refactoring of the theming
87+
// system to allow for density and typography configurations, this is no longer the case.
88+
// To ensure that constructed themes which will be passed to custom theme mixins do not break,
89+
// we copy the color configuration and put its properties at the top-level of the theme object.
90+
// Here is an example of a pattern that should still work until it's officially marked as a
91+
// breaking change:
92+
//
93+
// @mixin my-custom-component-theme($theme) {
94+
// .my-comp {
95+
// background-color: mat-color(map_get($theme, primary));
96+
// }
97+
// }
98+
//
99+
// Note that the `$theme.primary` key does usually not exist since the color configuration
100+
// is stored in `$theme.color` which contains a property for `primary`. This method copies
101+
// the map from `$theme.color` to `$theme` for backwards compatibility.
102+
@function _mat-create-backwards-compatibility-theme($theme) {
103+
@if not map_get($theme, color) {
104+
@return $theme;
105+
}
106+
$color: map_get($theme, color);
107+
@return map_merge($theme, $color);
108+
}
109+
85110
// Whether the specified object is a color configuration. This function is needed for backwards
86111
// compatibility of individual component theme mixins, because developers could pass in a color
87112
// configuration instead of a theme container object to a theme mixin.
@@ -134,9 +159,9 @@
134159
// If the legacy pattern is used, we generate a container object only with a light-themed
135160
// configuration for the `color` theming part.
136161
@if $accent != null {
137-
@return _mat-validate-theme((
162+
@return _mat-create-backwards-compatibility-theme(_mat-validate-theme((
138163
color: _mat-create-light-color-config($config-or-primary, $accent, $warn),
139-
));
164+
)));
140165
}
141166
// If the map pattern is used (1), we just pass-through the configurations for individual
142167
// parts of the theming system, but update the `color` configuration if set. As explained
@@ -149,7 +174,7 @@
149174
$warn: map_get($color-settings, warn);
150175
$result: map_merge($result, (color: _mat-create-light-color-config($primary, $accent, $warn)));
151176
}
152-
@return _mat-validate-theme($result);
177+
@return _mat-create-backwards-compatibility-theme(_mat-validate-theme($result));
153178
}
154179

155180
// Creates a container object for a dark theme to be given to individual component theme mixins.
@@ -168,9 +193,9 @@
168193
// If the legacy pattern is used, we generate a container object only with a dark-themed
169194
// configuration for the `color` theming part.
170195
@if $accent != null {
171-
@return _mat-validate-theme((
196+
@return _mat-create-backwards-compatibility-theme(_mat-validate-theme((
172197
color: _mat-create-dark-color-config($config-or-primary, $accent, $warn),
173-
));
198+
)));
174199
}
175200
// If the map pattern is used (1), we just pass-through the configurations for individual
176201
// parts of the theming system, but update the `color` configuration if set. As explained
@@ -183,7 +208,7 @@
183208
$warn: map_get($color-settings, warn);
184209
$result: map_merge($result, (color: _mat-create-dark-color-config($primary, $accent, $warn)));
185210
}
186-
@return _mat-validate-theme($result);
211+
@return _mat-create-backwards-compatibility-theme(_mat-validate-theme($result));
187212
}
188213

189214
@function mat-get-color-config($theme, $default: null) {

src/material/core/theming/tests/test-theming-api.scss

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,39 @@ $dark-theme-only-typography: mat-dark-theme((typography: $typography-config));
169169
@include angular-material-theme($dark-theme-only-typography);
170170
}
171171

172+
// Custom theme mixin used by the custom theme backwards compatibility test.
173+
// This replicates a custom theme that expects legacy theme objects.
174+
@mixin _my-custom-theme-legacy($theme) {
175+
.demo-custom-comp {
176+
border-color: mat-color(map_get($theme, primary));
177+
}
178+
}
179+
180+
@mixin _my-custom-theme-new-api-color($config) {
181+
.demo-custom-comp {
182+
border-color: mat-color(map_get($config, primary));
183+
}
184+
}
185+
186+
// Custom theme mixin used by the custom theme backwards compatibility test.
187+
@mixin _my-custom-theme-new-api($theme) {
188+
$color: mat-get-color-config($theme);
189+
@if $color != null {
190+
@include _my-custom-theme-new-api-color($color);
191+
}
192+
}
193+
194+
@mixin test-custom-theme-backwards-compatibility() {
195+
@include _my-custom-theme-legacy($legacy-light-theme);
196+
@include _my-custom-theme-legacy($legacy-dark-theme);
197+
@include _my-custom-theme-legacy($new-api-light-theme);
198+
@include _my-custom-theme-legacy($new-api-dark-theme);
199+
@include _my-custom-theme-new-api($legacy-light-theme);
200+
@include _my-custom-theme-new-api($legacy-dark-theme);
201+
@include _my-custom-theme-new-api($new-api-light-theme);
202+
@include _my-custom-theme-new-api($new-api-dark-theme);
203+
}
204+
172205
// Include all tests. Sass will throw if one of the tests fails.
173206
@include test-create-color-config();
174207
@include test-default-theming-system-configs();
@@ -177,3 +210,4 @@ $dark-theme-only-typography: mat-dark-theme((typography: $typography-config));
177210
@include test-get-color-config();
178211
@include test-get-density-config();
179212
@include test-get-typography-config();
213+
@include test-custom-theme-backwards-compatibility();

0 commit comments

Comments
 (0)