Skip to content

Commit

Permalink
refactor(material-experimental/mdc-button): switch to new theming API (
Browse files Browse the repository at this point in the history
…#24201)

* refactor(material-experimental/mdc-button): switch to new theming API

Switches the MDC-based buttons to the new token-based theming API.

* refactor(material-experimental/mdc-button): reduce bundle size

Reworks the MDC buttons to reduce their bundle size.

(cherry picked from commit 4ee7159)
  • Loading branch information
crisbeto committed Jan 20, 2022
1 parent 95c1889 commit 4acbae7
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 207 deletions.
43 changes: 28 additions & 15 deletions src/material-experimental/mdc-button/_button-base.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use 'sass:map';
@use '@material/touch-target' as mdc-touch-target;
@use '../mdc-helpers/mdc-helpers';
@use '../../material/core/style/layout-common';
Expand All @@ -8,22 +9,10 @@
// ripple and state container so that they fill the button, match the border radius, and avoid
// pointer events.
@mixin mat-private-button-interactive() {
.mdc-button__ripple::before, .mdc-button__ripple::after,
.mdc-fab__ripple::before, .mdc-fab__ripple::after {
content: '';
pointer-events: none;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
border-radius: inherit;
@content;
}

// The ripple container should match the bounds of the entire button.
.mat-mdc-button-ripple, .mdc-button__ripple, .mdc-fab__ripple {
.mat-mdc-button-ripple,
.mat-mdc-button-persistent-ripple,
.mat-mdc-button-persistent-ripple::before {
@include layout-common.fill;

// Disable pointer events for the ripple container and state overlay because the container
Expand All @@ -38,6 +27,17 @@
border-radius: inherit;
}

// We use ::before so that we can reuse some of MDC's theming.
.mat-mdc-button-persistent-ripple::before {
content: '';
opacity: 0;
background-color: var(--mat-mdc-button-persistent-ripple-color);
}

.mat-ripple-element {
background-color: var(--mat-mdc-button-ripple-color);
}

// The content should appear over the state and ripple layers, otherwise they may adversely affect
// the accessibility of the text content.
.mdc-button__label {
Expand All @@ -59,6 +59,7 @@
&[disabled] {
cursor: default;
pointer-events: none;
@content;
}
}

Expand All @@ -75,3 +76,15 @@
$query: mdc-helpers.$mat-base-styles-query);
}
}

// Changes a button theme to exclude the ripple styles.
@function mat-private-button-remove-ripple($theme) {
@return map.merge($theme, (
focus-state-layer-color: null,
focus-state-layer-opacity: null,
hover-state-layer-color: null,
hover-state-layer-opacity: null,
pressed-state-layer-color: null,
pressed-state-layer-opacity: null,
));
}
63 changes: 35 additions & 28 deletions src/material-experimental/mdc-button/_button-theme-private.scss
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
@use 'sass:map';
@use '@material/ripple/ripple-theme' as mdc-ripple-theme;
@use '@material/theme/theme-color' as mdc-theme-color;
@use '@material/theme/theme' as mdc-theme;
@use '../../material/core/ripple/ripple-theme';

// Selector for the element that has a background color and opacity applied to its ::before and
// ::after for state interactions (hover, active, focus). Their API calls this their
// "ripple target", but we do not use it as our ripple, just state color.
$button-state-target: '.mdc-button__ripple';
$fab-state-target: '.mdc-fab__ripple';

// The MDC button's ripple ink color is based on the theme color, not on the foreground base
// which is what the ripple mixin uses. This creates a new theme that sets the color to the
// foreground base to appropriately color the ink.
@mixin ripple-ink-color($mdc-color) {
@include ripple-theme.color((
foreground: (
base: mdc-theme-color.prop-value($mdc-color)
),
));
@mixin _ripple-color($color) {
--mat-mdc-button-persistent-ripple-color: #{$color};
--mat-mdc-button-ripple-color: #{rgba($color, 0.1)};
}

// Applies the disabled theme color to the text color.
@mixin apply-disabled-color() {
@include mdc-theme.prop(color,
mdc-theme-color.ink-color-for-fill_(disabled, mdc-theme-color.$background));
@mixin ripple-theme-styles($config, $is-filled) {
$opacities: if(map.get($config, is-dark),
mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities);

// Ideally these styles would be structural, but MDC bases some of the opacities on the theme.
&:hover .mat-mdc-button-persistent-ripple::before {
opacity: map.get($opacities, hover);
}

&:focus .mat-mdc-button-persistent-ripple::before {
opacity: map.get($opacities, focus);
}

&:active .mat-mdc-button-persistent-ripple::before {
opacity: map.get($opacities, press);
}

@include _ripple-color(mdc-theme-color.prop-value(on-surface));

&.mat-primary {
@include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-primary, primary)));
}

&.mat-accent {
@include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-secondary, secondary)));
}

&.mat-warn {
@include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-error, error)));
}
}

// Wraps the content style in a selector for the disabled state.
Expand All @@ -37,14 +52,6 @@ $fab-state-target: '.mdc-fab__ripple';
}
}

// Applies the disabled theme background color for raised buttons. Value is taken from
// mixin `mdc-button--filled`.
// TODO(andrewseguin): Discuss with the MDC team about providing a variable for the 0.12 value
// or otherwise have a mixin we can call to apply this style for both button and anchors.
@mixin apply-disabled-background() {
@include mdc-theme.prop(background-color, rgba(mdc-theme-color.prop-value(on-surface), 0.12));
}

// Hides the touch target on lower densities.
@mixin touch-target-density($scale) {
@if ($scale == -2 or $scale == 'minimum') {
Expand Down
Loading

0 comments on commit 4acbae7

Please sign in to comment.