From 1dcffe692ce59e2cf9badcdee887213e17385077 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 5 Oct 2021 21:04:32 +0200 Subject: [PATCH] fix(material-experimental/mdc-radio): switch to new theming API Reworks the MDC-based radio button to use the new theming API based on CSS variables. Also fixes a minor issue where the high contrast styles were emitting slightly more CSS than they need to. --- .../mdc-radio/_radio-theme.scss | 54 ++++++++++++------- .../mdc-radio/radio.scss | 33 +++++++----- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/material-experimental/mdc-radio/_radio-theme.scss b/src/material-experimental/mdc-radio/_radio-theme.scss index a98acebf68a3..aa7b90288c6a 100644 --- a/src/material-experimental/mdc-radio/_radio-theme.scss +++ b/src/material-experimental/mdc-radio/_radio-theme.scss @@ -1,3 +1,4 @@ +@use 'sass:map'; @use '@material/theme/theme-color' as mdc-theme-color; @use '@material/radio/radio-theme' as mdc-radio-theme; @use '@material/radio/radio' as mdc-radio; @@ -6,42 +7,59 @@ @use '../../material/core/typography/typography'; @use '../../material/core/theming/theming'; +@mixin _color-palette($color-palette) { + @include mdc-radio-theme.theme(( + selected-focus-icon-color: $color-palette, + selected-focus-state-layer-color: $color-palette, + selected-hover-icon-color: $color-palette, + selected-hover-state-layer-color: $color-palette, + selected-icon-color: $color-palette, + selected-pressed-icon-color: $color-palette, + selected-pressed-state-layer-color: $color-palette, + )); + + // TODO(crisbeto): this should be included by MDC's `theme-styles`, but it isn't currently. + @include mdc-radio-theme.focus-indicator-color($color-palette); +} + @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-baseline-theme-color: mdc-radio-theme.$baseline-theme-color; - $orig-unchecked-color: mdc-radio-theme.$unchecked-color; - $orig-disabled-circle-color: mdc-radio-theme.$disabled-circle-color; + $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) { - mdc-radio-theme.$baseline-theme-color: primary; - mdc-radio-theme.$unchecked-color: rgba(mdc-theme-color.prop-value(on-surface), 0.54); - mdc-radio-theme.$disabled-circle-color: rgba(mdc-theme-color.prop-value(on-surface), 0.38); + $on-surface: rgba(mdc-theme-color.$on-surface, 0.54); .mat-mdc-radio-button { @include mdc-form-field.core-styles($query: mdc-helpers.$mat-theme-styles-query); + @include mdc-radio-theme.theme(( + // The disabled colors don't use the `rgba` version, because + // MDC applies a separate opacity to disabled buttons. + disabled-selected-icon-color: mdc-theme-color.$on-surface, + disabled-unselected-icon-color: mdc-theme-color.$on-surface, + unselected-focus-icon-color: $on-surface, + unselected-focus-state-layer-color: $on-surface, + unselected-hover-icon-color: $on-surface, + unselected-hover-state-layer-color: $on-surface, + unselected-icon-color: $on-surface, + unselected-pressed-icon-color: $on-surface, + unselected-pressed-state-layer-color: $on-surface, + )); &.mat-primary { - @include mdc-radio.without-ripple($query: mdc-helpers.$mat-theme-styles-query); + @include _color-palette($primary); } &.mat-accent { - mdc-radio-theme.$baseline-theme-color: secondary; - @include mdc-radio.without-ripple($query: mdc-helpers.$mat-theme-styles-query); + @include _color-palette($accent); } &.mat-warn { - mdc-radio-theme.$baseline-theme-color: error; - @include mdc-radio.without-ripple($query: mdc-helpers.$mat-theme-styles-query); + @include _color-palette($warn); } } } - - // Restore original values of MDC global variables. - mdc-radio-theme.$baseline-theme-color: $orig-baseline-theme-color; - mdc-radio-theme.$unchecked-color: $orig-unchecked-color; - mdc-radio-theme.$disabled-circle-color: $orig-disabled-circle-color; } @mixin typography($config-or-theme) { diff --git a/src/material-experimental/mdc-radio/radio.scss b/src/material-experimental/mdc-radio/radio.scss index e4a8c9bcc474..3be586f6050e 100644 --- a/src/material-experimental/mdc-radio/radio.scss +++ b/src/material-experimental/mdc-radio/radio.scss @@ -9,21 +9,28 @@ @include mdc-radio.without-ripple($query: mdc-helpers.$mat-base-styles-without-animation-query); @include mdc-form-field.core-styles($query: mdc-helpers.$mat-base-styles-query); -// This is necessary because we do not depend on MDC's ripple, but have our own that should be -// positioned correctly. This can be removed once we start using MDC's ripple implementation. -.mat-mdc-radio-button .mat-radio-ripple { - @include layout-common.fill; - - pointer-events: none; - border-radius: 50%; +.mat-mdc-radio-button { + &:not(._mat-animation-noopable) { + @include mdc-radio.without-ripple($query: animation); + } - .mat-ripple-element:not(.mat-radio-persistent-ripple) { - opacity: mdc-radio-theme.$ripple-opacity; + .mdc-radio { + // MDC theme styles also include structural styles so we have to include the theme at least + // once here. The values will be overwritten by our own theme file afterwards. + @include mdc-radio-theme.theme-styles(mdc-radio-theme.$light-theme); } -} -.mat-mdc-radio-button:not(._mat-animation-noopable) { - @include mdc-radio.without-ripple($query: animation); + // This is necessary because we do not depend on MDC's ripple, but have our own that should be + // positioned correctly. This can be removed once we start using MDC's ripple implementation. + .mat-radio-ripple { + @include layout-common.fill; + pointer-events: none; + border-radius: 50%; + + .mat-ripple-element:not(.mat-radio-persistent-ripple) { + opacity: mdc-radio-theme.$ripple-opacity; + } + } } // Element used to provide a larger tap target for users on touch devices. @@ -42,7 +49,7 @@ // Note that this creates a square box around the circle, however it's consistent with // how IE/Edge treat native radio buttons in high contrast mode. We can't turn the border // into a dotted one, because it's too thick which causes the circles to look off. -@include a11y.high-contrast { +@include a11y.high-contrast(active, 'off') { .mat-mdc-radio-button:not(.mat-radio-disabled) { &.cdk-keyboard-focused, &.cdk-program-focused {