Skip to content

Commit 1d7f2be

Browse files
committed
refactor(material/core): split up M3 token processing into separate files
Splits up our processing of MDC's tokens into separate files so they're a bit more manageable. (cherry picked from commit f245153)
1 parent 8e45545 commit 1d7f2be

30 files changed

+1384
-1236
lines changed

src/material/core/tokens/_custom-tokens.scss

Lines changed: 0 additions & 605 deletions
This file was deleted.

src/material/core/tokens/_m3-tokens.scss

Lines changed: 0 additions & 605 deletions
Large diffs are not rendered by default.

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
@use '@material/theme/custom-properties' as mdc-custom-properties;
66
@use '@material/theme/theme' as mdc-theme;
77
@use '@material/theme/keys' as mdc-keys;
8+
@use '@material/tokens/v0_161' as mdc-tokens;
89
@use '../style/sass-utils';
910
@use '../m2/palette' as m2-palette;
1011
@use '../m2/theming' as m2-theming;
@@ -142,6 +143,17 @@ $_component-prefix: null;
142143
}
143144
}
144145

146+
/// Gets all the MDC token values for a specific component. This function serves as single
147+
/// point at which we directly reference a specific version of the MDC tokens.
148+
/// @param {String} $component Name of the component for which to get the tokens
149+
/// @param {Map} $systems The MDC system tokens
150+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
151+
/// @return {List} Map of token names to values
152+
@function get-mdc-tokens($component, $systems, $exclude-hardcoded) {
153+
$fn: meta.get-function($name: 'md-comp-' + $component + '-values', $module: 'mdc-tokens');
154+
@return meta.call($fn, $systems, $exclude-hardcoded);
155+
}
156+
145157
// MDC doesn't currently handle elevation tokens properly. As a temporary workaround we can combine
146158
// the elevation and shadow-color tokens into a full box-shadow and use it as the value for the
147159
// elevation token.
@@ -288,6 +300,63 @@ $_component-prefix: null;
288300
@return $result;
289301
}
290302

303+
/// Maps the values in a map to new values using the given mapping function
304+
/// @param {Map} $map The maps whose values will be mapped to new values.
305+
/// @param {Function} $fn The value mapping function.
306+
/// @param {Map} A new map with its values updated using the mapping function.
307+
@function map-values($map, $fn) {
308+
$result: ();
309+
@each $key, $value in $map {
310+
$result: map.set($result, $key, meta.call($fn, $value));
311+
}
312+
@return $result;
313+
}
314+
315+
/// Renames the keys in a map
316+
/// @param {Map} $map The map whose keys should be renamed
317+
/// @param {Map} $rename-keys A map of original key to renamed key to apply to $map
318+
/// @return {Map} The result of applying the given key renames to the given map.
319+
@function rename-map-keys($map, $rename-keys) {
320+
$result: $map;
321+
@each $old-key-name, $new-key-name in $rename-keys {
322+
@if map.has-key($map, $old-key-name) {
323+
$result: map.set($result, $new-key-name, map.get($map, $old-key-name));
324+
}
325+
}
326+
@return $result;
327+
}
328+
329+
/// At the time of writing, some color tokens (e.g. disabled state) are defined as a solid color
330+
/// token and a separate opacity token. This function applies the opacity to the color and drops the
331+
/// opacity key from the map. Can be removed once b/213331407 is resolved.
332+
/// @param {Map} $tokens The map of tokens currently being generated
333+
/// @param {Map} $all-tokens A map of all tokens, including hardcoded values
334+
/// @param {List} $pairs Pairs of color token names and their opacities. Should be in the shape of
335+
/// `((color: 'color-key', opacity: 'opacity-key'))`.
336+
/// @return {Map} The initial tokens with the combined color values.
337+
@function combine-color-tokens($tokens, $opacity-lookup, $pairs) {
338+
$result: $tokens;
339+
340+
@each $pair in $pairs {
341+
$color-key: map.get($pair, color);
342+
$opacity-key: map.get($pair, opacity);
343+
$color: map.get($tokens, $color-key);
344+
$opacity: map.get($opacity-lookup, $opacity-key);
345+
346+
@if(meta.type-of($color) == 'color') {
347+
$result: map.remove($result, $opacity-key);
348+
$result: map.set($result, $color-key, rgba($color, $opacity));
349+
}
350+
@else if($color != null) {
351+
$result: map.remove($result, $opacity-key);
352+
$combined-color: #{color-mix(in srgb, #{$color} #{($opacity * 100) + '%'}, transparent)};
353+
$result: map.set($result, $color-key, $combined-color);
354+
}
355+
}
356+
357+
@return $result;
358+
}
359+
291360
/// Verifies that the token overrides exist and are used in one of the given token maps.
292361
@mixin _validate-token-overrides($overrides: (), $token-maps) {
293362
$valid-token-names: ();

src/material/core/tokens/m3/_index.scss

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,35 @@
4242
@use './mat/table' as tokens-mat-table;
4343
@use './mat/toolbar' as tokens-mat-toolbar;
4444
@use './mat/tree' as tokens-mat-tree;
45-
// @use './mdc/checkbox' as tokens-mdc-checkbox;
46-
// @use './mdc/text-button' as tokens-mdc-text-button;
47-
// @use './mdc/protected-button' as tokens-mdc-protected-button;
48-
// @use './mdc/filled-button' as tokens-mdc-filled-button;
49-
// @use './mdc/outlined-button' as tokens-mdc-outlined-button;
50-
// @use './mdc/chip' as tokens-mdc-chip;
51-
// @use './mdc/circular-progress' as tokens-mdc-circular-progress;
52-
// @use './mdc/dialog' as tokens-mdc-dialog;
53-
// @use './mdc/elevated-card' as tokens-mdc-elevated-card;
54-
// @use './mdc/extended-fab' as tokens-mdc-extended-fab;
55-
// @use './mdc/fab' as tokens-mdc-fab;
56-
// @use './mdc/fab-small' as tokens-mdc-fab-small;
57-
// @use './mdc/form-field' as tokens-mdc-form-field;
58-
// @use './mdc/filled-text-field' as tokens-mdc-filled-text-field;
59-
// @use './mdc/icon-button' as tokens-mdc-icon-button;
60-
// @use './mdc/linear-progress' as tokens-mdc-linear-progress;
61-
// @use './mdc/list' as tokens-mdc-list;
62-
// @use './mdc/outlined-card' as tokens-mdc-outlined-card;
63-
// @use './mdc/outlined-text-field' as tokens-mdc-outlined-text-field;
64-
// @use './mdc/plain-tooltip' as tokens-mdc-plain-tooltip;
65-
// @use './mdc/radio' as tokens-mdc-radio;
66-
// @use './mdc/slider' as tokens-mdc-slider;
67-
// @use './mdc/snack-bar' as tokens-mdc-snack-bar;
68-
// @use './mdc/switch' as tokens-mdc-switch;
69-
// @use './mdc/tab' as tokens-mdc-tab;
70-
// @use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
45+
@use './mdc/checkbox' as tokens-mdc-checkbox;
46+
@use './mdc/text-button' as tokens-mdc-text-button;
47+
@use './mdc/protected-button' as tokens-mdc-protected-button;
48+
@use './mdc/filled-button' as tokens-mdc-filled-button;
49+
@use './mdc/outlined-button' as tokens-mdc-outlined-button;
50+
@use './mdc/chip' as tokens-mdc-chip;
51+
@use './mdc/circular-progress' as tokens-mdc-circular-progress;
52+
@use './mdc/dialog' as tokens-mdc-dialog;
53+
@use './mdc/elevated-card' as tokens-mdc-elevated-card;
54+
@use './mdc/extended-fab' as tokens-mdc-extended-fab;
55+
@use './mdc/fab' as tokens-mdc-fab;
56+
@use './mdc/fab-small' as tokens-mdc-fab-small;
57+
@use './mdc/form-field' as tokens-mdc-form-field;
58+
@use './mdc/filled-text-field' as tokens-mdc-filled-text-field;
59+
@use './mdc/icon-button' as tokens-mdc-icon-button;
60+
@use './mdc/linear-progress' as tokens-mdc-linear-progress;
61+
@use './mdc/list' as tokens-mdc-list;
62+
@use './mdc/outlined-card' as tokens-mdc-outlined-card;
63+
@use './mdc/outlined-text-field' as tokens-mdc-outlined-text-field;
64+
@use './mdc/plain-tooltip' as tokens-mdc-plain-tooltip;
65+
@use './mdc/radio' as tokens-mdc-radio;
66+
@use './mdc/slider' as tokens-mdc-slider;
67+
@use './mdc/snack-bar' as tokens-mdc-snack-bar;
68+
@use './mdc/switch' as tokens-mdc-switch;
69+
@use './mdc/tab' as tokens-mdc-tab;
70+
@use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
7171

7272
$_module-names: (
73+
// Custom tokens
7374
tokens-mat-app,
7475
tokens-mat-autocomplete,
7576
tokens-mat-badge,
@@ -112,6 +113,35 @@ $_module-names: (
112113
tokens-mat-text-button,
113114
tokens-mat-toolbar,
114115
tokens-mat-tree,
116+
117+
// MDC tokens
118+
tokens-mdc-checkbox,
119+
tokens-mdc-chip,
120+
tokens-mdc-text-button,
121+
tokens-mdc-protected-button,
122+
tokens-mdc-filled-button,
123+
tokens-mdc-outlined-button,
124+
tokens-mdc-chip,
125+
tokens-mdc-circular-progress,
126+
tokens-mdc-dialog,
127+
tokens-mdc-elevated-card,
128+
tokens-mdc-extended-fab,
129+
tokens-mdc-fab,
130+
tokens-mdc-fab-small,
131+
tokens-mdc-form-field,
132+
tokens-mdc-filled-text-field,
133+
tokens-mdc-icon-button,
134+
tokens-mdc-linear-progress,
135+
tokens-mdc-list,
136+
tokens-mdc-outlined-card,
137+
tokens-mdc-outlined-text-field,
138+
tokens-mdc-plain-tooltip,
139+
tokens-mdc-radio,
140+
tokens-mdc-slider,
141+
tokens-mdc-snack-bar,
142+
tokens-mdc-switch,
143+
tokens-mdc-tab,
144+
tokens-mdc-tab-indicator,
115145
);
116146

117147
/// Gets the full set of M3 tokens for the given theme object.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
@use 'sass:map';
2+
@use 'sass:meta';
3+
@use '../../token-utils';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mdc, checkbox);
7+
8+
/// Generates the tokens for MDC checkbox
9+
/// @param {Map} $systems The MDC system tokens
10+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
11+
/// @param {Map} $token-slots Possible token slots
12+
/// @return {Map} A set of tokens for the MDC checkbox
13+
@function get-tokens($systems, $exclude-hardcoded, $token-slots) {
14+
$mdc-tokens: token-utils.get-mdc-tokens('checkbox', $systems, $exclude-hardcoded);
15+
$variant-tokens: (
16+
primary: (), // Default, no overrides needed
17+
secondary: (
18+
selected-container-color: map.get($systems, md-sys-color, secondary),
19+
selected-focus-container-color: map.get($systems, md-sys-color, secondary),
20+
selected-focus-icon-color: map.get($systems, md-sys-color, on-secondary),
21+
selected-focus-state-layer-color: map.get($systems, md-sys-color, secondary),
22+
selected-hover-container-color: map.get($systems, md-sys-color, secondary),
23+
selected-hover-icon-color: map.get($systems, md-sys-color, on-secondary),
24+
selected-hover-state-layer-color: map.get($systems, md-sys-color, secondary),
25+
selected-icon-color: map.get($systems, md-sys-color, on-secondary),
26+
selected-pressed-container-color: map.get($systems, md-sys-color, secondary),
27+
selected-pressed-icon-color: map.get($systems, md-sys-color, on-secondary),
28+
unselected-pressed-state-layer-color: map.get($systems, md-sys-color, secondary),
29+
),
30+
tertiary: (
31+
selected-container-color: map.get($systems, md-sys-color, tertiary),
32+
selected-focus-container-color: map.get($systems, md-sys-color, tertiary),
33+
selected-focus-icon-color: map.get($systems, md-sys-color, on-tertiary),
34+
selected-focus-state-layer-color: map.get($systems, md-sys-color, tertiary),
35+
selected-hover-container-color: map.get($systems, md-sys-color, tertiary),
36+
selected-hover-icon-color: map.get($systems, md-sys-color, on-tertiary),
37+
selected-hover-state-layer-color: map.get($systems, md-sys-color, tertiary),
38+
selected-icon-color: map.get($systems, md-sys-color, on-tertiary),
39+
selected-pressed-container-color: map.get($systems, md-sys-color, tertiary),
40+
selected-pressed-icon-color: map.get($systems, md-sys-color, on-tertiary),
41+
unselected-pressed-state-layer-color: map.get($systems, md-sys-color, tertiary),
42+
),
43+
error: (
44+
selected-container-color: map.get($systems, md-sys-color, error),
45+
selected-focus-container-color: map.get($systems, md-sys-color, error),
46+
selected-focus-icon-color: map.get($systems, md-sys-color, on-error),
47+
selected-focus-state-layer-color: map.get($systems, md-sys-color, error),
48+
selected-hover-container-color: map.get($systems, md-sys-color, error),
49+
selected-hover-icon-color: map.get($systems, md-sys-color, on-error),
50+
selected-hover-state-layer-color: map.get($systems, md-sys-color, error),
51+
selected-icon-color: map.get($systems, md-sys-color, on-error),
52+
selected-pressed-container-color: map.get($systems, md-sys-color, error),
53+
selected-pressed-icon-color: map.get($systems, md-sys-color, on-error),
54+
unselected-pressed-state-layer-color: map.get($systems, md-sys-color, error),
55+
)
56+
);
57+
58+
@return token-utils.namespace-tokens(
59+
$prefix,
60+
(
61+
_fix-tokens($mdc-tokens),
62+
token-utils.map-values($variant-tokens, meta.get-function(_fix-tokens))
63+
),
64+
$token-slots
65+
);
66+
}
67+
68+
/// Renames the official checkbox tokens to match the names actually used in MDC's code (which are
69+
/// different). This is a temporary workaround until MDC updates to use the correct names for the
70+
/// tokens.
71+
/// @param {Map} $tokens The map of checkbox tokens with the official tokens names
72+
/// @param {Map} $all-tokens Map of all checkbox tokens, including hardcoded values.
73+
/// This is necessary in order to do opacity lookups.
74+
/// @return {Map} The given tokens, renamed to be compatible with MDC's token implementation.
75+
@function _fix-tokens($tokens) {
76+
// Need to get the hardcoded values, because they include opacities that are used for the disabled
77+
// state.
78+
$hardcoded-tokens: token-utils.get-mdc-tokens('checkbox', (), false);
79+
80+
$rename-keys: (
81+
selected-icon-color: selected-checkmark-color,
82+
selected-disabled-icon-color: disabled-selected-checkmark-color,
83+
selected-container-color: selected-icon-color,
84+
selected-hover-container-color: selected-hover-icon-color,
85+
selected-disabled-container-color: disabled-selected-icon-color,
86+
selected-disabled-container-opacity: disabled-selected-icon-opacity,
87+
selected-focus-container-color: selected-focus-icon-color,
88+
selected-pressed-container-color: selected-pressed-icon-color,
89+
unselected-disabled-outline-color: disabled-unselected-icon-color,
90+
unselected-disabled-container-opacity: disabled-unselected-icon-opacity,
91+
unselected-focus-outline-color: unselected-focus-icon-color,
92+
unselected-hover-outline-color: unselected-hover-icon-color,
93+
unselected-outline-color: unselected-icon-color,
94+
unselected-pressed-outline-color: unselected-pressed-icon-color
95+
);
96+
97+
$remapped-tokens: token-utils.rename-map-keys($tokens, $rename-keys);
98+
$remapped-hardcoded-tokens: token-utils.rename-map-keys($hardcoded-tokens, $rename-keys);
99+
100+
@return token-utils.combine-color-tokens($remapped-tokens, $remapped-hardcoded-tokens, (
101+
(
102+
color: disabled-selected-icon-color,
103+
opacity: disabled-selected-icon-opacity,
104+
),
105+
(
106+
color: disabled-unselected-icon-color,
107+
opacity: disabled-unselected-icon-opacity,
108+
),
109+
));
110+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@use 'sass:map';
2+
@use '../../../style/sass-utils';
3+
@use '../../token-utils';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mdc, chip);
7+
8+
/// Generates the tokens for MDC chip
9+
/// @param {Map} $systems The MDC system tokens
10+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
11+
/// @param {Map} $token-slots Possible token slots
12+
/// @return {Map} A set of tokens for the MDC chip
13+
@function get-tokens($systems, $exclude-hardcoded, $token-slots) {
14+
// MDC has a chip component, but they seem to have made up the tokens rather than using ones
15+
// generated from the token database, therefore we need a custom token function for it.
16+
$tokens: sass-utils.merge-all(
17+
token-utils.generate-typography-tokens($systems, label-text, label-large),
18+
(
19+
container-shape: token-utils.hardcode((
20+
family: rounded,
21+
radius: 8px,
22+
), $exclude-hardcoded),
23+
with-avatar-avatar-size: token-utils.hardcode(24px, $exclude-hardcoded),
24+
label-text-color: map.get($systems, md-sys-color, on-surface-variant),
25+
disabled-label-text-color: sass-utils.safe-color-change(
26+
map.get($systems, md-sys-color, on-surface),
27+
$alpha: 0.38,
28+
),
29+
with-icon-icon-size: token-utils.hardcode(18px, $exclude-hardcoded),
30+
with-icon-icon-color: map.get($systems, md-sys-color, on-surface-variant),
31+
with-icon-disabled-icon-color: map.get($systems, md-sys-color, on-surface),
32+
with-icon-selected-icon-color: map.get($systems, md-sys-color, on-secondary-container),
33+
with-trailing-icon-trailing-icon-color: map.get($systems, md-sys-color, on-surface-variant),
34+
with-trailing-icon-disabled-trailing-icon-color: map.get($systems, md-sys-color, on-surface),
35+
focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity),
36+
focus-state-layer-color: map.get($systems, md-sys-color, on-surface-variant),
37+
outline-width: token-utils.hardcode(1px, $exclude-hardcoded),
38+
outline-color: map.get($systems, md-sys-color, outline),
39+
disabled-outline-color: sass-utils.safe-color-change(
40+
map.get($systems, md-sys-color, on-surface),
41+
$alpha: 0.12,
42+
),
43+
focus-outline-color: map.get($systems, md-sys-color, on-surface-variant),
44+
hover-state-layer-color: map.get($systems, md-sys-color, on-surface-variant),
45+
hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity),
46+
with-avatar-disabled-avatar-opacity: token-utils.hardcode(0.38, $exclude-hardcoded),
47+
elevated-selected-container-color: map.get($systems, md-sys-color, secondary-container),
48+
flat-selected-outline-width: token-utils.hardcode(0, $exclude-hardcoded),
49+
selected-label-text-color: map.get($systems, md-sys-color, on-secondary-container),
50+
flat-disabled-selected-container-color: sass-utils.safe-color-change(
51+
map.get($systems, md-sys-color, on-surface),
52+
$alpha: 0.12,
53+
),
54+
selected-hover-state-layer-color: map.get($systems, md-sys-color, on-secondary-container),
55+
selected-hover-state-layer-opacity:
56+
map.get($systems, md-sys-state, hover-state-layer-opacity),
57+
selected-focus-state-layer-color: map.get($systems, md-sys-color, on-secondary-container),
58+
selected-focus-state-layer-opacity:
59+
map.get($systems, md-sys-state, focus-state-layer-opacity),
60+
with-icon-disabled-icon-opacity: token-utils.hardcode(0.38, $exclude-hardcoded),
61+
with-trailing-icon-disabled-trailing-icon-opacity:
62+
token-utils.hardcode(0.38, $exclude-hardcoded),
63+
),
64+
), (
65+
// Color variants:
66+
primary: (
67+
with-icon-selected-icon-color: map.get($systems, md-sys-color, on-primary-container),
68+
elevated-selected-container-color: map.get($systems, md-sys-color, primary-container),
69+
selected-label-text-color: map.get($systems, md-sys-color, on-primary-container),
70+
selected-hover-state-layer-color: map.get($systems, md-sys-color, on-primary-container),
71+
selected-focus-state-layer-color: map.get($systems, md-sys-color, on-primary-container),
72+
),
73+
secondary: (), // Default, no overrides needed.
74+
tertiary: (
75+
with-icon-selected-icon-color: map.get($systems, md-sys-color, on-tertiary-container),
76+
elevated-selected-container-color: map.get($systems, md-sys-color, tertiary-container),
77+
selected-label-text-color: map.get($systems, md-sys-color, on-tertiary-container),
78+
selected-hover-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container),
79+
selected-focus-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container),
80+
),
81+
error: (
82+
with-icon-selected-icon-color: map.get($systems, md-sys-color, on-error-container),
83+
elevated-selected-container-color: map.get($systems, md-sys-color, error-container),
84+
selected-label-text-color: map.get($systems, md-sys-color, on-error-container),
85+
selected-hover-state-layer-color: map.get($systems, md-sys-color, on-error-container),
86+
selected-focus-state-layer-color: map.get($systems, md-sys-color, on-error-container),
87+
)
88+
);
89+
90+
@return token-utils.namespace-tokens($prefix, $tokens, $token-slots);
91+
}

0 commit comments

Comments
 (0)