Skip to content

Commit 7bbcb93

Browse files
committed
fix(menu): update to use overlay backdrop
1 parent cfe3e98 commit 7bbcb93

File tree

6 files changed

+42
-35
lines changed

6 files changed

+42
-35
lines changed

e2e/components/menu/menu.e2e.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,6 @@ describe('menu', () => {
1515
expect(page.menu().getText()).toEqual("One\nTwo\nThree\nFour");
1616
});
1717

18-
it('should close menu when area outside menu is clicked', () => {
19-
page.trigger().click();
20-
page.body().click();
21-
page.expectMenuPresent(false);
22-
});
23-
24-
it('should close menu when menu item is clicked', () => {
25-
page.trigger().click();
26-
page.items(0).click();
27-
page.expectMenuPresent(false);
28-
});
29-
3018
it('should run click handlers on regular menu items', () => {
3119
page.trigger().click();
3220
page.items(0).click();

src/lib/menu/menu-directive.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {UP_ARROW, DOWN_ARROW, TAB} from '../core';
2727
exportAs: 'mdMenu'
2828
})
2929
export class MdMenu {
30-
_showClickCatcher: boolean = false;
3130
private _focusedItemIndex: number = 0;
3231

3332
// config object to be passed into the menu's ngClass
@@ -61,15 +60,6 @@ export class MdMenu {
6160

6261
@Output() close = new EventEmitter;
6362

64-
/**
65-
* This function toggles the display of the menu's click catcher element.
66-
* This element covers the viewport when the menu is open to detect clicks outside the menu.
67-
* TODO: internal
68-
*/
69-
_setClickCatcher(bool: boolean): void {
70-
this._showClickCatcher = bool;
71-
}
72-
7363
/**
7464
* Focus the first item in the menu. This method is used by the menu trigger
7565
* to focus the first item when the menu is opened by the ENTER key.

src/lib/menu/menu-trigger.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
7070
if (!this._menuOpen) {
7171
this._createOverlay();
7272
this._overlayRef.attach(this._portal);
73+
this._overlayRef.backdropClick().first().subscribe(() => this.closeMenu());
7374
this._initMenu();
7475
}
7576
}
@@ -120,7 +121,6 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
120121
// set state rather than toggle to support triggers sharing a menu
121122
private _setIsMenuOpen(isOpen: boolean): void {
122123
this._menuOpen = isOpen;
123-
this.menu._setClickCatcher(isOpen);
124124
this._menuOpen ? this.onMenuOpen.emit(null) : this.onMenuClose.emit(null);
125125
}
126126

@@ -152,6 +152,8 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
152152
private _getOverlayConfig(): OverlayState {
153153
const overlayState = new OverlayState();
154154
overlayState.positionStrategy = this._getPosition();
155+
overlayState.hasBackdrop = true;
156+
overlayState.backdropClass = 'md-overlay-transparent-backdrop';
155157
return overlayState;
156158
}
157159

src/lib/menu/menu.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
<ng-content></ng-content>
55
</div>
66
</template>
7-
<div class="md-menu-click-catcher" *ngIf="_showClickCatcher" (click)="_emitCloseEvent()"></div>
7+

src/lib/menu/menu.scss

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,4 @@ $md-menu-vertical-padding: 8px !default;
5252

5353
button[md-menu-item] {
5454
width: 100%;
55-
}
56-
57-
.md-menu-click-catcher {
58-
@include md-fullscreen();
59-
}
55+
}

src/lib/menu/menu.spec.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,70 @@ import {TestBed, async} from '@angular/core/testing';
22
import {Component, ViewChild} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {MdMenuModule, MdMenuTrigger} from './menu';
5+
import {OverlayContainer} from '../core/overlay/overlay-container';
56

67

78
describe('MdMenu', () => {
9+
let overlayContainerElement: HTMLElement;
810

911
beforeEach(async(() => {
1012
TestBed.configureTestingModule({
1113
imports: [MdMenuModule.forRoot()],
1214
declarations: [SimpleMenu],
15+
providers: [
16+
{provide: OverlayContainer, useFactory: () => {
17+
overlayContainerElement = document.createElement('div');
18+
return {getContainerElement: () => overlayContainerElement};
19+
}}
20+
]
1321
});
1422

1523
TestBed.compileComponents();
1624
}));
1725

1826
it('should open the menu as an idempotent operation', () => {
19-
let fixture = TestBed.createComponent(SimpleMenu);
27+
const fixture = TestBed.createComponent(SimpleMenu);
2028
fixture.detectChanges();
21-
let menu = fixture.debugElement.query(By.css('.md-menu-panel'));
22-
expect(menu).toBe(null);
29+
expect(overlayContainerElement.textContent).toBe('');
2330
expect(() => {
2431
fixture.componentInstance.trigger.openMenu();
2532
fixture.componentInstance.trigger.openMenu();
2633

27-
menu = fixture.debugElement.query(By.css('.md-menu-panel'));
28-
expect(menu.nativeElement.innerHTML.trim()).toEqual('Content');
34+
expect(overlayContainerElement.textContent.trim()).toBe('Content');
2935
}).not.toThrowError();
3036
});
37+
38+
it('should close the menu when a menu item is clicked', () => {
39+
const fixture = TestBed.createComponent(SimpleMenu);
40+
fixture.detectChanges();
41+
fixture.componentInstance.trigger.openMenu();
42+
43+
const menuItem = fixture.debugElement.query(By.css('[md-menu-item]'));
44+
menuItem.nativeElement.click();
45+
fixture.detectChanges();
46+
47+
expect(overlayContainerElement.textContent).toBe('');
48+
});
49+
50+
it('should close the menu when a click occurs outside the menu', () => {
51+
const fixture = TestBed.createComponent(SimpleMenu);
52+
fixture.detectChanges();
53+
fixture.componentInstance.trigger.openMenu();
54+
55+
const backdrop = <HTMLElement> overlayContainerElement.querySelector('.md-overlay-backdrop');
56+
backdrop.click();
57+
fixture.detectChanges();
58+
59+
expect(overlayContainerElement.textContent).toBe('');
60+
});
61+
3162
});
3263

3364
@Component({
3465
template: `
3566
<button [md-menu-trigger-for]="menu">Toggle menu</button>
3667
<md-menu #menu="mdMenu">
37-
Content
68+
<button md-menu-item> Content </button>
3869
</md-menu>
3970
`
4071
})

0 commit comments

Comments
 (0)