diff --git a/src/material/core/tokens/_density.scss b/src/material/core/tokens/_density.scss index a3063ff10c91..7b3101c7665c 100644 --- a/src/material/core/tokens/_density.scss +++ b/src/material/core/tokens/_density.scss @@ -60,7 +60,7 @@ $_density-tokens: ( (mdc, slider): (), (mdc, snackbar): (), (mdc, switch): (), - (mdc, tab): ( + (mdc, secondary-navigation-tab): ( container-height: (48px, 44px, 40px, 36px, 32px) ), (mdc, tab-indicator): (), diff --git a/src/material/core/tokens/m2/_index.scss b/src/material/core/tokens/m2/_index.scss index 5fa75c0aae3b..ea6fadb54442 100644 --- a/src/material/core/tokens/m2/_index.scss +++ b/src/material/core/tokens/m2/_index.scss @@ -67,7 +67,7 @@ @use './mdc/slider' as tokens-mdc-slider; @use './mdc/snack-bar' as tokens-mdc-snack-bar; @use './mdc/switch' as tokens-mdc-switch; -@use './mdc/tab' as tokens-mdc-tab; +@use './mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-tab; @use './mdc/tab-indicator' as tokens-mdc-tab-indicator; @use '../../theming/inspection'; @@ -179,7 +179,7 @@ _get-tokens-for-module($theme, tokens-mdc-snack-bar), _get-tokens-for-module($theme, tokens-mdc-switch), _get-tokens-for-module($theme, tokens-mdc-tab-indicator), - _get-tokens-for-module($theme, tokens-mdc-tab), + _get-tokens-for-module($theme, tokens-mdc-secondary-navigation-tab), _get-tokens-for-module($theme, tokens-mdc-text-button) ); } diff --git a/src/material/core/tokens/m2/mdc/_tab.scss b/src/material/core/tokens/m2/mdc/_secondary-navigation-tab.scss similarity index 98% rename from src/material/core/tokens/m2/mdc/_tab.scss rename to src/material/core/tokens/m2/mdc/_secondary-navigation-tab.scss index e95c7e670280..df4b3711aa68 100644 --- a/src/material/core/tokens/m2/mdc/_tab.scss +++ b/src/material/core/tokens/m2/mdc/_secondary-navigation-tab.scss @@ -5,7 +5,7 @@ @use '../../token-utils'; // The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mdc, tab); +$prefix: (mdc, secondary-navigation-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. diff --git a/src/material/core/tokens/m3/_index.scss b/src/material/core/tokens/m3/_index.scss index 2845be333830..2fa5ff4691c9 100644 --- a/src/material/core/tokens/m3/_index.scss +++ b/src/material/core/tokens/m3/_index.scss @@ -65,7 +65,7 @@ @use './mdc/slider' as tokens-mdc-slider; @use './mdc/snack-bar' as tokens-mdc-snack-bar; @use './mdc/switch' as tokens-mdc-switch; -@use './mdc/tab' as tokens-mdc-tab; +@use './mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-tab; @use './mdc/tab-indicator' as tokens-mdc-tab-indicator; $_module-names: ( @@ -137,7 +137,7 @@ $_module-names: ( tokens-mdc-slider, tokens-mdc-snack-bar, tokens-mdc-switch, - tokens-mdc-tab, + tokens-mdc-secondary-navigation-tab, tokens-mdc-tab-indicator ); diff --git a/src/material/core/tokens/m3/mdc/_tab.scss b/src/material/core/tokens/m3/mdc/_secondary-navigation-tab.scss similarity index 93% rename from src/material/core/tokens/m3/mdc/_tab.scss rename to src/material/core/tokens/m3/mdc/_secondary-navigation-tab.scss index b6b0cda33bb8..3261ec9d207f 100644 --- a/src/material/core/tokens/m3/mdc/_tab.scss +++ b/src/material/core/tokens/m3/mdc/_secondary-navigation-tab.scss @@ -1,7 +1,7 @@ @use '../../token-utils'; // The prefix used to generate the fully qualified name for tokens in this file. -$prefix: (mdc, tab); +$prefix: (mdc, secondary-navigation-tab); /// Generates the tokens for MDC tab /// @param {Map} $systems The MDC system tokens diff --git a/src/material/core/tokens/tests/test-validate-tokens.scss b/src/material/core/tokens/tests/test-validate-tokens.scss index 46d1cd82e77e..38bb3e4bd6aa 100644 --- a/src/material/core/tokens/tests/test-validate-tokens.scss +++ b/src/material/core/tokens/tests/test-validate-tokens.scss @@ -18,7 +18,6 @@ @use '@material/radio/radio-theme' as mdc-radio-theme; @use '@material/switch/switch-theme' as mdc-switch-theme; @use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; -@use '@material/tab/tab-theme' as mdc-tab-theme; @use '@material/snackbar/snackbar-theme' as mdc-snackbar-theme; @use '@material/slider/slider-theme' as mdc-slider-theme; @use '@material/chips/chip-theme' as mdc-chips-theme; @@ -44,7 +43,6 @@ @use '../m2/mdc/radio' as tokens-mdc-radio; @use '../m2/mdc/switch' as tokens-mdc-switch; @use '../m2/mdc/tab-indicator' as tokens-mdc-tab-indicator; -@use '../m2/mdc/tab' as tokens-mdc-tab; @use '../m2/mdc/snack-bar' as tokens-mdc-snack-bar; @use '../m2/mdc/slider' as tokens-mdc-slider; @use '../m2/mdc/chip' as tokens-mdc-chip; @@ -119,11 +117,6 @@ $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 -); @include validate-slots( $component: 'm2.mdc.snackbar', $slots: tokens-mdc-snack-bar.get-token-slots(), diff --git a/src/material/tabs/_tabs-common.scss b/src/material/tabs/_tabs-common.scss index 0db2aba1998a..8b2bdc981911 100644 --- a/src/material/tabs/_tabs-common.scss +++ b/src/material/tabs/_tabs-common.scss @@ -1,29 +1,86 @@ -@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/mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-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'; $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-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.static-styles($query: mdc-helpers.$mdc-base-styles-query); + .mdc-tab { + min-width: 90px; + padding: 0 24px; + display: flex; + flex: 1 0 auto; + justify-content: center; + box-sizing: border-box; + border: none; + outline: none; + text-align: center; + white-space: nowrap; + cursor: pointer; + z-index: 1; + } + + .mdc-tab__content { + display: flex; + align-items: center; + justify-content: center; + height: inherit; + pointer-events: none; + } + + .mdc-tab__text-label { + transition: 150ms color linear; + display: inline-block; + line-height: 1; + z-index: 2; + } + + .mdc-tab--active .mdc-tab__text-label { + transition-delay: 100ms; + } + + ._mat-animation-noopable .mdc-tab__text-label { + transition: none; + } + + .mdc-tab-indicator { + display: flex; + position: absolute; + top: 0; + left: 0; + justify-content: center; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + } + + .mdc-tab-indicator__content { + transition: var(--mat-tab-animation-duration, 250ms) transform cubic-bezier(0.4, 0, 0.2, 1); + transform-origin: left; + opacity: 0; + } + + .mdc-tab-indicator__content--underline { + align-self: flex-end; + box-sizing: border-box; + width: 100%; + border-top-style: solid; + } + + .mdc-tab-indicator--active .mdc-tab-indicator__content { + opacity: 1; + } + + ._mat-animation-noopable, .mdc-tab-indicator--no-transition { + .mdc-tab-indicator__content { + transition: none; + } } .mat-mdc-tab-ripple { @@ -37,14 +94,6 @@ $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; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -53,6 +102,13 @@ $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( + tokens-mdc-secondary-navigation-tab.$prefix, + tokens-mdc-secondary-navigation-tab.get-token-slots() + ) { + @include token-utils.create-token-slot(height, container-height); + } + &.mdc-tab { // 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 @@ -60,6 +116,17 @@ $mat-tab-animation-duration: 500ms !default; flex-grow: 0; } + .mdc-tab-indicator__content--underline { + @include token-utils.use-tokens( + tokens-mdc-tab-indicator.$prefix, + tokens-mdc-tab-indicator.get-token-slots() + ) { + @include token-utils.create-token-slot(border-color, active-indicator-color); + @include token-utils.create-token-slot(border-top-width, active-indicator-height); + @include token-utils.create-token-slot(border-radius, active-indicator-shape); + } + } + @include token-utils.use-tokens( tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() @@ -185,18 +252,18 @@ $mat-tab-animation-duration: 500ms !default; // We need to handle the hover and focus indication ourselves, because we don't use MDC's ripple. &:hover .mdc-tab__ripple::before { - opacity: map.get(mdc-ripple.$dark-ink-opacities, hover); + opacity: 0.04; } &.cdk-program-focused, &.cdk-keyboard-focused { .mdc-tab__ripple::before { - opacity: map.get(mdc-ripple.$dark-ink-opacities, focus); + opacity: 0.12; } } .mat-ripple-element { - opacity: map.get(mdc-ripple.$dark-ink-opacities, press); + opacity: 0.12; @include token-utils.use-tokens( tokens-mat-tab-header.$prefix, @@ -243,7 +310,7 @@ $mat-tab-animation-duration: 500ms !default; } .mat-ripple-element { - opacity: map.get(mdc-ripple.$dark-ink-opacities, press); + opacity: 0.12; @include token-utils.use-tokens( tokens-mat-tab-header.$prefix, @@ -309,15 +376,6 @@ $mat-tab-animation-duration: 500ms !default; transition: none; } } - - // The `span` is in the selector in order to increase the specificity, ensuring - // that it's always higher than the selector that declares the transition. - ._mat-animation-noopable { - span.mdc-tab-indicator__content, - span.mdc-tab__text-label { - transition: none; - } - } } // Structural styles for the element that wraps the paginated header items. diff --git a/src/material/tabs/_tabs-theme.scss b/src/material/tabs/_tabs-theme.scss index 8c53e421ffb7..348139743a32 100644 --- a/src/material/tabs/_tabs-theme.scss +++ b/src/material/tabs/_tabs-theme.scss @@ -1,7 +1,5 @@ -@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; -@use '@material/tab/tab-theme' as mdc-tab-theme; @use '../core/style/sass-utils'; -@use '../core/tokens/m2/mdc/tab' as tokens-mdc-tab; +@use '../core/tokens/m2/mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-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; @@ -20,14 +18,16 @@ } @else { @include sass-utils.current-selector-or-root() { - @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()); + tokens-mdc-secondary-navigation-tab.$prefix, + tokens-mdc-secondary-navigation-tab.get-unthemable-tokens()); @include token-utils.create-token-values( - tokens-mat-tab-header-with-background.$prefix, - tokens-mat-tab-header-with-background.get-unthemable-tokens() - ); + tokens-mdc-tab-indicator.$prefix, tokens-mdc-tab-indicator.get-unthemable-tokens()); + @include token-utils.create-token-values( + tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-unthemable-tokens()); + @include token-utils.create-token-values( + tokens-mat-tab-header-with-background.$prefix, + tokens-mat-tab-header-with-background.get-unthemable-tokens()); } } } @@ -74,9 +74,12 @@ } @mixin _palette-styles($theme, $palette-name) { - @include mdc-tab-theme.secondary-navigation-tab-theme( - tokens-mdc-tab.get-color-tokens($theme, $palette-name)); - @include mdc-tab-indicator-theme.theme( + @include token-utils.create-token-values( + tokens-mdc-secondary-navigation-tab.$prefix, + tokens-mdc-secondary-navigation-tab.get-color-tokens($theme, $palette-name) + ); + @include token-utils.create-token-values( + tokens-mdc-tab-indicator.$prefix, tokens-mdc-tab-indicator.get-color-tokens($theme, $palette-name)); @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-color-tokens($theme, $palette-name)); @@ -90,10 +93,11 @@ } @else { .mat-mdc-tab-header { - @include mdc-tab-theme.secondary-navigation-tab-theme( - tokens-mdc-tab.get-typography-tokens($theme)); - @include mdc-tab-indicator-theme.theme( - tokens-mdc-tab-indicator.get-typography-tokens($theme)); + @include token-utils.create-token-values( + tokens-mdc-secondary-navigation-tab.$prefix, + tokens-mdc-secondary-navigation-tab.get-typography-tokens($theme)); + @include token-utils.create-token-values( + tokens-mdc-tab-indicator.$prefix, tokens-mdc-tab-indicator.get-typography-tokens($theme)); @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-typography-tokens($theme)); @include token-utils.create-token-values(tokens-mat-tab-header-with-background.$prefix, @@ -110,10 +114,11 @@ } @else { .mat-mdc-tab-header { - @include mdc-tab-theme.secondary-navigation-tab-theme( - tokens-mdc-tab.get-density-tokens($theme)); - @include mdc-tab-indicator-theme.theme( - tokens-mdc-tab-indicator.get-density-tokens($theme)); + @include token-utils.create-token-values( + tokens-mdc-secondary-navigation-tab.$prefix, + tokens-mdc-secondary-navigation-tab.get-density-tokens($theme)); + @include token-utils.create-token-values( + tokens-mdc-tab-indicator.$prefix, tokens-mdc-tab-indicator.get-density-tokens($theme)); @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-density-tokens($theme)); @include token-utils.create-token-values(tokens-mat-tab-header-with-background.$prefix, @@ -125,14 +130,14 @@ /// Outputs the CSS variable values for the given tokens. /// @param {Map} $tokens The token values to emit. @mixin overrides($tokens: ()) { - $tab-tokens: tokens-mdc-tab.get-token-slots(); + $tab-tokens: tokens-mdc-secondary-navigation-tab.get-token-slots(); $tab-indicator-tokens: tokens-mdc-tab-indicator.get-token-slots(); $tab-header-tokens: tokens-mat-tab-header.get-token-slots(); $tab-header-with-background-tokens: tokens-mat-tab-header-with-background.get-token-slots(); @include token-utils.batch-create-token-values( $tokens, - (prefix: tokens-mdc-tab.$prefix, tokens: $tab-tokens), + (prefix: tokens-mdc-secondary-navigation-tab.$prefix, tokens: $tab-tokens), (prefix: tokens-mdc-tab-indicator.$prefix, tokens: $tab-indicator-tokens), (prefix: tokens-mat-tab-header.$prefix, tokens: $tab-header-tokens), ( @@ -176,8 +181,11 @@ $tokens, tokens-mat-tab-header.$prefix, $options...); // Don't pass $options here, because the mdc-tab doesn't have color variants, // only the mdc-tab-indicator and mat-tab-header do. - $mdc-tab-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-tab.$prefix); - @include mdc-tab-theme.secondary-navigation-tab-theme($mdc-tab-tokens); - @include mdc-tab-indicator-theme.theme($mdc-tab-indicator-tokens); + $mdc-secondary-navigation-tab-tokens: + token-utils.get-tokens-for($tokens, tokens-mdc-secondary-navigation-tab.$prefix); + @include token-utils.create-token-values(tokens-mdc-secondary-navigation-tab.$prefix, + $mdc-secondary-navigation-tab-tokens); + @include token-utils.create-token-values(tokens-mdc-tab-indicator.$prefix, + $mdc-tab-indicator-tokens); @include token-utils.create-token-values(tokens-mat-tab-header.$prefix, $mat-tab-header-tokens); }