From 21ac74905d960ef6a3d133903125c57e67d2b14e Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 5 Oct 2021 21:16:24 +0200 Subject: [PATCH] feat(material-experimental/mdc-tabs): switch to new theming API Switches the MDC-based tabs to the new theming API. Note that while this uses the new mixins which clean up some of our overrides, it doesn't get us there completely in regards to the new API. Currently MDC's tabs mixins output the token values directly, rather than generating CSS variables for them. That being said, this still makes it easier to switch to CSS variables once they're available. These changes also introduce a new `structural-styles` mixin in `tabs-common` which centralizes the various structural styles we include from MDC. Previously they were scattered across multiple files. --- .../mdc-tabs/_tabs-common.scss | 27 +++--- .../mdc-tabs/_tabs-theme.scss | 96 ++++++++++++++----- .../mdc-tabs/tab-group.scss | 5 +- .../mdc-tabs/tab-header.scss | 3 - .../mdc-tabs/tab-nav-bar/tab-link.scss | 7 -- .../mdc-tabs/tab-nav-bar/tab-nav-bar.scss | 1 + 6 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/material-experimental/mdc-tabs/_tabs-common.scss b/src/material-experimental/mdc-tabs/_tabs-common.scss index cc228e8e3fc5..432aa2964b69 100644 --- a/src/material-experimental/mdc-tabs/_tabs-common.scss +++ b/src/material-experimental/mdc-tabs/_tabs-common.scss @@ -1,5 +1,6 @@ @use '@material/ripple' as mdc-ripple; @use '@material/tab' as mdc-tab; +@use '@material/tab-indicator' as mdc-tab-indicator; @use 'sass:map'; @use '../../material/core/style/vendor-prefixes'; @use '../../cdk/a11y'; @@ -7,6 +8,21 @@ $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-tab.without-ripple($query: mdc-helpers.$mat-base-styles-query); + @include mdc-tab-indicator.core-styles($query: mdc-helpers.$mat-base-styles-query); + + .mat-mdc-tab-ripple { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + pointer-events: none; + } +} + @mixin tab { &.mdc-tab { // This is usually included by MDC's tab bar, however we don't @@ -58,17 +74,6 @@ $mat-tab-animation-duration: 500ms !default; } } -@mixin tab-ripple { - .mat-mdc-tab-ripple { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - pointer-events: none; - } -} - // Structural styles for a tab header. Used by both `mat-tab-header` and `mat-tab-nav-bar`. // We need this styles on top of MDC's, because MDC doesn't support pagination like ours. @mixin paginated-tab-header { diff --git a/src/material-experimental/mdc-tabs/_tabs-theme.scss b/src/material-experimental/mdc-tabs/_tabs-theme.scss index 580ccbee371d..ccb1253521bb 100644 --- a/src/material-experimental/mdc-tabs/_tabs-theme.scss +++ b/src/material-experimental/mdc-tabs/_tabs-theme.scss @@ -1,7 +1,10 @@ +@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/tab-theme' as mdc-tab-theme; @use '@material/tab-bar' as mdc-tab-bar; @use '../mdc-helpers/mdc-helpers'; @use '../../material/core/typography/typography'; @@ -9,31 +12,59 @@ @mixin color($config-or-theme) { $config: theming.get-color-config($config-or-theme); - // Save original values of MDC global variables. We need to save these so we can restore the - // variables to their original values and prevent unintended side effects from using this mixin. - $orig-text-label-color-active: mdc-tab.$text-label-color-active; - $orig-icon-color-active: mdc-tab.$icon-color-active; - $orig-text-label-color-default: mdc-tab.$text-label-color-default; + $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)); @include mdc-helpers.mat-using-mdc-theme($config) { - // This value is the same as MDC's default, but MDC defines it once inside - // a variables file which means that we can't override it with our own palette. - mdc-tab.$text-label-color-default: - rgba(mdc-theme-color.prop-value(on-surface), mdc-tab.$text-label-opacity); + .mat-mdc-tab, .mat-mdc-tab-link { + $surface: mdc-theme-color.$surface; + $on-surface: rgba(mdc-theme-color.$on-surface, 0.6); + + // TODO(crisbeto): these styles should actually be set through the `theme` mixin while the + // `theme-styles` are included in the `tab` mixin inside `_tabs-common.scss`. Currently + // they are not, because `theme-styles` outputs the token values directly, rather than + // generating CSS variables. + @include mdc-tab-theme.theme-styles(map.merge(mdc-tab-theme.$light-theme, ( + container-color: $surface, + inactive-focus-state-layer-color: $on-surface, + inactive-hover-state-layer-color: $on-surface, + inactive-pressed-state-layer-color: $on-surface, + with-icon-inactive-focus-icon-color: $on-surface, + with-icon-inactive-hover-icon-color: $on-surface, + with-icon-inactive-icon-color: $on-surface, + with-icon-inactive-pressed-icon-color: $on-surface, + with-label-text-inactive-focus-label-text-color: $on-surface, + with-label-text-inactive-hover-label-text-color: $on-surface, + with-label-text-inactive-label-text-color: $on-surface, + with-label-text-inactive-pressed-label-text-color: $on-surface, + + // TODO(crisbeto): MDC's styles are set up so that the icon size is set through a + // `font-size` at the root of the tab while the text size of the tab is set on + // `.mdc-tab__text-label` which overrides the one from the root. The problem is that the + // `$light-theme` is looking for a `subhead2` level which doesn't exist in MDC's code which + // in turn causes no text label styles to be emitted and for the icon size to be applied to + // the entire tab. Since we don't support icons inside the tab anyway, we can temporarily + // work around it by preventing MDC from emitting icon styles. The correct label typography + // will be applied by our theme instead. + with-icon-icon-size: null + ))); + + // 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; + } - @include _palette-styles(mdc-tab.$text-label-color-active); + @include _palette-styles($primary); .mat-mdc-tab-group, .mat-mdc-tab-nav-bar { &.mat-accent { - mdc-tab.$text-label-color-active: secondary; - mdc-tab.$icon-color-active: secondary; - @include _palette-styles(mdc-tab.$text-label-color-active); + @include _palette-styles($accent); } &.mat-warn { - mdc-tab.$text-label-color-active: error; - mdc-tab.$icon-color-active: error; - @include _palette-styles(mdc-tab.$text-label-color-active); + @include _palette-styles($warn); } } @@ -55,11 +86,6 @@ @include mdc-theme.prop(border-color, on-surface); } } - - // Restore original values of MDC global variables. - mdc-tab.$text-label-color-active: $orig-text-label-color-active; - mdc-tab.$icon-color-active: $orig-icon-color-active; - mdc-tab.$text-label-color-default: $orig-text-label-color-default; } @mixin _background($background-color, $foreground-color) { @@ -73,7 +99,7 @@ > .mat-mdc-tab-header, > .mat-mdc-tab-link-container { // Set labels to contrast against background - .mdc-tab__text-label, .mat-mdc-tab-link { + .mat-mdc-tab .mdc-tab__text-label, .mat-mdc-tab-link .mdc-tab__text-label { @include mdc-theme.prop(color, $foreground-color); } @@ -96,9 +122,29 @@ } @mixin _palette-styles($color) { - @include mdc-tab.without-ripple($query: mdc-helpers.$mat-theme-styles-query); - @include mdc-tab-indicator.underline-color($color, $query: mdc-helpers.$mat-theme-styles-query); - @include mdc-tab-indicator.icon-color($color, $query: mdc-helpers.$mat-theme-styles-query); + .mat-mdc-tab, .mat-mdc-tab-link { + // TODO(crisbeto): these styles should actually be set through the `theme` mixin while the + // `theme-styles` are included in the `tab` mixin inside `_tabs-common.scss`. Currently + // they are not, because `theme-styles` outputs the token values directly, rather than + // generating CSS variables. + @include mdc-tab-theme.theme-styles(( + active-focus-state-layer-color: $color, + active-hover-state-layer-color: $color, + active-pressed-state-layer-color: $color, + with-icon-active-focus-icon-color: $color, + with-icon-active-hover-icon-color: $color, + with-icon-active-icon-color: $color, + with-icon-active-pressed-icon-color: $color, + with-label-text-active-focus-label-text-color: $color, + with-label-text-active-hover-label-text-color: $color, + with-label-text-active-label-text-color: $color, + with-label-text-active-pressed-label-text-color: $color, + )); + + @include mdc-tab-indicator-theme.theme-styles(( + active-indicator-color: $color + )); + } .mdc-tab__ripple::before, .mat-mdc-tab .mat-ripple-element, diff --git a/src/material-experimental/mdc-tabs/tab-group.scss b/src/material-experimental/mdc-tabs/tab-group.scss index fbe2785a0964..62c9691fc14e 100644 --- a/src/material-experimental/mdc-tabs/tab-group.scss +++ b/src/material-experimental/mdc-tabs/tab-group.scss @@ -1,11 +1,8 @@ -@use '@material/tab' as mdc-tab; @use '../../material/core/style/variables'; @use '../../material/core/style/private'; -@use '../mdc-helpers/mdc-helpers'; @use './tabs-common'; -@include mdc-tab.without-ripple($query: mdc-helpers.$mat-base-styles-query); -@include tabs-common.tab-ripple; +@include tabs-common.structural-styles; .mat-mdc-tab { @include tabs-common.tab; diff --git a/src/material-experimental/mdc-tabs/tab-header.scss b/src/material-experimental/mdc-tabs/tab-header.scss index cc6ac77cef7d..6e98db2fe11c 100644 --- a/src/material-experimental/mdc-tabs/tab-header.scss +++ b/src/material-experimental/mdc-tabs/tab-header.scss @@ -1,8 +1,5 @@ -@use '@material/tab-indicator' as mdc-tab-indicator; -@use '../mdc-helpers/mdc-helpers'; @use './tabs-common'; -@include mdc-tab-indicator.core-styles($query: mdc-helpers.$mat-base-styles-query); @include tabs-common.paginated-tab-header; .mat-mdc-tab-label-container { diff --git a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-link.scss b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-link.scss index 7c8b9f756a8c..cdd5ac83ac81 100644 --- a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-link.scss +++ b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-link.scss @@ -1,13 +1,6 @@ -@use '@material/tab' as mdc-tab; -@use '@material/tab-indicator' as mdc-tab-indicator; @use '../../../material/core/style/variables'; -@use '../../mdc-helpers/mdc-helpers'; @use '../tabs-common'; -@include mdc-tab.without-ripple($query: mdc-helpers.$mat-base-styles-query); -@include mdc-tab-indicator.core-styles($query: mdc-helpers.$mat-base-styles-query); -@include tabs-common.tab-ripple; - // Wraps each link in the header .mat-mdc-tab-link { @include tabs-common.tab; diff --git a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.scss b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.scss index 334886d45280..1d10da3c4bec 100644 --- a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.scss +++ b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.scss @@ -1,5 +1,6 @@ @use '../tabs-common'; +@include tabs-common.structural-styles; @include tabs-common.paginated-tab-header; .mat-mdc-tab-links {