Skip to content

Commit 8eacecf

Browse files
committed
refactor(dialog): better handling of scrollable content
Currently, the dialog's scrollable content (md-dialog-content) is limited to 65% of the viewport height, however on smaller screens the dialog still ends up being too high. This proposal reworks the `md-dialog-content` to make it take up all of the remaining height, instead of being hardcoded to 65%. The max height is provided by the wrapper instead. Fixes #2481.
1 parent f4f69c4 commit 8eacecf

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

src/lib/dialog/dialog-container.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import {
55
ViewEncapsulation,
66
NgZone,
77
OnDestroy,
8+
Renderer,
89
} from '@angular/core';
910
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
1011
import {MdDialogConfig} from './dialog-config';
1112
import {MdDialogRef} from './dialog-ref';
13+
import {MD_DIALOG_CONTENT_SELECTOR} from './dialog-content-directives';
1214
import {MdDialogContentAlreadyAttachedError} from './dialog-errors';
1315
import {FocusTrap} from '../core/a11y/focus-trap';
1416
import 'rxjs/add/operator/first';
@@ -46,7 +48,7 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
4648
/** Reference to the open dialog. */
4749
dialogRef: MdDialogRef<any>;
4850

49-
constructor(private _ngZone: NgZone) {
51+
constructor(private _ngZone: NgZone, private _renderer: Renderer) {
5052
super();
5153
}
5254

@@ -60,6 +62,16 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6062
}
6163

6264
let attachResult = this._portalHost.attachComponentPortal(portal);
65+
let componentElement = attachResult.location.nativeElement;
66+
67+
// Add a class that we can use for styling the root element.
68+
this._renderer.setElementClass(componentElement, 'md-dialog-root', true);
69+
70+
// Add flexbox styling if the user is using the `md-dialog-content`.
71+
if ('querySelector' in componentElement) {
72+
this._renderer.setElementClass(componentElement, 'md-dialog-root-flex',
73+
!!componentElement.querySelector(MD_DIALOG_CONTENT_SELECTOR));
74+
}
6375

6476
// If were to attempt to focus immediately, then the content of the dialog would not yet be
6577
// ready in instances where change detection has to run first. To deal with this, we simply

src/lib/dialog/dialog-content-directives.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import {Directive, Input} from '@angular/core';
22
import {MdDialogRef} from './dialog-ref';
33

4+
export const MD_DIALOG_CONTENT_SELECTOR = '[md-dialog-content], md-dialog-content' +
5+
', [mat-dialog-content], mat-dialog-content';
6+
47

58
/**
69
* Button that will close the current dialog.
@@ -32,7 +35,7 @@ export class MdDialogTitle { }
3235
* Scrollable content container of a dialog.
3336
*/
3437
@Directive({
35-
selector: '[md-dialog-content], md-dialog-content, [mat-dialog-content], mat-dialog-content'
38+
selector: MD_DIALOG_CONTENT_SELECTOR
3639
})
3740
export class MdDialogContent { }
3841

src/lib/dialog/dialog.scss

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
$md-dialog-padding: 24px !default;
66
$md-dialog-border-radius: 2px !default;
77
$md-dialog-max-width: 80vw !default;
8-
$md-dialog-max-height: 65vh !default;
8+
$md-dialog-max-height: 80vh !default;
99

1010
md-dialog-container {
1111
@include md-elevation(24);
@@ -15,7 +15,6 @@ md-dialog-container {
1515
border-radius: $md-dialog-border-radius;
1616
box-sizing: border-box;
1717
overflow: auto;
18-
max-width: $md-dialog-max-width;
1918

2019
// The dialog container should completely fill its parent overlay element.
2120
width: 100%;
@@ -26,11 +25,20 @@ md-dialog-container {
2625
}
2726
}
2827

28+
.md-dialog-root {
29+
max-height: calc(#{$md-dialog-max-height} - #{$md-dialog-padding * 2});
30+
max-width: $md-dialog-max-width;
31+
32+
&.md-dialog-root-flex {
33+
display: flex;
34+
flex-flow: column;
35+
}
36+
}
37+
2938
md-dialog-content, [md-dialog-content], mat-dialog-content, [mat-dialog-content] {
3039
display: block;
3140
margin: 0 $md-dialog-padding * -1;
3241
padding: 0 $md-dialog-padding;
33-
max-height: $md-dialog-max-height;
3442
overflow: auto;
3543
}
3644

src/lib/dialog/dialog.spec.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,23 @@ describe('MdDialog', () => {
227227
expect(overlayContainerElement.querySelectorAll('md-dialog-container').length).toBe(0);
228228
});
229229

230+
it('should add a class for styling to the root element', () => {
231+
dialog.open(PizzaMsg);
232+
233+
let pizzaMsgContainer = overlayContainerElement.querySelector('pizza-msg');
234+
235+
expect(pizzaMsgContainer.classList).toContain('md-dialog-root');
236+
expect(pizzaMsgContainer.classList).not.toContain('md-dialog-root-flex');
237+
});
238+
239+
it('should add an extra flexbox class to components that use md-dialog-content', () => {
240+
dialog.open(ContentElementDialog);
241+
242+
let dialogContainer = overlayContainerElement.querySelector('content-element-dialog');
243+
244+
expect(dialogContainer.classList).toContain('md-dialog-root-flex');
245+
});
246+
230247
describe('disableClose option', () => {
231248
it('should prevent closing via clicks on the backdrop', () => {
232249
dialog.open(PizzaMsg, {
@@ -365,7 +382,10 @@ class ComponentWithChildViewContainer {
365382
}
366383

367384
/** Simple component for testing ComponentPortal. */
368-
@Component({template: '<p>Pizza</p> <input> <button>Close</button>'})
385+
@Component({
386+
template: '<p>Pizza</p> <input> <button>Close</button>',
387+
selector: 'pizza-msg'
388+
})
369389
class PizzaMsg {
370390
constructor(public dialogRef: MdDialogRef<PizzaMsg>) { }
371391
}
@@ -378,7 +398,8 @@ class PizzaMsg {
378398
<button md-dialog-close [aria-label]="closeButtonAriaLabel">Close</button>
379399
<div md-dialog-close>Should not close</div>
380400
</md-dialog-actions>
381-
`
401+
`,
402+
selector: 'content-element-dialog'
382403
})
383404
class ContentElementDialog {
384405
closeButtonAriaLabel: string;

0 commit comments

Comments
 (0)