From 27004ee0136781e7601ad472b86aefa94805cd9e Mon Sep 17 00:00:00 2001 From: Andrew Seguin Date: Tue, 13 May 2025 20:53:59 -0600 Subject: [PATCH 1/3] refactor: remove component m3 tokens from theme config --- src/material/autocomplete/BUILD.bazel | 1 + .../autocomplete/_autocomplete-theme.scss | 35 +- .../autocomplete/_m3-autocomplete.scss | 19 +- src/material/autocomplete/autocomplete.scss | 5 +- src/material/badge/_badge-theme.scss | 13 +- src/material/badge/_m3-badge.scss | 32 +- .../bottom-sheet/_bottom-sheet-theme.scss | 35 +- .../bottom-sheet/_m3-bottom-sheet.scss | 31 +- .../bottom-sheet/bottom-sheet-container.scss | 7 +- .../button-toggle/_button-toggle-theme.scss | 54 ++- .../button-toggle/_m3-button-toggle.scss | 83 ++-- src/material/button-toggle/button-toggle.scss | 8 +- src/material/button/_button-theme.scss | 59 ++- src/material/button/_fab-theme.scss | 44 +-- src/material/button/_icon-button-theme.scss | 57 ++- src/material/button/_m3-button.scss | 356 +++++++----------- src/material/button/_m3-fab.scss | 193 +++------- src/material/button/_m3-icon-button.scss | 74 ++-- src/material/button/button.scss | 8 +- src/material/button/fab.scss | 8 +- src/material/button/icon-button.scss | 5 +- src/material/card/_card-theme.scss | 35 +- src/material/card/_m3-card.scss | 67 ++-- src/material/card/card.scss | 12 +- src/material/checkbox/_checkbox-common.scss | 19 +- src/material/checkbox/_checkbox-theme.scss | 51 +-- src/material/checkbox/_m3-checkbox.scss | 123 +++--- src/material/checkbox/checkbox.scss | 9 +- src/material/chips/_chips-theme.scss | 46 ++- src/material/chips/_m3-chip.scss | 165 +++----- src/material/chips/chip.scss | 27 +- src/material/core/_core-theme.scss | 93 +++-- src/material/core/_core.scss | 10 +- src/material/core/_m3-app.scss | 57 +-- src/material/core/option/_m3-optgroup.scss | 28 +- src/material/core/option/_m3-option.scss | 72 ++-- src/material/core/option/_optgroup-theme.scss | 35 +- src/material/core/option/_option-theme.scss | 44 +-- src/material/core/option/optgroup.scss | 8 +- src/material/core/option/option.scss | 15 +- src/material/core/ripple/_m3-ripple.scss | 20 +- src/material/core/ripple/_ripple-theme.scss | 35 +- src/material/core/ripple/_ripple.scss | 8 +- .../pseudo-checkbox/_m3-pseudo-checkbox.scss | 61 ++- .../_pseudo-checkbox-theme.scss | 34 +- .../pseudo-checkbox/pseudo-checkbox.scss | 9 +- src/material/core/style/_sass-utils.scss | 29 -- .../_color-api-backwards-compatibility.scss | 49 ++- src/material/core/theming/_definition.scss | 6 + src/material/core/theming/_inspection.scss | 25 -- .../core/theming/tests/m3-theme.spec.ts | 6 - .../tests/theming-definition-api.spec.ts | 1 + src/material/core/tokens/_m3-tokens.scss | 98 ----- src/material/core/tokens/_m3-utils.scss | 92 +---- src/material/core/tokens/_token-utils.scss | 118 ------ .../datepicker/_datepicker-theme.scss | 44 ++- src/material/datepicker/_m3-datepicker.scss | 171 +++------ src/material/datepicker/calendar-body.scss | 23 +- src/material/datepicker/calendar.scss | 15 +- src/material/datepicker/date-range-input.scss | 10 +- .../datepicker/datepicker-content.scss | 12 +- .../datepicker/datepicker-toggle.scss | 10 +- src/material/dialog/_dialog-theme.scss | 35 +- src/material/dialog/_m3-dialog.scss | 66 ++-- src/material/dialog/dialog.scss | 19 +- src/material/divider/_divider-theme.scss | 35 +- src/material/divider/_m3-divider.scss | 22 +- src/material/divider/divider.scss | 8 +- src/material/expansion/_expansion-theme.scss | 36 +- src/material/expansion/_m3-expansion.scss | 72 ++-- .../expansion/expansion-panel-header.scss | 13 +- src/material/expansion/expansion-panel.scss | 11 +- .../form-field/_form-field-focus-overlay.scss | 9 +- .../form-field/_form-field-native-select.scss | 12 +- .../form-field/_form-field-subscript.scss | 11 +- .../form-field/_form-field-theme.scss | 49 +-- src/material/form-field/_m3-form-field.scss | 214 +++++------ .../_mdc-text-field-density-overrides.scss | 8 +- .../_mdc-text-field-structure-overrides.scss | 8 +- .../form-field/_mdc-text-field-structure.scss | 5 +- src/material/form-field/form-field.scss | 15 +- src/material/grid-list/_grid-list-theme.scss | 35 +- src/material/grid-list/_m3-grid-list.scss | 25 +- src/material/grid-list/grid-list.scss | 11 +- src/material/icon/_icon-theme.scss | 44 +-- src/material/icon/_m3-icon.scss | 36 +- src/material/icon/icon.scss | 8 +- src/material/input/_input-theme.scss | 43 +-- .../list/_list-inherited-structure.scss | 25 +- src/material/list/_list-theme.scss | 33 +- src/material/list/_m3-list.scss | 115 +++--- src/material/list/list.scss | 10 +- src/material/menu/_m3-menu.scss | 69 ++-- src/material/menu/_menu-theme.scss | 35 +- src/material/menu/menu.scss | 23 +- src/material/paginator/_m3-paginator.scss | 40 +- src/material/paginator/_paginator-theme.scss | 45 +-- src/material/paginator/paginator.scss | 11 +- .../progress-bar/_m3-progress-bar.scss | 42 +-- .../progress-bar/_progress-bar-theme.scss | 32 +- src/material/progress-bar/progress-bar.scss | 17 +- .../_m3-progress-spinner.scss | 36 +- .../_progress-spinner-theme.scss | 43 +-- .../progress-spinner/progress-spinner.scss | 11 +- src/material/radio/_m3-radio.scss | 88 ++--- src/material/radio/_radio-common.scss | 23 +- src/material/radio/_radio-theme.scss | 46 ++- src/material/radio/radio.scss | 9 +- src/material/select/_m3-select.scss | 65 ++-- src/material/select/_select-theme.scss | 45 +-- src/material/select/select.scss | 21 +- src/material/sidenav/_m3-sidenav.scss | 38 +- src/material/sidenav/_sidenav-theme.scss | 35 +- src/material/sidenav/drawer.scss | 13 +- .../slide-toggle/_m3-slide-toggle.scss | 232 +++++------- .../slide-toggle/_slide-toggle-theme.scss | 43 +-- src/material/slide-toggle/slide-toggle.scss | 41 +- src/material/slider/_m3-slider.scss | 159 +++----- src/material/slider/_slider-theme.scss | 40 +- src/material/slider/slider.scss | 37 +- src/material/snack-bar/_m3-snack-bar.scss | 35 +- src/material/snack-bar/_snack-bar-theme.scss | 31 +- .../snack-bar/snack-bar-container.scss | 12 +- src/material/sort/_m3-sort.scss | 19 +- src/material/sort/_sort-theme.scss | 35 +- src/material/sort/sort-header.scss | 8 +- src/material/stepper/_m3-stepper.scss | 120 +++--- src/material/stepper/_stepper-theme.scss | 48 +-- src/material/stepper/step-header.scss | 19 +- src/material/stepper/stepper.scss | 15 +- src/material/table/_m3-table.scss | 53 +-- src/material/table/_table-flex-styles.scss | 8 +- src/material/table/_table-theme.scss | 37 +- src/material/table/table.scss | 10 +- src/material/tabs/_m3-tabs.scss | 82 ++-- src/material/tabs/_tabs-common.scss | 32 +- src/material/tabs/_tabs-theme.scss | 48 +-- src/material/timepicker/_m3-timepicker.scss | 25 +- .../timepicker/_timepicker-theme.scss | 46 +-- src/material/timepicker/timepicker.scss | 10 +- src/material/toolbar/_m3-toolbar.scss | 31 +- src/material/toolbar/_toolbar-theme.scss | 32 +- src/material/toolbar/toolbar.scss | 18 +- src/material/tooltip/_m3-tooltip.scss | 34 +- src/material/tooltip/_tooltip-theme.scss | 34 +- src/material/tooltip/tooltip.scss | 8 +- src/material/tree/_m3-tree.scss | 32 +- src/material/tree/_tree-theme.scss | 37 +- src/material/tree/tree.scss | 12 +- 149 files changed, 2693 insertions(+), 3529 deletions(-) diff --git a/src/material/autocomplete/BUILD.bazel b/src/material/autocomplete/BUILD.bazel index daae0aa320bf..7a0e06085b2b 100644 --- a/src/material/autocomplete/BUILD.bazel +++ b/src/material/autocomplete/BUILD.bazel @@ -56,6 +56,7 @@ sass_binary( src = "autocomplete.scss", deps = [ ":m2", + ":m3", "//src/cdk:sass_lib", "//src/material/core/tokens:token_utils", ], diff --git a/src/material/autocomplete/_autocomplete-theme.scss b/src/material/autocomplete/_autocomplete-theme.scss index bc05192ced75..b240471548ac 100644 --- a/src/material/autocomplete/_autocomplete-theme.scss +++ b/src/material/autocomplete/_autocomplete-theme.scss @@ -1,15 +1,17 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @use 'm2-autocomplete'; +@use 'm3-autocomplete'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-autocomplete.$prefix, + map.get(m3-autocomplete.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -22,7 +24,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-autocomplete.$prefix, + map.get(m3-autocomplete.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,7 +39,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-autocomplete.$prefix, + map.get(m3-autocomplete.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -48,7 +54,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-autocomplete.$prefix, + map.get(m3-autocomplete.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -76,7 +84,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-autocomplete') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -91,15 +102,3 @@ } } } - -@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( - m2-autocomplete.$prefix, - map.get($tokens, m2-autocomplete.$prefix) - ); - } -} diff --git a/src/material/autocomplete/_m3-autocomplete.scss b/src/material/autocomplete/_m3-autocomplete.scss index 14adce4e997d..4f148eadb41c 100644 --- a/src/material/autocomplete/_m3-autocomplete.scss +++ b/src/material/autocomplete/_m3-autocomplete.scss @@ -10,12 +10,19 @@ $prefix: (mat, autocomplete); /// @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-autocomplete -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); $tokens: ( - background-color: map.get($systems, md-sys-color, surface-container), - container-shape: map.get($systems, md-sys-shape, corner-extra-small), - container-elevation-shadow: - m3-utils.hardcode(elevation.get-box-shadow(2), $exclude-hardcoded), + base: ( + container-shape: map.get($system, corner-extra-small), + container-elevation-shadow: elevation.get-box-shadow(2), + ), + color: ( + background-color: map.get($system, surface-container), + ), + typography: (), + density: (), ); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + + @return $tokens; } diff --git a/src/material/autocomplete/autocomplete.scss b/src/material/autocomplete/autocomplete.scss index df5dc9bafe9d..1f014e9632b2 100644 --- a/src/material/autocomplete/autocomplete.scss +++ b/src/material/autocomplete/autocomplete.scss @@ -1,9 +1,12 @@ @use '@angular/cdk'; @use './m2-autocomplete'; +@use './m3-autocomplete'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; $token-prefix: m2-autocomplete.$prefix; $token-slots: m2-autocomplete.get-token-slots(); +$fallbacks: m3-autocomplete.get-tokens(m3-system.$theme-with-system-vars); // Even though we don't use the MDC styles, we need to keep the classes in the // DOM for the Gmat versions to work. We need to bump up the specificity here @@ -21,7 +24,7 @@ div.mat-mdc-autocomplete-panel { // panel which is required for scroll calculations (see #30974). position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-radius: token-utils.slot(container-shape); box-shadow: token-utils.slot(container-elevation-shadow); background-color: token-utils.slot(background-color); diff --git a/src/material/badge/_badge-theme.scss b/src/material/badge/_badge-theme.scss index ced78f1ffddd..34ba2cd6c362 100644 --- a/src/material/badge/_badge-theme.scss +++ b/src/material/badge/_badge-theme.scss @@ -1,7 +1,6 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-badge'; @@ -107,9 +106,7 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-badge. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the badge: primary, secondary, tertiary, -/// or error (If not specified, default error color will be used). +/// @param {String} $color-variant The color variant to use for the component @mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-badge') { @if inspection.get-theme-version($theme) == 1 { @@ -131,11 +128,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-badge-tokens: token-utils.get-tokens-for($tokens, m2-badge.$prefix, $options...); - @include token-utils.create-token-values(m2-badge.$prefix, $mat-badge-tokens); -} diff --git a/src/material/badge/_m3-badge.scss b/src/material/badge/_m3-badge.scss index f41305a74e91..f56de6cac480 100644 --- a/src/material/badge/_m3-badge.scss +++ b/src/material/badge/_m3-badge.scss @@ -13,38 +13,38 @@ $prefix: (mat, badge); $tokens: ( base: ( - container-shape: map.get($system, corner-full), - container-size: 16px, - legacy-container-size: unset, - legacy-small-size-container-size: unset, - small-size-container-size: 6px, - container-padding: 0 4px, - small-size-container-padding: 0, container-offset: -12px 0, - small-size-container-offset: -6px 0, container-overlap-offset: -12px, - small-size-container-overlap-offset: -6px, - large-size-container-size: 16px, + container-padding: 0 4px, + container-shape: map.get($system, corner-full), + container-size: 16px, large-size-container-offset: -12px 0, large-size-container-overlap-offset: -12px, large-size-container-padding: 0 4px, + large-size-container-size: 16px, + legacy-container-size: unset, legacy-large-size-container-size: unset, + legacy-small-size-container-size: unset, + small-size-container-offset: -6px 0, + small-size-container-overlap-offset: -6px, + small-size-container-padding: 0, + small-size-container-size: 6px, ), color: ( background-color: map.get($system, error), - text-color: map.get($system, on-error), disabled-state-background-color: m3-utils.color-with-opacity(map.get($system, error), 38%), disabled-state-text-color: map.get($system, on-error), + text-color: map.get($system, on-error), ), typography: ( - text-font: map.get($system, label-small-font), - text-size: map.get($system, label-small-size), - text-weight: map.get($system, label-small-weight), + large-size-line-height: 16px, large-size-text-size: map.get($system, label-small-size), - small-size-text-size: 0, line-height: 16px, small-size-line-height: 6px, - large-size-line-height: 16px, + small-size-text-size: 0, + text-font: map.get($system, label-small-font), + text-size: map.get($system, label-small-size), + text-weight: map.get($system, label-small-weight), ), density: (), ); diff --git a/src/material/bottom-sheet/_bottom-sheet-theme.scss b/src/material/bottom-sheet/_bottom-sheet-theme.scss index 3fc593944d06..01ea3e477a21 100644 --- a/src/material/bottom-sheet/_bottom-sheet-theme.scss +++ b/src/material/bottom-sheet/_bottom-sheet-theme.scss @@ -2,14 +2,16 @@ @use '../core/typography/typography'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @use './m2-bottom-sheet'; +@use './m3-bottom-sheet'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-bottom-sheet.$prefix, + map.get(m3-bottom-sheet.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -22,7 +24,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-bottom-sheet.$prefix, + map.get(m3-bottom-sheet.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,7 +39,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-bottom-sheet.$prefix, + map.get(m3-bottom-sheet.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -48,7 +54,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-bottom-sheet.$prefix, + map.get(m3-bottom-sheet.get-tokens($theme), density)); } @else { } } @@ -70,7 +78,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-bottom-sheet') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -85,15 +96,3 @@ } } } - -@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( - m2-bottom-sheet.$prefix, - map.get($tokens, m2-bottom-sheet.$prefix) - ); - } -} diff --git a/src/material/bottom-sheet/_m3-bottom-sheet.scss b/src/material/bottom-sheet/_m3-bottom-sheet.scss index d628b04e19d9..f4a3b104bba7 100644 --- a/src/material/bottom-sheet/_m3-bottom-sheet.scss +++ b/src/material/bottom-sheet/_m3-bottom-sheet.scss @@ -1,24 +1,27 @@ @use 'sass:map'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, bottom-sheet); /// Generates custom tokens for the mat-bottom-sheet. -/// @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-bottom-sheet -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, container-text, body-large), - ( - container-shape: m3-utils.hardcode(28px, $exclude-hardcoded), - container-text-color: map.get($systems, md-sys-color, on-surface), - container-background-color: map.get($systems, md-sys-color, surface-container-low), +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + @return ( + base: ( + container-shape: 28px, ), + color: ( + container-text-color: map.get($system, on-surface), + container-background-color: map.get($system, surface-container-low), + ), + typography: ( + container-text-font: map.get($system, body-large-font), + container-text-line-height: map.get($system, body-large-line-height), + container-text-size: map.get($system, body-large-size), + container-text-tracking: map.get($system, body-large-tracking), + container-text-weight: map.get($system, body-large-weight), + ), + density: (), ); - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } diff --git a/src/material/bottom-sheet/bottom-sheet-container.scss b/src/material/bottom-sheet/bottom-sheet-container.scss index 4f47d87a5dce..02914cc02a7c 100644 --- a/src/material/bottom-sheet/bottom-sheet-container.scss +++ b/src/material/bottom-sheet/bottom-sheet-container.scss @@ -1,7 +1,9 @@ @use '@angular/cdk'; @use '../core/style/elevation'; @use './m2-bottom-sheet'; +@use './m3-bottom-sheet'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; // The bottom sheet minimum width on larger screen sizes is based // on increments of the toolbar, according to the spec. See: @@ -12,6 +14,7 @@ $container-horizontal-padding: 16px !default; $token-prefix: m2-bottom-sheet.$prefix; $token-slots: m2-bottom-sheet.get-token-slots(); +$fallbacks: m3-bottom-sheet.get-tokens(m3-system.$theme-with-system-vars); @keyframes _mat-bottom-sheet-enter { from { @@ -48,7 +51,7 @@ $token-slots: m2-bottom-sheet.get-token-slots(); // elements (e.g. close buttons) inside the bottom sheet. position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(container-background-color); color: token-utils.slot(container-text-color); font-family: token-utils.slot(container-text-font); @@ -77,7 +80,7 @@ $token-slots: m2-bottom-sheet.get-token-slots(); // Applies a border radius to the bottom sheet. Should only be applied when it's not full-screen. %_mat-bottom-sheet-container-border-radius { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-left-radius: token-utils.slot(container-shape); border-top-right-radius: token-utils.slot(container-shape); } diff --git a/src/material/button-toggle/_button-toggle-theme.scss b/src/material/button-toggle/_button-toggle-theme.scss index 6ea99840bf34..f6f07a2de20b 100644 --- a/src/material/button-toggle/_button-toggle-theme.scss +++ b/src/material/button-toggle/_button-toggle-theme.scss @@ -1,18 +1,20 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-button-toggle'; @use './m3-button-toggle'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-button-toggle. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-button-toggle.$prefix, + map.get(m3-button-toggle.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -25,12 +27,13 @@ /// Outputs color theme styles for the mat-button-toggle. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button toggle: primary, secondary, tertiary, -/// or error (If not specified, default secondary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the button toggle: primary, +/// secondary, tertiary, or error (If not specified, default secondary color will be used). +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-button-toggle.$prefix, + map.get(m3-button-toggle.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -45,7 +48,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-button-toggle.$prefix, + map.get(m3-button-toggle.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -61,7 +66,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-button-toggle.$prefix, m3-button-toggle.get-density-tokens($theme)); + m3-button-toggle.$prefix, + map.get(m3-button-toggle.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -92,16 +98,15 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-button-toggle. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button toggle: primary, secondary, tertiary, -/// or error (If not specified, default secondary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the button toggle: primary, +/// secondary, tertiary, or error (If not specified, default secondary color will be used). +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-button-toggle') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -116,18 +121,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-standard-button-toggle-tokens: token-utils.get-tokens-for( - $tokens, - m2-button-toggle.$prefix, - $options... - ); - @include token-utils.create-token-values( - m2-button-toggle.$prefix, - $mat-standard-button-toggle-tokens - ); -} diff --git a/src/material/button-toggle/_m3-button-toggle.scss b/src/material/button-toggle/_m3-button-toggle.scss index 6eea960a27fd..d02fc08bc61b 100644 --- a/src/material/button-toggle/_m3-button-toggle.scss +++ b/src/material/button-toggle/_m3-button-toggle.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,62 +8,48 @@ $prefix: (mat, button-toggle); /// Generates custom tokens for the mat-button-toggle. -/// @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-button-toggle -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, label-text, label-large), - ( - shape: map.get($systems, md-sys-shape, corner-extra-large), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - text-color: map.get($systems, md-sys-color, on-surface), - background-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - state-layer-color: map.get($systems, md-sys-color, on-surface), - selected-state-background-color: map.get($systems, md-sys-color, secondary-container), - selected-state-text-color: map.get($systems, md-sys-color, on-secondary-container), - disabled-state-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38, - ), - disabled-state-background-color: - m3-utils.hardcode(transparent, $exclude-hardcoded), - disabled-selected-state-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38, - ), - disabled-selected-state-background-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.12, - ), - divider-color: map.get($systems, md-sys-color, outline), - )); +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, secondary, $color-variant); + } - $color-variants: ( - // Color variants: - primary: ( - selected-state-background-color: map.get($systems, md-sys-color, primary-container), - selected-state-text-color: map.get($systems, md-sys-color, on-primary-container), + $tokens: ( + base: ( + focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + shape: map.get($system, corner-extra-large), + ), + typography: ( + label-text-font: map.get($system, label-large-font), + label-text-line-height: map.get($system, label-large-line-height), + label-text-size: map.get($system, label-large-size), + label-text-tracking: map.get($system, label-large-tracking), + label-text-weight: map.get($system, label-large-weight), ), - secondary: (), // Default, no overrides needed - tertiary: ( - selected-state-background-color: map.get($systems, md-sys-color, tertiary-container), - selected-state-text-color: map.get($systems, md-sys-color, on-tertiary-container), + color: ( + background-color: transparent, + disabled-selected-state-background-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + disabled-selected-state-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-state-background-color: transparent, + disabled-state-text-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + divider-color: map.get($system, outline), + selected-state-background-color: map.get($system, secondary-container), + selected-state-text-color: map.get($system, on-secondary-container), + state-layer-color: map.get($system, on-surface), + text-color: map.get($system, on-surface), ), - error: ( - selected-state-background-color: map.get($systems, md-sys-color, error-container), - selected-state-text-color: map.get($systems, md-sys-color, on-error-container), - ) + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - @return m3-utils.namespace($prefix, ($tokens, $color-variants), $token-slots); + @return $tokens; } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -4); +@function get-density-tokens($scale) { + $scale: theming.clamp-density(scale, -4); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/button-toggle/button-toggle.scss b/src/material/button-toggle/button-toggle.scss index 2ffd3a6b0b12..cce337b1077b 100644 --- a/src/material/button-toggle/button-toggle.scss +++ b/src/material/button-toggle/button-toggle.scss @@ -5,6 +5,8 @@ @use '../core/style/elevation'; @use '../core/tokens/token-utils'; @use './m2-button-toggle'; +@use './m3-button-toggle'; +@use '../core/tokens/m3-system'; $standard-padding: 12px !default; $legacy-padding: 16px !default; @@ -17,7 +19,11 @@ $legacy-height: 36px !default; $standard-border-radius: 4px !default; $legacy-border-radius: 2px !default; -@include token-utils.use-tokens(m2-button-toggle.$prefix, m2-button-toggle.get-token-slots()) { +$token-prefix: m2-button-toggle.$prefix; +$token-slots: m2-button-toggle.get-token-slots(); +$fallbacks: m3-button-toggle.get-tokens(m3-system.$theme-with-system-vars); + +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-button-toggle-standalone, .mat-button-toggle-group { position: relative; diff --git a/src/material/button/_button-theme.scss b/src/material/button/_button-theme.scss index a88abbd91180..ff66f0a85359 100644 --- a/src/material/button/_button-theme.scss +++ b/src/material/button/_button-theme.scss @@ -1,13 +1,13 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-button'; @use './m3-button'; +@use 'sass:map'; -@mixin _button-variant($theme, $palette) { +@mixin _m2-button-variant($theme, $palette) { $mat-tokens: if( $palette, m2-button.private-get-color-palette-color-tokens($theme, $palette), @@ -17,21 +17,14 @@ @include token-utils.create-token-values-mixed(m2-button.$prefix, $mat-tokens); } -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-text-button-tokens: token-utils.get-tokens-for( - $tokens, m2-button.$prefix, $options...); - @include token-utils.create-token-values(m2-button.$prefix, $mat-text-button-tokens); -} - /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-button. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-button.$prefix, + map.get(m3-button.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -42,15 +35,17 @@ /// Outputs color theme styles for the mat-button. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for +/// the badge: primary, secondary, tertiary, or error (If not specified, +/// default primary color will be used). +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-button.$prefix, + map.get(m3-button.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { - @include _button-variant($theme, null); + @include _m2-button-variant($theme, null); } .mat-mdc-button, @@ -59,15 +54,15 @@ .mat-mdc-outlined-button, .mat-tonal-button { &.mat-primary { - @include _button-variant($theme, primary); + @include _m2-button-variant($theme, primary); } &.mat-accent { - @include _button-variant($theme, accent); + @include _m2-button-variant($theme, accent); } &.mat-warn { - @include _button-variant($theme, warn); + @include _m2-button-variant($theme, warn); } } } @@ -77,7 +72,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-button.$prefix, + map.get(m3-button.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -93,7 +90,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-button.$prefix, m3-button.get-density-tokens($theme)); + m3-button.$prefix, + map.get(m3-button.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -122,16 +120,15 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-button. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the button: primary, secondary, +// tertiary, or error (If not specified, default primary color will be used). +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-button') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { diff --git a/src/material/button/_fab-theme.scss b/src/material/button/_fab-theme.scss index a4a8e8eec768..450ca6cd4873 100644 --- a/src/material/button/_fab-theme.scss +++ b/src/material/button/_fab-theme.scss @@ -1,18 +1,17 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use './m2-fab'; @use './m3-fab'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-fab. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,12 +34,13 @@ /// Outputs color theme styles for the mat-fab. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the fab: primary, secondary, or tertiary -/// (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {ArgList} $color-variant: The color variant to use for the fab: primary, secondary, +// or tertiary. (If not specified, default primary color will be used). +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-fab.$prefix, + map.get(m3-fab.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include _fab-variant($theme, null); @@ -66,7 +66,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-fab.$prefix, + map.get(m3-fab.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -81,7 +83,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-fab.$prefix, m3-fab.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-fab.$prefix, + map.get(m3-fab.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -110,16 +114,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-checkbox. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the fab: primary, secondary, or tertiary -/// (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the fab +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-fab') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -134,11 +136,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-fab-tokens: token-utils.get-tokens-for($tokens, m2-fab.$prefix, $options...); - @include token-utils.create-token-values(m2-fab.$prefix, $mat-fab-tokens); -} diff --git a/src/material/button/_icon-button-theme.scss b/src/material/button/_icon-button-theme.scss index 963d568b9706..c401ce4e98e1 100644 --- a/src/material/button/_icon-button-theme.scss +++ b/src/material/button/_icon-button-theme.scss @@ -6,11 +6,12 @@ @use '../core/tokens/token-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-icon-button.$prefix, + map.get(m3-icon-button.get-tokens($theme), base)); } @else { // Add default values for tokens not related to color, typography, or density. @include sass-utils.current-selector-or-root() { @@ -22,7 +23,7 @@ } } -@mixin _icon-button-variant($theme, $palette) { +@mixin _m2-icon-button-variant($theme, $palette) { $mat-tokens: if( $palette, m2-icon-button.private-get-color-palette-color-tokens($theme, $palette), @@ -34,26 +35,28 @@ /// Outputs color theme styles for the mat-icon-button. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button: primary, secondary, tertiary, or error. -@mixin color($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the +// button: primary, secondary, tertiary, or error. +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-icon-button.$prefix, + map.get(m3-icon-button.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { - @include _icon-button-variant($theme, null); + @include _m2-icon-button-variant($theme, null); .mat-mdc-icon-button { &.mat-primary { - @include _icon-button-variant($theme, primary); + @include _m2-icon-button-variant($theme, primary); } &.mat-accent { - @include _icon-button-variant($theme, accent); + @include _m2-icon-button-variant($theme, accent); } &.mat-warn { - @include _icon-button-variant($theme, warn); + @include _m2-icon-button-variant($theme, warn); } } } @@ -62,7 +65,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-icon-button.$prefix, + map.get(m3-icon-button.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -76,7 +81,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-icon-button.$prefix, m3-icon-button.get-density-tokens($theme)); + m3-icon-button.$prefix, + map.get(m3-icon-button.get-tokens($theme), density)); } @else { $icon-size: 24px; $density-scale: inspection.get-theme-density($theme); @@ -133,15 +139,15 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-icon-button. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the button: primary, secondary, tertiary, or error. -@mixin theme($theme, $options...) { +/// @param {String} $color-variant: The color variant to use for the button: primary, +// secondary, tertiary, or error. +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-icon-button') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -156,14 +162,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - @if ($tokens != ()) { - $mat-tokens: token-utils.get-tokens-for($tokens, m2-icon-button.$prefix, $options...); - - @include token-utils.create-token-values(m2-icon-button.$prefix, $mat-tokens); - } -} diff --git a/src/material/button/_m3-button.scss b/src/material/button/_m3-button.scss index 3ed296652edd..bc9b542689ed 100644 --- a/src/material/button/_m3-button.scss +++ b/src/material/button/_m3-button.scss @@ -1,7 +1,6 @@ @use 'sass:map'; @use 'sass:list'; @use '../core/tokens/m3-utils'; -@use '../core/style/sass-utils'; @use '../core/style/elevation'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,240 +8,141 @@ // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, button); -/// Generates custom tokens for the mat-flat-button. -/// @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-flat-button -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - filled-container-color: map.get($systems, md-sys-color, primary), - filled-container-shape: map.get($systems, md-sys-shape, corner-full), - filled-disabled-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - filled-disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - filled-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - filled-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - filled-horizontal-padding: m3-utils.hardcode(24px, $exclude-hardcoded), - filled-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - filled-icon-offset: m3-utils.hardcode(-8px, $exclude-hardcoded), - filled-icon-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - filled-label-text-color: map.get($systems, md-sys-color, on-primary), - filled-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - filled-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - filled-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - filled-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - filled-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - filled-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-primary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) ), - filled-state-layer-color: map.get($systems, md-sys-color, on-primary), - outlined-container-shape: map.get($systems, md-sys-shape, corner-full), - outlined-disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - outlined-disabled-outline-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - outlined-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - outlined-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - outlined-horizontal-padding: m3-utils.hardcode(24px, $exclude-hardcoded), - outlined-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - outlined-icon-offset: m3-utils.hardcode(-8px, $exclude-hardcoded), - outlined-icon-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - outlined-label-text-color: map.get($systems, md-sys-color, primary), - outlined-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - outlined-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - outlined-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - outlined-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - outlined-outline-color: map.get($systems, md-sys-color, outline), - outlined-outline-width: if($exclude-hardcoded, null, 1px), - outlined-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - outlined-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - outlined-state-layer-color: map.get($systems, md-sys-color, primary), - protected-container-color: map.get($systems, md-sys-color, surface), - protected-container-elevation-shadow: map.get($systems, md-sys-elevation, level1), - protected-container-shape: map.get($systems, md-sys-shape, corner-full), - protected-disabled-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - protected-disabled-container-elevation-shadow: map.get($systems, md-sys-elevation, level0), - protected-disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - protected-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - protected-focus-container-elevation-shadow: map.get($systems, md-sys-elevation, level1), - protected-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - protected-horizontal-padding: m3-utils.hardcode(24px, $exclude-hardcoded), - protected-hover-container-elevation-shadow: map.get($systems, md-sys-elevation, level2), - protected-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - protected-icon-offset: m3-utils.hardcode(-8px, $exclude-hardcoded), - protected-icon-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - protected-label-text-color: map.get($systems, md-sys-color, primary), - protected-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - protected-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - protected-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - protected-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - protected-pressed-container-elevation-shadow: map.get($systems, md-sys-elevation, level1), - protected-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - protected-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - protected-state-layer-color: map.get($systems, md-sys-color, primary), - text-container-shape: map.get($systems, md-sys-shape, corner-full), - text-disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - text-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - text-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - text-horizontal-padding: m3-utils.hardcode(12px, $exclude-hardcoded), - text-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - text-icon-offset: m3-utils.hardcode(-4px, $exclude-hardcoded), - text-icon-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - text-label-text-color: map.get($systems, md-sys-color, primary), - text-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - text-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - text-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - text-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - text-pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity), - text-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - text-state-layer-color: map.get($systems, md-sys-color, primary), - text-with-icon-horizontal-padding: m3-utils.hardcode(16px, $exclude-hardcoded), - tonal-container-color: map.get($systems, md-sys-color, secondary-container), - tonal-container-shape: map.get($systems, md-sys-shape, corner-full), - tonal-disabled-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - tonal-disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - tonal-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - tonal-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - tonal-horizontal-padding: m3-utils.hardcode(24px, $exclude-hardcoded), - tonal-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - tonal-icon-offset: m3-utils.hardcode(-8px, $exclude-hardcoded), - tonal-icon-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - tonal-label-text-color: map.get($systems, md-sys-color, on-secondary-container), - tonal-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - tonal-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - tonal-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - tonal-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - tonal-pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity), - tonal-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-secondary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - tonal-state-layer-color: map.get($systems, md-sys-color, on-secondary-container), - ); +/// Generates custom tokens for the button. +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + $system: m3-utils.replace-colors-with-variant($system, secondary, $color-variant); + } - $variant-tokens: ( - primary: (), // Default, no overrides needed. - secondary: ( - filled-container-color: map.get($systems, md-sys-color, secondary), - filled-label-text-color: map.get($systems, md-sys-color, on-secondary), - filled-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-secondary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - filled-state-layer-color: map.get($systems, md-sys-color, on-secondary), - outlined-label-text-color: map.get($systems, md-sys-color, secondary), - outlined-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - outlined-state-layer-color: map.get($systems, md-sys-color, secondary), - protected-label-text-color: map.get($systems, md-sys-color, secondary), - protected-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - protected-state-layer-color: map.get($systems, md-sys-color, secondary), - text-label-text-color: map.get($systems, md-sys-color, secondary), - text-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - text-state-layer-color: map.get($systems, md-sys-color, secondary), + @return ( + base: ( + filled-container-shape: map.get($system, corner-full), + filled-horizontal-padding: 24px, + filled-icon-offset: -8px, + filled-icon-spacing: 8px, + outlined-container-shape: map.get($system, corner-full), + outlined-horizontal-padding: 24px, + outlined-icon-offset: -8px, + outlined-icon-spacing: 8px, + outlined-outline-width: 1px, + protected-container-shape: map.get($system, corner-full), + protected-horizontal-padding: 24px, + protected-icon-offset: -8px, + protected-icon-spacing: 8px, + text-container-shape: map.get($system, corner-full), + text-horizontal-padding: 12px, + text-icon-offset: -4px, + text-icon-spacing: 8px, + text-with-icon-horizontal-padding: 16px, + tonal-container-shape: map.get($system, corner-full), + tonal-horizontal-padding: 24px, + tonal-icon-offset: -8px, + tonal-icon-spacing: 8px, ), - tertiary: ( - filled-container-color: map.get($systems, md-sys-color, tertiary), - filled-label-text-color: map.get($systems, md-sys-color, on-tertiary), - filled-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-tertiary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - filled-state-layer-color: map.get($systems, md-sys-color, on-tertiary), - outlined-label-text-color: map.get($systems, md-sys-color, tertiary), - outlined-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - outlined-state-layer-color: map.get($systems, md-sys-color, tertiary), - protected-label-text-color: map.get($systems, md-sys-color, tertiary), - protected-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - protected-state-layer-color: map.get($systems, md-sys-color, tertiary), - text-label-text-color: map.get($systems, md-sys-color, tertiary), - text-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - text-state-layer-color: map.get($systems, md-sys-color, tertiary), - tonal-container-color: map.get($systems, md-sys-color, tertiary-container), - tonal-label-text-color: map.get($systems, md-sys-color, on-tertiary-container), - tonal-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-tertiary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - tonal-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container), + color: ( + filled-container-color: map.get($system, primary), + filled-disabled-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + filled-disabled-label-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + filled-disabled-state-layer-color: map.get($system, on-surface-variant), + filled-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + filled-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + filled-label-text-color: map.get($system, on-primary), + filled-pressed-state-layer-opacity:map.get($system, pressed-state-layer-opacity), + filled-ripple-color: m3-utils.color-with-opacity( + map.get($system, on-primary), map.get($system, pressed-state-layer-opacity)), + filled-state-layer-color: map.get($system, on-primary), + outlined-disabled-label-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + outlined-disabled-outline-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + outlined-disabled-state-layer-color: map.get($system, on-surface-variant), + outlined-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + outlined-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + outlined-label-text-color: map.get($system, primary), + outlined-outline-color: map.get($system, outline), + outlined-pressed-state-layer-opacity:map.get($system, pressed-state-layer-opacity), + outlined-ripple-color: m3-utils.color-with-opacity( + map.get($system, primary), map.get($system, pressed-state-layer-opacity)), + outlined-state-layer-color: map.get($system, primary), + protected-container-color: map.get($system, surface), + protected-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level1)), + protected-disabled-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + protected-disabled-container-elevation-shadow: + elevation.get-box-shadow(map.get($system, level0)), + protected-disabled-label-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + protected-disabled-state-layer-color: map.get($system, on-surface-variant), + protected-focus-container-elevation-shadow: + elevation.get-box-shadow(map.get($system, level1)), + protected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + protected-hover-container-elevation-shadow: + elevation.get-box-shadow(map.get($system, level2)), + protected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + protected-label-text-color: map.get($system, primary), + protected-pressed-container-elevation-shadow: + elevation.get-box-shadow(map.get($system, level1)), + protected-pressed-state-layer-opacity:map.get($system, pressed-state-layer-opacity), + protected-ripple-color: m3-utils.color-with-opacity( + map.get($system, primary), map.get($system, pressed-state-layer-opacity)), + protected-state-layer-color: map.get($system, primary), + text-disabled-label-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + text-disabled-state-layer-color: map.get($system, on-surface-variant), + text-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + text-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + text-label-text-color: map.get($system, primary), + text-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + text-ripple-color: m3-utils.color-with-opacity( + map.get($system, primary), map.get($system, pressed-state-layer-opacity)), + text-state-layer-color: map.get($system, primary), + tonal-container-color: map.get($system, secondary-container), + tonal-disabled-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + tonal-disabled-label-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + tonal-disabled-state-layer-color: map.get($system, on-surface-variant), + tonal-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + tonal-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + tonal-label-text-color: map.get($system, on-secondary-container), + tonal-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + tonal-ripple-color: m3-utils.color-with-opacity( + map.get($system, on-secondary-container), map.get($system, pressed-state-layer-opacity)), + tonal-state-layer-color: map.get($system, on-secondary-container), ), - error: ( - filled-container-color: map.get($systems, md-sys-color, error), - filled-label-text-color: map.get($systems, md-sys-color, on-error), - filled-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-error), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - filled-state-layer-color: map.get($systems, md-sys-color, on-error), - outlined-label-text-color: map.get($systems, md-sys-color, error), - outlined-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - outlined-state-layer-color: map.get($systems, md-sys-color, error), - protected-label-text-color: map.get($systems, md-sys-color, error), - protected-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - protected-state-layer-color: map.get($systems, md-sys-color, error), - text-label-text-color: map.get($systems, md-sys-color, error), - text-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - text-state-layer-color: map.get($systems, md-sys-color, error), - tonal-container-color: map.get($systems, md-sys-color, error-container), - tonal-label-text-color: map.get($systems, md-sys-color, on-error-container), - tonal-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-error-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - tonal-state-layer-color: map.get($systems, md-sys-color, on-error-container), - ) - ); - - $elevation-tokens: ( - protected-container-elevation-shadow, - protected-disabled-container-elevation-shadow, - protected-focus-container-elevation-shadow, - protected-hover-container-elevation-shadow, - protected-pressed-container-elevation-shadow, + typography: ( + filled-label-text-font: map.get($system, label-large-font), + filled-label-text-size: map.get($system, label-large-size), + filled-label-text-tracking: map.get($system, label-large-tracking), + filled-label-text-weight: map.get($system, label-large-weight), + outlined-label-text-font: map.get($system, label-large-font), + outlined-label-text-size: map.get($system, label-large-size), + outlined-label-text-tracking: map.get($system, label-large-tracking), + outlined-label-text-weight: map.get($system, label-large-weight), + protected-label-text-font: map.get($system, label-large-font), + protected-label-text-size: map.get($system, label-large-size), + protected-label-text-tracking: map.get($system, label-large-tracking), + protected-label-text-weight: map.get($system, label-large-weight), + text-label-text-font: map.get($system, label-large-font), + text-label-text-size: map.get($system, label-large-size), + text-label-text-tracking: map.get($system, label-large-tracking), + text-label-text-weight: map.get($system, label-large-weight), + tonal-label-text-font: map.get($system, label-large-font), + tonal-label-text-size: map.get($system, label-large-size), + tonal-label-text-tracking: map.get($system, label-large-tracking), + tonal-label-text-weight: map.get($system, label-large-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @each $token in $elevation-tokens { - $elevation: map.get($tokens, $token); - - @if ($elevation != null) { - $tokens: map.set($tokens, $token, elevation.get-box-shadow($elevation)); - } - } - - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/button/_m3-fab.scss b/src/material/button/_m3-fab.scss index 0581f621cee8..0a9f514febec 100644 --- a/src/material/button/_m3-fab.scss +++ b/src/material/button/_m3-fab.scss @@ -1,157 +1,78 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/style/elevation'; @use '../core/theming/theming'; -@use '../core/theming/inspection'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, fab); /// Generates custom tokens for the mat-fab. -/// @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-fab -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-color: map.get($systems, md-sys-color, primary-container), - container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - container-shape: map.get($systems, md-sys-shape, corner-large), - disabled-state-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - disabled-state-foreground-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - extended-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - extended-container-height: if($exclude-hardcoded, null, 56px), - extended-container-shape: map.get($systems, md-sys-shape, corner-large), - extended-focus-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - extended-hover-container-elevation-shadow: map.get($systems, md-sys-elevation, level4), - extended-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - extended-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - extended-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - extended-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - extended-pressed-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - focus-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - foreground-color: map.get($systems, md-sys-color, on-primary-container), - hover-container-elevation-shadow: map.get($systems, md-sys-elevation, level4), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - pressed-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-primary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-container-color: map.get($systems, md-sys-color, primary-container), - small-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - small-container-shape: map.get($systems, md-sys-shape, corner-medium), - small-disabled-state-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - small-disabled-state-foreground-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - small-focus-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - small-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - small-foreground-color: map.get($systems, md-sys-color, on-primary-container), - small-hover-container-elevation-shadow: map.get($systems, md-sys-elevation, level4), - small-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - small-pressed-container-elevation-shadow: map.get($systems, md-sys-elevation, level3), - small-pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity), - small-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-primary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-state-layer-color: map.get($systems, md-sys-color, on-primary-container), - state-layer-color: map.get($systems, md-sys-color, on-primary-container), - ); - - $elevation-tokens: ( - container-elevation-shadow, - focus-container-elevation-shadow, - hover-container-elevation-shadow, - pressed-container-elevation-shadow, - extended-container-elevation-shadow, - extended-focus-container-elevation-shadow, - extended-hover-container-elevation-shadow, - extended-pressed-container-elevation-shadow, - small-container-elevation-shadow, - small-focus-container-elevation-shadow, - small-hover-container-elevation-shadow, - small-pressed-container-elevation-shadow, - ); - - @each $token in $elevation-tokens { - $elevation: map.get($tokens, $token); - - @if ($elevation != null) { - $tokens: map.set($tokens, $token, elevation.get-box-shadow($elevation)); - } +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); } - $variant-tokens: ( - // Color variants - primary: (), // Default, no overrides needed. - secondary: ( - container-color: map.get($systems, md-sys-color, secondary-container), - container-shape: map.get($systems, md-sys-shape, corner-large), - extended-container-height: if($exclude-hardcoded, null, 56px), - extended-container-shape: map.get($systems, md-sys-shape, corner-large), - extended-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - extended-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - extended-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - extended-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - foreground-color: map.get($systems, md-sys-color, on-secondary-container), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-secondary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-container-color: map.get($systems, md-sys-color, secondary-container), - small-container-shape: map.get($systems, md-sys-shape, corner-medium), - small-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - small-foreground-color: map.get($systems, md-sys-color, on-secondary-container), - small-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - small-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - small-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-secondary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-state-layer-color: map.get($systems, md-sys-color, on-secondary-container), - state-layer-color: map.get($systems, md-sys-color, on-secondary-container), + $tokens: ( + base: ( + container-shape: map.get($system, corner-large), + extended-container-height: 56px, + extended-container-shape: map.get($system, corner-large), + small-container-shape: map.get($system, corner-medium), + ), + color: ( + container-color: map.get($system, primary-container), + container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + disabled-state-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + disabled-state-foreground-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + extended-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + extended-focus-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + extended-hover-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level4)), + extended-pressed-container-elevation-shadow: map.get($system, level3), + focus-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + foreground-color: map.get($system, on-primary-container), + hover-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level4)), + hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + pressed-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + ripple-color: m3-utils.color-with-opacity( + map.get($system, on-primary-container), map.get($system, pressed-state-layer-opacity)), + small-container-color: map.get($system, primary-container), + small-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + small-disabled-state-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + small-disabled-state-foreground-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + small-focus-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + small-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + small-foreground-color: map.get($system, on-primary-container), + small-hover-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level4)), + small-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + small-pressed-container-elevation-shadow: elevation.get-box-shadow(map.get($system, level3)), + small-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + small-ripple-color: m3-utils.color-with-opacity( + map.get($system, on-primary-container), map.get($system, pressed-state-layer-opacity)), + small-state-layer-color: map.get($system, on-primary-container), + state-layer-color: map.get($system, on-primary-container), + ), + typography: ( + extended-label-text-font: map.get($system, label-large-font), + extended-label-text-size: map.get($system, label-large-size), + extended-label-text-tracking: map.get($system, label-large-tracking), + extended-label-text-weight: map.get($system, label-large-weight), ), - tertiary: ( - container-color: map.get($systems, md-sys-color, tertiary-container), - container-shape: map.get($systems, md-sys-shape, corner-large), - extended-container-height: if($exclude-hardcoded, null, 56px), - extended-container-shape: map.get($systems, md-sys-shape, corner-large), - extended-label-text-font: map.get($systems, md-sys-typescale, label-large-font), - extended-label-text-size: map.get($systems, md-sys-typescale, label-large-size), - extended-label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - extended-label-text-weight: map.get($systems, md-sys-typescale, label-large-weight), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - foreground-color: map.get($systems, md-sys-color, on-tertiary-container), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-tertiary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-container-color: map.get($systems, md-sys-color, tertiary-container), - small-container-shape: map.get($systems, md-sys-shape, corner-medium), - small-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - small-foreground-color: map.get($systems, md-sys-color, on-tertiary-container), - small-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - small-ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-tertiary-container), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)), - small-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container), - state-layer-color: map.get($systems, md-sys-color, on-tertiary-container), - ) ); - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); + @return $tokens; } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/button/_m3-icon-button.scss b/src/material/button/_m3-icon-button.scss index 18747ac78c7d..73c03d049396 100644 --- a/src/material/button/_m3-icon-button.scss +++ b/src/material/button/_m3-icon-button.scss @@ -1,7 +1,6 @@ @use 'sass:map'; @use 'sass:list'; @use '../core/tokens/m3-utils'; -@use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -13,64 +12,37 @@ $prefix: (mat, icon-button); /// @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-icon-button -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface-variant), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) - ), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity), - disabled-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - icon-size: if($exclude-hardcoded, null, 24px), - icon-color: map.get($systems, md-sys-color, on-surface-variant), - ); +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - primary: ( - state-layer-color: map.get($systems, md-sys-color, primary), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) - ), - icon-color: map.get($systems, md-sys-color, primary) - ), - secondary: ( - state-layer-color: map.get($systems, md-sys-color, secondary), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) - ), - icon-color: map.get($systems, md-sys-color, secondary) + $tokens: ( + base: ( + icon-size: 24px, ), - tertiary: ( - state-layer-color: map.get($systems, md-sys-color, tertiary), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) - ), - icon-color: map.get($systems, md-sys-color, tertiary) + color: ( + disabled-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-state-layer-color: map.get($system, on-surface-variant), + focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + icon-color: map.get($system, on-surface-variant), + pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + ripple-color: m3-utils.color-with-opacity( + map.get($system, on-surface-variant), map.get($system, pressed-state-layer-opacity)), + state-layer-color: map.get($system, on-surface-variant), ), - error: ( - state-layer-color: map.get($systems, md-sys-color, error), - ripple-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), - $alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity) - ), - icon-color: map.get($systems, md-sys-color, error) - ) + typography: (), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); + @return $tokens; } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -5); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -5); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/button/button.scss b/src/material/button/button.scss index baa1a7562b8b..244168619bee 100644 --- a/src/material/button/button.scss +++ b/src/material/button/button.scss @@ -4,6 +4,12 @@ @use '../core/tokens/token-utils'; @use '../core/focus-indicators/private' as focus-indicators-private; @use './m2-button'; +@use './m3-button'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-button.$prefix; +$token-slots: m2-button.get-token-slots(); +$fallbacks: m3-button.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-button-base { text-decoration: none; @@ -53,7 +59,7 @@ } } -@include token-utils.use-tokens(m2-button.$prefix, m2-button.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-button { padding: 0 #{token-utils.slot(text-horizontal-padding, true)}; height: token-utils.slot(text-container-height); diff --git a/src/material/button/fab.scss b/src/material/button/fab.scss index 327532994e5e..cf861f2bf9b2 100644 --- a/src/material/button/fab.scss +++ b/src/material/button/fab.scss @@ -4,6 +4,12 @@ @use '../core/style/vendor-prefixes'; @use '../core/focus-indicators/private' as focus-indicators-private; @use './m2-fab'; +@use './m3-fab'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-fab.$prefix; +$token-slots: m2-fab.get-token-slots(); +$fallbacks: m3-fab.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-fab-base { @include vendor-prefixes.user-select(none); @@ -93,7 +99,7 @@ } } -@include token-utils.use-tokens(m2-fab.$prefix, m2-fab.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-fab { background-color: token-utils.slot(container-color); border-radius: token-utils.slot(container-shape); diff --git a/src/material/button/icon-button.scss b/src/material/button/icon-button.scss index 08cac53d494c..0fb2e7a2a640 100644 --- a/src/material/button/icon-button.scss +++ b/src/material/button/icon-button.scss @@ -3,11 +3,14 @@ @use '../core/tokens/token-utils'; @use './button-base'; @use './m2-icon-button'; +@use './m3-icon-button'; +@use '../core/tokens/m3-system'; $token-prefix: m2-icon-button.$prefix; $token-slots: m2-icon-button.get-token-slots(); +$fallbacks: m3-icon-button.get-tokens(m3-system.$theme-with-system-vars); -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-icon-button { @include vendor-prefixes.user-select(none); display: inline-block; diff --git a/src/material/card/_card-theme.scss b/src/material/card/_card-theme.scss index d0453b1f647c..2f6052702cc7 100644 --- a/src/material/card/_card-theme.scss +++ b/src/material/card/_card-theme.scss @@ -2,14 +2,16 @@ @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 './m2-card'; +@use './m3-card'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-card.$prefix, + map.get(m3-card.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -22,7 +24,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-card.$prefix, + map.get(m3-card.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,7 +39,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-card.$prefix, + map.get(m3-card.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -48,7 +54,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-card.$prefix, + map.get(m3-card.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -76,7 +84,10 @@ @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)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -91,15 +102,3 @@ } } } - -@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( - m2-card.$prefix, - map.get($tokens, m2-card.$prefix) - ); - } -} diff --git a/src/material/card/_m3-card.scss b/src/material/card/_m3-card.scss index cc6a4deabfce..6690ff612468 100644 --- a/src/material/card/_m3-card.scss +++ b/src/material/card/_m3-card.scss @@ -1,5 +1,4 @@ @use 'sass:map'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/style/elevation'; @@ -7,42 +6,38 @@ $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( - m3-utils.generate-typography-tokens($systems, title-text, title-large), - m3-utils.generate-typography-tokens($systems, subtitle-text, title-medium), - ( - subtitle-text-color: map.get($systems, md-sys-color, on-surface), - elevated-container-color: map.get($systems, md-sys-color, surface-container-low), - elevated-container-elevation: map.get($systems, md-sys-elevation, level1), - elevated-container-shape: map.get($systems, md-sys-shape, corner-medium), - outlined-container-color: map.get($systems, md-sys-color, surface), - outlined-container-elevation: map.get($systems, md-sys-elevation, level0), - outlined-container-shape: map.get($systems, md-sys-shape, corner-medium), - outlined-outline-color: map.get($systems, md-sys-color, outline-variant), - outlined-outline-width: if($exclude-hardcoded, null, 1px), - filled-container-color: map.get($systems, md-sys-color, surface-container-highest), - filled-container-elevation: map.get($systems, md-sys-elevation, level0), - filled-container-shape: map.get($systems, md-sys-shape, corner-medium), +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + @return ( + base: ( + elevated-container-shape: map.get($system, corner-medium), + filled-container-shape: map.get($system, corner-medium), + outlined-container-shape: map.get($system, corner-medium), + outlined-outline-width: 1px, ), + color: ( + elevated-container-color: map.get($system, surface-container-low), + elevated-container-elevation: elevation.get-box-shadow(map.get($system, level1)), + filled-container-color: map.get($system, surface-container-highest), + filled-container-elevation: elevation.get-box-shadow(map.get($system, level0)), + outlined-container-color: map.get($system, surface), + outlined-container-elevation: elevation.get-box-shadow(map.get($system, level0)), + outlined-outline-color: map.get($system, outline-variant), + subtitle-text-color: map.get($system, on-surface), + ), + typography: ( + subtitle-text-font: map.get($system, subtitle-large-font), + subtitle-text-line-height: map.get($system, subtitle-large-line-height), + subtitle-text-size: map.get($system, subtitle-large-size), + subtitle-text-tracking: map.get($system, subtitle-large-tracking), + subtitle-text-weight: map.get($system, subtitle-large-weight), + title-text-font: map.get($system, title-large-font), + title-text-line-height: map.get($system, title-large-line-height), + title-text-size: map.get($system, title-large-size), + title-text-tracking: map.get($system, title-large-tracking), + title-text-weight: map.get($system, title-large-weight), + ), + density: (), ); - - $elevated-elevation: map.get($tokens, elevated-container-elevation); - @if ($elevated-elevation != null) { - $tokens: map.set($tokens, elevated-container-elevation, - elevation.get-box-shadow($elevated-elevation)); - } - - $outlined-elevation: map.get($tokens, outlined-container-elevation); - @if ($outlined-elevation != null) { - $tokens: map.set($tokens, outlined-container-elevation, - elevation.get-box-shadow($outlined-elevation)); - } - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } diff --git a/src/material/card/card.scss b/src/material/card/card.scss index 7083d28d92af..d64b90b75c9e 100644 --- a/src/material/card/card.scss +++ b/src/material/card/card.scss @@ -1,5 +1,7 @@ @use '../core/tokens/token-utils'; @use './m2-card'; +@use './m3-card'; +@use '../core/tokens/m3-system'; // Size of the `mat-card-header` region custom to Angular Material. $mat-card-header-size: 40px !default; @@ -7,7 +9,11 @@ $mat-card-header-size: 40px !default; // Default padding for text content within a card. $mat-card-default-padding: 16px !default; -@include token-utils.use-tokens(m2-card.$prefix, m2-card.get-token-slots()) { +$token-prefix: m2-card.$prefix; +$token-slots: m2-card.get-token-slots(); +$fallbacks: m3-card.get-tokens(m3-system.$theme-with-system-vars); + +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-card { display: flex; flex-direction: column; @@ -52,7 +58,7 @@ $mat-card-default-padding: 16px !default; } .mat-mdc-card-filled { - @include token-utils.use-tokens(m2-card.$prefix, m2-card.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(filled-container-color); border-radius: token-utils.slot(filled-container-shape); box-shadow: token-utils.slot(filled-container-elevation); @@ -92,7 +98,7 @@ $mat-card-default-padding: 16px !default; } // Add slots for custom Angular Material card tokens. -@include token-utils.use-tokens(m2-card.$prefix, m2-card.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-card-title { font-family: token-utils.slot(title-text-font); line-height: token-utils.slot(title-text-line-height); diff --git a/src/material/checkbox/_checkbox-common.scss b/src/material/checkbox/_checkbox-common.scss index c28689a07e3c..34b80151e524 100644 --- a/src/material/checkbox/_checkbox-common.scss +++ b/src/material/checkbox/_checkbox-common.scss @@ -1,8 +1,10 @@ @use 'sass:math'; @use '@angular/cdk'; @use './m2-checkbox'; +@use './m3-checkbox'; @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; $_path-length: 29.7833385; $_transition-duration: 90ms; @@ -18,6 +20,7 @@ $_fallback-size: 40px; @mixin checkbox-structure($include-state-layer-styles) { $prefix: m2-checkbox.$prefix; $slots: m2-checkbox.get-token-slots(); + $fallbacks: m3-checkbox.get-tokens(m3-system.$theme-with-system-vars); .mdc-checkbox { display: inline-block; @@ -31,7 +34,7 @@ $_fallback-size: 40px; cursor: pointer; vertical-align: bottom; - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { $layer-size: token-utils.slot(state-layer-size, $fallback: $_fallback-size); padding: calc((#{$layer-size} - #{$_icon-size}) / 2); margin: calc((#{$layer-size} - #{$layer-size}) / 2); @@ -51,7 +54,7 @@ $_fallback-size: 40px; cursor: inherit; z-index: 1; - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { $layer-size: token-utils.slot(state-layer-size, $fallback: $_fallback-size); $offset: calc((#{$layer-size} - #{$layer-size}) / 2); width: $layer-size; @@ -91,7 +94,7 @@ $_fallback-size: 40px; // Force browser to show background-color when using the print function @include vendor-prefixes.color-adjust(exact); - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { $layer-size: token-utils.slot(state-layer-size, $fallback: $_fallback-size); $offset: calc((#{$layer-size} - #{$_icon-size}) / 2); @@ -103,7 +106,7 @@ $_fallback-size: 40px; // These can't be under `.mdc-checkbox__background` because // the selectors will break when the mixin is nested. - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { .mdc-checkbox__native-control:enabled:checked ~ .mdc-checkbox__background, .mdc-checkbox__native-control:enabled:indeterminate ~ .mdc-checkbox__background { border-color: token-utils.slot(selected-icon-color); @@ -174,7 +177,7 @@ $_fallback-size: 40px; opacity: 0; transition: opacity $_transition-duration * 2 $_exit-curve; - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { // Always apply the color since the element becomes `opacity: 0` // when unchecked. This makes the animation look better. color: token-utils.slot(selected-checkmark-color); @@ -185,7 +188,7 @@ $_fallback-size: 40px; } } - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { .mdc-checkbox--disabled { &, &.mat-mdc-checkbox-disabled-interactive { .mdc-checkbox__checkmark { @@ -217,7 +220,7 @@ $_fallback-size: 40px; transition: opacity $_transition-duration $_exit-curve, transform $_transition-duration $_exit-curve; - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { // Always apply the color since the element becomes `opacity: 0` // when unchecked. This makes the animation look better. border-color: token-utils.slot(selected-checkmark-color); @@ -228,7 +231,7 @@ $_fallback-size: 40px; } } - @include token-utils.use-tokens($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots, $fallbacks) { .mdc-checkbox--disabled { &, &.mat-mdc-checkbox-disabled-interactive { .mdc-checkbox__mixedmark { diff --git a/src/material/checkbox/_checkbox-theme.scss b/src/material/checkbox/_checkbox-theme.scss index f22043ff80f1..5b00a7f0651a 100644 --- a/src/material/checkbox/_checkbox-theme.scss +++ b/src/material/checkbox/_checkbox-theme.scss @@ -1,18 +1,20 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-checkbox'; @use './m3-checkbox'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-checkbox. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-checkbox.$prefix, + map.get(m3-checkbox.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -23,12 +25,12 @@ /// Outputs color theme styles for the mat-checkbox. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the checkbox: primary, secondary, tertiary, or -/// error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-checkbox.$prefix, + map.get(m3-checkbox.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -59,7 +61,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-checkbox.$prefix, + map.get(m3-checkbox.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -73,11 +77,10 @@ /// Outputs density theme styles for the mat-checkbox. /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { - $density-scale: inspection.get-theme-density($theme); - @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-checkbox.$prefix, m3-checkbox.get-density-tokens($theme)); + m3-checkbox.$prefix, + map.get(m3-checkbox.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -106,16 +109,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-checkbox. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the checkbox: primary, secondary, tertiary, or -/// error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-checkbox') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -130,15 +131,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-checkbox-tokens: token-utils.get-tokens-for( - $tokens, - m2-checkbox.$prefix, - $options... - ); - @include token-utils.create-token-values(m2-checkbox.$prefix, $mat-checkbox-tokens); -} diff --git a/src/material/checkbox/_m3-checkbox.scss b/src/material/checkbox/_m3-checkbox.scss index fa1acdada71e..3ac2b6ad1b55 100644 --- a/src/material/checkbox/_m3-checkbox.scss +++ b/src/material/checkbox/_m3-checkbox.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,91 +8,57 @@ $prefix: (mat, checkbox); /// Generates custom tokens for mat-checkbox. -/// @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 mat-checkbox -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - disabled-label-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - disabled-selected-checkmark-color: map.get($systems, md-sys-color, surface), - disabled-selected-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - disabled-unselected-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - label-text-color: map.get($systems, md-sys-color, on-surface), - label-text-font: map.get($systems, md-sys-typescale, body-medium-font), - label-text-line-height: map.get($systems, md-sys-typescale, body-medium-line-height), - label-text-size: map.get($systems, md-sys-typescale, body-medium-size), - label-text-tracking: map.get($systems, md-sys-typescale, body-medium-tracking), - label-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - selected-checkmark-color: map.get($systems, md-sys-color, on-primary), - selected-focus-icon-color: map.get($systems, md-sys-color, primary), - selected-focus-state-layer-color: map.get($systems, md-sys-color, primary), - selected-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - selected-hover-icon-color: map.get($systems, md-sys-color, primary), - selected-hover-state-layer-color: map.get($systems, md-sys-color, primary), - selected-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - selected-icon-color: map.get($systems, md-sys-color, primary), - selected-pressed-icon-color: map.get($systems, md-sys-color, primary), - selected-pressed-state-layer-color: map.get($systems, md-sys-color, on-surface), - selected-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - unselected-focus-icon-color: map.get($systems, md-sys-color, on-surface), - unselected-focus-state-layer-color: map.get($systems, md-sys-color, on-surface), - unselected-focus-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - unselected-hover-icon-color: map.get($systems, md-sys-color, on-surface), - unselected-hover-state-layer-color: map.get($systems, md-sys-color, on-surface), - unselected-hover-state-layer-opacity: - map.get($systems, md-sys-state, hover-state-layer-opacity), - unselected-icon-color: map.get($systems, md-sys-color, on-surface-variant), - unselected-pressed-state-layer-color: map.get($systems, md-sys-color, primary), - unselected-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - ); +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - selected-focus-icon-color: map.get($systems, md-sys-color, secondary), - selected-focus-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-hover-icon-color: map.get($systems, md-sys-color, secondary), - selected-hover-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-icon-color: map.get($systems, md-sys-color, secondary), - selected-pressed-icon-color: map.get($systems, md-sys-color, secondary), - unselected-pressed-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-checkmark-color: map.get($systems, md-sys-color, on-secondary), + @return ( + base: ( + selected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + selected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + selected-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + unselected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + unselected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + unselected-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), ), - tertiary: ( - selected-focus-icon-color: map.get($systems, md-sys-color, tertiary), - selected-focus-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-hover-icon-color: map.get($systems, md-sys-color, tertiary), - selected-hover-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-icon-color: map.get($systems, md-sys-color, tertiary), - selected-pressed-icon-color: map.get($systems, md-sys-color, tertiary), - unselected-pressed-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-checkmark-color: map.get($systems, md-sys-color, on-tertiary), + color: ( + disabled-label-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-selected-checkmark-color: map.get($system, surface), + disabled-selected-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-unselected-icon-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + label-text-color: map.get($system, on-surface), + selected-checkmark-color: map.get($system, on-primary), + selected-focus-icon-color: map.get($system, primary), + selected-focus-state-layer-color: map.get($system, primary), + selected-hover-icon-color: map.get($system, primary), + selected-hover-state-layer-color: map.get($system, primary), + selected-icon-color: map.get($system, primary), + selected-pressed-icon-color: map.get($system, primary), + selected-pressed-state-layer-color: map.get($system, on-surface), + unselected-focus-icon-color: map.get($system, on-surface), + unselected-focus-state-layer-color: map.get($system, on-surface), + unselected-hover-icon-color: map.get($system, on-surface), + unselected-hover-state-layer-color: map.get($system, on-surface), + unselected-icon-color: map.get($system, on-surface-variant), + unselected-pressed-state-layer-color: map.get($system, primary), ), - error: ( - selected-focus-icon-color: map.get($systems, md-sys-color, error), - selected-focus-state-layer-color: map.get($systems, md-sys-color, error), - selected-hover-icon-color: map.get($systems, md-sys-color, error), - selected-hover-state-layer-color: map.get($systems, md-sys-color, error), - selected-icon-color: map.get($systems, md-sys-color, error), - selected-pressed-icon-color: map.get($systems, md-sys-color, error), - unselected-pressed-state-layer-color: map.get($systems, md-sys-color, error), - selected-checkmark-color: map.get($systems, md-sys-color, on-error), - ) + typography: ( + label-text-font: map.get($system, body-medium-font), + label-text-line-height: map.get($system, body-medium-line-height), + label-text-size: map.get($system, body-medium-size), + label-text-tracking: map.get($system, body-medium-tracking), + label-text-weight: map.get($system, body-medium-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/checkbox/checkbox.scss b/src/material/checkbox/checkbox.scss index 10674897aa71..c874c390619d 100644 --- a/src/material/checkbox/checkbox.scss +++ b/src/material/checkbox/checkbox.scss @@ -1,12 +1,15 @@ @use '../core/style/layout-common'; @use './m2-checkbox'; +@use './m3-checkbox'; @use '../core/tokens/token-utils'; @use './checkbox-common'; +@use '../core/tokens/m3-system'; @include checkbox-common.checkbox-structure(true); $token-prefix: m2-checkbox.$prefix; $token-slots: m2-checkbox.get-token-slots(); +$fallbacks: m3-checkbox.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-checkbox { // The host node defaults to `display: inline`, we have to change it in order for margins to work. @@ -25,7 +28,7 @@ $token-slots: m2-checkbox.get-token-slots(); } .mat-internal-form-field { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(label-text-color); font-family: token-utils.slot(label-text-font); line-height: token-utils.slot(label-text-line-height); @@ -47,7 +50,7 @@ $token-slots: m2-checkbox.get-token-slots(); label { cursor: default; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(disabled-label-color); } } @@ -95,7 +98,7 @@ $token-slots: m2-checkbox.get-token-slots(); width: 48px; transform: translate(-50%, -50%); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { display: token-utils.slot(touch-target-display); } } diff --git a/src/material/chips/_chips-theme.scss b/src/material/chips/_chips-theme.scss index 07b8c6f61641..c6bd16a74876 100644 --- a/src/material/chips/_chips-theme.scss +++ b/src/material/chips/_chips-theme.scss @@ -4,15 +4,17 @@ @use '../core/tokens/token-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-chips. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-chip.$prefix, + map.get(m3-chip.get-tokens($theme), base)); } @else { .mat-mdc-standard-chip { @include token-utils.create-token-values-mixed( @@ -23,12 +25,12 @@ /// Outputs color theme styles for the mat-chips. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the selected chip: primary, secondary, tertiary, -/// or error (If not specified, default secondary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-chip.$prefix, + map.get(m3-chip.get-tokens($theme, $color-variant), color)); } @else { .mat-mdc-standard-chip { @include token-utils.create-token-values-mixed( @@ -59,7 +61,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-chip.$prefix, + map.get(m3-chip.get-tokens($theme), typography)); } @else { .mat-mdc-standard-chip { @include token-utils.create-token-values-mixed( @@ -73,7 +77,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-chip.$prefix, m3-chip.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-chip.$prefix, + map.get(m3-chip.get-tokens($theme), density)); } @else { .mat-mdc-chip.mat-mdc-standard-chip { @include token-utils.create-token-values-mixed( @@ -101,16 +107,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-chips. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the selected chip: primary, secondary, tertiary, -/// or error (If not specified, default secondary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-chips') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -125,11 +129,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-chip-tokens: token-utils.get-tokens-for($tokens, m2-chip.$prefix, $options...); - @include token-utils.create-token-values(m2-chip.$prefix, $mat-chip-tokens); -} diff --git a/src/material/chips/_m3-chip.scss b/src/material/chips/_m3-chip.scss index fb1344099c46..091d2760eb5c 100644 --- a/src/material/chips/_m3-chip.scss +++ b/src/material/chips/_m3-chip.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,118 +8,72 @@ $prefix: (mat, chip); /// Generates custom tokens for the mat-chip. -/// @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-chip -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - // MDC has a chip component, but they seem to have made up the tokens rather than using ones - // generated from the token database, therefore we need a custom token function for it. - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, label-text, label-large), - ( - disabled-container-opacity: m3-utils.hardcode(1, $exclude-hardcoded), - selected-trailing-icon-color: map.get($systems, md-sys-color, on-secondary-container), - selected-disabled-trailing-icon-color: map.get($systems, md-sys-color, on-surface), - trailing-action-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - selected-trailing-action-state-layer-color: - map.get($systems, md-sys-color, on-secondary-container), - trailing-action-hover-state-layer-opacity: - map.get($systems, md-sys-state, hover-state-layer-opacity), - trailing-action-focus-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - trailing-action-opacity: m3-utils.hardcode(1, $exclude-hardcoded), - trailing-action-focus-opacity: m3-utils.hardcode(1, $exclude-hardcoded), - container-shape-radius: m3-utils.hardcode(8px, $exclude-hardcoded), - with-avatar-avatar-size: m3-utils.hardcode(24px, $exclude-hardcoded), - with-avatar-avatar-shape-radius: m3-utils.hardcode(24px, $exclude-hardcoded), - label-text-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-label-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38, - ), - with-icon-icon-size: m3-utils.hardcode(18px, $exclude-hardcoded), - with-icon-icon-color: map.get($systems, md-sys-color, on-surface-variant), - with-icon-disabled-icon-color: map.get($systems, md-sys-color, on-surface), - with-icon-selected-icon-color: map.get($systems, md-sys-color, on-secondary-container), - with-trailing-icon-trailing-icon-color: map.get($systems, md-sys-color, on-surface-variant), - with-trailing-icon-disabled-trailing-icon-color: - map.get($systems, md-sys-color, on-surface), - focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - focus-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - outline-width: m3-utils.hardcode(1px, $exclude-hardcoded), - outline-color: map.get($systems, md-sys-color, outline), - disabled-outline-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.12, - ), - focus-outline-color: map.get($systems, md-sys-color, on-surface-variant), - hover-state-layer-color: map.get($systems, md-sys-color, on-surface-variant), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - with-avatar-disabled-avatar-opacity: m3-utils.hardcode(0.38, $exclude-hardcoded), - elevated-selected-container-color: map.get($systems, md-sys-color, secondary-container), - // In the M3 tokens this is a `surface` color, but in the MDC implementation its - // never being emitted. We emit `transparent` so consumers override the color. - elevated-container-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - flat-selected-outline-width: m3-utils.hardcode(0, $exclude-hardcoded), - selected-label-text-color: map.get($systems, md-sys-color, on-secondary-container), - flat-disabled-selected-container-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.12, - ), - selected-hover-state-layer-color: map.get($systems, md-sys-color, on-secondary-container), - selected-hover-state-layer-opacity: - map.get($systems, md-sys-state, hover-state-layer-opacity), - selected-focus-state-layer-color: map.get($systems, md-sys-color, on-secondary-container), - selected-focus-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - with-icon-disabled-icon-opacity: m3-utils.hardcode(0.38, $exclude-hardcoded), - with-trailing-icon-disabled-trailing-icon-opacity: - m3-utils.hardcode(0.38, $exclude-hardcoded), - ), - ); +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, secondary, $color-variant); + } - $variant-tokens: ( - // Color variants: - primary: ( - selected-trailing-icon-color: map.get($systems, md-sys-color, on-primary-container), - selected-trailing-action-state-layer-color: - map.get($systems, md-sys-color, on-primary-container), - with-icon-selected-icon-color: map.get($systems, md-sys-color, on-primary-container), - elevated-selected-container-color: map.get($systems, md-sys-color, primary-container), - selected-label-text-color: map.get($systems, md-sys-color, on-primary-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, on-primary-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, on-primary-container), + @return ( + base: ( + container-shape-radius: 8px, + disabled-container-opacity: 1, + elevated-container-color: transparent, // surface in M3, but not emitted in MDC + flat-selected-outline-width: 0, + outline-width: 1px, + trailing-action-focus-opacity: 1, + trailing-action-opacity: 1, + with-avatar-avatar-shape-radius: 24px, + with-avatar-avatar-size: 24px, + with-avatar-disabled-avatar-opacity: 0.38, + with-icon-disabled-icon-opacity: 0.38, + with-icon-icon-size: 18px, + with-trailing-icon-disabled-trailing-icon-opacity: 0.38, ), - secondary: (), // Default, no overrides needed. - tertiary: ( - selected-trailing-icon-color: map.get($systems, md-sys-color, on-tertiary-container), - selected-trailing-action-state-layer-color: - map.get($systems, md-sys-color, on-tertiary-container), - with-icon-selected-icon-color: map.get($systems, md-sys-color, on-tertiary-container), - elevated-selected-container-color: map.get($systems, md-sys-color, tertiary-container), - selected-label-text-color: map.get($systems, md-sys-color, on-tertiary-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, on-tertiary-container), + color: ( + disabled-label-text-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-outline-color: m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + elevated-selected-container-color: map.get($system, secondary-container), + flat-disabled-selected-container-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + focus-outline-color: map.get($system, on-surface-variant), + focus-state-layer-color: map.get($system, on-surface-variant), + focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + hover-state-layer-color: map.get($system, on-surface-variant), + hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + label-text-color: map.get($system, on-surface-variant), + outline-color: map.get($system, outline), + selected-disabled-trailing-icon-color: map.get($system, on-surface), + selected-focus-state-layer-color: map.get($system, on-secondary-container), + selected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + selected-hover-state-layer-color: map.get($system, on-secondary-container), + selected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + selected-label-text-color: map.get($system, on-secondary-container), + selected-trailing-action-state-layer-color: map.get($system, on-secondary-container), + selected-trailing-icon-color: map.get($system, on-secondary-container), + trailing-action-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + trailing-action-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + trailing-action-state-layer-color: map.get($system, on-surface-variant), + with-icon-disabled-icon-color: map.get($system, on-surface), + with-icon-icon-color: map.get($system, on-surface-variant), + with-icon-selected-icon-color: map.get($system, on-secondary-container), + with-trailing-icon-disabled-trailing-icon-color:map.get($system, on-surface), + with-trailing-icon-trailing-icon-color: map.get($system, on-surface-variant), ), - error: ( - selected-trailing-icon-color: map.get($systems, md-sys-color, on-error-container), - selected-trailing-action-state-layer-color: - map.get($systems, md-sys-color, on-error-container), - with-icon-selected-icon-color: map.get($systems, md-sys-color, on-error-container), - elevated-selected-container-color: map.get($systems, md-sys-color, error-container), - selected-label-text-color: map.get($systems, md-sys-color, on-error-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, on-error-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, on-error-container), - ) + typography: ( + label-text-font: map.get($system, label-large-font), + label-text-line-height: map.get($system, label-large-line-height), + label-text-size: map.get($system, label-large-size), + label-text-tracking: map.get($system, label-large-tracking), + label-text-weight: map.get($system, label-large-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -2); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -2); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/chips/chip.scss b/src/material/chips/chip.scss index d29ac049f32d..0108a8d5e200 100644 --- a/src/material/chips/chip.scss +++ b/src/material/chips/chip.scss @@ -4,6 +4,8 @@ @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use './m2-chip'; +@use './m3-chip'; +@use '../core/tokens/m3-system'; $_checkmark-size: 20px; $_trailing-icon-size: 18px; @@ -15,6 +17,7 @@ $_avatar-trailing-padding: 8px; $token-prefix: m2-chip.$prefix; $token-slots: m2-chip.get-token-slots(); +$fallbacks: m3-chip.get-tokens(m3-system.$theme-with-system-vars); .mdc-evolution-chip, .mdc-evolution-chip__cell, @@ -77,7 +80,7 @@ $token-slots: m2-chip.get-token-slots(); white-space: inherit; overflow-x: hidden; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip &::before { border-width: token-utils.slot(outline-width); border-radius: token-utils.slot(container-shape-radius); @@ -180,7 +183,7 @@ $token-slots: m2-chip.get-token-slots(); position: relative; overflow: visible; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip:not(.mdc-evolution-chip--disabled) & { color: token-utils.slot(with-trailing-icon-trailing-icon-color); } @@ -223,7 +226,7 @@ $token-slots: m2-chip.get-token-slots(); text-overflow: ellipsis; overflow: hidden; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip & { font-family: token-utils.slot(label-text-font); line-height: token-utils.slot(label-text-line-height); @@ -256,7 +259,7 @@ $token-slots: m2-chip.get-token-slots(); position: relative; flex: 1 0 auto; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip & { width: token-utils.slot(with-avatar-avatar-size); height: token-utils.slot(with-avatar-avatar-size); @@ -316,7 +319,7 @@ $token-slots: m2-chip.get-token-slots(); height: $_checkmark-size; width: $_checkmark-size; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip:not(.mdc-evolution-chip--disabled) & { color: token-utils.slot(with-icon-selected-icon-color); } @@ -372,7 +375,7 @@ $token-slots: m2-chip.get-token-slots(); } $disabled-icon-opacity: null; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $disabled-icon-opacity: token-utils.slot(with-trailing-icon-disabled-trailing-icon-opacity); } @@ -380,7 +383,7 @@ $token-slots: m2-chip.get-token-slots(); // If the trailing icon is a chip-remove button, we have to factor in the trailing action // opacity as well as the disabled opacity. .mdc-evolution-chip--disabled &.mat-mdc-chip-remove { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $action-opacity: token-utils.slot(trailing-action-opacity); opacity: calc(#{$action-opacity} * #{$disabled-icon-opacity}); @@ -393,7 +396,7 @@ $token-slots: m2-chip.get-token-slots(); } .mat-mdc-standard-chip { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-radius: token-utils.slot(container-shape-radius); height: token-utils.slot(container-height); @@ -420,7 +423,7 @@ $token-slots: m2-chip.get-token-slots(); } .mdc-evolution-chip__icon--primary { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-standard-chip & { border-radius: token-utils.slot(with-avatar-avatar-shape-radius); width: token-utils.slot(with-icon-icon-size); @@ -448,7 +451,7 @@ $token-slots: m2-chip.get-token-slots(); // that we don't re-implement ourselves below. // TODO(crisbeto): with some future refactors we may be able to clean this up. .mat-mdc-chip-highlighted { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $highlighted-remapped-tokens: ( with-icon-icon-color: with-icon-selected-icon-color, elevated-container-color: elevated-selected-container-color, @@ -463,7 +466,7 @@ $token-slots: m2-chip.get-token-slots(); } // Add additional slots for the MDC chip tokens, needed in Angular Material. -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-chip-focus-overlay { background: token-utils.slot(focus-state-layer-color); @@ -508,7 +511,7 @@ $token-slots: m2-chip.get-token-slots(); } } -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // Historically, MDC did not support disabled chips, so we needed our own disabled styles. // Now that MDC supports disabled styles, we should switch to using theirs. .mat-mdc-standard-chip { diff --git a/src/material/core/_core-theme.scss b/src/material/core/_core-theme.scss index aace526523e1..c742c6b6510f 100644 --- a/src/material/core/_core-theme.scss +++ b/src/material/core/_core-theme.scss @@ -1,6 +1,5 @@ @use './theming/theming'; @use './theming/inspection'; -@use './theming/validation'; @use './ripple/ripple-theme'; @use './option/option-theme'; @use './option/optgroup-theme'; @@ -9,14 +8,30 @@ @use './typography/typography'; @use './tokens/token-utils'; @use './m2-app'; +@use './m3-app'; @use 'ripple/m2-ripple'; +@use 'ripple/m3-ripple'; @use 'option/m2-option'; +@use 'option/m3-option'; @use 'option/m2-optgroup'; +@use 'option/m3-optgroup'; @use 'selection/pseudo-checkbox/m2-pseudo-checkbox'; +@use 'sass:map'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-app.$prefix, + map.get(m3-app.get-tokens($theme), base)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), base)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), base)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), base)); } @else { @include ripple-theme.base($theme); @include option-theme.base($theme); @@ -31,7 +46,18 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-app.$prefix, + map.get(m3-app.get-tokens($theme), color)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), color)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), color)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), color)); } @else { @include ripple-theme.color($theme); @include option-theme.color($theme); @@ -46,7 +72,18 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-app.$prefix, + map.get(m3-app.get-tokens($theme), typography)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), typography)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), typography)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), typography)); } @else { @include option-theme.typography($theme); @include optgroup-theme.typography($theme); @@ -57,7 +94,18 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-app.$prefix, + map.get(m3-app.get-tokens($theme), density)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), density)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), density)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), density)); } @else { @include option-theme.density($theme); @include optgroup-theme.density($theme); @@ -91,13 +139,16 @@ } // Mixin that renders all of the core styles that depend on the theme. -@mixin theme($theme, $options...) { +@mixin theme($theme) { // Wrap the sub-theme includes in the duplicate theme styles mixin. This ensures that // there won't be multiple warnings. e.g. if `mat-core-theme` reports a warning, then // the imported themes (such as `mat-ripple-theme`) should not report again. @include theming.private-check-duplicate-theme-styles($theme, 'mat-core') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -112,31 +163,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-app-tokens: token-utils.get-tokens-for($tokens, m2-app.$prefix, $options...); - $mat-ripple-tokens: token-utils.get-tokens-for($tokens, m2-ripple.$prefix, $options...); - $mat-option-tokens: token-utils.get-tokens-for($tokens, m2-option.$prefix, $options...); - $mat-optgroup-tokens: token-utils.get-tokens-for( - $tokens, - m2-optgroup.$prefix, - $options... - ); - $mat-pseudo-checkbox-tokens: token-utils.get-tokens-for( - $tokens, - m2-pseudo-checkbox.$prefix, - $options... - ); - - @include token-utils.create-token-values(m2-app.$prefix, $mat-app-tokens); - @include token-utils.create-token-values(m2-ripple.$prefix, $mat-ripple-tokens); - @include token-utils.create-token-values(m2-option.$prefix, $mat-option-tokens); - @include token-utils.create-token-values(m2-optgroup.$prefix, $mat-optgroup-tokens); - @include token-utils.create-token-values( - m2-pseudo-checkbox.$prefix, - $mat-pseudo-checkbox-tokens - ); -} diff --git a/src/material/core/_core.scss b/src/material/core/_core.scss index c864699c7308..6e8f97f87f8e 100644 --- a/src/material/core/_core.scss +++ b/src/material/core/_core.scss @@ -1,6 +1,12 @@ @use './m2-app'; +@use './m3-app'; @use './tokens/token-utils'; @use './style/elevation'; +@use './tokens/m3-system'; + +$token-prefix: m2-app.$prefix; +$token-slots: m2-app.get-token-slots(); +$fallbacks: m3-app.get-tokens(m3-system.$theme-with-system-vars); /// @deprecated This mixin is a no-op and is going to be removed in v21. @mixin core() {} @@ -20,7 +26,7 @@ // user's content isn't inside of a `mat-sidenav-container`. @at-root { // Note: we need to emit fallback values here to avoid errors in internal builds. - @include token-utils.use-tokens(m2-app.$prefix, m2-app.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-app-background { background-color: token-utils.slot(background-color, transparent); color: token-utils.slot(text-color, inherit); @@ -35,7 +41,7 @@ // Material Design specification. @mixin elevation-classes() { @at-root { - @include token-utils.use-tokens(m2-app.$prefix, m2-app.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // Provides external CSS classes for each elevation value. Each CSS class is formatted as // `mat-elevation-z$z-value` where `$z-value` corresponds to the z-space to which the element // is elevated. diff --git a/src/material/core/_m3-app.scss b/src/material/core/_m3-app.scss index b070ad582ec4..961daea111fa 100644 --- a/src/material/core/_m3-app.scss +++ b/src/material/core/_m3-app.scss @@ -1,5 +1,4 @@ @use 'sass:map'; -@use 'sass:meta'; @use './style/elevation'; @use './tokens/m3-utils'; @@ -7,25 +6,41 @@ $prefix: (mat, app); /// Generates custom tokens for the app. -/// @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 app -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - background-color: map.get($systems, md-sys-color, background), - text-color: map.get($systems, md-sys-color, on-background), - ); - - // If the shadow-color is an actual color, convert it to a box-shadow value. Otherwise - // use the token value as itself (e,g. as a CSS var name). - $shadow-color: map.get($systems, md-sys-color, shadow); - @if (meta.type-of($shadow-color) == color) { - @for $zValue from 0 through 24 { - $shadow: elevation.get-box-shadow($zValue, $shadow-color); - $tokens: map.set($tokens, 'elevation-shadow-level-#{$zValue}', $shadow); - } - } +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + background-color: map.get($system, background), + text-color: map.get($system, on-background), + elevation-shadow-level-0: elevation.get-box-shadow(0, map.get($system, shadow)), + elevation-shadow-level-1: elevation.get-box-shadow(1, map.get($system, shadow)), + elevation-shadow-level-2: elevation.get-box-shadow(2, map.get($system, shadow)), + elevation-shadow-level-3: elevation.get-box-shadow(3, map.get($system, shadow)), + elevation-shadow-level-4: elevation.get-box-shadow(4, map.get($system, shadow)), + elevation-shadow-level-5: elevation.get-box-shadow(5, map.get($system, shadow)), + elevation-shadow-level-6: elevation.get-box-shadow(6, map.get($system, shadow)), + elevation-shadow-level-7: elevation.get-box-shadow(7, map.get($system, shadow)), + elevation-shadow-level-8: elevation.get-box-shadow(8, map.get($system, shadow)), + elevation-shadow-level-9: elevation.get-box-shadow(9, map.get($system, shadow)), + elevation-shadow-level-10: elevation.get-box-shadow(10, map.get($system, shadow)), + elevation-shadow-level-11: elevation.get-box-shadow(11, map.get($system, shadow)), + elevation-shadow-level-12: elevation.get-box-shadow(12, map.get($system, shadow)), + elevation-shadow-level-13: elevation.get-box-shadow(13, map.get($system, shadow)), + elevation-shadow-level-14: elevation.get-box-shadow(14, map.get($system, shadow)), + elevation-shadow-level-15: elevation.get-box-shadow(15, map.get($system, shadow)), + elevation-shadow-level-16: elevation.get-box-shadow(16, map.get($system, shadow)), + elevation-shadow-level-17: elevation.get-box-shadow(17, map.get($system, shadow)), + elevation-shadow-level-18: elevation.get-box-shadow(18, map.get($system, shadow)), + elevation-shadow-level-19: elevation.get-box-shadow(19, map.get($system, shadow)), + elevation-shadow-level-20: elevation.get-box-shadow(20, map.get($system, shadow)), + elevation-shadow-level-21: elevation.get-box-shadow(21, map.get($system, shadow)), + elevation-shadow-level-22: elevation.get-box-shadow(22, map.get($system, shadow)), + elevation-shadow-level-23: elevation.get-box-shadow(23, map.get($system, shadow)), + elevation-shadow-level-24: elevation.get-box-shadow(24, map.get($system, shadow)), + ), + typography: (), + density: (), + ); } diff --git a/src/material/core/option/_m3-optgroup.scss b/src/material/core/option/_m3-optgroup.scss index 60c7466d3fe0..043bee6704e1 100644 --- a/src/material/core/option/_m3-optgroup.scss +++ b/src/material/core/option/_m3-optgroup.scss @@ -1,22 +1,24 @@ @use 'sass:map'; -@use '../style/sass-utils'; @use '../tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, optgroup); /// Generates custom tokens for the mat-optgroup. -/// @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-optgroup -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, label-text, title-small), - ( - label-text-color: map.get($systems, md-sys-color, on-surface-variant), - ) +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + @return ( + base: (), + color: ( + label-text-color: map.get($system, on-surface-variant), + ), + typography: ( + label-text-font: map.get($system, title-small-font), + label-text-line-height: map.get($system, title-small-line-height), + label-text-size: map.get($system, title-small-size), + label-text-tracking: map.get($system, title-small-tracking), + label-text-weight: map.get($system, title-small-weight), + ), + density: (), ); - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } diff --git a/src/material/core/option/_m3-option.scss b/src/material/core/option/_m3-option.scss index 11a9c385235b..43f4e6311aa2 100644 --- a/src/material/core/option/_m3-option.scss +++ b/src/material/core/option/_m3-option.scss @@ -1,57 +1,39 @@ @use 'sass:map'; -@use '../style/sass-utils'; @use '../tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, option); /// Generates custom tokens for the mat-option. -/// @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-option -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - selected-state-label-text-color: map.get($systems, md-sys-color, on-secondary-container), - label-text-color: map.get($systems, md-sys-color, on-surface), - hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) - ), - focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) - ), - selected-state-layer-color: map.get($systems, md-sys-color, secondary-container), +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, secondary, $color-variant); + } - // According to the spec the options have to be `label-large` in all typography - // dimensions, however this is inconsistent with the designs and with MDC's - // own implementation. This appears to be a bug in the spec, because MDC overrides - // the font size and weight to be `body-large` (see b/261838263). We make the same - // override here so the label looks correct. - label-text-size: map.get($systems, md-sys-typescale, body-large-size), - label-text-weight: map.get($systems, md-sys-typescale, body-large-weight), - label-text-font: map.get($systems, md-sys-typescale, label-large-font), - label-text-line-height: map.get($systems, md-sys-typescale, label-large-line-height), - label-text-tracking: map.get($systems, md-sys-typescale, label-large-tracking), - ); - - $variant-tokens: ( - // Color variants: - primary: ( - selected-state-label-text-color: map.get($systems, md-sys-color, on-primary-container), - selected-state-layer-color: map.get($systems, md-sys-color, primary-container), + // According to the spec the options have to be `label-large` in all typography + // dimensions, however this is inconsistent with the designs and with MDC's + // own implementation. This appears to be a bug in the spec, because MDC overrides + // the font size and weight to be `body-large` (see b/261838263). We make the same + // override here so the label looks correct. + @return ( + base: (), + color: ( + focus-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, focus-state-layer-opacity)), + hover-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, hover-state-layer-opacity)), + label-text-color: map.get($system, on-surface), + selected-state-label-text-color: map.get($system, on-secondary-container), + selected-state-layer-color: map.get($system, secondary-container), ), - secondary: (), // Default, no overrides needed - tertiary: ( - selected-state-label-text-color: map.get($systems, md-sys-color, on-tertiary-container), - selected-state-layer-color: map.get($systems, md-sys-color, tertiary-container), + typography: ( + label-text-size: map.get($system, body-large-size), + label-text-weight: map.get($system, body-large-weight), + label-text-font: map.get($system, label-large-font), + label-text-line-height: map.get($system, label-large-line-height), + label-text-tracking: map.get($system, label-large-tracking), ), - error: ( - selected-state-label-text-color: map.get($systems, md-sys-color, on-error-container), - selected-state-layer-color: map.get($systems, md-sys-color, error-container), - ) + density: (), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/core/option/_optgroup-theme.scss b/src/material/core/option/_optgroup-theme.scss index f0ae5befefe3..bb0f5875be93 100644 --- a/src/material/core/option/_optgroup-theme.scss +++ b/src/material/core/option/_optgroup-theme.scss @@ -1,22 +1,26 @@ @use 'sass:map'; @use './m2-optgroup'; +@use './m3-optgroup'; @use '../tokens/token-utils'; @use '../style/sass-utils'; @use '../theming/theming'; -@use '../theming/validation'; @use '../theming/inspection'; @use '../typography/typography'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), base)); } @else { } } @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -27,7 +31,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -38,7 +44,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-optgroup.$prefix, + map.get(m3-optgroup.get-tokens($theme), base)); } @else { } } @@ -60,7 +68,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-optgroup') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -75,15 +86,3 @@ } } } - -@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( - m2-optgroup.$prefix, - map.get($tokens, m2-optgroup.$prefix) - ); - } -} diff --git a/src/material/core/option/_option-theme.scss b/src/material/core/option/_option-theme.scss index edc3250c6ef4..5294b90952f9 100644 --- a/src/material/core/option/_option-theme.scss +++ b/src/material/core/option/_option-theme.scss @@ -1,29 +1,32 @@ @use './m2-option'; +@use './m3-option'; @use '../tokens/token-utils'; @use '../style/sass-utils'; @use '../theming/theming'; @use '../theming/inspection'; -@use '../theming/validation'; @use '../typography/typography'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-option. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), base)); } @else { } } /// Outputs color theme styles for the mat-option. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the selected option: primary, secondary, -/// tertiary, or error (If not specified, default secondary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -46,7 +49,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -59,7 +64,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-option.$prefix, + map.get(m3-option.get-tokens($theme), density)); } @else { } } @@ -82,13 +89,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-option. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the selected option: primary, secondary, -/// tertiary, or error (If not specified, default secondary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-option') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -103,11 +111,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-option-tokens: token-utils.get-tokens-for($tokens, m2-option.$prefix, $options...); - @include token-utils.create-token-values(m2-option.$prefix, $mat-option-tokens); -} diff --git a/src/material/core/option/optgroup.scss b/src/material/core/option/optgroup.scss index 548ac49bd347..a5932d258e9a 100644 --- a/src/material/core/option/optgroup.scss +++ b/src/material/core/option/optgroup.scss @@ -1,9 +1,15 @@ @use './m2-optgroup'; +@use './m3-optgroup'; @use '../tokens/token-utils'; +@use '../tokens/m3-system'; + +$token-prefix: m2-optgroup.$prefix; +$token-slots: m2-optgroup.get-token-slots(); +$fallbacks: m3-optgroup.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-optgroup { // These tokens are set on the root option group to make them easier to override. - @include token-utils.use-tokens(m2-optgroup.$prefix, m2-optgroup.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(label-text-color); font-family: token-utils.slot(label-text-font); line-height: token-utils.slot(label-text-line-height); diff --git a/src/material/core/option/option.scss b/src/material/core/option/option.scss index 67a39fa6be8d..2c4f5c7a39aa 100644 --- a/src/material/core/option/option.scss +++ b/src/material/core/option/option.scss @@ -1,10 +1,17 @@ @use '@angular/cdk'; @use './m2-option'; +@use './m3-option'; @use '../../list/m2-list'; +@use '../../list/m3-list'; @use '../tokens/token-utils'; @use '../style/vendor-prefixes'; @use '../style/layout-common'; +@use '../tokens/m3-system'; + +$token-prefix: m2-option.$prefix; +$token-slots: m2-option.get-token-slots(); +$fallbacks: m3-option.get-tokens(m3-system.$theme-with-system-vars); $_side-padding: 16px; @@ -21,7 +28,7 @@ $_side-padding: 16px; cursor: pointer; -webkit-tap-highlight-color: transparent; - @include token-utils.use-tokens(m2-option.$prefix, m2-option.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(label-text-color); font-family: token-utils.slot(label-text-font); line-height: token-utils.slot(label-text-line-height); @@ -180,12 +187,16 @@ $_side-padding: 16px; } } +$list-token-prefix: m2-list.$prefix; +$list-token-slots: m2-list.get-token-slots(); +$list-fallbacks: m3-list.get-tokens(m3-system.$theme-with-system-vars); + .mat-mdc-option-multiple { // Multi-select options in the selected state aren't supposed to change their background color, // because the checkbox already indicates that they're selected. This happened to work in M2, // due to `list-item-selected-container-color` being the same as `list-item-container-color`, // but that's no longer the case in M3. This overrides ensures that the appearance is consistent. - @include token-utils.use-tokens(m2-list.$prefix, m2-list.get-token-slots()) { + @include token-utils.use-tokens($list-token-prefix, $list-token-slots, $list-fallbacks) { $selected-token: token-utils.get-token-variable-name(list-item-selected-container-color); $base-token: token-utils.slot(list-item-container-color, $fallback: transparent); #{$selected-token}: $base-token; diff --git a/src/material/core/ripple/_m3-ripple.scss b/src/material/core/ripple/_m3-ripple.scss index 67e95dc691ee..eb5ab610544d 100644 --- a/src/material/core/ripple/_m3-ripple.scss +++ b/src/material/core/ripple/_m3-ripple.scss @@ -1,19 +1,19 @@ @use 'sass:map'; -@use '../style/sass-utils'; @use '../tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, ripple); /// Generates custom tokens for the mat-ripple. -/// @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-ripple -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - color: sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.1), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + color: m3-utils.color-with-opacity(map.get($system, on-surface), 10%), + ), + typography: (), + density: (), + ); } diff --git a/src/material/core/ripple/_ripple-theme.scss b/src/material/core/ripple/_ripple-theme.scss index b9def167b960..325fb01258e0 100644 --- a/src/material/core/ripple/_ripple-theme.scss +++ b/src/material/core/ripple/_ripple-theme.scss @@ -1,21 +1,25 @@ @use 'sass:map'; @use './m2-ripple'; +@use './m3-ripple'; @use '../tokens/token-utils'; @use '../style/sass-utils'; @use '../theming/theming'; @use '../theming/inspection'; -@use '../theming/validation'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), base)); } @else { } } @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -28,7 +32,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -41,7 +47,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-ripple.$prefix, + map.get(m3-ripple.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -69,7 +77,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-ripple') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -84,15 +95,3 @@ } } } - -@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( - m2-ripple.$prefix, - map.get($tokens, m2-ripple.$prefix) - ); - } -} diff --git a/src/material/core/ripple/_ripple.scss b/src/material/core/ripple/_ripple.scss index 54e12ec439f4..233d49ac6db3 100644 --- a/src/material/core/ripple/_ripple.scss +++ b/src/material/core/ripple/_ripple.scss @@ -1,6 +1,12 @@ @use '@angular/cdk'; @use './m2-ripple'; +@use './m3-ripple'; @use '../tokens/token-utils'; +@use '../tokens/m3-system'; + +$token-prefix: m2-ripple.$prefix; +$token-slots: m2-ripple.get-token-slots(); +$fallbacks: m3-ripple.get-tokens(m3-system.$theme-with-system-vars); @mixin ripple() { // The host element of an mat-ripple directive should always have a position of "absolute" or @@ -37,7 +43,7 @@ // the ripples aren't clipped when inside the shadow DOM (see #24028). transform: scale3d(0, 0, 0); - @include token-utils.use-tokens(m2-ripple.$prefix, m2-ripple.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // We have to emit a fallback value here, because some internal builds depend on it. background-color: token-utils.slot(color, $fallback: rgba(#000, 0.1)); } diff --git a/src/material/core/selection/pseudo-checkbox/_m3-pseudo-checkbox.scss b/src/material/core/selection/pseudo-checkbox/_m3-pseudo-checkbox.scss index 38b3d66ae199..2057797db33d 100644 --- a/src/material/core/selection/pseudo-checkbox/_m3-pseudo-checkbox.scss +++ b/src/material/core/selection/pseudo-checkbox/_m3-pseudo-checkbox.scss @@ -1,49 +1,36 @@ @use 'sass:map'; -@use '../../style/sass-utils'; @use '../../tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, pseudo-checkbox); /// Generates custom tokens for the full variant of mat-pseudo-checkbox. -/// @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 full variant of mat-pseudo-checkbox -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - full-disabled-selected-checkmark-color: map.get($systems, md-sys-color, surface), - full-disabled-selected-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - full-disabled-unselected-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - full-selected-checkmark-color: map.get($systems, md-sys-color, on-primary), - full-selected-icon-color: map.get($systems, md-sys-color, primary), - full-unselected-icon-color: map.get($systems, md-sys-color, on-surface-variant), - minimal-disabled-selected-checkmark-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - minimal-selected-checkmark-color: map.get($systems, md-sys-color, primary), - ); +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - // Color variants: - primary: (), // Default, no overrides needed. - secondary: ( - full-selected-checkmark-color: map.get($systems, md-sys-color, on-secondary), - full-selected-icon-color: map.get($systems, md-sys-color, secondary), - minimal-selected-checkmark-color: map.get($systems, md-sys-color, secondary), - ), - tertiary: ( - full-selected-checkmark-color: map.get($systems, md-sys-color, on-tertiary), - full-selected-icon-color: map.get($systems, md-sys-color, tertiary), - minimal-selected-checkmark-color: map.get($systems, md-sys-color, tertiary), + @return ( + base: (), + color: ( + full-disabled-selected-checkmark-color: map.get($system, surface), + full-disabled-selected-icon-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + full-disabled-unselected-icon-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + full-selected-checkmark-color: map.get($system, on-primary), + full-selected-icon-color: map.get($system, primary), + full-unselected-icon-color: map.get($system, on-surface-variant), + minimal-disabled-selected-checkmark-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + minimal-selected-checkmark-color: map.get($system, primary), ), - error: ( - full-selected-checkmark-color: map.get($systems, md-sys-color, on-error), - full-selected-icon-color: map.get($systems, md-sys-color, error), - minimal-selected-checkmark-color: map.get($systems, md-sys-color, error), - ) + typography: (), + density: (), ); - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); + $tokens: ( + ); } diff --git a/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss b/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss index 92da5270c904..2d4f30a6201f 100644 --- a/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss +++ b/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss @@ -1,9 +1,10 @@ @use '../../theming/theming'; @use '../../theming/inspection'; -@use '../../theming/validation'; @use '../../style/sass-utils'; @use '../../tokens/token-utils'; @use './m2-pseudo-checkbox'; +@use './m3-pseudo-checkbox'; +@use 'sass:map'; @mixin _palette-styles($theme, $palette-name) { @include sass-utils.current-selector-or-root() { @@ -14,16 +15,6 @@ } } -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-pseudo-checkbox-tokens: token-utils.get-tokens-for( - $tokens, m2-pseudo-checkbox.$prefix, $options...); - @include token-utils.create-token-values-mixed( - m2-pseudo-checkbox.$prefix, $mat-pseudo-checkbox-tokens); -} - /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-pseudo-checkbox. /// @param {Map} $theme The theme to generate base styles for. @@ -48,12 +39,12 @@ /// Outputs color theme styles for the mat-pseudo-checkbox. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the pseudo-checkbox: primary, secondary, -/// tertiary, or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-pseudo-checkbox.$prefix, + map.get(m3-pseudo-checkbox.get-tokens($theme, $color-variant), base)); } @else { // Default to the accent color. Note that the pseudo checkboxes are meant to inherit the // theme from their parent, rather than implementing their own theming, which is why we @@ -88,13 +79,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-pseudo-checkbox. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the pseudo-checkbox: primary, secondary, -/// tertiary, or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-pseudo-checkbox') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { diff --git a/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.scss b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.scss index da6a89c46319..12ae4b2ba6b6 100644 --- a/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.scss +++ b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.scss @@ -4,7 +4,13 @@ @use '../../style/variables'; @use '../../tokens/token-utils'; @use './m2-pseudo-checkbox'; +@use './m3-pseudo-checkbox'; @use './pseudo-checkbox-common'; +@use '../../tokens/m3-system'; + +$token-prefix: m2-pseudo-checkbox.$prefix; +$token-slots: m2-pseudo-checkbox.get-token-slots(); +$fallbacks: m3-pseudo-checkbox.get-tokens(m3-system.$theme-with-system-vars); .mat-pseudo-checkbox { border-radius: 2px; @@ -53,8 +59,7 @@ box-sizing: content-box; } -@include token-utils.use-tokens( - m2-pseudo-checkbox.$prefix, m2-pseudo-checkbox.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-pseudo-checkbox-minimal { &.mat-pseudo-checkbox-checked, &.mat-pseudo-checkbox-indeterminate { &::after { diff --git a/src/material/core/style/_sass-utils.scss b/src/material/core/style/_sass-utils.scss index 0d51c92e0f32..e2ff89eb952f 100644 --- a/src/material/core/style/_sass-utils.scss +++ b/src/material/core/style/_sass-utils.scss @@ -1,6 +1,5 @@ @use 'sass:color'; @use 'sass:string'; -@use 'sass:list'; @use 'sass:map'; @use 'sass:meta'; @@ -52,16 +51,6 @@ $use-system-typography-variables: false; @return $result; } -/// Coerces the given value to a list, by converting any non-list value into a single-item list. -/// This should be used when dealing with user-passed lists of args to avoid confusing errors, -/// since Sass treats `($x)` as equivalent to `$x`. -/// @param {Any} $value The value to coerce to a list. -/// @return {List} The original $value if it was a list, otherwise a single-item list containing -/// $value. -@function coerce-to-list($value) { - @return if(meta.type-of($value) != 'list', ($value,), $value); -} - /// A version of the Sass `color.change` function that is safe ot use with CSS variables. @function safe-color-change($color, $args...) { $args: meta.keywords($args); @@ -90,24 +79,6 @@ $use-system-typography-variables: false; @return $color; } -/// Gets the given arguments as a map of keywords and validates that only supported arguments were -/// passed. -/// @param {ArgList} $args The arguments to convert to a keywords map. -/// @param {List} $supported-args The supported argument names. -/// @return {Map} The $args as a map of argument name to argument value. -@function validate-keyword-args($args, $supported-args) { - @if list.length($args) > 0 { - @error #{'Expected keyword args, but got positional args: '}#{$args}; - } - $kwargs: meta.keywords($args); - @each $arg, $v in $kwargs { - @if list.index($supported-args, $arg) == null { - @error #{'Unsupported argument '}#{$arg}#{'. Valid arguments are: '}#{$supported-args}; - } - } - @return $kwargs; -} - // Returns whether the $value is a CSS variable name based on whether it's a string prefixed // by "--". @function is-css-var-name($value) { diff --git a/src/material/core/theming/_color-api-backwards-compatibility.scss b/src/material/core/theming/_color-api-backwards-compatibility.scss index 84f449bc61fc..e9199cf604f4 100644 --- a/src/material/core/theming/_color-api-backwards-compatibility.scss +++ b/src/material/core/theming/_color-api-backwards-compatibility.scss @@ -24,92 +24,85 @@ $_overrides-only: true; @mixin _color-variant-styles($theme, $color-variant) { - $primary-options: (color-variant: $color-variant, emit-overrides-only: $_overrides-only); - - // Some components use the secondary color rather than primary color for `.mat-primary`. - // Those components should use the $secondary-color-variant. - $secondary-options: ( - color-variant: if($color-variant == primary, secondary, $color-variant), - emit-overrides-only: $_overrides-only - ); + $secondary-when-primary: if($color-variant == primary, secondary, $color-variant); & { - @include option-theme.color($theme, $secondary-options...); + @include option-theme.color($theme, $secondary-when-primary); } & { - @include progress-spinner-theme.color($theme, $primary-options...); + @include progress-spinner-theme.color($theme, $color-variant); } & { - @include pseudo-checkbox-theme.color($theme, $primary-options...); + @include pseudo-checkbox-theme.color($theme, $color-variant); } & { - @include stepper-theme.color($theme, $primary-options...); + @include stepper-theme.color($theme, $color-variant); } &.mat-icon { - @include icon-theme.color($theme, $primary-options...); + @include icon-theme.color($theme, $color-variant); } &.mat-mdc-checkbox { - @include checkbox-theme.color($theme, $primary-options...); + @include checkbox-theme.color($theme, $color-variant); } &.mat-mdc-slider { - @include slider-theme.color($theme, $primary-options...); + @include slider-theme.color($theme, $color-variant); } &.mat-mdc-tab-group, &.mat-mdc-tab-nav-bar { - @include tabs-theme.color($theme, $primary-options...); + @include tabs-theme.color($theme, $color-variant); } &.mat-mdc-slide-toggle { - @include slide-toggle-theme.color($theme, $primary-options...); + @include slide-toggle-theme.color($theme, $color-variant); } &.mat-mdc-form-field { - @include select-theme.color($theme, $primary-options...); + @include select-theme.color($theme, $color-variant); } &.mat-mdc-radio-button { - @include radio-theme.color($theme, $primary-options...); + @include radio-theme.color($theme, $color-variant); } &.mat-mdc-progress-bar { - @include progress-bar-theme.color($theme, $primary-options...); + @include progress-bar-theme.color($theme, $color-variant); } &.mat-mdc-form-field { - @include form-field-theme.color($theme, $primary-options...); + @include form-field-theme.color($theme, $color-variant); } &.mat-datepicker-content { - @include datepicker-theme.color($theme, $primary-options...); + @include datepicker-theme.color($theme, $color-variant); } &.mat-mdc-button-base { - @include button-theme.color($theme, $primary-options...); - @include icon-button-theme.color($theme, $primary-options...); + @include button-theme.color($theme, $color-variant); + @include icon-button-theme.color($theme, $color-variant); } &.mat-mdc-standard-chip { - @include chips-theme.color($theme, $secondary-options...); + @include chips-theme.color($theme, $secondary-when-primary); } .mdc-list-item__start, .mdc-list-item__end { - @include checkbox-theme.color($theme, $primary-options...); - @include radio-theme.color($theme, $primary-options...); + @include checkbox-theme.color($theme, $color-variant); + @include radio-theme.color($theme, $color-variant); } // M3 dropped support for warn/error color FABs. @if $color-variant != error { &.mat-mdc-fab, &.mat-mdc-mini-fab { - @include fab-theme.color($theme, $primary-options...); + @include fab-theme.color($theme, $color-variant); } } } diff --git a/src/material/core/theming/_definition.scss b/src/material/core/theming/_definition.scss index 27ddffbf1117..595b8fc69137 100644 --- a/src/material/core/theming/_definition.scss +++ b/src/material/core/theming/_definition.scss @@ -89,6 +89,12 @@ $theme-version: 1; md-sys-motion: m3.md-sys-motion-values(), md-sys-shape: m3.md-sys-shape-values(), md-sys-state: m3.md-sys-state-values(), + md-ref-palette: ( + // Form field native select option text color + neutral10: map.get($palettes, neutral, 10), + // Sidenav scrim (container background shadow when opened), + neutral-variant20: map.get($palettes, neutral-variant, 20), + ), md-sys-typescale: m3-tokens.get-sys-typeface($typography, $typography-system-variables-prefix), palettes: $palettes, diff --git a/src/material/core/theming/_inspection.scss b/src/material/core/theming/_inspection.scss index ae86be3523f7..cd329f138bed 100644 --- a/src/material/core/theming/_inspection.scss +++ b/src/material/core/theming/_inspection.scss @@ -280,31 +280,6 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac } } -/// Gets the set of tokens from the given theme, limited to those affected by the requested theming -/// systems. -/// @param {Map} $theme The theme to get tokens from. -/// @param {String...} $systems The theming systems to get tokens for. Valid values are: color, -/// typography, density, base. If no systems are passed, all tokens will be returned. -/// @return {Map} The requested tokens for the theme. -@function get-theme-tokens($theme, $systems...) { - $systems: if(list.length($systems) == 0, (color, typography, density, base), $systems); - $err: _validate-theme-object($theme); - @if $err { - @error #{'Expected $theme to be an Angular Material theme object. Got:'} $theme; - } - $err: validation.validate-allowed-values($systems, color, typography, density, base); - @if $err { - @error #{'Expected $systems to contain valid system names (color, typography, density, or'} - #{'base). Got invalid system names:'} $err; - } - $result: (); - @each $system in $systems { - $result: map.deep-merge($result, map.get($theme, $internals, '#{$system}-tokens') or ()); - } - - @return $result; -} - /// Gets a version of the theme with a modified typography config that preserves old behavior in /// some components that previously used `private-typography-to-2014-config`. /// Do not introduce new usages of this, it should be cleaned up and removed. diff --git a/src/material/core/theming/tests/m3-theme.spec.ts b/src/material/core/theming/tests/m3-theme.spec.ts index 01061e9873e9..eaa524c78f85 100644 --- a/src/material/core/theming/tests/m3-theme.spec.ts +++ b/src/material/core/theming/tests/m3-theme.spec.ts @@ -128,12 +128,6 @@ describe('M3 theme', () => { .toEqual([]); }); - it('should throw if theme included at root', () => { - expect(() => transpile(`@include mat.all-component-themes($theme)`)).toThrowError( - /Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector/, - ); - }); - describe('theme override API', () => { beforeEach(() => { spyOn(process.stderr, 'write').and.callThrough(); 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 746128266659..f1050cbdf461 100644 --- a/src/material/core/theming/tests/theming-definition-api.spec.ts +++ b/src/material/core/theming/tests/theming-definition-api.spec.ts @@ -79,6 +79,7 @@ describe('theming definition api', () => { 'md-sys-motion', 'md-sys-shape', 'md-sys-state', + 'md-ref-palette', 'md-sys-typescale', 'palettes', 'theme-type', diff --git a/src/material/core/tokens/_m3-tokens.scss b/src/material/core/tokens/_m3-tokens.scss index 4ae58eecaab4..2d2d994e235d 100644 --- a/src/material/core/tokens/_m3-tokens.scss +++ b/src/material/core/tokens/_m3-tokens.scss @@ -1,44 +1,4 @@ -@use '../../autocomplete/m3-autocomplete'; -@use '../../bottom-sheet/m3-bottom-sheet'; -@use '../../button-toggle/m3-button-toggle'; -@use '../../button/m3-button'; -@use '../../button/m3-fab'; -@use '../../button/m3-icon-button'; -@use '../../card/m3-card'; -@use '../../checkbox/m3-checkbox'; -@use '../../chips/m3-chip'; -@use '../../datepicker/m3-datepicker'; -@use '../../dialog/m3-dialog'; -@use '../../divider/m3-divider'; -@use '../../expansion/m3-expansion'; -@use '../../form-field/m3-form-field'; -@use '../../grid-list/m3-grid-list'; -@use '../../icon/m3-icon'; -@use '../../list/m3-list'; -@use '../../menu/m3-menu'; -@use '../../paginator/m3-paginator'; -@use '../../progress-bar/m3-progress-bar'; -@use '../../progress-spinner/m3-progress-spinner'; -@use '../../radio/m3-radio'; -@use '../../select/m3-select'; -@use '../../sidenav/m3-sidenav'; -@use '../../slide-toggle/m3-slide-toggle'; -@use '../../slider/m3-slider'; -@use '../../snack-bar/m3-snack-bar'; -@use '../../sort/m3-sort'; -@use '../../stepper/m3-stepper'; -@use '../../table/m3-table'; -@use '../../tabs/m3-tabs'; -@use '../../timepicker/m3-timepicker'; -@use '../../toolbar/m3-toolbar'; -@use '../../tooltip/m3-tooltip'; -@use '../../tree/m3-tree'; @use '../m2' as m2-theming; -@use '../m3-app'; -@use '../option/m3-optgroup'; -@use '../option/m3-option'; -@use '../ripple/m3-ripple'; -@use '../selection/pseudo-checkbox/m3-pseudo-checkbox'; @use '../style/sass-utils'; @use './m2-tokens'; @use './m3'; @@ -95,7 +55,6 @@ $_cached-token-slots: null; (mat, theme): map.get($systems, md-sys-color), (mat, typography): map.get($systems, md-sys-typescale), ), - get-m3-tokens($systems, $exclude-hardcoded, $token-slots), ); @return $result; @@ -191,60 +150,3 @@ $_cached-token-slots: null; md-sys-shape: m3.md-sys-shape-values(), ), $include-non-systemized: true); } - -/// Gets the full set of M3 tokens for the given theme object. -/// @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} Full set of M3 tokens -@function get-m3-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens-list: ( - m3-app.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-autocomplete.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-bottom-sheet.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-button-toggle.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-button.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-card.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-checkbox.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-chip.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-datepicker.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-dialog.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-divider.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-expansion.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-fab.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-form-field.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-grid-list.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-icon-button.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-icon.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-list.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-menu.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-optgroup.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-option.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-paginator.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-progress-bar.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-progress-spinner.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-pseudo-checkbox.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-radio.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-ripple.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-tabs.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-select.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-sidenav.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-slide-toggle.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-slider.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-snack-bar.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-sort.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-stepper.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-table.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-timepicker.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-toolbar.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-tooltip.get-tokens($systems, $exclude-hardcoded, $token-slots), - m3-tree.get-tokens($systems, $exclude-hardcoded, $token-slots), - ); - - $merged-tokens: (); - @each $tokens in $tokens-list { - $merged-tokens: map.deep-merge($merged-tokens, $tokens); - } - - @return $merged-tokens; -} diff --git a/src/material/core/tokens/_m3-utils.scss b/src/material/core/tokens/_m3-utils.scss index e22c9bb17a01..f9cc25a15653 100644 --- a/src/material/core/tokens/_m3-utils.scss +++ b/src/material/core/tokens/_m3-utils.scss @@ -1,90 +1,7 @@ @use 'sass:map'; -@use 'sass:list'; @use 'sass:meta'; @use 'sass:string'; -/// Gets the MDC tokens for the given prefix, M3 token values, and supported token slots. -/// @param {List} $prefix The token prefix for the given tokens. -/// @param {Map|(Map, Map)} $values A map of M3 token values for the given prefix. -/// This param may also be a tuple of maps, the first one representing the default M3 token values, -// and the second containing overrides for different color variants. -// Single map example: -// (token1: green, token2: 2px) -// Tuple example: -// ( -// (token1: green, token2: 2px), -// ( -// secondary: (token1: blue), -// error: (token1: red), -// ) -// ) -/// @param {Map} $slots A map of token slots, with null value indicating the token is not supported. -/// @param {String|null} $variant The name of the variant the token values are for. -/// @return {Map} A map of fully qualified token names to values, for only the supported tokens. -@function namespace($prefix, $values, $slots, $variant: null) { - $result: (); - @if $variant == null and meta.type-of($values) == 'list' and list.length($values == 2) { - $variants: list.nth($values, 2); - $values: list.nth($values, 1); - @each $variant, $overrides in $variants { - - $result: map.merge($result, namespace($prefix, $overrides, $slots, $variant)); - } - } - $used-token-names: map.keys(_filter-nulls(map.get($slots, $prefix))); - $used-m3-tokens: _pick(_filter-nulls($values), $used-token-names); - $prefix: if($variant == null, $prefix, list.append($prefix, $variant)); - @return map.merge($result, ($prefix: $used-m3-tokens)); -} - -/// Hardcode the given value, or null if hardcoded values are excluded. -@function hardcode($value, $exclude-hardcoded) { - @return if($exclude-hardcoded, null, $value); -} - -/// Picks a submap containing only the given keys out the given map. -/// @param {Map} $map The map to pick from. -/// @param {List} $keys The map keys to pick. -/// @return {Map} A submap containing only the given keys. -@function _pick($map, $keys) { - $result: (); - @each $key in $keys { - @if map.has-key($map, $key) { - $result: map.set($result, $key, map.get($map, $key)); - } - } - @return $result; -} - - -/// Filters keys with a null value out of the map. -/// @param {Map} $map The map to filter. -/// @return {Map} The given map with all of the null keys filtered out. -@function _filter-nulls($map) { - $result: (); - @each $key, $val in $map { - @if $val != null { - $result: map.set($result, $key, $val); - } - } - @return $result; -} - -/// Sets all of the standard typography tokens for the given token base name to the given typography -/// level. -/// @param {Map} $systems The MDC system tokens -/// @param {String} $base-name The token base name to get the typography tokens for -/// @param {String} $typography-level The typography level to base the token values on -/// @return {Map} A map containing the typography tokens for the given base token name -@function generate-typography-tokens($systems, $base-name, $typography-level) { - $result: (); - @each $prop in (font, line-height, size, tracking, weight) { - $result: map.set($result, #{$base-name}-#{$prop}, - map.get($systems, md-sys-typescale, #{$typography-level}-#{$prop})); - } - @return $result; -} - // Replaces color tokens in the map with those defined as the variant color. @function replace-colors-with-variant($system, $color, $variant) { $system: map.set($system, on-#{$color}, map.get($system, on-#{$variant})); @@ -107,6 +24,8 @@ map.get($theme, _mat-theming-internals-do-not-access, md-sys-state)); $system: map.merge($system, map.get($theme, _mat-theming-internals-do-not-access, md-sys-typescale)); + $system: map.merge($system, + map.get($theme, _mat-theming-internals-do-not-access, md-ref-palette)); @return $system; } @@ -116,5 +35,12 @@ @if (meta.type-of($color) == string and string.index($color, '--') == 1) { $color: var($color); } + + // Opacity may be a system level value less than 1, instead of the intended + // whole percentage, e.g. 38%. Remove this support when possible. + @if (meta.type-of($opacity) == number and $opacity < 1) { + $opacity: '#{$opacity * 100}%'; + } + @return color-mix(in srgb, #{$color} #{$opacity}, transparent); } diff --git a/src/material/core/tokens/_token-utils.scss b/src/material/core/tokens/_token-utils.scss index b1e1e966b863..7ae686cd60d1 100644 --- a/src/material/core/tokens/_token-utils.scss +++ b/src/material/core/tokens/_token-utils.scss @@ -1,8 +1,6 @@ -@use '../style/elevation'; @use '../style/sass-utils'; @use './m3-system'; @use 'sass:list'; -@use 'sass:meta'; @use 'sass:map'; @use 'sass:string'; @@ -161,88 +159,6 @@ $_direct-system-fallbacks: (); #{$name}: #{$value}; } -// MDC doesn't currently handle elevation tokens properly. As a temporary workaround we can combine -// the elevation and shadow-color tokens into a full box-shadow and use it as the value for the -// elevation token. -@function resolve-elevation($tokens, $elevation-token, $shadow-color-token) { - $elevation: map.get($tokens, $elevation-token); - $shadow-color: map.get($tokens, $shadow-color-token); - @return map.merge( - $tokens, - ( - $elevation-token: elevation.get-box-shadow($elevation, $shadow-color), - $shadow-color-token: null, - ) - ); -} - -/// Checks whether a list starts wih a given prefix -/// @param {List} $list The list value to check the prefix of. -/// @param {List} $prefix The prefix to check. -/// @return {Boolean} Whether the list starts with the prefix. -@function _is-prefix($list, $prefix) { - @for $i from 1 through list.length($prefix) { - @if list.nth($list, $i) != list.nth($prefix, $i) { - @return false; - } - } - @return true; -} - -/// Gets the supported color variants in the given token set for the given prefix. -/// @param {Map} $tokens The full token map. -/// @param {List} $prefix The component prefix to get color variants for. -/// @return {List} The supported color variants. -@function _supported-color-variants($tokens, $prefix) { - $result: (); - @each $namespace in map.keys($tokens) { - @if list.length($prefix) == list.length($namespace) - 1 and _is-prefix($namespace, $prefix) { - $result: list.append($result, list.nth($namespace, list.length($namespace)), comma); - } - } - @return $result; -} - -/// Gets the token values for the given components prefix with the given options. -/// @param {Map} $tokens The full token map. -/// @param {List} $prefix The component prefix to get the token values for. -/// @param {ArgList} Any additional options -/// Currently the additional supported options are: -// - $color-variant - The color variant to use for the component -// - $emit-overrides-only - Whether to emit *only* the overrides for the -// specific color variant, or all color styles. Defaults to false. -/// @throws If given options are invalid -/// @return {Map} The token values for the requested component. -@function get-tokens-for($tokens, $prefix, $options...) { - $options: sass-utils.validate-keyword-args($options, (color-variant, emit-overrides-only)); - @if $tokens == () { - @return (); - } - $values: map.get($tokens, $prefix); - @if ($values == null) { - @return (); - } - - $color-variant: map.get($options, color-variant); - $emit-overrides-only: map.get($options, emit-overrides-only); - @if $color-variant == null { - @return $values; - } - $overrides: map.get($tokens, list.append($prefix, $color-variant)); - @if $overrides == null { - $variants: _supported-color-variants($tokens, $prefix); - $secondary-message: if( - $variants == (), - 'Mixin does not support color variants', - 'Supported color variants are: #{$variants}' - ); - - @error 'Invalid color variant: #{$color-variant}. #{$secondary-message}.'; - } - - @return if($emit-overrides-only, $overrides, map.merge($values, $overrides)); -} - /// 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. @@ -292,37 +208,3 @@ $_direct-system-fallbacks: (); } @return $result; } - -/// Gets the MDC tokens for the given prefix, M3 token values, and supported token slots. -/// @param {List} $prefix The token prefix for the given tokens. -/// @param {Map|(Map, Map)} $values A map of M3 token values for the given prefix. -/// This param may also be a tuple of maps, the first one representing the default M3 token values, -// and the second containing overrides for different color variants. -// Single map example: -// (token1: green, token2: 2px) -// Tuple example: -// ( -// (token1: green, token2: 2px), -// ( -// secondary: (token1: blue), -// error: (token1: red), -// ) -// ) -/// @param {Map} $slots A map of token slots, with null value indicating the token is not supported. -/// @param {String|null} $variant The name of the variant the token values are for. -/// @return {Map} A map of fully qualified token names to values, for only the supported tokens. -@function namespace-tokens($prefix, $values, $slots, $variant: null) { - $result: (); - @if $variant == null and meta.type-of($values) == 'list' and list.length($values == 2) { - $variants: list.nth($values, 2); - $values: list.nth($values, 1); - @each $variant, $overrides in $variants { - - $result: map.merge($result, namespace-tokens($prefix, $overrides, $slots, $variant)); - } - } - $used-token-names: map.keys(_filter-nulls(map.get($slots, $prefix))); - $used-m3-tokens: _pick(_filter-nulls($values), $used-token-names); - $prefix: if($variant == null, $prefix, list.append($prefix, $variant)); - @return map.merge($result, ($prefix: $used-m3-tokens)); -} diff --git a/src/material/datepicker/_datepicker-theme.scss b/src/material/datepicker/_datepicker-theme.scss index fd817b98c68a..441a1b7882a5 100644 --- a/src/material/datepicker/_datepicker-theme.scss +++ b/src/material/datepicker/_datepicker-theme.scss @@ -1,9 +1,9 @@ @use 'sass:color'; @use 'sass:map'; @use './m2-datepicker'; +@use './m3-datepicker'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/style/sass-utils'; @use '../core/typography/typography'; @@ -35,7 +35,9 @@ $calendar-weekday-table-font-size: 11px !default; /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-datepicker.$prefix, + map.get(m3-datepicker.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -46,12 +48,12 @@ $calendar-weekday-table-font-size: 11px !default; /// Outputs color theme styles for the mat-datepicker. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the main selection: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-datepicker.$prefix, + map.get(m3-datepicker.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -86,7 +88,9 @@ $calendar-weekday-table-font-size: 11px !default; /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-datepicker.$prefix, + map.get(m3-datepicker.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -120,7 +124,9 @@ $calendar-weekday-table-font-size: 11px !default; /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-datepicker.$prefix, + map.get(m3-datepicker.get-tokens($theme), density)); } @else { // TODO(crisbeto): move this into the structural styles // once the icon button density is switched to tokens. @@ -151,13 +157,14 @@ $calendar-weekday-table-font-size: 11px !default; /// Outputs all (base, color, typography, and density) theme styles for the mat-datepicker. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the main selection: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-datepicker') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -172,12 +179,3 @@ $calendar-weekday-table-font-size: 11px !default; } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-datepicker-tokens: token-utils.get-tokens-for( - $tokens, m2-datepicker.$prefix, $options...); - @include token-utils.create-token-values(m2-datepicker.$prefix, $mat-datepicker-tokens); -} diff --git a/src/material/datepicker/_m3-datepicker.scss b/src/material/datepicker/_m3-datepicker.scss index 5b75e92704c1..4282099df9e7 100644 --- a/src/material/datepicker/_m3-datepicker.scss +++ b/src/material/datepicker/_m3-datepicker.scss @@ -1,125 +1,76 @@ @use 'sass:map'; @use '../core/style/elevation'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, datepicker); /// Generates custom tokens for the mat-datepicker. -/// @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-datepicker -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - calendar-date-in-range-state-background-color: - map.get($systems, md-sys-color, primary-container), - calendar-date-in-comparison-range-state-background-color: - map.get($systems, md-sys-color, tertiary-container), - calendar-date-in-overlap-range-state-background-color: - map.get($systems, md-sys-color, secondary-container), - calendar-date-in-overlap-range-selected-state-background-color: - map.get($systems, md-sys-color, secondary), - calendar-date-selected-state-text-color: map.get($systems, md-sys-color, on-primary), - calendar-date-selected-state-background-color: map.get($systems, md-sys-color, primary), - calendar-date-selected-disabled-state-background-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38 - ), - calendar-date-today-selected-state-outline-color: map.get($systems, md-sys-color, primary), - calendar-date-focus-state-background-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) - ), - calendar-date-hover-state-background-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) - ), - toggle-active-state-icon-color: map.get($systems, md-sys-color, on-surface-variant), - toggle-icon-color: map.get($systems, md-sys-color, on-surface-variant), - calendar-body-label-text-color: map.get($systems, md-sys-color, on-surface), - calendar-period-button-text-color: map.get($systems, md-sys-color, on-surface-variant), - calendar-period-button-icon-color: map.get($systems, md-sys-color, on-surface-variant), - calendar-navigation-button-icon-color: map.get($systems, md-sys-color, on-surface-variant), - calendar-header-divider-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - calendar-header-text-color: map.get($systems, md-sys-color, on-surface-variant), - calendar-date-today-outline-color: map.get($systems, md-sys-color, primary), - calendar-date-today-disabled-state-outline-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38 - ), - calendar-date-text-color: map.get($systems, md-sys-color, on-surface), - calendar-date-outline-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - calendar-date-disabled-state-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38 +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } + + @return ( + base: ( + calendar-container-elevation-shadow:elevation.get-box-shadow(0), + calendar-container-shape: map.get($system, corner-large), + calendar-container-touch-elevation-shadow:elevation.get-box-shadow(0), + calendar-container-touch-shape: map.get($system, corner-extra-large), ), - calendar-date-preview-state-outline-color: map.get($systems, md-sys-color, primary), - range-input-separator-color: map.get($systems, md-sys-color, on-surface), - range-input-disabled-state-separator-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38 + color: ( + calendar-body-label-text-color: map.get($system, on-surface), + calendar-container-background-color: map.get($system, surface-container-high), + calendar-container-text-color: map.get($system, on-surface), + calendar-date-disabled-state-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + calendar-date-focus-state-background-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, focus-state-layer-opacity)), + calendar-date-hover-state-background-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, hover-state-layer-opacity)), + calendar-date-in-comparison-range-state-background-color:map.get($system, tertiary-container), + calendar-date-in-overlap-range-selected-state-background-color:map.get($system, secondary), + calendar-date-in-overlap-range-state-background-color:map.get($system, secondary-container), + calendar-date-in-range-state-background-color:map.get($system, primary-container), + calendar-date-outline-color: transparent, + calendar-date-preview-state-outline-color: map.get($system, primary), + calendar-date-selected-disabled-state-background-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + calendar-date-selected-state-background-color: map.get($system, primary), + calendar-date-selected-state-text-color: map.get($system, on-primary), + calendar-date-text-color: map.get($system, on-surface), + calendar-date-today-disabled-state-outline-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + calendar-date-today-outline-color: map.get($system, primary), + calendar-date-today-selected-state-outline-color: map.get($system, primary), + calendar-header-divider-color: transparent, + calendar-header-text-color: map.get($system, on-surface-variant), + calendar-navigation-button-icon-color: map.get($system, on-surface-variant), + calendar-period-button-icon-color: map.get($system, on-surface-variant), + calendar-period-button-text-color: map.get($system, on-surface-variant), + range-input-disabled-state-separator-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + range-input-disabled-state-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + range-input-separator-color: map.get($system, on-surface), + toggle-active-state-icon-color: map.get($system, on-surface-variant), + toggle-icon-color: map.get($system, on-surface-variant), ), - range-input-disabled-state-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: 0.38 + typography: ( + calendar-body-label-text-size: map.get($system, title-small-size), + calendar-body-label-text-weight: map.get($system, title-small-weight), + calendar-header-text-size: map.get($system, title-small-size), + calendar-header-text-weight: map.get($system, title-small-weight), + calendar-period-button-text-size: map.get($system, title-small-size), + calendar-period-button-text-weight: map.get($system, title-small-weight), + calendar-text-font: map.get($system, body-medium-font), + calendar-text-size: map.get($system, body-medium-size), ), - calendar-container-background-color: map.get($systems, md-sys-color, surface-container-high), - calendar-container-text-color: map.get($systems, md-sys-color, on-surface), - calendar-container-elevation-shadow: - m3-utils.hardcode(elevation.get-box-shadow(0), $exclude-hardcoded), - calendar-container-touch-elevation-shadow: - m3-utils.hardcode(elevation.get-box-shadow(0), $exclude-hardcoded), - calendar-container-shape: map.get($systems, md-sys-shape, corner-large), - calendar-container-touch-shape: map.get($systems, md-sys-shape, corner-extra-large), - calendar-text-font: map.get($systems, md-sys-typescale, body-medium-font), - calendar-text-size: map.get($systems, md-sys-typescale, body-medium-size), - calendar-body-label-text-size: map.get($systems, md-sys-typescale, title-small-size), - calendar-body-label-text-weight: map.get($systems, md-sys-typescale, title-small-weight), - calendar-period-button-text-size: map.get($systems, md-sys-typescale, title-small-size), - calendar-period-button-text-weight: map.get($systems, md-sys-typescale, title-small-weight), - calendar-header-text-size: map.get($systems, md-sys-typescale, title-small-size), - calendar-header-text-weight: map.get($systems, md-sys-typescale, title-small-weight), + density: (), ); - $variant-tokens: ( - // Color variants: - primary: (), // Default, no overrides needed. - secondary: ( - calendar-date-in-range-state-background-color: - map.get($systems, md-sys-color, secondary-container), - calendar-date-selected-state-text-color: map.get($systems, md-sys-color, on-secondary), - calendar-date-selected-state-background-color: map.get($systems, md-sys-color, secondary), - calendar-date-today-selected-state-outline-color: map.get($systems, md-sys-color, secondary), - calendar-date-today-outline-color: map.get($systems, md-sys-color, secondary), - calendar-date-preview-state-outline-color: map.get($systems, md-sys-color, secondary), - calendar-date-in-overlap-range-state-background-color: - map.get($systems, md-sys-color, primary-container), - calendar-date-in-overlap-range-selected-state-background-color: - map.get($systems, md-sys-color, primary), - ), - tertiary: ( - calendar-date-in-range-state-background-color: - map.get($systems, md-sys-color, tertiary-container), - calendar-date-selected-state-text-color: map.get($systems, md-sys-color, on-tertiary), - calendar-date-selected-state-background-color: map.get($systems, md-sys-color, tertiary), - calendar-date-today-selected-state-outline-color: map.get($systems, md-sys-color, tertiary), - calendar-date-today-outline-color: map.get($systems, md-sys-color, tertiary), - calendar-date-preview-state-outline-color: map.get($systems, md-sys-color, tertiary), - calendar-date-in-comparison-range-state-background-color: - map.get($systems, md-sys-color, primary-container), - ), - error: ( - calendar-date-in-range-state-background-color: - map.get($systems, md-sys-color, error-container), - calendar-date-selected-state-text-color: map.get($systems, md-sys-color, on-error), - calendar-date-selected-state-background-color: map.get($systems, md-sys-color, error), - calendar-date-today-selected-state-outline-color: map.get($systems, md-sys-color, error), - calendar-date-today-outline-color: map.get($systems, md-sys-color, error), - calendar-date-preview-state-outline-color: map.get($systems, md-sys-color, error), - ) + $tokens: ( ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/datepicker/calendar-body.scss b/src/material/datepicker/calendar-body.scss index d27c6edcd58e..35d03461addb 100644 --- a/src/material/datepicker/calendar-body.scss +++ b/src/material/datepicker/calendar-body.scss @@ -4,6 +4,8 @@ @use '../core/style/button-common'; @use '../core/tokens/token-utils'; @use './m2-datepicker'; +@use './m3-datepicker'; +@use '../core/tokens/m3-system'; $calendar-body-label-padding-start: 5% !default; // We don't want the label to jump around when we switch between month and year views, so we use @@ -25,6 +27,7 @@ $calendar-range-end-body-cell-size: $token-prefix: m2-datepicker.$prefix; $token-slots: m2-datepicker.get-token-slots(); +$fallbacks: m3-datepicker.get-tokens(m3-system.$theme-with-system-vars); // Styles for a highlighted calendar cell (e.g. hovered or focused). @mixin _highlighted-cell($token-name) { @@ -48,7 +51,7 @@ $token-slots: m2-datepicker.get-token-slots(); .mat-calendar-body-today { @include _unselected-cell { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(calendar-date-today-outline-color); } } @@ -61,7 +64,7 @@ $token-slots: m2-datepicker.get-token-slots(); padding-left: $calendar-body-label-side-padding; padding-right: $calendar-body-label-side-padding; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-size: token-utils.slot(calendar-body-label-text-size); font-weight: token-utils.slot(calendar-body-label-text-weight); color: token-utils.slot(calendar-body-label-text-color); @@ -92,7 +95,7 @@ $token-slots: m2-datepicker.get-token-slots(); margin: 0; // Needs to be repeated here in order to override the user agent styles. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(calendar-text-font); font-size: token-utils.slot(calendar-text-size); } @@ -188,7 +191,7 @@ $token-slots: m2-datepicker.get-token-slots(); } .mat-calendar-body-in-preview { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(calendar-date-preview-state-outline-color); } @@ -219,7 +222,7 @@ $token-slots: m2-datepicker.get-token-slots(); .mat-calendar-body-disabled { cursor: default; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { & > .mat-calendar-body-cell-content { @include _unselected-cell { color: token-utils.slot(calendar-date-disabled-state-text-color); @@ -263,7 +266,7 @@ $token-slots: m2-datepicker.get-token-slots(); // Choosing a value clearly larger than the height ensures we get the correct capsule shape. border-radius: $calendar-body-cell-radius; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(calendar-date-text-color); border-color: token-utils.slot(calendar-date-outline-color); } @@ -280,7 +283,7 @@ $token-slots: m2-datepicker.get-token-slots(); } .mat-calendar-body-active { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .cdk-keyboard-focused &, .cdk-program-focused & { @include _highlighted-cell(calendar-date-focus-state-background-color); } @@ -289,14 +292,14 @@ $token-slots: m2-datepicker.get-token-slots(); @media (hover: hover) { .mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include _highlighted-cell(calendar-date-hover-state-background-color); } } } .mat-calendar-body-selected { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(calendar-date-selected-state-background-color); color: token-utils.slot(calendar-date-selected-state-text-color); @@ -311,7 +314,7 @@ $token-slots: m2-datepicker.get-token-slots(); } } -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $range-color: token-utils.slot(calendar-date-in-range-state-background-color); $comparison-color: diff --git a/src/material/datepicker/calendar.scss b/src/material/datepicker/calendar.scss index c64748efebbc..0f2f56e08f17 100644 --- a/src/material/datepicker/calendar.scss +++ b/src/material/datepicker/calendar.scss @@ -3,6 +3,8 @@ @use '../core/focus-indicators/private'; @use '../core/tokens/token-utils'; @use './m2-datepicker'; +@use './m3-datepicker'; +@use '../core/tokens/m3-system'; $calendar-padding: 8px !default; $calendar-header-divider-width: 1px !default; @@ -17,6 +19,7 @@ $calendar-arrow-disabled-opacity: 0.5 !default; $token-prefix: m2-datepicker.$prefix; $token-slots: m2-datepicker.get-token-slots(); +$fallbacks: m3-datepicker.get-tokens(m3-system.$theme-with-system-vars); .mat-calendar { display: block; @@ -24,7 +27,7 @@ $token-slots: m2-datepicker.get-token-slots(); // Prevents layout issues if the line height bleeds in from the body (see #29756). line-height: normal; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(calendar-text-font); font-size: token-utils.slot(calendar-text-size); } @@ -53,7 +56,7 @@ $token-slots: m2-datepicker.get-token-slots(); min-width: 0; margin: 0 8px; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-size: token-utils.slot(calendar-period-button-text-size); font-weight: token-utils.slot(calendar-period-button-text-weight); --mat-button-text-label-text-color: #{token-utils.slot(calendar-period-button-text-color)}; @@ -67,7 +70,7 @@ $token-slots: m2-datepicker.get-token-slots(); margin: 0 0 0 $calendar-arrow-size; vertical-align: middle; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { fill: token-utils.slot(calendar-period-button-icon-color); } @@ -87,7 +90,7 @@ $token-slots: m2-datepicker.get-token-slots(); .mat-calendar-previous-button, .mat-calendar-next-button { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // Needs need a bit more specificity to avoid being overwritten by the .mat-icon-button. .mat-datepicker-content &:not(.mat-mdc-button-disabled) { color: token-utils.slot(calendar-navigation-button-icon-color); @@ -109,7 +112,7 @@ $token-slots: m2-datepicker.get-token-slots(); text-align: center; padding: 0 0 $calendar-padding 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(calendar-header-text-color); font-size: token-utils.slot(calendar-header-text-size); font-weight: token-utils.slot(calendar-header-text-weight); @@ -130,7 +133,7 @@ $token-slots: m2-datepicker.get-token-slots(); right: -$calendar-padding; height: $calendar-header-divider-width; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(calendar-header-divider-color); } } diff --git a/src/material/datepicker/date-range-input.scss b/src/material/datepicker/date-range-input.scss index cb58af0cfa70..f493dfd116ae 100644 --- a/src/material/datepicker/date-range-input.scss +++ b/src/material/datepicker/date-range-input.scss @@ -3,12 +3,18 @@ @use '../core/style/variables'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; @use '../core/tokens/token-utils'; @use './m2-datepicker'; +@use './m3-datepicker'; $date-range-input-separator-spacing: 4px; $date-range-input-part-max-width: calc(50% - #{$date-range-input-separator-spacing}); +$token-prefix: m2-datepicker.$prefix; +$token-slots: m2-datepicker.get-token-slots(); +$fallbacks: m3-datepicker.get-tokens(m3-system.$theme-with-system-vars); + @mixin _placeholder-transition($property) { transition: #{$property} variables.$swift-ease-out-duration math.div(variables.$swift-ease-out-duration, 3) @@ -32,7 +38,7 @@ $date-range-input-part-max-width: calc(50% - #{$date-range-input-separator-spaci @include _placeholder-transition(opacity); margin: 0 $date-range-input-separator-spacing; - @include token-utils.use-tokens(m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(range-input-separator-color); .mat-form-field-disabled & { @@ -100,7 +106,7 @@ $date-range-input-part-max-width: calc(50% - #{$date-range-input-separator-spaci @include _placeholder-transition(color); } - @include token-utils.use-tokens(m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &[disabled] { color: token-utils.slot(range-input-disabled-state-text-color); diff --git a/src/material/datepicker/datepicker-content.scss b/src/material/datepicker/datepicker-content.scss index ce68ddc2f2b5..f59e86ddb7b5 100644 --- a/src/material/datepicker/datepicker-content.scss +++ b/src/material/datepicker/datepicker-content.scss @@ -1,5 +1,11 @@ @use './m2-datepicker'; +@use './m3-datepicker'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-datepicker.$prefix; +$token-slots: m2-datepicker.get-token-slots(); +$fallbacks: m3-datepicker.get-tokens(m3-system.$theme-with-system-vars); $calendar-padding: 8px; $non-touch-calendar-cell-size: 40px; @@ -62,8 +68,7 @@ $touch-max-height: 788px; display: block; border-radius: 4px; - @include token-utils.use-tokens( - m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(calendar-container-background-color); color: token-utils.slot(calendar-container-text-color); box-shadow: token-utils.slot(calendar-container-elevation-shadow); @@ -114,8 +119,7 @@ $touch-max-height: 788px; display: block; max-height: 80vh; - @include token-utils.use-tokens( - m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { box-shadow: token-utils.slot(calendar-container-touch-elevation-shadow); border-radius: token-utils.slot(calendar-container-touch-shape); } diff --git a/src/material/datepicker/datepicker-toggle.scss b/src/material/datepicker/datepicker-toggle.scss index 68de3278d185..8add2e568254 100644 --- a/src/material/datepicker/datepicker-toggle.scss +++ b/src/material/datepicker/datepicker-toggle.scss @@ -1,19 +1,25 @@ @use '@angular/cdk'; @use './m2-datepicker'; +@use './m3-datepicker'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-datepicker.$prefix; +$token-slots: m2-datepicker.get-token-slots(); +$fallbacks: m3-datepicker.get-tokens(m3-system.$theme-with-system-vars); // We support the case where the form field is disabled, but the datepicker is not. // MDC sets `pointer-events: none` on disabled form fields which prevents clicks on the toggle. .mat-datepicker-toggle { pointer-events: auto; - @include token-utils.use-tokens(m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(toggle-icon-color); } } .mat-datepicker-toggle-active { - @include token-utils.use-tokens(m2-datepicker.$prefix, m2-datepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(toggle-active-state-icon-color); } } diff --git a/src/material/dialog/_dialog-theme.scss b/src/material/dialog/_dialog-theme.scss index fd28b6990657..c36f05ce2e51 100644 --- a/src/material/dialog/_dialog-theme.scss +++ b/src/material/dialog/_dialog-theme.scss @@ -1,15 +1,17 @@ @use 'sass:map'; @use '../core/style/sass-utils'; @use './m2-dialog'; +@use './m3-dialog'; @use '../core/tokens/token-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-dialog.$prefix, + map.get(m3-dialog.get-tokens($theme), base)); } @else { // Add default values for tokens not related to color, typography, or density. @include sass-utils.current-selector-or-root() { @@ -21,7 +23,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-dialog.$prefix, + map.get(m3-dialog.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -32,7 +36,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-dialog.$prefix, + map.get(m3-dialog.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -43,7 +49,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-dialog.$prefix, + map.get(m3-dialog.get-tokens($theme), density)); } @else { } } @@ -65,7 +73,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-dialog') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -80,15 +91,3 @@ } } } - -@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( - m2-dialog.$prefix, - map.get($tokens, m2-dialog.$prefix) - ); - } -} diff --git a/src/material/dialog/_m3-dialog.scss b/src/material/dialog/_m3-dialog.scss index 23f6a4e613ac..0cbea35ce85f 100644 --- a/src/material/dialog/_m3-dialog.scss +++ b/src/material/dialog/_m3-dialog.scss @@ -5,43 +5,45 @@ $prefix: (mat, dialog); /// Generates custom tokens for the dialog. -/// @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 dialog -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + // headline-padding: // The vertical padding values are a bit weird, because MDC uses a `::before` pseudo // element to size the title which in turn means that we can't set a specific padding // and get the exact same space out of it. These values were determined through // trial and error so that the first line of text is 24px from the top and the bottom // of the text is 16px from the content under it. - $tokens: ( - actions-alignment: m3-utils.hardcode(flex-end, $exclude-hardcoded), - actions-padding: m3-utils.hardcode(16px 24px, $exclude-hardcoded), - container-color: map.get($systems, md-sys-color, surface), - container-elevation-shadow: m3-utils.hardcode(none, $exclude-hardcoded), - container-max-width: m3-utils.hardcode(560px, $exclude-hardcoded), - container-min-width: m3-utils.hardcode(280px, $exclude-hardcoded), - container-shape: map.get($systems, md-sys-shape, corner-extra-large), - container-small-max-width: - m3-utils.hardcode(calc(100vw - 32px), $exclude-hardcoded), - content-padding: m3-utils.hardcode(20px 24px, $exclude-hardcoded), - headline-padding: m3-utils.hardcode(6px 24px 13px, $exclude-hardcoded), - subhead-color: map.get($systems, md-sys-color, on-surface), - subhead-font: map.get($systems, md-sys-typescale, headline-small-font), - subhead-line-height: map.get($systems, md-sys-typescale, headline-small-line-height), - subhead-size: map.get($systems, md-sys-typescale, headline-small-size), - subhead-tracking: map.get($systems, md-sys-typescale, headline-small-tracking), - subhead-weight: map.get($systems, md-sys-typescale, headline-small-weight), - supporting-text-color: map.get($systems, md-sys-color, on-surface-variant), - supporting-text-font: map.get($systems, md-sys-typescale, body-medium-font), - supporting-text-line-height: map.get($systems, md-sys-typescale, body-medium-line-height), - supporting-text-size: map.get($systems, md-sys-typescale, body-medium-size), - supporting-text-tracking: map.get($systems, md-sys-typescale, body-medium-tracking), - supporting-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - with-actions-content-padding: m3-utils.hardcode(20px 24px 0, $exclude-hardcoded), + @return ( + base: ( + actions-alignment: flex-end, + actions-padding: 16px 24px, + container-elevation-shadow: none, + container-max-width: 560px, + container-min-width: 280px, + container-shape: map.get($system, corner-extra-large), + container-small-max-width: calc(100vw - 32px), + content-padding: 20px 24px, + headline-padding: 6px 24px 13px, + with-actions-content-padding: 20px 24px 0, + ), + color: ( + container-color: map.get($system, surface), + subhead-color: map.get($system, on-surface), + supporting-text-color: map.get($system, on-surface-variant), + ), + typography: ( + subhead-font: map.get($system, headline-small-font), + subhead-line-height: map.get($system, headline-small-line-height), + subhead-size: map.get($system, headline-small-size), + subhead-tracking: map.get($system, headline-small-tracking), + subhead-weight: map.get($system, headline-small-weight), + supporting-text-font: map.get($system, body-medium-font), + supporting-text-line-height: map.get($system, body-medium-line-height), + supporting-text-size: map.get($system, body-medium-size), + supporting-text-tracking: map.get($system, body-medium-tracking), + supporting-text-weight: map.get($system, body-medium-weight), + ), + density: (), ); - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } diff --git a/src/material/dialog/dialog.scss b/src/material/dialog/dialog.scss index 7b89b5dc9007..58d786d4a58f 100644 --- a/src/material/dialog/dialog.scss +++ b/src/material/dialog/dialog.scss @@ -1,7 +1,9 @@ @use '@angular/cdk'; @use './m2-dialog'; +@use './m3-dialog'; @use '../core/tokens/token-utils'; @use '../core/style/variables'; +@use '../core/tokens/m3-system'; // Dialog content max height. This has been copied from the standard dialog // and is needed to make the dialog content scrollable. @@ -22,6 +24,7 @@ $_emit-fallbacks: true; $token-prefix: m2-dialog.$prefix; $token-slots: m2-dialog.get-token-slots(); +$fallbacks: m3-dialog.get-tokens(m3-system.$theme-with-system-vars); // Note that we disable fallback declarations, but we don't disable fallback // values, because there are a lot of internal apps that don't include a proper @@ -42,7 +45,7 @@ $token-slots: m2-dialog.get-token-slots(); // This needs extra specificity so it doesn't get overwritten by the CDK structural styles. .cdk-overlay-pane.mat-mdc-dialog-panel { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { max-width: token-utils.slot(container-max-width, $_emit-fallbacks); min-width: token-utils.slot(container-min-width, $_emit-fallbacks); @@ -98,11 +101,11 @@ $token-slots: m2-dialog.get-token-slots(); min-width: inherit; max-width: inherit; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { box-shadow: token-utils.slot(container-elevation-shadow, $_emit-fallbacks); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-radius: token-utils.slot(container-shape, $_emit-fallbacks); background-color: token-utils.slot(container-color, $_emit-fallbacks); } @@ -142,7 +145,7 @@ $token-slots: m2-dialog.get-token-slots(); box-sizing: border-box; margin: 0 0 1px; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { padding: token-utils.slot(headline-padding, $_emit-fallbacks); } @@ -163,7 +166,7 @@ $token-slots: m2-dialog.get-token-slots(); // Nested to maintain the old specificity. .mat-mdc-dialog-container & { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(subhead-color, $_emit-fallbacks); font-family: token-utils.slot(subhead-font, if($_emit-fallbacks, inherit, null)); line-height: token-utils.slot(subhead-line-height, $_emit-fallbacks); @@ -192,7 +195,7 @@ $token-slots: m2-dialog.get-token-slots(); // Nested to maintain the old specificity. .mat-mdc-dialog-container & { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(supporting-text-color, $_emit-fallbacks); font-family: token-utils.slot(supporting-text-font, if($_emit-fallbacks, inherit, null)); line-height: token-utils.slot(supporting-text-line-height, $_emit-fallbacks); @@ -202,7 +205,7 @@ $token-slots: m2-dialog.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // These styles need a bit more specificity. .mat-mdc-dialog-container & { padding: token-utils.slot(content-padding, $_emit-fallbacks); @@ -235,7 +238,7 @@ $token-slots: m2-dialog.get-token-slots(); // For backwards compatibility, actions align at start by default. MDC usually // aligns actions at the end of the container. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { padding: token-utils.slot(actions-padding, $_emit-fallbacks); justify-content: token-utils.slot(actions-alignment, $_emit-fallbacks); } diff --git a/src/material/divider/_divider-theme.scss b/src/material/divider/_divider-theme.scss index fb079fabc028..c5ca64e939d7 100644 --- a/src/material/divider/_divider-theme.scss +++ b/src/material/divider/_divider-theme.scss @@ -2,13 +2,15 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use './m2-divider'; +@use './m3-divider'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-divider.$prefix, + map.get(m3-divider.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -19,7 +21,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-divider.$prefix, + map.get(m3-divider.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -30,14 +34,18 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-divider.$prefix, + map.get(m3-divider.get-tokens($theme), typography)); } @else { } } @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-divider.$prefix, + map.get(m3-divider.get-tokens($theme), density)); } @else { } } @@ -59,7 +67,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-divider') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -74,15 +85,3 @@ } } } - -@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( - m2-divider.$prefix, - map.get($tokens, m2-divider.$prefix) - ); - } -} diff --git a/src/material/divider/_m3-divider.scss b/src/material/divider/_m3-divider.scss index 2a1b605846c4..9259b94bcb63 100644 --- a/src/material/divider/_m3-divider.scss +++ b/src/material/divider/_m3-divider.scss @@ -5,15 +5,17 @@ $prefix: (mat, divider); /// Generates custom tokens for the mat-divider. -/// @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-divider -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - width: m3-utils.hardcode(1px, $exclude-hardcoded), - color: map.get($systems, md-sys-color, outline), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + width: 1px, + ), + color: ( + color: map.get($system, outline), + ), + typography: (), + density: (), + ); } diff --git a/src/material/divider/divider.scss b/src/material/divider/divider.scss index bbde097ef05d..0b4c57b1596c 100644 --- a/src/material/divider/divider.scss +++ b/src/material/divider/divider.scss @@ -1,13 +1,19 @@ @use '../core/tokens/token-utils'; @use './m2-divider'; +@use './m3-divider'; +@use '../core/tokens/m3-system'; $inset-margin: 80px; +$token-prefix: m2-divider.$prefix; +$token-slots: m2-divider.get-token-slots(); +$fallbacks: m3-divider.get-tokens(m3-system.$theme-with-system-vars); + .mat-divider { display: block; margin: 0; border-top-style: solid; - @include token-utils.use-tokens(m2-divider.$prefix, m2-divider.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-color: token-utils.slot(color); border-top-width: token-utils.slot(width); diff --git a/src/material/expansion/_expansion-theme.scss b/src/material/expansion/_expansion-theme.scss index 251fc806e543..cf56e58c72ca 100644 --- a/src/material/expansion/_expansion-theme.scss +++ b/src/material/expansion/_expansion-theme.scss @@ -1,7 +1,6 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @@ -10,7 +9,9 @@ @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-expansion.$prefix, + map.get(m3-expansion.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -21,7 +22,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-expansion.$prefix, + map.get(m3-expansion.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -32,7 +35,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-expansion.$prefix, + map.get(m3-expansion.get-tokens($theme), typography)); } @else { // TODO(mmalerba): Stop calling this and resolve resulting screen diffs. $theme: inspection.private-get-typography-back-compat-theme($theme); @@ -47,7 +52,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-expansion.$prefix, m3-expansion.get-density-tokens($theme)); + m3-expansion.$prefix, + map.get(m3-expansion.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -73,10 +79,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-expansion') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -91,15 +97,3 @@ } } } - -@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( - m2-expansion.$prefix, - map.get($tokens, m2-expansion.$prefix) - ); - } -} diff --git a/src/material/expansion/_m3-expansion.scss b/src/material/expansion/_m3-expansion.scss index f0299de8eab4..295fc6e0a7d4 100644 --- a/src/material/expansion/_m3-expansion.scss +++ b/src/material/expansion/_m3-expansion.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,43 +8,48 @@ $prefix: (mat, expansion); /// Generates custom tokens for the mat-expansion. -/// @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-expansion -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, header-text, title-medium), - m3-utils.generate-typography-tokens($systems, container-text, body-large), - ( - container-shape: m3-utils.hardcode(12px, $exclude-hardcoded), - legacy-header-indicator-display: m3-utils.hardcode(none, $exclude-hardcoded), - header-indicator-display: m3-utils.hardcode(inline-block, $exclude-hardcoded), - container-background-color: map.get($systems, md-sys-color, surface), - container-text-color: map.get($systems, md-sys-color, on-surface), - actions-divider-color: map.get($systems, md-sys-color, outline), - header-hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) - ), - header-focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) - ), - header-disabled-state-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - header-text-color: map.get($systems, md-sys-color, on-surface), - header-description-color: map.get($systems, md-sys-color, on-surface-variant), - header-indicator-color: map.get($systems, md-sys-color, on-surface-variant), - ) - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + container-shape: 12px, + header-indicator-display: inline-block, + legacy-header-indicator-display: none, + ), + color: ( + actions-divider-color: map.get($system, outline), + container-background-color: map.get($system, surface), + container-text-color: map.get($system, on-surface), + header-description-color: map.get($system, on-surface-variant), + header-disabled-state-text-color: + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + header-focus-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, focus-state-layer-opacity)), + header-hover-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, hover-state-layer-opacity)), + header-indicator-color: map.get($system, on-surface-variant), + header-text-color: map.get($system, on-surface), + ), + typography: ( + container-text-font: map.get($system, body-large-font), + container-text-line-height: map.get($system, body-large-line-height), + container-text-size: map.get($system, body-large-size), + container-text-tracking: map.get($system, body-large-tracking), + container-text-weight: map.get($system, body-large-weight), + header-text-font: map.get($system, title-medium-font), + header-text-line-height: map.get($system, title-medium-line-height), + header-text-size: map.get($system, title-medium-size), + header-text-tracking: map.get($system, title-medium-tracking), + header-text-weight: map.get($system, title-medium-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), + ); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/expansion/expansion-panel-header.scss b/src/material/expansion/expansion-panel-header.scss index c9a9af2826bc..0168628995ce 100644 --- a/src/material/expansion/expansion-panel-header.scss +++ b/src/material/expansion/expansion-panel-header.scss @@ -1,10 +1,13 @@ @use '@angular/cdk'; @use './m2-expansion'; +@use './m3-expansion'; @use '../core/tokens/token-utils'; @use './expansion-variables'; +@use '../core/tokens/m3-system'; $token-prefix: m2-expansion.$prefix; $token-slots: m2-expansion.get-token-slots(); +$fallbacks: m3-expansion.get-tokens(m3-system.$theme-with-system-vars); .mat-expansion-panel-header { display: flex; @@ -22,7 +25,7 @@ $token-slots: m2-expansion.get-token-slots(); border-radius: inherit; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(header-collapsed-state-height); font-family: token-utils.slot(header-text-font); font-size: token-utils.slot(header-text-size); @@ -115,7 +118,7 @@ $token-slots: m2-expansion.get-token-slots(); } .mat-expansion-panel-header-title { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(header-text-color); } } @@ -141,7 +144,7 @@ $token-slots: m2-expansion.get-token-slots(); .mat-expansion-panel-header-description { flex-grow: 2; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(header-description-color); } } @@ -166,7 +169,7 @@ $token-slots: m2-expansion.get-token-slots(); transform: rotate(45deg); vertical-align: middle; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(header-indicator-color); display: token-utils.slot(legacy-header-indicator-display, inline-block); @@ -185,7 +188,7 @@ $token-slots: m2-expansion.get-token-slots(); // Ideally we'd make the container `inline-flex`, but that affects M2. vertical-align: middle; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { fill: token-utils.slot(header-indicator-color); display: token-utils.slot(header-indicator-display, none); } diff --git a/src/material/expansion/expansion-panel.scss b/src/material/expansion/expansion-panel.scss index 99f62abbdab1..3afae84fd04c 100644 --- a/src/material/expansion/expansion-panel.scss +++ b/src/material/expansion/expansion-panel.scss @@ -1,12 +1,15 @@ @use '@angular/cdk'; @use './m2-expansion'; +@use './m3-expansion'; @use '../core/tokens/token-utils'; @use '../core/style/variables'; @use '../core/style/elevation'; +@use '../core/tokens/m3-system'; $token-prefix: m2-expansion.$prefix; $token-slots: m2-expansion.get-token-slots(); +$fallbacks: m3-expansion.get-tokens(m3-system.$theme-with-system-vars); .mat-expansion-panel { box-sizing: content-box; @@ -23,7 +26,7 @@ $token-slots: m2-expansion.get-token-slots(); // focus indicator relatively positions the header. position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(container-background-color); color: token-utils.slot(container-text-color); border-radius: token-utils.slot(container-shape); @@ -36,7 +39,7 @@ $token-slots: m2-expansion.get-token-slots(); border-radius: 0; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:first-of-type { border-top-right-radius: token-utils.slot(container-shape); border-top-left-radius: token-utils.slot(container-shape); @@ -105,7 +108,7 @@ $token-slots: m2-expansion.get-token-slots(); visibility: visible; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(container-text-font); font-size: token-utils.slot(container-text-size); font-weight: token-utils.slot(container-text-weight); @@ -140,7 +143,7 @@ $token-slots: m2-expansion.get-token-slots(); justify-content: flex-end; padding: 16px 8px 16px 24px; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-color: token-utils.slot(actions-divider-color); } diff --git a/src/material/form-field/_form-field-focus-overlay.scss b/src/material/form-field/_form-field-focus-overlay.scss index 02e0d96a205b..5663b37181bd 100644 --- a/src/material/form-field/_form-field-focus-overlay.scss +++ b/src/material/form-field/_form-field-focus-overlay.scss @@ -1,6 +1,13 @@ @use './m2-form-field'; +@use './m3-form-field'; @use '../core/tokens/token-utils'; @use '../core/style/layout-common'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); + // MDC text-field used to use their ripple in order to show a focus and hover effect for // text-fields. This is unnecessary because the ripples bring in a lot of unnecessary @@ -15,7 +22,7 @@ opacity: 0; pointer-events: none; // Make sure we don't block click on the prefix/suffix. - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(state-layer-color); .mat-mdc-text-field-wrapper:hover & { diff --git a/src/material/form-field/_form-field-native-select.scss b/src/material/form-field/_form-field-native-select.scss index 16279807959d..444eb7a3427a 100644 --- a/src/material/form-field/_form-field-native-select.scss +++ b/src/material/form-field/_form-field-native-select.scss @@ -1,6 +1,12 @@ @use 'sass:math'; @use './m2-form-field'; +@use './m3-form-field'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); // Width of the Material Design form-field select arrow. $mat-form-field-select-arrow-width: 10px; @@ -30,7 +36,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt } &:not(.mat-mdc-native-select-inline) { - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { option { color: token-utils.slot(select-option-text-color); } @@ -62,7 +68,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt // Make the arrow non-clickable so the user can click on the form control under it. pointer-events: none; - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(enabled-select-arrow-color); } @@ -72,7 +78,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt } } - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &.mat-focused .mat-mdc-form-field-infix::after { color: token-utils.slot(focus-select-arrow-color); } diff --git a/src/material/form-field/_form-field-subscript.scss b/src/material/form-field/_form-field-subscript.scss index ddd61049ee1e..4acea5a4402c 100644 --- a/src/material/form-field/_form-field-subscript.scss +++ b/src/material/form-field/_form-field-subscript.scss @@ -1,6 +1,12 @@ @use './m2-form-field'; +@use './m3-form-field'; @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); @mixin private-form-field-subscript() { @keyframes _mat-form-field-subscript-animation { @@ -72,7 +78,7 @@ .mat-mdc-form-field-error { display: block; - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(error-text-color); } } @@ -81,8 +87,7 @@ // jumps when hints or errors are displayed. .mat-mdc-form-field-subscript-wrapper, .mat-mdc-form-field-bottom-align::before { - @include token-utils.use-tokens( - m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include vendor-prefixes.smooth-font(); font-family: token-utils.slot(subscript-text-font); line-height: token-utils.slot(subscript-text-line-height); diff --git a/src/material/form-field/_form-field-theme.scss b/src/material/form-field/_form-field-theme.scss index bedb1810841d..c911abc5b2c4 100644 --- a/src/material/form-field/_form-field-theme.scss +++ b/src/material/form-field/_form-field-theme.scss @@ -2,17 +2,19 @@ @use './m3-form-field'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-form-field. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-form-field.$prefix, + map.get(m3-form-field.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -25,12 +27,12 @@ /// Outputs color theme styles for the mat-form-field. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the form field: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-form-field.$prefix, + map.get(m3-form-field.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -59,7 +61,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-form-field.$prefix, + map.get(m3-form-field.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -75,7 +79,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-form-field.$prefix, m3-form-field.get-density-tokens($theme)); + m3-form-field.$prefix, + map.get(m3-form-field.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -106,16 +111,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-form-field. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the form field: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-form-field') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -130,15 +133,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-form-field-tokens: token-utils.get-tokens-for( - $tokens, - m2-form-field.$prefix, - $options... - ); - @include token-utils.create-token-values(m2-form-field.$prefix, $mat-form-field-tokens); -} diff --git a/src/material/form-field/_m3-form-field.scss b/src/material/form-field/_m3-form-field.scss index 7cc6e124feb2..84e8fcafb1d0 100644 --- a/src/material/form-field/_m3-form-field.scss +++ b/src/material/form-field/_m3-form-field.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,138 +8,115 @@ $prefix: (mat, form-field); /// Generates custom tokens for the mat-form-field. -/// @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-form-field -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, container-text, body-large), - m3-utils.generate-typography-tokens($systems, subscript-text, body-small), - ( +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } + + @return ( + base: ( + filled-active-indicator-height: 1px, + filled-focus-active-indicator-height: 2px, + filled-container-shape: map.get($system, corner-extra-small), + outlined-outline-width: 1px, + outlined-focus-outline-width: 2px, + outlined-container-shape: map.get($system, corner-extra-small), + ), + color: ( disabled-input-text-placeholder-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - state-layer-color: map.get($systems, md-sys-color, on-surface), - error-text-color: map.get($systems, md-sys-color, error), - select-option-text-color: map.get($systems, md-ref-palette, neutral10), - select-disabled-option-text-color: - sass-utils.safe-color-change(map.get($systems, md-ref-palette, neutral10), $alpha: 0.38), - enabled-select-arrow-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-select-arrow-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - focus-state-layer-opacity: m3-utils.hardcode(0, $exclude-hardcoded), - focus-select-arrow-color: map.get($systems, md-sys-color, primary), - leading-icon-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-leading-icon-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - trailing-icon-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-trailing-icon-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - error-focus-trailing-icon-color: map.get($systems, md-sys-color, error), - error-hover-trailing-icon-color: map.get($systems, md-sys-color, on-error-container), - error-trailing-icon-color: map.get($systems, md-sys-color, error), - filled-active-indicator-color: map.get($systems, md-sys-color, on-surface-variant), - filled-active-indicator-height: if($exclude-hardcoded, null, 1px), - filled-caret-color: map.get($systems, md-sys-color, primary), - filled-container-color: map.get($systems, md-sys-color, surface-variant), - filled-container-shape: map.get($systems, md-sys-shape, corner-extra-small), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-leading-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-select-arrow-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-trailing-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + enabled-select-arrow-color: map.get($system, on-surface-variant), + error-focus-trailing-icon-color: map.get($system, error), + error-hover-trailing-icon-color: map.get($system, on-error-container), + error-text-color: map.get($system, error), + error-trailing-icon-color: map.get($system, error), + filled-active-indicator-color: map.get($system, on-surface-variant), + filled-caret-color: map.get($system, primary), + filled-container-color: map.get($system, surface-variant), filled-disabled-active-indicator-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), filled-disabled-container-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.04), + m3-utils.color-with-opacity(map.get($system, on-surface), 4%), filled-disabled-input-text-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), filled-disabled-label-text-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - filled-error-active-indicator-color: map.get($systems, md-sys-color, error), - filled-error-focus-active-indicator-color: map.get($systems, md-sys-color, error), - filled-error-focus-label-text-color: map.get($systems, md-sys-color, error), - filled-error-hover-active-indicator-color: - map.get($systems, md-sys-color, on-error-container), - filled-error-hover-label-text-color: map.get($systems, md-sys-color, on-error-container), - filled-error-label-text-color: map.get($systems, md-sys-color, error), - filled-focus-active-indicator-color: map.get($systems, md-sys-color, primary), - filled-focus-active-indicator-height: if($exclude-hardcoded, null, 2px), - filled-focus-label-text-color: map.get($systems, md-sys-color, primary), - filled-hover-active-indicator-color: map.get($systems, md-sys-color, on-surface), - filled-hover-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - filled-input-text-color: map.get($systems, md-sys-color, on-surface), - filled-input-text-placeholder-color: map.get($systems, md-sys-color, on-surface-variant), - filled-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - filled-label-text-font: map.get($systems, md-sys-typescale, body-large-font), - filled-label-text-size: map.get($systems, md-sys-typescale, body-large-size), - filled-label-text-tracking: map.get($systems, md-sys-typescale, body-large-tracking), - filled-label-text-weight: map.get($systems, md-sys-typescale, body-large-weight), - outlined-caret-color: map.get($systems, md-sys-color, primary), - outlined-container-shape: map.get($systems, md-sys-shape, corner-extra-small), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + filled-error-active-indicator-color: map.get($system, error), + filled-error-focus-active-indicator-color: map.get($system, error), + filled-error-focus-label-text-color: map.get($system, error), + filled-error-hover-active-indicator-color: map.get($system, on-error-container), + filled-error-hover-label-text-color: map.get($system, on-error-container), + filled-error-label-text-color: map.get($system, error), + filled-focus-active-indicator-color: map.get($system, primary), + filled-focus-label-text-color: map.get($system, primary), + filled-hover-active-indicator-color: map.get($system, on-surface), + filled-hover-label-text-color: map.get($system, on-surface-variant), + filled-input-text-color: map.get($system, on-surface), + filled-input-text-placeholder-color: map.get($system, on-surface-variant), + filled-label-text-color: map.get($system, on-surface-variant), + filled-label-text-font: map.get($system, body-large-font), + filled-label-text-size: map.get($system, body-large-size), + filled-label-text-tracking: map.get($system, body-large-tracking), + filled-label-text-weight: map.get($system, body-large-weight), + focus-select-arrow-color: map.get($system, primary), + focus-state-layer-opacity: 0, + hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + leading-icon-color: map.get($system, on-surface-variant), + outlined-caret-color: map.get($system, primary), outlined-disabled-input-text-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), outlined-disabled-label-text-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), + m3-utils.color-with-opacity(map.get($system, on-surface), 38%), outlined-disabled-outline-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.12), - outlined-error-focus-label-text-color: map.get($systems, md-sys-color, error), - outlined-error-focus-outline-color: map.get($systems, md-sys-color, error), - outlined-error-hover-label-text-color: map.get($systems, md-sys-color, on-error-container), - outlined-error-hover-outline-color: map.get($systems, md-sys-color, on-error-container), - outlined-error-label-text-color: map.get($systems, md-sys-color, error), - outlined-error-outline-color: map.get($systems, md-sys-color, error), - outlined-focus-label-text-color: map.get($systems, md-sys-color, primary), - outlined-focus-outline-color: map.get($systems, md-sys-color, primary), - outlined-focus-outline-width: if($exclude-hardcoded, null, 2px), - outlined-hover-label-text-color: map.get($systems, md-sys-color, on-surface), - outlined-hover-outline-color: map.get($systems, md-sys-color, on-surface), - outlined-input-text-color: map.get($systems, md-sys-color, on-surface), - outlined-input-text-placeholder-color: map.get($systems, md-sys-color, on-surface-variant), - outlined-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - outlined-label-text-font: map.get($systems, md-sys-typescale, body-large-font), - outlined-label-text-size: map.get($systems, md-sys-typescale, body-large-size), - outlined-label-text-tracking: map.get($systems, md-sys-typescale, body-large-tracking), - outlined-label-text-weight: map.get($systems, md-sys-typescale, body-large-weight), - outlined-outline-color: map.get($systems, md-sys-color, outline), - outlined-outline-width: if($exclude-hardcoded, null, 1px), - ) - ); - - $variant-tokens: ( - // Color variants: - primary: (), // Default, no overrides needed. - secondary: ( - focus-select-arrow-color: map.get($systems, md-sys-color, secondary), - filled-caret-color: map.get($systems, md-sys-color, secondary), - filled-focus-active-indicator-color: map.get($systems, md-sys-color, secondary), - filled-focus-label-text-color: map.get($systems, md-sys-color, secondary), - outlined-caret-color: map.get($systems, md-sys-color, secondary), - outlined-focus-label-text-color: map.get($systems, md-sys-color, secondary), - outlined-focus-outline-color: map.get($systems, md-sys-color, secondary), + m3-utils.color-with-opacity(map.get($system, on-surface), 12%), + outlined-error-focus-label-text-color: map.get($system, error), + outlined-error-focus-outline-color: map.get($system, error), + outlined-error-hover-label-text-color: map.get($system, on-error-container), + outlined-error-hover-outline-color: map.get($system, on-error-container), + outlined-error-label-text-color: map.get($system, error), + outlined-error-outline-color: map.get($system, error), + outlined-focus-label-text-color: map.get($system, primary), + outlined-focus-outline-color: map.get($system, primary), + outlined-hover-label-text-color: map.get($system, on-surface), + outlined-hover-outline-color: map.get($system, on-surface), + outlined-input-text-color: map.get($system, on-surface), + outlined-input-text-placeholder-color: map.get($system, on-surface-variant), + outlined-label-text-color: map.get($system, on-surface-variant), + outlined-label-text-font: map.get($system, body-large-font), + outlined-label-text-size: map.get($system, body-large-size), + outlined-label-text-tracking: map.get($system, body-large-tracking), + outlined-label-text-weight: map.get($system, body-large-weight), + outlined-outline-color: map.get($system, outline), + select-disabled-option-text-color: + m3-utils.color-with-opacity(map.get($system, neutral10), 38%), + select-option-text-color: map.get($system, neutral10), + state-layer-color: map.get($system, on-surface), + trailing-icon-color: map.get($system, on-surface-variant), ), - tertiary: ( - focus-select-arrow-color: map.get($systems, md-sys-color, tertiary), - filled-caret-color: map.get($systems, md-sys-color, tertiary), - filled-focus-active-indicator-color: map.get($systems, md-sys-color, tertiary), - filled-focus-label-text-color: map.get($systems, md-sys-color, tertiary), - outlined-caret-color: map.get($systems, md-sys-color, tertiary), - outlined-focus-label-text-color: map.get($systems, md-sys-color, tertiary), - outlined-focus-outline-color: map.get($systems, md-sys-color, tertiary), + typography: ( + container-text-font: map.get($system, body-large-font), + container-text-line-height: map.get($system, body-large-line-height), + container-text-size: map.get($system, body-large-size), + container-text-tracking: map.get($system, body-large-tracking), + container-text-weight: map.get($system, body-large-weight), + subscript-text-font: map.get($system, body-small-font), + subscript-text-line-height: map.get($system, body-small-line-height), + subscript-text-size: map.get($system, body-small-size), + subscript-text-tracking: map.get($system, body-small-tracking), + subscript-text-weight: map.get($system, body-small-weight), ), - error: ( - focus-select-arrow-color: map.get($systems, md-sys-color, error), - filled-caret-color: map.get($systems, md-sys-color, error), - filled-focus-active-indicator-color: map.get($systems, md-sys-color, error), - filled-focus-label-text-color: map.get($systems, md-sys-color, error), - outlined-caret-color: map.get($systems, md-sys-color, error), - outlined-focus-label-text-color: map.get($systems, md-sys-color, error), - outlined-focus-outline-color: map.get($systems, md-sys-color, error), - ) + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -5); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -5); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/form-field/_mdc-text-field-density-overrides.scss b/src/material/form-field/_mdc-text-field-density-overrides.scss index 248c159d5245..555396cd6500 100644 --- a/src/material/form-field/_mdc-text-field-density-overrides.scss +++ b/src/material/form-field/_mdc-text-field-density-overrides.scss @@ -1,5 +1,11 @@ @use './m2-form-field'; +@use './m3-form-field'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); // Mixin that includes the density styles for form fields. MDC provides their own density // styles for MDC text-field which we cannot use. MDC relies on input elements to stretch @@ -9,7 +15,7 @@ // specification. In order to support density, we need to adjust the vertical spacing to be // based on the density scale. @mixin private-text-field-density-overrides() { - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $height: token-utils.slot(container-height); .mat-mdc-form-field-infix { diff --git a/src/material/form-field/_mdc-text-field-structure-overrides.scss b/src/material/form-field/_mdc-text-field-structure-overrides.scss index 15202fb913b5..638f74925803 100644 --- a/src/material/form-field/_mdc-text-field-structure-overrides.scss +++ b/src/material/form-field/_mdc-text-field-structure-overrides.scss @@ -1,6 +1,12 @@ @use './m2-form-field'; +@use './m3-form-field'; @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); // TODO(b/263527625): should be removed when this is addressed on the MDC side. // MDC sets a will-change on this element, because of the animation. This can cause @@ -116,7 +122,7 @@ $_enable-form-field-will-change-reset: true; // is disabled, but now there's no token for it so we need to implement it ourselves. .mat-form-field-disabled .mdc-text-field__input { @include vendor-prefixes.input-placeholder { - @include token-utils.use-tokens(m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(disabled-input-text-placeholder-color); } } diff --git a/src/material/form-field/_mdc-text-field-structure.scss b/src/material/form-field/_mdc-text-field-structure.scss index 181e99a45d4c..8e017040500f 100644 --- a/src/material/form-field/_mdc-text-field-structure.scss +++ b/src/material/form-field/_mdc-text-field-structure.scss @@ -2,16 +2,19 @@ @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use './m2-form-field'; +@use './m3-form-field'; +@use '../core/tokens/m3-system'; // File contains some extra long selectors due to MDC's old styling // stylelint-disable max-line-length $token-prefix: m2-form-field.$prefix; $token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); // Includes the structural styles for the form field inherited from MDC. @mixin private-text-field-structure { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-text-field { display: inline-flex; align-items: baseline; diff --git a/src/material/form-field/form-field.scss b/src/material/form-field/form-field.scss index 65d0bed2570b..33fb658e9b0d 100644 --- a/src/material/form-field/form-field.scss +++ b/src/material/form-field/form-field.scss @@ -1,6 +1,7 @@ @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; @use './m2-form-field'; +@use './m3-form-field'; @use './form-field-subscript'; @use './form-field-focus-overlay'; @use './form-field-high-contrast'; @@ -10,6 +11,11 @@ @use './mdc-text-field-textarea-overrides'; @use './mdc-text-field-structure-overrides'; @use './mdc-text-field-density-overrides'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-form-field.$prefix; +$token-slots: m2-form-field.get-token-slots(); +$fallbacks: m3-form-field.get-tokens(m3-system.$theme-with-system-vars); // Base styles for MDC text-field, notched-outline, floating label and line-ripple. @include mdc-text-field-structure.private-text-field-structure(); @@ -45,8 +51,7 @@ $_icon-prefix-infix-padding: 4px; // To avoid problems with text-align. text-align: left; - @include token-utils.use-tokens( - m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include vendor-prefixes.smooth-font(); font-family: token-utils.slot(container-text-font); line-height: token-utils.slot(container-text-line-height); @@ -115,8 +120,7 @@ $_icon-prefix-infix-padding: 4px; } .mat-mdc-form-field-icon-prefix { - @include token-utils.use-tokens( - m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(leading-icon-color); .mat-form-field-disabled & { @@ -126,8 +130,7 @@ $_icon-prefix-infix-padding: 4px; } .mat-mdc-form-field-icon-suffix { - @include token-utils.use-tokens( - m2-form-field.$prefix, m2-form-field.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(trailing-icon-color); .mat-form-field-disabled & { diff --git a/src/material/grid-list/_grid-list-theme.scss b/src/material/grid-list/_grid-list-theme.scss index dfee81821281..0a755a710716 100644 --- a/src/material/grid-list/_grid-list-theme.scss +++ b/src/material/grid-list/_grid-list-theme.scss @@ -1,15 +1,17 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use './m2-grid-list'; +@use './m3-grid-list'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-grid-list.$prefix, + map.get(m3-grid-list.get-tokens($theme), base)); } @else { } } @@ -17,14 +19,18 @@ // Include this empty mixin for consistency with the other components. @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-grid-list.$prefix, + map.get(m3-grid-list.get-tokens($theme), color)); } @else { } } @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-grid-list.$prefix, + map.get(m3-grid-list.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,7 +41,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-grid-list.$prefix, + map.get(m3-grid-list.get-tokens($theme), density)); } @else { } } @@ -57,7 +65,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-grid-list') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -72,15 +83,3 @@ } } } - -@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( - m2-grid-list.$prefix, - map.get($tokens, m2-grid-list.$prefix) - ); - } -} diff --git a/src/material/grid-list/_m3-grid-list.scss b/src/material/grid-list/_m3-grid-list.scss index 75a882d46a38..871e8ab9e080 100644 --- a/src/material/grid-list/_m3-grid-list.scss +++ b/src/material/grid-list/_m3-grid-list.scss @@ -5,17 +5,18 @@ $prefix: (mat, grid-list); /// Generates custom tokens for the mat-grid-list. -/// @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-grid-list -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - tile-header-primary-text-size: map.get($systems, md-sys-typescale, body-large), - tile-header-secondary-text-size: map.get($systems, md-sys-typescale, body-medium), - tile-footer-primary-text-size: map.get($systems, md-sys-typescale, body-large), - tile-footer-secondary-text-size: map.get($systems, md-sys-typescale, body-medium), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: (), + typography: ( + tile-header-primary-text-size: map.get($system, body-large), + tile-header-secondary-text-size: map.get($system, body-medium), + tile-footer-primary-text-size: map.get($system, body-large), + tile-footer-secondary-text-size: map.get($system, body-medium), + ), + density: (), + ); } diff --git a/src/material/grid-list/grid-list.scss b/src/material/grid-list/grid-list.scss index 65f8d51e3dfb..b28ba72bfab2 100644 --- a/src/material/grid-list/grid-list.scss +++ b/src/material/grid-list/grid-list.scss @@ -1,8 +1,13 @@ @use '../core/style/list-common'; @use '../core/style/layout-common'; @use './m2-grid-list'; +@use './m3-grid-list'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; +$token-prefix: m2-grid-list.$prefix; +$token-slots: m2-grid-list.get-token-slots(); +$fallbacks: m3-grid-list.get-tokens(m3-system.$theme-with-system-vars); // height of tile header or footer if it has one line $one-line-height: 48px; @@ -71,8 +76,7 @@ $text-padding: 16px; } .mat-grid-tile-header { - @include token-utils.use-tokens( - m2-grid-list.$prefix, m2-grid-list.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $secondary-token-name: token-utils.slot(tile-header-secondary-text-size); font-size: token-utils.slot(tile-header-primary-text-size); @include list-common.base(#{$secondary-token-name}); @@ -80,8 +84,7 @@ $text-padding: 16px; } .mat-grid-tile-footer { - @include token-utils.use-tokens( - m2-grid-list.$prefix, m2-grid-list.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $secondary-token-name: token-utils.slot(tile-footer-secondary-text-size); font-size: token-utils.slot(tile-footer-primary-text-size); @include list-common.base(#{$secondary-token-name}); diff --git a/src/material/icon/_icon-theme.scss b/src/material/icon/_icon-theme.scss index bce7c9fafa57..38881444bad5 100644 --- a/src/material/icon/_icon-theme.scss +++ b/src/material/icon/_icon-theme.scss @@ -1,9 +1,10 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use './m2-icon'; +@use './m3-icon'; +@use 'sass:map'; @mixin _palette-colors($theme, $palette-name) { $color: inspection.get-theme-color($theme, $palette-name, text); @@ -16,19 +17,21 @@ /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-icon.$prefix, + map.get(m3-icon.get-tokens($theme), base)); } @else { } } /// Outputs color theme styles for the mat-icon. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the icon: primary, secondary, tertiary, or error -/// (If not specified, default neutral color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-icon.$prefix, + map.get(m3-icon.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -57,7 +60,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-icon.$prefix, + map.get(m3-icon.get-tokens($theme), typography)); } @else { } } @@ -66,7 +71,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-icon.$prefix, + map.get(m3-icon.get-tokens($theme), density)); } @else { } } @@ -89,13 +96,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-icon. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the icon: surface, primary, secondary, tertiary, -/// or error (If not specified, default surface color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-icon') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -110,11 +118,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-icon-tokens: token-utils.get-tokens-for($tokens, m2-icon.$prefix, $options...); - @include token-utils.create-token-values(m2-icon.$prefix, $mat-icon-tokens); -} diff --git a/src/material/icon/_m3-icon.scss b/src/material/icon/_m3-icon.scss index 9883fe468d34..c90e956518c6 100644 --- a/src/material/icon/_m3-icon.scss +++ b/src/material/icon/_m3-icon.scss @@ -5,31 +5,19 @@ $prefix: (mat, icon); /// Generates custom tokens for the mat-icon. -/// @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-icon -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - color: m3-utils.hardcode(inherit, $exclude-hardcoded), - ); +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + $color: inherit; + @if $color-variant { + $color: map.get($system, $color-variant); + } - $variant-tokens: ( - // Color variants: - surface: (), // Default, no overrides needed. - primary: ( - color: map.get($systems, md-sys-color, primary), - ), - secondary: ( - color: map.get($systems, md-sys-color, secondary), + @return ( + base: (), + color: ( + color: $color, ), - tertiary: ( - color: map.get($systems, md-sys-color, tertiary), - ), - error: ( - color: map.get($systems, md-sys-color, error), - ) + typography: (), + density: (), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/icon/icon.scss b/src/material/icon/icon.scss index 10cf58d39fa3..7607d6022f2c 100644 --- a/src/material/icon/icon.scss +++ b/src/material/icon/icon.scss @@ -1,6 +1,12 @@ @use '../core/style/vendor-prefixes'; @use './m2-icon'; +@use './m3-icon'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-icon.$prefix; +$token-slots: m2-icon.get-token-slots(); +$fallbacks: m3-icon.get-tokens(m3-system.$theme-with-system-vars); // The width/height of the icon element. $size: 24px !default; @@ -15,7 +21,7 @@ $size: 24px !default; // `warn` because there we want the additional specificity. mat-icon { &, &.mat-primary, &.mat-accent, &.mat-warn { - @include token-utils.use-tokens(m2-icon.$prefix, m2-icon.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(color); } } diff --git a/src/material/input/_input-theme.scss b/src/material/input/_input-theme.scss index e3448faab96d..ae758cdd1cfd 100644 --- a/src/material/input/_input-theme.scss +++ b/src/material/input/_input-theme.scss @@ -1,35 +1,21 @@ @use '../core/theming/theming'; -@use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/tokens/token-utils'; @mixin base($theme) { - @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); - } @else { - } + // No-op } @mixin color($theme) { - @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); - } @else { - } + // No-op } @mixin typography($theme) { - @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); - } @else { - } + // No-op } @mixin density($theme) { - @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component - } @else { - } + // No-op } /// Defines the tokens that will be available in the `overrides` mixin and for docs extraction. @@ -48,25 +34,6 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-input') { - @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); - } - } + // No-op } } - -@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' - ); -} diff --git a/src/material/list/_list-inherited-structure.scss b/src/material/list/_list-inherited-structure.scss index 1b8b30ef04f6..42b219e3c887 100644 --- a/src/material/list/_list-inherited-structure.scss +++ b/src/material/list/_list-inherited-structure.scss @@ -1,9 +1,12 @@ @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use './m2-list'; +@use './m3-list'; +@use '../core/tokens/m3-system'; $token-prefix: m2-list.$prefix; $token-slots: m2-list.get-token-slots(); +$fallbacks: m3-list.get-tokens(m3-system.$theme-with-system-vars); // Includes the structural styles for the list that were inherited from MDC. @mixin private-list-inherited-structural-styles { @@ -28,7 +31,7 @@ $token-slots: m2-list.get-token-slots(); padding-left: 16px; padding-right: 16px; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(list-item-container-color); border-radius: token-utils.slot(list-item-container-shape); @@ -46,7 +49,7 @@ $token-slots: m2-list.get-token-slots(); } &.mdc-list-item--with-one-line { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(list-item-one-line-container-height); } @@ -62,7 +65,7 @@ $token-slots: m2-list.get-token-slots(); } &.mdc-list-item--with-two-lines { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(list-item-two-line-container-height); } @@ -78,7 +81,7 @@ $token-slots: m2-list.get-token-slots(); } &.mdc-list-item--with-three-lines { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(list-item-three-line-container-height); } @@ -118,7 +121,7 @@ $token-slots: m2-list.get-token-slots(); flex-shrink: 0; pointer-events: none; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-list-item--with-leading-icon & { color: token-utils.slot(list-item-leading-icon-color); width: token-utils.slot(list-item-leading-icon-size); @@ -158,7 +161,7 @@ $token-slots: m2-list.get-token-slots(); flex-shrink: 0; pointer-events: none; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-list-item--with-trailing-meta & { font-family: token-utils.slot(list-item-trailing-supporting-text-font); line-height: token-utils.slot(list-item-trailing-supporting-text-line-height); @@ -208,7 +211,7 @@ $token-slots: m2-list.get-token-slots(); white-space: nowrap; overflow: hidden; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(list-item-label-text-color); font-family: token-utils.slot(list-item-label-text-font); line-height: token-utils.slot(list-item-label-text-line-height); @@ -259,7 +262,7 @@ $token-slots: m2-list.get-token-slots(); display: block; margin-top: 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(list-item-supporting-text-color); font-family: token-utils.slot(list-item-supporting-text-font); line-height: token-utils.slot(list-item-supporting-text-line-height); @@ -470,20 +473,20 @@ $token-slots: m2-list.get-token-slots(); .mdc-list-item__primary-text, .mdc-list-item__secondary-text { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { opacity: token-utils.slot(list-item-disabled-label-text-opacity); } } &.mdc-list-item--with-leading-icon .mdc-list-item__start { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(list-item-disabled-leading-icon-color); opacity: token-utils.slot(list-item-disabled-leading-icon-opacity); } } &.mdc-list-item--with-trailing-icon .mdc-list-item__end { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(list-item-disabled-trailing-icon-color); opacity: token-utils.slot(list-item-disabled-trailing-icon-opacity); } diff --git a/src/material/list/_list-theme.scss b/src/material/list/_list-theme.scss index 86fcbb4f05d4..bb9907fef16f 100644 --- a/src/material/list/_list-theme.scss +++ b/src/material/list/_list-theme.scss @@ -4,7 +4,6 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use '../radio/m2-radio'; @@ -14,7 +13,9 @@ @mixin base($theme) { // Add default values for tokens not related to color, typography, or density. @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-list.$prefix, + map.get(m3-list.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -25,7 +26,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-list.$prefix, + map.get(m3-list.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -104,7 +107,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-list.$prefix, m3-list.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-list.$prefix, + map.get(m3-list.get-tokens($theme), density)); } @else { $density-scale: inspection.get-theme-density($theme); @@ -161,7 +166,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-list.$prefix, + map.get(m3-list.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -194,10 +201,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-list') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -212,11 +219,3 @@ } } } - -@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' - ); - $mat-list-tokens: token-utils.get-tokens-for($tokens, m2-list.$prefix); - @include token-utils.create-token-values(m2-list.$prefix, $mat-list-tokens); -} diff --git a/src/material/list/_m3-list.scss b/src/material/list/_m3-list.scss index 4fc1ab936c2b..5dfd8e220e8b 100644 --- a/src/material/list/_m3-list.scss +++ b/src/material/list/_m3-list.scss @@ -8,11 +8,9 @@ $prefix: (mat, list); /// Generates custom tokens for the mat-list. -/// @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-list -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + // list-item-container-color // This does not match the spec, which defines this to be `md.sys.color.surface`. // However, this interferes with the use case of placing a list on other components. For example, @@ -22,64 +20,63 @@ $prefix: (mat, list); // list-item-leading-icon-size // Match spec, which has list-item-leading-icon-size of 24px. // Current version of tokens (0_161) has 18px. - $tokens: ( - active-indicator-color: map.get($systems, md-sys-color, secondary-container), - active-indicator-shape: map.get($systems, md-sys-shape, corner-full), - list-item-container-color: if($exclude-hardcoded, null, transparent), - list-item-container-shape: map.get($systems, md-sys-shape, corner-none), - list-item-disabled-label-text-color: map.get($systems, md-sys-color, on-surface), - list-item-disabled-label-text-opacity: if($exclude-hardcoded, null, 0.3), - list-item-disabled-leading-icon-color: map.get($systems, md-sys-color, on-surface), - list-item-disabled-leading-icon-opacity: if($exclude-hardcoded, null, 0.38), - list-item-disabled-state-layer-color: map.get($systems, md-sys-color, on-surface), - list-item-disabled-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - list-item-disabled-trailing-icon-color: map.get($systems, md-sys-color, on-surface), - list-item-disabled-trailing-icon-opacity: if($exclude-hardcoded, null, 0.38), - list-item-focus-label-text-color: map.get($systems, md-sys-color, on-surface), - list-item-focus-state-layer-color: map.get($systems, md-sys-color, on-surface), - list-item-focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity), - list-item-hover-label-text-color: map.get($systems, md-sys-color, on-surface), - list-item-hover-state-layer-color: map.get($systems, md-sys-color, on-surface), - list-item-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - list-item-label-text-color: map.get($systems, md-sys-color, on-surface), - list-item-label-text-font: map.get($systems, md-sys-typescale, body-large-font), - list-item-label-text-line-height: map.get($systems, md-sys-typescale, body-large-line-height), - list-item-label-text-size: map.get($systems, md-sys-typescale, body-large-size), - list-item-label-text-tracking: map.get($systems, md-sys-typescale, body-large-tracking), - list-item-label-text-weight: map.get($systems, md-sys-typescale, body-large-weight), - list-item-leading-avatar-color: map.get($systems, md-sys-color, primary-container), - list-item-leading-avatar-shape: map.get($systems, md-sys-shape, corner-full), - list-item-leading-avatar-size: if($exclude-hardcoded, null, 40px), - list-item-leading-icon-color: map.get($systems, md-sys-color, on-surface-variant), - list-item-leading-icon-size: if($exclude-hardcoded, null, 24px), - list-item-selected-trailing-icon-color: map.get($systems, md-sys-color, primary), - list-item-supporting-text-color: map.get($systems, md-sys-color, on-surface-variant), - list-item-supporting-text-font: map.get($systems, md-sys-typescale, body-medium-font), - list-item-supporting-text-line-height: - map.get($systems, md-sys-typescale, body-medium-line-height), - list-item-supporting-text-size: map.get($systems, md-sys-typescale, body-medium-size), - list-item-supporting-text-tracking: map.get($systems, md-sys-typescale, body-medium-tracking), - list-item-supporting-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - list-item-trailing-icon-color: map.get($systems, md-sys-color, on-surface-variant), - list-item-trailing-icon-size: if($exclude-hardcoded, null, 24px), - list-item-trailing-supporting-text-color: map.get($systems, md-sys-color, on-surface-variant), - list-item-trailing-supporting-text-font: map.get($systems, md-sys-typescale, label-small-font), - list-item-trailing-supporting-text-line-height: - map.get($systems, md-sys-typescale, label-small-line-height), - list-item-trailing-supporting-text-size: map.get($systems, md-sys-typescale, label-small-size), - list-item-trailing-supporting-text-tracking: - map.get($systems, md-sys-typescale, label-small-tracking), - list-item-trailing-supporting-text-weight: - map.get($systems, md-sys-typescale, label-small-weight), + @return ( + base: (), + color: ( + active-indicator-color: map.get($system, secondary-container), + active-indicator-shape: map.get($system, corner-full), + list-item-container-color: transparent, + list-item-container-shape: map.get($system, corner-none), + list-item-disabled-label-text-color: map.get($system, on-surface), + list-item-disabled-label-text-opacity: 0.3, + list-item-disabled-leading-icon-color: map.get($system, on-surface), + list-item-disabled-leading-icon-opacity: 0.38, + list-item-disabled-state-layer-color: map.get($system, on-surface), + list-item-disabled-state-layer-opacity: map.get($system, focus-state-layer-opacity), + list-item-disabled-trailing-icon-color: map.get($system, on-surface), + list-item-disabled-trailing-icon-opacity: 0.38, + list-item-focus-label-text-color: map.get($system, on-surface), + list-item-focus-state-layer-color: map.get($system, on-surface), + list-item-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + list-item-hover-label-text-color: map.get($system, on-surface), + list-item-hover-state-layer-color: map.get($system, on-surface), + list-item-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + list-item-label-text-color: map.get($system, on-surface), + list-item-leading-avatar-color: map.get($system, primary-container), + list-item-leading-avatar-shape: map.get($system, corner-full), + list-item-leading-avatar-size: 40px, + list-item-leading-icon-color: map.get($system, on-surface-variant), + list-item-leading-icon-size: 24px, + list-item-selected-trailing-icon-color: map.get($system, primary), + list-item-supporting-text-color: map.get($system, on-surface-variant), + list-item-trailing-icon-color: map.get($system, on-surface-variant), + list-item-trailing-icon-size: 24px, + list-item-trailing-supporting-text-color: map.get($system, on-surface-variant), + ), + typography: ( + list-item-label-text-font: map.get($system, body-large-font), + list-item-label-text-line-height: map.get($system, body-large-line-height), + list-item-label-text-size: map.get($system, body-large-size), + list-item-label-text-tracking: map.get($system, body-large-tracking), + list-item-label-text-weight: map.get($system, body-large-weight), + list-item-supporting-text-font: map.get($system, body-medium-font), + list-item-supporting-text-line-height: map.get($system, body-medium-line-height), + list-item-supporting-text-size: map.get($system, body-medium-size), + list-item-supporting-text-tracking: map.get($system, body-medium-tracking), + list-item-supporting-text-weight: map.get($system, body-medium-weight), + list-item-trailing-supporting-text-font: map.get($system, label-small-font), + list-item-trailing-supporting-text-line-height: map.get($system, label-small-line-height), + list-item-trailing-supporting-text-size: map.get($system, label-small-size), + list-item-trailing-supporting-text-tracking: map.get($system, label-small-tracking), + list-item-trailing-supporting-text-weight: map.get($system, label-small-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -5); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -5); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/list/list.scss b/src/material/list/list.scss index 210396e57b57..7cc4cacccf65 100644 --- a/src/material/list/list.scss +++ b/src/material/list/list.scss @@ -1,13 +1,19 @@ @use '../core/style/layout-common'; @use './m2-list'; +@use './m3-list'; @use '../core/tokens/token-utils'; @use './list-item-hcm-indicator'; @use './list-inherited-structure'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-list.$prefix; +$token-slots: m2-list.get-token-slots(); +$fallbacks: m3-list.get-tokens(m3-system.$theme-with-system-vars); @include list-inherited-structure.private-list-inherited-structural-styles; // Add additional slots for the MDC list tokens, needed in Angular Material. -@include token-utils.use-tokens(m2-list.$prefix, m2-list.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // MDC allows focus and hover colors to take precedence over disabled color. We add the disabled // color here with higher specificity so that the disabled color takes precedence. // TODO(mmalerba): Dicuss with MDC whether to change this in their code. @@ -170,7 +176,7 @@ mat-action-list button { } } -@include token-utils.use-tokens(m2-list.$prefix, m2-list.get-token-slots()) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-list-item--with-leading-icon .mdc-list-item__start { margin-inline-start: token-utils.slot(list-item-leading-icon-start-space); margin-inline-end: token-utils.slot(list-item-leading-icon-end-space); diff --git a/src/material/menu/_m3-menu.scss b/src/material/menu/_m3-menu.scss index a23b6da9e49e..1aef1bcad6a5 100644 --- a/src/material/menu/_m3-menu.scss +++ b/src/material/menu/_m3-menu.scss @@ -1,5 +1,4 @@ @use 'sass:map'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/style/elevation'; @@ -7,39 +6,39 @@ $prefix: (mat, menu); /// Generates custom tokens for the mat-menu. -/// @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-menu -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, item-label-text, label-large), - ( - container-shape: map.get($systems, md-sys-shape, corner-extra-small), - divider-color: map.get($systems, md-sys-color, surface-variant), - divider-bottom-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - divider-top-spacing: m3-utils.hardcode(8px, $exclude-hardcoded), - item-label-text-color: map.get($systems, md-sys-color, on-surface), - item-icon-color: map.get($systems, md-sys-color, on-surface-variant), - item-icon-size: m3-utils.hardcode(24px, $exclude-hardcoded), - item-hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) - ), - item-focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), - $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) - ), - item-spacing: m3-utils.hardcode(12px, $exclude-hardcoded), - item-leading-spacing: m3-utils.hardcode(12px, $exclude-hardcoded), - item-trailing-spacing: m3-utils.hardcode(12px, $exclude-hardcoded), - item-with-icon-leading-spacing: m3-utils.hardcode(12px, $exclude-hardcoded), - item-with-icon-trailing-spacing: m3-utils.hardcode(12px, $exclude-hardcoded), - container-color: map.get($systems, md-sys-color, surface-container), - container-elevation-shadow: m3-utils.hardcode( - elevation.get-box-shadow(2), $exclude-hardcoded), - ) - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + divider-bottom-spacing: 8px, + divider-top-spacing: 8px, + item-icon-size: 24px, + item-spacing: 12px, + item-leading-spacing: 12px, + item-trailing-spacing: 12px, + item-with-icon-leading-spacing: 12px, + item-with-icon-trailing-spacing: 12px, + ), + color: ( + container-shape: map.get($system, corner-extra-small), + divider-color: map.get($system, surface-variant), + item-label-text-color: map.get($system, on-surface), + item-icon-color: map.get($system, on-surface-variant), + item-hover-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, hover-state-layer-opacity)), + item-focus-state-layer-color: m3-utils.color-with-opacity( + map.get($system, on-surface), map.get($system, focus-state-layer-opacity)), + container-color: map.get($system, surface-container), + container-elevation-shadow: elevation.get-box-shadow(2), + ), + typography: ( + item-label-text-font: map.get($system, label-large-font), + item-label-text-line-height: map.get($system, label-large-line-height), + item-label-text-size: map.get($system, label-large-size), + item-label-text-tracking: map.get($system, label-large-tracking), + item-label-text-weight: map.get($system, label-large-weight), + ), + density: (), + ); } diff --git a/src/material/menu/_menu-theme.scss b/src/material/menu/_menu-theme.scss index 70666842a876..97418c06d837 100644 --- a/src/material/menu/_menu-theme.scss +++ b/src/material/menu/_menu-theme.scss @@ -1,15 +1,17 @@ @use 'sass:map'; @use './m2-menu'; +@use './m3-menu'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-menu.$prefix, + map.get(m3-menu.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -20,7 +22,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-menu.$prefix, + map.get(m3-menu.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -31,7 +35,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-menu.$prefix, + map.get(m3-menu.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -42,7 +48,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-menu.$prefix, + map.get(m3-menu.get-tokens($theme), density)); } @else { } } @@ -64,7 +72,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-menu') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -79,15 +90,3 @@ } } } - -@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( - m2-menu.$prefix, - map.get($tokens, m2-menu.$prefix) - ); - } -} diff --git a/src/material/menu/menu.scss b/src/material/menu/menu.scss index 517f0626b524..705860505709 100644 --- a/src/material/menu/menu.scss +++ b/src/material/menu/menu.scss @@ -1,12 +1,15 @@ @use '@angular/cdk'; @use './m2-menu'; +@use './m3-menu'; @use '../core/tokens/token-utils'; @use '../core/style/menu-common'; @use '../core/style/button-common'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; $token-prefix: m2-menu.$prefix; $token-slots: m2-menu.get-token-slots(); +$fallbacks: m3-menu.get-tokens(m3-system.$theme-with-system-vars); // Prevent rendering mat-menu as it can affect the flex layout. mat-menu { @@ -24,7 +27,7 @@ mat-menu { flex: 1; white-space: normal; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(item-label-text-font); line-height: token-utils.slot(item-label-text-line-height); font-size: token-utils.slot(item-label-text-size); @@ -62,7 +65,7 @@ mat-menu { outline: 0; animation: _mat-menu-enter 120ms cubic-bezier(0, 0, 0.2, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-radius: token-utils.slot(container-shape); background-color: token-utils.slot(container-color); box-shadow: token-utils.slot(container-elevation-shadow); @@ -106,7 +109,7 @@ mat-menu { .mat-divider { // Use margin instead of padding since divider uses border-top to render out the line. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(divider-color); margin-bottom: token-utils.slot(divider-bottom-spacing); margin-top: token-utils.slot(divider-top-spacing); @@ -135,14 +138,14 @@ mat-menu { margin: 0; // Resolves an issue where buttons have an extra 2px margin on Safari. min-height: 48px; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { padding-left: token-utils.slot(item-leading-spacing); padding-right: token-utils.slot(item-trailing-spacing); } @include button-common.reset; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $icons-selector: '.material-icons, mat-icon, [matButtonIcon]'; [dir='rtl'] & { @@ -161,7 +164,7 @@ mat-menu { } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // The class selector isn't specific enough to overide the link pseudo selectors so we need // to target them specifically, otherwise the item color might be overwritten by the user // agent resets of the app. @@ -201,7 +204,7 @@ mat-menu { .mat-icon { flex-shrink: 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { margin-right: token-utils.slot(item-spacing); height: token-utils.slot(item-icon-size); width: token-utils.slot(item-icon-size); @@ -213,14 +216,14 @@ mat-menu { .mat-icon { margin-right: 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { margin-left: token-utils.slot(item-spacing); } } } &:not([disabled]) { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:hover { background-color: token-utils.slot(item-hover-state-layer-color); } @@ -243,7 +246,7 @@ mat-menu { } .mat-mdc-menu-submenu-icon { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include menu-common.item-submenu-icon( token-utils.slot(item-spacing), token-utils.slot(item-icon-size) diff --git a/src/material/paginator/_m3-paginator.scss b/src/material/paginator/_m3-paginator.scss index 8abc6fd5102e..bd3fc2321130 100644 --- a/src/material/paginator/_m3-paginator.scss +++ b/src/material/paginator/_m3-paginator.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,29 +8,30 @@ $prefix: (mat, paginator); /// Generates custom tokens for the mat-paginator. -/// @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-paginator -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, container-text, body-small), - ( - container-text-color: map.get($systems, md-sys-color, on-surface), - container-background-color: map.get($systems, md-sys-color, surface), - enabled-icon-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-icon-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - select-trigger-text-size: map.get($systems, md-sys-typescale, body-small-size), - ) - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: (), + typography: ( + container-background-color: map.get($system, surface), + container-text-font: map.get($system, body-small-font), + container-text-line-height: map.get($system, body-small-line-height), + container-text-size: map.get($system, body-small-size), + container-text-tracking: map.get($system, body-small-tracking), + container-text-weight: map.get($system, body-small-weight), + disabled-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + enabled-icon-color: map.get($system, on-surface-variant), + select-trigger-text-size: map.get($system, body-small-size), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), + ); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -5); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -5); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/paginator/_paginator-theme.scss b/src/material/paginator/_paginator-theme.scss index af9dd4817270..b1be2f61ec27 100644 --- a/src/material/paginator/_paginator-theme.scss +++ b/src/material/paginator/_paginator-theme.scss @@ -1,24 +1,26 @@ @use 'sass:map'; -@use 'sass:meta'; @use './m2-paginator'; @use './m3-paginator'; @use '../core/style/sass-utils'; @use '../core/typography/typography'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-paginator.$prefix, + map.get(m3-paginator.get-tokens($theme), base)); } @else { } } @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-paginator.$prefix, + map.get(m3-paginator.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -29,7 +31,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-paginator.$prefix, + map.get(m3-paginator.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -39,17 +43,10 @@ } @mixin density($theme) { - $density-scale: inspection.get-theme-density($theme); - $form-field-density: if( - (meta.type-of($density-scale) == 'number' and $density-scale >= -4) or - ($density-scale == maximum), - -4, - $density-scale - ); - @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-paginator.$prefix, m3-paginator.get-density-tokens($theme)); + m3-paginator.$prefix, + map.get(m3-paginator.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -75,10 +72,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-paginator') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -93,15 +90,3 @@ } } } - -@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( - m2-paginator.$prefix, - map.get($tokens, m2-paginator.$prefix) - ); - } -} diff --git a/src/material/paginator/paginator.scss b/src/material/paginator/paginator.scss index f25fe623a386..7020d78d0659 100644 --- a/src/material/paginator/paginator.scss +++ b/src/material/paginator/paginator.scss @@ -1,7 +1,9 @@ @use '@angular/cdk'; @use './m2-paginator'; +@use './m3-paginator'; @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; $padding: 0 8px; $page-size-margin-right: 8px; @@ -16,11 +18,12 @@ $button-icon-size: 28px; $token-prefix: m2-paginator.$prefix; $token-slots: m2-paginator.get-token-slots(); +$fallbacks: m3-paginator.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-paginator { display: block; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include vendor-prefixes.smooth-font(); color: token-utils.slot(container-text-color); background-color: token-utils.slot(container-background-color); @@ -67,7 +70,7 @@ $token-slots: m2-paginator.get-token-slots(); flex-wrap: wrap; width: 100%; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { min-height: token-utils.slot(container-size); } } @@ -105,7 +108,7 @@ $token-slots: m2-paginator.get-token-slots(); display: inline-block; width: $button-icon-size; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { fill: token-utils.slot(enabled-icon-color); .mat-mdc-icon-button[aria-disabled] & { @@ -135,7 +138,7 @@ $token-slots: m2-paginator.get-token-slots(); } .mat-mdc-paginator-touch-target { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { display: token-utils.slot(touch-target-display); } diff --git a/src/material/progress-bar/_m3-progress-bar.scss b/src/material/progress-bar/_m3-progress-bar.scss index dd7bda9673a4..0aaa79fdf8d5 100644 --- a/src/material/progress-bar/_m3-progress-bar.scss +++ b/src/material/progress-bar/_m3-progress-bar.scss @@ -5,34 +5,24 @@ $prefix: (mat, progress-bar); /// Generates the tokens for MDC linear-progress -/// @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 linear-progress -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - active-indicator-color: map.get($systems, md-sys-color, primary), - active-indicator-height: if($exclude-hardcoded, null, 4px), - track-color: map.get($systems, md-sys-color, surface-variant), - track-height: if($exclude-hardcoded, null, 4px), - track-shape: map.get($systems, md-sys-shape, corner-none) - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - active-indicator-color: map.get($systems, md-sys-color, secondary), - track-color: map.get($systems, md-sys-color, secondary-container), - ), - tertiary: ( - active-indicator-color: map.get($systems, md-sys-color, tertiary), - track-color: map.get($systems, md-sys-color, tertiary-container), + @return ( + base: ( + active-indicator-height: 4px, + track-height: 4px, + track-shape: map.get($system, corner-none) ), - error: ( - active-indicator-color: map.get($systems, md-sys-color, error), - track-color: map.get($systems, md-sys-color, error-container), + color: ( + active-indicator-color: map.get($system, primary), + track-color: map.get($system, surface-variant), ), + typography: (), + density: (), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/progress-bar/_progress-bar-theme.scss b/src/material/progress-bar/_progress-bar-theme.scss index 50d554be6fa8..4a0c6b532b3a 100644 --- a/src/material/progress-bar/_progress-bar-theme.scss +++ b/src/material/progress-bar/_progress-bar-theme.scss @@ -1,16 +1,19 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use './m2-progress-bar'; +@use './m3-progress-bar'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-progress-bar. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-progress-bar.$prefix, + map.get(m3-progress-bar.get-tokens($theme), base)); } @else { // Add default values for tokens not related to color, typography, or density. @include sass-utils.current-selector-or-root() { @@ -34,9 +37,11 @@ /// @param {ArgList} Additional optional arguments (only supported for M3 themes): /// $color-variant: The color variant to use for the progress bar: primary, secondary, tertiary, /// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-progress-bar.$prefix, + map.get(m3-progress-bar.get-tokens($theme, $color-variant), color)); } @else { .mat-mdc-progress-bar { @include _palette-styles($theme, primary); @@ -80,13 +85,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-progress-bar. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the progress bar: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-progress-bar') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -101,11 +107,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $tokens: token-utils.get-tokens-for($tokens, m2-progress-bar.$prefix, $options...); - @include token-utils.create-token-values(m2-progress-bar.$prefix, $tokens); -} diff --git a/src/material/progress-bar/progress-bar.scss b/src/material/progress-bar/progress-bar.scss index f30c6fb8a5e5..cd026332e1f1 100644 --- a/src/material/progress-bar/progress-bar.scss +++ b/src/material/progress-bar/progress-bar.scss @@ -1,10 +1,13 @@ @use '@angular/cdk'; @use './m2-progress-bar'; +@use './m3-progress-bar'; @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; $token-prefix: m2-progress-bar.$prefix; $token-slots: m2-progress-bar.get-token-slots(); +$fallbacks: m3-progress-bar.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-progress-bar { // Explicitly set to `block` since the browser defaults custom elements to `inline`. @@ -44,7 +47,7 @@ $token-slots: m2-progress-bar.get-token-slots(); overflow-x: hidden; transition: opacity 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $track-variable: token-utils.slot(track-height); $indicator-height-variable: token-utils.slot(active-indicator-height); height: max(#{$track-variable}, #{$indicator-height-variable}); @@ -65,7 +68,7 @@ $token-slots: m2-progress-bar.get-token-slots(); transform-origin: top left; transition: transform 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(active-indicator-height); } @@ -86,7 +89,7 @@ $token-slots: m2-progress-bar.get-token-slots(); animation: none; border-top-style: solid; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(active-indicator-color); border-top-width: token-utils.slot(active-indicator-height); } @@ -101,7 +104,7 @@ $token-slots: m2-progress-bar.get-token-slots(); width: 100%; overflow: hidden; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(track-height); border-radius: token-utils.slot(track-shape); } @@ -119,7 +122,7 @@ $token-slots: m2-progress-bar.get-token-slots(); transform: rotate(180deg); animation: mdc-linear-progress-buffering 250ms infinite linear; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(track-color); } @@ -137,7 +140,7 @@ $token-slots: m2-progress-bar.get-token-slots(); flex: 0 1 100%; transition: flex-basis 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(track-color); } } @@ -199,7 +202,7 @@ $token-slots: m2-progress-bar.get-token-slots(); @keyframes mdc-linear-progress-buffering { from { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $track-variable: token-utils.slot(track-height); transform: rotate(180deg) translateX(calc(#{$track-variable} * -2.5)); } diff --git a/src/material/progress-spinner/_m3-progress-spinner.scss b/src/material/progress-spinner/_m3-progress-spinner.scss index 34d69a7ffdf9..0b85457769bc 100644 --- a/src/material/progress-spinner/_m3-progress-spinner.scss +++ b/src/material/progress-spinner/_m3-progress-spinner.scss @@ -5,30 +5,22 @@ $prefix: (mat, progress-spinner); /// Generates the tokens for MDC circular-progress -/// @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 circular-progress -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - active-indicator-color: map.get($systems, md-sys-color, primary), - active-indicator-width: if($exclude-hardcoded, null, 4px), - size: if($exclude-hardcoded, null, 48px) - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - active-indicator-color: map.get($systems, md-sys-color, secondary), + @return ( + base: ( + size: 48px, + active-indicator-width: 4px, ), - tertiary: ( - active-indicator-color: map.get($systems, md-sys-color, tertiary), + color: ( + active-indicator-color: map.get($system, primary), ), - error: ( - active-indicator-color: map.get($systems, md-sys-color, error), - ) + typography: (), + density: (), ); - - @return m3-utils.namespace( - $prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/progress-spinner/_progress-spinner-theme.scss b/src/material/progress-spinner/_progress-spinner-theme.scss index 081205b2600d..538a6d1789cd 100644 --- a/src/material/progress-spinner/_progress-spinner-theme.scss +++ b/src/material/progress-spinner/_progress-spinner-theme.scss @@ -1,16 +1,19 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use './m2-progress-spinner'; +@use './m3-progress-spinner'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-progress-spinner. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-progress-spinner.$prefix, + map.get(m3-progress-spinner.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -23,12 +26,12 @@ /// Outputs color theme styles for the mat-progress-spinner. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the spinner: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-progress-spinner.$prefix, + map.get(m3-progress-spinner.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -81,13 +84,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-progress-spinner. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the spinner: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-progress-spinner') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -102,18 +106,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mdc-circular-progress-tokens: token-utils.get-tokens-for( - $tokens, - m2-progress-spinner.$prefix, - $options... - ); - @include token-utils.create-token-values( - m2-progress-spinner.$prefix, - $mdc-circular-progress-tokens - ); -} diff --git a/src/material/progress-spinner/progress-spinner.scss b/src/material/progress-spinner/progress-spinner.scss index 574cf184c4b6..9c504521ec8e 100644 --- a/src/material/progress-spinner/progress-spinner.scss +++ b/src/material/progress-spinner/progress-spinner.scss @@ -1,6 +1,12 @@ @use '@angular/cdk'; @use '../core/tokens/token-utils'; @use './m2-progress-spinner'; +@use './m3-progress-spinner'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-progress-spinner.$prefix; +$token-slots: m2-progress-spinner.get-token-slots(); +$fallbacks: m3-progress-spinner.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-progress-spinner { // Explicitly set to `block` since the browser defaults custom elements to `inline`. @@ -17,10 +23,7 @@ transition: opacity 250ms cubic-bezier(0.4, 0, 0.6, 1); circle { - @include token-utils.use-tokens( - m2-progress-spinner.$prefix, - m2-progress-spinner.get-token-slots() - ) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { stroke-width: token-utils.slot(active-indicator-width); } } diff --git a/src/material/radio/_m3-radio.scss b/src/material/radio/_m3-radio.scss index 243ebfa469c7..9293d88e087a 100644 --- a/src/material/radio/_m3-radio.scss +++ b/src/material/radio/_m3-radio.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,67 +8,48 @@ $prefix: (mat, radio); /// Generates custom tokens for the mat-radio. -/// @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-radio -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - ripple-color: map.get($systems, md-sys-color, on-surface), - checked-ripple-color: map.get($systems, md-sys-color, primary), - disabled-label-color: - sass-utils.safe-color-change(map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - label-text-color: map.get($systems, md-sys-color, on-surface), - label-text-font: map.get($systems, md-sys-typescale, body-medium-font), - label-text-line-height: map.get($systems, md-sys-typescale, body-medium-line-height), - label-text-size: map.get($systems, md-sys-typescale, body-medium-size), - label-text-tracking: map.get($systems, md-sys-typescale, body-medium-tracking), - label-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - disabled-selected-icon-color: map.get($systems, md-sys-color, on-surface), - disabled-selected-icon-opacity: if($exclude-hardcoded, null, 0.38), - disabled-unselected-icon-color: map.get($systems, md-sys-color, on-surface), - disabled-unselected-icon-opacity: if($exclude-hardcoded, null, 0.38), - selected-focus-icon-color: map.get($systems, md-sys-color, primary), - selected-hover-icon-color: map.get($systems, md-sys-color, primary), - selected-icon-color: map.get($systems, md-sys-color, primary), - selected-pressed-icon-color: map.get($systems, md-sys-color, primary), - unselected-focus-icon-color: map.get($systems, md-sys-color, on-surface), - unselected-hover-icon-color: map.get($systems, md-sys-color, on-surface), - unselected-icon-color: map.get($systems, md-sys-color, on-surface-variant), - unselected-pressed-icon-color: map.get($systems, md-sys-color, on-surface), - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - checked-ripple-color: map.get($systems, md-sys-color, secondary), - selected-focus-icon-color: map.get($systems, md-sys-color, secondary), - selected-hover-icon-color: map.get($systems, md-sys-color, secondary), - selected-icon-color: map.get($systems, md-sys-color, secondary), - selected-pressed-icon-color: map.get($systems, md-sys-color, secondary), + @return ( + base: ( + disabled-unselected-icon-opacity: 0.38, + disabled-selected-icon-opacity: 0.38, ), - tertiary: ( - checked-ripple-color: map.get($systems, md-sys-color, tertiary), - selected-focus-icon-color: map.get($systems, md-sys-color, tertiary), - selected-hover-icon-color: map.get($systems, md-sys-color, tertiary), - selected-icon-color: map.get($systems, md-sys-color, tertiary), - selected-pressed-icon-color: map.get($systems, md-sys-color, tertiary), + color: ( + checked-ripple-color: map.get($system, primary), + disabled-label-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + disabled-selected-icon-color: map.get($system, on-surface), + disabled-unselected-icon-color: map.get($system, on-surface), + label-text-color: map.get($system, on-surface), + ripple-color: map.get($system, on-surface), + selected-focus-icon-color: map.get($system, primary), + selected-hover-icon-color: map.get($system, primary), + selected-icon-color: map.get($system, primary), + selected-pressed-icon-color: map.get($system, primary), + unselected-focus-icon-color: map.get($system, on-surface), + unselected-hover-icon-color: map.get($system, on-surface), + unselected-icon-color: map.get($system, on-surface-variant), + unselected-pressed-icon-color: map.get($system, on-surface), ), - error: ( - checked-ripple-color: map.get($systems, md-sys-color, error), - selected-focus-icon-color: map.get($systems, md-sys-color, error), - selected-hover-icon-color: map.get($systems, md-sys-color, error), - selected-icon-color: map.get($systems, md-sys-color, error), - selected-pressed-icon-color: map.get($systems, md-sys-color, error), + typography: ( + label-text-font: map.get($system, body-medium-font), + label-text-line-height: map.get($system, body-medium-line-height), + label-text-size: map.get($system, body-medium-size), + label-text-tracking: map.get($system, body-medium-tracking), + label-text-weight: map.get($system, body-medium-weight), ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/radio/_radio-common.scss b/src/material/radio/_radio-common.scss index c0836cd35482..2ab8ff4d99d5 100644 --- a/src/material/radio/_radio-common.scss +++ b/src/material/radio/_radio-common.scss @@ -1,10 +1,13 @@ @use './m2-radio'; +@use './m3-radio'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; $_icon-size: 20px; $token-prefix: m2-radio.$prefix; $token-slots: m2-radio.get-token-slots(); +$fallbacks: m3-radio.get-tokens(m3-system.$theme-with-system-vars); @function _enter-transition($name) { @return $name 90ms cubic-bezier(0, 0, 0.2, 1); @@ -29,7 +32,7 @@ $token-slots: m2-radio.get-token-slots(); // Removing it will likely lead to screenshot diffs. will-change: opacity, transform, border-color, color; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $size-token: token-utils.slot(state-layer-size); padding: calc((#{$size-token} - #{$_icon-size}) / 2); } @@ -45,7 +48,7 @@ $token-slots: m2-radio.get-token-slots(); &:hover > .mdc-radio__native-control:not([disabled]) ~ .mdc-radio__background { > .mdc-radio__outer-circle { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(unselected-hover-icon-color); } } @@ -54,7 +57,7 @@ $token-slots: m2-radio.get-token-slots(); &:hover > .mdc-radio__native-control:enabled:checked + .mdc-radio__background { > .mdc-radio__outer-circle, > .mdc-radio__inner-circle { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(selected-hover-icon-color); } } @@ -62,7 +65,7 @@ $token-slots: m2-radio.get-token-slots(); &:active > .mdc-radio__native-control:enabled:not(:checked) + .mdc-radio__background { > .mdc-radio__outer-circle { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(unselected-pressed-icon-color); } } @@ -71,7 +74,7 @@ $token-slots: m2-radio.get-token-slots(); &:active > .mdc-radio__native-control:enabled:checked + .mdc-radio__background { > .mdc-radio__outer-circle, > .mdc-radio__inner-circle { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(selected-pressed-icon-color); } } @@ -95,7 +98,7 @@ $token-slots: m2-radio.get-token-slots(); content: ''; transition: _exit-transition(opacity), _exit-transition(transform); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $size: token-utils.slot(state-layer-size); $offset: calc(-1 * (#{$size} - #{$_icon-size}) / 2); width: $size; @@ -144,7 +147,7 @@ $token-slots: m2-radio.get-token-slots(); cursor: inherit; z-index: 1; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(state-layer-size); height: token-utils.slot(state-layer-size); } @@ -172,7 +175,7 @@ $token-slots: m2-radio.get-token-slots(); } &:disabled { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:not(:checked) + .mdc-radio__background > .mdc-radio__outer-circle { border-color: token-utils.slot(disabled-unselected-icon-color); opacity: token-utils.slot(disabled-unselected-icon-opacity); @@ -191,7 +194,7 @@ $token-slots: m2-radio.get-token-slots(); } &:enabled { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:not(:checked) + .mdc-radio__background > .mdc-radio__outer-circle { border-color: token-utils.slot(unselected-icon-color); } @@ -224,7 +227,7 @@ $token-slots: m2-radio.get-token-slots(); &.mat-mdc-radio-disabled-interactive .mdc-radio--disabled { pointer-events: auto; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // stylelint-disable selector-combinator-space-before .mdc-radio__native-control:not(:checked) + .mdc-radio__background > .mdc-radio__outer-circle { diff --git a/src/material/radio/_radio-theme.scss b/src/material/radio/_radio-theme.scss index ea6be9874ee7..f01c5dbc2553 100644 --- a/src/material/radio/_radio-theme.scss +++ b/src/material/radio/_radio-theme.scss @@ -1,18 +1,20 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-radio'; @use './m3-radio'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-radio. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-radio.$prefix, + map.get(m3-radio.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -23,12 +25,12 @@ /// Outputs color theme styles for the mat-radio. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the radio button: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-radio.$prefix, + map.get(m3-radio.get-tokens($theme, $color-variant), color)); } @else { .mat-mdc-radio-button { &.mat-primary { @@ -59,7 +61,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-radio.$prefix, + map.get(m3-radio.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -74,7 +78,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-radio.$prefix, m3-radio.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-radio.$prefix, + map.get(m3-radio.get-tokens($theme), density)); } @else { $density-scale: inspection.get-theme-density($theme); @@ -105,16 +111,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-radio. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the radio button: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-radio') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -129,11 +133,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-radio-tokens: token-utils.get-tokens-for($tokens, m2-radio.$prefix, $options...); - @include token-utils.create-token-values(m2-radio.$prefix, $mat-radio-tokens); -} diff --git a/src/material/radio/radio.scss b/src/material/radio/radio.scss index a240eb54a884..6985637bdc41 100644 --- a/src/material/radio/radio.scss +++ b/src/material/radio/radio.scss @@ -1,10 +1,13 @@ @use './m2-radio'; +@use './m3-radio'; @use '../core/tokens/token-utils'; @use '../core/style/layout-common'; @use './radio-common'; +@use '../core/tokens/m3-system'; $token-prefix: m2-radio.$prefix; $token-slots: m2-radio.get-token-slots(); +$fallbacks: m3-radio.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-radio-button { -webkit-tap-highlight-color: transparent; @@ -12,7 +15,7 @@ $token-slots: m2-radio.get-token-slots(); @include radio-common.radio-structure(true); @include radio-common.radio-noop-animations(); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-radio__background::before { background-color: token-utils.slot(ripple-color); } @@ -63,7 +66,7 @@ $token-slots: m2-radio.get-token-slots(); // We don't inherit the border focus style from MDC since we don't use their ripple. // Instead we need to replicate it here. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-radio > .mdc-radio__native-control:focus:enabled:not(:checked) { & ~ .mdc-radio__background > .mdc-radio__outer-circle { border-color: token-utils.slot(unselected-focus-icon-color); @@ -97,7 +100,7 @@ $token-slots: m2-radio.get-token-slots(); width: 48px; transform: translate(-50%, -50%); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { display: token-utils.slot(touch-target-display); } diff --git a/src/material/select/_m3-select.scss b/src/material/select/_m3-select.scss index 3f760aaedd15..a49afc6e8130 100644 --- a/src/material/select/_m3-select.scss +++ b/src/material/select/_m3-select.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/style/elevation'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @@ -10,49 +9,41 @@ $prefix: (mat, select); /// Generates custom tokens for the mat-select. -/// @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-select -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, trigger-text, body-large), - ( - panel-background-color: map.get($systems, md-sys-color, surface-container), - enabled-trigger-text-color: map.get($systems, md-sys-color, on-surface), - disabled-trigger-text-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - placeholder-text-color: map.get($systems, md-sys-color, on-surface-variant), - enabled-arrow-color: map.get($systems, md-sys-color, on-surface-variant), - disabled-arrow-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, on-surface), $alpha: 0.38), - focused-arrow-color: map.get($systems, md-sys-color, primary), - invalid-arrow-color: map.get($systems, md-sys-color, error), - container-elevation-shadow: - m3-utils.hardcode(elevation.get-box-shadow(2), $exclude-hardcoded), - ) - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - // Color variants: - primary: (), // Default, no overrides needed - secondary: ( - focused-arrow-color: map.get($systems, md-sys-color, secondary), + @return ( + base: ( + container-elevation-shadow: elevation.get-box-shadow(2), ), - tertiary: ( - focused-arrow-color: map.get($systems, md-sys-color, tertiary), + color: ( + panel-background-color: map.get($system, surface-container), + enabled-trigger-text-color: map.get($system, on-surface), + disabled-trigger-text-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + placeholder-text-color: map.get($system, on-surface-variant), + enabled-arrow-color: map.get($system, on-surface-variant), + disabled-arrow-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + focused-arrow-color: map.get($system, primary), + invalid-arrow-color: map.get($system, error), ), - error: ( - focused-arrow-color: map.get($systems, md-sys-color, error), - ) + typography: ( + trigger-text-font: map.get($system, body-large-font), + trigger-text-line-height: map.get($system, body-large-line-height), + trigger-text-size: map.get($system, body-large-size), + trigger-text-tracking: map.get($system, body-large-tracking), + trigger-text-weight: map.get($system, body-large-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -2); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -2); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/select/_select-theme.scss b/src/material/select/_select-theme.scss index 9f8f091425cb..f7957a156a79 100644 --- a/src/material/select/_select-theme.scss +++ b/src/material/select/_select-theme.scss @@ -1,18 +1,20 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-select'; @use './m3-select'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-select. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-select.$prefix, + map.get(m3-select.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { $mat-tokens: m2-select.get-unthemable-tokens(); @@ -23,12 +25,12 @@ /// Outputs color theme styles for the mat-select. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the select arrow: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-select.$prefix, + map.get(m3-select.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -57,7 +59,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-select.$prefix, + map.get(m3-select.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -73,7 +77,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-select.$prefix, m3-select.get-density-tokens($theme)); + m3-select.$prefix, + map.get(m3-select.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -102,16 +107,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-icon. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the select arrow: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-select') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -126,11 +129,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-select-tokens: token-utils.get-tokens-for($tokens, m2-select.$prefix, $options...); - @include token-utils.create-token-values(m2-select.$prefix, $mat-select-tokens); -} diff --git a/src/material/select/select.scss b/src/material/select/select.scss index b4128c814673..69998663f654 100644 --- a/src/material/select/select.scss +++ b/src/material/select/select.scss @@ -4,6 +4,8 @@ @use '../core/style/variables'; @use '../core/tokens/token-utils'; @use './m2-select'; +@use './m3-select'; +@use '../core/tokens/m3-system'; $mat-select-arrow-size: 5px !default; $mat-select-arrow-margin: 4px !default; @@ -15,6 +17,7 @@ $scale: 0.75 !default; $token-prefix: m2-select.$prefix; $token-slots: m2-select.get-token-slots(); +$fallbacks: m3-select.get-tokens(m3-system.$theme-with-system-vars); @keyframes _mat-select-enter { from { @@ -43,7 +46,7 @@ $token-slots: m2-select.get-token-slots(); width: 100%; outline: none; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { @include vendor-prefixes.smooth-font(); color: token-utils.slot(enabled-trigger-text-color); font-family: token-utils.slot(trigger-text-font); @@ -53,19 +56,19 @@ $token-slots: m2-select.get-token-slots(); letter-spacing: token-utils.slot(trigger-text-tracking); } } -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { div.mat-mdc-select-panel { box-shadow: token-utils.slot(container-elevation-shadow); } } .mat-mdc-select-disabled { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(disabled-trigger-text-color); } .mat-mdc-select-placeholder { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(disabled-trigger-text-color); } } @@ -111,7 +114,7 @@ $token-slots: m2-select.get-token-slots(); .mat-mdc-form-field .mat-mdc-select.mat-mdc-select-invalid .mat-mdc-select-arrow, .mat-form-field-invalid:not(.mat-form-field-disabled) .mat-mdc-form-field-infix::after { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(invalid-arrow-color); } } @@ -121,7 +124,7 @@ $token-slots: m2-select.get-token-slots(); height: $mat-select-arrow-size; position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(enabled-arrow-color); .mat-mdc-form-field.mat-focused & { @@ -168,7 +171,7 @@ div.mat-mdc-select-panel { // panel which is required for scroll calculations (see #30974). position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(panel-background-color); } @@ -204,7 +207,7 @@ div.mat-mdc-select-panel { math.div(variables.$swift-ease-out-duration, 3) variables.$swift-ease-out-timing-function; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(placeholder-text-color); } @@ -271,7 +274,7 @@ div.mat-mdc-select-panel { visibility: hidden; } -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-form-field-appearance-fill .mat-mdc-select-arrow-wrapper { transform: token-utils.slot(arrow-transform); } diff --git a/src/material/sidenav/_m3-sidenav.scss b/src/material/sidenav/_m3-sidenav.scss index b4cebe5237ea..cf162663e2ea 100644 --- a/src/material/sidenav/_m3-sidenav.scss +++ b/src/material/sidenav/_m3-sidenav.scss @@ -1,28 +1,28 @@ @use 'sass:map'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, sidenav); /// Generates custom tokens for the mat-sidenav. -/// @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-sidenav -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-elevation-shadow: m3-utils.hardcode(none, $exclude-hardcoded), - container-divider-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - container-width: m3-utils.hardcode(360px, $exclude-hardcoded), - container-shape: map.get($systems, md-sys-shape, corner-large), - container-background-color: map.get($systems, md-sys-color, surface), - container-text-color: map.get($systems, md-sys-color, on-surface-variant), - content-background-color: map.get($systems, md-sys-color, background), - content-text-color: map.get($systems, md-sys-color, on-background), - scrim-color: sass-utils.safe-color-change( - map.get($systems, md-ref-palette, neutral-variant20), $alpha: 0.4), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + container-shape: map.get($system, corner-large), + container-elevation-shadow: none, + container-divider-color: transparent, + container-width: 360px, + ), + color: ( + container-background-color: map.get($system, surface), + container-text-color: map.get($system, on-surface-variant), + content-background-color: map.get($system, background), + content-text-color: map.get($system, on-background), + scrim-color: m3-utils.color-with-opacity(map.get($system, neutral-variant20), 40%), + ), + typography: (), + density: (), + ); } diff --git a/src/material/sidenav/_sidenav-theme.scss b/src/material/sidenav/_sidenav-theme.scss index 46cc171b42a0..e85a50063e8d 100644 --- a/src/material/sidenav/_sidenav-theme.scss +++ b/src/material/sidenav/_sidenav-theme.scss @@ -2,13 +2,15 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use './m2-sidenav'; +@use './m3-sidenav'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-sidenav.$prefix, + map.get(m3-sidenav.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -19,7 +21,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-sidenav.$prefix, + map.get(m3-sidenav.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -30,14 +34,18 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-sidenav.$prefix, + map.get(m3-sidenav.get-tokens($theme), typography)); } @else { } } @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-sidenav.$prefix, + map.get(m3-sidenav.get-tokens($theme), base)); } @else { } } @@ -59,7 +67,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-sidenav') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -74,15 +85,3 @@ } } } - -@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( - m2-sidenav.$prefix, - map.get($tokens, m2-sidenav.$prefix) - ); - } -} diff --git a/src/material/sidenav/drawer.scss b/src/material/sidenav/drawer.scss index f0b8e68198da..72d3a846c107 100644 --- a/src/material/sidenav/drawer.scss +++ b/src/material/sidenav/drawer.scss @@ -1,9 +1,11 @@ @use '@angular/cdk'; @use './m2-sidenav'; +@use './m3-sidenav'; @use '../core/tokens/token-utils'; @use '../core/style/variables'; @use '../core/style/layout-common'; +@use '../core/tokens/m3-system'; $drawer-content-z-index: 1; $drawer-side-drawer-z-index: 2; @@ -12,6 +14,7 @@ $drawer-over-drawer-z-index: 4; $token-prefix: m2-sidenav.$prefix; $token-slots: m2-sidenav.get-token-slots(); +$fallbacks: m3-sidenav.get-tokens(m3-system.$theme-with-system-vars); // Mixin that creates a new stacking context. // see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context @@ -30,7 +33,7 @@ $token-slots: m2-sidenav.get-token-slots(); // the application content does not get messed up with our own CSS. @include drawer-stacking-context(); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(content-text-color); background-color: token-utils.slot(content-background-color); } @@ -86,7 +89,7 @@ $token-slots: m2-sidenav.get-token-slots(); &.mat-drawer-shown { visibility: visible; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(scrim-color); } } @@ -129,7 +132,7 @@ $token-slots: m2-sidenav.get-token-slots(); @include drawer-stacking-context($drawer-over-drawer-z-index); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(container-text-color); box-shadow: token-utils.slot(container-elevation-shadow); background-color: token-utils.slot(container-background-color); @@ -171,7 +174,7 @@ $token-slots: m2-sidenav.get-token-slots(); right: 0; transform: translate3d(100%, 0, 0); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-left-radius: token-utils.slot(container-shape); border-bottom-left-radius: token-utils.slot(container-shape); border-top-right-radius: 0; @@ -180,7 +183,7 @@ $token-slots: m2-sidenav.get-token-slots(); } [dir='rtl'] & { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-left-radius: token-utils.slot(container-shape); border-bottom-left-radius: token-utils.slot(container-shape); border-top-right-radius: 0; diff --git a/src/material/slide-toggle/_m3-slide-toggle.scss b/src/material/slide-toggle/_m3-slide-toggle.scss index b3ca9ed52a8f..5bf4af1bafdf 100644 --- a/src/material/slide-toggle/_m3-slide-toggle.scss +++ b/src/material/slide-toggle/_m3-slide-toggle.scss @@ -5,11 +5,13 @@ $prefix: (mat, slide-toggle); /// Generates custom tokens for the mat-slide-toggle. -/// @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-slide-toggle -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } + // visible/hidden-track-opacity: // The hidden and visible track represent whichever track is visible or // hidden in the ui. This could be the .mdc-switch__track :before or @@ -17,144 +19,94 @@ $prefix: (mat, slide-toggle); // // The m2 slide-toggle uses transforms to hide & show the tracks while // the m3 slide-toggle uses opacity. - $tokens: ( - disabled-selected-handle-color: map.get($systems, md-sys-color, surface), - disabled-selected-handle-opacity: if($exclude-hardcoded, null, 1), - disabled-selected-icon-color: map.get($systems, md-sys-color, on-surface), - disabled-selected-icon-opacity: if($exclude-hardcoded, null, 0.38), - disabled-selected-track-color: map.get($systems, md-sys-color, on-surface), - disabled-track-opacity: if($exclude-hardcoded, null, 0.12), - disabled-unselected-handle-color: map.get($systems, md-sys-color, on-surface), - disabled-unselected-handle-opacity: if($exclude-hardcoded, null, 0.38), - disabled-unselected-icon-color: map.get($systems, md-sys-color, surface-variant), - disabled-unselected-icon-opacity: if($exclude-hardcoded, null, 0.38), - disabled-unselected-track-color: map.get($systems, md-sys-color, surface-variant), - disabled-unselected-track-outline-color: map.get($systems, md-sys-color, on-surface), - disabled-unselected-track-outline-width: - m3-utils.hardcode(2px, $exclude-hardcoded), - handle-shape: map.get($systems, md-sys-shape, corner-full), - hidden-track-opacity: m3-utils.hardcode(0, $exclude-hardcoded), - hidden-track-transition: m3-utils.hardcode(opacity 75ms, $exclude-hardcoded), - label-text-color: map.get($systems, md-sys-color, on-surface), - label-text-font: map.get($systems, md-sys-typescale, body-medium-font), - label-text-line-height: map.get($systems, md-sys-typescale, body-medium-line-height), - label-text-size: map.get($systems, md-sys-typescale, body-medium-size), - label-text-tracking: map.get($systems, md-sys-typescale, body-medium-tracking), - label-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - pressed-handle-size: m3-utils.hardcode(28px, $exclude-hardcoded), - selected-focus-handle-color: map.get($systems, md-sys-color, primary-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, primary), - selected-focus-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - selected-focus-track-color: map.get($systems, md-sys-color, primary), - selected-handle-color: map.get($systems, md-sys-color, on-primary), - selected-handle-horizontal-margin: m3-utils.hardcode(0 24px, $exclude-hardcoded), - selected-handle-size: m3-utils.hardcode(24px, $exclude-hardcoded), - selected-hover-handle-color: map.get($systems, md-sys-color, primary-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, primary), - selected-hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity), - selected-hover-track-color: map.get($systems, md-sys-color, primary), - selected-icon-color: map.get($systems, md-sys-color, on-primary-container), - selected-icon-size: if($exclude-hardcoded, null, 16px), - selected-pressed-handle-color: map.get($systems, md-sys-color, primary-container), - selected-pressed-handle-horizontal-margin: - m3-utils.hardcode(0 22px, $exclude-hardcoded), - selected-pressed-state-layer-color: map.get($systems, md-sys-color, primary), - selected-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - selected-pressed-track-color: map.get($systems, md-sys-color, primary), - selected-track-color: map.get($systems, md-sys-color, primary), - selected-track-outline-color: m3-utils.hardcode(transparent, $exclude-hardcoded), - selected-track-outline-width: m3-utils.hardcode(2px, $exclude-hardcoded), - selected-with-icon-handle-horizontal-margin: - m3-utils.hardcode(0 24px, $exclude-hardcoded), - state-layer-size: if($exclude-hardcoded, null, 40px), - track-height: if($exclude-hardcoded, null, 32px), - track-outline-color: map.get($systems, md-sys-color, outline), - track-outline-width: if($exclude-hardcoded, null, 2px), - track-shape: map.get($systems, md-sys-shape, corner-full), - track-width: if($exclude-hardcoded, null, 52px), - unselected-focus-handle-color: map.get($systems, md-sys-color, on-surface-variant), - unselected-focus-state-layer-color: map.get($systems, md-sys-color, on-surface), - unselected-focus-state-layer-opacity: - map.get($systems, md-sys-state, focus-state-layer-opacity), - unselected-focus-track-color: map.get($systems, md-sys-color, surface-variant), - unselected-handle-color: map.get($systems, md-sys-color, outline), - unselected-handle-horizontal-margin: - m3-utils.hardcode(0 8px, $exclude-hardcoded), - unselected-handle-size: m3-utils.hardcode(16px, $exclude-hardcoded), - unselected-hover-handle-color: map.get($systems, md-sys-color, on-surface-variant), - unselected-hover-state-layer-color: map.get($systems, md-sys-color, on-surface), - unselected-hover-state-layer-opacity: - map.get($systems, md-sys-state, hover-state-layer-opacity), - unselected-hover-track-color: map.get($systems, md-sys-color, surface-variant), - unselected-icon-color: map.get($systems, md-sys-color, surface-variant), - unselected-icon-size: if($exclude-hardcoded, null, 16px), - unselected-pressed-handle-color: map.get($systems, md-sys-color, on-surface-variant), - unselected-pressed-handle-horizontal-margin: - m3-utils.hardcode(0 2px, $exclude-hardcoded), - unselected-pressed-state-layer-color: map.get($systems, md-sys-color, on-surface), - unselected-pressed-state-layer-opacity: - map.get($systems, md-sys-state, pressed-state-layer-opacity), - unselected-pressed-track-color: map.get($systems, md-sys-color, surface-variant), - unselected-track-color: map.get($systems, md-sys-color, surface-variant), - unselected-with-icon-handle-horizontal-margin: - m3-utils.hardcode(0 4px, $exclude-hardcoded), - visible-track-opacity: m3-utils.hardcode(1, $exclude-hardcoded), - visible-track-transition: m3-utils.hardcode(opacity 75ms, $exclude-hardcoded), - with-icon-handle-size: m3-utils.hardcode(24px, $exclude-hardcoded), - // These tokens have always been empty for M3, but these token values should be used - // (with the same technique of calling `elevation.get-box-shadow`) - // Currently, internal users have M2 tokens being applied by accident - // handle-elevation-shadow: map.get($systems, md-sys-elevation, level0), - // disabled-handle-elevation-shadow: map.get($systems, md-sys-elevation, level0), - ); - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - selected-focus-handle-color: map.get($systems, md-sys-color, secondary-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-focus-track-color: map.get($systems, md-sys-color, secondary), - selected-handle-color: map.get($systems, md-sys-color, on-secondary), - selected-hover-handle-color: map.get($systems, md-sys-color, secondary-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-hover-track-color: map.get($systems, md-sys-color, secondary), - selected-icon-color: map.get($systems, md-sys-color, on-secondary-container), - selected-pressed-handle-color: map.get($systems, md-sys-color, secondary-container), - selected-pressed-state-layer-color: map.get($systems, md-sys-color, secondary), - selected-pressed-track-color: map.get($systems, md-sys-color, secondary), - selected-track-color: map.get($systems, md-sys-color, secondary), + // These tokens have always been empty for M3, but these token values should be used + // (with the same technique of calling `elevation.get-box-shadow`) + // Currently, internal users have M2 tokens being applied by accident + // handle-elevation-shadow: map.get($system, level0), + // disabled-handle-elevation-shadow: map.get($system, level0), + + @return ( + base: ( + disabled-selected-handle-opacity: 1, + disabled-selected-icon-opacity: 0.38, + disabled-track-opacity: 0.12, + disabled-unselected-handle-opacity: 0.38, + disabled-unselected-icon-opacity: 0.38, + disabled-unselected-track-outline-width: 2px, + handle-shape: map.get($system, corner-full), + hidden-track-opacity: 0, + hidden-track-transition: opacity 75ms, + pressed-handle-size: 28px, + selected-handle-horizontal-margin: 0 24px, + selected-handle-size: 24px, + selected-icon-size: 16px, + selected-pressed-handle-horizontal-margin: 0 22px, + selected-track-outline-color: transparent, + selected-track-outline-width: 2px, + selected-with-icon-handle-horizontal-margin: 0 24px, + state-layer-size: 40px, + track-height: 32px, + track-outline-width: 2px, + track-shape: map.get($system, corner-full), + track-width: 52px, + unselected-handle-horizontal-margin: 0 8px, + unselected-handle-size: 16px, + unselected-icon-size: 16px, + unselected-pressed-handle-horizontal-margin: 0 2px, + unselected-with-icon-handle-horizontal-margin: 0 4px, + visible-track-opacity: 1, + visible-track-transition: opacity 75ms, + with-icon-handle-size: 24px, ), - tertiary: ( - selected-focus-handle-color: map.get($systems, md-sys-color, tertiary-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-focus-track-color: map.get($systems, md-sys-color, tertiary), - selected-handle-color: map.get($systems, md-sys-color, on-tertiary), - selected-hover-handle-color: map.get($systems, md-sys-color, tertiary-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-hover-track-color: map.get($systems, md-sys-color, tertiary), - selected-icon-color: map.get($systems, md-sys-color, on-tertiary-container), - selected-pressed-handle-color: map.get($systems, md-sys-color, tertiary-container), - selected-pressed-state-layer-color: map.get($systems, md-sys-color, tertiary), - selected-pressed-track-color: map.get($systems, md-sys-color, tertiary), - selected-track-color: map.get($systems, md-sys-color, tertiary), + color: ( + disabled-selected-handle-color: map.get($system, surface), + disabled-selected-icon-color: map.get($system, on-surface), + disabled-selected-track-color: map.get($system, on-surface), + disabled-unselected-handle-color: map.get($system, on-surface), + disabled-unselected-icon-color: map.get($system, surface-variant), + disabled-unselected-track-color: map.get($system, surface-variant), + disabled-unselected-track-outline-color: map.get($system, on-surface), + label-text-color: map.get($system, on-surface), + selected-focus-handle-color: map.get($system, primary-container), + selected-focus-state-layer-color: map.get($system, primary), + selected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + selected-focus-track-color: map.get($system, primary), + selected-handle-color: map.get($system, on-primary), + selected-hover-handle-color: map.get($system, primary-container), + selected-hover-state-layer-color: map.get($system, primary), + selected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + selected-hover-track-color: map.get($system, primary), + selected-icon-color: map.get($system, on-primary-container), + selected-pressed-handle-color: map.get($system, primary-container), + selected-pressed-state-layer-color: map.get($system, primary), + selected-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + selected-pressed-track-color: map.get($system, primary), + selected-track-color: map.get($system, primary), + track-outline-color: map.get($system, outline), + unselected-focus-handle-color: map.get($system, on-surface-variant), + unselected-focus-state-layer-color: map.get($system, on-surface), + unselected-focus-state-layer-opacity: map.get($system, focus-state-layer-opacity), + unselected-focus-track-color: map.get($system, surface-variant), + unselected-handle-color: map.get($system, outline), + unselected-hover-handle-color: map.get($system, on-surface-variant), + unselected-hover-state-layer-color: map.get($system, on-surface), + unselected-hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), + unselected-hover-track-color: map.get($system, surface-variant), + unselected-icon-color: map.get($system, surface-variant), + unselected-pressed-handle-color: map.get($system, on-surface-variant), + unselected-pressed-state-layer-color: map.get($system, on-surface), + unselected-pressed-state-layer-opacity: map.get($system, pressed-state-layer-opacity), + unselected-pressed-track-color: map.get($system, surface-variant), + unselected-track-color: map.get($system, surface-variant), ), - error: ( - selected-focus-handle-color: map.get($systems, md-sys-color, error-container), - selected-focus-state-layer-color: map.get($systems, md-sys-color, error), - selected-focus-track-color: map.get($systems, md-sys-color, error), - selected-handle-color: map.get($systems, md-sys-color, on-error), - selected-hover-handle-color: map.get($systems, md-sys-color, error-container), - selected-hover-state-layer-color: map.get($systems, md-sys-color, error), - selected-hover-track-color: map.get($systems, md-sys-color, error), - selected-icon-color: map.get($systems, md-sys-color, on-error-container), - selected-pressed-handle-color: map.get($systems, md-sys-color, error-container), - selected-pressed-state-layer-color: map.get($systems, md-sys-color, error), - selected-pressed-track-color: map.get($systems, md-sys-color, error), - selected-track-color: map.get($systems, md-sys-color, error), + typography: ( + label-text-font: map.get($system, body-medium-font), + label-text-line-height: map.get($system, body-medium-line-height), + label-text-size: map.get($system, body-medium-size), + label-text-tracking: map.get($system, body-medium-tracking), + label-text-weight: map.get($system, body-medium-weight), ), + density: (), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/slide-toggle/_slide-toggle-theme.scss b/src/material/slide-toggle/_slide-toggle-theme.scss index e590d8f52fb2..528e8a0ca581 100644 --- a/src/material/slide-toggle/_slide-toggle-theme.scss +++ b/src/material/slide-toggle/_slide-toggle-theme.scss @@ -2,17 +2,19 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-slide-toggle'; +@use './m3-slide-toggle'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-slide-toggle. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-slide-toggle.$prefix, + map.get(m3-slide-toggle.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { // TODO: See if this can be removed @@ -33,12 +35,12 @@ /// Outputs color theme styles for the mat-slide-toggle. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the slide-toggle: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-slide-toggle.$prefix, + map.get(m3-slide-toggle.get-tokens($theme, $color-variant), color)); } @else { $mat-tokens: m2-slide-toggle.get-color-tokens($theme); @@ -96,7 +98,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-slide-toggle.$prefix, + map.get(m3-slide-toggle.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { // TODO: See if this can be removed @@ -156,13 +160,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-icon. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the slide-toggle: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-slide-toggle') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -177,15 +182,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-switch-tokens: token-utils.get-tokens-for($tokens, m2-slide-toggle.$prefix); - $mat-switch-tokens-options: - token-utils.get-tokens-for($tokens, m2-slide-toggle.$prefix, $options...); - - $tokens: map.merge($mat-switch-tokens, $mat-switch-tokens-options); - @include token-utils.create-token-values(m2-slide-toggle.$prefix, $tokens); -} diff --git a/src/material/slide-toggle/slide-toggle.scss b/src/material/slide-toggle/slide-toggle.scss index 882adaca091a..346ecdca1088 100644 --- a/src/material/slide-toggle/slide-toggle.scss +++ b/src/material/slide-toggle/slide-toggle.scss @@ -2,12 +2,15 @@ @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use './m2-slide-toggle'; +@use './m3-slide-toggle'; @use '@angular/cdk'; +@use '../core/tokens/m3-system'; $_interactive-disabled-selector: '.mat-mdc-slide-toggle-disabled-interactive.mdc-switch--disabled'; $token-prefix: m2-slide-toggle.$prefix; $token-slots: m2-slide-toggle.get-token-slots(); +$fallbacks: m3-slide-toggle.get-tokens(m3-system.$theme-with-system-vars); .mdc-switch { @@ -23,7 +26,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); padding: 0; position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(track-width); } @@ -42,7 +45,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); position: relative; width: 100%; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(track-height); border-radius: token-utils.slot(track-shape); @@ -62,7 +65,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); position: absolute; width: 100%; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-width: token-utils.slot(track-outline-width); border-color: token-utils.slot(track-outline-color); @@ -86,7 +89,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); transition: transform 75ms 0ms cubic-bezier(0, 0, 0.2, 1); transform: translateX(0); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(unselected-track-color); } @@ -99,7 +102,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch--selected & { opacity: token-utils.slot(hidden-track-opacity); transition: token-utils.slot(hidden-track-transition); @@ -111,7 +114,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch:enabled:hover:not(:focus):not(:active) & { background: token-utils.slot(unselected-hover-track-color); } @@ -136,7 +139,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); &::after { transform: translateX(-100%); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(selected-track-color); } @@ -148,7 +151,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); transform: translateX(0); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch--selected & { opacity: token-utils.slot(visible-track-opacity); transition: token-utils.slot(visible-track-transition); @@ -160,7 +163,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch:enabled:hover:not(:focus):not(:active) & { background: token-utils.slot(selected-hover-track-color); } @@ -193,7 +196,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); right: auto; transform: translateX(0); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: calc(100% - #{token-utils.slot(handle-width)}); } @@ -227,7 +230,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); height 75ms cubic-bezier(0.4, 0, 0.2, 1), margin 75ms cubic-bezier(0.4, 0, 0.2, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(handle-width); height: token-utils.slot(handle-height); border-radius: token-utils.slot(handle-shape); @@ -238,7 +241,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); right: 0; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-slide-toggle .mdc-switch--unselected & { width: token-utils.slot(unselected-handle-size); height: token-utils.slot(unselected-handle-size); @@ -306,7 +309,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &::after { .mdc-switch--selected:enabled & { background: token-utils.slot(selected-handle-color); @@ -366,7 +369,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); right: 0; top: 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch:enabled & { box-shadow: token-utils.slot(handle-elevation-shadow); } @@ -387,7 +390,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); transform: translate(-50%, -50%); z-index: -1; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(state-layer-size); height: token-utils.slot(state-layer-size); } @@ -408,7 +411,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); transition: 75ms opacity cubic-bezier(0, 0, 0.2, 1); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { #{$_interactive-disabled-selector}:enabled:focus &, #{$_interactive-disabled-selector}:enabled:active &, #{$_interactive-disabled-selector}:enabled:hover:not(:focus) &, @@ -456,7 +459,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); // Works around a rendering issue in Safari 18.3 (see #30487). transform: translateZ(0); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch--disabled.mdc-switch--unselected & { opacity: token-utils.slot(disabled-unselected-icon-opacity); } @@ -477,7 +480,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); opacity: 0; transition: opacity 30ms 0ms cubic-bezier(0.4, 0, 1, 1); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-switch--unselected & { width: token-utils.slot(unselected-icon-size); height: token-utils.slot(unselected-icon-size); @@ -538,7 +541,7 @@ $token-slots: m2-slide-toggle.get-token-slots(); } .mat-internal-form-field { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(label-text-color); font-family: token-utils.slot(label-text-font); line-height: token-utils.slot(label-text-line-height); diff --git a/src/material/slider/_m3-slider.scss b/src/material/slider/_m3-slider.scss index 46ef07d5d071..478b00f4b27a 100644 --- a/src/material/slider/_m3-slider.scss +++ b/src/material/slider/_m3-slider.scss @@ -1,5 +1,4 @@ @use 'sass:map'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/style/elevation'; @@ -7,115 +6,63 @@ $prefix: (mat, slider); /// Generates custom tokens for the mat-slider. -/// @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-slider -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - ripple-color: map.get($systems, md-sys-color, primary), - hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), $alpha: 0.05), - focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, primary), $alpha: 0.2), - value-indicator-opacity: m3-utils.hardcode(1, $exclude-hardcoded), - value-indicator-padding: m3-utils.hardcode(0, $exclude-hardcoded), - value-indicator-width: m3-utils.hardcode(28px, $exclude-hardcoded), - value-indicator-height: m3-utils.hardcode(28px, $exclude-hardcoded), - value-indicator-caret-display: m3-utils.hardcode(none, $exclude-hardcoded), - value-indicator-border-radius: - m3-utils.hardcode(50% 50% 50% 0, $exclude-hardcoded), - value-indicator-text-transform: - m3-utils.hardcode(rotate(45deg), $exclude-hardcoded), - value-indicator-container-transform: - m3-utils.hardcode(translateX(-50%) rotate(-45deg), $exclude-hardcoded), - active-track-color: map.get($systems, md-sys-color, primary), - active-track-height: if($exclude-hardcoded, null, 4px), - active-track-shape: map.get($systems, md-sys-shape, corner-full), - disabled-active-track-color: map.get($systems, md-sys-color, on-surface), - disabled-handle-color: map.get($systems, md-sys-color, on-surface), - disabled-inactive-track-color: map.get($systems, md-sys-color, on-surface), - focus-handle-color: map.get($systems, md-sys-color, primary), - handle-color: map.get($systems, md-sys-color, primary), - handle-elevation: map.get($systems, md-sys-elevation, level1), - handle-height: if($exclude-hardcoded, null, 20px), - handle-shape: map.get($systems, md-sys-shape, corner-full), - handle-width: if($exclude-hardcoded, null, 20px), - hover-handle-color: map.get($systems, md-sys-color, primary), - inactive-track-color: map.get($systems, md-sys-color, surface-variant), - inactive-track-height: if($exclude-hardcoded, null, 4px), - inactive-track-shape: map.get($systems, md-sys-shape, corner-full), - label-container-color: map.get($systems, md-sys-color, primary), - label-label-text-color: map.get($systems, md-sys-color, on-primary), - label-label-text-font: map.get($systems, md-sys-typescale, label-medium-font), - label-label-text-line-height: map.get($systems, md-sys-typescale, label-medium-line-height), - label-label-text-size: map.get($systems, md-sys-typescale, label-medium-size), - label-label-text-tracking: map.get($systems, md-sys-typescale, label-medium-tracking), - label-label-text-weight: map.get($systems, md-sys-typescale, label-medium-weight), - with-overlap-handle-outline-color: map.get($systems, md-sys-color, on-primary), - with-overlap-handle-outline-width: if($exclude-hardcoded, null, 1px), - with-tick-marks-active-container-color: map.get($systems, md-sys-color, on-primary), - with-tick-marks-active-container-opacity: if($exclude-hardcoded, null, 0.38), - with-tick-marks-container-shape: map.get($systems, md-sys-shape, corner-full), - with-tick-marks-container-size: if($exclude-hardcoded, null, 2px), - with-tick-marks-disabled-container-color: map.get($systems, md-sys-color, on-surface), - with-tick-marks-inactive-container-color: map.get($systems, md-sys-color, on-surface-variant), - with-tick-marks-inactive-container-opacity: if($exclude-hardcoded, null, 0.38) - ); - $handle-elevation: map.get($tokens, handle-elevation); - - @if ($handle-elevation != null) { - $tokens: map.set($tokens, handle-elevation, elevation.get-box-shadow($handle-elevation)); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); } - $variant-tokens: ( - primary: (), // Default, no overrides needed - secondary: ( - ripple-color: map.get($systems, md-sys-color, secondary), - hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), $alpha: 0.05), - focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, secondary), $alpha: 0.2), - active-track-color: map.get($systems, md-sys-color, secondary), - focus-handle-color: map.get($systems, md-sys-color, secondary), - handle-color: map.get($systems, md-sys-color, secondary), - hover-handle-color: map.get($systems, md-sys-color, secondary), - label-container-color: map.get($systems, md-sys-color, secondary), - label-label-text-color: map.get($systems, md-sys-color, on-secondary), - with-overlap-handle-outline-color: map.get($systems, md-sys-color, on-secondary), - with-tick-marks-active-container-color: map.get($systems, md-sys-color, on-secondary), + @return ( + base: ( + value-indicator-opacity: 1, + value-indicator-padding: 0, + value-indicator-width: 28px, + value-indicator-height: 28px, + value-indicator-caret-display: none, + value-indicator-border-radius: 50% 50% 50% 0, + value-indicator-text-transform: rotate(45deg), + value-indicator-container-transform: translateX(-50%) rotate(-45deg), + active-track-height: 4px, + handle-height: 20px, + handle-width: 20px, + inactive-track-height: 4px, + with-overlap-handle-outline-width: 1px, + with-tick-marks-active-container-opacity: 0.38, + with-tick-marks-container-size: 2px, + with-tick-marks-inactive-container-opacity: 0.38, ), - tertiary: ( - ripple-color: map.get($systems, md-sys-color, tertiary), - hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), $alpha: 0.05), - focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, tertiary), $alpha: 0.2), - active-track-color: map.get($systems, md-sys-color, tertiary), - focus-handle-color: map.get($systems, md-sys-color, tertiary), - handle-color: map.get($systems, md-sys-color, tertiary), - hover-handle-color: map.get($systems, md-sys-color, tertiary), - label-container-color: map.get($systems, md-sys-color, tertiary), - label-label-text-color: map.get($systems, md-sys-color, on-tertiary), - with-overlap-handle-outline-color: map.get($systems, md-sys-color, on-tertiary), - with-tick-marks-active-container-color: map.get($systems, md-sys-color, on-tertiary), + color: ( + active-track-color: map.get($system, primary), + active-track-shape: map.get($system, corner-full), + disabled-active-track-color: map.get($system, on-surface), + disabled-handle-color: map.get($system, on-surface), + disabled-inactive-track-color: map.get($system, on-surface), + focus-handle-color: map.get($system, primary), + focus-state-layer-color: m3-utils.color-with-opacity(map.get($system, primary), 20%), + handle-color: map.get($system, primary), + handle-elevation: elevation.get-box-shadow(map.get($system, level1)), + handle-shape: map.get($system, corner-full), + hover-handle-color: map.get($system, primary), + hover-state-layer-color: m3-utils.color-with-opacity(map.get($system, primary), 5%), + inactive-track-color: map.get($system, surface-variant), + inactive-track-shape: map.get($system, corner-full), + label-container-color: map.get($system, primary), + label-label-text-color: map.get($system, on-primary), + ripple-color: map.get($system, primary), + with-overlap-handle-outline-color: map.get($system, on-primary), + with-tick-marks-active-container-color: map.get($system, on-primary), + with-tick-marks-container-shape: map.get($system, corner-full), + with-tick-marks-disabled-container-color: map.get($system, on-surface), + with-tick-marks-inactive-container-color: map.get($system, on-surface-variant), ), - error: ( - ripple-color: map.get($systems, md-sys-color, error), - hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), $alpha: 0.05), - focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, error), $alpha: 0.2), - active-track-color: map.get($systems, md-sys-color, error), - focus-handle-color: map.get($systems, md-sys-color, error), - handle-color: map.get($systems, md-sys-color, error), - hover-handle-color: map.get($systems, md-sys-color, error), - label-container-color: map.get($systems, md-sys-color, error), - label-label-text-color: map.get($systems, md-sys-color, on-error), - with-overlap-handle-outline-color: map.get($systems, md-sys-color, on-error), - with-tick-marks-active-container-color: map.get($systems, md-sys-color, on-error), + typography: ( + label-label-text-font: map.get($system, label-medium-font), + label-label-text-line-height: map.get($system, label-medium-line-height), + label-label-text-size: map.get($system, label-medium-size), + label-label-text-tracking: map.get($system, label-medium-tracking), + label-label-text-weight: map.get($system, label-medium-weight), ), + density: (), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } diff --git a/src/material/slider/_slider-theme.scss b/src/material/slider/_slider-theme.scss index 98d1b686b8ac..f5e8d7197ae7 100644 --- a/src/material/slider/_slider-theme.scss +++ b/src/material/slider/_slider-theme.scss @@ -1,17 +1,20 @@ @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @use './m2-slider'; +@use './m3-slider'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for the mat-slider. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-slider.$prefix, + map.get(m3-slider.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -22,12 +25,12 @@ /// Outputs color theme styles for the mat-slider. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the slider: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-slider.$prefix, + map.get(m3-slider.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -50,7 +53,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-slider.$prefix, + map.get(m3-slider.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -90,13 +95,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-option. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the slider: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-slider') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -111,11 +117,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $mat-slider-tokens: token-utils.get-tokens-for($tokens, m2-slider.$prefix, $options...); - @include token-utils.create-token-values(m2-slider.$prefix, $mat-slider-tokens); -} diff --git a/src/material/slider/slider.scss b/src/material/slider/slider.scss index 1bdbfbf5b7fa..12720ce78841 100644 --- a/src/material/slider/slider.scss +++ b/src/material/slider/slider.scss @@ -1,13 +1,16 @@ @use '@angular/cdk'; @use './m2-slider'; +@use './m3-slider'; @use '../core/tokens/token-utils'; @use '../core/style/vendor-prefixes'; +@use '../core/tokens/m3-system'; $mat-slider-min-size: 128px !default; $mat-slider-horizontal-margin: 8px !default; $token-prefix: m2-slider.$prefix; $token-slots: m2-slider.get-token-slots(); +$fallbacks: m3-slider.get-tokens(m3-system.$theme-with-system-vars); .mdc-slider__track { position: absolute; @@ -16,7 +19,7 @@ $token-slots: m2-slider.get-token-slots(); width: 100%; pointer-events: none; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(inactive-track-height); } } @@ -32,7 +35,7 @@ $token-slots: m2-slider.get-token-slots(); .mdc-slider__track--active { overflow: hidden; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-radius: token-utils.slot(active-track-shape); $active-height-ref: token-utils.slot(active-track-height); $inactive-height-ref: token-utils.slot(inactive-track-height); @@ -50,7 +53,7 @@ $token-slots: m2-slider.get-token-slots(); transform-origin: left; transition: transform 80ms ease; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(active-track-color); border-top-width: token-utils.slot(active-track-height); @@ -70,7 +73,7 @@ $token-slots: m2-slider.get-token-slots(); top: 0; opacity: 0.24; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(inactive-track-color); height: token-utils.slot(inactive-track-height); border-radius: token-utils.slot(inactive-track-shape); @@ -106,7 +109,7 @@ $token-slots: m2-slider.get-token-slots(); position: absolute; transform: translateX(-50%); - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { transform: token-utils.slot(value-indicator-container-transform); } @@ -130,12 +133,12 @@ $token-slots: m2-slider.get-token-slots(); // the word-break of the value indicator. word-break: normal; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(label-container-color); color: token-utils.slot(label-label-text-color); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(value-indicator-width); height: token-utils.slot(value-indicator-height); padding: token-utils.slot(value-indicator-padding); @@ -160,11 +163,11 @@ $token-slots: m2-slider.get-token-slots(); transform: translateX(-50%); width: 0; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { display: token-utils.slot(value-indicator-caret-display); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-color: token-utils.slot(label-container-color); } } @@ -190,12 +193,12 @@ $token-slots: m2-slider.get-token-slots(); .mdc-slider__value-indicator-text { text-align: center; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(value-indicator-width); transform: token-utils.slot(value-indicator-text-transform); } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(label-label-text-font); font-size: token-utils.slot(label-label-text-size); font-weight: token-utils.slot(label-label-text-weight); @@ -235,7 +238,7 @@ $token-slots: m2-slider.get-token-slots(); transform: translate(-50%, -50%); border-style: solid; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $width-ref: token-utils.slot(handle-width); $height-ref: token-utils.slot(handle-height); width: $width-ref; @@ -269,7 +272,7 @@ $token-slots: m2-slider.get-token-slots(); border: solid 1px #fff; box-sizing: content-box; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(with-overlap-handle-outline-color); border-width: token-utils.slot(with-overlap-handle-outline-width); } @@ -289,7 +292,7 @@ $token-slots: m2-slider.get-token-slots(); .mdc-slider__tick-mark--active, .mdc-slider__tick-mark--inactive { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { width: token-utils.slot(with-tick-marks-container-size); height: token-utils.slot(with-tick-marks-container-size); border-radius: token-utils.slot(with-tick-marks-container-shape); @@ -297,7 +300,7 @@ $token-slots: m2-slider.get-token-slots(); } .mdc-slider__tick-mark--inactive { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { opacity: token-utils.slot(with-tick-marks-inactive-container-opacity); background-color: token-utils.slot(with-tick-marks-inactive-container-color); @@ -309,7 +312,7 @@ $token-slots: m2-slider.get-token-slots(); } .mdc-slider__tick-mark--active { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { opacity: token-utils.slot(with-tick-marks-active-container-opacity); background-color: token-utils.slot(with-tick-marks-active-container-color); } @@ -389,7 +392,7 @@ $token-slots: m2-slider.get-token-slots(); } // Add slots for custom Angular Material slider tokens. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // The `.mat-ripple` wrapper here is redundant, but we need it to // increase the specificity due to how some styles are setup in g3. .mat-ripple { diff --git a/src/material/snack-bar/_m3-snack-bar.scss b/src/material/snack-bar/_m3-snack-bar.scss index 52ad45f0d2e8..10d9448c25a8 100644 --- a/src/material/snack-bar/_m3-snack-bar.scss +++ b/src/material/snack-bar/_m3-snack-bar.scss @@ -5,21 +5,24 @@ $prefix: (mat, snack-bar); /// Generates custom tokens for the mat-snack-bar. -/// @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-snack-bar -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - button-color: map.get($systems, md-sys-color, inverse-primary), - container-color: map.get($systems, md-sys-color, inverse-surface), - container-shape: map.get($systems, md-sys-shape, corner-extra-small), - supporting-text-color: map.get($systems, md-sys-color, inverse-on-surface), - supporting-text-font: map.get($systems, md-sys-typescale, body-medium-font), - supporting-text-line-height: map.get($systems, md-sys-typescale, body-medium-line-height), - supporting-text-size: map.get($systems, md-sys-typescale, body-medium-size), - supporting-text-weight: map.get($systems, md-sys-typescale, body-medium-weight), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + container-shape: map.get($system, corner-extra-small), + ), + color: ( + button-color: map.get($system, inverse-primary), + container-color: map.get($system, inverse-surface), + supporting-text-color: map.get($system, inverse-on-surface), + ), + typography: ( + supporting-text-font: map.get($system, body-medium-font), + supporting-text-line-height: map.get($system, body-medium-line-height), + supporting-text-size: map.get($system, body-medium-size), + supporting-text-weight: map.get($system, body-medium-weight), + ), + density: (), + ); } diff --git a/src/material/snack-bar/_snack-bar-theme.scss b/src/material/snack-bar/_snack-bar-theme.scss index ec133baaab0d..14c4f7b00d00 100644 --- a/src/material/snack-bar/_snack-bar-theme.scss +++ b/src/material/snack-bar/_snack-bar-theme.scss @@ -1,15 +1,17 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/style/sass-utils'; @use '../core/typography/typography'; @use '../core/tokens/token-utils'; @use './m2-snack-bar'; +@use './m3-snack-bar'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-snack-bar.$prefix, + map.get(m3-snack-bar.get-tokens($theme), base)); } @else { // Add default values for tokens not related to color, typography, or density. @include sass-utils.current-selector-or-root() { @@ -21,7 +23,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-snack-bar.$prefix, + map.get(m3-snack-bar.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -32,7 +36,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-snack-bar.$prefix, + map.get(m3-snack-bar.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -63,7 +69,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-snack-bar') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -78,15 +87,3 @@ } } } - -@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( - m2-snack-bar.$prefix, - map.get($tokens, m2-snack-bar.$prefix) - ); - } -} diff --git a/src/material/snack-bar/snack-bar-container.scss b/src/material/snack-bar/snack-bar-container.scss index 6e66482d7833..944e4d15ca74 100644 --- a/src/material/snack-bar/snack-bar-container.scss +++ b/src/material/snack-bar/snack-bar-container.scss @@ -1,13 +1,17 @@ @use '@angular/cdk'; @use './m2-snack-bar'; +@use './m3-snack-bar'; @use '../button/m2-button'; +@use '../button/m3-button'; @use '../core/tokens/token-utils'; @use '../core/style/elevation'; +@use '../core/tokens/m3-system'; $_side-padding: 8px; $token-prefix: m2-snack-bar.$prefix; $token-slots: m2-snack-bar.get-token-slots(); +$fallbacks: m3-snack-bar.get-tokens(m3-system.$theme-with-system-vars); @keyframes _mat-snack-bar-enter { from { @@ -90,7 +94,7 @@ $token-slots: m2-snack-bar.get-token-slots(); outline: solid 1px; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-snack-bar-container & { color: token-utils.slot(supporting-text-color); border-radius: token-utils.slot(container-shape); @@ -111,7 +115,7 @@ $token-slots: m2-snack-bar.get-token-slots(); padding-right: 16px; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mat-mdc-snack-bar-container & { font-family: token-utils.slot(supporting-text-font); font-size: token-utils.slot(supporting-text-size); @@ -144,11 +148,13 @@ $token-slots: m2-snack-bar.get-token-slots(); // MDC's `action-label-text-color` should be able to do this, but the button theme has a // higher specificity so it ends up overriding it. Define our own variable that we can // use to control the color instead. - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(button-color); } } + $button-fallbacks: m3-button.get-tokens(m3-system.$theme-with-system-vars); + // Darken the ripples in the button so they're visible against the dark background. @include token-utils.create-token-values-mixed(m2-button.$prefix, ( text-state-layer-color: currentColor, diff --git a/src/material/sort/_m3-sort.scss b/src/material/sort/_m3-sort.scss index b9cadc762fdd..286dfd979288 100644 --- a/src/material/sort/_m3-sort.scss +++ b/src/material/sort/_m3-sort.scss @@ -5,14 +5,15 @@ $prefix: (mat, sort); /// Generates custom tokens for the mat-sort. -/// @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-sort -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - arrow-color: map.get($systems, md-sys-color, on-surface), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + arrow-color: map.get($system, on-surface), + ), + typography: (), + density: (), + ); } diff --git a/src/material/sort/_sort-theme.scss b/src/material/sort/_sort-theme.scss index b27aa8722189..04b0c7e49d15 100644 --- a/src/material/sort/_sort-theme.scss +++ b/src/material/sort/_sort-theme.scss @@ -1,22 +1,26 @@ @use 'sass:map'; @use './m2-sort'; +@use './m3-sort'; @use '../core/style/sass-utils'; @use '../core/typography/typography'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-sort.$prefix, + map.get(m3-sort.get-tokens($theme), base)); } @else { } } @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-sort.$prefix, + map.get(m3-sort.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -27,7 +31,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-sort.$prefix, + map.get(m3-sort.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -38,7 +44,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-sort.$prefix, + map.get(m3-sort.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -64,7 +72,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-sort') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -79,15 +90,3 @@ } } } - -@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( - m2-sort.$prefix, - map.get($tokens, m2-sort.$prefix) - ); - } -} diff --git a/src/material/sort/sort-header.scss b/src/material/sort/sort-header.scss index 54ad6f0e9dea..4d98a80bb941 100644 --- a/src/material/sort/sort-header.scss +++ b/src/material/sort/sort-header.scss @@ -1,6 +1,12 @@ @use './m2-sort'; +@use './m3-sort'; @use '../core/tokens/token-utils'; @use '../core/focus-indicators/private'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-sort.$prefix; +$token-slots: m2-sort.get-token-slots(); +$fallbacks: m3-sort.get-tokens(m3-system.$theme-with-system-vars); .mat-sort-header { cursor: pointer; @@ -77,7 +83,7 @@ opacity: 0; overflow: visible; - @include token-utils.use-tokens(m2-sort.$prefix, m2-sort.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(arrow-color); } diff --git a/src/material/stepper/_m3-stepper.scss b/src/material/stepper/_m3-stepper.scss index 2aa1884e83c1..f869cba9be87 100644 --- a/src/material/stepper/_m3-stepper.scss +++ b/src/material/stepper/_m3-stepper.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,91 +8,56 @@ $prefix: (mat, stepper); /// Generates custom tokens for the mat-stepper. -/// @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-stepper -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-color: map.get($systems, md-sys-color, surface), - line-color: map.get($systems, md-sys-color, outline), - header-hover-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, inverse-surface), - $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) - ), - header-focus-state-layer-color: sass-utils.safe-color-change( - map.get($systems, md-sys-color, inverse-surface), - $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) - ), - header-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - header-optional-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - header-selected-state-label-text-color: map.get($systems, md-sys-color, on-surface-variant), - header-icon-background-color: map.get($systems, md-sys-color, on-surface-variant), - header-icon-foreground-color: map.get($systems, md-sys-color, surface), - header-edit-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-edit-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), - header-done-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-done-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), - header-error-state-label-text-color: map.get($systems, md-sys-color, error), - header-error-state-icon-foreground-color: map.get($systems, md-sys-color, error), - header-error-state-icon-background-color: - m3-utils.hardcode(transparent, $exclude-hardcoded), - container-text-font: map.get($systems, md-sys-typescale, body-medium-font), - header-label-text-font: map.get($systems, md-sys-typescale, title-small-font), - header-label-text-size: map.get($systems, md-sys-typescale, title-small-size), - header-label-text-weight: map.get($systems, md-sys-typescale, title-small-weight), - header-error-state-label-text-size: map.get($systems, md-sys-typescale, title-small-size), - header-focus-state-layer-shape: map.get($systems, md-sys-shape, corner-medium), - header-hover-state-layer-shape: map.get($systems, md-sys-shape, corner-medium), - header-selected-state-label-text-size: map.get($systems, md-sys-typescale, title-small-size), - header-selected-state-label-text-weight: map.get( - $systems, md-sys-typescale, title-small-weight), - header-selected-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-selected-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - // Color variants - primary: ( - header-edit-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-edit-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), - header-done-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-done-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), - header-selected-state-icon-background-color: map.get($systems, md-sys-color, primary), - header-selected-state-icon-foreground-color: map.get($systems, md-sys-color, on-primary), + @return ( + base: ( + header-error-state-icon-background-color: transparent, + header-focus-state-layer-shape: map.get($system, corner-medium), + header-hover-state-layer-shape: map.get($system, corner-medium), ), - secondary: ( - header-edit-state-icon-background-color: map.get($systems, md-sys-color, secondary), - header-edit-state-icon-foreground-color: map.get($systems, md-sys-color, on-secondary), - header-done-state-icon-background-color: map.get($systems, md-sys-color, secondary), - header-done-state-icon-foreground-color: map.get($systems, md-sys-color, on-secondary), - header-selected-state-icon-background-color: map.get($systems, md-sys-color, secondary), - header-selected-state-icon-foreground-color: map.get($systems, md-sys-color, on-secondary), + color: ( + container-color: map.get($system, surface), + header-done-state-icon-background-color: map.get($system, primary), + header-done-state-icon-foreground-color: map.get($system, on-primary), + header-edit-state-icon-background-color: map.get($system, primary), + header-edit-state-icon-foreground-color: map.get($system, on-primary), + header-error-state-icon-foreground-color: map.get($system, error), + header-error-state-label-text-color: map.get($system, error), + header-focus-state-layer-color: m3-utils.color-with-opacity( + map.get($system, inverse-surface), map.get($system, focus-state-layer-opacity)), + header-hover-state-layer-color: m3-utils.color-with-opacity( + map.get($system, inverse-surface), map.get($system, hover-state-layer-opacity)), + header-icon-background-color: map.get($system, on-surface-variant), + header-icon-foreground-color: map.get($system, surface), + header-label-text-color: map.get($system, on-surface-variant), + header-optional-label-text-color: map.get($system, on-surface-variant), + header-selected-state-icon-background-color: map.get($system, primary), + header-selected-state-icon-foreground-color: map.get($system, on-primary), + header-selected-state-label-text-color: map.get($system, on-surface-variant), + line-color: map.get($system, outline), ), - tertiary: ( - header-edit-state-icon-background-color: map.get($systems, md-sys-color, tertiary), - header-edit-state-icon-foreground-color: map.get($systems, md-sys-color, on-tertiary), - header-done-state-icon-background-color: map.get($systems, md-sys-color, tertiary), - header-done-state-icon-foreground-color: map.get($systems, md-sys-color, on-tertiary), - header-selected-state-icon-background-color: map.get($systems, md-sys-color, tertiary), - header-selected-state-icon-foreground-color: map.get($systems, md-sys-color, on-tertiary), + typography: ( + container-text-font: map.get($system, body-medium-font), + header-label-text-font: map.get($system, title-small-font), + header-label-text-size: map.get($system, title-small-size), + header-label-text-weight: map.get($system, title-small-weight), + header-error-state-label-text-size: map.get($system, title-small-size), + header-selected-state-label-text-size: map.get($system, title-small-size), + header-selected-state-label-text-weight: map.get($system, title-small-weight), ), - error: ( - header-edit-state-icon-background-color: map.get($systems, md-sys-color, error), - header-edit-state-icon-foreground-color: map.get($systems, md-sys-color, on-error), - header-done-state-icon-background-color: map.get($systems, md-sys-color, error), - header-done-state-icon-foreground-color: map.get($systems, md-sys-color, on-error), - header-selected-state-icon-background-color: map.get($systems, md-sys-color, error), - header-selected-state-icon-foreground-color: map.get($systems, md-sys-color, on-error), - ) + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -4); +@function get-density-tokens($scale) { + $scale: theming.clamp-density(scale, -4); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/stepper/_stepper-theme.scss b/src/material/stepper/_stepper-theme.scss index 924facb0acd2..bc90684bdd8d 100644 --- a/src/material/stepper/_stepper-theme.scss +++ b/src/material/stepper/_stepper-theme.scss @@ -1,30 +1,32 @@ @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @use './m2-stepper'; @use './m3-stepper'; +@use 'sass:map'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) /// for mat-stepper. /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-stepper.$prefix, + map.get(m3-stepper.get-tokens($theme), base)); } @else { } } /// Outputs color theme styles for mat-stepper. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the stepper: primary, secondary, -/// tertiary, or error (If not specified, primary color values will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-stepper.$prefix, + map.get(m3-stepper.get-tokens($theme, $color-variant), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -53,7 +55,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-stepper.$prefix, + map.get(m3-stepper.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -69,7 +73,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-stepper.$prefix, m3-stepper.get-density-tokens($theme)); + m3-stepper.$prefix, + map.get(m3-stepper.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -98,13 +103,14 @@ /// Outputs all (base, color, typography, and density) theme styles for mat-stepper. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the stepper: primary, secondary, -/// tertiary, or error (If not specified, primary color values will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-stepper') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); @if inspection.theme-has($theme, density) { @include density($theme); } @@ -122,17 +128,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - @if ($tokens != ()) { - $mat-stepper-tokens: token-utils.get-tokens-for( - $tokens, - m2-stepper.$prefix, - $options... - ); - @include token-utils.create-token-values(m2-stepper.$prefix, $mat-stepper-tokens); - } -} diff --git a/src/material/stepper/step-header.scss b/src/material/stepper/step-header.scss index 92e241eac38a..05240a431c61 100644 --- a/src/material/stepper/step-header.scss +++ b/src/material/stepper/step-header.scss @@ -2,10 +2,13 @@ @use '../core/style/layout-common'; @use '../core/tokens/token-utils'; @use './m2-stepper'; +@use './m3-stepper'; @use './stepper-variables'; +@use '../core/tokens/m3-system'; $token-prefix: m2-stepper.$prefix; $token-slots: m2-stepper.get-token-slots(); +$fallbacks: m3-stepper.get-tokens(m3-system.$theme-with-system-vars); .mat-step-header { overflow: hidden; @@ -25,7 +28,7 @@ $token-slots: m2-stepper.get-token-slots(); cursor: default; } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:hover:not([aria-disabled]), &:hover[aria-disabled='false'] { @@ -74,7 +77,7 @@ $token-slots: m2-stepper.get-token-slots(); .mat-step-optional { font-size: stepper-variables.$step-sub-label-font-size; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(header-optional-label-text-color); } } @@ -91,7 +94,7 @@ $token-slots: m2-stepper.get-token-slots(); flex-shrink: 0; position: relative; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(header-icon-foreground-color); background-color: token-utils.slot(header-icon-background-color); } @@ -116,7 +119,7 @@ $token-slots: m2-stepper.get-token-slots(); } .mat-step-icon-state-error { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(header-error-state-icon-background-color); color: token-utils.slot(header-error-state-icon-foreground-color); } @@ -136,7 +139,7 @@ $token-slots: m2-stepper.get-token-slots(); min-width: stepper-variables.$label-min-width; vertical-align: middle; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(header-label-text-font); font-size: token-utils.slot(header-label-text-size); font-weight: token-utils.slot(header-label-text-weight); @@ -171,21 +174,21 @@ $token-slots: m2-stepper.get-token-slots(); } .mat-step-icon-selected { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(header-selected-state-icon-background-color); color: token-utils.slot(header-selected-state-icon-foreground-color); } } .mat-step-icon-state-done { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(header-done-state-icon-background-color); color: token-utils.slot(header-done-state-icon-foreground-color); } } .mat-step-icon-state-edit { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(header-edit-state-icon-background-color); color: token-utils.slot(header-edit-state-icon-foreground-color); } diff --git a/src/material/stepper/stepper.scss b/src/material/stepper/stepper.scss index a271ddd4b11e..26857f90d27c 100644 --- a/src/material/stepper/stepper.scss +++ b/src/material/stepper/stepper.scss @@ -1,8 +1,10 @@ @use 'sass:math'; @use '@angular/cdk'; @use './m2-stepper'; +@use './m3-stepper'; @use '../core/tokens/token-utils'; @use './stepper-variables'; +@use '../core/tokens/m3-system'; // Gets the `calc` expression for the vertical padding of the stepper header. @function _get-vertical-padding-calc() { @@ -12,12 +14,13 @@ $token-prefix: m2-stepper.$prefix; $token-slots: m2-stepper.get-token-slots(); +$fallbacks: m3-stepper.get-tokens(m3-system.$theme-with-system-vars); .mat-stepper-vertical, .mat-stepper-horizontal { display: block; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(container-text-font); background: token-utils.slot(container-color); } @@ -45,7 +48,7 @@ $token-slots: m2-stepper.get-token-slots(); margin: 0 stepper-variables.$line-gap - stepper-variables.$side-gap; min-width: stepper-variables.$line-gap + stepper-variables.$side-gap; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-color: token-utils.slot(line-color); .mat-stepper-label-position-bottom & { @@ -78,7 +81,7 @@ $token-slots: m2-stepper.get-token-slots(); align-items: center; padding: 0 stepper-variables.$side-gap; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(header-height); } @@ -92,7 +95,7 @@ $token-slots: m2-stepper.get-token-slots(); } } - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $vertical-padding: _get-vertical-padding-calc(); &::before, @@ -156,7 +159,7 @@ $token-slots: m2-stepper.get-token-slots(); // We can't use `max-height` here, because it breaks the flexbox centering in IE. height: stepper-variables.$label-header-height; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { padding: #{_get-vertical-padding-calc()} stepper-variables.$side-gap; } @@ -271,7 +274,7 @@ $token-slots: m2-stepper.get-token-slots(); border-left-width: stepper-variables.$line-width; border-left-style: solid; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $vertical-padding: _get-vertical-padding-calc(); $vertical-offset: calc(#{stepper-variables.$line-gap} - #{$vertical-padding}); diff --git a/src/material/table/_m3-table.scss b/src/material/table/_m3-table.scss index 8d22e8722170..460996298e21 100644 --- a/src/material/table/_m3-table.scss +++ b/src/material/table/_m3-table.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -9,31 +8,43 @@ $prefix: (mat, table); /// Generates custom tokens for the mat-table. -/// @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-table -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, header-headline, title-small), - m3-utils.generate-typography-tokens($systems, row-item-label-text, body-medium), - m3-utils.generate-typography-tokens( - $systems, footer-supporting-text, body-medium), - ( - row-item-outline-width: m3-utils.hardcode(1px, $exclude-hardcoded), - background-color: map.get($systems, md-sys-color, surface), - header-headline-color: map.get($systems, md-sys-color, on-surface), - row-item-label-text-color: map.get($systems, md-sys-color, on-surface), - row-item-outline-color: map.get($systems, md-sys-color, outline), +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); + + @return ( + base: ( + row-item-outline-width: 1px, + ), + color: ( + background-color: map.get($system, surface), + header-headline-color: map.get($system, on-surface), + row-item-label-text-color: map.get($system, on-surface), + row-item-outline-color: map.get($system, outline), ), + typography: ( + header-headline-font: map.get($system, title-small-font), + header-headline-line-height: map.get($system, title-small-line-height), + header-headline-size: map.get($system, title-small-size), + header-headline-tracking: map.get($system, title-small-tracking), + header-headline-weight: map.get($system, title-small-weight), + row-item-label-text-font: map.get($system, body-medium-font), + row-item-label-text-line-height: map.get($system, body-medium-line-height), + row-item-label-text-size: map.get($system, body-medium-size), + row-item-label-text-tracking: map.get($system, body-medium-tracking), + row-item-label-text-weight: map.get($system, body-medium-weight), + footer-supporting-text-font: map.get($system, body-medium-font), + footer-supporting-text-line-height: map.get($system, body-medium-line-height), + footer-supporting-text-size: map.get($system, body-medium-size), + footer-supporting-text-tracking: map.get($system, body-medium-tracking), + footer-supporting-text-weight: map.get($system, body-medium-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, $tokens, $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -4); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -4); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/table/_table-flex-styles.scss b/src/material/table/_table-flex-styles.scss index 164a402e6a77..a0195cace781 100644 --- a/src/material/table/_table-flex-styles.scss +++ b/src/material/table/_table-flex-styles.scss @@ -1,5 +1,11 @@ @use '../core/tokens/token-utils'; @use './m2-table'; +@use './m3-table'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-table.$prefix; +$token-slots: m2-table.get-token-slots(); +$fallbacks: m3-table.get-tokens(m3-system.$theme-with-system-vars); // Flex-based table structure $header-row-height: 56px; @@ -12,7 +18,7 @@ $row-horizontal-padding: 24px; display: block; } - @include token-utils.use-tokens(m2-table.$prefix, m2-table.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { mat-header-row { min-height: token-utils.slot(header-container-height, $header-row-height); } diff --git a/src/material/table/_table-theme.scss b/src/material/table/_table-theme.scss index 29c2cfa6a738..0eef9374cfea 100644 --- a/src/material/table/_table-theme.scss +++ b/src/material/table/_table-theme.scss @@ -3,14 +3,15 @@ @use './m3-table'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/tokens/token-utils'; @use '../core/style/sass-utils'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-table.$prefix, + map.get(m3-table.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -21,7 +22,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-table.$prefix, + map.get(m3-table.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -32,7 +35,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-table.$prefix, + map.get(m3-table.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -43,7 +48,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-table.$prefix, m3-table.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-table.$prefix, + map.get(m3-table.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -69,10 +76,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-table') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -87,15 +94,3 @@ } } } - -@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( - m2-table.$prefix, - map.get($tokens, m2-table.$prefix) - ); - } -} diff --git a/src/material/table/table.scss b/src/material/table/table.scss index 5dab30bae5d6..77ab2e9063ed 100644 --- a/src/material/table/table.scss +++ b/src/material/table/table.scss @@ -1,7 +1,13 @@ @use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use './m2-table'; +@use './m3-table'; @use './table-flex-styles'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-table.$prefix; +$token-slots: m2-table.get-token-slots(); +$fallbacks: m3-table.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-table-sticky { // Note that the table can either set this class or an inline style to make something sticky. @@ -28,7 +34,7 @@ $token-slots: m2-table.get-token-slots(); table-layout: auto; white-space: normal; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(background-color); } } @@ -49,7 +55,7 @@ $token-slots: m2-table.get-token-slots(); padding: 0 16px; } -@include token-utils.use-tokens($token-prefix, $token-slots) { +@include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // TODO(crisbeto): these tokens have default values in order to make the initial token // work easier to land in g3. Eventually we should remove them. .mat-mdc-header-row { diff --git a/src/material/tabs/_m3-tabs.scss b/src/material/tabs/_m3-tabs.scss index db91da546ea8..86e13587498e 100644 --- a/src/material/tabs/_m3-tabs.scss +++ b/src/material/tabs/_m3-tabs.scss @@ -1,5 +1,4 @@ @use '../core/tokens/m3-utils'; -@use '../core/style/sass-utils'; @use 'sass:map'; @use 'sass:list'; @use '../core/theming/theming'; @@ -9,59 +8,48 @@ $prefix: (mat, tab); /// Generates the tokens for MDC tab -/// @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 tab -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, label-text, title-small), - ( - active-focus-indicator-color: map.get($systems, md-sys-color, primary), - active-focus-label-text-color: map.get($systems, md-sys-color, on-surface), - active-hover-indicator-color: map.get($systems, md-sys-color, primary), - active-hover-label-text-color: map.get($systems, md-sys-color, on-surface), - active-indicator-color: map.get($systems, md-sys-color, primary), - active-indicator-height: m3-utils.hardcode(2px, $exclude-hardcoded), - active-indicator-shape: m3-utils.hardcode(0, $exclude-hardcoded), - active-label-text-color: map.get($systems, md-sys-color, on-surface), - active-ripple-color: map.get($systems, md-sys-color, on-surface), - divider-color: map.get($systems, md-sys-color, surface-variant), - divider-height: m3-utils.hardcode(1px, $exclude-hardcoded), - inactive-focus-label-text-color: map.get($systems, md-sys-color, on-surface), - inactive-hover-label-text-color: map.get($systems, md-sys-color, on-surface), - inactive-label-text-color: map.get($systems, md-sys-color, on-surface), - inactive-ripple-color: map.get($systems, md-sys-color, on-surface), - pagination-icon-color: map.get($systems, md-sys-color, on-surface), - ), - ); +/// @param {String} $color-variant The color variant to use for the component +@function get-tokens($theme, $color-variant: null) { + $system: m3-utils.get-system($theme); + @if $color-variant { + $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + } - $variant-tokens: ( - // Color variants - primary: (), // Default, no overrides needed - secondary: ( - active-focus-indicator-color: map.get($systems, md-sys-color, secondary), - active-hover-indicator-color: map.get($systems, md-sys-color, secondary), - active-indicator-color: map.get($systems, md-sys-color, secondary), + @return ( + base: ( + active-indicator-height: 2px, + active-indicator-shape: 0, + divider-height: 1px, ), - tertiary: ( - active-focus-indicator-color: map.get($systems, md-sys-color, tertiary), - active-hover-indicator-color: map.get($systems, md-sys-color, tertiary), - active-indicator-color: map.get($systems, md-sys-color, tertiary), + color: ( + active-focus-indicator-color: map.get($system, primary), + active-focus-label-text-color: map.get($system, on-surface), + active-hover-indicator-color: map.get($system, primary), + active-hover-label-text-color: map.get($system, on-surface), + active-indicator-color: map.get($system, primary), + active-label-text-color: map.get($system, on-surface), + active-ripple-color: map.get($system, on-surface), + divider-color: map.get($system, surface-variant), + inactive-focus-label-text-color: map.get($system, on-surface), + inactive-hover-label-text-color: map.get($system, on-surface), + inactive-label-text-color: map.get($system, on-surface), + inactive-ripple-color: map.get($system, on-surface), + pagination-icon-color: map.get($system, on-surface), ), - error: ( - active-focus-indicator-color: map.get($systems, md-sys-color, error), - active-hover-indicator-color: map.get($systems, md-sys-color, error), - active-indicator-color: map.get($systems, md-sys-color, error), - ) + typography: ( + label-text-font: map.get($system, title-small-font), + label-text-line-height: map.get($system, title-small-line-height), + label-text-size: map.get($system, title-small-size), + label-text-tracking: map.get($system, title-small-tracking), + label-text-weight: map.get($system, title-small-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); - - @return m3-utils.namespace($prefix, ($tokens, $variant-tokens), $token-slots); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -4); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -4); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/tabs/_tabs-common.scss b/src/material/tabs/_tabs-common.scss index 3c0047953b9b..be22aa65b845 100644 --- a/src/material/tabs/_tabs-common.scss +++ b/src/material/tabs/_tabs-common.scss @@ -1,6 +1,12 @@ @use '../core/style/vendor-prefixes'; @use './m2-tabs'; +@use './m3-tabs'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-tabs.$prefix; +$token-slots: m2-tabs.get-token-slots(); +$fallbacks: m3-tabs.get-tokens(m3-system.$theme-with-system-vars); $mat-tab-animation-duration: 500ms !default; @@ -98,11 +104,11 @@ $mat-tab-animation-duration: 500ms !default; // Tabs might be `button` elements so we have to reset the user agent styling. background: none; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(container-height); } - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { font-family: token-utils.slot(label-text-font); font-size: token-utils.slot(label-text-size); letter-spacing: token-utils.slot(label-text-tracking); @@ -118,14 +124,14 @@ $mat-tab-animation-duration: 500ms !default; } .mdc-tab-indicator__content--underline { - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(active-indicator-color); border-top-width: token-utils.slot(active-indicator-height); border-radius: token-utils.slot(active-indicator-shape); } } - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { &:hover .mdc-tab__text-label { color: token-utils.slot(inactive-hover-label-text-color); } @@ -183,7 +189,7 @@ $mat-tab-animation-duration: 500ms !default; pointer-events: none; } - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { .mdc-tab__ripple::before, .mat-ripple-element { background-color: token-utils.slot(disabled-ripple-color); @@ -204,13 +210,13 @@ $mat-tab-animation-duration: 500ms !default; opacity: 0; pointer-events: none; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(inactive-ripple-color); } } .mdc-tab__text-label { - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(inactive-label-text-color); } @@ -245,7 +251,7 @@ $mat-tab-animation-duration: 500ms !default; .mat-ripple-element { opacity: 0.12; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(inactive-ripple-color); } } @@ -286,7 +292,7 @@ $mat-tab-animation-duration: 500ms !default; .mat-ripple-element { opacity: 0.12; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(inactive-ripple-color); } } @@ -320,7 +326,7 @@ $mat-tab-animation-duration: 500ms !default; height: 8px; width: 8px; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-color: token-utils.slot(pagination-icon-color); } } @@ -368,7 +374,7 @@ $mat-tab-animation-duration: 500ms !default; // list, but it ended up being hugely breaking internally. .cdk-drop-list &, &.cdk-drop-list { - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { min-height: token-utils.slot(container-height); } } @@ -382,7 +388,7 @@ $mat-tab-animation-duration: 500ms !default; flex-grow: 1; overflow: hidden; z-index: 1; - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-bottom-style: solid; border-bottom-width: token-utils.slot(divider-height); border-bottom-color: token-utils.slot(divider-color); @@ -400,7 +406,7 @@ $mat-tab-animation-duration: 500ms !default; @mixin paginated-tab-header-with-background($header-selector, $tab-selector) { &.mat-tabs-with-background { - @include token-utils.use-tokens(m2-tabs.$prefix, m2-tabs.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // Note that these selectors target direct descendants so // that the styles don't apply to any nested tab groups. > #{$header-selector}, > .mat-mdc-tab-header-pagination { diff --git a/src/material/tabs/_tabs-theme.scss b/src/material/tabs/_tabs-theme.scss index dd87a7bcc104..73abf96151ca 100644 --- a/src/material/tabs/_tabs-theme.scss +++ b/src/material/tabs/_tabs-theme.scss @@ -3,7 +3,6 @@ @use './m3-tabs'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/tokens/token-utils'; @use 'sass:map'; @@ -13,7 +12,9 @@ /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-tabs.$prefix, + map.get(m3-tabs.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -24,12 +25,12 @@ /// Outputs color theme styles for the mat-tab. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the tab indicator: primary, secondary, -/// tertiary, or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin color($theme, $color-variant: null) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-tabs.$prefix, + map.get(m3-tabs.get-tokens($theme, $color-variant), color)); } @else { .mat-mdc-tab-group, .mat-mdc-tab-nav-bar { @@ -83,7 +84,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-tabs.$prefix, + map.get(m3-tabs.get-tokens($theme), typography)); } @else { .mat-mdc-tab-header { @include token-utils.create-token-values-mixed( @@ -96,7 +99,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-tabs.$prefix, m3-tabs.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-tabs.$prefix, + map.get(m3-tabs.get-tokens($theme), density)); } @else { .mat-mdc-tab-header { @include token-utils.create-token-values-mixed( @@ -123,16 +128,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-tab. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the tab indicator: primary, secondary, -/// tertiary, or error (If not specified, default primary color will be used). -@mixin theme($theme, $options...) { +/// @param {String} $color-variant The color variant to use for the component (M3 only) +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-tabs') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme), $options...); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme, $color-variant); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -147,14 +150,3 @@ } } } - -@mixin _theme-from-tokens($tokens, $options...) { - @include validation.selector-defined( - 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector' - ); - $tabs-tokens: token-utils.get-tokens-for($tokens, m2-tabs.$prefix, $options...); - $tabs-tokens-without-options: token-utils.get-tokens-for($tokens, m2-tabs.$prefix); - - @include token-utils.create-token-values(m2-tabs.$prefix, $tabs-tokens-without-options); - @include token-utils.create-token-values(m2-tabs.$prefix, $tabs-tokens); -} diff --git a/src/material/timepicker/_m3-timepicker.scss b/src/material/timepicker/_m3-timepicker.scss index 3edc539c0926..1736bd7a1dda 100644 --- a/src/material/timepicker/_m3-timepicker.scss +++ b/src/material/timepicker/_m3-timepicker.scss @@ -6,17 +6,18 @@ $prefix: (mat, timepicker); /// Generates custom tokens for the mat-timepicker. -/// @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-timepicker -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-background-color: map.get($systems, md-sys-color, surface-container), - container-shape: map.get($systems, md-sys-shape, corner-extra-small), - container-elevation-shadow: - m3-utils.hardcode(elevation.get-box-shadow(2), $exclude-hardcoded), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: ( + container-shape: map.get($system, corner-extra-small), + ), + color: ( + container-background-color: map.get($system, surface-container), + container-elevation-shadow: elevation.get-box-shadow(2), + ), + typography: (), + density: (), + ); } diff --git a/src/material/timepicker/_timepicker-theme.scss b/src/material/timepicker/_timepicker-theme.scss index ae76f7aba02e..65618b58b46b 100644 --- a/src/material/timepicker/_timepicker-theme.scss +++ b/src/material/timepicker/_timepicker-theme.scss @@ -1,10 +1,10 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use './m2-timepicker'; +@use './m3-timepicker'; @use '../core/tokens/token-utils'; /// Outputs base theme styles (styles not dependent on the color, typography, or density settings) @@ -12,7 +12,9 @@ /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-timepicker.$prefix, + map.get(m3-timepicker.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -25,12 +27,11 @@ /// Outputs color theme styles for the mat-timepicker. /// @param {Map} $theme The theme to generate color styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the main selection: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin color($theme, $options...) { +@mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...); + @include token-utils.create-token-values( + m3-timepicker.$prefix, + map.get(m3-timepicker.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -45,7 +46,9 @@ /// @param {Map} $theme The theme to generate typography styles for. @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-timepicker.$prefix, + map.get(m3-timepicker.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -60,7 +63,9 @@ /// @param {Map} $theme The theme to generate density styles for. @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-timepicker.$prefix, + map.get(m3-timepicker.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -89,13 +94,14 @@ /// Outputs all (base, color, typography, and density) theme styles for the mat-timepicker. /// @param {Map} $theme The theme to generate styles for. -/// @param {ArgList} Additional optional arguments (only supported for M3 themes): -/// $color-variant: The color variant to use for the main selection: primary, secondary, tertiary, -/// or error (If not specified, default primary color will be used). -@mixin theme($theme) { +/// @param {String} $color-variant The color variant to use for the component +@mixin theme($theme, $color-variant: null) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-timepicker') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -110,15 +116,3 @@ } } } - -@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( - m2-timepicker.$prefix, - map.get($tokens, m2-timepicker.$prefix) - ); - } -} diff --git a/src/material/timepicker/timepicker.scss b/src/material/timepicker/timepicker.scss index e81e5ea23bc8..94c294cbb00c 100644 --- a/src/material/timepicker/timepicker.scss +++ b/src/material/timepicker/timepicker.scss @@ -1,6 +1,12 @@ @use '@angular/cdk'; @use '../core/tokens/token-utils'; @use './m2-timepicker'; +@use './m3-timepicker'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-timepicker.$prefix; +$token-slots: m2-timepicker.get-token-slots(); +$fallbacks: m3-timepicker.get-tokens(m3-system.$theme-with-system-vars); @keyframes _mat-timepicker-enter { from { @@ -40,7 +46,7 @@ mat-timepicker { // panel which is required for scroll calculations (see #30974). position: relative; - @include token-utils.use-tokens(m2-timepicker.$prefix, m2-timepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-bottom-left-radius: token-utils.slot(container-shape); border-bottom-right-radius: token-utils.slot(container-shape); box-shadow: token-utils.slot(container-elevation-shadow); @@ -55,7 +61,7 @@ mat-timepicker { border-bottom-left-radius: 0; border-bottom-right-radius: 0; - @include token-utils.use-tokens(m2-timepicker.$prefix, m2-timepicker.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { border-top-left-radius: token-utils.slot(container-shape); border-top-right-radius: token-utils.slot(container-shape); } diff --git a/src/material/toolbar/_m3-toolbar.scss b/src/material/toolbar/_m3-toolbar.scss index 08ab80368650..630fb952d13e 100644 --- a/src/material/toolbar/_m3-toolbar.scss +++ b/src/material/toolbar/_m3-toolbar.scss @@ -1,6 +1,5 @@ @use 'sass:map'; @use 'sass:list'; -@use '../core/style/sass-utils'; @use '../core/tokens/m3-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; @@ -13,21 +12,29 @@ $prefix: (mat, toolbar); /// @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-toolbar -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: sass-utils.merge-all( - m3-utils.generate-typography-tokens($systems, title-text, title-large), - ( - container-background-color: map.get($systems, md-sys-color, surface), - container-text-color: map.get($systems, md-sys-color, on-surface), - ) - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + container-background-color: map.get($system, surface), + container-text-color: map.get($system, on-surface), + ), + typography: ( + title-text-font: map.get($system, title-large-font), + title-text-line-height: map.get($system, title-large-line-height), + title-text-size: map.get($system, title-large-size), + title-text-tracking: map.get($system, title-large-tracking), + title-text-weight: map.get($system, title-large-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), + ); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -3); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -3); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/toolbar/_toolbar-theme.scss b/src/material/toolbar/_toolbar-theme.scss index cca9e3c9e26a..0ef7240c727d 100644 --- a/src/material/toolbar/_toolbar-theme.scss +++ b/src/material/toolbar/_toolbar-theme.scss @@ -2,7 +2,6 @@ @use '../core/style/sass-utils'; @use '../core/theming/inspection'; @use '../core/theming/theming'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-toolbar'; @@ -23,7 +22,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-toolbar.$prefix, + map.get(m3-toolbar.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -50,7 +51,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-toolbar.$prefix, + map.get(m3-toolbar.get-tokens($theme), typography)); } @else { // TODO(mmalerba): Stop calling this and resolve resulting screen diffs. $theme: inspection.private-get-typography-back-compat-theme($theme); @@ -67,7 +70,8 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( - m3-toolbar.$prefix, m3-toolbar.get-density-tokens($theme)); + m3-toolbar.$prefix, + map.get(m3-toolbar.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -97,10 +101,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-toolbar') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -115,15 +119,3 @@ } } } - -@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( - m2-toolbar.$prefix, - map.get($tokens, m2-toolbar.$prefix) - ); - } -} diff --git a/src/material/toolbar/toolbar.scss b/src/material/toolbar/toolbar.scss index ee13ec3ba952..137ca01066c6 100644 --- a/src/material/toolbar/toolbar.scss +++ b/src/material/toolbar/toolbar.scss @@ -1,20 +1,24 @@ @use '@angular/cdk'; @use '../button/m2-button'; +@use '../button/m3-button'; @use '../core/style/variables'; @use '../core/tokens/token-utils'; @use './m2-toolbar'; +@use './m3-toolbar'; +@use '../core/tokens/m3-system'; $row-padding: 16px !default; $token-prefix: m2-toolbar.$prefix; $token-slots: m2-toolbar.get-token-slots(); +$fallbacks: m3-toolbar.get-tokens(m3-system.$theme-with-system-vars); // @deprecated @breaking-change 8.0.0 // TODO: Remove once internal g3 apps no longer depend on this variable. Tracked with: COMP-303. $height-mobile-portrait: 56px !default; .mat-toolbar { - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background: token-utils.slot(container-background-color); color: token-utils.slot(container-text-color); @@ -54,11 +58,15 @@ $height-mobile-portrait: 56px !default; .mat-mdc-button-base.mat-mdc-button-base.mat-unthemed { $color-token: null; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { $color-token: token-utils.slot(container-text-color); } - @include token-utils.use-tokens(m2-button.$prefix, m2-button.get-token-slots()) { + $button-token-prefix: m2-button.$prefix; + $button-token-slots: m2-button.get-token-slots(); + $button-fallbacks: m3-button.get-tokens(m3-system.$theme-with-system-vars); + + @include token-utils.use-tokens($button-token-prefix, $button-token-slots, $button-fallbacks) { #{token-utils.get-token-variable-name(text-label-text-color)}: #{$color-token}; #{token-utils.get-token-variable-name(outlined-label-text-color)}: #{$color-token}; } @@ -80,7 +88,7 @@ $height-mobile-portrait: 56px !default; // Disable text wrapping inside of the toolbar. Developers are still able to overwrite it. white-space: nowrap; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { height: token-utils.slot(standard-height); @media (variables.$xsmall) { @@ -95,7 +103,7 @@ $height-mobile-portrait: 56px !default; flex-direction: column; width: 100%; - @include token-utils.use-tokens($token-prefix, $token-slots) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { min-height: token-utils.slot(standard-height); // As per specs, toolbars should have a different height in mobile devices. This has been diff --git a/src/material/tooltip/_m3-tooltip.scss b/src/material/tooltip/_m3-tooltip.scss index bc4d802c0a6e..b228d4955d94 100644 --- a/src/material/tooltip/_m3-tooltip.scss +++ b/src/material/tooltip/_m3-tooltip.scss @@ -5,21 +5,23 @@ $prefix: (mat, tooltip); /// Generates the tokens for MDC plain-tooltip -/// @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 plain-tooltip -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-color: map.get($systems, md-sys-color, inverse-surface), - container-shape: map.get($systems, md-sys-shape, corner-extra-small), - supporting-text-color: map.get($systems, md-sys-color, inverse-on-surface), - supporting-text-font: map.get($systems, md-sys-typescale, body-small-font), - supporting-text-line-height: map.get($systems, md-sys-typescale, body-small-line-height), - supporting-text-size: map.get($systems, md-sys-typescale, body-small-size), - supporting-text-tracking: map.get($systems, md-sys-typescale, body-small-tracking), - supporting-text-weight: map.get($systems, md-sys-typescale, body-small-weight) - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + container-color: map.get($system, inverse-surface), + container-shape: map.get($system, corner-extra-small), + supporting-text-color: map.get($system, inverse-on-surface), + ), + typography: ( + supporting-text-font: map.get($system, body-small-font), + supporting-text-line-height: map.get($system, body-small-line-height), + supporting-text-size: map.get($system, body-small-size), + supporting-text-tracking: map.get($system, body-small-tracking), + supporting-text-weight: map.get($system, body-small-weight) + ), + density: (), + ); } diff --git a/src/material/tooltip/_tooltip-theme.scss b/src/material/tooltip/_tooltip-theme.scss index df629ea41c40..9082ad6820c3 100644 --- a/src/material/tooltip/_tooltip-theme.scss +++ b/src/material/tooltip/_tooltip-theme.scss @@ -1,14 +1,17 @@ @use '../core/style/sass-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use './m2-tooltip'; +@use './m3-tooltip'; +@use 'sass:map'; @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-tooltip.$prefix, + map.get(m3-tooltip.get-tokens($theme), base)); } @else { // Add default values for tokens not related to color, typography, or density. @include sass-utils.current-selector-or-root() { @@ -22,7 +25,9 @@ @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-tooltip.$prefix, + map.get(m3-tooltip.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -35,7 +40,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-tooltip.$prefix, + map.get(m3-tooltip.get-tokens($theme), typography)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -48,7 +55,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - // There are no M3 density tokens for this component + @include token-utils.create-token-values( + m3-tooltip.$prefix, + map.get(m3-tooltip.get-tokens($theme), density)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -76,7 +85,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-tooltip') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -91,13 +103,3 @@ } } } - -@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 != () { - $tokens: token-utils.get-tokens-for($tokens, m2-tooltip.$prefix); - @include token-utils.create-token-values(m2-tooltip.$prefix, $tokens); - } -} diff --git a/src/material/tooltip/tooltip.scss b/src/material/tooltip/tooltip.scss index 5da06030c133..14ba932c0e6b 100644 --- a/src/material/tooltip/tooltip.scss +++ b/src/material/tooltip/tooltip.scss @@ -1,5 +1,11 @@ @use './m2-tooltip'; +@use './m3-tooltip'; @use '../core/tokens/token-utils'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-tooltip.$prefix; +$token-slots: m2-tooltip.get-token-slots(); +$fallbacks: m3-tooltip.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-tooltip { // We don't use MDC's positioning so this has to be relative. @@ -61,7 +67,7 @@ // MDC and removing them is likely to cause screenshot differences. will-change: transform, opacity; - @include token-utils.use-tokens(m2-tooltip.$prefix, m2-tooltip.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(container-color); color: token-utils.slot(supporting-text-color); border-radius: token-utils.slot(container-shape); diff --git a/src/material/tree/_m3-tree.scss b/src/material/tree/_m3-tree.scss index 7fb28ab600c7..3a154eee51ff 100644 --- a/src/material/tree/_m3-tree.scss +++ b/src/material/tree/_m3-tree.scss @@ -8,25 +8,27 @@ $prefix: (mat, tree); /// Generates custom tokens for the mat-tree. -/// @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-tree -@function get-tokens($systems, $exclude-hardcoded, $token-slots) { - $tokens: ( - container-background-color: map.get($systems, md-sys-color, surface), - node-text-color: map.get($systems, md-sys-color, on-surface), - node-text-font: map.get($systems, md-sys-typescale, body-large-font), - node-text-size: map.get($systems, md-sys-typescale, body-large-size), - node-text-weight: map.get($systems, md-sys-typescale, body-large-weight), - ); +@function get-tokens($theme) { + $system: m3-utils.get-system($theme); - @return m3-utils.namespace($prefix, $tokens, $token-slots); + @return ( + base: (), + color: ( + container-background-color: map.get($system, surface), + node-text-color: map.get($system, on-surface), + ), + typography: ( + node-text-font: map.get($system, body-large-font), + node-text-size: map.get($system, body-large-size), + node-text-weight: map.get($system, body-large-weight), + ), + density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), + ); } // Tokens that can be configured through Angular Material's density theming API. -@function get-density-tokens($theme) { - $scale: theming.clamp-density(inspection.get-theme-density($theme), -4); +@function get-density-tokens($scale) { + $scale: theming.clamp-density($scale, -4); $index: ($scale * -1) + 1; @return ( diff --git a/src/material/tree/_tree-theme.scss b/src/material/tree/_tree-theme.scss index 70671db570c1..33261a64bfbe 100644 --- a/src/material/tree/_tree-theme.scss +++ b/src/material/tree/_tree-theme.scss @@ -1,7 +1,6 @@ @use 'sass:map'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -@use '../core/theming/validation'; @use '../core/typography/typography'; @use '../core/style/sass-utils'; @use '../core/tokens/token-utils'; @@ -10,14 +9,18 @@ @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); + @include token-utils.create-token-values( + m3-tree.$prefix, + map.get(m3-tree.get-tokens($theme), base)); } @else { } } @mixin color($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, color)); + @include token-utils.create-token-values( + m3-tree.$prefix, + map.get(m3-tree.get-tokens($theme), color)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( @@ -30,7 +33,9 @@ @mixin typography($theme) { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); + @include token-utils.create-token-values( + m3-tree.$prefix, + map.get(m3-tree.get-tokens($theme), typography)); } @else { // TODO(mmalerba): Stop calling this and resolve resulting screen diffs. $theme: inspection.private-get-typography-back-compat-theme($theme); @@ -46,7 +51,9 @@ @mixin density($theme) { @if inspection.get-theme-version($theme) == 1 { - @include token-utils.create-token-values(m3-tree.$prefix, m3-tree.get-density-tokens($theme)); + @include token-utils.create-token-values( + m3-tree.$prefix, + map.get(m3-tree.get-tokens($theme), density)); } @else { $density-scale: inspection.get-theme-density($theme); @@ -76,10 +83,10 @@ @mixin theme($theme) { @include theming.private-check-duplicate-theme-styles($theme, 'mat-tree') { @if inspection.get-theme-version($theme) == 1 { - @include _theme-from-tokens(inspection.get-theme-tokens($theme)); - @if inspection.theme-has($theme, density) { - @include density($theme); - } + @include base($theme); + @include color($theme); + @include density($theme); + @include typography($theme); } @else { @include base($theme); @if inspection.theme-has($theme, color) { @@ -94,15 +101,3 @@ } } } - -@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( - m2-tree.$prefix, - map.get($tokens, m2-tree.$prefix) - ); - } -} diff --git a/src/material/tree/tree.scss b/src/material/tree/tree.scss index c6f11a992633..b2c975797ec8 100644 --- a/src/material/tree/tree.scss +++ b/src/material/tree/tree.scss @@ -1,17 +1,23 @@ @use '../core/tokens/token-utils'; @use './m2-tree'; +@use './m3-tree'; +@use '../core/tokens/m3-system'; + +$token-prefix: m2-tree.$prefix; +$token-slots: m2-tree.get-token-slots(); +$fallbacks: m3-tree.get-tokens(m3-system.$theme-with-system-vars); .mat-tree { display: block; - @include token-utils.use-tokens(m2-tree.$prefix, m2-tree.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { background-color: token-utils.slot(container-background-color); } } .mat-tree-node, .mat-nested-tree-node { - @include token-utils.use-tokens(m2-tree.$prefix, m2-tree.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { color: token-utils.slot(node-text-color); font-family: token-utils.slot(node-text-font); font-size: token-utils.slot(node-text-size); @@ -25,7 +31,7 @@ flex: 1; word-wrap: break-word; - @include token-utils.use-tokens(m2-tree.$prefix, m2-tree.get-token-slots()) { + @include token-utils.use-tokens($token-prefix, $token-slots, $fallbacks) { // TODO: before tokens were introduced, the `min-height` only applied to the // non-nested tree node. Should it apply to the nested one as well? min-height: token-utils.slot(node-min-height); From 681c22694cae0723f50f7e84286b8788b9b2296e Mon Sep 17 00:00:00 2001 From: Andrew Seguin Date: Thu, 15 May 2025 09:25:00 -0600 Subject: [PATCH 2/3] refactor: fixes found during internal testing --- src/material/button/_fab-theme.scss | 3 + src/material/button/_m3-icon-button.scss | 1 + src/material/card/_m3-card.scss | 10 ++-- src/material/core/_core-theme.scss | 13 +++++ .../_pseudo-checkbox-theme.scss | 2 +- .../_color-api-backwards-compatibility.scss | 56 ++++++++++++++----- src/material/core/tokens/_m3-utils.scss | 4 +- src/material/form-field/_m3-form-field.scss | 16 +++--- src/material/paginator/_m3-paginator.scss | 10 ++-- .../progress-spinner/progress-spinner.scss | 3 +- src/material/radio/_m3-radio.scss | 10 +++- src/material/sidenav/_m3-sidenav.scss | 2 +- src/material/sidenav/drawer.scss | 3 +- 13 files changed, 95 insertions(+), 38 deletions(-) diff --git a/src/material/button/_fab-theme.scss b/src/material/button/_fab-theme.scss index 450ca6cd4873..43e6111aede3 100644 --- a/src/material/button/_fab-theme.scss +++ b/src/material/button/_fab-theme.scss @@ -12,6 +12,9 @@ /// @param {Map} $theme The theme to generate base styles for. @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { + @include token-utils.create-token-values( + m3-fab.$prefix, + map.get(m3-fab.get-tokens($theme), base)); } @else { @include sass-utils.current-selector-or-root() { @include token-utils.create-token-values-mixed( diff --git a/src/material/button/_m3-icon-button.scss b/src/material/button/_m3-icon-button.scss index 73c03d049396..4514dc5fa699 100644 --- a/src/material/button/_m3-icon-button.scss +++ b/src/material/button/_m3-icon-button.scss @@ -16,6 +16,7 @@ $prefix: (mat, icon-button); $system: m3-utils.get-system($theme); @if $color-variant { $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); + $system: map.set($system, on-surface-variant, map.get($system, $color-variant)); } $tokens: ( diff --git a/src/material/card/_m3-card.scss b/src/material/card/_m3-card.scss index 6690ff612468..c9010cbd742b 100644 --- a/src/material/card/_m3-card.scss +++ b/src/material/card/_m3-card.scss @@ -26,11 +26,11 @@ $prefix: (mat, card); subtitle-text-color: map.get($system, on-surface), ), typography: ( - subtitle-text-font: map.get($system, subtitle-large-font), - subtitle-text-line-height: map.get($system, subtitle-large-line-height), - subtitle-text-size: map.get($system, subtitle-large-size), - subtitle-text-tracking: map.get($system, subtitle-large-tracking), - subtitle-text-weight: map.get($system, subtitle-large-weight), + subtitle-text-font: map.get($system, title-medium-font), + subtitle-text-line-height: map.get($system, title-medium-line-height), + subtitle-text-size: map.get($system, title-medium-size), + subtitle-text-tracking: map.get($system, title-medium-tracking), + subtitle-text-weight: map.get($system, title-medium-weight), title-text-font: map.get($system, title-large-font), title-text-line-height: map.get($system, title-large-line-height), title-text-size: map.get($system, title-large-size), diff --git a/src/material/core/_core-theme.scss b/src/material/core/_core-theme.scss index c742c6b6510f..7f3d4aaacfb2 100644 --- a/src/material/core/_core-theme.scss +++ b/src/material/core/_core-theme.scss @@ -16,6 +16,7 @@ @use 'option/m2-optgroup'; @use 'option/m3-optgroup'; @use 'selection/pseudo-checkbox/m2-pseudo-checkbox'; +@use 'selection/pseudo-checkbox/m3-pseudo-checkbox'; @use 'sass:map'; @mixin base($theme) { @@ -32,6 +33,9 @@ @include token-utils.create-token-values( m3-optgroup.$prefix, map.get(m3-optgroup.get-tokens($theme), base)); + @include token-utils.create-token-values( + m3-pseudo-checkbox.$prefix, + map.get(m3-pseudo-checkbox.get-tokens($theme), base)); } @else { @include ripple-theme.base($theme); @include option-theme.base($theme); @@ -58,6 +62,9 @@ @include token-utils.create-token-values( m3-optgroup.$prefix, map.get(m3-optgroup.get-tokens($theme), color)); + @include token-utils.create-token-values( + m3-pseudo-checkbox.$prefix, + map.get(m3-pseudo-checkbox.get-tokens($theme), color)); } @else { @include ripple-theme.color($theme); @include option-theme.color($theme); @@ -84,6 +91,9 @@ @include token-utils.create-token-values( m3-optgroup.$prefix, map.get(m3-optgroup.get-tokens($theme), typography)); + @include token-utils.create-token-values( + m3-pseudo-checkbox.$prefix, + map.get(m3-pseudo-checkbox.get-tokens($theme), typography)); } @else { @include option-theme.typography($theme); @include optgroup-theme.typography($theme); @@ -106,6 +116,9 @@ @include token-utils.create-token-values( m3-optgroup.$prefix, map.get(m3-optgroup.get-tokens($theme), density)); + @include token-utils.create-token-values( + m3-pseudo-checkbox.$prefix, + map.get(m3-pseudo-checkbox.get-tokens($theme), density)); } @else { @include option-theme.density($theme); @include optgroup-theme.density($theme); diff --git a/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss b/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss index 2d4f30a6201f..01c94389191a 100644 --- a/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss +++ b/src/material/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss @@ -44,7 +44,7 @@ @if inspection.get-theme-version($theme) == 1 { @include token-utils.create-token-values( m3-pseudo-checkbox.$prefix, - map.get(m3-pseudo-checkbox.get-tokens($theme, $color-variant), base)); + map.get(m3-pseudo-checkbox.get-tokens($theme, $color-variant), color)); } @else { // Default to the accent color. Note that the pseudo checkboxes are meant to inherit the // theme from their parent, rather than implementing their own theming, which is why we diff --git a/src/material/core/theming/_color-api-backwards-compatibility.scss b/src/material/core/theming/_color-api-backwards-compatibility.scss index e9199cf604f4..5a1bea93654e 100644 --- a/src/material/core/theming/_color-api-backwards-compatibility.scss +++ b/src/material/core/theming/_color-api-backwards-compatibility.scss @@ -27,15 +27,21 @@ $_overrides-only: true; $secondary-when-primary: if($color-variant == primary, secondary, $color-variant); & { - @include option-theme.color($theme, $secondary-when-primary); + @if ($color-variant != primary) { + @include option-theme.color($theme, $secondary-when-primary); + } } & { - @include progress-spinner-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include progress-spinner-theme.color($theme, $color-variant); + } } & { - @include pseudo-checkbox-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include pseudo-checkbox-theme.color($theme, $color-variant); + } } & { @@ -47,16 +53,22 @@ $_overrides-only: true; } &.mat-mdc-checkbox { - @include checkbox-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include checkbox-theme.color($theme, $color-variant); + } } &.mat-mdc-slider { - @include slider-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include slider-theme.color($theme, $color-variant); + } } &.mat-mdc-tab-group, &.mat-mdc-tab-nav-bar { - @include tabs-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include tabs-theme.color($theme, $color-variant); + } } &.mat-mdc-slide-toggle { @@ -64,19 +76,27 @@ $_overrides-only: true; } &.mat-mdc-form-field { - @include select-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include select-theme.color($theme, $color-variant); + } } &.mat-mdc-radio-button { - @include radio-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include radio-theme.color($theme, $color-variant); + } } &.mat-mdc-progress-bar { - @include progress-bar-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include progress-bar-theme.color($theme, $color-variant); + } } &.mat-mdc-form-field { - @include form-field-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include form-field-theme.color($theme, $color-variant); + } } &.mat-datepicker-content { @@ -84,22 +104,28 @@ $_overrides-only: true; } &.mat-mdc-button-base { - @include button-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include button-theme.color($theme, $color-variant); + } @include icon-button-theme.color($theme, $color-variant); } &.mat-mdc-standard-chip { - @include chips-theme.color($theme, $secondary-when-primary); + @if ($color-variant != primary) { + @include chips-theme.color($theme, $secondary-when-primary); + } } .mdc-list-item__start, .mdc-list-item__end { - @include checkbox-theme.color($theme, $color-variant); - @include radio-theme.color($theme, $color-variant); + @if ($color-variant != primary) { + @include checkbox-theme.color($theme, $color-variant); + @include radio-theme.color($theme, $color-variant); + } } // M3 dropped support for warn/error color FABs. - @if $color-variant != error { + @if $color-variant != error and $color-variant != primary { &.mat-mdc-fab, &.mat-mdc-mini-fab { @include fab-theme.color($theme, $color-variant); diff --git a/src/material/core/tokens/_m3-utils.scss b/src/material/core/tokens/_m3-utils.scss index f9cc25a15653..0d096e151c7f 100644 --- a/src/material/core/tokens/_m3-utils.scss +++ b/src/material/core/tokens/_m3-utils.scss @@ -38,7 +38,9 @@ // Opacity may be a system level value less than 1, instead of the intended // whole percentage, e.g. 38%. Remove this support when possible. - @if (meta.type-of($opacity) == number and $opacity < 1) { + @if (meta.type-of($opacity) == string and string.index($opacity, '--') == 1) { + $opacity: 'calc(var(#{$opacity}) * 100%)'; + } @else if (meta.type-of($opacity) == number and $opacity < 1) { $opacity: '#{$opacity * 100}%'; } diff --git a/src/material/form-field/_m3-form-field.scss b/src/material/form-field/_m3-form-field.scss index 84e8fcafb1d0..ee7e8bf1e78c 100644 --- a/src/material/form-field/_m3-form-field.scss +++ b/src/material/form-field/_m3-form-field.scss @@ -59,10 +59,6 @@ $prefix: (mat, form-field); filled-input-text-color: map.get($system, on-surface), filled-input-text-placeholder-color: map.get($system, on-surface-variant), filled-label-text-color: map.get($system, on-surface-variant), - filled-label-text-font: map.get($system, body-large-font), - filled-label-text-size: map.get($system, body-large-size), - filled-label-text-tracking: map.get($system, body-large-tracking), - filled-label-text-weight: map.get($system, body-large-weight), focus-select-arrow-color: map.get($system, primary), focus-state-layer-opacity: 0, hover-state-layer-opacity: map.get($system, hover-state-layer-opacity), @@ -87,10 +83,6 @@ $prefix: (mat, form-field); outlined-input-text-color: map.get($system, on-surface), outlined-input-text-placeholder-color: map.get($system, on-surface-variant), outlined-label-text-color: map.get($system, on-surface-variant), - outlined-label-text-font: map.get($system, body-large-font), - outlined-label-text-size: map.get($system, body-large-size), - outlined-label-text-tracking: map.get($system, body-large-tracking), - outlined-label-text-weight: map.get($system, body-large-weight), outlined-outline-color: map.get($system, outline), select-disabled-option-text-color: m3-utils.color-with-opacity(map.get($system, neutral10), 38%), @@ -109,6 +101,14 @@ $prefix: (mat, form-field); subscript-text-size: map.get($system, body-small-size), subscript-text-tracking: map.get($system, body-small-tracking), subscript-text-weight: map.get($system, body-small-weight), + outlined-label-text-font: map.get($system, body-large-font), + outlined-label-text-size: map.get($system, body-large-size), + outlined-label-text-tracking: map.get($system, body-large-tracking), + outlined-label-text-weight: map.get($system, body-large-weight), + filled-label-text-font: map.get($system, body-large-font), + filled-label-text-size: map.get($system, body-large-size), + filled-label-text-tracking: map.get($system, body-large-tracking), + filled-label-text-weight: map.get($system, body-large-weight), ), density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); diff --git a/src/material/paginator/_m3-paginator.scss b/src/material/paginator/_m3-paginator.scss index bd3fc2321130..9732a0779f94 100644 --- a/src/material/paginator/_m3-paginator.scss +++ b/src/material/paginator/_m3-paginator.scss @@ -13,16 +13,18 @@ $prefix: (mat, paginator); @return ( base: (), - color: (), - typography: ( + color: ( + container-text-color: map.get($system, on-surface), container-background-color: map.get($system, surface), + disabled-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), + enabled-icon-color: map.get($system, on-surface-variant), + ), + typography: ( container-text-font: map.get($system, body-small-font), container-text-line-height: map.get($system, body-small-line-height), container-text-size: map.get($system, body-small-size), container-text-tracking: map.get($system, body-small-tracking), container-text-weight: map.get($system, body-small-weight), - disabled-icon-color: m3-utils.color-with-opacity(map.get($system, on-surface), 38%), - enabled-icon-color: map.get($system, on-surface-variant), select-trigger-text-size: map.get($system, body-small-size), ), density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), diff --git a/src/material/progress-spinner/progress-spinner.scss b/src/material/progress-spinner/progress-spinner.scss index 9c504521ec8e..00cde8d7ad73 100644 --- a/src/material/progress-spinner/progress-spinner.scss +++ b/src/material/progress-spinner/progress-spinner.scss @@ -98,7 +98,8 @@ $fallbacks: m3-progress-spinner.get-tokens(m3-system.$theme-with-system-vars); .mat-mdc-progress-spinner .mdc-circular-progress__indeterminate-circle-graphic { @include token-utils.use-tokens( m2-progress-spinner.$prefix, - m2-progress-spinner.get-token-slots() + m2-progress-spinner.get-token-slots(), + $fallbacks, ) { stroke: token-utils.slot(active-indicator-color); } diff --git a/src/material/radio/_m3-radio.scss b/src/material/radio/_m3-radio.scss index 9293d88e087a..b9e3035ad835 100644 --- a/src/material/radio/_m3-radio.scss +++ b/src/material/radio/_m3-radio.scss @@ -15,7 +15,7 @@ $prefix: (mat, radio); $system: m3-utils.replace-colors-with-variant($system, primary, $color-variant); } - @return ( + $tokens: ( base: ( disabled-unselected-icon-opacity: 0.38, disabled-selected-icon-opacity: 0.38, @@ -45,6 +45,14 @@ $prefix: (mat, radio); ), density: get-density-tokens(map.get($theme, inspection.$internals, density-scale)), ); + + // Temporary removal where color variants previously did not include the + // unselected icon color. Remove this and approve internal screenshot changes. + @if $color-variant { + $tokens: map.remove($tokens, color, unselected-icon-color); + } + + @return $tokens; } // Tokens that can be configured through Angular Material's density theming API. diff --git a/src/material/sidenav/_m3-sidenav.scss b/src/material/sidenav/_m3-sidenav.scss index cf162663e2ea..d66ff5bcdf7e 100644 --- a/src/material/sidenav/_m3-sidenav.scss +++ b/src/material/sidenav/_m3-sidenav.scss @@ -12,7 +12,6 @@ $prefix: (mat, sidenav); base: ( container-shape: map.get($system, corner-large), container-elevation-shadow: none, - container-divider-color: transparent, container-width: 360px, ), color: ( @@ -21,6 +20,7 @@ $prefix: (mat, sidenav); content-background-color: map.get($system, background), content-text-color: map.get($system, on-background), scrim-color: m3-utils.color-with-opacity(map.get($system, neutral-variant20), 40%), + container-divider-color: transparent, ), typography: (), density: (), diff --git a/src/material/sidenav/drawer.scss b/src/material/sidenav/drawer.scss index 72d3a846c107..955cacb3d4b5 100644 --- a/src/material/sidenav/drawer.scss +++ b/src/material/sidenav/drawer.scss @@ -232,7 +232,8 @@ $fallbacks: m3-sidenav.get-tokens(m3-system.$theme-with-system-vars); @include token-utils.use-tokens( $token-prefix, - $token-slots + $token-slots, + $fallbacks, ) { border-right-color: token-utils.slot(container-divider-color); border-right-width: 1px; From c49ae7ec4a4f32c98b583e20b06c9fce64d8264c Mon Sep 17 00:00:00 2001 From: Andrew Seguin Date: Thu, 15 May 2025 10:20:12 -0600 Subject: [PATCH 3/3] refactor: more fixes --- .../core/theming/_color-api-backwards-compatibility.scss | 2 -- src/material/sidenav/_m3-sidenav.scss | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/material/core/theming/_color-api-backwards-compatibility.scss b/src/material/core/theming/_color-api-backwards-compatibility.scss index 5a1bea93654e..0b90e7adcfb5 100644 --- a/src/material/core/theming/_color-api-backwards-compatibility.scss +++ b/src/material/core/theming/_color-api-backwards-compatibility.scss @@ -66,9 +66,7 @@ $_overrides-only: true; &.mat-mdc-tab-group, &.mat-mdc-tab-nav-bar { - @if ($color-variant != primary) { @include tabs-theme.color($theme, $color-variant); - } } &.mat-mdc-slide-toggle { diff --git a/src/material/sidenav/_m3-sidenav.scss b/src/material/sidenav/_m3-sidenav.scss index d66ff5bcdf7e..9cb71bdbfb01 100644 --- a/src/material/sidenav/_m3-sidenav.scss +++ b/src/material/sidenav/_m3-sidenav.scss @@ -13,6 +13,7 @@ $prefix: (mat, sidenav); container-shape: map.get($system, corner-large), container-elevation-shadow: none, container-width: 360px, + container-divider-color: transparent, ), color: ( container-background-color: map.get($system, surface), @@ -20,7 +21,6 @@ $prefix: (mat, sidenav); content-background-color: map.get($system, background), content-text-color: map.get($system, on-background), scrim-color: m3-utils.color-with-opacity(map.get($system, neutral-variant20), 40%), - container-divider-color: transparent, ), typography: (), density: (),