Skip to content

Commit b13c6aa

Browse files
authored
fix(material/slider): change slider to use MDC's token API (#27375)
1 parent a162afd commit b13c6aa

File tree

5 files changed

+375
-157
lines changed

5 files changed

+375
-157
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@use 'sass:map';
2+
@use '../../token-utils';
3+
@use '../../../style/sass-utils';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mat, slider);
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+
$is-dark: map.get($config, is-dark);
17+
18+
@return (
19+
// Opacity of value indicator text container
20+
value-indicator-opacity: if($is-dark, 0.9, 0.6),
21+
);
22+
}
23+
24+
// Tokens that can be configured through Angular Material's typography theming API.
25+
@function get-typography-tokens($config) {
26+
@return ();
27+
}
28+
29+
// Tokens that can be configured through Angular Material's density theming API.
30+
@function get-density-tokens($config) {
31+
@return ();
32+
}
33+
34+
// Combines the tokens generated by the above functions into a single map with placeholder values.
35+
// This is used to create token slots.
36+
@function get-token-slots() {
37+
@return sass-utils.deep-merge-all(
38+
get-unthemable-tokens(),
39+
get-color-tokens(token-utils.$placeholder-color-config),
40+
get-typography-tokens(token-utils.$placeholder-typography-config),
41+
get-density-tokens(token-utils.$placeholder-density-config)
42+
);
43+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
@use 'sass:map';
2+
@use '../../../theming/theming';
3+
@use '../../token-utils';
4+
@use '../../../style/sass-utils';
5+
@use '../../../typography/typography-utils';
6+
7+
// The prefix used to generate the fully qualified name for tokens in this file.
8+
$prefix: (mdc, slider);
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+
@function get-unthemable-tokens() {
17+
@return (
18+
// Height of active track.
19+
active-track-height: 6px,
20+
// Border radius of active track.
21+
active-track-shape: 9999px,
22+
// Height of handle.
23+
handle-height: 20px,
24+
// Border radius of handle.
25+
handle-shape: 50%,
26+
// Width of handle.
27+
handle-width: 20px,
28+
// Height of inactive track.
29+
inactive-track-height: 4px,
30+
// Border radius of inactive track.
31+
inactive-track-shape: 9999px,
32+
// Width of handle when overlapping with another handle below it.
33+
with-overlap-handle-outline-width: 1px,
34+
// Opacity of active container with tick marks.
35+
with-tick-marks-active-container-opacity: 0.6,
36+
// Border radius of container with tick marks.
37+
with-tick-marks-container-shape: 50%,
38+
// Size of container with tick marks.
39+
with-tick-marks-container-size: 2px,
40+
// Opacity of inactive container with tick marks.
41+
with-tick-marks-inactive-container-opacity: 0.6,
42+
// =============================================================================================
43+
// = TOKENS NOT USED IN ANGULAR MATERIAL =
44+
// =============================================================================================
45+
disabled-handle-elevation: null,
46+
label-container-elevation: null,
47+
label-container-height: null,
48+
track-elevation: null,
49+
focus-state-layer-opacity: null,
50+
hover-state-layer-opacity: null,
51+
pressed-state-layer-opacity: null,
52+
// MDC does not seem to use these tokens.
53+
hover-state-layer-color: null,
54+
pressed-handle-color: null,
55+
);
56+
}
57+
58+
// Tokens that can be configured through Angular Material's color theming API.
59+
@function get-color-tokens($config) {
60+
$foreground: map.get($config, foreground);
61+
$elevation: theming.get-color-from-palette($foreground, elevation);
62+
$is-dark: map.get($config, is-dark);
63+
$on-surface: if($is-dark, #fff, #000);
64+
65+
// The default for tokens that rely on the theme will use the primary palette
66+
$primary: map.get($config, primary);
67+
$theme-color-tokens: private-get-color-palette-color-tokens($primary);
68+
69+
@return map.merge(
70+
$theme-color-tokens,
71+
(
72+
// Color of active track when disabled.
73+
disabled-active-track-color: $on-surface,
74+
// Color of handle when disabled.
75+
disabled-handle-color: $on-surface,
76+
// Color of inactive track when disabled.
77+
disabled-inactive-track-color: $on-surface,
78+
// Color of container label.
79+
label-container-color: $on-surface,
80+
// Color of label text.
81+
label-label-text-color: if($is-dark, #000, #fff),
82+
// Color of handle outline when overlapping with another handle below it.
83+
with-overlap-handle-outline-color: #fff,
84+
// Color of container with tick marks when disabled.
85+
with-tick-marks-disabled-container-color: $on-surface,
86+
// (Part of the color tokens because it needs to be combined with the
87+
// shadow color to generate the box-shadow.)
88+
// Elevation level for handle.
89+
handle-elevation: 1,
90+
// Color of handle shadow.
91+
handle-shadow-color: if($elevation != null, $elevation, elevation.$color),
92+
)
93+
);
94+
}
95+
96+
// Generates tokens for the slider properties that change based on the theme.
97+
@function private-get-color-palette-color-tokens($color-palette) {
98+
$color: theming.get-color-from-palette($color-palette);
99+
$on-color: map.get($color-palette, default-contrast);
100+
101+
@return (
102+
// Color of handle.
103+
handle-color: $color,
104+
// Color of handle when focused.
105+
focus-handle-color: $color,
106+
// Color of handle on hover.
107+
hover-handle-color: $color,
108+
// Color of handle when active.
109+
active-track-color: $color,
110+
// Color of inactive track.
111+
inactive-track-color: $color,
112+
// Color of inactive container with tick marks.
113+
with-tick-marks-inactive-container-color: $color,
114+
// Color of active container with tick marks.
115+
with-tick-marks-active-container-color: $on-color,
116+
);
117+
}
118+
119+
// Tokens that can be configured through Angular Material's typography theming API.
120+
@function get-typography-tokens($config) {
121+
@if ($config == null) {
122+
$config: mdc-helpers.private-fallback-typography-from-mdc();
123+
}
124+
125+
@return (
126+
// Font for label text.
127+
label-label-text-font: typography-utils.font-family($config, subtitle-2)
128+
or typography-utils.font-family($config),
129+
// Font size of label text.
130+
label-label-text-size: typography-utils.font-size($config, subtitle-2),
131+
// Line height of label text.
132+
label-label-text-line-height: typography-utils.line-height($config, subtitle-2),
133+
// Letter spacing of label text.
134+
label-label-text-tracking: typography-utils.letter-spacing($config, subtitle-2),
135+
// Font weight of label text.
136+
label-label-text-weight: typography-utils.font-weight($config, subtitle-2),
137+
);
138+
}
139+
140+
// Tokens that can be configured through Angular Material's density theming API.
141+
@function get-density-tokens($config) {
142+
@return ();
143+
}
144+
145+
// Combines the tokens generated by the above functions into a single map with placeholder values.
146+
// This is used to create token slots.
147+
@function get-token-slots() {
148+
@return sass-utils.deep-merge-all(
149+
get-unthemable-tokens(),
150+
get-color-tokens(token-utils.$placeholder-color-config),
151+
get-typography-tokens(token-utils.$placeholder-typography-config),
152+
get-density-tokens(token-utils.$placeholder-density-config)
153+
);
154+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme;
1717
@use '@material/tab/tab-theme' as mdc-tab-theme;
1818
@use '@material/snackbar/snackbar-theme' as mdc-snackbar-theme;
19+
@use '@material/slider/slider-theme' as mdc-slider-theme;
1920
@use '@material/chips/chip-theme' as mdc-chips-theme;
2021
@use '@material/dialog/dialog-theme' as mdc-dialog-theme;
2122
@use '@material/theme/validate' as mdc-validate;
@@ -35,6 +36,7 @@
3536
@use '../m2/mdc/tab-indicator' as tokens-mdc-tab-indicator;
3637
@use '../m2/mdc/tab' as tokens-mdc-tab;
3738
@use '../m2/mdc/snack-bar' as tokens-mdc-snack-bar;
39+
@use '../m2/mdc/slider' as tokens-mdc-slider;
3840
@use '../m2/mdc/chip' as tokens-mdc-chip;
3941
@use '../m2/mdc/dialog' as tokens-mdc-dialog;
4042

@@ -115,6 +117,11 @@
115117
$slots: tokens-mdc-snack-bar.get-token-slots(),
116118
$reference: mdc-snackbar-theme.$light-theme
117119
);
120+
@include validate-slots(
121+
$component: 'm2.mdc.slider',
122+
$slots: tokens-mdc-slider.get-token-slots(),
123+
$reference: mdc-slider-theme.$light-theme
124+
);
118125
@include validate-slots(
119126
$component: 'm2.mdc.chips',
120127
$slots: tokens-mdc-chip.get-token-slots(),
Lines changed: 55 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,71 @@
11
@use 'sass:map';
22

33
@use '@material/slider/slider-theme' as mdc-slider-theme;
4-
@use '@material/theme/theme-color' as mdc-theme-color;
5-
@use '@material/typography/typography' as mdc-typography;
6-
@use '@material/theme/variables' as mdc-theme-variables;
7-
@use '../core/mdc-helpers/mdc-helpers';
84
@use '../core/theming/theming';
95
@use '../core/typography/typography';
10-
6+
@use '../core/tokens/token-utils';
7+
@use '../core/tokens/m2/mat/slider' as m2-mat-slider;
8+
@use '../core/tokens/m2/mdc/slider' as m2-mdc-slider;
119

1210
@mixin color($config-or-theme) {
1311
$config: theming.get-color-config($config-or-theme);
12+
$is-dark: map.get($config, is-dark);
13+
14+
$mdc-color-tokens: token-utils.resolve-elevation(
15+
m2-mdc-slider.get-color-tokens($config),
16+
handle-elevation,
17+
handle-shadow-color
18+
);
19+
20+
$mat-slider-color-tokens: m2-mat-slider.get-color-tokens($config);
21+
22+
// Add values for MDC slider tokens.
23+
.mat-mdc-slider {
24+
@include mdc-slider-theme.theme($mdc-color-tokens);
25+
@include _slider-ripple-color(map.get($config, primary));
26+
@include token-utils.create-token-values(
27+
m2-mat-slider.$prefix,
28+
$mat-slider-color-tokens
29+
);
30+
31+
&.mat-accent {
32+
$accent: map.get($config, accent);
33+
@include mdc-slider-theme.theme(
34+
m2-mdc-slider.private-get-color-palette-color-tokens($accent)
35+
);
36+
@include _slider-ripple-color($accent);
37+
}
1438

15-
@include mdc-helpers.using-mdc-theme($config) {
16-
.mat-mdc-slider {
17-
$is-dark: map.get($config, is-dark);
18-
$on-surface: mdc-theme-color.prop-value(on-surface);
19-
20-
@include mdc-slider-theme.theme((
21-
label-container-color: if($is-dark, white, black),
22-
label-label-text-color: if($is-dark, black, white),
23-
disabled-handle-color: $on-surface,
24-
disabled-active-track-color: $on-surface,
25-
disabled-inactive-track-color: $on-surface,
26-
with-tick-marks-disabled-container-color: $on-surface,
27-
));
28-
29-
// Note that technically we can control this using an `rgba` color in `label-container-color`.
30-
// We don't do it, because the shapes MDC uses to construct the indicator overlap which causes
31-
// their color opacities to stack with an `rgba` color.
32-
--mat-mdc-slider-value-indicator-opacity: #{if($is-dark, 0.9, 0.6)};
33-
34-
&.mat-primary {
35-
@include _slider-color(primary, on-primary);
36-
}
37-
38-
&.mat-accent {
39-
@include _slider-color(secondary, on-secondary);
40-
}
41-
42-
&.mat-warn {
43-
@include _slider-color(error, on-error);
44-
}
39+
&.mat-warn {
40+
$warn: map.get($config, warn);
41+
@include mdc-slider-theme.theme(
42+
m2-mdc-slider.private-get-color-palette-color-tokens($warn)
43+
);
44+
@include _slider-ripple-color($warn);
4545
}
4646
}
4747
}
4848

4949
@mixin typography($config-or-theme) {
5050
$config: typography.private-typography-to-2018-config(
5151
theming.get-typography-config($config-or-theme));
52-
@include mdc-helpers.using-mdc-typography($config) {
53-
.mat-mdc-slider {
54-
@include mdc-slider-theme.theme((
55-
label-label-text-font: mdc-typography.get-font(subtitle2),
56-
label-label-text-size: mdc-typography.get-size(subtitle2),
57-
label-label-text-line-height: mdc-typography.get-line-height(subtitle2),
58-
label-label-text-tracking: mdc-typography.get-tracking(subtitle2),
59-
label-label-text-weight: mdc-typography.get-weight(subtitle2),
60-
));
61-
}
52+
$mdc-typography-tokens: m2-mdc-slider.get-typography-tokens($config);
53+
54+
// Add values for MDC slider tokens.
55+
.mat-mdc-slider {
56+
@include mdc-slider-theme.theme($mdc-typography-tokens);
6257
}
6358
}
6459

65-
@mixin density($config-or-theme) {}
60+
@mixin density($config-or-theme) {
61+
$density-scale: theming.get-density-config($config-or-theme);
62+
$mdc-density-tokens: m2-mdc-slider.get-density-tokens($density-scale);
63+
64+
// Add values for MDC slider tokens.
65+
.mat-mdc-slider {
66+
@include mdc-slider-theme.theme($mdc-density-tokens);
67+
}
68+
}
6669

6770
@mixin theme($theme-or-color-config) {
6871
$theme: theming.private-legacy-get-theme($theme-or-color-config);
@@ -83,22 +86,10 @@
8386
}
8487
}
8588

86-
@mixin _slider-color($color, $on-color) {
87-
$ripple-color: map.get(mdc-theme-variables.$property-values, $color);
88-
$resolved-color: mdc-theme-color.prop-value($color);
89-
$resolved-on-color: mdc-theme-color.prop-value($on-color);
90-
91-
@include mdc-slider-theme.theme((
92-
handle-color: $resolved-color,
93-
focus-handle-color: $resolved-color,
94-
hover-handle-color: $resolved-color,
95-
active-track-color: $resolved-color,
96-
inactive-track-color: $resolved-color,
97-
with-tick-marks-active-container-color: $resolved-on-color,
98-
with-tick-marks-inactive-container-color: $resolved-color,
99-
));
100-
101-
--mat-mdc-slider-ripple-color: #{$ripple-color};
102-
--mat-mdc-slider-hover-ripple-color: #{rgba($ripple-color, 0.05)};
103-
--mat-mdc-slider-focus-ripple-color: #{rgba($ripple-color, 0.2)};
89+
// Generated MDC ripple color tokens are not being calculated so needs to be set
90+
@mixin _slider-ripple-color($color-palette) {
91+
$color: theming.get-color-from-palette($color-palette);
92+
--mat-mdc-slider-ripple-color: #{$color};
93+
--mat-mdc-slider-hover-ripple-color: #{rgba($color, 0.05)};
94+
--mat-mdc-slider-focus-ripple-color: #{rgba($color, 0.2)};
10495
}

0 commit comments

Comments
 (0)