From 2ed92f4edf2e6fc4d40be3587fdc1ba2b9b806f7 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 4 Apr 2023 14:40:47 +0200 Subject: [PATCH] refactor(material/tabs): switch to tokens API Switches the tabs to use the new tokens API. --- .../m2/mat/_tab-header-with-background.scss | 43 +++++ .../core/tokens/m2/mat/_tab-header.scss | 46 ++++++ .../core/tokens/m2/mdc/_tab-indicator.scss | 53 ++++++ src/material/core/tokens/m2/mdc/_tab.scss | 93 +++++++++++ .../tokens/tests/test-validate-tokens.scss | 14 ++ src/material/tabs/_tabs-common.scss | 154 ++++++++++++++---- src/material/tabs/_tabs-theme.scss | 121 ++++++-------- src/material/tabs/tab-group.scss | 7 +- src/material/tabs/tab-nav-bar/tab-link.scss | 3 - .../tabs/tab-nav-bar/tab-nav-bar.scss | 3 +- 10 files changed, 425 insertions(+), 112 deletions(-) create mode 100644 src/material/core/tokens/m2/mat/_tab-header-with-background.scss create mode 100644 src/material/core/tokens/m2/mat/_tab-header.scss create mode 100644 src/material/core/tokens/m2/mdc/_tab-indicator.scss create mode 100644 src/material/core/tokens/m2/mdc/_tab.scss diff --git a/src/material/core/tokens/m2/mat/_tab-header-with-background.scss b/src/material/core/tokens/m2/mat/_tab-header-with-background.scss new file mode 100644 index 000000000000..96db92e5cb76 --- /dev/null +++ b/src/material/core/tokens/m2/mat/_tab-header-with-background.scss @@ -0,0 +1,43 @@ +@use 'sass:map'; +@use '../../token-utils'; +@use '../../../theming/theming'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, tab-header-with-background); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($config) { + $primary: map.get($config, primary); + + @return ( + background-color: theming.get-color-from-palette($primary, default), + foreground-color: theming.get-color-from-palette($primary, default-contrast), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($config) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($config) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return token-utils.merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_tab-header.scss b/src/material/core/tokens/m2/mat/_tab-header.scss new file mode 100644 index 000000000000..5ebf672c7bc5 --- /dev/null +++ b/src/material/core/tokens/m2/mat/_tab-header.scss @@ -0,0 +1,46 @@ +@use 'sass:map'; +@use '../../token-utils'; +@use '../../../theming/theming'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, tab-header); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($config) { + $is-dark: map.get($config, is-dark); + $foreground: map.get($config, foreground); + $primary: map.get($config, primary); + + @return ( + ripple-color: theming.get-color-from-palette($primary, default), + disabled-ripple-color: theming.get-color-from-palette($foreground, disabled), + pagination-icon-color: if($is-dark, #fff, #000), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($config) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($config) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return token-utils.merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mdc/_tab-indicator.scss b/src/material/core/tokens/m2/mdc/_tab-indicator.scss new file mode 100644 index 000000000000..776e8002fc35 --- /dev/null +++ b/src/material/core/tokens/m2/mdc/_tab-indicator.scss @@ -0,0 +1,53 @@ +@use 'sass:map'; +@use '../../../theming/theming'; +@use '../../token-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mdc, tab-indicator); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +// +// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`. +// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in +// our CSS. +@function get-unthemable-tokens() { + @return ( + active-indicator-height: 2px, + + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= + active-indicator-shape: null, + ); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($config) { + $primary: map.get($config, primary); + + @return ( + active-indicator-color: theming.get-color-from-palette($primary, default), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($config) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($config) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return token-utils.merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mdc/_tab.scss b/src/material/core/tokens/m2/mdc/_tab.scss new file mode 100644 index 000000000000..468142acfe35 --- /dev/null +++ b/src/material/core/tokens/m2/mdc/_tab.scss @@ -0,0 +1,93 @@ +@use 'sass:map'; +@use '../../../theming/theming'; +@use '../../token-utils'; +@use '../../../typography/typography-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mdc, tab); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +// +// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`. +// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in +// our CSS. +@function get-unthemable-tokens() { + @return ( + // This is specified both here and in the density tokens, because it determines the size of the + // tab itself and there are internal tests who don't configure the theme correctly. + container-height: 48px, + + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= + container-color: null, + container-elevation: null, + container-shadow-color: null, + container-shape: null, + focus-label-text-color: null, + focus-state-layer-color: null, + focus-state-layer-opacity: null, + hover-label-text-color: null, + hover-state-layer-color: null, + hover-state-layer-opacity: null, + pressed-label-text-color: null, + pressed-state-layer-color: null, + pressed-state-layer-opacity: null, + with-icon-active-icon-color: null, + with-icon-focus-icon-color: null, + with-icon-hover-icon-color: null, + with-icon-inactive-icon-color: null, + with-icon-pressed-icon-color: null, + with-icon-icon-size: null, + ); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($config) { + $is-dark: map.get($config, is-dark); + $primary: map.get($config, primary); + + @return ( + inactive-label-text-color: rgba(if($is-dark, #fff, #000), 0.6), + active-label-text-color: theming.get-color-from-palette($primary, default), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($config) { + @return ( + label-text-font: + typography-utils.font-family($config, button) or typography-utils.font-family($config), + label-text-size: typography-utils.font-size($config, button), + label-text-letter-spacing: typography-utils.letter-spacing($config, button), + label-text-line-height: typography-utils.line-height($config, button), + label-text-weight: typography-utils.font-weight($config, button), + ); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($config) { + $scale: theming.clamp-density($config, -4); + + @return ( + container-height: map.get(( + 0: 48px, + -1: 44px, + -2: 40px, + -3: 36px, + -4: 32px, + ), $scale), + ); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return token-utils.merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/tests/test-validate-tokens.scss b/src/material/core/tokens/tests/test-validate-tokens.scss index 9f3a57b02558..94524e051ef0 100644 --- a/src/material/core/tokens/tests/test-validate-tokens.scss +++ b/src/material/core/tokens/tests/test-validate-tokens.scss @@ -9,6 +9,8 @@ @use '@material/linear-progress/linear-progress-theme' as mdc-linear-progress-theme; @use '@material/list/list-theme' as mdc-list-theme; @use '@material/radio/radio-theme' as mdc-radio-theme; +@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; +@use '@material/tab/tab-theme' as mdc-tab-theme; @use '@material/theme/validate' as mdc-validate; @use '../m2/mdc/circular-progress' as tokens-mdc-circular-progress; @@ -19,6 +21,8 @@ @use '../m2/mdc/list' as tokens-mdc-list; @use '../m2/mdc/outlined-card' as tokens-mdc-outlined-card; @use '../m2/mdc/radio' as tokens-mdc-radio; +@use '../m2/mdc/tab-indicator' as tokens-mdc-tab-indicator; +@use '../m2/mdc/tab' as tokens-mdc-tab; @mixin validate-slots($component, $slots, $reference) { @debug 'Validating #{$component}...'; @@ -72,3 +76,13 @@ $slots: tokens-mdc-radio.get-token-slots(), $reference: mdc-radio-theme.$light-theme ); +@include validate-slots( + $component: 'm2.mdc.tab-indicator', + $slots: tokens-mdc-tab-indicator.get-token-slots(), + $reference: mdc-tab-indicator-theme.$light-theme +); +@include validate-slots( + $component: 'm2.mdc.tab', + $slots: tokens-mdc-tab.get-token-slots(), + $reference: mdc-tab-theme.$secondary-light-theme +); diff --git a/src/material/tabs/_tabs-common.scss b/src/material/tabs/_tabs-common.scss index 9d7d98f803d4..fd1f6dbc109e 100644 --- a/src/material/tabs/_tabs-common.scss +++ b/src/material/tabs/_tabs-common.scss @@ -1,8 +1,16 @@ -@use '../core/mdc-helpers/mdc-helpers'; -@use '../core/style/vendor-prefixes'; @use '@material/ripple' as mdc-ripple; @use '@material/tab' as mdc-tab; @use '@material/tab-indicator' as mdc-tab-indicator; +@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; +@use '@material/tab/tab-theme' as mdc-tab-theme; +@use '@material/theme/custom-properties' as mdc-custom-properties; +@use '../core/mdc-helpers/mdc-helpers'; +@use '../core/style/vendor-prefixes'; +@use '../core/tokens/m2/mdc/tab-indicator' as tokens-mdc-tab-indicator; +@use '../core/tokens/m2/mdc/tab' as tokens-mdc-tab; +@use '../core/tokens/m2/mat/tab-header' as tokens-mat-tab-header; +@use '../core/tokens/m2/mat/tab-header-with-background' as tokens-mat-tab-header-with-background; +@use '../core/tokens/token-utils'; @use 'sass:map'; @@ -10,9 +18,12 @@ $mat-tab-animation-duration: 500ms !default; // Combines the various structural styles we need for the tab group and tab nav bar. @mixin structural-styles { - @include mdc-helpers.disable-mdc-fallback-declarations { + @include mdc-custom-properties.configure( + $emit-fallback-values: false, + $emit-fallback-vars: false + ) { @include mdc-tab.static-styles($query: mdc-helpers.$mdc-base-styles-query); - @include mdc-tab-indicator.core-styles($query: mdc-helpers.$mdc-base-styles-query); + @include mdc-tab-indicator.static-styles($query: mdc-helpers.$mdc-base-styles-query); } .mat-mdc-tab-ripple { @@ -26,19 +37,38 @@ $mat-tab-animation-duration: 500ms !default; } @mixin tab { + @include mdc-custom-properties.configure( + $emit-fallback-values: false, + $emit-fallback-vars: false + ) { + @include mdc-tab-indicator-theme.theme-styles(tokens-mdc-tab-indicator.get-token-slots()); + @include mdc-tab-theme.secondary-navigation-tab-theme-styles(tokens-mdc-tab.get-token-slots()); + } + -webkit-tap-highlight-color: transparent; &.mdc-tab { - // This is usually included by MDC's tab bar, however we don't - // use it because we implement our own pagination. - @include mdc-tab.height(mdc-tab.$height, mdc-helpers.$mdc-base-styles-query); - // MDC's tabs stretch to fit the header by default, whereas stretching on our current ones // is an opt-in behavior. Also technically we don't need to combine the two classes, but // we need the extra specificity to avoid issues with CSS insertion order. flex-grow: 0; } + &.mat-mdc-tab-disabled { + // MDC doesn't support disabled tabs so we need to improvise. + opacity: 0.4; + + @include token-utils.use-tokens( + tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-token-slots() + ) { + .mdc-tab__ripple::before, + .mat-ripple-element { + @include token-utils.create-token-slot(background-color, disabled-ripple-color); + } + } + } + // Used to render out the background tint when hovered/focused. Usually this is done by // MDC's ripple styles, however we're using our own ripples due to size concerns. .mdc-tab__ripple::before { @@ -51,6 +81,13 @@ $mat-tab-animation-duration: 500ms !default; bottom: 0; opacity: 0; pointer-events: none; + + @include token-utils.use-tokens( + tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-token-slots() + ) { + @include token-utils.create-token-slot(background-color, ripple-color); + } } // We support projecting icons into the tab. These styles ensure that they're centered. @@ -63,7 +100,7 @@ $mat-tab-animation-duration: 500ms !default; // Required for `fitInkBarToContent` to work. This used to be included with MDC's // `without-ripple` mixin, but that no longer appears to be the case with `static-styles`. // Since the latter is ~10kb smaller, we include this one extra style ourselves. - @include mdc-tab-indicator.surface; + position: relative; // MDC sets `pointer-events: none` on the content which prevents interactions with the // nested content. Re-enable it since we allow nesting any content in the tab (see #26195). @@ -84,6 +121,13 @@ $mat-tab-animation-duration: 500ms !default; .mat-ripple-element { opacity: map.get(mdc-ripple.$dark-ink-opacities, press); + + @include token-utils.use-tokens( + tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-token-slots() + ) { + @include token-utils.create-token-slot(background-color, ripple-color); + } } } @@ -95,6 +139,11 @@ $mat-tab-animation-duration: 500ms !default; overflow: hidden; position: relative; flex-shrink: 0; + + @include mdc-tab-indicator-theme.theme(tokens-mdc-tab-indicator.get-unthemable-tokens()); + @include mdc-tab-theme.secondary-navigation-tab-theme(tokens-mdc-tab.get-unthemable-tokens()); + @include token-utils.create-token-values( + tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-unthemable-tokens()); } .mat-mdc-tab-header-pagination { @@ -120,6 +169,13 @@ $mat-tab-animation-duration: 500ms !default; .mat-ripple-element { opacity: map.get(mdc-ripple.$dark-ink-opacities, press); + + @include token-utils.use-tokens( + tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-token-slots() + ) { + @include token-utils.create-token-slot(background-color, ripple-color); + } } .mat-mdc-tab-header-pagination-controls-enabled & { @@ -150,6 +206,13 @@ $mat-tab-animation-duration: 500ms !default; border-width: 2px 2px 0 0; height: 8px; width: 8px; + + @include token-utils.use-tokens( + tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-token-slots() + ) { + @include token-utils.create-token-slot(border-color, pagination-icon-color); + } } .mat-mdc-tab-header-pagination-disabled { @@ -207,35 +270,64 @@ $mat-tab-animation-duration: 500ms !default; z-index: 1; } -@mixin paginated-tab-header-with-background($header-selector) { +@mixin paginated-tab-header-with-background($header-selector, $tab-selector) { &.mat-tabs-with-background { - // 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 { - // Set background color for the tab group - background-color: var(--mat-mdc-tab-header-with-background-background-color, transparent); - } - - > #{$header-selector} { - // Set labels to contrast against background - .mat-mdc-tab .mdc-tab__text-label, .mat-mdc-tab-link .mdc-tab__text-label { - color: var(--mat-mdc-tab-header-with-background-foreground-color, inherit); + @include token-utils.create-token-values( + tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-unthemable-tokens() + ); + + @include token-utils.use-tokens( + tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-token-slots() + ) { + // 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 { + // Set background color for the tab group + @include token-utils.create-token-slot(background-color, background-color); } - .mdc-tab-indicator__content--underline, - .mat-mdc-tab-header-pagination-chevron, - .mat-mdc-focus-indicator::before { - border-color: var(--mat-mdc-tab-header-with-background-foreground-color, inherit); + // Note: this is only scoped to primary, because the legacy tabs had the incorrect behavior + // where setting both a background and `mat-accent` would add the background, but keep + // accent on the selected tab. There are some internal apps whose design depends on this now + // so we have to replicate it here. + &.mat-primary > #{$header-selector} { + // Set labels to contrast against background + #{$tab-selector} .mdc-tab__text-label { + @include token-utils.create-token-slot(color, foreground-color); + } + + .mdc-tab-indicator__content--underline { + @include token-utils.create-token-slot(border-color, foreground-color); + } } - } - > #{$header-selector}, > .mat-mdc-tab-header-pagination { - .mat-ripple-element, .mdc-tab__ripple::before { - background-color: var(--mat-mdc-tab-header-with-background-foreground-color, inherit); + &:not(.mat-primary) > #{$header-selector} { + #{$tab-selector}:not(.mdc-tab--active) { + .mdc-tab__text-label { + @include token-utils.create-token-slot(color, foreground-color); + } + + .mdc-tab-indicator__content--underline { + @include token-utils.create-token-slot(border-color, foreground-color); + } + } } - .mat-mdc-tab-header-pagination-chevron { - border-color: var(--mat-mdc-tab-header-with-background-foreground-color, inherit); + > #{$header-selector}, > .mat-mdc-tab-header-pagination { + .mat-mdc-tab-header-pagination-chevron, + .mat-mdc-focus-indicator::before { + @include token-utils.create-token-slot(border-color, foreground-color); + } + + .mat-ripple-element, .mdc-tab__ripple::before { + @include token-utils.create-token-slot(background-color, foreground-color); + } + + .mat-mdc-tab-header-pagination-chevron { + @include token-utils.create-token-slot(color, foreground-color); + } } } } diff --git a/src/material/tabs/_tabs-theme.scss b/src/material/tabs/_tabs-theme.scss index 5b943801c87b..203be33801ec 100644 --- a/src/material/tabs/_tabs-theme.scss +++ b/src/material/tabs/_tabs-theme.scss @@ -1,108 +1,87 @@ @use 'sass:map'; -@use '@material/theme/theme-color' as mdc-theme-color; -@use '@material/theme/theme' as mdc-theme; -@use '@material/tab-indicator' as mdc-tab-indicator; @use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; @use '@material/tab' as mdc-tab; -@use '@material/tab/mixins' as mdc-tab-mixins; -@use '@material/tab-bar' as mdc-tab-bar; +@use '@material/tab/tab-theme' as mdc-tab-theme; +@use '../core/tokens/m2/mdc/tab' as tokens-mdc-tab; +@use '../core/tokens/m2/mdc/tab-indicator' as tokens-mdc-tab-indicator; +@use '../core/tokens/m2/mat/tab-header' as tokens-mat-tab-header; +@use '../core/tokens/m2/mat/tab-header-with-background' as tokens-mat-tab-header-with-background; @use '../core/theming/theming'; @use '../core/typography/typography'; -@use '../core/mdc-helpers/mdc-helpers'; +@use '../core/tokens/token-utils'; @mixin color($config-or-theme) { $config: theming.get-color-config($config-or-theme); - $primary: theming.get-color-from-palette(map.get($config, primary)); - $accent: theming.get-color-from-palette(map.get($config, accent)); - $warn: theming.get-color-from-palette(map.get($config, warn)); - $foreground: map.get($config, foreground); - - @include mdc-helpers.using-mdc-theme($config) { - .mat-mdc-tab, .mat-mdc-tab-link { - @include mdc-tab-mixins.text-label-color(rgba(mdc-theme-color.$on-surface, 0.6)); - - // MDC seems to include a background color on tabs which only stands out on dark themes. - // Disable for now for backwards compatibility. These styles are inside the theme in order - // to avoid CSS specificity issues. - background-color: transparent; - - &.mat-mdc-tab-disabled { - .mdc-tab__ripple::before, - .mat-ripple-element { - background-color: theming.get-color-from-palette($foreground, disabled); - } - } - } - - @include _palette-styles($primary); - .mat-mdc-tab-group, .mat-mdc-tab-nav-bar { - &.mat-accent { - @include _palette-styles($accent); - } + .mat-mdc-tab-group, .mat-mdc-tab-nav-bar { + @include _palette-styles($config, primary); - &.mat-warn { - @include _palette-styles($warn); - } + &.mat-accent { + @include _palette-styles($config, accent); } - .mat-mdc-tab-group, .mat-mdc-tab-nav-bar { - &.mat-background-primary { - @include _background(primary, on-primary); - } + &.mat-warn { + @include _palette-styles($config, warn); + } - &.mat-background-accent { - @include _background(secondary, on-secondary); - } + &.mat-background-primary { + @include _background-styles($config, primary); + } - &.mat-background-warn { - @include _background(error, on-error); - } + &.mat-background-accent { + @include _background-styles($config, accent); } - .mat-mdc-tab-header-pagination-chevron { - @include mdc-theme.prop(border-color, on-surface); + &.mat-background-warn { + @include _background-styles($config, warn); } } } -@mixin _background($background-color, $foreground-color) { - $background-value: mdc-theme-color.prop-value($background-color); - $foreground-value: mdc-theme-color.prop-value($foreground-color); - --mat-mdc-tab-header-with-background-background-color: #{$background-value}; - --mat-mdc-tab-header-with-background-foreground-color: #{$foreground-value}; +@mixin _background-styles($initial-config, $palette) { + $config: map.merge($initial-config, (primary: map.get($initial-config, $palette))); + @include token-utils.create-token-values(tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-color-tokens($config)); } -@mixin _palette-styles($color) { - .mat-mdc-tab, .mat-mdc-tab-link { - &:not(.mat-mdc-tab-disabled) { - @include mdc-tab-mixins.active-text-label-color($color); - @include mdc-tab-indicator-theme.theme-styles((active-indicator-color: $color)); - } - } - - .mdc-tab__ripple::before, - .mat-mdc-tab .mat-ripple-element, - .mat-mdc-tab-header-pagination .mat-ripple-element, - .mat-mdc-tab-link .mat-ripple-element { - @include mdc-theme.prop(background-color, $color); - } +@mixin _palette-styles($initial-config, $palette) { + $config: map.merge($initial-config, (primary: map.get($initial-config, $palette))); + @include mdc-tab-theme.secondary-navigation-tab-theme( + tokens-mdc-tab.get-color-tokens($config)); + @include mdc-tab-indicator-theme.theme( + tokens-mdc-tab-indicator.get-color-tokens($config)); + @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-color-tokens($config)); } @mixin typography($config-or-theme) { $config: typography.private-typography-to-2018-config( theming.get-typography-config($config-or-theme)); - @include mdc-helpers.using-mdc-typography($config) { - @include mdc-tab.without-ripple($query: mdc-helpers.$mdc-typography-styles-query); - @include mdc-tab-indicator.core-styles($query: mdc-helpers.$mdc-typography-styles-query); + + .mat-mdc-tab-header { + @include mdc-tab-theme.secondary-navigation-tab-theme( + tokens-mdc-tab.get-typography-tokens($config)); + @include mdc-tab-indicator-theme.theme( + tokens-mdc-tab-indicator.get-typography-tokens($config)); + @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-typography-tokens($config)); + @include token-utils.create-token-values(tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-typography-tokens($config)); } } @mixin density($config-or-theme) { $density-scale: theming.get-density-config($config-or-theme); .mat-mdc-tab-header { - @include mdc-tab-bar.density($density-scale, $query: mdc-helpers.$mdc-base-styles-query); + @include mdc-tab-theme.secondary-navigation-tab-theme( + tokens-mdc-tab.get-density-tokens($density-scale)); + @include mdc-tab-indicator-theme.theme( + tokens-mdc-tab-indicator.get-density-tokens($density-scale)); + @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, + tokens-mat-tab-header.get-density-tokens($density-scale)); + @include token-utils.create-token-values(tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-density-tokens($density-scale)); } } diff --git a/src/material/tabs/tab-group.scss b/src/material/tabs/tab-group.scss index fe9667800a7e..4b03eee5b8c5 100644 --- a/src/material/tabs/tab-group.scss +++ b/src/material/tabs/tab-group.scss @@ -13,13 +13,8 @@ } } -// MDC doesn't support disabled tabs so we need to improvise. -.mat-mdc-tab-disabled { - opacity: 0.4; -} - .mat-mdc-tab-group { - @include tabs-common.paginated-tab-header-with-background('.mat-mdc-tab-header'); + @include tabs-common.paginated-tab-header-with-background('.mat-mdc-tab-header', '.mat-mdc-tab'); display: flex; flex-direction: column; diff --git a/src/material/tabs/tab-nav-bar/tab-link.scss b/src/material/tabs/tab-nav-bar/tab-link.scss index 55951ad0537f..88ea285d10f4 100644 --- a/src/material/tabs/tab-nav-bar/tab-link.scss +++ b/src/material/tabs/tab-nav-bar/tab-link.scss @@ -11,9 +11,6 @@ // due to other directives potentially registering their events earlier. This shouldn't cause // the user to click through, because we always have a `.mat-tab-links` behind the link. pointer-events: none; - - // MDC doesn't support disabled tabs so we need to improvise. - opacity: 0.4; } // Note that we only want to target direct descendant tabs. diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.scss b/src/material/tabs/tab-nav-bar/tab-nav-bar.scss index dcd50e769737..5d3addf4a09e 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.scss +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.scss @@ -12,5 +12,6 @@ } .mat-mdc-tab-nav-bar { - @include tabs-common.paginated-tab-header-with-background('.mat-mdc-tab-link-container'); + @include tabs-common.paginated-tab-header-with-background('.mat-mdc-tab-link-container', + '.mat-mdc-tab-link'); }