Skip to content

Commit

Permalink
fix(material-experimental/mdc-checkbox): switch to non-deprecated sty…
Browse files Browse the repository at this point in the history
…les (#23218)

Switches the MDC-based checkbox to the non-deprecated styles.

(cherry picked from commit a5fb8f8)
  • Loading branch information
crisbeto authored and wagnermaciel committed Jan 7, 2022
1 parent 34e4d20 commit ae9f3d5
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 52 deletions.
62 changes: 32 additions & 30 deletions src/material-experimental/mdc-checkbox/_checkbox-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@use '@material/theme/theme-color' as mdc-theme-color;
@use '@material/theme/theme';
@use 'sass:map';
@use 'sass:color';
@use '../mdc-helpers/mdc-helpers';
@use '../../material/core/typography/typography';
@use '../../material/core/theming/theming';
Expand All @@ -12,15 +13,34 @@

// Mixin that includes the checkbox theme styles with a given palette.
// By default, the MDC checkbox always uses the `secondary` palette.
@mixin private-checkbox-styles-with-color($color) {
@include mdc-checkbox-theme.theme-deprecated(
(
checkmark-color: mdc-theme-color.prop-value(on-#{$color}),
container-checked-color: $color,
container-disabled-color: rgba(mdc-theme-color.prop-value(on-surface), 0.38),
outline-color: rgba(mdc-theme-color.prop-value(on-surface), 0.54),
)
);
@mixin private-checkbox-styles-with-color($color, $mdcColor) {
$on-surface: mdc-theme-color.prop-value(on-surface);
$border-color: rgba($on-surface, color.opacity(mdc-checkbox-theme.$border-color));
$disabled-color: rgba($on-surface, color.opacity(mdc-checkbox-theme.$disabled-color));

@include mdc-checkbox-theme.theme((
selected-checkmark-color: mdc-theme-color.prop-value(on-#{$mdcColor}),

selected-focus-icon-color: $color,
selected-hover-icon-color: $color,
selected-hover-state-layer-color: $color,
selected-icon-color: $color,
selected-pressed-icon-color: $color,
unselected-focus-icon-color: $color,
unselected-hover-icon-color: $color,

selected-focus-state-layer-color: $on-surface,
selected-pressed-state-layer-color: $on-surface,
unselected-focus-state-layer-color: $on-surface,
unselected-hover-state-layer-color: $on-surface,
unselected-pressed-state-layer-color: $on-surface,

disabled-selected-icon-color: $disabled-color,
disabled-unselected-icon-color: $disabled-color,

unselected-icon-color: $border-color,
unselected-pressed-icon-color: $border-color,
));
}

// Apply ripple colors to the MatRipple element and the MDC ripple element when the
Expand All @@ -47,21 +67,7 @@
$accent: theming.get-color-from-palette(map.get($config, accent));
$warn: theming.get-color-from-palette(map.get($config, warn));

// 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-border-color: mdc-checkbox-theme.$border-color;
$orig-disabled-color: mdc-checkbox-theme.$disabled-color;

@include mdc-helpers.mat-using-mdc-theme($config) {
mdc-checkbox-theme.$border-color: rgba(
mdc-theme-color.prop-value(on-surface),
0.54
);
mdc-checkbox-theme.$disabled-color: rgba(
mdc-theme-color.prop-value(on-surface),
0.26
);

.mat-mdc-checkbox {
@include mdc-form-field.core-styles($query: mdc-helpers.$mat-theme-styles-query);
@include ripple-theme.color((
Expand All @@ -78,25 +84,21 @@
// class for accent and warn style, and applying the appropriate overrides below. Since we
// don't use MDC's ripple, we also need to set the color for our replacement ripple.
&.mat-primary {
@include private-checkbox-styles-with-color(primary);
@include private-checkbox-styles-with-color($primary, primary);
@include _selected-ripple-colors($primary, primary);
}

&.mat-accent {
@include private-checkbox-styles-with-color(secondary);
@include private-checkbox-styles-with-color($accent, secondary);
@include _selected-ripple-colors($accent, secondary);
}

&.mat-warn {
@include private-checkbox-styles-with-color(error);
@include private-checkbox-styles-with-color($warn, error);
@include _selected-ripple-colors($warn, error);
}
}
}

// Restore original values of MDC global variables.
mdc-checkbox-theme.$border-color: $orig-border-color;
mdc-checkbox-theme.$disabled-color: $orig-disabled-color;
}

@mixin typography($config-or-theme) {
Expand Down
41 changes: 24 additions & 17 deletions src/material-experimental/mdc-checkbox/checkbox.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@use '@material/checkbox' as mdc-checkbox;
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '@material/form-field' as mdc-form-field;
@use '@material/ripple' as mdc-ripple;
@use '@material/touch-target' as mdc-touch-target;
Expand All @@ -23,25 +24,31 @@
// we have to change it in order for margins to work.
display: inline-block;

// The MDC checkbox styles related to the hover state are intertwined with the MDC ripple styles.
// We currently don't use the MDC ripple due to size concerns, therefore we need to add some
// additional styles to restore the hover state.
.mdc-checkbox:hover .mdc-checkbox__native-control:not([disabled]) ~ .mdc-checkbox__ripple {
opacity: map.get(mdc-ripple.$dark-ink-opacities, hover);
transform: scale(1);
transition: mdc-checkbox-transition-enter(opacity, 0, 80ms),
mdc-checkbox-transition-enter(transform, 0, 80ms);
}
.mdc-checkbox {
// 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-checkbox-theme.theme-styles(mdc-checkbox-theme.$light-theme);

// The MDC checkbox styles related to the hover state are intertwined with the MDC ripple
// styles. We currently don't use the MDC ripple due to size concerns, therefore we need to
// add some additional styles to restore the hover state.
&:hover .mdc-checkbox__native-control:not([disabled]) ~ .mdc-checkbox__ripple {
opacity: map.get(mdc-ripple.$dark-ink-opacities, hover);
transform: scale(1);
transition: mdc-checkbox-transition-enter(opacity, 0, 80ms),
mdc-checkbox-transition-enter(transform, 0, 80ms);
}

// Note that the :not([disabled]) here isn't necessary, but we need it for the
// extra specificity so that the hover styles don't override the focus styles.
.mdc-checkbox .mdc-checkbox__native-control:not([disabled]):focus ~ .mdc-checkbox__ripple {
opacity: map.get(mdc-ripple.$dark-ink-opacities, hover) +
map.get(mdc-ripple.$dark-ink-opacities, focus);
// Note that the :not([disabled]) here isn't necessary, but we need it for the
// extra specificity so that the hover styles don't override the focus styles.
.mdc-checkbox__native-control:not([disabled]):focus ~ .mdc-checkbox__ripple {
opacity: map.get(mdc-ripple.$dark-ink-opacities, hover) +
map.get(mdc-ripple.$dark-ink-opacities, focus);

@include a11y.high-contrast(active, off) {
outline: solid 3px;
opacity: 1;
@include a11y.high-contrast(active, off) {
outline: solid 3px;
opacity: 1;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/material-experimental/mdc-list/_list-option-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// Mixin that overrides the selected item and checkbox colors for list options. By
// default, the MDC list uses the `primary` color for list items. The MDC checkbox
// inside list options by default uses the `primary` color too.
@mixin private-list-option-color-override($color) {
@mixin private-list-option-color-override($color, $mdcColor) {
& .mdc-list-item__start, & .mdc-list-item__end {
@include checkbox-theme.private-checkbox-styles-with-color($color);
@include checkbox-theme.private-checkbox-styles-with-color($color, $mdcColor);
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/material-experimental/mdc-list/_list-theme.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use 'sass:map';
@use '@material/list/evolution-mixins' as mdc-list;
@use './interactive-list-theme';
@use './list-option-theme';
Expand All @@ -11,6 +12,9 @@

@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));

// MDC's state styles are tied in with their ripple. Since we don't use the MDC
// ripple, we need to add the hover, focus and selected states manually.
Expand All @@ -20,13 +24,13 @@
@include mdc-list.without-ripple($query: mdc-helpers.$mat-theme-styles-query);

.mat-mdc-list-option {
@include list-option-theme.private-list-option-color-override(primary);
@include list-option-theme.private-list-option-color-override($primary, primary);
}
.mat-mdc-list-option.mat-accent {
@include list-option-theme.private-list-option-color-override(secondary);
@include list-option-theme.private-list-option-color-override($accent, secondary);
}
.mat-mdc-list-option.mat-warn {
@include list-option-theme.private-list-option-color-override(error);
@include list-option-theme.private-list-option-color-override($warn, error);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/material-experimental/mdc-list/list-option.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@use '@material/checkbox' as mdc-checkbox;
@use '@material/list/evolution-variables' as mdc-list-variables;
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '../mdc-helpers/mdc-helpers';
@use '../../cdk/a11y';
@use './list-option-trailing-avatar-compat';
Expand All @@ -18,6 +19,14 @@
@include mdc-checkbox.without-ripple($query: animation);
}

// We can't use the MDC checkbox here directly, because this checkbox is purely
// decorative and including the MDC one will bring in unnecessary JS.
.mdc-checkbox {
// 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-checkbox-theme.theme-styles(mdc-checkbox-theme.$light-theme);
}

// The internal checkbox is purely decorative, but because it's an `input`, the user can still
// focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role which
// doesn't allow a nested `input`. We use `display: none` both to remove it from the tab order
Expand Down

0 comments on commit ae9f3d5

Please sign in to comment.