diff --git a/src/material/_index.scss b/src/material/_index.scss index 91e90ff18ba9..cd51f6b55a25 100644 --- a/src/material/_index.scss +++ b/src/material/_index.scss @@ -23,7 +23,6 @@ system-level-motion, system-level-state, theme, theme-overrides; // Private/Internal -@forward './core/density/private/all-density' show all-component-densities; @forward './core/theming/theming' show private-check-duplicate-theme-styles, private-legacy-get-theme, private-is-theme-object; @forward './core/style/private' show private-theme-elevation; @@ -42,9 +41,9 @@ @forward './core/style/elevation' show elevation, overridable-elevation, elevation-transition; // Theme bundles -@forward './core/theming/all-theme' show all-component-themes, all-component-bases; -@forward './core/color/all-color' show all-component-colors; -@forward './core/typography/all-typography' show all-component-typographies; +@forward './core/theming/all-theme' show + all-component-themes, all-component-bases, all-component-colors, + all-component-typographies, all-component-densities; // Component themes @forward './core/core-theme' as core-* show core-color, core-theme, core-typography, core-density, diff --git a/src/material/card/BUILD.bazel b/src/material/card/BUILD.bazel index 7bc489c3f610..474a44bbbf4a 100644 --- a/src/material/card/BUILD.bazel +++ b/src/material/card/BUILD.bazel @@ -33,10 +33,22 @@ sass_library( ], ) +sass_library( + name = "tokens_scss_lib", + srcs = [ + "_m2-tokens.scss", + "_m3-tokens.scss", + ], + deps = [ + "//src/material/core:core_scss_lib", + ], +) + sass_binary( name = "card_scss", src = "card.scss", deps = [ + ":tokens_scss_lib", "//src/material/core:core_scss_lib", ], ) diff --git a/src/material/card/_card-theme.scss b/src/material/card/_card-theme.scss index 012f2c9185e5..de2b8cfd1c37 100644 --- a/src/material/card/_card-theme.scss +++ b/src/material/card/_card-theme.scss @@ -2,29 +2,20 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/tokens/token-utils'; -@use '../core/tokens/m2/mat/card' as tokens-mat-card; -@use '../core/tokens/m2/mdc/elevated-card' as tokens-mdc-elevated-card; -@use '../core/tokens/m2/mdc/outlined-card' as tokens-mdc-outlined-card; +@use 'm2-tokens' as m2-tokens; +@use 'm3-tokens' as m3-tokens; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.define-token-values( + m3-tokens.get-unthemable-tokens($theme) + ); } @else { @include sass-utils.current-selector-or-root() { - @include token-utils.create-token-values-mixed( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-unthemable-tokens() - ); - @include token-utils.create-token-values-mixed( - tokens-mdc-outlined-card.$prefix, - tokens-mdc-outlined-card.get-unthemable-tokens() - ); - @include token-utils.create-token-values-mixed( - tokens-mat-card.$prefix, - tokens-mat-card.get-unthemable-tokens() + @include token-utils.define-token-values-mixed( + m2-tokens.get-unthemable-tokens() ); } } @@ -32,20 +23,13 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.define-token-values( + m3-tokens.get-color-tokens($theme) + ); } @else { @include sass-utils.current-selector-or-root() { - @include token-utils.create-token-values-mixed( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-color-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mdc-outlined-card.$prefix, - tokens-mdc-outlined-card.get-color-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mat-card.$prefix, - tokens-mat-card.get-color-tokens($theme) + @include token-utils.define-token-values-mixed( + m2-tokens.get-color-tokens($theme) ); } } @@ -53,20 +37,13 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.define-token-values( + m3-tokens.get-typography-tokens($theme) + ); } @else { @include sass-utils.current-selector-or-root() { - @include token-utils.create-token-values-mixed( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-typography-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mdc-outlined-card.$prefix, - tokens-mdc-outlined-card.get-typography-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mat-card.$prefix, - tokens-mat-card.get-typography-tokens($theme) + @include token-utils.define-token-values-mixed( + m2-tokens.get-typography-tokens($theme) ); } } @@ -74,20 +51,13 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, density)); + @include token-utils.define-token-values( + m3-tokens.get-density-tokens($theme) + ); } @else { @include sass-utils.current-selector-or-root() { - @include token-utils.create-token-values-mixed( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-density-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mdc-outlined-card.$prefix, - tokens-mdc-outlined-card.get-density-tokens($theme) - ); - @include token-utils.create-token-values-mixed( - tokens-mat-card.$prefix, - tokens-mat-card.get-density-tokens($theme) + @include token-utils.define-token-values-mixed( + m2-tokens.get-density-tokens($theme) ); } } @@ -97,61 +67,46 @@ @function _define-overrides() { @return ( ( - namespace: tokens-mat-card.$prefix, - tokens: tokens-mat-card.get-token-slots(), - ), - ( - namespace: tokens-mdc-elevated-card.$prefix, - tokens: tokens-mdc-elevated-card.get-token-slots(), - prefix: 'elevated-', - ), - ( - namespace: tokens-mdc-outlined-card.$prefix, - tokens: tokens-mdc-outlined-card.get-token-slots(), - prefix: 'outlined-', + namespace: (mat), + tokens: m3-tokens.get-system-fallbacks(), + overrideTransforms: $overrideTransforms, ), ); } +/// Map of override keys that should be transformed to their corresponding token name +$overrideTransforms: ( + elevated-container-shape: elevated-card-container-shape, + outlined-container-shape: outlined-card-container-shape, + outlined-outline-width: outlined-card-outline-width, + elevated-container-color: elevated-card-container-color, + elevated-container-elevation: elevated-card-container-elevation, + outlined-container-color: outlined-card-container-color, + outlined-outline-color: outlined-card-outline-color, + outlined-container-elevation: outlined-card-container-elevation +); + @mixin overrides($tokens: ()) { - @include token-utils.batch-create-token-values($tokens, _define-overrides()...); + $override-tokens: (); + @each $key, $value in $tokens { + $token: map.get($overrideTransforms, $key) or $key; + $override-tokens: map.set($override-tokens, $token, $value); + } + + @include token-utils.batch-create-token-values($override-tokens, _define-overrides()...); } @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-card') { - @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - } @else { - @include base($theme); - @if inspection.theme-has($theme, color) { - @include color($theme); - } - @if inspection.theme-has($theme, density) { - @include density($theme); - } - @if inspection.theme-has($theme, typography) { - @include typography($theme); - } + @include base($theme); + @if inspection.theme-has($theme, color) { + @include color($theme); + } + @if inspection.theme-has($theme, density) { + @include density($theme); + } + @if inspection.theme-has($theme, typography) { + @include typography($theme); } - } -} - -@mixin _theme-from-tokens($tokens) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - @if ($tokens != ()) { - @include token-utils.create-token-values( - tokens-mdc-elevated-card.$prefix, - map.get($tokens, tokens-mdc-elevated-card.$prefix) - ); - @include token-utils.create-token-values( - tokens-mdc-outlined-card.$prefix, - map.get($tokens, tokens-mdc-outlined-card.$prefix) - ); - @include token-utils.create-token-values( - tokens-mat-card.$prefix, - map.get($tokens, tokens-mat-card.$prefix) - ); } } diff --git a/src/material/card/_m2-tokens.scss b/src/material/card/_m2-tokens.scss new file mode 100644 index 000000000000..40f4c39f4dc9 --- /dev/null +++ b/src/material/card/_m2-tokens.scss @@ -0,0 +1,47 @@ +@use '../core/theming/inspection'; +@use '../core/style/elevation'; + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return ( + elevated-card-container-shape: 4px, + outlined-card-container-shape: 4px, + outlined-card-outline-width: 1px, + ); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + @return ( + card-subtitle-text-color: inspection.get-theme-color($theme, foreground, secondary-text), + elevated-card-container-color: inspection.get-theme-color($theme, background, card), + elevated-card-container-elevation: elevation.get-box-shadow(1), + outlined-card-container-color: inspection.get-theme-color($theme, background, card), + outlined-card-outline-color: rgba(inspection.get-theme-color($theme, foreground, base), 0.12), + outlined-card-container-elevation: elevation.get-box-shadow(0), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return ( + card-title-text-font: inspection.get-theme-typography($theme, headline-6, font-family), + card-title-text-line-height: inspection.get-theme-typography($theme, headline-6, line-height), + card-title-text-size: inspection.get-theme-typography($theme, headline-6, font-size), + card-title-text-tracking: inspection.get-theme-typography($theme, headline-6, letter-spacing), + card-title-text-weight: inspection.get-theme-typography($theme, headline-6, font-weight), + card-subtitle-text-font: inspection.get-theme-typography($theme, subtitle-2, font-family), + card-subtitle-text-line-height: + inspection.get-theme-typography($theme, subtitle-2, line-height), + card-subtitle-text-size: inspection.get-theme-typography($theme, subtitle-2, font-size), + card-subtitle-text-tracking: + inspection.get-theme-typography($theme, subtitle-2, letter-spacing), + card-subtitle-text-weight: inspection.get-theme-typography($theme, subtitle-2, font-weight), + ); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} diff --git a/src/material/card/_m3-tokens.scss b/src/material/card/_m3-tokens.scss new file mode 100644 index 000000000000..c9da8abdc5cb --- /dev/null +++ b/src/material/card/_m3-tokens.scss @@ -0,0 +1,63 @@ +@use 'sass:map'; +@use '../core/style/sass-utils'; +@use '../core/tokens/token-definition'; +@use '../core/tokens/m3-system'; +@use '../core/style/elevation'; + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens($theme) { + $systems: map.get($theme, _mat-theming-internals-do-not-access, system); + @return ( + elevated-card-container-shape: map.get($systems, md-sys-shape, corner-medium), + outlined-card-container-shape: map.get($systems, md-sys-shape, corner-medium), + outlined-card-outline-width: 1px, + ); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $systems: map.get($theme, _mat-theming-internals-do-not-access, system); + $tokens: ( + card-subtitle-text-color: map.get($systems, md-sys-color, on-surface), + elevated-card-container-color: map.get($systems, md-sys-color, surface-container-low), + elevated-card-container-elevation: map.get($systems, md-sys-elevation, level1), + outlined-card-container-color: map.get($systems, md-sys-color, surface), + outlined-card-outline-color: map.get($systems, md-sys-color, outline-variant), + outlined-card-container-elevation: map.get($systems, md-sys-elevation, level0), + ); + + $elevation: map.get($tokens, elevated-card-container-elevation); + + @if ($elevation != null) { + $tokens: map.set( + $tokens, elevated-card-container-elevation, elevation.get-box-shadow($elevation)); + } + + @return $tokens; +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + $systems: map.get($theme, _mat-theming-internals-do-not-access, system); + @return sass-utils.merge-all( + token-definition.generate-typography-tokens($systems, card-title-text, title-large), + token-definition.generate-typography-tokens($systems, card-subtitle-text, title-medium), + ); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with M3 system fallbacks. +// This is used to create token slots. +@function get-system-fallbacks() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(m3-system.$system-var-theme), + get-color-tokens(m3-system.$system-var-theme), + get-typography-tokens(m3-system.$system-var-theme), + get-density-tokens(m3-system.$system-var-theme) + ); +} diff --git a/src/material/card/card.scss b/src/material/card/card.scss index 21ae1ee38b42..d3dda7c1f7e1 100644 --- a/src/material/card/card.scss +++ b/src/material/card/card.scss @@ -1,7 +1,5 @@ -@use '../core/tokens/token-utils'; -@use '../core/tokens/m2/mat/card' as tokens-mat-card; -@use '../core/tokens/m2/mdc/elevated-card' as tokens-mdc-elevated-card; -@use '../core/tokens/m2/mdc/outlined-card' as tokens-mdc-outlined-card; +@use '../core/tokens/token-utils' as token; +@use 'm3-tokens'; // Size of the `mat-card-header` region custom to Angular Material. $mat-card-header-size: 40px !default; @@ -9,6 +7,8 @@ $mat-card-header-size: 40px !default; // Default padding for text content within a card. $mat-card-default-padding: 16px !default; +$_tokens: m3-tokens.get-system-fallbacks(); + .mat-mdc-card { display: flex; flex-direction: column; @@ -16,16 +16,10 @@ $mat-card-default-padding: 16px !default; position: relative; border-style: solid; border-width: 0; - - @include token-utils.use-tokens( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-token-slots() - ) { - @include token-utils.create-token-slot(background-color, container-color); - @include token-utils.create-token-slot(border-color, container-color); - @include token-utils.create-token-slot(border-radius, container-shape); - @include token-utils.create-token-slot(box-shadow, container-elevation); - } + background-color: token.slot(elevated-card-container-color, $_tokens); + border-color: token.slot(elevated-card-container-color, $_tokens); + border-radius: token.slot(elevated-card-container-shape, $_tokens); + box-shadow: token.slot(elevated-card-container-elevation, $_tokens); // Transparent card border for high-contrast mode. &::after { @@ -39,27 +33,16 @@ $mat-card-default-padding: 16px !default; display: block; pointer-events: none; box-sizing: border-box; - - @include token-utils.use-tokens( - tokens-mdc-elevated-card.$prefix, - tokens-mdc-elevated-card.get-token-slots() - ) { - @include token-utils.create-token-slot(border-radius, container-shape); - } + border-radius: token.slot(elevated-card-container-shape, $_tokens); } } .mat-mdc-card-outlined { - @include token-utils.use-tokens( - tokens-mdc-outlined-card.$prefix, - tokens-mdc-outlined-card.get-token-slots() - ) { - @include token-utils.create-token-slot(background-color, container-color); - @include token-utils.create-token-slot(border-radius, container-shape); - @include token-utils.create-token-slot(border-width, outline-width); - @include token-utils.create-token-slot(border-color, outline-color); - @include token-utils.create-token-slot(box-shadow, container-elevation); - } + background-color: token.slot(outlined-card-container-color, $_tokens); + border-radius: token.slot(outlined-card-container-shape, $_tokens); + border-width: token.slot(outlined-card-outline-width, $_tokens); + border-color: token.slot(outlined-card-outline-color, $_tokens); + box-shadow: token.slot(outlined-card-container-elevation, $_tokens); // Outlined card already displays border in high-contrast mode. // Overwriting styles set above to remove a duplicate border. @@ -101,23 +84,21 @@ $mat-card-default-padding: 16px !default; } // Add slots for custom Angular Material card tokens. -@include token-utils.use-tokens(tokens-mat-card.$prefix, tokens-mat-card.get-token-slots()) { - .mat-mdc-card-title { - @include token-utils.create-token-slot(font-family, title-text-font); - @include token-utils.create-token-slot(line-height, title-text-line-height); - @include token-utils.create-token-slot(font-size, title-text-size); - @include token-utils.create-token-slot(letter-spacing, title-text-tracking); - @include token-utils.create-token-slot(font-weight, title-text-weight); - } +.mat-mdc-card-title { + font-family: token.slot(card-title-text-font, $_tokens); + line-height: token.slot(card-title-text-line-height, $_tokens); + font-size: token.slot(card-title-text-size, $_tokens); + letter-spacing: token.slot(card-title-text-tracking, $_tokens); + font-weight: token.slot(card-title-text-weight, $_tokens); +} - .mat-mdc-card-subtitle { - @include token-utils.create-token-slot(color, subtitle-text-color); - @include token-utils.create-token-slot(font-family, subtitle-text-font); - @include token-utils.create-token-slot(line-height, subtitle-text-line-height); - @include token-utils.create-token-slot(font-size, subtitle-text-size); - @include token-utils.create-token-slot(letter-spacing, subtitle-text-tracking); - @include token-utils.create-token-slot(font-weight, subtitle-text-weight); - } +.mat-mdc-card-subtitle { + color: token.slot(card-subtitle-text-color, $_tokens); + font-family: token.slot(card-subtitle-text-font, $_tokens); + line-height: token.slot(card-subtitle-text-line-height, $_tokens); + font-size: token.slot(card-subtitle-text-size, $_tokens); + letter-spacing: token.slot(card-subtitle-text-tracking, $_tokens); + font-weight: token.slot(card-subtitle-text-weight, $_tokens); } // Title text and subtitles text within a card. MDC doesn't have pre-made title sections for cards. diff --git a/src/material/core/theming/_all-theme.scss b/src/material/core/theming/_all-theme.scss index 66823927319b..37d17818470e 100644 --- a/src/material/core/theming/_all-theme.scss +++ b/src/material/core/theming/_all-theme.scss @@ -125,6 +125,129 @@ @include timepicker-theme.base($theme); } +@mixin all-component-colors($theme) { + @include core-theme.color($theme); + @include card-theme.color($theme); + @include progress-bar-theme.color($theme); + @include tooltip-theme.color($theme); + @include form-field-theme.color($theme); + @include input-theme.color($theme); + @include select-theme.color($theme); + @include autocomplete-theme.color($theme); + @include dialog-theme.color($theme); + @include chips-theme.color($theme); + @include slide-toggle-theme.color($theme); + @include radio-theme.color($theme); + @include slider-theme.color($theme); + @include menu-theme.color($theme); + @include list-theme.color($theme); + @include paginator-theme.color($theme); + @include tabs-theme.color($theme); + @include checkbox-theme.color($theme); + @include button-theme.color($theme); + @include icon-button-theme.color($theme); + @include fab-theme.color($theme); + @include snack-bar-theme.color($theme); + @include table-theme.color($theme); + @include progress-spinner-theme.color($theme); + @include badge-theme.color($theme); + @include bottom-sheet-theme.color($theme); + @include button-toggle-theme.color($theme); + @include datepicker-theme.color($theme); + @include divider-theme.color($theme); + @include expansion-theme.color($theme); + @include grid-list-theme.color($theme); + @include icon-theme.color($theme); + @include sidenav-theme.color($theme); + @include stepper-theme.color($theme); + @include sort-theme.color($theme); + @include toolbar-theme.color($theme); + @include tree-theme.color($theme); + @include timepicker-theme.color($theme); +} + +@mixin all-component-typographies($theme) { + @include core-theme.typography($theme); + @include card-theme.typography($theme); + @include progress-bar-theme.typography($theme); + @include tooltip-theme.typography($theme); + @include form-field-theme.typography($theme); + @include input-theme.typography($theme); + @include select-theme.typography($theme); + @include autocomplete-theme.typography($theme); + @include dialog-theme.typography($theme); + @include chips-theme.typography($theme); + @include slide-toggle-theme.typography($theme); + @include radio-theme.typography($theme); + @include slider-theme.typography($theme); + @include menu-theme.typography($theme); + @include list-theme.typography($theme); + @include paginator-theme.typography($theme); + @include tabs-theme.typography($theme); + @include checkbox-theme.typography($theme); + @include button-theme.typography($theme); + @include icon-button-theme.typography($theme); + @include fab-theme.typography($theme); + @include snack-bar-theme.typography($theme); + @include table-theme.typography($theme); + @include progress-spinner-theme.typography($theme); + @include badge-theme.typography($theme); + @include bottom-sheet-theme.typography($theme); + @include button-toggle-theme.typography($theme); + @include datepicker-theme.typography($theme); + @include divider-theme.typography($theme); + @include expansion-theme.typography($theme); + @include grid-list-theme.typography($theme); + @include icon-theme.typography($theme); + @include sidenav-theme.typography($theme); + @include stepper-theme.typography($theme); + @include sort-theme.typography($theme); + @include toolbar-theme.typography($theme); + @include tree-theme.typography($theme); + @include timepicker-theme.typography($theme); +} + +@mixin all-component-densities($theme) { + @include core-theme.density($theme); + @include card-theme.density($theme); + @include progress-bar-theme.density($theme); + @include tooltip-theme.density($theme); + @include form-field-theme.density($theme); + @include input-theme.density($theme); + @include select-theme.density($theme); + @include autocomplete-theme.density($theme); + @include dialog-theme.density($theme); + @include chips-theme.density($theme); + @include slide-toggle-theme.density($theme); + @include radio-theme.density($theme); + @include slider-theme.density($theme); + @include menu-theme.density($theme); + @include list-theme.density($theme); + @include paginator-theme.density($theme); + @include tabs-theme.density($theme); + @include checkbox-theme.density($theme); + @include button-theme.density($theme); + @include icon-button-theme.density($theme); + @include fab-theme.density($theme); + @include snack-bar-theme.density($theme); + @include table-theme.density($theme); + @include progress-spinner-theme.density($theme); + @include badge-theme.density($theme); + @include bottom-sheet-theme.density($theme); + @include button-toggle-theme.density($theme); + @include datepicker-theme.density($theme); + @include divider-theme.density($theme); + @include expansion-theme.density($theme); + @include grid-list-theme.density($theme); + @include icon-theme.density($theme); + @include sidenav-theme.density($theme); + @include stepper-theme.density($theme); + @include sort-theme.density($theme); + @include toolbar-theme.density($theme); + @include tree-theme.density($theme); + @include timepicker-theme.density($theme); +} + // @deprecated Use `all-component-themes`. @mixin angular-material-theme($theme) { @include all-component-themes($theme); diff --git a/src/material/core/theming/_definition.scss b/src/material/core/theming/_definition.scss index 511786869338..4174b8e0258c 100644 --- a/src/material/core/theming/_definition.scss +++ b/src/material/core/theming/_definition.scss @@ -34,7 +34,10 @@ $theme-version: 1; define-colors(map.get($config, color) or ()), define-typography(map.get($config, typography) or ()), define-density(map.get($config, density) or ()), - ($internals: (base-tokens: m3-tokens.generate-base-tokens())), + ($internals: ( + base-tokens: m3-tokens.generate-base-tokens(), + system: m3-tokens.create-base-system(), + )), ); } @@ -53,6 +56,9 @@ $theme-version: 1; $system-variables-prefix: map.get($config, system-variables-prefix) or $system-level-prefix; sass-utils.$use-system-color-variables: map.get($config, use-system-variables) or false; + $color-system: m3-tokens.create-color-system( + $type, $primary, $tertiary, map.get($primary, error), $system-variables-prefix); + @return ( $internals: ( theme-version: $theme-version, @@ -66,8 +72,8 @@ $theme-version: 1; error: map.get($primary, error), ), color-system-variables-prefix: $system-variables-prefix, - color-tokens: m3-tokens.generate-color-tokens( - $type, $primary, $tertiary, map.get($primary, error), $system-variables-prefix) + color-tokens: m3-tokens.generate-tokens($color-system), + system: $color-system, ) ); } @@ -89,6 +95,9 @@ $theme-version: 1; $system-variables-prefix: map.get($config, system-variables-prefix) or $system-level-prefix; sass-utils.$use-system-typography-variables: map.get($config, use-system-variables) or false; + $typography-system: m3-tokens.create-typography-system( + $brand, $plain, $bold, $medium, $regular, $system-variables-prefix); + @return ( $internals: ( theme-version: $theme-version, @@ -100,8 +109,8 @@ $theme-version: 1; regular: $regular, ), typography-system-variables-prefix: $system-variables-prefix, - typography-tokens: m3-tokens.generate-typography-tokens( - $brand, $plain, $bold, $medium, $regular, $system-variables-prefix) + typography-tokens: m3-tokens.generate-tokens($typography-system), + system: $typography-system, ) ); } diff --git a/src/material/core/theming/tests/theming-definition-api.spec.ts b/src/material/core/theming/tests/theming-definition-api.spec.ts index 12d95f842ddd..30f38a047815 100644 --- a/src/material/core/theming/tests/theming-definition-api.spec.ts +++ b/src/material/core/theming/tests/theming-definition-api.spec.ts @@ -74,6 +74,7 @@ describe('theming definition api', () => { 'palettes', 'color-system-variables-prefix', 'color-tokens', + 'system', 'font-definition', 'typography-system-variables-prefix', 'typography-tokens', @@ -261,6 +262,7 @@ describe('theming definition api', () => { 'palettes', 'color-system-variables-prefix', 'color-tokens', + 'system', ]); }); }); @@ -280,6 +282,7 @@ describe('theming definition api', () => { 'font-definition', 'typography-system-variables-prefix', 'typography-tokens', + 'system', ]); }); }); diff --git a/src/material/core/theming/tests/theming-inspection-api.spec.ts b/src/material/core/theming/tests/theming-inspection-api.spec.ts index 0da3e6853a0c..99d8e29c8221 100644 --- a/src/material/core/theming/tests/theming-inspection-api.spec.ts +++ b/src/material/core/theming/tests/theming-inspection-api.spec.ts @@ -453,14 +453,5 @@ describe('theming inspection api', () => { `), ).toThrowError(/Density information is not available on this theme/); }); - - it('should not emit styles for removed theme dimensions', () => { - const css = transpile(` - $theme: mat.theme-remove(mat.define-theme(), base, color, typography, density); - div { - @include mat.all-component-themes($theme); - }`); - expect(css.trim()).toBe(''); - }); }); }); diff --git a/src/material/core/tokens/_m3-system.scss b/src/material/core/tokens/_m3-system.scss index 606bb5d70fbf..b4877f842efb 100644 --- a/src/material/core/tokens/_m3-system.scss +++ b/src/material/core/tokens/_m3-system.scss @@ -106,27 +106,14 @@ } @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 definition.$system-level-prefix; } - $ref: ( - md-ref-palette: m3-tokens.generate-ref-palette-tokens($primary, $tertiary, $error) - ); + $ref: map.get($theme, _mat-theming-internals-do-not-access, system); $sys-colors: _generate-sys-colors($ref, $type); @@ -231,33 +218,39 @@ @return $new-map; } +$system-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()), + // Add a subset of palette-specific colors used by components instead of system values + 'md-ref-palette': + _create-system-app-vars-map( + ( + neutral10: '', // Form field native select option text color + neutral-variant20: '', // Sidenav scrim (container background shadow when opened), + ) + ), +); + +$system-var-theme: ( + _mat-theming-internals-do-not-access: ( + system: $system-vars + ) +); + // 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()), - // Add a subset of palette-specific colors used by components instead of system values - 'md-ref-palette': - _create-system-app-vars-map( - ( - neutral10: '', // Form field native select option text color - neutral-variant20: '', // Sidenav scrim (container background shadow when opened), - ) - ), - ); - @return sass-utils.deep-merge-all( - m3-tokens.generate-tokens($app-vars, true, true), + m3-tokens.generate-tokens($system-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 7dcae56356fb..b6582188847b 100644 --- a/src/material/core/tokens/_m3-tokens.scss +++ b/src/material/core/tokens/_m3-tokens.scss @@ -83,6 +83,17 @@ $_cached-token-slots: null; @return $_cached-token-slots; } +@function define-systems($config) { + @return ( + md-sys-color: (), + md-sys-elevation: (), + md-sys-motion: (), + md-sys-shape: (), + md-sys-state: (), + md-sys-typescale: () + ); +} + /// Generates a set of namespaced tokens for all components. /// @param {Map} $systems The MDC system tokens /// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens @@ -111,6 +122,7 @@ $_cached-token-slots: null; (mat, theme): map.get($systems, md-sys-color), (mat, typography): map.get($systems, md-sys-typescale), ), + $systems, m3.get-m3-tokens($systems, $exclude-hardcoded, $token-slots), ); @@ -301,21 +313,14 @@ $_cached-token-slots: null; @return m3-token-definitions.md-sys-typescale-values($ref); } -/// Generates a set of namespaced color tokens for all components. -/// @param {String} $type The type of theme system (light or dark) -/// @param {Map} $primary The primary palette -/// @param {Map} $tertiary The tertiary palette -/// @param {Map} $error The error palette -/// @param {String} $system-variables-prefix The prefix of system tokens -/// @return {Map} A map of namespaced color tokens -@function generate-color-tokens($type, $primary, $tertiary, $error, $system-variables-prefix) { +@function create-color-system($type, $primary, $tertiary, $error, $system-variables-prefix) { $ref: ( 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 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. @@ -325,7 +330,30 @@ $_cached-token-slots: null; // TODO(mmalerba): If at some point we remove the need for these combined values, we can move // state to the base dimension. md-sys-state: m3-token-definitions.md-sys-state-values(), - ))); + )); +} + +/// Generates a set of namespaced color tokens for all components. +/// @param {String} $type The type of theme system (light or dark) +/// @param {Map} $primary The primary palette +/// @param {Map} $tertiary The tertiary palette +/// @param {Map} $error The error palette +/// @param {String} $system-variables-prefix The prefix of system tokens +/// @return {Map} A map of namespaced color tokens +@function generate-color-tokens($type, $primary, $tertiary, $error, $system-variables-prefix) { + $color-system: create-color-system($type, $primary, $tertiary, $error, $system-variables-prefix); + @return generate-tokens($color-system); +} + +@function create-typography-system( + $brand, $plain, $bold, $medium, $regular, $system-variables-prefix) { + $ref: ( + md-ref-typeface: generate-ref-typeface-tokens($brand, $plain, $bold, $medium, $regular) + ); + $sys-typeface: _get-sys-typeface($ref, $system-variables-prefix); + @return ( + md-sys-typescale: $sys-typeface + ); } /// Generates a set of namespaced color tokens for all components. @@ -338,13 +366,9 @@ $_cached-token-slots: null; /// @return {Map} A map of namespaced typography tokens @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) - ); - $sys-typeface: _get-sys-typeface($ref, $system-variables-prefix); - @return generate-tokens(( - md-sys-typescale: $sys-typeface - )); + $typography-system: create-typography-system( + $brand, $plain, $bold, $medium, $regular, $system-variables-prefix); + @return generate-tokens($typography-system); } /// Generates a set of namespaced density tokens for all components. @@ -354,13 +378,18 @@ $system-variables-prefix) { @return density.get-tokens-for-scale($scale); } +@function create-base-system() { + @return ( + md-sys-motion: m3-token-definitions.md-sys-motion-values(), + md-sys-shape: m3-token-definitions.md-sys-shape-values(), + ); +} + /// Generates a set of namespaced tokens not related to color, typography, or density for all /// components. /// @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(( - md-sys-motion: m3-token-definitions.md-sys-motion-values(), - md-sys-shape: m3-token-definitions.md-sys-shape-values(), - ), $include-non-systemized: true); + $base-system: create-base-system(); + @return generate-tokens($base-system, $include-non-systemized: true); } diff --git a/src/material/core/tokens/_token-utils.scss b/src/material/core/tokens/_token-utils.scss index ebe4d0b22eaf..f5670594937a 100644 --- a/src/material/core/tokens/_token-utils.scss +++ b/src/material/core/tokens/_token-utils.scss @@ -1,5 +1,6 @@ @use '../style/elevation'; @use '../style/sass-utils'; +@use '../theming/validation'; @use './m3-system'; @use 'sass:list'; @use 'sass:map'; @@ -33,6 +34,7 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); $string-prefix: if($string-prefix == '', $part, '#{$string-prefix}-#{$part}'); } + @return string.unquote('--#{$string-prefix}-#{$token}'); } @@ -46,9 +48,9 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); } // Gets the value of the token given the current global context state. -@function _get-token-value($token, $fallback) { +@function _get-token-value($token, $fallback, $fallbacks: null) { $var-name: _create-var-name($_component-prefix, $token); - $fallback: _get-token-fallback($token, $fallback); + $fallback: _get-token-fallback($token, $fallback, $component-fallbacks: $fallbacks); @return _create-var($var-name, $fallback); } @@ -77,6 +79,22 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); } } +// Emits a slot for the given token, provided that it has a non-null value in the token map passed +// to `use-tokens`. +// Accepts an optional fallback parameter to include in the CSS variable. +// If $fallback is `true`, then use the tokens map to get the fallback. +// TODO: Remove the use case where we accept "true" and handle any failing client screenshots +@function slot($token, $tokens) { + $_component-prefix: ('mat') !global; + $_tokens: $tokens !global; + + $_assert: _assert-use-tokens($token); + @return _get-token-value($token, $fallback: null, $fallbacks: $tokens); + + $_component-prefix: null !global; + $_tokens: null !global; +} + // Returns the name of a token including the current prefix. Intended to be used in calculations // involving tokens. `create-token-slot` should be used when outputting tokens. @function get-token-variable-name($token) { @@ -96,7 +114,7 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); // Gets the token's fallback value. Prefers adding a system-level fallback if one exists, otherwise // use the provided fallback. -@function _get-token-fallback($token, $fallback: null) { +@function _get-token-fallback($token, $fallback: null, $component-fallbacks: null) { // If the $fallback is `true`, this is the component's signal to use the current token map value @if ($fallback == true) { $fallback: map.get($_tokens, $token); @@ -105,6 +123,9 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); // Check whether there's a system-level fallback. If not, return the optional // provided fallback (otherwise null). $sys-fallback: map.get($_system-fallbacks, $_component-prefix, $token); + @if ($component-fallbacks) { + $sys-fallback: map.get($component-fallbacks, $token); + } @if (not $sys-fallback) { @return $fallback; } @@ -116,11 +137,22 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); @return $sys-fallback; } +// Outputs a map of tokens. +@mixin define-token-values($tokens) { + @include _create-token-values-internal((mat), $tokens, false); +} + // Outputs a map of tokens under a specific prefix. @mixin create-token-values($prefix, $tokens) { @include _create-token-values-internal($prefix, $tokens, false); } +// Outputs a map of tokens 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 define-token-values-mixed($tokens) { + @include _create-token-values-internal((mat), $tokens, true); +} + // 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($prefix, $tokens) { @@ -149,6 +181,11 @@ $_system-fallbacks: m3-system.create-system-fallbacks(); @mixin define-css-var($prefix, $key, $value) { $name: _create-var-name($prefix, $key); + + @include validation.selector-defined( + 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' + ); + #{$name}: #{$value}; } diff --git a/src/material/core/tokens/m2/_index.scss b/src/material/core/tokens/m2/_index.scss index ada2482ff850..7680633a99ca 100644 --- a/src/material/core/tokens/m2/_index.scss +++ b/src/material/core/tokens/m2/_index.scss @@ -10,7 +10,6 @@ @use './mat/outlined-button' as tokens-mat-outlined-button; @use './mat/dialog' as tokens-mat-dialog; @use './mat/bottom-sheet' as tokens-mat-bottom-sheet; -@use './mat/card' as tokens-mat-card; @use './mat/chip' as tokens-mat-chip; @use './mat/datepicker' as tokens-mat-datepicker; @use './mat/divider' as tokens-mat-divider; @@ -54,7 +53,6 @@ @use './mdc/chip' as tokens-mdc-chip; @use './mdc/circular-progress' as tokens-mdc-circular-progress; @use './mdc/dialog' as tokens-mdc-dialog; -@use './mdc/elevated-card' as tokens-mdc-elevated-card; @use './mdc/extended-fab' as tokens-mdc-extended-fab; @use './mdc/fab' as tokens-mdc-fab; @use './mdc/fab-small' as tokens-mdc-fab-small; @@ -62,7 +60,6 @@ @use './mdc/icon-button' as tokens-mdc-icon-button; @use './mdc/linear-progress' as tokens-mdc-linear-progress; @use './mdc/list' as tokens-mdc-list; -@use './mdc/outlined-card' as tokens-mdc-outlined-card; @use './mdc/outlined-text-field' as tokens-mdc-outlined-text-field; @use './mdc/plain-tooltip' as tokens-mdc-plain-tooltip; @use './mdc/radio' as tokens-mdc-radio; @@ -81,6 +78,11 @@ /// @return {Map} The token map by calling the token getter for the given system in the given module /// with the given Angular Material theme. Token names are not fully-qualified. @function _get-tokens-for-module-and-system($theme, $module, $system) { + @if (meta.function-exists(tokens, $module: $module)) { + $token-slots: meta.call(meta.get-function(tokens, $module: $module), $theme); + @return map.get($token-slots, $system); + } + @if $system == unthemable { @return meta.call(meta.get-function(get-#{$system}-tokens, $module: $module)); } @@ -120,7 +122,6 @@ _get-tokens-for-module($theme, tokens-mat-badge), _get-tokens-for-module($theme, tokens-mat-bottom-sheet), _get-tokens-for-module($theme, tokens-mat-button-toggle), - _get-tokens-for-module($theme, tokens-mat-card), _get-tokens-for-module($theme, tokens-mat-chip), _get-tokens-for-module($theme, tokens-mat-datepicker), _get-tokens-for-module($theme, tokens-mat-dialog), @@ -164,7 +165,6 @@ _get-tokens-for-module($theme, tokens-mdc-chip), _get-tokens-for-module($theme, tokens-mdc-circular-progress), _get-tokens-for-module($theme, tokens-mdc-dialog), - _get-tokens-for-module($theme, tokens-mdc-elevated-card), _get-tokens-for-module($theme, tokens-mdc-extended-fab), _get-tokens-for-module($theme, tokens-mdc-fab), _get-tokens-for-module($theme, tokens-mdc-fab-small), @@ -174,7 +174,6 @@ _get-tokens-for-module($theme, tokens-mdc-linear-progress), _get-tokens-for-module($theme, tokens-mdc-list), _get-tokens-for-module($theme, tokens-mdc-outlined-button), - _get-tokens-for-module($theme, tokens-mdc-outlined-card), _get-tokens-for-module($theme, tokens-mdc-outlined-text-field), _get-tokens-for-module($theme, tokens-mdc-plain-tooltip), _get-tokens-for-module($theme, tokens-mdc-protected-button), diff --git a/src/material/core/tokens/m2/mat/_card.scss b/src/material/core/tokens/m2/mat/_card.scss deleted file mode 100644 index 20ea73bdc779..000000000000 --- a/src/material/core/tokens/m2/mat/_card.scss +++ /dev/null @@ -1,62 +0,0 @@ -@use '../../token-definition'; -@use '../../../theming/inspection'; -@use '../../../style/sass-utils'; - -// The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mat, card); - -// Tokens that can't be configured through Angular Material's current theming API, -// but may be in a future version of the theming API. -@function get-unthemable-tokens() { - @return (); -} - -// Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme) { - @return ( - // Text color of the card's subtitle. - subtitle-text-color: inspection.get-theme-color($theme, foreground, secondary-text), - ); -} - -// Tokens that can be configured through Angular Material's typography theming API. -@function get-typography-tokens($theme) { - @return ( - // Font family of the card's title. - title-text-font: inspection.get-theme-typography($theme, headline-6, font-family), - // Line height of the card's title. - title-text-line-height: inspection.get-theme-typography($theme, headline-6, line-height), - // Font size of the card's title. - title-text-size: inspection.get-theme-typography($theme, headline-6, font-size), - // Letter spacing of the card's title. - title-text-tracking: inspection.get-theme-typography($theme, headline-6, letter-spacing), - // Font weight of the card's title. - title-text-weight: inspection.get-theme-typography($theme, headline-6, font-weight), - // Font family of the card's subtitle. - subtitle-text-font: inspection.get-theme-typography($theme, subtitle-2, font-family), - // Line height of the card's subtitle. - subtitle-text-line-height: inspection.get-theme-typography($theme, subtitle-2, line-height), - // Font size of the card's subtitle. - subtitle-text-size: inspection.get-theme-typography($theme, subtitle-2, font-size), - // Letter spacing of the card's subtitle. - subtitle-text-tracking: inspection.get-theme-typography($theme, subtitle-2, letter-spacing), - // Font weight of the card's subtitle. - subtitle-text-weight: inspection.get-theme-typography($theme, subtitle-2, font-weight), - ); -} - -// Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - @return (); -} - -// Combines the tokens generated by the above functions into a single map with placeholder values. -// This is used to create token slots. -@function get-token-slots() { - @return sass-utils.deep-merge-all( - get-unthemable-tokens(), - get-color-tokens(token-definition.$placeholder-color-config), - get-typography-tokens(token-definition.$placeholder-typography-config), - get-density-tokens(token-definition.$placeholder-density-config) - ); -} diff --git a/src/material/core/tokens/m2/mdc/_elevated-card.scss b/src/material/core/tokens/m2/mdc/_elevated-card.scss deleted file mode 100644 index b0e56a52ac5c..000000000000 --- a/src/material/core/tokens/m2/mdc/_elevated-card.scss +++ /dev/null @@ -1,77 +0,0 @@ -@use '../../../theming/inspection'; -@use '../../../style/elevation'; -@use '../../../style/sass-utils'; -@use '../../token-definition'; - -// The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mat, elevated-card); - -// Tokens that can't be configured through Angular Material's current theming API, -// but may be in a future version of the theming API. -// -// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`. -// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in -// our CSS. -@function get-unthemable-tokens() { - @return ( - // The border-radius of the card. - container-shape: 4px, - // ============================================================================================= - // = TOKENS NOT USED IN ANGULAR MATERIAL = - // ============================================================================================= - // Angular Material's card is not an interactive element, and therefore does not support states. - disabled-container-color: null, - disabled-container-elevation: null, - disabled-container-opacity: null, - dragged-container-elevation: null, - dragged-state-layer-color: null, - dragged-state-layer-opacity: null, - focus-container-elevation: null, - focus-state-layer-color:null, - focus-state-layer-opacity: null, - hover-container-elevation: null, - hover-state-layer-color: null, - hover-state-layer-opacity: null, - pressed-container-elevation: null, - pressed-state-layer-color: null, - pressed-state-layer-opacity: null, - container-shadow-color: null, - // Angular Material does not currently support surface tint. - container-surface-tint-layer-color: null, - // MDC does not seem to use these tokens. - icon-color: null, - icon-size: null, - ); -} - -// Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme) { - $elevation: inspection.get-theme-color($theme, foreground, elevation); - - @return ( - // The background color of the card. - container-color: inspection.get-theme-color($theme, background, card), - container-elevation: elevation.get-box-shadow(1), - ); -} - -// Tokens that can be configured through Angular Material's typography theming API. -@function get-typography-tokens($theme) { - @return (); -} - -// Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - @return (); -} - -// Combines the tokens generated by the above functions into a single map with placeholder values. -// This is used to create token slots. -@function get-token-slots() { - @return sass-utils.deep-merge-all( - get-unthemable-tokens(), - get-color-tokens(token-definition.$placeholder-color-config), - get-typography-tokens(token-definition.$placeholder-typography-config), - get-density-tokens(token-definition.$placeholder-density-config) - ); -} diff --git a/src/material/core/tokens/m2/mdc/_outlined-card.scss b/src/material/core/tokens/m2/mdc/_outlined-card.scss deleted file mode 100644 index 3caa5b5b5b32..000000000000 --- a/src/material/core/tokens/m2/mdc/_outlined-card.scss +++ /dev/null @@ -1,85 +0,0 @@ -@use '../../../style/elevation'; -@use '../../../theming/inspection'; -@use '../../../style/sass-utils'; -@use '../../token-definition'; - -// The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mat, outlined-card); - -// Tokens that can't be configured through Angular Material's current theming API, -// but may be in a future version of the theming API. -// -// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`. -// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in -// our CSS. -@function get-unthemable-tokens() { - @return ( - // The border-radius of the card. - container-shape: 4px, - // The thickness of the card's border. - outline-width: 1px, - // ============================================================================================= - // = TOKENS NOT USED IN ANGULAR MATERIAL = - // ============================================================================================= - // Angular Material's card is not an interactive element, and therefore does not support states. - disabled-container-elevation: null, - disabled-outline-color: null, - disabled-outline-opacity: null, - dragged-container-elevation: null, - dragged-outline-color: null, - dragged-state-layer-color: null, - dragged-state-layer-opacity: null, - focus-container-elevation: null, - focus-outline-color: null, - focus-state-layer-color: null, - focus-state-layer-opacity: null, - hover-container-elevation: null, - hover-outline-color: null, - hover-state-layer-color: null, - hover-state-layer-opacity: null, - pressed-container-elevation: null, - pressed-outline-color: null, - pressed-state-layer-color: null, - pressed-state-layer-opacity: null, - container-shadow-color: null, - // Angular Material does not currently support surface tint. - container-surface-tint-layer-color: null, - // MDC does not seem to use these tokens. - icon-color: null, - icon-size: null, - ); -} - -// Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme) { - $elevation: inspection.get-theme-color($theme, foreground, elevation); - - @return ( - // The background color of the card. - container-color: inspection.get-theme-color($theme, background, card), - // The border color of the card. - outline-color: rgba(inspection.get-theme-color($theme, foreground, base), 0.12), - container-elevation: elevation.get-box-shadow(0), - ); -} - -// Tokens that can be configured through Angular Material's typography theming API. -@function get-typography-tokens($theme) { - @return (); -} - -// Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - @return (); -} - -// Combines the tokens generated by the above functions into a single map with placeholder values. -// This is used to create token slots. -@function get-token-slots() { - @return sass-utils.deep-merge-all( - get-unthemable-tokens(), - get-color-tokens(token-definition.$placeholder-color-config), - get-typography-tokens(token-definition.$placeholder-typography-config), - get-density-tokens(token-definition.$placeholder-density-config) - ); -} diff --git a/src/material/core/tokens/m3/_index.scss b/src/material/core/tokens/m3/_index.scss index b9a7a6f130bc..5db6433d6b85 100644 --- a/src/material/core/tokens/m3/_index.scss +++ b/src/material/core/tokens/m3/_index.scss @@ -9,7 +9,6 @@ @use './mat/outlined-button' as tokens-mat-outlined-button; @use './mat/dialog' as tokens-mat-dialog; @use './mat/bottom-sheet' as tokens-mat-bottom-sheet; -@use './mat/card' as tokens-mat-card; @use './mat/chip' as tokens-mat-chip; @use './mat/datepicker' as tokens-mat-datepicker; @use './mat/divider' as tokens-mat-divider; @@ -52,7 +51,6 @@ @use './mdc/chip' as tokens-mdc-chip; @use './mdc/circular-progress' as tokens-mdc-circular-progress; @use './mdc/dialog' as tokens-mdc-dialog; -@use './mdc/elevated-card' as tokens-mdc-elevated-card; @use './mdc/extended-fab' as tokens-mdc-extended-fab; @use './mdc/fab' as tokens-mdc-fab; @use './mdc/fab-small' as tokens-mdc-fab-small; @@ -60,7 +58,6 @@ @use './mdc/icon-button' as tokens-mdc-icon-button; @use './mdc/linear-progress' as tokens-mdc-linear-progress; @use './mdc/list' as tokens-mdc-list; -@use './mdc/outlined-card' as tokens-mdc-outlined-card; @use './mdc/outlined-text-field' as tokens-mdc-outlined-text-field; @use './mdc/plain-tooltip' as tokens-mdc-plain-tooltip; @use './mdc/radio' as tokens-mdc-radio; @@ -77,7 +74,6 @@ $_module-names: ( tokens-mat-badge, tokens-mat-bottom-sheet, tokens-mat-button-toggle, - tokens-mat-card, tokens-mat-chip, tokens-mat-datepicker, tokens-mat-dialog, @@ -126,7 +122,6 @@ $_module-names: ( tokens-mdc-chip, tokens-mdc-circular-progress, tokens-mdc-dialog, - tokens-mdc-elevated-card, tokens-mdc-extended-fab, tokens-mdc-fab, tokens-mdc-fab-small, @@ -134,7 +129,6 @@ $_module-names: ( tokens-mdc-icon-button, tokens-mdc-linear-progress, tokens-mdc-list, - tokens-mdc-outlined-card, tokens-mdc-outlined-text-field, tokens-mdc-plain-tooltip, tokens-mdc-radio, diff --git a/src/material/core/tokens/m3/definitions/_index.scss b/src/material/core/tokens/m3/definitions/_index.scss index 60eb8adf886f..f8a961623a0f 100644 --- a/src/material/core/tokens/m3/definitions/_index.scss +++ b/src/material/core/tokens/m3/definitions/_index.scss @@ -3,7 +3,6 @@ @forward './md-comp-data-table' as md-comp-data-table-*; @forward './md-comp-dialog' as md-comp-dialog-*; @forward './md-comp-elevated-button' as md-comp-elevated-button-*; -@forward './md-comp-elevated-card' as md-comp-elevated-card-*; @forward './md-comp-extended-fab-primary' as md-comp-extended-fab-primary-*; @forward './md-comp-extended-fab-secondary' as md-comp-extended-fab-secondary-*; @forward './md-comp-extended-fab-tertiary' as md-comp-extended-fab-tertiary-*; @@ -15,7 +14,6 @@ @forward './md-comp-fab-tertiary' as md-comp-fab-tertiary-*; @forward './md-comp-filled-button' as md-comp-filled-button-*; @forward './md-comp-filled-tonal-button' as md-comp-filled-tonal-button-*; -@forward './md-comp-filled-card' as md-comp-filled-card-*; @forward './md-comp-filled-icon-button' as md-comp-filled-icon-button-*; @forward './md-comp-filled-text-field' as md-comp-filled-text-field-*; @forward './md-comp-icon-button' as md-comp-icon-button-*; diff --git a/src/material/core/tokens/m3/definitions/_md-comp-elevated-card.scss b/src/material/core/tokens/m3/definitions/_md-comp-elevated-card.scss deleted file mode 100644 index d5102433966c..000000000000 --- a/src/material/core/tokens/m3/definitions/_md-comp-elevated-card.scss +++ /dev/null @@ -1,55 +0,0 @@ -// -// Design system display name: Material 3 -// Design system version: v0.161 -// - -@use 'sass:map'; - -@use './md-sys-color'; - -@use './md-sys-elevation'; - -@use './md-sys-shape'; - -@use './md-sys-state'; - -$_default: ( - 'md-sys-color': md-sys-color.values-light(), - 'md-sys-elevation': md-sys-elevation.values(), - 'md-sys-shape': md-sys-shape.values(), - 'md-sys-state': md-sys-state.values(), -); - -@function values($deps: $_default, $exclude-hardcoded-values: false) { - $values: ( - 'container-color': map.get($deps, 'md-sys-color', 'surface-container-low'), - 'container-elevation': map.get($deps, 'md-sys-elevation', 'level1'), - 'container-shadow-color': map.get($deps, 'md-sys-color', 'shadow'), - 'container-shape': map.get($deps, 'md-sys-shape', 'corner-medium'), - 'container-surface-tint-layer-color': - map.get($deps, 'md-sys-color', 'surface-tint'), - 'disabled-container-color': map.get($deps, 'md-sys-color', 'surface'), - 'disabled-container-elevation': map.get($deps, 'md-sys-elevation', 'level1'), - 'disabled-container-opacity': if($exclude-hardcoded-values, null, 0.38), - 'dragged-container-elevation': map.get($deps, 'md-sys-elevation', 'level4'), - 'dragged-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'dragged-state-layer-opacity': - map.get($deps, 'md-sys-state', 'dragged-state-layer-opacity'), - 'focus-container-elevation': map.get($deps, 'md-sys-elevation', 'level1'), - 'focus-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'focus-state-layer-opacity': - map.get($deps, 'md-sys-state', 'focus-state-layer-opacity'), - 'hover-container-elevation': map.get($deps, 'md-sys-elevation', 'level2'), - 'hover-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'hover-state-layer-opacity': - map.get($deps, 'md-sys-state', 'hover-state-layer-opacity'), - 'icon-color': map.get($deps, 'md-sys-color', 'primary'), - 'icon-size': if($exclude-hardcoded-values, null, 24px), - 'pressed-container-elevation': map.get($deps, 'md-sys-elevation', 'level1'), - 'pressed-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'pressed-state-layer-opacity': - map.get($deps, 'md-sys-state', 'pressed-state-layer-opacity') - ); - - @return $values; -} diff --git a/src/material/core/tokens/m3/definitions/_md-comp-filled-card.scss b/src/material/core/tokens/m3/definitions/_md-comp-filled-card.scss deleted file mode 100644 index f0efd483581c..000000000000 --- a/src/material/core/tokens/m3/definitions/_md-comp-filled-card.scss +++ /dev/null @@ -1,52 +0,0 @@ -// -// Design system display name: Material 3 -// Design system version: v0.161 -// - -@use 'sass:map'; - -@use './md-sys-color'; - -@use './md-sys-elevation'; - -@use './md-sys-shape'; - -@use './md-sys-state'; - -$_default: ( - 'md-sys-color': md-sys-color.values-light(), - 'md-sys-elevation': md-sys-elevation.values(), - 'md-sys-shape': md-sys-shape.values(), - 'md-sys-state': md-sys-state.values(), -); - -@function values($deps: $_default, $exclude-hardcoded-values: false) { - @return ( - 'container-color': map.get($deps, 'md-sys-color', 'surface-variant'), - 'container-elevation': map.get($deps, 'md-sys-elevation', 'level0'), - 'container-shadow-color': map.get($deps, 'md-sys-color', 'shadow'), - 'container-shape': map.get($deps, 'md-sys-shape', 'corner-medium'), - 'disabled-container-color': - map.get($deps, 'md-sys-color', 'surface-variant'), - 'disabled-container-elevation': map.get($deps, 'md-sys-elevation', 'level0'), - 'disabled-container-opacity': if($exclude-hardcoded-values, null, 0.38), - 'dragged-container-elevation': map.get($deps, 'md-sys-elevation', 'level3'), - 'dragged-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'dragged-state-layer-opacity': - map.get($deps, 'md-sys-state', 'dragged-state-layer-opacity'), - 'focus-container-elevation': map.get($deps, 'md-sys-elevation', 'level0'), - 'focus-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'focus-state-layer-opacity': - map.get($deps, 'md-sys-state', 'focus-state-layer-opacity'), - 'hover-container-elevation': map.get($deps, 'md-sys-elevation', 'level1'), - 'hover-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'hover-state-layer-opacity': - map.get($deps, 'md-sys-state', 'hover-state-layer-opacity'), - 'icon-color': map.get($deps, 'md-sys-color', 'primary'), - 'icon-size': if($exclude-hardcoded-values, null, 24px), - 'pressed-container-elevation': map.get($deps, 'md-sys-elevation', 'level0'), - 'pressed-state-layer-color': map.get($deps, 'md-sys-color', 'on-surface'), - 'pressed-state-layer-opacity': - map.get($deps, 'md-sys-state', 'pressed-state-layer-opacity') - ); -} diff --git a/src/material/core/tokens/m3/mat/_card.scss b/src/material/core/tokens/m3/mat/_card.scss deleted file mode 100644 index 1d4051c7ffdb..000000000000 --- a/src/material/core/tokens/m3/mat/_card.scss +++ /dev/null @@ -1,24 +0,0 @@ -@use 'sass:map'; -@use '../../../style/sass-utils'; -@use '../../token-definition'; - -// The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mat, card); - -/// Generates custom tokens for the mat-card. -/// @param {Map} $systems The MDC system tokens -/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values -/// @param {Map} $token-slots Possible token slots -/// @return {Map} A set of custom tokens for the mat-card -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - token-definition.generate-typography-tokens($systems, title-text, title-large), - token-definition.generate-typography-tokens($systems, subtitle-text, title-medium), - ( - subtitle-text-color: map.get($systems, md-sys-color, on-surface) - ) - ); - - @return token-definition.namespace-tokens($prefix, $tokens, $token-slots); -} - diff --git a/src/material/core/tokens/m3/mdc/_elevated-card.scss b/src/material/core/tokens/m3/mdc/_elevated-card.scss deleted file mode 100644 index c0e8607ed9d9..000000000000 --- a/src/material/core/tokens/m3/mdc/_elevated-card.scss +++ /dev/null @@ -1,22 +0,0 @@ -@use 'sass:map'; -@use '../../../style/elevation'; -@use '../../token-definition'; - -// The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mat, elevated-card); - -/// Generates the tokens for MDC elevated-card -/// @param {Map} $systems The MDC system tokens -/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values -/// @param {Map} $token-slots Possible token slots -/// @return {Map} A set of tokens for the MDC elevated-card -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: token-definition.get-mdc-tokens('elevated-card', $systems, $exclude-hardcoded); - $elevation: map.get($tokens, container-elevation); - - @if ($elevation != null) { - $tokens: map.set($tokens, container-elevation, elevation.get-box-shadow($elevation)); - } - - @return token-definition.namespace-tokens($prefix, $tokens, $token-slots); -} diff --git a/tools/extract-tokens/extract-tokens.ts b/tools/extract-tokens/extract-tokens.ts index 7611a0851e55..8b12105e6965 100644 --- a/tools/extract-tokens/extract-tokens.ts +++ b/tools/extract-tokens/extract-tokens.ts @@ -133,8 +133,7 @@ function extractTokens(themePath: string): Token[] { const parsedTokens = JSON.parse(data[0]) as ExtractedToken[]; return parsedTokens.map(token => { - const value = token.value; - const derivedFrom = typeof value === 'string' ? textBetween(value, 'var(', ')') : null; + const derivedFrom = extractDerivedFrom(token.value); return { name: token.name, @@ -147,6 +146,24 @@ function extractTokens(themePath: string): Token[] { }); } +/** + * Gets the system variable from the token value. May either be a variable shaped as 'var(...)' + * or just the variable name itself. + */ +function extractDerivedFrom(value: string | number) { + if (typeof value === 'string') { + if (value.startsWith('var(')) { + return textBetween(value, 'var(', ')'); + } + + if (value.startsWith('--mat')) { + return value; + } + } + + return null; +} + /** * Generates a highlighted code snippet that illustrates how an overrides mixin can be used. * @param themes Themes that were extracted from a specific entrypoint. One of these themes will @@ -286,6 +303,7 @@ function getTokenExtractionCode( @each $map in $__override-tokens { $namespace: ${map}.get($map, namespace); $tokens: ${map}.get($map, tokens); + $overrideTransforms: ${map}.get($map, overrideTransforms); $prefix: ${map}.get($map, prefix) or ''; $color: ${map}.get($__all-color, $namespace) or (); $base: ${map}.get($__all-base, $namespace) or (); @@ -328,13 +346,19 @@ function getTokenExtractionCode( $value: $resolved-value; } + // Transform the token's name if the overrides function accepts a different key. + @each $overrideTokenKey, $overrideTokenName in $overrideTransforms { + @if ($name == $overrideTokenName) { + $name: $overrideTokenKey; + } + } + @if ($value) { $__results: ${list}.append($__results, ( name: ${str}.unquote($name), value: $value, type: $type, prefix: ${str}.unquote(${stringJoin}($namespace, '-')), - overridesName: ${str}.unquote($prefix + $name), )) !global; } }