Skip to content

Commit

Permalink
fix(menu): nested menu hover not working when trigger is added lazily (
Browse files Browse the repository at this point in the history
…#6807)

Fixes not being able to open a sub-menu if its trigger is added after initialization.

Fixes #6731.
  • Loading branch information
crisbeto authored and tinayuangao committed Sep 6, 2017
1 parent cf1ece0 commit 6b5100b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/lib/menu/menu-directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {ESCAPE, LEFT_ARROW, RIGHT_ARROW} from '../core/keyboard/keycodes';
import {merge} from 'rxjs/observable/merge';
import {Observable} from 'rxjs/Observable';
import {Direction} from '@angular/cdk/bidi';
import {RxChain, startWith, switchMap} from '@angular/cdk/rxjs';

/** Default `md-menu` options that can be overridden. */
export interface MdMenuDefaultOptions {
Expand Down Expand Up @@ -157,7 +158,10 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {

/** Stream that emits whenever the hovered menu item changes. */
hover(): Observable<MdMenuItem> {
return merge(...this.items.map(item => item.hover));
return RxChain.from(this.items.changes)
.call(startWith, this.items)
.call(switchMap, (items: MdMenuItem[]) => merge(...items.map(item => item.hover)))
.result();
}

/** Handle a keyboard event from the menu, delegating to the appropriate action. */
Expand Down
33 changes: 32 additions & 1 deletion src/lib/menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,23 @@ describe('MdMenu', () => {
expect(overlay.querySelectorAll('.mat-menu-panel').length).toBe(0, 'Expected no open menus');
}));

it('should toggle a nested menu when its trigger is added after init', fakeAsync(() => {
compileTestComponent();
instance.rootTriggerEl.nativeElement.click();
fixture.detectChanges();
expect(overlay.querySelectorAll('.mat-menu-panel').length).toBe(1, 'Expected one open menu');

instance.showLazy = true;
fixture.detectChanges();

const lazyTrigger = overlay.querySelector('#lazy-trigger')!;

dispatchMouseEvent(lazyTrigger, 'mouseenter');
fixture.detectChanges();
expect(lazyTrigger.classList)
.toContain('mat-menu-item-highlighted', 'Expected the trigger to be highlighted');
expect(overlay.querySelectorAll('.mat-menu-panel').length).toBe(2, 'Expected two open menus');
}));

});

Expand Down Expand Up @@ -1126,7 +1143,11 @@ class CustomMenu {
[mdMenuTriggerFor]="levelOne"
#levelOneTrigger="mdMenuTrigger">One</button>
<button md-menu-item>Two</button>
<button md-menu-item>Three</button>
<button md-menu-item
*ngIf="showLazy"
id="lazy-trigger"
[mdMenuTriggerFor]="lazy"
#lazyTrigger="mdMenuTrigger">Three</button>
</md-menu>
<md-menu #levelOne="mdMenu">
Expand All @@ -1143,6 +1164,12 @@ class CustomMenu {
<button md-menu-item>Eight</button>
<button md-menu-item>Nine</button>
</md-menu>
<md-menu #lazy="mdMenu">
<button md-menu-item>Ten</button>
<button md-menu-item>Eleven</button>
<button md-menu-item>Twelve</button>
</md-menu>
`
})
class NestedMenu {
Expand All @@ -1156,6 +1183,10 @@ class NestedMenu {

@ViewChild('levelTwo') levelTwoMenu: MdMenu;
@ViewChild('levelTwoTrigger') levelTwoTrigger: MdMenuTrigger;

@ViewChild('lazy') lazyMenu: MdMenu;
@ViewChild('lazyTrigger') lazyTrigger: MdMenuTrigger;
showLazy = false;
}

@Component({
Expand Down

0 comments on commit 6b5100b

Please sign in to comment.