Skip to content

Commit

Permalink
feat(multiple): fallback to system level variables
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewseguin committed Jul 30, 2024
1 parent fd47a0e commit 8c4b151
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 55 deletions.
4 changes: 3 additions & 1 deletion src/material/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
@forward './core/typography/typography' show typography-hierarchy;
@forward './core/typography/typography-utils' show font-shorthand;
@forward './core/tokens/m2' show m2-tokens-from-theme;
@forward './core/tokens/m3-tokens' show system-level-colors, system-level-typography;
@forward './core/tokens/m3-tokens' show system-level-colors,
system-level-typography, system-level-elevation, system-level-shape,
system-level-motion, system-level-state;

// Private/Internal
@forward './core/density/private/all-density' show all-component-densities;
Expand Down
5 changes: 5 additions & 0 deletions src/material/core/style/_elevation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ $prefix: 'mat-elevation-z';
@return null;
}

// Return the value if it is a CSS variable name
@if (meta.type-of($zValue) == string and string.index($zValue, '--') == 1) {
@return $zValue;
}

@if meta.type-of($zValue) != number or not math.is-unitless($zValue) {
@error '$zValue must be a unitless number, but received `#{$zValue}`';
}
Expand Down
14 changes: 12 additions & 2 deletions src/material/core/style/_sass-utils.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@use 'sass:color';
@use 'sass:string';
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
Expand Down Expand Up @@ -67,9 +68,18 @@ $use-system-typography-variables: false;
@if (meta.type-of($color) == 'color') {
@return color.change($color, $args...);
}
@else if ($color != null and map.get($args, alpha) != null and $use-system-color-variables) {
@else if ($color != null and map.get($args, alpha) != null) {
$opacity: map.get($args, alpha);
@return #{color-mix(in srgb, #{$color} #{($opacity * 100) + '%'}, transparent)};
@if meta.type-of($opacity) == number {
$opacity: ($opacity * 100) + '%';
}

// Wrap the $color as a `var()` if it's the name of a CSS variable
@if (meta.type-of($opacity) == string and string.index($color, '--') == 1) {
$color: var($color);
}

@return #{color-mix(in srgb, #{$color} #{$opacity}, transparent)};
}
@return $color;
}
Expand Down
111 changes: 101 additions & 10 deletions src/material/core/tokens/_m3-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
@use './m3';
@use './m3/definitions' as m3-token-definitions;
@use '../tokens/m2' as m2-tokens;
@use '../style/elevation';
@use './density';
@use './format-tokens';

// Default system level prefix to use when directly calling the `system-level-*` mixins
$system-level-prefix: sys;

/// Generates tokens for the given palette with the given prefix.
/// @param {Map} $palette The palette to generate tokens for
/// @param {String} $prefix The key prefix used to name the tokens
Expand Down Expand Up @@ -87,7 +91,7 @@ $_cached-token-slots: null;
/// @param {Map} $systems The MDC system tokens
/// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens
/// @return {Map} A map of namespaced tokens
@function _generate-tokens($systems, $include-non-systemized: false) {
@function _generate-tokens($systems, $include-non-systemized: false, $include-density: false) {
$systems: map.merge((
md-sys-color: (),
md-sys-elevation: (),
Expand Down Expand Up @@ -116,16 +120,63 @@ $_cached-token-slots: null;
// Strip out tokens that are systemized by our made up density system.
@each $namespace, $tokens in $result {
@each $token, $value in $tokens {
@if density.is-systemized($namespace, $token) {
@if density.is-systemized($namespace, $token) and not $include-density {
$tokens: map.remove($tokens, $token);
}
}
$result: map.set($result, $namespace, $tokens);
}

@return $result;
}

@mixin system-level-colors($theme, $overrides: ()) {
// Return a new map where the values are the same as the provided map's
// keys, prefixed with "--mat-app-". For example:
// (key1: '', key2: '') --> (key1: --mat-app-key1, key2: --mat-app-key2)
@function create-system-app-vars-map($map) {
$new-map: ();
@each $key, $value in $map {
$new-map: map.set($new-map, $key, --mat-app-#{$key});
}
@return $new-map;
}

// Create a components tokens map where values are based on
// system fallback variables referencing Material's system keys.
// Includes density token fallbacks where density is 0.
@function create-system-fallbacks() {
$app-vars: (
'md-sys-color':
create-system-app-vars-map(m3-token-definitions.md-sys-color-values-light()),
'md-sys-typescale':
create-system-app-vars-map(m3-token-definitions.md-sys-typescale-values()),
'md-sys-elevation':
create-system-app-vars-map(m3-token-definitions.md-sys-elevation-values()),
'md-sys-state':
create-system-app-vars-map(m3-token-definitions.md-sys-state-values()),
'md-sys-shape':
create-system-app-vars-map(m3-token-definitions.md-sys-shape-values()),
);

@return sass-utils.deep-merge-all(
_generate-tokens($app-vars, true, true),
generate-density-tokens(0)
);
}

// Emits CSS variables for Material's system level values. Uses the
// namespace "--mat-app" .
// e.g. --mat-app-surface: #E5E5E5
@mixin theme($theme, $overrides: ()) {
@include system-level-colors($theme, $overrides, mat-app);
@include system-level-typography($theme, $overrides, mat-app);
@include system-level-elevation($theme, $overrides, mat-app);
@include system-level-shape($theme, $overrides, mat-app);
@include system-level-motion($theme, $overrides, mat-app);
@include system-level-state($theme, $overrides, mat-app);
}

@mixin system-level-colors($theme, $overrides: (), $prefix: null) {
$palettes: map.get($theme, _mat-theming-internals-do-not-access, palettes);
$base-palettes: (
neutral: map.get($palettes, neutral),
Expand All @@ -135,11 +186,15 @@ $_cached-token-slots: null;
);

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

@if (not $prefix) {
// TODO: Change this after #29513 is merged.
$prefix: map.get($theme, system-variables-prefix) or $system-level-prefix;
}

$ref: (
md-ref-palette: _generate-ref-palette-tokens($primary, $tertiary, $error)
);
Expand All @@ -149,26 +204,28 @@ $_cached-token-slots: null;
m3-token-definitions.md-sys-color-values-light($ref));

@each $name, $value in $sys-colors {
--#{$system-variables-prefix}-#{$name}: #{map.get($overrides, $name) or $value};
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
}
}

@mixin system-level-typography($theme, $overrides: ()) {
@mixin system-level-typography($theme, $overrides: (), $prefix: null) {
$font-definition: map.get($theme, _mat-theming-internals-do-not-access, font-definition);
$brand: map.get($font-definition, brand);
$plain: map.get($font-definition, plain);
$bold: map.get($font-definition, bold);
$medium: map.get($font-definition, medium);
$regular: map.get($font-definition, regular);
$system-variables-prefix: map.get($theme, system-variables-prefix) or sys;
$ref: (
md-ref-typeface: _generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular)
);

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

@each $name, $value in $sys-typescale {
--#{$system-variables-prefix}-#{$name}: #{map.get($overrides, $name) or $value};
@each $name, $value in m3-token-definitions.md-sys-typescale-values($ref) {
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
}
}

Expand All @@ -180,6 +237,40 @@ $_cached-token-slots: null;
@return $result;
}

@mixin system-level-elevation($theme, $overrides: (), $prefix: $system-level-prefix) {
$shadow-color: map.get(
$theme, _mat-theming-internals-do-not-access, color-tokens, (mdc, theme), shadow);

@for $level from 0 through 24 {
$value: elevation.get-box-shadow($level, $shadow-color);
--#{$prefix}-elevation-shadow-level-#{$level}: #{$value};
}

@each $name, $value in m3-token-definitions.md-sys-elevation-values() {
$level: map.get($overrides, $name) or $value;
$value: elevation.get-box-shadow($level, $shadow-color);
--#{$prefix}-#{$name}: #{$value};
}
}

@mixin system-level-shape($theme, $overrides: (), $prefix: $system-level-prefix) {
@each $name, $value in m3-token-definitions.md-sys-shape-values() {
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
}
}

@mixin system-level-state($theme, $overrides: (), $prefix: $system-level-prefix) {
@each $name, $value in m3-token-definitions.md-sys-state-values() {
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
}
}

@mixin system-level-motion($theme, $overrides: (), $prefix: $system-level-prefix) {
@each $name, $value in m3-token-definitions.md-sys-motion-values() {
--#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
}
}

@function _get-sys-color($type, $ref, $prefix) {
$mdc-sys-color: if($type == dark,
m3-token-definitions.md-sys-color-values-dark($ref),
Expand Down
7 changes: 7 additions & 0 deletions src/material/core/tokens/_token-definition.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
@use 'sass:string';
@use 'sass:math';
@use '../m2/palette' as m2-palette;
@use '../m2/theming' as m2-theming;
Expand Down Expand Up @@ -161,6 +162,12 @@ $_system-fallbacks: null;
$color-key: map.get($pair, color);
$opacity-key: map.get($pair, opacity);
$color: map.get($tokens, $color-key);

// If the color is a CSS variable name, wrap it in a `var()` statement
@if (meta.type-of($color) == 'string' and string.index($color, '--') == 1) {
$color: var(#{$color});
}

$opacity: map.get($opacity-lookup, $opacity-key);

@if(meta.type-of($color) == 'color') {
Expand Down
Loading

0 comments on commit 8c4b151

Please sign in to comment.