diff --git a/src/material/core/theming/_inspection.scss b/src/material/core/theming/_inspection.scss index 30f6afc069c1..7747097aa126 100644 --- a/src/material/core/theming/_inspection.scss +++ b/src/material/core/theming/_inspection.scss @@ -75,8 +75,8 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac @function get-theme-color($theme, $args...) { $version: get-theme-version($theme); $args-count: list.length($args); - @if $args-count != 1 and $args-count != 2 { - @error #{'Expected 2 or 3 arguments. Got:'} $args-count + 1; + @if $args-count != 1 and $args-count != 2 and $args-count != 3 { + @error #{'Expected between 2 and 4 arguments. Got:'} $args-count + 1; } @if $version == 0 { diff --git a/src/material/core/theming/tests/theming-inspection-api.spec.ts b/src/material/core/theming/tests/theming-inspection-api.spec.ts index 61d56dceef8e..abe38d84e515 100644 --- a/src/material/core/theming/tests/theming-inspection-api.spec.ts +++ b/src/material/core/theming/tests/theming-inspection-api.spec.ts @@ -328,7 +328,7 @@ describe('theming inspection api', () => { color: mat.get-theme-color($theme); } `), - ).toThrowError(/Expected 2 or 3 arguments. Got: 1/); + ).toThrowError(/Expected between 2 and 4 arguments\. Got: 1/); }); it('should get typography properties from theme', () => { diff --git a/src/material/core/tokens/_token-utils.scss b/src/material/core/tokens/_token-utils.scss index e6d9565f798a..a09bd188f6d7 100644 --- a/src/material/core/tokens/_token-utils.scss +++ b/src/material/core/tokens/_token-utils.scss @@ -9,6 +9,9 @@ @use '../theming/theming'; @use '../typography/typography'; +// Indicates whether we're building internally. Used for backwards compatibility. +$private-is-internal-build: false; + $_placeholder-color-palette: theming.define-palette(palette.$red-palette); // Placeholder color config that can be passed to token getter functions when generating token diff --git a/src/material/core/tokens/m2/mat/_datepicker.scss b/src/material/core/tokens/m2/mat/_datepicker.scss index 6493a5d45776..ef00a98bf717 100644 --- a/src/material/core/tokens/m2/mat/_datepicker.scss +++ b/src/material/core/tokens/m2/mat/_datepicker.scss @@ -50,7 +50,6 @@ $private-default-overlap-color: #a8dab5; $preview-outline-color: $divider-color; $today-disabled-outline-color: null; $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $primary-color: inspection.get-theme-color($theme, primary); $range-tokens: get-range-color-tokens(private-get-range-background-color($primary-color)); @@ -75,7 +74,7 @@ $private-default-overlap-color: #a8dab5; @return sass-utils.merge-all($calendar-tokens, $toggle-tokens, $range-tokens, ( toggle-icon-color: $inactive-icon-color, calendar-body-label-text-color: $secondary-text-color, - calendar-period-button-text-color: $on-surface, + calendar-period-button-text-color: inspection.get-theme-color($theme, foreground, text, 1), calendar-period-button-icon-color: $inactive-icon-color, calendar-navigation-button-icon-color: $inactive-icon-color, calendar-header-divider-color: $divider-color, diff --git a/src/material/core/tokens/m2/mat/_fab-small.scss b/src/material/core/tokens/m2/mat/_fab-small.scss index 4ff3476b347b..beb74723bb9b 100644 --- a/src/material/core/tokens/m2/mat/_fab-small.scss +++ b/src/material/core/tokens/m2/mat/_fab-small.scss @@ -18,7 +18,6 @@ $prefix: (mat, fab-small); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -29,13 +28,13 @@ $prefix: (mat, fab-small); foreground-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), @@ -48,24 +47,42 @@ $prefix: (mat, fab-small); // MDC doesn't have tokens for disabled FABs so we need to implemented them ourselves. // Background color of the container when the FAB is disabled. - disabled-state-container-color: rgba($on-surface, 0.12), + disabled-state-container-color: inspection.get-theme-color($theme, background, disabled-button, + 0.12), // Color of the icons and projected text when the FAB is disabled. - disabled-state-foreground-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), + disabled-state-foreground-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), ); } // Generates the mapping for the properties that change based on the FAB palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; - $container-color: inspection.get-theme-color($theme, $palette-name); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); - $color: if($contrast-tone == 'dark', #000, #fff); + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $foreground-color: null; + $state-layer-color: null; + $ripple-color: null; + + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + $foreground-color: $color; + $state-layer-color: $color; + $ripple-color: rgba($color, 0.1); + } + @else { + $foreground-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1); + } @return ( - foreground-color: $color, - state-layer-color: $color, - ripple-color: rgba($color, 0.1), + foreground-color: $foreground-color, + state-layer-color: $state-layer-color, + ripple-color: $ripple-color, ); } diff --git a/src/material/core/tokens/m2/mat/_fab.scss b/src/material/core/tokens/m2/mat/_fab.scss index ede83f1dbc39..e3aed807d262 100644 --- a/src/material/core/tokens/m2/mat/_fab.scss +++ b/src/material/core/tokens/m2/mat/_fab.scss @@ -18,7 +18,6 @@ $prefix: (mat, fab); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -29,13 +28,13 @@ $prefix: (mat, fab); foreground-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), @@ -48,24 +47,42 @@ $prefix: (mat, fab); // MDC doesn't have tokens for disabled FABs so we need to implemented them ourselves. // Background color of the container when the FAB is disabled. - disabled-state-container-color: rgba($on-surface, 0.12), + disabled-state-container-color: inspection.get-theme-color($theme, background, disabled-button, + 0.12), // Color of the icons and projected text when the FAB is disabled. - disabled-state-foreground-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), + disabled-state-foreground-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), ); } // Generates the mapping for the properties that change based on the FAB palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; - $container-color: inspection.get-theme-color($theme, $palette-name); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); - $color: if($contrast-tone == 'dark', #000, #fff); + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $foreground-color: null; + $state-layer-color: null; + $ripple-color: null; + + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + $foreground-color: $color; + $state-layer-color: $color; + $ripple-color: rgba($color, 0.1); + } + @else { + $foreground-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1); + } @return ( - foreground-color: $color, - state-layer-color: $color, - ripple-color: rgba($color, 0.1), + foreground-color: $foreground-color, + state-layer-color: $state-layer-color, + ripple-color: $ripple-color, ); } diff --git a/src/material/core/tokens/m2/mat/_filled-button.scss b/src/material/core/tokens/m2/mat/_filled-button.scss index 0fc6855ea769..5fc78f2070ff 100644 --- a/src/material/core/tokens/m2/mat/_filled-button.scss +++ b/src/material/core/tokens/m2/mat/_filled-button.scss @@ -28,7 +28,6 @@ $prefix: (mat, filled-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -36,13 +35,13 @@ $prefix: (mat, filled-button); @return ( // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), @@ -57,14 +56,27 @@ $prefix: (mat, filled-button); // Generates the mapping for the properties that change based on the button palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; - $container-color: inspection.get-theme-color($theme, $palette-name); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); - $color: if($contrast-tone == 'dark', #000, #fff); + $state-layer-color: null; + $ripple-color: null; + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + $state-layer-color: $color; + $ripple-color: rgba($color, 0.1); + } + @else { + $state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1); + } @return ( - state-layer-color: $color, - ripple-color: rgba($color, 0.1), + state-layer-color: $state-layer-color, + ripple-color: $ripple-color, ); } diff --git a/src/material/core/tokens/m2/mat/_form-field.scss b/src/material/core/tokens/m2/mat/_form-field.scss index 96ec73b5b2bb..376e92993947 100644 --- a/src/material/core/tokens/m2/mat/_form-field.scss +++ b/src/material/core/tokens/m2/mat/_form-field.scss @@ -20,13 +20,13 @@ $prefix: (mat, form-field); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $color-tokens: private-get-color-palette-color-tokens($theme, primary); @return map.merge($color-tokens, ( // MDC has a token for the enabled placeholder, but not for the disabled one. - disabled-input-text-placeholder-color: rgba($on-surface, 0.38), - state-layer-color: rgba($on-surface, 0.87), + disabled-input-text-placeholder-color: + inspection.get-theme-color($theme, foreground, icon, 0.38), + state-layer-color: inspection.get-theme-color($theme, foreground, base, 0.87), error-text-color: inspection.get-theme-color($theme, warn), // On dark themes we set the native `select` color to some shade of white, @@ -56,8 +56,8 @@ $prefix: (mat, form-field); // These values are taken from the MDC select implementation: // https://github.com/material-components/material-components-web/blob/master/packages/mdc-select/_select-theme.scss - enabled-select-arrow-color: rgba($on-surface, 0.54), - disabled-select-arrow-color: rgba($on-surface, 0.38), + enabled-select-arrow-color: inspection.get-theme-color($theme, foreground, icon, 0.54), + disabled-select-arrow-color: inspection.get-theme-color($theme, foreground, icon, 0.38), hover-state-layer-opacity: if($is-dark, 0.08, 0.04), focus-state-layer-opacity: if($is-dark, 0.24, 0.08), diff --git a/src/material/core/tokens/m2/mat/_icon-button.scss b/src/material/core/tokens/m2/mat/_icon-button.scss index c516895b67ff..48013f246243 100644 --- a/src/material/core/tokens/m2/mat/_icon-button.scss +++ b/src/material/core/tokens/m2/mat/_icon-button.scss @@ -18,7 +18,6 @@ $prefix: (mat, icon-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -26,13 +25,13 @@ $prefix: (mat, icon-button); @return ( // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), diff --git a/src/material/core/tokens/m2/mat/_menu.scss b/src/material/core/tokens/m2/mat/_menu.scss index 8b8ad3dfa6be..79c9155eeb26 100644 --- a/src/material/core/tokens/m2/mat/_menu.scss +++ b/src/material/core/tokens/m2/mat/_menu.scss @@ -24,8 +24,8 @@ $prefix: (mat, menu); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); - $active-state-layer-color: rgba($on-surface, if($is-dark, 0.08, 0.04)); + $active-state-layer-color: inspection.get-theme-color($theme, foreground, base, + if($is-dark, 0.08, 0.04)); $text-color: inspection.get-theme-color($theme, foreground, text); @return ( diff --git a/src/material/core/tokens/m2/mat/_option.scss b/src/material/core/tokens/m2/mat/_option.scss index b7a76a9a2ab3..321d408bbcf2 100644 --- a/src/material/core/tokens/m2/mat/_option.scss +++ b/src/material/core/tokens/m2/mat/_option.scss @@ -15,8 +15,8 @@ $prefix: (mat, option); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme, $palette-name: primary) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); - $active-state-layer-color: rgba($on-surface, if($is-dark, 0.08, 0.04)); + $active-state-layer-color: inspection.get-theme-color($theme, foreground, base, + if($is-dark, 0.08, 0.04)); @return ( selected-state-label-text-color: inspection.get-theme-color($theme, $palette-name), diff --git a/src/material/core/tokens/m2/mat/_outlined-button.scss b/src/material/core/tokens/m2/mat/_outlined-button.scss index cb33ce751872..6f706fe55019 100644 --- a/src/material/core/tokens/m2/mat/_outlined-button.scss +++ b/src/material/core/tokens/m2/mat/_outlined-button.scss @@ -28,7 +28,6 @@ $prefix: (mat, outlined-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -36,13 +35,13 @@ $prefix: (mat, outlined-button); @return ( // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), diff --git a/src/material/core/tokens/m2/mat/_protected-button.scss b/src/material/core/tokens/m2/mat/_protected-button.scss index dc3291f90c0b..5550574dab5d 100644 --- a/src/material/core/tokens/m2/mat/_protected-button.scss +++ b/src/material/core/tokens/m2/mat/_protected-button.scss @@ -28,7 +28,6 @@ $prefix: (mat, protected-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -36,13 +35,13 @@ $prefix: (mat, protected-button); @return ( // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), @@ -57,14 +56,27 @@ $prefix: (mat, protected-button); // Generates the mapping for the properties that change based on the button palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; - $container-color: inspection.get-theme-color($theme, $palette-name); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); - $color: if($contrast-tone == 'dark', #000, #fff); + $state-layer-color: null; + $ripple-color: null; + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + $state-layer-color: $color; + $ripple-color: rgba($color, 0.1); + } + @else { + $state-layer-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + $ripple-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 0.1); + } @return ( - state-layer-color: $color, - ripple-color: rgba($color, 0.1), + state-layer-color: $state-layer-color, + ripple-color: $ripple-color, ); } diff --git a/src/material/core/tokens/m2/mat/_radio.scss b/src/material/core/tokens/m2/mat/_radio.scss index 54170f26ab02..605ffa870639 100644 --- a/src/material/core/tokens/m2/mat/_radio.scss +++ b/src/material/core/tokens/m2/mat/_radio.scss @@ -14,10 +14,8 @@ $prefix: (mat, radio); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme, $palette-name: accent) { - $is-dark: inspection.get-theme-type($theme) == dark; - @return ( - ripple-color: if($is-dark, #fff, #000), + ripple-color: inspection.get-theme-color($theme, foreground, base), checked-ripple-color: inspection.get-theme-color($theme, $palette-name, default), disabled-label-color: inspection.get-theme-color($theme, foreground, disabled-text), ); diff --git a/src/material/core/tokens/m2/mat/_select.scss b/src/material/core/tokens/m2/mat/_select.scss index 76bcd932011d..5dbfa01aa2a1 100644 --- a/src/material/core/tokens/m2/mat/_select.scss +++ b/src/material/core/tokens/m2/mat/_select.scss @@ -19,19 +19,29 @@ $prefix: (mat, select); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme, $palette-name: primary) { $is-dark: inspection.get-theme-type($theme) == dark; + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. $on-surface: if($is-dark, #fff, #000); + $text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, text, 1)); + $disabled-text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, disabled-text, 1)); + $icon-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, divider, 1)); @return ( panel-background-color: inspection.get-theme-color($theme, background, card), - enabled-trigger-text-color: rgba($on-surface, 0.87), - disabled-trigger-text-color: rgba($on-surface, 0.38), - placeholder-text-color: rgba($on-surface, 0.6), - enabled-arrow-color: rgba($on-surface, 0.54), - disabled-arrow-color: rgba($on-surface, 0.38), + enabled-trigger-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.87), + disabled-trigger-text-color: + sass-utils.safe-color-change($disabled-text-color-base, $alpha: 0.38), + placeholder-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), + enabled-arrow-color: sass-utils.safe-color-change($icon-color-base, $alpha: 0.54), + disabled-arrow-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.38), focused-arrow-color: sass-utils.safe-color-change( - inspection.get-theme-color($theme, $palette-name, default), $alpha: 0.87), + inspection.get-theme-color($theme, $palette-name, default), $alpha: 0.87), invalid-arrow-color: sass-utils.safe-color-change( - inspection.get-theme-color($theme, warn, default), $alpha: 0.87), + inspection.get-theme-color($theme, warn, default), $alpha: 0.87), ); } diff --git a/src/material/core/tokens/m2/mat/_tab-header.scss b/src/material/core/tokens/m2/mat/_tab-header.scss index deaebf6ac72f..9773fb70d769 100644 --- a/src/material/core/tokens/m2/mat/_tab-header.scss +++ b/src/material/core/tokens/m2/mat/_tab-header.scss @@ -19,13 +19,13 @@ $prefix: (mat, tab-header); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme, $palette-name: primary) { $is-dark: inspection.get-theme-type($theme) == dark; - $inactive-label-text-color: rgba(if($is-dark, #fff, #000), 0.6); + $inactive-label-text-color: inspection.get-theme-color($theme, foreground, text, 0.6); $active-label-text-color: inspection.get-theme-color($theme, $palette-name, default); $ripple-color: inspection.get-theme-color($theme, $palette-name, default); @return ( disabled-ripple-color: inspection.get-theme-color($theme, foreground, disabled), - pagination-icon-color: if($is-dark, #fff, #000), + pagination-icon-color: inspection.get-theme-color($theme, foreground, icon, 1), // Note: MDC has equivalents of these tokens, but they lead to much higher selector specificity. inactive-label-text-color: $inactive-label-text-color, diff --git a/src/material/core/tokens/m2/mat/_text-button.scss b/src/material/core/tokens/m2/mat/_text-button.scss index 37c749811d84..aeb4474a4267 100644 --- a/src/material/core/tokens/m2/mat/_text-button.scss +++ b/src/material/core/tokens/m2/mat/_text-button.scss @@ -31,7 +31,6 @@ $prefix: (mat, text-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $ripple-opacities: if($is-dark, mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities @@ -39,13 +38,13 @@ $prefix: (mat, text-button); @return ( // Color of the element that shows the hover, focus and pressed states. - state-layer-color: $on-surface, + state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the element that shows the hover, focus and pressed states while disabled. - disabled-state-layer-color: $on-surface, + disabled-state-layer-color: inspection.get-theme-color($theme, foreground, base), // Color of the ripple element. - ripple-color: rgba($on-surface, 0.1), + ripple-color: inspection.get-theme-color($theme, foreground, base, 0.1), // Opacity of the ripple when the button is hovered. hover-state-layer-opacity: map.get($ripple-opacities, hover), diff --git a/src/material/core/tokens/m2/mdc/_dialog.scss b/src/material/core/tokens/m2/mdc/_dialog.scss index 83fc63519880..51d13ae801aa 100644 --- a/src/material/core/tokens/m2/mdc/_dialog.scss +++ b/src/material/core/tokens/m2/mdc/_dialog.scss @@ -55,15 +55,21 @@ $prefix: (mdc, dialog); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $text-base: if(token-utils.$private-is-internal-build, + if($is-dark, #fff, #000), + inspection.get-theme-color($theme, foreground, text, 1) + ); @return ( // Background color of the container. container-color: inspection.get-theme-color($theme, background, dialog), // Color of the dialog header. - subhead-color: rgba($on-surface, 0.87), + subhead-color: sass-utils.safe-color-change($text-base, $alpha: 0.87), // Color of the dialog body text. - supporting-text-color: rgba($on-surface, 0.6), + supporting-text-color: sass-utils.safe-color-change($text-base, $alpha: 0.6), ); } diff --git a/src/material/core/tokens/m2/mdc/_filled-button.scss b/src/material/core/tokens/m2/mdc/_filled-button.scss index 408c6716f04a..93800ea7261e 100644 --- a/src/material/core/tokens/m2/mdc/_filled-button.scss +++ b/src/material/core/tokens/m2/mdc/_filled-button.scss @@ -51,26 +51,36 @@ $prefix: (mdc, filled-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $surface: inspection.get-theme-color($theme, background, card); - $on-surface: if($is-dark, #fff, #000); @return ( - container-color: $surface, - label-text-color: $on-surface, - disabled-container-color: rgba($on-surface, 0.12), - disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), + container-color: inspection.get-theme-color($theme, background, card), + label-text-color: inspection.get-theme-color($theme, foreground, text, 1), + disabled-container-color: inspection.get-theme-color($theme, foreground, disabled-button, + 0.12), + disabled-label-text-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), ); } // Generates the mapping for the properties that change based on the button palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; $container-color: inspection.get-theme-color($theme, $palette-name, default); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $label-text-color: null; + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $label-text-color: if($contrast-tone == 'dark', #000, #fff); + } + @else { + $label-text-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + } @return ( container-color: $container-color, - label-text-color: if($contrast-tone == 'dark', #000, #fff), + label-text-color: $label-text-color, ); } diff --git a/src/material/core/tokens/m2/mdc/_filled-text-field.scss b/src/material/core/tokens/m2/mdc/_filled-text-field.scss index ee4d80779ae6..34e1e570396f 100644 --- a/src/material/core/tokens/m2/mdc/_filled-text-field.scss +++ b/src/material/core/tokens/m2/mdc/_filled-text-field.scss @@ -93,30 +93,42 @@ $prefix: (mdc, filled-text-field); @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; $surface: inspection.get-theme-color($theme, background, card); - $on-surface: if($is-dark, #fff, #000); $warn-color: inspection.get-theme-color($theme, warn); $color-tokens: private-get-color-palette-color-tokens($theme, primary); + $on-surface: if($is-dark, #fff, #000); + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, text, 1)); + $disabled-text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, disabled-text, 1)); + $divider-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, divider, 1)); @return map.merge($color-tokens, ( container-color: _variable-safe-mix($on-surface, $surface, 4%), disabled-container-color: _variable-safe-mix($on-surface, $surface, 2%), - label-text-color: rgba($on-surface, 0.6), - hover-label-text-color: rgba($on-surface, 0.6), - disabled-label-text-color: rgba($on-surface, 0.38), + label-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), + hover-label-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), + disabled-label-text-color: + sass-utils.safe-color-change($disabled-text-color-base, $alpha: 0.38), - input-text-color: rgba($on-surface, 0.87), - disabled-input-text-color: rgba($on-surface, 0.38), - input-text-placeholder-color: rgba($on-surface, 0.6), + input-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.87), + disabled-input-text-color: + sass-utils.safe-color-change($disabled-text-color-base, $alpha: 0.38), + input-text-placeholder-color: + sass-utils.safe-color-change($text-color-base, $alpha: 0.6), error-hover-label-text-color: $warn-color, error-focus-label-text-color: $warn-color, error-label-text-color: $warn-color, error-caret-color: $warn-color, - active-indicator-color: rgba($on-surface, 0.42), - disabled-active-indicator-color: rgba($on-surface, 0.06), - hover-active-indicator-color: rgba($on-surface, 0.87), + active-indicator-color: sass-utils.safe-color-change($divider-base, $alpha: 0.42), + disabled-active-indicator-color: sass-utils.safe-color-change($divider-base, $alpha: 0.06), + hover-active-indicator-color: sass-utils.safe-color-change($divider-base, $alpha: 0.87), error-active-indicator-color: $warn-color, error-focus-active-indicator-color: $warn-color, error-hover-active-indicator-color: $warn-color, diff --git a/src/material/core/tokens/m2/mdc/_outlined-button.scss b/src/material/core/tokens/m2/mdc/_outlined-button.scss index 2795a94ac186..3629ebe76505 100644 --- a/src/material/core/tokens/m2/mdc/_outlined-button.scss +++ b/src/material/core/tokens/m2/mdc/_outlined-button.scss @@ -3,7 +3,6 @@ @use '../../../style/sass-utils'; @use '../../../theming/inspection'; @use '../../../theming/theming'; -@use '../../../mdc-helpers/mdc-helpers'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mdc, outlined-button); @@ -55,15 +54,20 @@ $prefix: (mdc, outlined-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $surface: inspection.get-theme-color($theme, background, card); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($surface, $is-dark); - $on-surface: if($contrast-tone == 'dark', #000, #fff); + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $outline: if(token-utils.$private-is-internal-build, + rgba(if($is-dark, #fff, #000), 0.12), + inspection.get-theme-color($theme, foreground, divider) + ); @return ( - disabled-outline-color: rgba($on-surface, 0.12), - disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), - label-text-color: if($is-dark, #fff, #000), - outline-color: rgba($on-surface, 0.12) + disabled-outline-color: $outline, + disabled-label-text-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), + label-text-color: inspection.get-theme-color($theme, foreground, text, 1), + outline-color: $outline, ); } diff --git a/src/material/core/tokens/m2/mdc/_outlined-text-field.scss b/src/material/core/tokens/m2/mdc/_outlined-text-field.scss index cc63f65f0c0c..e0b54b9d93e2 100644 --- a/src/material/core/tokens/m2/mdc/_outlined-text-field.scss +++ b/src/material/core/tokens/m2/mdc/_outlined-text-field.scss @@ -86,18 +86,29 @@ $prefix: (mdc, outlined-text-field); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); $warn-color: inspection.get-theme-color($theme, warn); $color-tokens: private-get-color-palette-color-tokens($theme, primary); + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + $on-surface: if($is-dark, #fff, #000); + $text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, text, 1)); + $disabled-text-color-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, disabled-text, 1)); + $divider-base: if(token-utils.$private-is-internal-build, $on-surface, + inspection.get-theme-color($theme, foreground, divider, 1)); + @return map.merge($color-tokens, ( - label-text-color: rgba($on-surface, 0.6), - hover-label-text-color: rgba($on-surface, 0.6), - disabled-label-text-color: rgba($on-surface, 0.38), + label-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), + hover-label-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), + disabled-label-text-color: + sass-utils.safe-color-change($disabled-text-color-base, $alpha: 0.38), - input-text-color: rgba($on-surface, 0.87), - disabled-input-text-color: rgba($on-surface, 0.38), - input-text-placeholder-color: rgba($on-surface, 0.6), + input-text-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.87), + disabled-input-text-color: + sass-utils.safe-color-change($disabled-text-color-base, $alpha: 0.38), + input-text-placeholder-color: sass-utils.safe-color-change($text-color-base, $alpha: 0.6), error-caret-color: $warn-color, error-focus-label-text-color: $warn-color, @@ -105,9 +116,9 @@ $prefix: (mdc, outlined-text-field); error-hover-label-text-color: $warn-color, // Outline tokens - outline-color: rgba($on-surface, 0.38), - disabled-outline-color: rgba($on-surface, 0.06), - hover-outline-color: rgba($on-surface, 0.87), + outline-color: sass-utils.safe-color-change($divider-base, $alpha: 0.38), + disabled-outline-color: sass-utils.safe-color-change($divider-base, $alpha: 0.06), + hover-outline-color: sass-utils.safe-color-change($divider-base, $alpha: 0.87), error-focus-outline-color: $warn-color, error-hover-outline-color: $warn-color, error-outline-color: $warn-color, diff --git a/src/material/core/tokens/m2/mdc/_protected-button.scss b/src/material/core/tokens/m2/mdc/_protected-button.scss index 9ce223d83776..c3b8eac6211e 100644 --- a/src/material/core/tokens/m2/mdc/_protected-button.scss +++ b/src/material/core/tokens/m2/mdc/_protected-button.scss @@ -45,13 +45,14 @@ $prefix: (mdc, protected-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); @return ( container-color: inspection.get-theme-color($theme, background, card), - label-text-color: $on-surface, - disabled-container-color: rgba($on-surface, 0.12), - disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), + label-text-color: inspection.get-theme-color($theme, foreground, text, 1), + disabled-container-color: inspection.get-theme-color($theme, foreground, disabled-button, + 0.12), + disabled-label-text-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), container-elevation: 2, disabled-container-elevation: 0, focus-container-elevation: 4, @@ -63,13 +64,23 @@ $prefix: (mdc, protected-button); // Generates the mapping for the properties that change based on the button palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $is-dark: inspection.get-theme-type($theme) == dark; $container-color: inspection.get-theme-color($theme, $palette-name, default); - $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $label-text-color: null; + + // Ideally we would derive all values directly from the theme, but it causes a lot of regressions + // internally. For now we fall back to the old hardcoded behavior only for internal apps. + @if (token-utils.$private-is-internal-build) { + $is-dark: inspection.get-theme-type($theme) == dark; + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $label-text-color: if($contrast-tone == 'dark', #000, #fff); + } + @else { + $label-text-color: inspection.get-theme-color($theme, $palette-name, default-contrast, 1); + } @return ( container-color: $container-color, - label-text-color: if($contrast-tone == 'dark', #000, #fff), + label-text-color: $label-text-color, ); } diff --git a/src/material/core/tokens/m2/mdc/_radio.scss b/src/material/core/tokens/m2/mdc/_radio.scss index d912bede9616..c241ab1728a3 100644 --- a/src/material/core/tokens/m2/mdc/_radio.scss +++ b/src/material/core/tokens/m2/mdc/_radio.scss @@ -45,15 +45,14 @@ $prefix: (mdc, radio); @function get-color-tokens($theme, $palette-name: accent) { $is-dark: inspection.get-theme-type($theme) == dark; $palette-color: inspection.get-theme-color($theme, $palette-name, default); - $on-surface: if($is-dark, #fff, #000); $icon-color: theming.get-color-from-palette(palette.$gray-palette, if($is-dark, 200, 900)); @return ( - disabled-selected-icon-color: $on-surface, - disabled-unselected-icon-color: $on-surface, + disabled-selected-icon-color: inspection.get-theme-color($theme, foreground, icon, 1), + disabled-unselected-icon-color: inspection.get-theme-color($theme, foreground, icon, 1), unselected-hover-icon-color: $icon-color, - unselected-icon-color: rgba($on-surface, 0.54), - unselected-pressed-icon-color: rgba($on-surface, 0.54), + unselected-icon-color: inspection.get-theme-color($theme, foreground, icon, 0.54), + unselected-pressed-icon-color: inspection.get-theme-color($theme, foreground, icon, 0.54), selected-focus-icon-color: $palette-color, selected-hover-icon-color: $palette-color, selected-icon-color: $palette-color, diff --git a/src/material/core/tokens/m2/mdc/_text-button.scss b/src/material/core/tokens/m2/mdc/_text-button.scss index 9f8cfc0cc088..b4dac9bc92a2 100644 --- a/src/material/core/tokens/m2/mdc/_text-button.scss +++ b/src/material/core/tokens/m2/mdc/_text-button.scss @@ -44,11 +44,11 @@ $prefix: (mdc, text-button); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $on-surface: if($is-dark, #fff, #000); @return ( - label-text-color: $on-surface, - disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), + label-text-color: inspection.get-theme-color($theme, foreground, text, 1), + disabled-label-text-color: inspection.get-theme-color($theme, foreground, disabled-button, + if($is-dark, 0.5, 0.38)), ); }