Skip to content

Commit

Permalink
feat(dialog): add styles and ability to close. (#862)
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn authored and kara committed Jul 15, 2016
1 parent b2471f2 commit 758b851
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 16 deletions.
12 changes: 9 additions & 3 deletions src/components/dialog/dialog-container.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
@import 'elevation';
@import 'default-theme';

$md-dialog-padding: 24px !default;

:host {
// TODO(jelbourn): add real Material Design dialog styles.
display: block;
background: deeppink;
@include md-elevation(2);
overflow: hidden;

padding: $md-dialog-padding;

background: md-color($md-background, dialog);
@include md-elevation(24);
}
29 changes: 28 additions & 1 deletion src/components/dialog/dialog-ref.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
import {OverlayRef} from '@angular2-material/core/overlay/overlay-ref';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';


// TODO(jelbourn): resizing
// TODO(jelbourn): afterOpen and beforeClose


/**
* Reference to a dialog opened via the MdDialog service.
*/
export class MdDialogRef<T> {
/** The instance of component opened into the dialog. */
componentInstance: T;

// TODO(jelbourn): Add methods to resize, close, and get results from the dialog.
/** Subject for notifying the user that the dialog has finished closing. */
private _afterClosed: Subject<any> = new Subject();

constructor(private _overlayRef: OverlayRef) { }

/**
* Close the dialog.
* @param dialogResult Optional result to return to the dialog opener.
*/
close(dialogResult?: any): void {
this._overlayRef.dispose();
this._afterClosed.next(dialogResult);
this._afterClosed.complete();
}

/** Gets an observable that is notified when the dialog is finished closing. */
afterClosed(): Observable<any> {
return this._afterClosed.asObservable();
}
}
23 changes: 23 additions & 0 deletions src/components/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,29 @@ describe('MdDialog', () => {

detectChangesForDialogOpen(viewContainerFixture);
}));

it('should close a dialog and get back a result', async(() => {
let config = new MdDialogConfig();
config.viewContainerRef = testViewContainerRef;

dialog.open(PizzaMsg, config).then(dialogRef => {
viewContainerFixture.detectChanges();

let afterCloseResult: string;
dialogRef.afterClosed().subscribe(result => {
afterCloseResult = result;
});

dialogRef.close('Charmander');

viewContainerFixture.whenStable().then(() => {
expect(afterCloseResult).toBe('Charmander');
expect(overlayContainerElement.childNodes.length).toBe(0);
});
});

detectChangesForDialogOpen(viewContainerFixture);
}));
});


Expand Down
19 changes: 12 additions & 7 deletions src/components/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ export class MdDialog {
* @param config
*/
open<T>(component: ComponentType<T>, config: MdDialogConfig): Promise<MdDialogRef<T>> {
let overlayRef: OverlayRef;

return this._createOverlay(config)
.then(overlayRef => this._attachDialogContainer(overlayRef, config))
.then(containerRef => this._attachDialogContent(component, containerRef));
.then(overlay => overlayRef = overlay)
.then(overlay => this._attachDialogContainer(overlay, config))
.then(containerRef => this._attachDialogContent(component, containerRef, overlayRef));
}

/**
Expand All @@ -54,14 +57,14 @@ export class MdDialog {

/**
* Attaches an MdDialogContainer to a dialog's already-created overlay.
* @param overlayRef Reference to the dialog's underlying overlay.
* @param overlay Reference to the dialog's underlying overlay.
* @param config The dialog configuration.
* @returns A promise resolving to a ComponentRef for the attached container.
*/
private _attachDialogContainer(overlayRef: OverlayRef, config: MdDialogConfig):
private _attachDialogContainer(overlay: OverlayRef, config: MdDialogConfig):
Promise<ComponentRef<MdDialogContainer>> {
let containerPortal = new ComponentPortal(MdDialogContainer, config.viewContainerRef);
return overlayRef.attach(containerPortal).then(containerRef => {
return overlay.attach(containerPortal).then((containerRef: ComponentRef<MdDialogContainer>) => {
// Pass the config directly to the container so that it can consume any relevant settings.
containerRef.instance.dialogConfig = config;
return containerRef;
Expand All @@ -72,16 +75,18 @@ export class MdDialog {
* Attaches the user-provided component to the already-created MdDialogContainer.
* @param component The type of component being loaded into the dialog.
* @param containerRef Reference to the wrapping MdDialogContainer.
* @param overlayRef Reference to the overlay in which the dialog resides.
* @returns A promise resolving to the MdDialogRef that should be returned to the user.
*/
private _attachDialogContent<T>(
component: ComponentType<T>,
containerRef: ComponentRef<MdDialogContainer>): Promise<MdDialogRef<T>> {
containerRef: ComponentRef<MdDialogContainer>,
overlayRef: OverlayRef): Promise<MdDialogRef<T>> {
let dialogContainer = containerRef.instance;

// Create a reference to the dialog we're creating in order to give the user a handle
// to modify and close it.
let dialogRef = new MdDialogRef();
let dialogRef = new MdDialogRef(overlayRef);

// We create an injector specifically for the component we're instantiating so that it can
// inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself
Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/demo-app/demo-app.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.demo-root {
body {
font-family: Roboto, 'Helvetica Neue', sans-serif;

// Helps fonts on OSX looks more consistent with other systems
Expand Down
5 changes: 3 additions & 2 deletions src/demo-app/demo-app/demo-app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import {Component, ViewEncapsulation} from '@angular/core';
import {ROUTER_DIRECTIVES} from '@angular/router';

import {Dir} from '@angular2-material/core/rtl/dir';
Expand Down Expand Up @@ -32,6 +32,7 @@ export class Home {}
MD_LIST_DIRECTIVES,
MdToolbar,
],
pipes: []
pipes: [],
encapsulation: ViewEncapsulation.None,
})
export class DemoApp { }
4 changes: 4 additions & 0 deletions src/demo-app/dialog/dialog-demo.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<h1>Dialog demo</h1>

<button (click)="open()" [disabled]="dialogRef">Open dialog</button>

<p>
Last close result: {{lastCloseResult}}
</p>
15 changes: 13 additions & 2 deletions src/demo-app/dialog/dialog-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {OVERLAY_PROVIDERS} from '@angular2-material/core/overlay/overlay';
})
export class DialogDemo {
dialogRef: MdDialogRef<JazzDialog>;
lastCloseResult: string;

constructor(
public dialog: MdDialog,
Expand All @@ -22,13 +23,23 @@ export class DialogDemo {

this.dialog.open(JazzDialog, config).then(ref => {
this.dialogRef = ref;

this.dialogRef.afterClosed().subscribe(result => {
this.lastCloseResult = result;
this.dialogRef = null;
});
});
}
}


@Component({
selector: 'demo-jazz-dialog',
template: `<p>It's Jazz!</p>`
template: `
<p>It's Jazz!</p>
<p><label>How much? <input #howMuch></label></p>
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>`
})
export class JazzDialog { }
export class JazzDialog {
constructor(public dialogRef: MdDialogRef<JazzDialog>) { }
}

0 comments on commit 758b851

Please sign in to comment.