Skip to content

Commit 23143b9

Browse files
jelbournhansl
authored andcommitted
feat(dialog): close with the escape key (#1330)
1 parent 74dc5b2 commit 23143b9

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

src/lib/dialog/dialog-container.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from '@angular/core';
99
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
1010
import {MdDialogConfig} from './dialog-config';
11+
import {MdDialogRef} from './dialog-ref';
1112
import {MdDialogContentAlreadyAttachedError} from './dialog-errors';
1213
import {FocusTrap} from '../core/a11y/focus-trap';
1314
import 'rxjs/add/operator/first';
@@ -23,7 +24,8 @@ import 'rxjs/add/operator/first';
2324
styleUrls: ['dialog-container.css'],
2425
host: {
2526
'class': 'md-dialog-container',
26-
'[attr.role]': 'dialogConfig?.role'
27+
'[attr.role]': 'dialogConfig?.role',
28+
'(keydown.escape)': 'handleEscapeKey()',
2729
},
2830
encapsulation: ViewEncapsulation.None,
2931
})
@@ -40,6 +42,9 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
4042
/** The dialog configuration. */
4143
dialogConfig: MdDialogConfig;
4244

45+
/** Reference to the open dialog. */
46+
dialogRef: MdDialogRef<any>;
47+
4348
constructor(private _ngZone: NgZone) {
4449
super();
4550
}
@@ -67,6 +72,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6772
throw Error('Not yet implemented');
6873
}
6974

75+
/** Handles the user pressing the Escape key. */
76+
handleEscapeKey() {
77+
// TODO(jelbourn): add MdDialogConfig option to disable this behavior.
78+
this.dialogRef.close();
79+
}
80+
7081
ngOnDestroy() {
7182
// When the dialog is destroyed, return focus to the element that originally had it before
7283
// the dialog was opened. Wait for the DOM to finish settling before changing the focus so

src/lib/dialog/dialog.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import {
66
ComponentFixture,
77
TestBed,
88
} from '@angular/core/testing';
9+
import {By} from '@angular/platform-browser';
910
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
1011
import {MdDialog, MdDialogModule} from './dialog';
1112
import {OverlayContainer} from '../core';
1213
import {MdDialogConfig} from './dialog-config';
1314
import {MdDialogRef} from './dialog-ref';
15+
import {MdDialogContainer} from './dialog-container';
1416

1517

1618
describe('MdDialog', () => {
@@ -94,6 +96,24 @@ describe('MdDialog', () => {
9496
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeNull();
9597
});
9698

99+
100+
it('should close a dialog via the escape key', () => {
101+
let config = new MdDialogConfig();
102+
config.viewContainerRef = testViewContainerRef;
103+
104+
dialog.open(PizzaMsg, config);
105+
106+
viewContainerFixture.detectChanges();
107+
108+
let dialogContainer: MdDialogContainer =
109+
viewContainerFixture.debugElement.query(By.directive(MdDialogContainer)).componentInstance;
110+
111+
// Fake the user pressing the escape key by calling the handler directly.
112+
dialogContainer.handleEscapeKey();
113+
114+
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeNull();
115+
});
116+
97117
it('should close when clicking on the overlay backdrop', () => {
98118
let config = new MdDialogConfig();
99119
config.viewContainerRef = testViewContainerRef;

src/lib/dialog/dialog.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ export class MdDialog {
9090
// When the dialog backdrop is clicked, we want to close it.
9191
overlayRef.backdropClick().subscribe(() => dialogRef.close());
9292

93+
// Set the dialogRef to the container so that it can use the ref to close the dialog.
94+
dialogContainer.dialogRef = dialogRef;
95+
9396
// We create an injector specifically for the component we're instantiating so that it can
9497
// inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself
9598
// and, optionally, to return a value.

0 commit comments

Comments
 (0)