Skip to content

Commit 860aa42

Browse files
authored
fix(material/slide-toggle): change slide-toggle to use MDC's token API (#26966)
1 parent df30433 commit 860aa42

File tree

5 files changed

+315
-85
lines changed

5 files changed

+315
-85
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
@use '../../token-utils';
2+
@use '../../../style/sass-utils';
3+
@use '../../../typography/typography-utils';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mat, slide-toggle);
7+
8+
// Tokens that can't be configured through Angular Material's current theming API,
9+
// but may be in a future version of the theming API.
10+
@function get-unthemable-tokens() {
11+
@return ();
12+
}
13+
14+
// Tokens that can be configured through Angular Material's color theming API.
15+
@function get-color-tokens($config) {
16+
@return ();
17+
}
18+
19+
// Tokens that can be configured through Angular Material's typography theming API.
20+
@function get-typography-tokens($config) {
21+
// TODO(amysorto): The earlier implementation of the slide-toggle used MDC's APIs to create the
22+
// typography tokens. As a result, we unintentionally allowed `null` typography configs to be
23+
// passed in. Since there a lot of apps that now depend on this pattern, we need this temporary
24+
// fallback.
25+
@if ($config == null) {
26+
$config: mdc-helpers.private-fallback-typography-from-mdc();
27+
}
28+
29+
@return (
30+
label-text-font: typography-utils.font-family($config),
31+
label-text-size: typography-utils.font-size($config, body-2),
32+
label-text-letter-spacing: typography-utils.letter-spacing($config, body-2),
33+
label-text-line-height: typography-utils.line-height($config, body-2),
34+
label-text-weight: typography-utils.font-weight($config, body-2),
35+
);
36+
}
37+
38+
// Tokens that can be configured through Angular Material's density theming API.
39+
@function get-density-tokens($config) {
40+
@return ();
41+
}
42+
43+
// Combines the tokens generated by the above functions into a single map with placeholder values.
44+
// This is used to create token slots.
45+
@function get-token-slots() {
46+
@return sass-utils.deep-merge-all(
47+
get-unthemable-tokens(),
48+
get-color-tokens(token-utils.$placeholder-color-config),
49+
get-typography-tokens(token-utils.$placeholder-typography-config),
50+
get-density-tokens(token-utils.$placeholder-density-config)
51+
);
52+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
@use 'sass:map';
2+
@use '../../../style/elevation';
3+
@use '../../../style/sass-utils';
4+
@use '../../../theming/theming';
5+
@use '../../token-utils';
6+
7+
// The prefix used to generate the fully qualified name for tokens in this file.
8+
$prefix: (mdc, switch);
9+
10+
// Tokens that can't be configured through Angular Material's current theming API,
11+
// but may be in a future version of the theming API.
12+
//
13+
// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`.
14+
// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in
15+
// our CSS.
16+
17+
@function get-unthemable-tokens() {
18+
@return (
19+
// Opacity of handle when disabled.
20+
disabled-handle-opacity: 0.38,
21+
// Opacity of icon when disabled and selected.
22+
disabled-selected-icon-opacity: 0.38,
23+
// Opacity of track when disabled.
24+
disabled-track-opacity: 0.12,
25+
// Opacity of icon when disabled and unselected.
26+
disabled-unselected-icon-opacity: 0.38,
27+
// Height of handle.
28+
handle-height: 20px,
29+
// Border radius of handle.
30+
handle-shape: 10px,
31+
// Width of handle.
32+
handle-width: 20px,
33+
// Width and height of icon when selected.
34+
selected-icon-size: 18px,
35+
// Height of track.
36+
track-height: 14px,
37+
// Border radius of track.
38+
track-shape: 7px,
39+
// Width of track.
40+
track-width: 36px,
41+
// Width and height of icon when unselected.
42+
unselected-icon-size: 18px,
43+
// The diameter of the handle ripple.
44+
state-layer-size: 40px,
45+
// Opacity of ripple when selected and focused.
46+
selected-focus-state-layer-opacity: 0.12,
47+
// Opacity of ripple when selected and on hover.
48+
selected-hover-state-layer-opacity: 0.04,
49+
// Opacity of ripple when selected and pressed.
50+
selected-pressed-state-layer-opacity: 0.1,
51+
// Opacity of ripple when unselected and focused.
52+
unselected-focus-state-layer-opacity: 0.12,
53+
// Opacity of ripple when unselected and on hover.
54+
unselected-hover-state-layer-opacity: 0.04,
55+
// Opacity of ripple when unselected and pressed.
56+
unselected-pressed-state-layer-opacity: 0.1,
57+
);
58+
}
59+
60+
// Tokens that can be configured through Angular Material's color theming API.
61+
@function get-color-tokens($config) {
62+
$foreground: map.get($config, foreground);
63+
$elevation: theming.get-color-from-palette($foreground, elevation);
64+
$is-dark: map.get($config, is-dark);
65+
$on-surface: if($is-dark, #f5f5f5, #424242);
66+
$hairline: if($is-dark, #616161, #e0e0e0);
67+
$on-surface-variant: if($is-dark, #9e9e9e, #616161);
68+
$on-surface-state-content: if($is-dark, #fafafa, #212121);
69+
$disabled-handle-color: if($is-dark, #000, #424242);
70+
$icon-color: if($is-dark, #212121, #fff);
71+
72+
// The default for tokens that rely on the theme will use the primary palette
73+
$theme-color-tokens: private-get-color-palette-color-tokens(
74+
map.get($config, primary),
75+
$is-dark
76+
);
77+
78+
@return map.merge(
79+
$theme-color-tokens,
80+
(
81+
// Color of handle when selected while disabled.
82+
disabled-selected-handle-color: $disabled-handle-color,
83+
// Color of handle when selected while disabled.
84+
disabled-selected-icon-color: $icon-color,
85+
// Color of track when selected while disabled.
86+
disabled-selected-track-color: $on-surface,
87+
// Color of handle when unselected while disabled.
88+
disabled-unselected-handle-color: $disabled-handle-color,
89+
// Color of icon when unselected while disabled.
90+
disabled-unselected-icon-color: $icon-color,
91+
// Color of track when disabled.
92+
disabled-unselected-track-color: $on-surface,
93+
// Color of slide-toggle handle's surface.
94+
handle-surface-color: surface,
95+
// Elevation level for handle.
96+
handle-elevation: 1,
97+
// Color of handle's shadow
98+
handle-shadow-color: if($elevation != null, $elevation, elevation.$color),
99+
// Elevation level for handle when disabled.
100+
disabled-handle-elevation: 0,
101+
// Color of icon (ex. checkmark) when selected
102+
selected-icon-color: $icon-color,
103+
// Color of handle when unselected and focused.
104+
unselected-focus-handle-color: $on-surface-state-content,
105+
// Color of ripple when unselected and focused.
106+
unselected-focus-state-layer-color: $on-surface,
107+
// Color of track when unselected and focused.
108+
unselected-focus-track-color: $hairline,
109+
// Color of handle when unselected.
110+
unselected-handle-color: $on-surface-variant,
111+
// Color of handle when unselected and on hover.
112+
unselected-hover-handle-color: $on-surface-state-content,
113+
// Color of ripple when unselected and on hover.
114+
unselected-hover-state-layer-color: $on-surface,
115+
// Color of track when unselected and on hover.
116+
unselected-hover-track-color: $hairline,
117+
// Color of icon color when unselected.
118+
unselected-icon-color: $icon-color,
119+
// Color of handle when unselected and pressed.
120+
unselected-pressed-handle-color: $on-surface-state-content,
121+
// Color of ripple when unselected and pressed.
122+
unselected-pressed-state-layer-color: $on-surface,
123+
// Color of track when unselected and pressed.
124+
unselected-pressed-track-color: $hairline,
125+
// Color of track when selected.
126+
unselected-track-color: $hairline,
127+
)
128+
);
129+
}
130+
131+
// Generates the mapping for the properties that change based on the slide toggle color.
132+
@function private-get-color-palette-color-tokens($color-palette, $is-dark) {
133+
$primary: theming.get-color-from-palette($color-palette, if($is-dark, 300, 600));
134+
$state-content: theming.get-color-from-palette($color-palette, if($is-dark, 200, 900));
135+
$inverse: theming.get-color-from-palette($color-palette, if($is-dark, 600, 300));
136+
137+
@return (
138+
// Color of ripple when selected and focused.
139+
selected-focus-state-layer-color: $primary,
140+
// Color of handle when selected
141+
selected-handle-color: $primary,
142+
// Color of ripple when selected and on hover.
143+
selected-hover-state-layer-color: $primary,
144+
// Color of ripple when selected and pressed.
145+
selected-pressed-state-layer-color: $primary,
146+
// Color of handle when selected and focused.
147+
selected-focus-handle-color: $state-content,
148+
// Color of handle when selected and on hover.
149+
selected-hover-handle-color: $state-content,
150+
// Color of handle when selected and pressed.
151+
selected-pressed-handle-color: $state-content,
152+
// Color of track when selected and focused.
153+
selected-focus-track-color: $inverse,
154+
// Color of track when selected and on hover.
155+
selected-hover-track-color: $inverse,
156+
/// Color of track when selected and pressed.
157+
selected-pressed-track-color: $inverse,
158+
// Color of track when selected.
159+
selected-track-color: $inverse,
160+
);
161+
}
162+
163+
// Tokens that can be configured through Angular Material's typography theming API.
164+
@function get-typography-tokens($config) {
165+
@return ();
166+
}
167+
168+
// Tokens that can be configured through Angular Material's density theming API.
169+
@function get-density-tokens($config) {
170+
@return ();
171+
}
172+
173+
// Combines the tokens generated by the above functions into a single map with placeholder values.
174+
// This is used to create token slots.
175+
@function get-token-slots() {
176+
@return sass-utils.deep-merge-all(
177+
get-unthemable-tokens(),
178+
get-color-tokens(token-utils.$placeholder-color-config),
179+
get-typography-tokens(token-utils.$placeholder-typography-config),
180+
get-density-tokens(token-utils.$placeholder-density-config)
181+
);
182+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@use '@material/list/list-theme' as mdc-list-theme;
1111
@use '@material/tooltip/plain-tooltip-theme' as mdc-plaintip-tooltip-theme;
1212
@use '@material/radio/radio-theme' as mdc-radio-theme;
13+
@use '@material/switch/switch-theme' as mdc-switch-theme;
1314
@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme;
1415
@use '@material/tab/tab-theme' as mdc-tab-theme;
1516
@use '@material/snackbar/snackbar-theme' as mdc-snackbar-theme;
@@ -25,6 +26,7 @@
2526
@use '../m2/mdc/outlined-card' as tokens-mdc-outlined-card;
2627
@use '../m2/mdc/plain-tooltip' as tokens-mdc-plain-tooltip;
2728
@use '../m2/mdc/radio' as tokens-mdc-radio;
29+
@use '../m2/mdc/switch' as tokens-mdc-switch;
2830
@use '../m2/mdc/tab-indicator' as tokens-mdc-tab-indicator;
2931
@use '../m2/mdc/tab' as tokens-mdc-tab;
3032
@use '../m2/mdc/snack-bar' as tokens-mdc-snack-bar;
@@ -87,6 +89,11 @@
8789
$slots: tokens-mdc-radio.get-token-slots(),
8890
$reference: mdc-radio-theme.$light-theme
8991
);
92+
@include validate-slots(
93+
$component: 'm2.mdc.switch',
94+
$slots: tokens-mdc-switch.get-token-slots(),
95+
$reference: mdc-switch-theme.$light-theme,
96+
);
9097
@include validate-slots(
9198
$component: 'm2.mdc.tab-indicator',
9299
$slots: tokens-mdc-tab-indicator.get-token-slots(),

0 commit comments

Comments
 (0)