diff --git a/src/material/core/tokens/m2/mat/_tab-header.scss b/src/material/core/tokens/m2/mat/_tab-header.scss index f923b5d06a00..4a54c6880cc1 100644 --- a/src/material/core/tokens/m2/mat/_tab-header.scss +++ b/src/material/core/tokens/m2/mat/_tab-header.scss @@ -17,15 +17,27 @@ $prefix: (mat, tab-header); $is-dark: map.get($config, is-dark); $foreground: map.get($config, foreground); $primary: map.get($config, primary); + $inactive-label-text-color: rgba(if($is-dark, #fff, #000), 0.6); + $active-label-text-color: theming.get-color-from-palette($primary, default); + $ripple-color: theming.get-color-from-palette($primary, default); @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), // Note: MDC has equivalents of these tokens, but they lead to much higher selector specificity. - inactive-label-text-color: rgba(if($is-dark, #fff, #000), 0.6), - active-label-text-color: theming.get-color-from-palette($primary, default), + inactive-label-text-color: $inactive-label-text-color, + active-label-text-color: $active-label-text-color, + + // Tokens needed to implement the gmat styles. Externally they don't change. + active-ripple-color: $ripple-color, + inactive-ripple-color: $ripple-color, + inactive-focus-label-text-color: $inactive-label-text-color, + inactive-hover-label-text-color: $inactive-label-text-color, + active-focus-label-text-color: $active-label-text-color, + active-hover-label-text-color: $active-label-text-color, + active-focus-indicator-color: $active-label-text-color, + active-hover-indicator-color: $active-label-text-color, ); } diff --git a/src/material/core/tokens/m2/mdc/_tab-indicator.scss b/src/material/core/tokens/m2/mdc/_tab-indicator.scss index 776e8002fc35..82adb1dbdf89 100644 --- a/src/material/core/tokens/m2/mdc/_tab-indicator.scss +++ b/src/material/core/tokens/m2/mdc/_tab-indicator.scss @@ -15,10 +15,8 @@ $prefix: (mdc, tab-indicator); @return ( active-indicator-height: 2px, - // ============================================================================================= - // = TOKENS NOT USED IN ANGULAR MATERIAL = - // ============================================================================================= - active-indicator-shape: null, + // Currently set to zero, but used by the gmat styles to make the indicator rounded. + active-indicator-shape: 0, ); } diff --git a/src/material/tabs/_tabs-common.scss b/src/material/tabs/_tabs-common.scss index 6449059edaf8..0356f795d388 100644 --- a/src/material/tabs/_tabs-common.scss +++ b/src/material/tabs/_tabs-common.scss @@ -46,8 +46,17 @@ $mat-tab-animation-duration: 500ms !default; } -webkit-tap-highlight-color: transparent; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; text-decoration: none; + &.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 + // we need the extra specificity to avoid issues with CSS insertion order. + flex-grow: 0; + } + @include token-utils.use-tokens( tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() @@ -57,21 +66,44 @@ $mat-tab-animation-duration: 500ms !default; @include token-utils.create-token-slot(letter-spacing, label-text-letter-spacing); @include token-utils.create-token-slot(line-height, label-text-line-height); @include token-utils.create-token-slot(font-weight, label-text-weight); - } - &.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 - // we need the extra specificity to avoid issues with CSS insertion order. - flex-grow: 0; + &:hover .mdc-tab__text-label { + @include token-utils.create-token-slot(color, inactive-hover-label-text-color); + } - &:not(.mat-mdc-tab-disabled).mdc-tab--active .mdc-tab__text-label { - @include token-utils.use-tokens( - tokens-mat-tab-header.$prefix, - tokens-mat-tab-header.get-token-slots() - ) { + &:focus .mdc-tab__text-label { + @include token-utils.create-token-slot(color, inactive-focus-label-text-color); + } + + &.mdc-tab--active { + .mdc-tab__text-label { @include token-utils.create-token-slot(color, active-label-text-color); } + + .mdc-tab__ripple::before, + .mat-ripple-element { + @include token-utils.create-token-slot(background-color, active-ripple-color); + } + + &:hover { + .mdc-tab__text-label { + @include token-utils.create-token-slot(color, active-hover-label-text-color); + } + + .mdc-tab-indicator__content--underline { + @include token-utils.create-token-slot(border-color, active-hover-indicator-color); + } + } + + &:focus { + .mdc-tab__text-label { + @include token-utils.create-token-slot(color, active-focus-label-text-color); + } + + .mdc-tab-indicator__content--underline { + @include token-utils.create-token-slot(border-color, active-focus-indicator-color); + } + } } } @@ -79,6 +111,14 @@ $mat-tab-animation-duration: 500ms !default; // MDC doesn't support disabled tabs so we need to improvise. opacity: 0.4; + // We use `pointer-events` to make the element unclickable when it's disabled, rather than + // preventing the default action through JS, because we can't prevent the action reliably + // due to other directives potentially registering their events earlier. This shouldn't cause + // the user to click through, because we always have a header behind the tab. Furthermore, this + // saves us some CSS, because we don't have to add `:not(.mat-mdc-tab-disabled)` to all the + // hover and focus selectors. + pointer-events: none; + @include token-utils.use-tokens( tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() @@ -107,7 +147,7 @@ $mat-tab-animation-duration: 500ms !default; tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() ) { - @include token-utils.create-token-slot(background-color, ripple-color); + @include token-utils.create-token-slot(background-color, inactive-ripple-color); } } @@ -154,7 +194,7 @@ $mat-tab-animation-duration: 500ms !default; tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() ) { - @include token-utils.create-token-slot(background-color, ripple-color); + @include token-utils.create-token-slot(background-color, inactive-ripple-color); } } } @@ -202,7 +242,7 @@ $mat-tab-animation-duration: 500ms !default; tokens-mat-tab-header.$prefix, tokens-mat-tab-header.get-token-slots() ) { - @include token-utils.create-token-slot(background-color, ripple-color); + @include token-utils.create-token-slot(background-color, inactive-ripple-color); } } diff --git a/src/material/tabs/tab-nav-bar/tab-link.scss b/src/material/tabs/tab-nav-bar/tab-link.scss index 88ea285d10f4..0fcae6c69f2a 100644 --- a/src/material/tabs/tab-nav-bar/tab-link.scss +++ b/src/material/tabs/tab-nav-bar/tab-link.scss @@ -5,14 +5,6 @@ .mat-mdc-tab-link { @include tabs-common.tab; - &.mat-mdc-tab-disabled { - // We use `pointer-events` to make the element unclickable when it's disabled, rather than - // preventing the default action through JS, because we can't prevent the action reliably - // 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; - } - // Note that we only want to target direct descendant tabs. .mat-mdc-tab-header.mat-mdc-tab-nav-bar-stretch-tabs & { flex-grow: 1;