diff --git a/src/material-experimental/mdc-button/_button-base.scss b/src/material-experimental/mdc-button/_button-base.scss index 9b6a0f9220dc..f7252a2a0afc 100644 --- a/src/material-experimental/mdc-button/_button-base.scss +++ b/src/material-experimental/mdc-button/_button-base.scss @@ -1,3 +1,5 @@ +@use '@material/touch-target' as mdc-touch-target; +@use '../mdc-helpers/mdc-helpers'; @use '../../material/core/style/layout-common'; // Adds styles necessary to provide stateful interactions with the button. This includes providing @@ -59,3 +61,25 @@ pointer-events: none; } } + +@mixin mat-private-button-touch-target($is-square) { + // Element used to ensure that the button has a touch target that meets the required minimum. + // Note that we use this, instead of MDC's built-in `mdc-button--touch` class, because the MDC + // class is implemented as `margin-top: 6px; margin-bottom: 6px` on the host element which + // goes against our rule of not having margins on the host node. Furthermore, having the margin on + // the button itself would require us to wrap it in another div. See: + // https://github.com/material-components/material-components-web/tree/master/packages/mdc-button#making-buttons-accessible + .mat-mdc-button-touch-target { + @include mdc-touch-target.touch-target( + $set-width: $is-square, + $query: mdc-helpers.$mat-base-styles-query); + + @if ($is-square) { + [dir='rtl'] & { + left: auto; + right: 50%; + transform: translate(50%, -50%); + } + } + } +} diff --git a/src/material-experimental/mdc-button/_button-theme-private.scss b/src/material-experimental/mdc-button/_button-theme-private.scss index 132b386b61ef..84f73a2f9a2a 100644 --- a/src/material-experimental/mdc-button/_button-theme-private.scss +++ b/src/material-experimental/mdc-button/_button-theme-private.scss @@ -45,3 +45,11 @@ $fab-state-target: '.mdc-fab__ripple'; @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') { + .mat-mdc-button-touch-target { + display: none; + } + } +} diff --git a/src/material-experimental/mdc-button/_button-theme.scss b/src/material-experimental/mdc-button/_button-theme.scss index bcbb44d60280..4f0df23e0872 100644 --- a/src/material-experimental/mdc-button/_button-theme.scss +++ b/src/material-experimental/mdc-button/_button-theme.scss @@ -159,6 +159,7 @@ .mat-mdc-unelevated-button, .mat-mdc-outlined-button { @include mdc-button-theme.density($density-scale, $query: mdc-helpers.$mat-base-styles-query); + @include button-theme-private.touch-target-density($density-scale); } } diff --git a/src/material-experimental/mdc-button/_icon-button-theme.scss b/src/material-experimental/mdc-button/_icon-button-theme.scss index a9b42d036313..16196ca888db 100644 --- a/src/material-experimental/mdc-button/_icon-button-theme.scss +++ b/src/material-experimental/mdc-button/_icon-button-theme.scss @@ -58,6 +58,7 @@ $density-scale: theming.get-density-config($config-or-theme); .mat-mdc-icon-button { @include mdc-icon-button.density($density-scale, $query: mdc-helpers.$mat-base-styles-query); + @include button-theme-private.touch-target-density($density-scale); } } diff --git a/src/material-experimental/mdc-button/button.html b/src/material-experimental/mdc-button/button.html index 32b22df3a4b6..e5abbe3801ee 100644 --- a/src/material-experimental/mdc-button/button.html +++ b/src/material-experimental/mdc-button/button.html @@ -21,3 +21,5 @@ [matRippleDisabled]="_isRippleDisabled()" [matRippleCentered]="_isRippleCentered" [matRippleTrigger]="_elementRef.nativeElement"> + + diff --git a/src/material-experimental/mdc-button/button.scss b/src/material-experimental/mdc-button/button.scss index 1ca09d997b9c..62b10a18d10c 100644 --- a/src/material-experimental/mdc-button/button.scss +++ b/src/material-experimental/mdc-button/button.scss @@ -2,7 +2,7 @@ @use '@material/button/variables' as mdc-button-variables; @use '../mdc-helpers/mdc-helpers'; @use '../../cdk/a11y'; -@use '_button-base'; +@use 'button-base'; @include mdc-button.without-ripple($query: mdc-helpers.$mat-base-styles-query); @@ -10,6 +10,7 @@ .mat-mdc-button, .mat-mdc-unelevated-button, .mat-mdc-raised-button, .mat-mdc-outlined-button { @include button-base.mat-private-button-interactive(); @include button-base.mat-private-button-disabled(); + @include button-base.mat-private-button-touch-target(false); } // MDC expects button icons to contain this HTML content: diff --git a/src/material-experimental/mdc-button/fab.scss b/src/material-experimental/mdc-button/fab.scss index 4aa590867d66..074015505382 100644 --- a/src/material-experimental/mdc-button/fab.scss +++ b/src/material-experimental/mdc-button/fab.scss @@ -1,12 +1,13 @@ @use '@material/fab' as mdc-fab; @use '../mdc-helpers/mdc-helpers'; -@use '_button-base'; +@use 'button-base'; @include mdc-fab.without-ripple($query: mdc-helpers.$mat-base-styles-query); .mat-mdc-fab, .mat-mdc-mini-fab { @include button-base.mat-private-button-interactive(); @include button-base.mat-private-button-disabled(); + @include button-base.mat-private-button-touch-target(true); // MDC adds some styles to fab and mini-fab that conflict with some of our focus indicator // styles and don't actually do anything. This undoes those conflicting styles. diff --git a/src/material-experimental/mdc-button/icon-button.scss b/src/material-experimental/mdc-button/icon-button.scss index f7daec321298..38b236b6959b 100644 --- a/src/material-experimental/mdc-button/icon-button.scss +++ b/src/material-experimental/mdc-button/icon-button.scss @@ -1,6 +1,6 @@ @use '@material/icon-button' as mdc-icon-button; @use '../mdc-helpers/mdc-helpers'; -@use '_button-base'; +@use 'button-base'; @include mdc-icon-button.without-ripple($query: mdc-helpers.$mat-base-styles-query); @@ -13,6 +13,7 @@ border-radius: 50%; @include button-base.mat-private-button-disabled(); + @include button-base.mat-private-button-touch-target(true); // MDC adds some styles to icon buttons that conflict with some of our focus indicator styles // and don't actually do anything. This undoes those conflicting styles.