Skip to content

Commit 8c4b151

Browse files
committed
feat(multiple): fallback to system level variables
1 parent fd47a0e commit 8c4b151

File tree

7 files changed

+199
-55
lines changed

7 files changed

+199
-55
lines changed

src/material/_index.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
@forward './core/typography/typography' show typography-hierarchy;
1919
@forward './core/typography/typography-utils' show font-shorthand;
2020
@forward './core/tokens/m2' show m2-tokens-from-theme;
21-
@forward './core/tokens/m3-tokens' show system-level-colors, system-level-typography;
21+
@forward './core/tokens/m3-tokens' show system-level-colors,
22+
system-level-typography, system-level-elevation, system-level-shape,
23+
system-level-motion, system-level-state;
2224

2325
// Private/Internal
2426
@forward './core/density/private/all-density' show all-component-densities;

src/material/core/style/_elevation.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ $prefix: 'mat-elevation-z';
143143
@return null;
144144
}
145145

146+
// Return the value if it is a CSS variable name
147+
@if (meta.type-of($zValue) == string and string.index($zValue, '--') == 1) {
148+
@return $zValue;
149+
}
150+
146151
@if meta.type-of($zValue) != number or not math.is-unitless($zValue) {
147152
@error '$zValue must be a unitless number, but received `#{$zValue}`';
148153
}

src/material/core/style/_sass-utils.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@use 'sass:color';
2+
@use 'sass:string';
23
@use 'sass:list';
34
@use 'sass:map';
45
@use 'sass:meta';
@@ -67,9 +68,18 @@ $use-system-typography-variables: false;
6768
@if (meta.type-of($color) == 'color') {
6869
@return color.change($color, $args...);
6970
}
70-
@else if ($color != null and map.get($args, alpha) != null and $use-system-color-variables) {
71+
@else if ($color != null and map.get($args, alpha) != null) {
7172
$opacity: map.get($args, alpha);
72-
@return #{color-mix(in srgb, #{$color} #{($opacity * 100) + '%'}, transparent)};
73+
@if meta.type-of($opacity) == number {
74+
$opacity: ($opacity * 100) + '%';
75+
}
76+
77+
// Wrap the $color as a `var()` if it's the name of a CSS variable
78+
@if (meta.type-of($opacity) == string and string.index($color, '--') == 1) {
79+
$color: var($color);
80+
}
81+
82+
@return #{color-mix(in srgb, #{$color} #{$opacity}, transparent)};
7383
}
7484
@return $color;
7585
}

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

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
@use './m3';
55
@use './m3/definitions' as m3-token-definitions;
66
@use '../tokens/m2' as m2-tokens;
7+
@use '../style/elevation';
78
@use './density';
89
@use './format-tokens';
910

11+
// Default system level prefix to use when directly calling the `system-level-*` mixins
12+
$system-level-prefix: sys;
13+
1014
/// Generates tokens for the given palette with the given prefix.
1115
/// @param {Map} $palette The palette to generate tokens for
1216
/// @param {String} $prefix The key prefix used to name the tokens
@@ -87,7 +91,7 @@ $_cached-token-slots: null;
8791
/// @param {Map} $systems The MDC system tokens
8892
/// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens
8993
/// @return {Map} A map of namespaced tokens
90-
@function _generate-tokens($systems, $include-non-systemized: false) {
94+
@function _generate-tokens($systems, $include-non-systemized: false, $include-density: false) {
9195
$systems: map.merge((
9296
md-sys-color: (),
9397
md-sys-elevation: (),
@@ -116,16 +120,63 @@ $_cached-token-slots: null;
116120
// Strip out tokens that are systemized by our made up density system.
117121
@each $namespace, $tokens in $result {
118122
@each $token, $value in $tokens {
119-
@if density.is-systemized($namespace, $token) {
123+
@if density.is-systemized($namespace, $token) and not $include-density {
120124
$tokens: map.remove($tokens, $token);
121125
}
122126
}
123127
$result: map.set($result, $namespace, $tokens);
124128
}
129+
125130
@return $result;
126131
}
127132

128-
@mixin system-level-colors($theme, $overrides: ()) {
133+
// Return a new map where the values are the same as the provided map's
134+
// keys, prefixed with "--mat-app-". For example:
135+
// (key1: '', key2: '') --> (key1: --mat-app-key1, key2: --mat-app-key2)
136+
@function create-system-app-vars-map($map) {
137+
$new-map: ();
138+
@each $key, $value in $map {
139+
$new-map: map.set($new-map, $key, --mat-app-#{$key});
140+
}
141+
@return $new-map;
142+
}
143+
144+
// Create a components tokens map where values are based on
145+
// system fallback variables referencing Material's system keys.
146+
// Includes density token fallbacks where density is 0.
147+
@function create-system-fallbacks() {
148+
$app-vars: (
149+
'md-sys-color':
150+
create-system-app-vars-map(m3-token-definitions.md-sys-color-values-light()),
151+
'md-sys-typescale':
152+
create-system-app-vars-map(m3-token-definitions.md-sys-typescale-values()),
153+
'md-sys-elevation':
154+
create-system-app-vars-map(m3-token-definitions.md-sys-elevation-values()),
155+
'md-sys-state':
156+
create-system-app-vars-map(m3-token-definitions.md-sys-state-values()),
157+
'md-sys-shape':
158+
create-system-app-vars-map(m3-token-definitions.md-sys-shape-values()),
159+
);
160+
161+
@return sass-utils.deep-merge-all(
162+
_generate-tokens($app-vars, true, true),
163+
generate-density-tokens(0)
164+
);
165+
}
166+
167+
// Emits CSS variables for Material's system level values. Uses the
168+
// namespace "--mat-app" .
169+
// e.g. --mat-app-surface: #E5E5E5
170+
@mixin theme($theme, $overrides: ()) {
171+
@include system-level-colors($theme, $overrides, mat-app);
172+
@include system-level-typography($theme, $overrides, mat-app);
173+
@include system-level-elevation($theme, $overrides, mat-app);
174+
@include system-level-shape($theme, $overrides, mat-app);
175+
@include system-level-motion($theme, $overrides, mat-app);
176+
@include system-level-state($theme, $overrides, mat-app);
177+
}
178+
179+
@mixin system-level-colors($theme, $overrides: (), $prefix: null) {
129180
$palettes: map.get($theme, _mat-theming-internals-do-not-access, palettes);
130181
$base-palettes: (
131182
neutral: map.get($palettes, neutral),
@@ -135,11 +186,15 @@ $_cached-token-slots: null;
135186
);
136187

137188
$type: map.get($theme, _mat-theming-internals-do-not-access, theme-type);
138-
$system-variables-prefix: map.get($theme, system-variables-prefix) or sys;
139189
$primary: map.merge(map.get($palettes, primary), $base-palettes);
140190
$tertiary: map.merge(map.get($palettes, tertiary), $base-palettes);
141191
$error: map.get($palettes, error);
142192

193+
@if (not $prefix) {
194+
// TODO: Change this after #29513 is merged.
195+
$prefix: map.get($theme, system-variables-prefix) or $system-level-prefix;
196+
}
197+
143198
$ref: (
144199
md-ref-palette: _generate-ref-palette-tokens($primary, $tertiary, $error)
145200
);
@@ -149,26 +204,28 @@ $_cached-token-slots: null;
149204
m3-token-definitions.md-sys-color-values-light($ref));
150205

151206
@each $name, $value in $sys-colors {
152-
--#{$system-variables-prefix}-#{$name}: #{map.get($overrides, $name) or $value};
207+
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
153208
}
154209
}
155210

156-
@mixin system-level-typography($theme, $overrides: ()) {
211+
@mixin system-level-typography($theme, $overrides: (), $prefix: null) {
157212
$font-definition: map.get($theme, _mat-theming-internals-do-not-access, font-definition);
158213
$brand: map.get($font-definition, brand);
159214
$plain: map.get($font-definition, plain);
160215
$bold: map.get($font-definition, bold);
161216
$medium: map.get($font-definition, medium);
162217
$regular: map.get($font-definition, regular);
163-
$system-variables-prefix: map.get($theme, system-variables-prefix) or sys;
164218
$ref: (
165219
md-ref-typeface: _generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular)
166220
);
167221

168-
$sys-typescale: m3-token-definitions.md-sys-typescale-values($ref);
222+
@if (not $prefix) {
223+
// TODO: Change this after #29513 is merged.
224+
$prefix: map.get($theme, system-variables-prefix) or $system-level-prefix;
225+
}
169226

170-
@each $name, $value in $sys-typescale {
171-
--#{$system-variables-prefix}-#{$name}: #{map.get($overrides, $name) or $value};
227+
@each $name, $value in m3-token-definitions.md-sys-typescale-values($ref) {
228+
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
172229
}
173230
}
174231

@@ -180,6 +237,40 @@ $_cached-token-slots: null;
180237
@return $result;
181238
}
182239

240+
@mixin system-level-elevation($theme, $overrides: (), $prefix: $system-level-prefix) {
241+
$shadow-color: map.get(
242+
$theme, _mat-theming-internals-do-not-access, color-tokens, (mdc, theme), shadow);
243+
244+
@for $level from 0 through 24 {
245+
$value: elevation.get-box-shadow($level, $shadow-color);
246+
--#{$prefix}-elevation-shadow-level-#{$level}: #{$value};
247+
}
248+
249+
@each $name, $value in m3-token-definitions.md-sys-elevation-values() {
250+
$level: map.get($overrides, $name) or $value;
251+
$value: elevation.get-box-shadow($level, $shadow-color);
252+
--#{$prefix}-#{$name}: #{$value};
253+
}
254+
}
255+
256+
@mixin system-level-shape($theme, $overrides: (), $prefix: $system-level-prefix) {
257+
@each $name, $value in m3-token-definitions.md-sys-shape-values() {
258+
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
259+
}
260+
}
261+
262+
@mixin system-level-state($theme, $overrides: (), $prefix: $system-level-prefix) {
263+
@each $name, $value in m3-token-definitions.md-sys-state-values() {
264+
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
265+
}
266+
}
267+
268+
@mixin system-level-motion($theme, $overrides: (), $prefix: $system-level-prefix) {
269+
@each $name, $value in m3-token-definitions.md-sys-motion-values() {
270+
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
271+
}
272+
}
273+
183274
@function _get-sys-color($type, $ref, $prefix) {
184275
$mdc-sys-color: if($type == dark,
185276
m3-token-definitions.md-sys-color-values-dark($ref),

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@use 'sass:list';
33
@use 'sass:map';
44
@use 'sass:meta';
5+
@use 'sass:string';
56
@use 'sass:math';
67
@use '../m2/palette' as m2-palette;
78
@use '../m2/theming' as m2-theming;
@@ -161,6 +162,12 @@ $_system-fallbacks: null;
161162
$color-key: map.get($pair, color);
162163
$opacity-key: map.get($pair, opacity);
163164
$color: map.get($tokens, $color-key);
165+
166+
// If the color is a CSS variable name, wrap it in a `var()` statement
167+
@if (meta.type-of($color) == 'string' and string.index($color, '--') == 1) {
168+
$color: var(#{$color});
169+
}
170+
164171
$opacity: map.get($opacity-lookup, $opacity-key);
165172

166173
@if(meta.type-of($color) == 'color') {

0 commit comments

Comments
 (0)