@use '../style/sass-utils'; @use 'sass:list'; @use 'sass:map'; @use 'sass:string'; // Creates a CSS variable, including the fallback if provided. @function _create-var($name, $fallback: null) { @if ($fallback) { @return var($name, $fallback); } @else { @return var($name); } } // Returns a list of overrides for the given M3 get-tokens mixin and prefix. Each token has its // prefix removed since the overrides API expects its absence. The returned map includes "all" for // all override tokens, and also the subsets with keys base, color, typography, and density. @function get-overrides($tokens, $prefix) { $base: remove-token-prefixes(map.get($tokens, base), $prefix); $color: remove-token-prefixes(map.get($tokens, color), $prefix); $typography: remove-token-prefixes(map.get($tokens, typography), $prefix); $density: remove-token-prefixes(map.get($tokens, density), $prefix); $all: (); @each $map in ($base, $color, $typography, $density) { $all: map.merge($all, $map); } @return ( all: $all, base: $base, color: $color, typography: $typography, density: $density, ); } // Removes a prefix from each component token in the provided map of prefixed tokens. @function remove-token-prefixes($prefixed-tokens: (), $prefix) { $tokens: (); @each $prefixed-token, $value in $prefixed-tokens { $token: string.slice($prefixed-token, string.length($prefix) + 2); $tokens: map.set($tokens, $token, $value); } @return $tokens; } // Returns the token slot value. // Accepts an optional fallback parameter to include in the CSS variable. // If $fallback is `true`, then use the tokens map to get the fallback. @function slot($token, $fallbacks, $fallback: null) { // Fallbacks are a map of base, color, typography, and density tokens. To simplify // lookup, flatten these token groups into a single map. $fallbacks-flattened: (); @each $tokens in map.values($fallbacks) { @each $token, $value in $tokens { $fallbacks-flattened: map.set($fallbacks-flattened, $token, $value); } } @if not map.has-key($fallbacks-flattened, $token) { @error 'Token #{$token} does not exist. Configured tokens are:' + #{map.keys($fallbacks-flattened)}; } $sys-fallback: map.get($fallbacks-flattened, $token); @if (sass-utils.is-css-var-name($sys-fallback)) { $sys-fallback: _create-var($sys-fallback, $fallback); } @return _create-var(--mat-#{$token}, $sys-fallback); } // Outputs a map of tokens. @mixin create-token-values($tokens) { @include _create-token-values-internal($tokens, false); } // Outputs a map of tokens under a specific prefix in scenarios where tokens may be mixed with // other declarations (e.g. M2 themes). Used to avoid https://sass-lang.com/documentation/breaking-changes/mixed-decls/ @mixin create-token-values-mixed($tokens) { @include _create-token-values-internal($tokens, true); } @mixin _create-token-values-internal($tokens, $in-place) { @if ($tokens != null) { @if ($in-place) { & { @each $key, $value in $tokens { @if $value != null { --mat-#{$key}: #{$value}; } } } } @else { @each $key, $value in $tokens { @if $value != null { --mat-#{$key}: #{$value}; } } } } } /// Emits new token values for the given token overrides. /// Verifies that the overrides passed in are valid tokens. /// New token values are emitted under the current selector or root. @mixin batch-create-token-values($overrides: (), $namespace-configs) { @include sass-utils.current-selector-or-root() { $prefixed-name-data: (); $all-names: (); @each $config in $namespace-configs { $namespace: map.get($config, namespace); $prefix: if(map.has-key($config, prefix), map.get($config, prefix), ''); $tokens: map.get(map.get($config, tokens), all); @each $name, $value in $tokens { $prefixed-name: $prefix + $name; $all-names: list.append($all-names, $prefixed-name, $separator: comma); $prefixed-name-data: map.set($prefixed-name-data, $prefixed-name, ($namespace, $name)); } } @each $name, $value in $overrides { @if map.has-key($prefixed-name-data, $name) { $data: map.get($prefixed-name-data, $name); $namespace: list.nth($data, 1); $name: list.nth($data, 2); $prefixed-name: $namespace + '-' + $name; @include create-token-values(($prefixed-name: $value)); } @else { @error #{'Invalid token name `'}#{$name}#{'`. '}#{'Valid tokens are: '}#{$all-names}; } } } }