From ef1ca5a2d5a5fdbd9b215f2e3b1b681f679fc6cf Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 28 Mar 2022 10:31:21 +0200 Subject: [PATCH] fix(material/menu): clicks on disabled item closing the menu 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. --- 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 309b30f1a0c4..77c0348e549f 100644 --- a/src/material-experimental/mdc-menu/menu.scss +++ b/src/material-experimental/mdc-menu/menu.scss @@ -67,17 +67,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 bbb3c57510d6..b9b91b16e169 100644 --- a/src/material/menu/menu.scss +++ b/src/material/menu/menu.scss @@ -53,13 +53,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) {