Skip to content

Commit 1f96bf8

Browse files
committed
Generate all M2 tokens from a theme object
1 parent ecb12f8 commit 1f96bf8

23 files changed

+338
-260
lines changed

src/dev-app/theme-token-api.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@use '@angular/material' as mat;
2+
13
dev-app {
24
&::before {
35
content: 'Using experimental theming API';
@@ -12,3 +14,5 @@ dev-app {
1214
color: white;
1315
}
1416
}
17+
18+
@debug 'Generated M2 tokens:' mat.m2-tokens-from-theme();

src/material/_index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
define-legacy-typography-config, legacy-typography-hierarchy, typography-hierarchy;
1414
@forward './core/typography/typography-utils' show typography-level,
1515
font-size, line-height, font-weight, letter-spacing, font-family, font-shorthand;
16+
@forward './core/tokens/m2' show m2-tokens-from-theme;
1617

1718
// Private/Internal
1819
@forward './core/density/private/all-density' show all-component-densities;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1+
@use 'sass:map';
2+
13
// Include content under the current selector (&) or the document root if there is no current
24
// selector.
35
@mixin current-selector-or-root($root: html) {
46
@at-root #{& or $root} {
57
@content;
68
}
79
}
10+
11+
// A version of the standard `map.deep-merge` function that takes a variable number of arguments.
12+
// Each argument is deep-merged into the final result from left to right.
13+
@function deep-merge-all($maps...) {
14+
$result: ();
15+
@each $map in $maps {
16+
$result: map.deep-merge($result, $map);
17+
}
18+
@return $result;
19+
}

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ $_component-prefix: null;
5151
@mixin _configure-token-prefix($first, $rest...) {
5252
$_component-prefix: '' !global;
5353
@each $item in $rest {
54-
$_component-prefix:
55-
if($_component-prefix == '', $item, '#{$_component-prefix}-#{$item}') !global;
54+
$_component-prefix: if($_component-prefix == '', $item, '#{$_component-prefix}-#{$item}') !global;
5655
}
5756
@include mdc-custom-properties.configure($varname-prefix: $first) {
5857
@content;
@@ -87,15 +86,6 @@ $_component-prefix: null;
8786
}
8887
}
8988

90-
// Merges together a list of maps into a single map.
91-
@function merge-all($maps...) {
92-
$result: ();
93-
@each $map in $maps {
94-
$result: map.merge($result, $map);
95-
}
96-
@return $result;
97-
}
98-
9989
// MDC doesn't currently handle elevation tokens properly. As a temporary workaround we can combine
10090
// the elevation and shadow-color tokens into a full box-shadow and use it as the value for the
10191
// elevation token.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
@use 'sass:list';
2+
@use 'sass:map';
3+
@use 'sass:meta';
4+
@use '../../theming/palette';
5+
@use '../../theming/theming' as theming;
6+
@use '../../typography/all-typography';
7+
@use '../../style/sass-utils';
8+
9+
@use './mat/card' as tokens-mat-card;
10+
@use './mat/radio' as tokens-mat-radio;
11+
@use './mat/snack-bar' as tokens-mat-snack-bar;
12+
@use './mat/tab-header' as tokens-mat-tab-header;
13+
@use './mat/tab-header-with-background' as tokens-mat-tab-header-with-background;
14+
@use './mdc/checkbox' as tokens-mdc-checkbox;
15+
@use './mdc/circular-progress' as tokens-mdc-circular-progress;
16+
@use './mdc/dialog' as tokens-mdc-dialog;
17+
@use './mdc/elevated-card' as tokens-mdc-elevated-card;
18+
@use './mdc/icon-button' as tokens-mdc-icon-button;
19+
@use './mdc/linear-progress' as tokens-mdc-linear-progress;
20+
@use './mdc/list' as tokens-mdc-list;
21+
@use './mdc/outlined-card' as tokens-mdc-outlined-card;
22+
@use './mdc/radio' as tokens-mdc-radio;
23+
@use './mdc/snack-bar' as tokens-mdc-snack-bar;
24+
@use './mdc/tab' as tokens-mdc-tab;
25+
@use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
26+
27+
// Gets the tokens for the given theme, m2 tokens module, and theming system.
28+
// Valid theming systems are: unthemable, color, typography, density.
29+
@function _get-tokens-for-module-and-system($theme, $module, $system) {
30+
@if $system == unthemable {
31+
@return meta.call(
32+
meta.get-function(get-#{$system}-tokens, $module: $module));
33+
}
34+
@return meta.call(
35+
meta.get-function(get-#{$system}-tokens, $module: $module), map.get($theme, $system));
36+
}
37+
38+
// Gets the fully qualified tokens map for the given theme and m2 tokens module.
39+
@function _get-tokens-for-module($theme, $module) {
40+
$tokens: sass-utils.deep-merge-all(
41+
_get-tokens-for-module-and-system($theme, $module, unthemable),
42+
_get-tokens-for-module-and-system($theme, $module, color),
43+
_get-tokens-for-module-and-system($theme, $module, typography),
44+
_get-tokens-for-module-and-system($theme, $module, density));
45+
@return map.set((), map.get(meta.module-variables($module), prefix), $tokens);
46+
}
47+
48+
// Gets the full set of m2 tokens for the given theme object. If parts of the theme are missing
49+
// (color, density, etc), defaults are used. Returned format:
50+
// (
51+
// (fully, qualified, namespace): (
52+
// token: value
53+
// )
54+
// )
55+
@function m2-tokens-from-theme($theme: ()) {
56+
$theme: map.merge((
57+
color: theming.define-light-theme(
58+
theming.define-palette(palette.$indigo-palette),
59+
theming.define-palette(palette.$pink-palette),
60+
),
61+
typography: all-typography.define-typography-config(),
62+
density: 0
63+
), $theme);
64+
65+
@return sass-utils.deep-merge-all(
66+
_get-tokens-for-module($theme, tokens-mat-card),
67+
_get-tokens-for-module($theme, tokens-mat-radio),
68+
_get-tokens-for-module($theme, tokens-mat-snack-bar),
69+
_get-tokens-for-module($theme, tokens-mat-tab-header),
70+
_get-tokens-for-module($theme, tokens-mat-tab-header-with-background),
71+
_get-tokens-for-module($theme, tokens-mdc-checkbox),
72+
_get-tokens-for-module($theme, tokens-mdc-circular-progress),
73+
_get-tokens-for-module($theme, tokens-mdc-dialog),
74+
_get-tokens-for-module($theme, tokens-mdc-elevated-card),
75+
_get-tokens-for-module($theme, tokens-mdc-icon-button),
76+
_get-tokens-for-module($theme, tokens-mdc-linear-progress),
77+
_get-tokens-for-module($theme, tokens-mdc-list),
78+
_get-tokens-for-module($theme, tokens-mdc-outlined-card),
79+
_get-tokens-for-module($theme, tokens-mdc-radio),
80+
_get-tokens-for-module($theme, tokens-mdc-snack-bar),
81+
_get-tokens-for-module($theme, tokens-mdc-tab),
82+
_get-tokens-for-module($theme, tokens-mdc-tab-indicator),
83+
);
84+
}

src/material/core/tokens/m2/mat/_card.scss

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@use '../../token-utils';
33
@use '../../../theming/theming';
44
@use '../../../typography/typography-utils';
5+
@use '../../../style/sass-utils';
56

67
// The prefix used to generate the fully qualified name for tokens in this file.
78
$prefix: (mat, card);
@@ -18,35 +19,35 @@ $prefix: (mat, card);
1819

1920
@return (
2021
// Text color of the card's subtitle.
21-
subtitle-text-color: theming.get-color-from-palette($foreground, secondary-text),
22+
subtitle-text-color: theming.get-color-from-palette($foreground, secondary-text),
2223
);
2324
}
2425

2526
// Tokens that can be configured through Angular Material's typography theming API.
2627
@function get-typography-tokens($config) {
2728
@return (
2829
// Font family of the card's title.
29-
title-text-font: typography-utils.font-family($config, headline-6)
30+
title-text-font: typography-utils.font-family($config, headline-6)
3031
or typography-utils.font-family($config),
3132
// Line height of the card's title.
32-
title-text-line-height: typography-utils.line-height($config, headline-6),
33+
title-text-line-height: typography-utils.line-height($config, headline-6),
3334
// Font size of the card's title.
34-
title-text-size: typography-utils.font-size($config, headline-6),
35+
title-text-size: typography-utils.font-size($config, headline-6),
3536
// Letter spacing of the card's title.
36-
title-text-tracking: typography-utils.letter-spacing($config, headline-6),
37+
title-text-tracking: typography-utils.letter-spacing($config, headline-6),
3738
// Font weight of the card's title.
38-
title-text-weight: typography-utils.font-weight($config, headline-6),
39+
title-text-weight: typography-utils.font-weight($config, headline-6),
3940
// Font family of the card's subtitle.
40-
subtitle-text-font: typography-utils.font-family($config, subtitle-2)
41+
subtitle-text-font: typography-utils.font-family($config, subtitle-2)
4142
or typography-utils.font-family($config),
4243
// Line height of the card's subtitle.
43-
subtitle-text-line-height: typography-utils.line-height($config, subtitle-2),
44+
subtitle-text-line-height: typography-utils.line-height($config, subtitle-2),
4445
// Font size of the card's subtitle.
45-
subtitle-text-size: typography-utils.font-size($config, subtitle-2),
46+
subtitle-text-size: typography-utils.font-size($config, subtitle-2),
4647
// Letter spacing of the card's subtitle.
47-
subtitle-text-tracking: typography-utils.letter-spacing($config, subtitle-2),
48+
subtitle-text-tracking: typography-utils.letter-spacing($config, subtitle-2),
4849
// Font weight of the card's subtitle.
49-
subtitle-text-weight: typography-utils.font-weight($config, subtitle-2),
50+
subtitle-text-weight: typography-utils.font-weight($config, subtitle-2),
5051
);
5152
}
5253

@@ -58,10 +59,10 @@ $prefix: (mat, card);
5859
// Combines the tokens generated by the above functions into a single map with placeholder values.
5960
// This is used to create token slots.
6061
@function get-token-slots() {
61-
@return token-utils.merge-all(
62-
get-unthemable-tokens(),
63-
get-color-tokens(token-utils.$placeholder-color-config),
64-
get-typography-tokens(token-utils.$placeholder-typography-config),
65-
get-density-tokens(token-utils.$placeholder-density-config)
62+
@return sass-utils.deep-merge-all(
63+
get-unthemable-tokens(),
64+
get-color-tokens(token-utils.$placeholder-color-config),
65+
get-typography-tokens(token-utils.$placeholder-typography-config),
66+
get-density-tokens(token-utils.$placeholder-density-config)
6667
);
6768
}

src/material/core/tokens/m2/mat/_radio.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@use 'sass:map';
22
@use '../../token-utils';
33
@use '../../../theming/theming';
4+
@use '../../../style/sass-utils';
45

56
// The prefix used to generate the fully qualified name for tokens in this file.
67
$prefix: (mat, radio);
@@ -37,10 +38,10 @@ $prefix: (mat, radio);
3738
// Combines the tokens generated by the above functions into a single map with placeholder values.
3839
// This is used to create token slots.
3940
@function get-token-slots() {
40-
@return token-utils.merge-all(
41-
get-unthemable-tokens(),
42-
get-color-tokens(token-utils.$placeholder-color-config),
43-
get-typography-tokens(token-utils.$placeholder-typography-config),
44-
get-density-tokens(token-utils.$placeholder-density-config)
41+
@return sass-utils.deep-merge-all(
42+
get-unthemable-tokens(),
43+
get-color-tokens(token-utils.$placeholder-color-config),
44+
get-typography-tokens(token-utils.$placeholder-typography-config),
45+
get-density-tokens(token-utils.$placeholder-density-config)
4546
);
4647
}

src/material/core/tokens/m2/mat/_snack-bar.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@use 'sass:map';
22
@use '../../token-utils';
33
@use '../../../theming/theming';
4+
@use '../../../style/sass-utils';
45

56
// The prefix used to generate the fully qualified name for tokens in this file.
67
$prefix: (mat, snack-bar);
@@ -34,10 +35,10 @@ $prefix: (mat, snack-bar);
3435
// Combines the tokens generated by the above functions into a single map with placeholder values.
3536
// This is used to create token slots.
3637
@function get-token-slots() {
37-
@return token-utils.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)
38+
@return sass-utils.deep-merge-all(
39+
get-unthemable-tokens(),
40+
get-color-tokens(token-utils.$placeholder-color-config),
41+
get-typography-tokens(token-utils.$placeholder-typography-config),
42+
get-density-tokens(token-utils.$placeholder-density-config)
4243
);
4344
}

src/material/core/tokens/m2/mat/_tab-header-with-background.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@use 'sass:map';
22
@use '../../token-utils';
33
@use '../../../theming/theming';
4+
@use '../../../style/sass-utils';
45

56
// The prefix used to generate the fully qualified name for tokens in this file.
67
$prefix: (mat, tab-header-with-background);
@@ -34,10 +35,10 @@ $prefix: (mat, tab-header-with-background);
3435
// Combines the tokens generated by the above functions into a single map with placeholder values.
3536
// This is used to create token slots.
3637
@function get-token-slots() {
37-
@return token-utils.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)
38+
@return sass-utils.deep-merge-all(
39+
get-unthemable-tokens(),
40+
get-color-tokens(token-utils.$placeholder-color-config),
41+
get-typography-tokens(token-utils.$placeholder-typography-config),
42+
get-density-tokens(token-utils.$placeholder-density-config)
4243
);
4344
}

src/material/core/tokens/m2/mat/_tab-header.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@use '../../token-utils';
33
@use '../../../theming/theming';
44
@use '../../../typography/typography-utils';
5+
@use '../../../style/sass-utils';
56

67
// The prefix used to generate the fully qualified name for tokens in this file.
78
$prefix: (mat, tab-header);
@@ -62,7 +63,7 @@ $prefix: (mat, tab-header);
6263
// Combines the tokens generated by the above functions into a single map with placeholder values.
6364
// This is used to create token slots.
6465
@function get-token-slots() {
65-
@return token-utils.merge-all(
66+
@return sass-utils.deep-merge-all(
6667
get-unthemable-tokens(),
6768
get-color-tokens(token-utils.$placeholder-color-config),
6869
get-typography-tokens(token-utils.$placeholder-typography-config),

0 commit comments

Comments
 (0)