diff --git a/src/material/_index.scss b/src/material/_index.scss index 1f140daa4d99..a9c8a9ea0d48 100644 --- a/src/material/_index.scss +++ b/src/material/_index.scss @@ -18,7 +18,7 @@ @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, +@forward './core/tokens/m3-system' show system-level-colors, system-level-typography, system-level-elevation, system-level-shape, system-level-motion, system-level-state; diff --git a/src/material/core/tokens/_m3-system.scss b/src/material/core/tokens/_m3-system.scss new file mode 100644 index 000000000000..8db652c339cc --- /dev/null +++ b/src/material/core/tokens/_m3-system.scss @@ -0,0 +1,152 @@ +@use '../style/elevation'; +@use '../style/sass-utils'; +@use './m3-tokens'; +@use './m3/definitions'; +@use 'sass:map'; + +// Prefix used for component token fallback variables, e.g. +// `color: var(--mdc-text-button-label-text-color, var(--mat-app-primary));` +$_system-fallback-prefix: mat-app; + +// Emits CSS variables for Material's system level values. Uses the +// namespace prefix in $_system-fallback-prefix. +// e.g. --mat-app-surface: #E5E5E5 +@mixin theme($theme, $overrides: ()) { + @include system-level-colors($theme, $overrides, $_system-fallback-prefix); + @include system-level-typography($theme, $overrides, $_system-fallback-prefix); + @include system-level-elevation($theme, $overrides, $_system-fallback-prefix); + @include system-level-shape($theme, $overrides, $_system-fallback-prefix); + @include system-level-motion($theme, $overrides, $_system-fallback-prefix); + @include system-level-state($theme, $overrides, $_system-fallback-prefix); +} + +@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), + neutral-variant: map.get($palettes, neutral-variant), + secondary: map.get($palettes, secondary), + error: map.get($palettes, error), + ); + + $type: map.get($theme, _mat-theming-internals-do-not-access, theme-type); + $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) { + $prefix: map.get($theme, _mat-theming-internals-do-not-access, + color-system-variables-prefix) or $_system-level-prefix; + } + + $ref: ( + md-ref-palette: m3-tokens.generate-ref-palette-tokens($primary, $tertiary, $error) + ); + + $sys-colors: if($type == dark, + definitions.md-sys-color-values-dark($ref), + definitions.md-sys-color-values-light($ref)); + + & { + @each $name, $value in $sys-colors { + --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value}; + } + } +} + +@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); + $ref: (md-ref-typeface: + m3-tokens.generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) + ); + + @if (not $prefix) { + $prefix: map.get($theme, _mat-theming-internals-do-not-access, + typography-system-variables-prefix) or $_system-level-prefix; + } + + & { + @each $name, $value in definitions.md-sys-typescale-values($ref) { + --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value}; + } + } +} + +@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 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 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 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 definitions.md-sys-motion-values() { + --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value}; + } + } +} + +// 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, --#{$_system-fallback-prefix}-#{$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(definitions.md-sys-color-values-light()), + 'md-sys-typescale': + _create-system-app-vars-map(definitions.md-sys-typescale-values()), + 'md-sys-elevation': + _create-system-app-vars-map(definitions.md-sys-elevation-values()), + 'md-sys-state': + _create-system-app-vars-map(definitions.md-sys-state-values()), + 'md-sys-shape': + _create-system-app-vars-map(definitions.md-sys-shape-values()), + ); + + @return sass-utils.deep-merge-all( + m3-tokens.generate-tokens($app-vars, true, true), + m3-tokens.generate-density-tokens(0) + ); +} diff --git a/src/material/core/tokens/_m3-tokens.scss b/src/material/core/tokens/_m3-tokens.scss index 4c6f65990b19..cc6cbe155237 100644 --- a/src/material/core/tokens/_m3-tokens.scss +++ b/src/material/core/tokens/_m3-tokens.scss @@ -4,17 +4,12 @@ @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; -// Prefix used for component token fallback variables, e.g. -// `color: var(--mdc-text-button-label-text-color, var(--mat-app-primary));` -$_system-fallback-prefix: mat-app; - /// 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 @@ -35,7 +30,7 @@ $_system-fallback-prefix: mat-app; /// @param {Map} $tertiary The tertiary palette /// @param {Map} $error The error palette /// @return {Map} A set of `md-ref-palette` tokens -@function _generate-ref-palette-tokens($primary, $tertiary, $error) { +@function generate-ref-palette-tokens($primary, $tertiary, $error) { @return sass-utils.merge-all( (black: #000, white: #fff), _generate-palette-tokens($primary, primary), @@ -55,7 +50,7 @@ $_system-fallback-prefix: mat-app; /// @param {String} $medium The font-weight to use for medium text /// @param {String} $regular The font-weight to use for regular text /// @return {Map} A set of `md-ref-typeface` tokens -@function _generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) { +@function generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) { @return ( brand: $brand, plain: $plain, @@ -96,7 +91,7 @@ $_cached-token-slots: null; /// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens /// @param {Boolean} $include-density Whether to include density tokens /// @return {Map} A map of namespaced tokens -@function _generate-tokens($systems, $include-non-systemized: false, $include-density: false) { +@function generate-tokens($systems, $include-non-systemized: false, $include-density: false) { $systems: map.merge(( md-sys-color: (), md-sys-elevation: (), @@ -135,109 +130,6 @@ $_cached-token-slots: null; @return $result; } -// 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, --#{$_system-fallback-prefix}-#{$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 prefix in $_system-fallback-prefix. -// e.g. --mat-app-surface: #E5E5E5 -@mixin theme($theme, $overrides: ()) { - @include system-level-colors($theme, $overrides, $_system-fallback-prefix); - @include system-level-typography($theme, $overrides, $_system-fallback-prefix); - @include system-level-elevation($theme, $overrides, $_system-fallback-prefix); - @include system-level-shape($theme, $overrides, $_system-fallback-prefix); - @include system-level-motion($theme, $overrides, $_system-fallback-prefix); - @include system-level-state($theme, $overrides, $_system-fallback-prefix); -} - -@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), - neutral-variant: map.get($palettes, neutral-variant), - secondary: map.get($palettes, secondary), - error: map.get($palettes, error), - ); - - $type: map.get($theme, _mat-theming-internals-do-not-access, theme-type); - $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) { - $prefix: map.get($theme, _mat-theming-internals-do-not-access, - color-system-variables-prefix) or $_system-level-prefix; - } - - $ref: ( - md-ref-palette: _generate-ref-palette-tokens($primary, $tertiary, $error) - ); - - $sys-colors: if($type == dark, - m3-token-definitions.md-sys-color-values-dark($ref), - m3-token-definitions.md-sys-color-values-light($ref)); - - & { - @each $name, $value in $sys-colors { - --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value}; - } - } -} - -@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); - $ref: ( - md-ref-typeface: _generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) - ); - - @if (not $prefix) { - $prefix: map.get($theme, _mat-theming-internals-do-not-access, - typography-system-variables-prefix) or $_system-level-prefix; - } - - & { - @each $name, $value in m3-token-definitions.md-sys-typescale-values($ref) { - --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value}; - } - } -} - @function create-map($keys, $prefix) { $result: (); @each $key in $keys { @@ -246,46 +138,6 @@ $_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), @@ -461,12 +313,12 @@ $_cached-token-slots: null; /// @return {Map} A map of namespaced color tokens @function generate-color-tokens($type, $primary, $tertiary, $error, $system-variables-prefix) { $ref: ( - md-ref-palette: _generate-ref-palette-tokens($primary, $tertiary, $error) + md-ref-palette: generate-ref-palette-tokens($primary, $tertiary, $error) ); $sys-color: _get-sys-color($type, $ref, $system-variables-prefix); - @return _generate-tokens(map.merge($ref, ( + @return generate-tokens(map.merge($ref, ( md-sys-color: $sys-color, // Because the elevation values are always combined with color values to create the box shadow, // elevation needs to be part of the color dimension. @@ -490,10 +342,10 @@ $_cached-token-slots: null; @function generate-typography-tokens($brand, $plain, $bold, $medium, $regular, $system-variables-prefix) { $ref: ( - md-ref-typeface: _generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) + md-ref-typeface: generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) ); $sys-typeface: _get-sys-typeface($ref, $system-variables-prefix); - @return _generate-tokens(( + @return generate-tokens(( md-sys-typescale: $sys-typeface )); } @@ -510,7 +362,7 @@ $system-variables-prefix) { /// @return {Map} A map of namespaced tokens not related to color, typography, or density @function generate-base-tokens() { // TODO(mmalerba): Exclude density tokens once implemented. - @return _generate-tokens(( + @return generate-tokens(( md-sys-motion: m3-token-definitions.md-sys-motion-values(), md-sys-shape: m3-token-definitions.md-sys-shape-values(), ), $include-non-systemized: true); diff --git a/src/material/core/tokens/_token-utils.scss b/src/material/core/tokens/_token-utils.scss index a4845610970a..6015309d23fc 100644 --- a/src/material/core/tokens/_token-utils.scss +++ b/src/material/core/tokens/_token-utils.scss @@ -3,11 +3,11 @@ @use 'sass:string'; @use '../style/elevation'; @use '../style/sass-utils'; -@use './m3-tokens'; +@use 'm3-system'; $_tokens: null; $_component-prefix: null; -$_system-fallbacks: m3-tokens.create-system-fallbacks(); +$_system-fallbacks: m3-system.create-system-fallbacks(); // Sets the token prefix and map to use when creating token slots. @mixin use-tokens($prefix, $tokens) {