Skip to content

Commit d57f242

Browse files
committed
fix(menu): not closing sibling sub-menus when hovering over disabled items
* Fixes sub-menus not being closed when the user hovers over a disabled sibling menu item. * Fixes the sub-menu arrow not being greyed out for disabled items.
1 parent 6273d6a commit d57f242

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

src/lib/menu/_menu-theme.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
color: mat-color($foreground, 'text');
1717

1818
&[disabled] {
19-
color: mat-color($foreground, 'disabled');
19+
&, &::after {
20+
color: mat-color($foreground, 'disabled');
21+
}
2022
}
2123
}
2224

src/lib/menu/menu-item.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ export class MatMenuItem extends _MatMenuItemMixinBase
122122

123123
/** Emits to the hover stream. */
124124
_emitHoverEvent() {
125-
if (!this.disabled) {
126-
this._hovered.next(this);
127-
}
125+
this._hovered.next(this);
128126
}
129127

130128
/** Gets the label to be used when determining whether the option should be focused. */

src/lib/menu/menu-trigger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
163163
if (this.triggersSubmenu()) {
164164
// Subscribe to changes in the hovered item in order to toggle the panel.
165165
this._hoverSubscription = this._parentMenu._hovered()
166-
.pipe(filter(active => active === this._menuItemInstance))
166+
.pipe(filter(active => active === this._menuItemInstance && !active.disabled))
167167
.subscribe(() => {
168168
this._openedByMouse = true;
169169
this.openMenu();

src/lib/menu/menu.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,60 @@ describe('MatMenu', () => {
932932
.toBe(1, 'Expected one open menu');
933933
}));
934934

935+
it('should close submenu when hovering over disabled sibling item', fakeAsync(() => {
936+
compileTestComponent();
937+
instance.rootTriggerEl.nativeElement.click();
938+
fixture.detectChanges();
939+
tick(500);
940+
941+
const items = fixture.debugElement.queryAll(By.directive(MatMenuItem));
942+
943+
dispatchFakeEvent(items[0].nativeElement, 'mouseenter');
944+
fixture.detectChanges();
945+
tick(500);
946+
947+
expect(overlay.querySelectorAll('.mat-menu-panel').length)
948+
.toBe(2, 'Expected two open menus');
949+
950+
items[1].componentInstance.disabled = true;
951+
fixture.detectChanges();
952+
953+
// Note that we use `dispatchFakeEvent`, rather that `dispatchMouseEvent`, because the
954+
// fake mouse events aren't being dispatched for disabled elements, whereas the
955+
// native ones are.
956+
dispatchFakeEvent(items[1].nativeElement, 'mouseenter');
957+
fixture.detectChanges();
958+
tick(500);
959+
960+
expect(overlay.querySelectorAll('.mat-menu-panel').length)
961+
.toBe(1, 'Expected one open menu');
962+
}));
963+
964+
it('should not open submenu when hovering over disabled trigger', fakeAsync(() => {
965+
compileTestComponent();
966+
instance.rootTriggerEl.nativeElement.click();
967+
fixture.detectChanges();
968+
tick(500);
969+
970+
expect(overlay.querySelectorAll('.mat-menu-panel').length)
971+
.toBe(1, 'Expected one open menu');
972+
973+
const item = fixture.debugElement.query(By.directive(MatMenuItem));
974+
975+
// Note that we use `dispatchFakeEvent`, rather that `dispatchMouseEvent`, because the
976+
// fake mouse events aren't being dispatched for disabled elements, whereas the
977+
// native ones are.
978+
item.componentInstance.disabled = true;
979+
fixture.detectChanges();
980+
dispatchFakeEvent(item.nativeElement, 'mouseenter');
981+
fixture.detectChanges();
982+
tick(500);
983+
984+
expect(overlay.querySelectorAll('.mat-menu-panel').length)
985+
.toBe(1, 'Expected to remain at one open menu');
986+
}));
987+
988+
935989
it('should open a nested menu when its trigger is clicked', () => {
936990
compileTestComponent();
937991
instance.rootTriggerEl.nativeElement.click();

0 commit comments

Comments
 (0)