Skip to content

Commit 27bb88e

Browse files
committed
fix(multiple): derive all token values from theme
During the transition to tokens, we ended up with a bunch of places with hardcoded values in the form of `if($is-dark, #fff, #000)`. This is problematic for custom palettes, because the value is always hardcoded. These changes attempt to derive the same values from the palette directly. Fixes #26056.
1 parent f6e8584 commit 27bb88e

25 files changed

+216
-146
lines changed

src/material/core/theming/_inspection.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
7575
@function get-theme-color($theme, $args...) {
7676
$version: get-theme-version($theme);
7777
$args-count: list.length($args);
78-
@if $args-count != 1 and $args-count != 2 {
79-
@error #{'Expected 2 or 3 arguments. Got:'} $args-count + 1;
78+
@if $args-count != 1 and $args-count != 2 and $args-count != 3 {
79+
@error #{'Expected between 2 and 4 arguments. Got:'} $args-count + 1;
8080
}
8181

8282
@if $version == 0 {

src/material/core/theming/tests/theming-inspection-api.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ describe('theming inspection api', () => {
328328
color: mat.get-theme-color($theme);
329329
}
330330
`),
331-
).toThrowError(/Expected 2 or 3 arguments. Got: 1/);
331+
).toThrowError(/Expected between 2 and 4 arguments\. Got: 1/);
332332
});
333333

334334
it('should get typography properties from theme', () => {

src/material/core/tokens/_token-utils.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
@use '../theming/theming';
1010
@use '../typography/typography';
1111

12+
// Indicates whether we're building internally. Used for backwards compatibility.
13+
$private-is-internal-build: false;
14+
1215
$_placeholder-color-palette: theming.define-palette(palette.$red-palette);
1316

1417
// Placeholder color config that can be passed to token getter functions when generating token

src/material/core/tokens/m2/mat/_datepicker.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ $private-default-overlap-color: #a8dab5;
5050
$preview-outline-color: $divider-color;
5151
$today-disabled-outline-color: null;
5252
$is-dark: inspection.get-theme-type($theme) == dark;
53-
$on-surface: if($is-dark, #fff, #000);
5453

5554
$primary-color: inspection.get-theme-color($theme, primary);
5655
$range-tokens: get-range-color-tokens(private-get-range-background-color($primary-color));
@@ -75,7 +74,7 @@ $private-default-overlap-color: #a8dab5;
7574
@return sass-utils.merge-all($calendar-tokens, $toggle-tokens, $range-tokens, (
7675
toggle-icon-color: $inactive-icon-color,
7776
calendar-body-label-text-color: $secondary-text-color,
78-
calendar-period-button-text-color: $on-surface,
77+
calendar-period-button-text-color: inspection.get-theme-color($theme, foreground, text, 1),
7978
calendar-period-button-icon-color: $inactive-icon-color,
8079
calendar-navigation-button-icon-color: $inactive-icon-color,
8180
calendar-header-divider-color: $divider-color,

src/material/core/tokens/m2/mat/_fab-small.scss

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ $prefix: (mat, fab-small);
1818
// Tokens that can be configured through Angular Material's color theming API.
1919
@function get-color-tokens($theme) {
2020
$is-dark: inspection.get-theme-type($theme) == dark;
21-
$on-surface: if($is-dark, #fff, #000);
2221
$ripple-opacities: if($is-dark,
2322
mdc-ripple-theme.$light-ink-opacities,
2423
mdc-ripple-theme.$dark-ink-opacities
@@ -29,13 +28,13 @@ $prefix: (mat, fab-small);
2928
foreground-color: inspection.get-theme-color($theme, foreground, base),
3029

3130
// Color of the element that shows the hover, focus and pressed states.
32-
state-layer-color: $on-surface,
31+
state-layer-color: inspection.get-theme-color($theme, foreground, base),
3332

3433
// Color of the element that shows the hover, focus and pressed states while disabled.
35-
disabled-state-layer-color: $on-surface,
34+
disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base),
3635

3736
// Color of the ripple element.
38-
ripple-color: rgba($on-surface, 0.1),
37+
ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1),
3938

4039
// Opacity of the ripple when the button is hovered.
4140
hover-state-layer-opacity: map.get($ripple-opacities, hover),
@@ -48,24 +47,42 @@ $prefix: (mat, fab-small);
4847

4948
// MDC doesn't have tokens for disabled FABs so we need to implemented them ourselves.
5049
// Background color of the container when the FAB is disabled.
51-
disabled-state-container-color: rgba($on-surface, 0.12),
50+
disabled-state-container-color: inspection.get-theme-color($theme, background, disabled-button,
51+
0.12),
5252

5353
// Color of the icons and projected text when the FAB is disabled.
54-
disabled-state-foreground-color: rgba($on-surface, if($is-dark, 0.5, 0.38)),
54+
disabled-state-foreground-color: inspection.get-theme-color($theme, foreground, disabled-button,
55+
if($is-dark, 0.5, 0.38)),
5556
);
5657
}
5758

5859
// Generates the mapping for the properties that change based on the FAB palette color.
5960
@function private-get-color-palette-color-tokens($theme, $palette-name) {
60-
$is-dark: inspection.get-theme-type($theme) == dark;
61-
$container-color: inspection.get-theme-color($theme, $palette-name);
62-
$contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark);
63-
$color: if($contrast-tone == 'dark', #000, #fff);
61+
// Internally using these values from the palette causes a lot
62+
// of screenshot diffs. Maintain the old behavior for now.
63+
$foreground-color: null;
64+
$state-layer-color: null;
65+
$ripple-color: null;
66+
67+
@if (token-utils.$private-is-internal-build) {
68+
$is-dark: inspection.get-theme-type($theme) == dark;
69+
$container-color: inspection.get-theme-color($theme, $palette-name);
70+
$contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark);
71+
$color: if($contrast-tone == 'dark', #000, #fff);
72+
$foreground-color: $color;
73+
$state-layer-color: $color;
74+
$ripple-color: rgba($color, 0.1);
75+
}
76+
@else {
77+
$foreground-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1);
78+
$state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1);
79+
$ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1);
80+
}
6481

6582
@return (
66-
foreground-color: $color,
67-
state-layer-color: $color,
68-
ripple-color: rgba($color, 0.1),
83+
foreground-color: $foreground-color,
84+
state-layer-color: $state-layer-color,
85+
ripple-color: $ripple-color,
6986
);
7087
}
7188

src/material/core/tokens/m2/mat/_fab.scss

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ $prefix: (mat, fab);
1818
// Tokens that can be configured through Angular Material's color theming API.
1919
@function get-color-tokens($theme) {
2020
$is-dark: inspection.get-theme-type($theme) == dark;
21-
$on-surface: if($is-dark, #fff, #000);
2221
$ripple-opacities: if($is-dark,
2322
mdc-ripple-theme.$light-ink-opacities,
2423
mdc-ripple-theme.$dark-ink-opacities
@@ -29,13 +28,13 @@ $prefix: (mat, fab);
2928
foreground-color: inspection.get-theme-color($theme, foreground, base),
3029

3130
// Color of the element that shows the hover, focus and pressed states.
32-
state-layer-color: $on-surface,
31+
state-layer-color: inspection.get-theme-color($theme, foreground, base),
3332

3433
// Color of the element that shows the hover, focus and pressed states while disabled.
35-
disabled-state-layer-color: $on-surface,
34+
disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base),
3635

3736
// Color of the ripple element.
38-
ripple-color: rgba($on-surface, 0.1),
37+
ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1),
3938

4039
// Opacity of the ripple when the button is hovered.
4140
hover-state-layer-opacity: map.get($ripple-opacities, hover),
@@ -48,24 +47,42 @@ $prefix: (mat, fab);
4847

4948
// MDC doesn't have tokens for disabled FABs so we need to implemented them ourselves.
5049
// Background color of the container when the FAB is disabled.
51-
disabled-state-container-color: rgba($on-surface, 0.12),
50+
disabled-state-container-color: inspection.get-theme-color($theme, background, disabled-button,
51+
0.12),
5252

5353
// Color of the icons and projected text when the FAB is disabled.
54-
disabled-state-foreground-color: rgba($on-surface, if($is-dark, 0.5, 0.38)),
54+
disabled-state-foreground-color: inspection.get-theme-color($theme, foreground, disabled-button,
55+
if($is-dark, 0.5, 0.38)),
5556
);
5657
}
5758

5859
// Generates the mapping for the properties that change based on the FAB palette color.
5960
@function private-get-color-palette-color-tokens($theme, $palette-name) {
60-
$is-dark: inspection.get-theme-type($theme) == dark;
61-
$container-color: inspection.get-theme-color($theme, $palette-name);
62-
$contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark);
63-
$color: if($contrast-tone == 'dark', #000, #fff);
61+
// Internally using these values from the palette causes a lot
62+
// of screenshot diffs. Maintain the old behavior for now.
63+
$foreground-color: null;
64+
$state-layer-color: null;
65+
$ripple-color: null;
66+
67+
@if (token-utils.$private-is-internal-build) {
68+
$is-dark: inspection.get-theme-type($theme) == dark;
69+
$container-color: inspection.get-theme-color($theme, $palette-name);
70+
$contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark);
71+
$color: if($contrast-tone == 'dark', #000, #fff);
72+
$foreground-color: $color;
73+
$state-layer-color: $color;
74+
$ripple-color: rgba($color, 0.1);
75+
}
76+
@else {
77+
$foreground-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1);
78+
$state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1);
79+
$ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1);
80+
}
6481

6582
@return (
66-
foreground-color: $color,
67-
state-layer-color: $color,
68-
ripple-color: rgba($color, 0.1),
83+
foreground-color: $foreground-color,
84+
state-layer-color: $state-layer-color,
85+
ripple-color: $ripple-color,
6986
);
7087
}
7188

src/material/core/tokens/m2/mat/_filled-button.scss

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
@use '../../../theming/theming';
55
@use '../../../theming/inspection';
66
@use '../../../style/sass-utils';
7-
@use '../../../mdc-helpers/mdc-helpers';
87

98
// The prefix used to generate the fully qualified name for tokens in this file.
109
$prefix: (mat, filled-button);
@@ -28,21 +27,20 @@ $prefix: (mat, filled-button);
2827
// Tokens that can be configured through Angular Material's color theming API.
2928
@function get-color-tokens($theme) {
3029
$is-dark: inspection.get-theme-type($theme) == dark;
31-
$on-surface: if($is-dark, #fff, #000);
3230
$ripple-opacities: if($is-dark,
3331
mdc-ripple-theme.$light-ink-opacities,
3432
mdc-ripple-theme.$dark-ink-opacities
3533
);
3634

3735
@return (
3836
// Color of the element that shows the hover, focus and pressed states.
39-
state-layer-color: $on-surface,
37+
state-layer-color: inspection.get-theme-color($theme, foreground, base),
4038

4139
// Color of the element that shows the hover, focus and pressed states while disabled.
42-
disabled-state-layer-color: $on-surface,
40+
disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base),
4341

4442
// Color of the ripple element.
45-
ripple-color: rgba($on-surface, 0.1),
43+
ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1),
4644

4745
// Opacity of the ripple when the button is hovered.
4846
hover-state-layer-opacity: map.get($ripple-opacities, hover),
@@ -57,14 +55,9 @@ $prefix: (mat, filled-button);
5755

5856
// Generates the mapping for the properties that change based on the button palette color.
5957
@function private-get-color-palette-color-tokens($theme, $palette-name) {
60-
$is-dark: inspection.get-theme-type($theme) == dark;
61-
$container-color: inspection.get-theme-color($theme, $palette-name);
62-
$contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark);
63-
$color: if($contrast-tone == 'dark', #000, #fff);
64-
6558
@return (
66-
state-layer-color: $color,
67-
ripple-color: rgba($color, 0.1),
59+
state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1),
60+
ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1),
6861
);
6962
}
7063

src/material/core/tokens/m2/mat/_form-field.scss

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ $prefix: (mat, form-field);
2020
// Tokens that can be configured through Angular Material's color theming API.
2121
@function get-color-tokens($theme) {
2222
$is-dark: inspection.get-theme-type($theme) == dark;
23-
$on-surface: if($is-dark, #fff, #000);
2423
$color-tokens: private-get-color-palette-color-tokens($theme, primary);
2524

2625
@return map.merge($color-tokens, (
2726
// MDC has a token for the enabled placeholder, but not for the disabled one.
28-
disabled-input-text-placeholder-color: rgba($on-surface, 0.38),
29-
state-layer-color: rgba($on-surface, 0.87),
27+
disabled-input-text-placeholder-color:
28+
inspection.get-theme-color($theme, foreground, icon, 0.38),
29+
state-layer-color: inspection.get-theme-color($theme, foreground, base, 0.87),
3030
error-text-color: inspection.get-theme-color($theme, warn),
3131

3232
// On dark themes we set the native `select` color to some shade of white,
@@ -56,8 +56,8 @@ $prefix: (mat, form-field);
5656

5757
// These values are taken from the MDC select implementation:
5858
// https://github.com/material-components/material-components-web/blob/master/packages/mdc-select/_select-theme.scss
59-
enabled-select-arrow-color: rgba($on-surface, 0.54),
60-
disabled-select-arrow-color: rgba($on-surface, 0.38),
59+
enabled-select-arrow-color: inspection.get-theme-color($theme, foreground, icon, 0.54),
60+
disabled-select-arrow-color: inspection.get-theme-color($theme, foreground, icon, 0.38),
6161

6262
hover-state-layer-opacity: if($is-dark, 0.08, 0.04),
6363
focus-state-layer-opacity: if($is-dark, 0.24, 0.08),

src/material/core/tokens/m2/mat/_icon-button.scss

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ $prefix: (mat, icon-button);
1818
// Tokens that can be configured through Angular Material's color theming API.
1919
@function get-color-tokens($theme) {
2020
$is-dark: inspection.get-theme-type($theme) == dark;
21-
$on-surface: if($is-dark, #fff, #000);
2221
$ripple-opacities: if($is-dark,
2322
mdc-ripple-theme.$light-ink-opacities,
2423
mdc-ripple-theme.$dark-ink-opacities
2524
);
2625

2726
@return (
2827
// Color of the element that shows the hover, focus and pressed states.
29-
state-layer-color: $on-surface,
28+
state-layer-color: inspection.get-theme-color($theme, foreground, base),
3029

3130
// Color of the element that shows the hover, focus and pressed states while disabled.
32-
disabled-state-layer-color: $on-surface,
31+
disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base),
3332

3433
// Color of the ripple element.
35-
ripple-color: rgba($on-surface, 0.1),
34+
ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1),
3635

3736
// Opacity of the ripple when the button is hovered.
3837
hover-state-layer-opacity: map.get($ripple-opacities, hover),

src/material/core/tokens/m2/mat/_menu.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ $prefix: (mat, menu);
2424
// Tokens that can be configured through Angular Material's color theming API.
2525
@function get-color-tokens($theme) {
2626
$is-dark: inspection.get-theme-type($theme) == dark;
27-
$on-surface: if($is-dark, #fff, #000);
28-
$active-state-layer-color: rgba($on-surface, if($is-dark, 0.08, 0.04));
27+
$active-state-layer-color: inspection.get-theme-color($theme, foreground, base,
28+
if($is-dark, 0.08, 0.04));
2929
$text-color: inspection.get-theme-color($theme, foreground, text);
3030

3131
@return (

src/material/core/tokens/m2/mat/_option.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ $prefix: (mat, option);
1515
// Tokens that can be configured through Angular Material's color theming API.
1616
@function get-color-tokens($theme, $palette-name: primary) {
1717
$is-dark: inspection.get-theme-type($theme) == dark;
18-
$on-surface: if($is-dark, #fff, #000);
19-
$active-state-layer-color: rgba($on-surface, if($is-dark, 0.08, 0.04));
18+
$active-state-layer-color: inspection.get-theme-color($theme, foreground, base,
19+
if($is-dark, 0.08, 0.04));
2020

2121
@return (
2222
selected-state-label-text-color: inspection.get-theme-color($theme, $palette-name),

src/material/core/tokens/m2/mat/_outlined-button.scss

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,20 @@ $prefix: (mat, outlined-button);
2828
// Tokens that can be configured through Angular Material's color theming API.
2929
@function get-color-tokens($theme) {
3030
$is-dark: inspection.get-theme-type($theme) == dark;
31-
$on-surface: if($is-dark, #fff, #000);
3231
$ripple-opacities: if($is-dark,
3332
mdc-ripple-theme.$light-ink-opacities,
3433
mdc-ripple-theme.$dark-ink-opacities
3534
);
3635

3736
@return (
3837
// Color of the element that shows the hover, focus and pressed states.
39-
state-layer-color: $on-surface,
38+
state-layer-color: inspection.get-theme-color($theme, foreground, base),
4039

4140
// Color of the element that shows the hover, focus and pressed states while disabled.
42-
disabled-state-layer-color: $on-surface,
41+
disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base),
4342

4443
// Color of the ripple element.
45-
ripple-color: rgba($on-surface, 0.1),
44+
ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1),
4645

4746
// Opacity of the ripple when the button is hovered.
4847
hover-state-layer-opacity: map.get($ripple-opacities, hover),

0 commit comments

Comments
 (0)