Skip to content

Commit f2b4a04

Browse files
authored
refactor(material/button): switch raised button to tokens theming API (#27813)
1 parent 9751287 commit f2b4a04

File tree

5 files changed

+186
-60
lines changed

5 files changed

+186
-60
lines changed

src/material/button/_button-theme.scss

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@
55
@use '@material/button/button-protected-theme' as mdc-button-protected-theme;
66
@use '@material/button/button-outlined-theme' as mdc-button-outlined-theme;
77
@use '@material/theme/theme-color' as mdc-theme-color;
8+
@use '@material/elevation/elevation-theme' as mdc-elevation-theme;
89

910
@use './button-theme-private';
1011
@use '../core/mdc-helpers/mdc-helpers';
1112
@use '../core/theming/theming';
1213
@use '../core/theming/inspection';
1314
@use '../core/typography/typography';
1415
@use '../core/tokens/m2/mdc/button-filled' as tokens-mdc-button-filled;
16+
@use '../core/tokens/m2/mdc/button-protected' as tokens-mdc-button-protected;
1517

16-
@function on-color($theme, $palette) {
18+
@function _on-color($theme, $palette) {
1719
$is-dark: inspection.get-theme-type($theme) == dark;
1820
@return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff);
1921
}
@@ -24,13 +26,6 @@
2426
));
2527
}
2628

27-
@mixin _raised-button-variant($foreground, $background) {
28-
@include mdc-button-protected-theme.theme((
29-
container-color: $background,
30-
label-text-color: $foreground,
31-
));
32-
}
33-
3429
@mixin _outlined-button-variant($color) {
3530
@include mdc-button-outlined-theme.theme((
3631
label-text-color: $color,
@@ -78,36 +73,6 @@
7873
}
7974
}
8075

81-
.mat-mdc-raised-button {
82-
&.mat-unthemed {
83-
@include _raised-button-variant($on-surface, $surface);
84-
}
85-
86-
&.mat-primary {
87-
@include _raised-button-variant($on-primary, $primary);
88-
}
89-
90-
&.mat-accent {
91-
@include _raised-button-variant($on-secondary, $secondary);
92-
}
93-
94-
&.mat-warn {
95-
@include _raised-button-variant($on-error, $error);
96-
}
97-
98-
@include button-theme-private.apply-disabled-style() {
99-
@include mdc-button-protected-theme.theme((
100-
// We need to pass both the disabled and enabled values, because the enabled
101-
// ones apply to anchors while the disabled ones are for buttons.
102-
disabled-container-color: $disabled-container-color,
103-
disabled-label-text-color: $disabled-ink-color,
104-
container-color: $disabled-container-color,
105-
label-text-color: $disabled-ink-color,
106-
container-elevation: 0,
107-
));
108-
}
109-
}
110-
11176
.mat-mdc-outlined-button {
11277
@include mdc-button-outlined-theme.theme((
11378
outline-color: rgba(mdc-theme-color.prop-value(on-surface), 0.12)
@@ -151,17 +116,17 @@
151116
}
152117
}
153118

154-
.mat-mdc-unelevated-button {
155-
$surface: inspection.get-theme-color($theme, background, card);
156-
$primary: inspection.get-theme-color($theme, primary);
157-
$accent: inspection.get-theme-color($theme, accent);
158-
$error: inspection.get-theme-color($theme, warn);
119+
$surface: inspection.get-theme-color($theme, background, card);
120+
$primary: inspection.get-theme-color($theme, primary);
121+
$accent: inspection.get-theme-color($theme, accent);
122+
$error: inspection.get-theme-color($theme, warn);
159123

160-
$on-surface: on-color($theme, $surface);
161-
$on-primary: on-color($theme, $primary);
162-
$on-accent: on-color($theme, $accent);
163-
$on-error: on-color($theme, $error);
124+
$on-surface: _on-color($theme, $surface);
125+
$on-primary: _on-color($theme, $primary);
126+
$on-accent: _on-color($theme, $accent);
127+
$on-error: _on-color($theme, $error);
164128

129+
.mat-mdc-unelevated-button {
165130
$default-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $surface, $on-surface);
166131
$primary-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $primary, $on-primary);
167132
$accent-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $accent, $on-accent);
@@ -182,12 +147,66 @@
182147
&.mat-warn {
183148
@include mdc-button-filled-theme.theme($warn-color-tokens);
184149
}
150+
}
151+
152+
.mat-mdc-raised-button {
153+
$default-color-tokens: tokens-mdc-button-protected.get-color-tokens(
154+
$theme,
155+
$surface,
156+
$on-surface
157+
);
158+
$primary-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $primary, $on-primary);
159+
$accent-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $accent, $on-accent);
160+
$warn-color-tokens: tokens-mdc-button-filled.get-color-tokens($theme, $error, $on-error);
185161

162+
&.mat-unthemed {
163+
@include mdc-button-protected-theme.theme($default-color-tokens);
164+
}
165+
166+
&.mat-primary {
167+
@include mdc-button-protected-theme.theme($primary-color-tokens);
168+
}
169+
170+
&.mat-accent {
171+
@include mdc-button-protected-theme.theme($accent-color-tokens);
172+
}
173+
174+
&.mat-warn {
175+
@include mdc-button-protected-theme.theme($warn-color-tokens);
176+
}
177+
178+
// TODO(wagnermaciel): Remove this workaround when b/301126527 is resolved
179+
@include mdc-helpers.disable-mdc-fallback-declarations {
180+
@include mdc-elevation-theme.elevation(2);
181+
182+
&:hover, &:focus {
183+
@include mdc-elevation-theme.elevation(4);
184+
}
185+
186+
&:active, &:focus:active {
187+
@include mdc-elevation-theme.elevation(8);
188+
}
189+
}
190+
}
191+
192+
$is-dark: inspection.get-theme-type($theme) == dark;
193+
$disabled-ink-color: rgba($on-surface, if($is-dark, 0.5, 0.38));
194+
$disabled-container-color: rgba($on-surface, 0.12);
195+
196+
.mat-mdc-raised-button {
186197
@include button-theme-private.apply-disabled-style() {
187-
$is-dark: inspection.get-theme-type($theme) == dark;
188-
$disabled-ink-color: rgba($on-surface, if($is-dark, 0.5, 0.38));
189-
$disabled-container-color: rgba($on-surface, 0.12);
198+
@include mdc-elevation-theme.elevation(0);
199+
@include mdc-button-protected-theme.theme((
200+
disabled-container-color: $disabled-container-color,
201+
disabled-label-text-color: $disabled-ink-color,
202+
container-color: $disabled-container-color,
203+
label-text-color: $disabled-ink-color,
204+
));
205+
}
206+
}
190207

208+
.mat-mdc-unelevated-button {
209+
@include button-theme-private.apply-disabled-style() {
191210
@include mdc-button-filled-theme.theme((
192211
disabled-container-color: $disabled-container-color,
193212
disabled-label-text-color: $disabled-ink-color,

src/material/button/button.scss

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
@use '../core/style/private' as style-private;
1414
@use '../core/focus-indicators/private' as focus-indicators-private;
1515
@use '../core/tokens/m2/mdc/button-filled' as tokens-mdc-button-filled;
16+
@use '../core/tokens/m2/mdc/button-protected' as tokens-mdc-button-protected;
1617

1718
@include mdc-helpers.disable-mdc-fallback-declarations {
1819
@include mdc-button.static-styles-without-ripple($query: mdc-helpers.$mdc-base-styles-query);
@@ -35,13 +36,6 @@
3536
map.merge(mdc-button-text-theme.$light-theme, $override-keys));
3637
}
3738

38-
.mat-mdc-raised-button {
39-
@include mdc-button-protected-theme.theme-styles(
40-
map.merge(map.merge(mdc-button-protected-theme.$light-theme, $override-keys), (
41-
container-color: transparent,
42-
)));
43-
}
44-
4539
.mat-mdc-outlined-button {
4640
@include mdc-button-outlined-theme.theme-styles(
4741
map.merge(mdc-button-outlined-theme.$light-theme, $override-keys));
@@ -60,6 +54,18 @@
6054
// Add default values for MDC text button tokens that aren't outputted by the theming API.
6155
@include mdc-button-filled-theme.theme(tokens-mdc-button-filled.get-unthemable-tokens());
6256
}
57+
58+
// Note that we don't include a feature query, because this mixins declare
59+
// all the "slots" for CSS variables that will be defined in the theme.
60+
.mat-mdc-raised-button {
61+
$mdc-button-protected-slots: tokens-mdc-button-protected.get-token-slots();
62+
63+
// Add the slots for MDC text button.
64+
@include mdc-button-protected-theme.theme-styles($mdc-button-protected-slots);
65+
66+
// Add default values for MDC text button tokens that aren't outputted by the theming API.
67+
@include mdc-button-protected-theme.theme(tokens-mdc-button-protected.get-unthemable-tokens());
68+
}
6369
}
6470

6571
.mat-mdc-button,

src/material/core/tokens/m2/mdc/_button-filled.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ $prefix: (mdc, button-filled);
4444
);
4545
}
4646

47-
@function on-color($theme, $palette) {
47+
@function _on-color($theme, $palette) {
4848
@if ($palette) {
4949
$is-dark: inspection.get-theme-type($theme) == dark;
5050
@return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff);
@@ -56,8 +56,8 @@ $prefix: (mdc, button-filled);
5656
$is-dark: inspection.get-theme-type($theme) == dark;
5757
$primary: inspection.get-theme-color($theme, primary);
5858
$surface: inspection.get-theme-color($theme, background, card);
59-
$on-primary: on-color($theme, $primary);
60-
$on-surface: on-color($theme, $surface);
59+
$on-primary: _on-color($theme, $primary);
60+
$on-surface: _on-color($theme, $surface);
6161

6262
@return (
6363
container-color: if($color, $color, transparent),
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
@use '../../token-utils';
2+
@use '../../../mdc-helpers/mdc-helpers';
3+
@use '../../../style/sass-utils';
4+
@use '../../../theming/inspection';
5+
6+
// The prefix used to generate the fully qualified name for tokens in this file.
7+
$prefix: (mdc, button-protected);
8+
9+
// Tokens that can't be configured through Angular Material's current theming API,
10+
// but may be in a future version of the theming API.
11+
//
12+
// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`.
13+
// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in
14+
// our CSS.
15+
@function get-unthemable-tokens() {
16+
@return (
17+
container-shape: 4px,
18+
container-height: 36px,
19+
keep-touch-target: false,
20+
21+
focus-ring-color: null,
22+
focus-ring-offset: null,
23+
focus-state-layer-opacity: null,
24+
hover-state-layer-opacity: null,
25+
pressed-state-layer-opacity: null,
26+
container-shadow-color: null,
27+
container-elevation: null,
28+
hover-container-elevation: null,
29+
disabled-container-elevation: null,
30+
focus-container-elevation: null,
31+
pressed-container-elevation: null,
32+
label-text-font: null,
33+
label-text-size: null,
34+
label-text-tracking: null,
35+
label-text-transform: null,
36+
label-text-weight: null,
37+
with-icon-icon-size: null,
38+
focus-label-text-color: null,
39+
hover-label-text-color: null,
40+
pressed-label-text-color: null,
41+
with-icon-disabled-icon-color: null,
42+
with-icon-focus-icon-color: null,
43+
with-icon-hover-icon-color: null,
44+
with-icon-icon-color: null,
45+
with-icon-pressed-icon-color: null
46+
);
47+
}
48+
49+
@function _on-color($theme, $palette) {
50+
@if ($palette) {
51+
$is-dark: inspection.get-theme-type($theme) == dark;
52+
@return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff);
53+
}
54+
}
55+
56+
// Tokens that can be configured through Angular Material's color theming API.
57+
@function get-color-tokens($theme, $color: null, $on-color: null) {
58+
$is-dark: inspection.get-theme-type($theme) == dark;
59+
$primary: inspection.get-theme-color($theme, primary);
60+
$surface: inspection.get-theme-color($theme, background, card);
61+
$on-primary: _on-color($theme, $primary);
62+
$on-surface: _on-color($theme, $surface);
63+
64+
@return (
65+
container-color: if($color, $color, transparent),
66+
focus-state-layer-color: $on-primary,
67+
hover-state-layer-color: $on-primary,
68+
pressed-state-layer-color: $on-primary,
69+
label-text-color: if($on-color, $on-color, inherit),
70+
disabled-container-color: rgba($on-surface, 0.12),
71+
disabled-label-text-color: rgba($on-surface, 0.38)
72+
);
73+
}
74+
75+
// Tokens that can be configured through Angular Material's typography theming API.
76+
@function get-typography-tokens($theme) {
77+
@return ();
78+
}
79+
80+
// Tokens that can be configured through Angular Material's density theming API.
81+
@function get-density-tokens($theme) {
82+
@return ();
83+
}
84+
85+
// Combines the tokens generated by the above functions into a single map with placeholder values.
86+
// This is used to create token slots.
87+
@function get-token-slots() {
88+
@return sass-utils.deep-merge-all(
89+
get-unthemable-tokens(),
90+
get-color-tokens(token-utils.$placeholder-color-config),
91+
get-typography-tokens(token-utils.$placeholder-typography-config),
92+
get-density-tokens(token-utils.$placeholder-density-config)
93+
);
94+
}

src/material/core/tokens/tests/test-validate-tokens.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@use 'sass:list';
22
@use 'sass:map';
33

4+
@use '@material/button/button-protected-theme' as mdc-button-protected-theme;
45
@use '@material/card/elevated-card-theme' as mdc-elevated-card-theme;
56
@use '@material/card/outlined-card-theme' as mdc-outlined-card-theme;
67
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@@ -23,6 +24,7 @@
2324
@use '@material/textfield/outlined-text-field-theme' as mdc-outlined-text-field-theme;
2425
@use '@material/theme/validate' as mdc-validate;
2526

27+
@use '../m2/mdc/button-protected' as tokens-mdc-button-protected;
2628
@use '../m2/mdc/circular-progress' as tokens-mdc-circular-progress;
2729
@use '../m2/mdc/linear-progress' as tokens-mdc-linear-progress;
2830
@use '../m2/mdc/elevated-card' as tokens-mdc-elevated-card;
@@ -161,3 +163,8 @@
161163
$slots: tokens-mdc-extended-fab.get-token-slots(),
162164
$reference: mdc-extended-fab-theme.$extended-light-theme
163165
);
166+
@include validate-slots(
167+
$component: 'm2.mdc.button-protected',
168+
$slots: tokens-mdc-button-protected.get-token-slots(),
169+
$reference: mdc-button-protected-theme.$light-theme
170+
);

0 commit comments

Comments
 (0)