diff --git a/src/demo-app/dialog/dialog-demo.html b/src/demo-app/dialog/dialog-demo.html
index c87a0c9956a8..95340b58df7a 100644
--- a/src/demo-app/dialog/dialog-demo.html
+++ b/src/demo-app/dialog/dialog-demo.html
@@ -1,7 +1,32 @@
Dialog demo
-
+
-
- Last close result: {{lastCloseResult}}
-
+
+
+ Dialog dimensions
+
+
+
+
+
+
+ Dialog position
+
+
+
+
+
+
+
+
+
+
+
+ Other options
+
+ Disable close
+
+
+
+Last close result: {{lastCloseResult}}
diff --git a/src/demo-app/dialog/dialog-demo.scss b/src/demo-app/dialog/dialog-demo.scss
index 5ac00398d901..60febd335283 100644
--- a/src/demo-app/dialog/dialog-demo.scss
+++ b/src/demo-app/dialog/dialog-demo.scss
@@ -1,3 +1,8 @@
.demo-dialog {
color: rebeccapurple;
}
+
+md-card {
+ max-width: 350px;
+ margin: 20px 0;
+}
diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts
index 5935059be7c8..c2ffc0dad2ee 100644
--- a/src/demo-app/dialog/dialog-demo.ts
+++ b/src/demo-app/dialog/dialog-demo.ts
@@ -1,5 +1,5 @@
import {Component} from '@angular/core';
-import {MdDialog, MdDialogRef} from '@angular/material';
+import {MdDialog, MdDialogRef, MdDialogConfig} from '@angular/material';
@Component({
moduleId: module.id,
@@ -10,11 +10,22 @@ import {MdDialog, MdDialogRef} from '@angular/material';
export class DialogDemo {
dialogRef: MdDialogRef;
lastCloseResult: string;
+ config: MdDialogConfig = {
+ disableClose: false,
+ width: '',
+ height: '',
+ position: {
+ top: '',
+ bottom: '',
+ left: '',
+ right: ''
+ }
+ };
constructor(public dialog: MdDialog) { }
open() {
- this.dialogRef = this.dialog.open(JazzDialog);
+ this.dialogRef = this.dialog.open(JazzDialog, this.config);
this.dialogRef.afterClosed().subscribe(result => {
this.lastCloseResult = result;
diff --git a/src/lib/core/overlay/position/global-position-strategy.spec.ts b/src/lib/core/overlay/position/global-position-strategy.spec.ts
index 2f7f0924dffe..3a1f31117165 100644
--- a/src/lib/core/overlay/position/global-position-strategy.spec.ts
+++ b/src/lib/core/overlay/position/global-position-strategy.spec.ts
@@ -100,6 +100,40 @@ describe('GlobalPositonStrategy', () => {
expect(element.style.position).toBe('fixed');
}));
+
+ it('should set the element width', fakeAsync(() => {
+ strategy.width('100px').apply(element);
+
+ flushMicrotasks();
+
+ expect(element.style.width).toBe('100px');
+ }));
+
+ it('should set the element height', fakeAsync(() => {
+ strategy.height('100px').apply(element);
+
+ flushMicrotasks();
+
+ expect(element.style.height).toBe('100px');
+ }));
+
+ it('should reset the horizontal position and offset when the width is 100%', fakeAsync(() => {
+ strategy.centerHorizontally().width('100%').apply(element);
+
+ flushMicrotasks();
+
+ expect(element.style.left).toBe('0px');
+ expect(element.style.transform).toBe('');
+ }));
+
+ it('should reset the vertical position and offset when the height is 100%', fakeAsync(() => {
+ strategy.centerVertically().height('100%').apply(element);
+
+ flushMicrotasks();
+
+ expect(element.style.top).toBe('0px');
+ expect(element.style.transform).toBe('');
+ }));
});
function fakeAsyncTest(fn: () => void) {
diff --git a/src/lib/core/overlay/position/global-position-strategy.ts b/src/lib/core/overlay/position/global-position-strategy.ts
index bf0c377abde6..5d268c40be34 100644
--- a/src/lib/core/overlay/position/global-position-strategy.ts
+++ b/src/lib/core/overlay/position/global-position-strategy.ts
@@ -12,6 +12,8 @@ export class GlobalPositionStrategy implements PositionStrategy {
private _bottom: string = '';
private _left: string = '';
private _right: string = '';
+ private _width: string = '';
+ private _height: string = '';
/** Array of individual applications of translateX(). Currently only for centering. */
private _translateX: string[] = [];
@@ -63,14 +65,45 @@ export class GlobalPositionStrategy implements PositionStrategy {
return this;
}
+ /** Sets the overlay width and clears any previously set width. */
+ width(value: string) {
+ this._width = value;
+
+ if (value === '100%') {
+ // When the width is 100%, we should reset the `left` and the offset,
+ // in order to ensure that the element is flush against the viewport edge.
+ this.left('0px');
+ }
+
+ return this;
+ }
+
+ /** Sets the overlay height and clears any previously set height. */
+ height(value: string) {
+ this._height = value;
+
+ if (value === '100%') {
+ // When the height is 100%, we should reset the `top` and the offset,
+ // in order to ensure that the element is flush against the viewport edge.
+ this.top('0px');
+ }
+
+ return this;
+ }
+
/**
* Centers the overlay horizontally with an optional offset.
* Clears any previously set horizontal position.
*/
- centerHorizontally(offset = '0px') {
+ centerHorizontally(offset?: string) {
this._left = '50%';
this._right = '';
- this._translateX = ['-50%', offset];
+ this._translateX = ['-50%'];
+
+ if (offset) {
+ this._translateX.push(offset);
+ }
+
return this;
}
@@ -78,10 +111,15 @@ export class GlobalPositionStrategy implements PositionStrategy {
* Centers the overlay vertically with an optional offset.
* Clears any previously set vertical position.
*/
- centerVertically(offset = '0px') {
+ centerVertically(offset?: string) {
this._top = '50%';
this._bottom = '';
- this._translateY = ['-50%', offset];
+ this._translateY = ['-50%'];
+
+ if (offset) {
+ this._translateY.push(offset);
+ }
+
return this;
}
@@ -95,13 +133,15 @@ export class GlobalPositionStrategy implements PositionStrategy {
element.style.left = this._left;
element.style.bottom = this._bottom;
element.style.right = this._right;
+ element.style.width = this._width;
+ element.style.height = this._height;
// TODO(jelbourn): we don't want to always overwrite the transform property here,
// because it will need to be used for animations.
- let tranlateX = this._reduceTranslateValues('translateX', this._translateX);
+ let translateX = this._reduceTranslateValues('translateX', this._translateX);
let translateY = this._reduceTranslateValues('translateY', this._translateY);
- applyCssTransform(element, `${tranlateX} ${translateY}`);
+ applyCssTransform(element, `${translateX} ${translateY}`);
return Promise.resolve(null);
}
diff --git a/src/lib/dialog/README.md b/src/lib/dialog/README.md
index 53ae1ec0bbcf..b9fb3c3c1506 100644
--- a/src/lib/dialog/README.md
+++ b/src/lib/dialog/README.md
@@ -12,8 +12,11 @@ MdDialog is a service, which opens dialogs components in the view.
| Key | Description |
| --- | --- |
-| `role: DialogRole = 'dialog'` | The ARIA role of the dialog element. Possible values are `dialog` and `alertdialog`. Defaults to `dialog`. |
-| `disableClose: boolean = false` | Whether to prevent the user from closing a dialog by clicking on the backdrop or pressing escape. Defaults to `false`. |
+| `role: DialogRole = 'dialog'` | The ARIA role of the dialog element. Possible values are `dialog` and `alertdialog`. Optional. |
+| `disableClose: boolean = false` | Whether to prevent the user from closing a dialog by clicking on the backdrop or pressing escape. Optional. |
+| `width: string = ''` | Width of the dialog. Takes any valid CSS value. Optional. |
+| `height: string = ''` | Height of the dialog. Takes any valid CSS value. Optional. |
+| `position: { top?: string, bottom?: string, left?: string, right?: string }` | Position of the dialog that overrides the default centering in it's axis. Optional. |
| `viewContainerRef: ViewContainerRef` | The view container ref to attach the dialog to. Optional. |
## MdDialogRef
diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts
index a98f1b0a904e..070ed8272876 100644
--- a/src/lib/dialog/dialog-config.ts
+++ b/src/lib/dialog/dialog-config.ts
@@ -1,8 +1,15 @@
import {ViewContainerRef} from '@angular/core';
/** Valid ARIA roles for a dialog element. */
-export type DialogRole = 'dialog' | 'alertdialog'
+export type DialogRole = 'dialog' | 'alertdialog';
+/** Possible overrides for a dialog's position. */
+export interface DialogPosition {
+ top?: string;
+ bottom?: string;
+ left?: string;
+ right?: string;
+};
/**
@@ -17,5 +24,14 @@ export class MdDialogConfig {
/** Whether the user can use escape or clicking outside to close a modal. */
disableClose?: boolean = false;
- // TODO(jelbourn): add configuration for size, lifecycle hooks, ARIA labelling.
+ /** Width of the dialog. */
+ width?: string = '';
+
+ /** Height of the dialog. */
+ height?: string = '';
+
+ /** Position overrides. */
+ position?: DialogPosition;
+
+ // TODO(jelbourn): add configuration for lifecycle hooks, ARIA labelling.
}
diff --git a/src/lib/dialog/dialog-container.scss b/src/lib/dialog/dialog-container.scss
index aa5b9909200c..73d419637094 100644
--- a/src/lib/dialog/dialog-container.scss
+++ b/src/lib/dialog/dialog-container.scss
@@ -7,6 +7,9 @@ md-dialog-container {
@include md-elevation(24);
display: block;
- overflow: hidden;
padding: $md-dialog-padding;
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ overflow: auto;
}
diff --git a/src/lib/dialog/dialog.ts b/src/lib/dialog/dialog.ts
index a71b260e021d..5d1baf6b87e4 100644
--- a/src/lib/dialog/dialog.ts
+++ b/src/lib/dialog/dialog.ts
@@ -22,8 +22,6 @@ export {MdDialogRef} from './dialog-ref';
// TODO(jelbourn): add support for opening with a TemplateRef
// TODO(jelbourn): add `closeAll` method
-// TODO(jelbourn): default dialog config
-// TODO(jelbourn): escape key closes dialog
// TODO(jelbourn): dialog content directives (e.g., md-dialog-header)
// TODO(jelbourn): animations
@@ -119,12 +117,26 @@ export class MdDialog {
*/
private _getOverlayState(dialogConfig: MdDialogConfig): OverlayState {
let state = new OverlayState();
+ let strategy = this._overlay.position().global();
+ let position = dialogConfig.position;
state.hasBackdrop = true;
- state.positionStrategy = this._overlay.position()
- .global()
- .centerHorizontally()
- .centerVertically();
+ state.positionStrategy = strategy;
+
+ // TODO(crisbeto): replace with `horizontal` to support RTL?
+ if (position && (position.left || position.right)) {
+ position.left ? strategy.left(position.left) : strategy.right(position.right);
+ } else {
+ strategy.centerHorizontally();
+ }
+
+ if (position && (position.top || position.bottom)) {
+ position.top ? strategy.top(position.top) : strategy.bottom(position.bottom);
+ } else {
+ strategy.centerVertically();
+ }
+
+ strategy.width(dialogConfig.width).height(dialogConfig.height);
return state;
}