diff --git a/src/material-experimental/mdc-menu/_menu-theme.scss b/src/material-experimental/mdc-menu/_menu-theme.scss index f9f9e7160e9f..5df2ca6a81c3 100644 --- a/src/material-experimental/mdc-menu/_menu-theme.scss +++ b/src/material-experimental/mdc-menu/_menu-theme.scss @@ -18,7 +18,7 @@ // items so we have to grey them out ourselves. .mat-mdc-menu-item[disabled] { &, - &::after, + .mat-mdc-menu-submenu-icon, .mat-icon-no-color { @include mdc-theme.prop(color, text-disabled-on-background); } @@ -27,7 +27,7 @@ // Since we're creating `mat-icon` and the submenu trigger // chevron ourselves, we have to handle the color as well. .mat-mdc-menu-item .mat-icon-no-color, - .mat-mdc-menu-item-submenu-trigger::after { + .mat-mdc-menu-submenu-icon { @include mdc-theme.prop(color, text-icon-on-background); } diff --git a/src/material-experimental/mdc-menu/menu-item.html b/src/material-experimental/mdc-menu/menu-item.html index 3092e914580e..56fc8536688a 100644 --- a/src/material-experimental/mdc-menu/menu-item.html +++ b/src/material-experimental/mdc-menu/menu-item.html @@ -3,3 +3,8 @@ [matRippleDisabled]="disableRipple || disabled" [matRippleTrigger]="_getHostElement()"> + diff --git a/src/material-experimental/mdc-menu/menu.scss b/src/material-experimental/mdc-menu/menu.scss index d52d2093a41a..03aa5619be71 100644 --- a/src/material-experimental/mdc-menu/menu.scss +++ b/src/material-experimental/mdc-menu/menu.scss @@ -98,11 +98,14 @@ mat-menu { } } -// Renders out a chevron on menu items that trigger a sub-menu. .mat-mdc-menu-item-submenu-trigger { @include menu-common.item-submenu-trigger(mdc-list.$deprecated-side-padding); } +.mat-mdc-menu-submenu-icon { + @include menu-common.item-submenu-icon(mdc-list.$deprecated-side-padding); +} + // Increase specificity because ripple styles are part of the `mat-core` mixin and can // potentially overwrite the absolute position of the container. .mat-mdc-menu-item .mat-mdc-menu-ripple { diff --git a/src/material-experimental/mdc-menu/menu.spec.ts b/src/material-experimental/mdc-menu/menu.spec.ts index ac003751e194..683ab7dd7cb5 100644 --- a/src/material-experimental/mdc-menu/menu.spec.ts +++ b/src/material-experimental/mdc-menu/menu.spec.ts @@ -2070,7 +2070,9 @@ describe('MDC-based MatMenu', () => { const menuItems = overlay.querySelectorAll('[mat-menu-item]'); expect(menuItems[0].classList).toContain('mat-mdc-menu-item-submenu-trigger'); + expect(menuItems[0].querySelector('.mat-mdc-menu-submenu-icon')).toBeTruthy(); expect(menuItems[1].classList).not.toContain('mat-mdc-menu-item-submenu-trigger'); + expect(menuItems[1].querySelector('.mat-mdc-menu-submenu-icon')).toBeFalsy(); }); it('should increase the sub-menu elevation based on its depth', () => { diff --git a/src/material/core/style/_menu-common.scss b/src/material/core/style/_menu-common.scss index 3abcaece969f..ec0b00f33f4e 100644 --- a/src/material/core/style/_menu-common.scss +++ b/src/material/core/style/_menu-common.scss @@ -1,4 +1,4 @@ -@use './private'; +@use '../../../cdk/a11y'; @use './list-common'; @use './layout-common'; @@ -58,36 +58,34 @@ $icon-margin: 16px !default; } } -@mixin item-submenu-trigger($side-padding, $triangle-height: 10px) { +@mixin item-submenu-trigger($side-padding) { // Increase the side padding to prevent the indicator from overlapping the text. padding-right: $side-padding * 2; - // Renders a triangle to indicate that the menu item will open a sub-menu. - &::after { - $size: private.private-div($triangle-height, 2); - - width: 0; - height: 0; - border-style: solid; - border-width: $size 0 $size $size; - border-color: transparent transparent transparent currentColor; - content: ''; - display: inline-block; - position: absolute; - top: 50%; - right: $side-padding; - transform: translateY(-50%); - } - [dir='rtl'] & { padding-right: $side-padding; padding-left: $side-padding * 2; + } +} - &::after { - right: auto; - left: $side-padding; - transform: rotateY(180deg) translateY(-50%); - } +@mixin item-submenu-icon($side-padding) { + position: absolute; + top: 50%; + right: $side-padding; + transform: translateY(-50%); + width: 5px; + height: 10px; + fill: currentColor; + + [dir='rtl'] & { + right: auto; + left: $side-padding; + transform: translateY(-50%) scaleX(-1); + } + + // Fix for Chromium-based browsers blending in the `currentColor` with the background. + @include a11y.high-contrast(active, off) { + fill: CanvasText; } } diff --git a/src/material/menu/_menu-theme.scss b/src/material/menu/_menu-theme.scss index fd9a9addf947..4985ba5807a8 100644 --- a/src/material/menu/_menu-theme.scss +++ b/src/material/menu/_menu-theme.scss @@ -21,7 +21,7 @@ &[disabled] { &, - &::after, + .mat-menu-submenu-icon, .mat-icon-no-color { color: theming.get-color-from-palette($foreground, 'disabled'); } @@ -29,7 +29,7 @@ } .mat-menu-item .mat-icon-no-color, - .mat-menu-item-submenu-trigger::after { + .mat-menu-submenu-icon { color: theming.get-color-from-palette($foreground, 'icon'); } diff --git a/src/material/menu/menu-item.html b/src/material/menu/menu-item.html index a025ff57a01e..8073c518f777 100644 --- a/src/material/menu/menu-item.html +++ b/src/material/menu/menu-item.html @@ -3,3 +3,9 @@ [matRippleDisabled]="disableRipple || disabled" [matRippleTrigger]="_getHostElement()"> + + diff --git a/src/material/menu/menu.scss b/src/material/menu/menu.scss index 5f019a8c5216..353986269014 100644 --- a/src/material/menu/menu.scss +++ b/src/material/menu/menu.scss @@ -77,6 +77,10 @@ mat-menu { @include menu-common.item-submenu-trigger(menu-common.$side-padding); } +.mat-menu-submenu-icon { + @include menu-common.item-submenu-icon(menu-common.$side-padding); +} + button.mat-menu-item { width: 100%; } diff --git a/src/material/menu/menu.spec.ts b/src/material/menu/menu.spec.ts index 823c81ce8cce..2acff39e047d 100644 --- a/src/material/menu/menu.spec.ts +++ b/src/material/menu/menu.spec.ts @@ -2055,7 +2055,9 @@ describe('MatMenu', () => { const menuItems = overlay.querySelectorAll('[mat-menu-item]'); expect(menuItems[0].classList).toContain('mat-menu-item-submenu-trigger'); + expect(menuItems[0].querySelector('.mat-menu-submenu-icon')).toBeTruthy(); expect(menuItems[1].classList).not.toContain('mat-menu-item-submenu-trigger'); + expect(menuItems[1].querySelector('.mat-menu-submenu-icon')).toBeFalsy(); }); it('should increase the sub-menu elevation based on its depth', () => {