Skip to content

fix(material-experimental/mdc-checkbox): switch to non-deprecated styles #23218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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