From b07ae4ccc451f98c2907d6394cdf2a6f8631d2cd Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 28 Mar 2022 17:00:39 +0200 Subject: [PATCH] fix(material/menu): clicks on disabled item closing the menu (#19183) Adds an overlay on top of the content of a disabled menu item in order to capture clicks and prevent the menu from closing when clicking on it. Fixes #19173. (cherry picked from commit a76f30107ec70fcbee1c8ec87026307a55cd0494) --- src/material-experimental/mdc-menu/menu.scss | 20 ++++++++++++++------ src/material/menu/menu.scss | 19 ++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/material-experimental/mdc-menu/menu.scss b/src/material-experimental/mdc-menu/menu.scss index ea8f3fc64337..8b94d48215f2 100644 --- a/src/material-experimental/mdc-menu/menu.scss +++ b/src/material-experimental/mdc-menu/menu.scss @@ -64,17 +64,25 @@ mat-menu { min-height: map.get($height-config, default); &[disabled] { - // Usually every click inside the menu closes it, however some browsers will stop events - // when the user clicks on a disabled item, **except** when the user clicks on a non-disabled - // child node of the disabled button. This is inconsistent because some regions of a disabled - // button will still cause the menu to close and some won't (see #16694). We make the behavior - // more consistent by disabling pointer events and allowing the user to click through. - pointer-events: none; cursor: default; // This is the same as `mdc-list-mixins.list-disabled-opacity` which // we can't use directly, because it comes with some selectors. opacity: mdc-list-variables.$content-disabled-opacity; + + // The browser prevents clicks on disabled buttons from propagating which prevents the menu + // from closing, but clicks on child nodes still propagate which is inconsistent (see #16694). + // In order to keep the behavior consistent and prevent the menu from closing, we add an overlay + // on top of the content that will catch all the clicks while disabled. + &::before { + display: block; + position: absolute; + content: ''; + top: 0; + left: 0; + bottom: 0; + right: 0; + } } .mat-icon { diff --git a/src/material/menu/menu.scss b/src/material/menu/menu.scss index 353986269014..98ff66bf4d75 100644 --- a/src/material/menu/menu.scss +++ b/src/material/menu/menu.scss @@ -49,13 +49,18 @@ mat-menu { @include menu-common.item-base(); position: relative; - &[disabled] { - // Usually every click inside the menu closes it, however some browsers will stop events - // when the user clicks on a disabled item, **except** when the user clicks on a non-disabled - // child node of the disabled button. This is inconsistent because some regions of a disabled - // button will still cause the menu to close and some won't (see #16694). We make the behavior - // more consistent by disabling pointer events and allowing the user to click through. - pointer-events: none; + // The browser prevents clicks on disabled buttons from propagating which prevents the menu + // from closing, but clicks on child nodes still propagate which is inconsistent (see #16694). + // In order to keep the behavior consistent and prevent the menu from closing, we add an overlay + // on top of the content that will catch all the clicks while disabled. + &[disabled]::before { + display: block; + position: absolute; + content: ''; + top: 0; + left: 0; + bottom: 0; + right: 0; } @include a11y.high-contrast(active, off) {