Skip to content

Commit 382cc50

Browse files
authored
refactor(material/button): switch outlined button to tokens API (#27906)
1 parent cc2f2c5 commit 382cc50

File tree

4 files changed

+160
-50
lines changed

4 files changed

+160
-50
lines changed

src/material/button/_button-theme.scss

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
@use '../core/theming/inspection';
1414
@use '../core/typography/typography';
1515
@use '../core/tokens/m2/mdc/filled-button' as tokens-mdc-filled-button;
16+
@use '../core/tokens/m2/mdc/outlined-button' as tokens-mdc-outlined-button;
1617
@use '../core/tokens/m2/mdc/protected-button' as tokens-mdc-protected-button;
1718
@use '../core/tokens/m2/mdc/text-button' as tokens-mdc-text-button;
1819

@@ -40,39 +41,6 @@
4041
$secondary: mdc-theme-color.prop-value(secondary);
4142
$error: mdc-theme-color.prop-value(error);
4243

43-
.mat-mdc-outlined-button {
44-
@include mdc-button-outlined-theme.theme((
45-
outline-color: rgba(mdc-theme-color.prop-value(on-surface), 0.12)
46-
));
47-
48-
&.mat-unthemed {
49-
@include _outlined-button-variant($on-surface);
50-
}
51-
52-
&.mat-primary {
53-
@include _outlined-button-variant($primary);
54-
}
55-
56-
&.mat-accent {
57-
@include _outlined-button-variant($secondary);
58-
}
59-
60-
&.mat-warn {
61-
@include _outlined-button-variant($error);
62-
}
63-
64-
@include button-theme-private.apply-disabled-style() {
65-
@include mdc-button-outlined-theme.theme((
66-
// We need to pass both the disabled and enabled values, because the enabled
67-
// ones apply to anchors while the disabled ones are for buttons.
68-
label-text-color: $disabled-ink-color,
69-
disabled-label-text-color: $disabled-ink-color,
70-
outline-color: rgba($on-surface, 0.12),
71-
disabled-outline-color: rgba($on-surface, 0.12),
72-
));
73-
}
74-
}
75-
7644
// Ripple colors
7745
.mat-mdc-button, .mat-mdc-outlined-button {
7846
@include button-theme-private.ripple-theme-styles($theme, false);
@@ -179,6 +147,37 @@
179147
}
180148
}
181149

150+
.mat-mdc-outlined-button {
151+
$default-color-tokens: tokens-mdc-outlined-button.get-color-tokens(
152+
$theme,
153+
$on-surface,
154+
$on-surface
155+
);
156+
$primary-color-tokens: tokens-mdc-outlined-button.get-color-tokens(
157+
$theme,
158+
$primary,
159+
$on-primary
160+
);
161+
$accent-color-tokens: tokens-mdc-outlined-button.get-color-tokens($theme, $accent, $on-accent);
162+
$warn-color-tokens: tokens-mdc-outlined-button.get-color-tokens($theme, $error, $on-error);
163+
164+
&.mat-unthemed {
165+
@include mdc-button-outlined-theme.theme($default-color-tokens);
166+
}
167+
168+
&.mat-primary {
169+
@include mdc-button-outlined-theme.theme($primary-color-tokens);
170+
}
171+
172+
&.mat-accent {
173+
@include mdc-button-outlined-theme.theme($accent-color-tokens);
174+
}
175+
176+
&.mat-warn {
177+
@include mdc-button-outlined-theme.theme($warn-color-tokens);
178+
}
179+
}
180+
182181
$is-dark: inspection.get-theme-type($theme) == dark;
183182
$disabled-ink-color: rgba($on-surface, if($is-dark, 0.5, 0.38));
184183
$disabled-container-color: rgba($on-surface, 0.12);
@@ -206,6 +205,17 @@
206205
}
207206
}
208207

208+
.mat-mdc-outlined-button {
209+
@include button-theme-private.apply-disabled-style() {
210+
@include mdc-button-outlined-theme.theme((
211+
label-text-color: $disabled-ink-color,
212+
disabled-label-text-color: $disabled-ink-color,
213+
disabled-outline-color: rgba($on-surface, 0.12),
214+
outline-color: rgba($on-surface, 0.12),
215+
));
216+
}
217+
}
218+
209219
.mat-mdc-unelevated-button {
210220
@include button-theme-private.apply-disabled-style() {
211221
@include mdc-button-filled-theme.theme((

src/material/button/button.scss

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
@use 'sass:map';
21
@use '@material/button/button' as mdc-button;
32
@use '@material/button/button-base' as mdc-button-base;
43
@use '@material/button/variables' as mdc-button-variables;
@@ -13,27 +12,12 @@
1312
@use '../core/style/private' as style-private;
1413
@use '../core/focus-indicators/private' as focus-indicators-private;
1514
@use '../core/tokens/m2/mdc/filled-button' as tokens-mdc-filled-button;
15+
@use '../core/tokens/m2/mdc/outlined-button' as tokens-mdc-outlined-button;
1616
@use '../core/tokens/m2/mdc/protected-button' as tokens-mdc-protected-button;
1717
@use '../core/tokens/m2/mdc/text-button' as tokens-mdc-text-button;
1818

1919
@include mdc-helpers.disable-mdc-fallback-declarations {
2020
@include mdc-button.static-styles-without-ripple($query: mdc-helpers.$mdc-base-styles-query);
21-
22-
.mat-mdc-outlined-button {
23-
// Keys to exclude from the MDC theme config, allowing us to drop styles we don't need.
24-
$override-keys: button-base.mat-private-button-remove-ripple((
25-
label-text-font: null,
26-
label-text-size: null,
27-
label-text-tracking: null,
28-
label-text-transform: null,
29-
label-text-weight: null,
30-
with-icon-icon-size: null,
31-
label-text-color: inherit,
32-
));
33-
34-
@include mdc-button-outlined-theme.theme-styles(
35-
map.merge(mdc-button-outlined-theme.$light-theme, $override-keys));
36-
}
3721
}
3822

3923
@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
@@ -65,6 +49,18 @@
6549
// Add default values for MDC text button tokens that aren't outputted by the theming API.
6650
@include mdc-button-protected-theme.theme(tokens-mdc-protected-button.get-unthemable-tokens());
6751
}
52+
53+
// Note that we don't include a feature query, because this mixins declare
54+
// all the "slots" for CSS variables that will be defined in the theme.
55+
.mat-mdc-outlined-button {
56+
$mdc-outlined-button-slots: tokens-mdc-outlined-button.get-token-slots();
57+
58+
// Add the slots for MDC text button.
59+
@include mdc-button-outlined-theme.theme-styles($mdc-outlined-button-slots);
60+
61+
// Add default values for MDC text button tokens that aren't outputted by the theming API.
62+
@include mdc-button-outlined-theme.theme(tokens-mdc-outlined-button.get-unthemable-tokens());
63+
}
6864
}
6965

7066
.mat-mdc-button,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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, outlined-button);
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+
keep-touch-target: false,
18+
19+
outline-width: 1px,
20+
container-shape: 4px,
21+
22+
hover-state-layer-opacity: null,
23+
focus-state-layer-opacity: null,
24+
pressed-state-layer-opacity: null,
25+
26+
focus-state-layer-color: null,
27+
hover-state-layer-color: null,
28+
pressed-state-layer-color: null,
29+
30+
hover-label-text-color: null,
31+
focus-label-text-color: null,
32+
pressed-label-text-color: null,
33+
34+
hover-outline-color: null,
35+
focus-outline-color: null,
36+
pressed-outline-color: null,
37+
38+
focus-ring-color: null,
39+
focus-ring-offset: null,
40+
41+
with-icon-icon-size: null,
42+
with-icon-icon-color: null,
43+
with-icon-hover-icon-color: null,
44+
with-icon-focus-icon-color: null,
45+
with-icon-pressed-icon-color: null,
46+
with-icon-disabled-icon-color: null,
47+
48+
label-text-size: null,
49+
label-text-font: null,
50+
label-text-weight: null,
51+
label-text-tracking: null,
52+
label-text-transform: null,
53+
54+
container-height: 36px
55+
);
56+
}
57+
58+
@function _on-color($theme, $palette) {
59+
@if ($palette) {
60+
$is-dark: inspection.get-theme-type($theme) == dark;
61+
@return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff);
62+
}
63+
}
64+
65+
// Tokens that can be configured through Angular Material's color theming API.
66+
@function get-color-tokens($theme, $color: null, $on-color: null) {
67+
$surface: inspection.get-theme-color($theme, background, card);
68+
$on-surface: _on-color($theme, $surface);
69+
70+
@return (
71+
disabled-outline-color: rgba($on-surface, 0.12),
72+
disabled-label-text-color: rgba($on-surface, 0.38),
73+
label-text-color: if($color, $color, inherit),
74+
outline-color: rgba($on-surface, 0.12)
75+
);
76+
}
77+
78+
// Tokens that can be configured through Angular Material's typography theming API.
79+
@function get-typography-tokens($theme) {
80+
@return ();
81+
}
82+
83+
// Tokens that can be configured through Angular Material's density theming API.
84+
@function get-density-tokens($theme) {
85+
@return ();
86+
}
87+
88+
// Combines the tokens generated by the above functions into a single map with placeholder values.
89+
// This is used to create token slots.
90+
@function get-token-slots() {
91+
@return sass-utils.deep-merge-all(
92+
get-unthemable-tokens(),
93+
get-color-tokens(token-utils.$placeholder-color-config),
94+
get-typography-tokens(token-utils.$placeholder-typography-config),
95+
get-density-tokens(token-utils.$placeholder-density-config)
96+
);
97+
}

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-outlined-theme' as mdc-button-outlined-theme;
45
@use '@material/button/button-protected-theme' as mdc-button-protected-theme;
56
@use '@material/button/button-filled-theme' as mdc-button-filled-theme;
67
@use '@material/button/button-text-theme' as mdc-button-text-theme;
@@ -29,6 +30,7 @@
2930
@use '../m2/mdc/protected-button' as tokens-mdc-protected-button;
3031
@use '../m2/mdc/filled-button' as tokens-mdc-filled-button;
3132
@use '../m2/mdc/text-button' as tokens-mdc-text-button;
33+
@use '../m2/mdc/outlined-button' as tokens-mdc-outlined-button;
3234
@use '../m2/mdc/circular-progress' as tokens-mdc-circular-progress;
3335
@use '../m2/mdc/linear-progress' as tokens-mdc-linear-progress;
3436
@use '../m2/mdc/elevated-card' as tokens-mdc-elevated-card;
@@ -177,3 +179,8 @@
177179
$slots: tokens-mdc-text-button.get-token-slots(),
178180
$reference: mdc-button-text-theme.$light-theme
179181
);
182+
@include validate-slots(
183+
$component: 'm2.mdc.outlined-button',
184+
$slots: tokens-mdc-outlined-button.get-token-slots(),
185+
$reference: mdc-button-outlined-theme.$light-theme
186+
);

0 commit comments

Comments
 (0)