Skip to content

Commit fe37cb2

Browse files
crisbetojelbourn
authored andcommitted
refactor(overlay): allow for object to be passed to the OverlayState constructor (#6615)
Allows for a config object to be passed to the `OverlayState` constructor. This makes the longer configurations a bit more convenient to use.
1 parent 21c68ad commit fe37cb2

15 files changed

+93
-85
lines changed

src/cdk/overlay/overlay-directives.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,12 @@ export class ConnectedOverlayDirective implements OnDestroy, OnChanges {
272272

273273
/** Builds the overlay config based on the directive's inputs */
274274
private _buildConfig(): OverlayState {
275-
let overlayConfig = new OverlayState();
275+
const positionStrategy = this._position = this._createPositionStrategy();
276+
const overlayConfig = new OverlayState({
277+
positionStrategy,
278+
scrollStrategy: this.scrollStrategy,
279+
hasBackdrop: this.hasBackdrop
280+
});
276281

277282
if (this.width || this.width === 0) {
278283
overlayConfig.width = this.width;
@@ -290,16 +295,10 @@ export class ConnectedOverlayDirective implements OnDestroy, OnChanges {
290295
overlayConfig.minHeight = this.minHeight;
291296
}
292297

293-
overlayConfig.hasBackdrop = this.hasBackdrop;
294-
295298
if (this.backdropClass) {
296299
overlayConfig.backdropClass = this.backdropClass;
297300
}
298301

299-
this._position = this._createPositionStrategy() as ConnectedPositionStrategy;
300-
overlayConfig.positionStrategy = this._position;
301-
overlayConfig.scrollStrategy = this.scrollStrategy;
302-
303302
return overlayConfig;
304303
}
305304

src/cdk/overlay/overlay-ref.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ export class OverlayRef implements PortalHost {
2929
private _state: OverlayState,
3030
private _ngZone: NgZone) {
3131

32-
_state.scrollStrategy.attach(this);
32+
if (_state.scrollStrategy) {
33+
_state.scrollStrategy.attach(this);
34+
}
3335
}
3436

3537
/** The overlay's HTML element */
@@ -54,7 +56,10 @@ export class OverlayRef implements PortalHost {
5456
this.updateSize();
5557
this.updateDirection();
5658
this.updatePosition();
57-
this._state.scrollStrategy.enable();
59+
60+
if (this._state.scrollStrategy) {
61+
this._state.scrollStrategy.enable();
62+
}
5863

5964
// Enable pointer events for the overlay pane element.
6065
this._togglePointerEvents(true);
@@ -89,7 +94,10 @@ export class OverlayRef implements PortalHost {
8994
// This is necessary because otherwise the pane element will cover the page and disable
9095
// pointer events therefore. Depends on the position strategy and the applied pane boundaries.
9196
this._togglePointerEvents(false);
92-
this._state.scrollStrategy.disable();
97+
98+
if (this._state.scrollStrategy) {
99+
this._state.scrollStrategy.disable();
100+
}
93101

94102
let detachmentResult = this._portalHost.detach();
95103

@@ -107,7 +115,10 @@ export class OverlayRef implements PortalHost {
107115
this._state.positionStrategy.dispose();
108116
}
109117

110-
this._state.scrollStrategy.disable();
118+
if (this._state.scrollStrategy) {
119+
this._state.scrollStrategy.disable();
120+
}
121+
111122
this.detachBackdrop();
112123
this._portalHost.dispose();
113124
this._attachments.complete();

src/cdk/overlay/overlay-state.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ import {NoopScrollStrategy} from './scroll/noop-scroll-strategy';
1818
*/
1919
export class OverlayState {
2020
/** Strategy with which to position the overlay. */
21-
positionStrategy: PositionStrategy;
21+
positionStrategy?: PositionStrategy;
2222

2323
/** Strategy to be used when handling scroll events while the overlay is open. */
24-
scrollStrategy: ScrollStrategy = new NoopScrollStrategy();
24+
scrollStrategy?: ScrollStrategy = new NoopScrollStrategy();
2525

2626
/** Custom class to add to the overlay pane. */
2727
panelClass?: string | string[] = '';
@@ -53,6 +53,12 @@ export class OverlayState {
5353
/** The direction of the text in the overlay panel. */
5454
direction?: Direction = 'ltr';
5555

56+
constructor(state?: OverlayState) {
57+
if (state) {
58+
Object.keys(state).forEach(key => this[key] = state[key]);
59+
}
60+
}
61+
5662
// TODO(jelbourn): configuration still to add
5763
// - focus trap
5864
// - disable pointer events

src/cdk/overlay/overlay.spec.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@ describe('Overlay', () => {
133133
});
134134

135135
it('should set the direction', () => {
136-
const state = new OverlayState();
137-
state.direction = 'rtl';
136+
const state = new OverlayState({direction: 'rtl'});
138137

139138
overlay.create(state).attach(componentPortal);
140139

@@ -153,10 +152,7 @@ describe('Overlay', () => {
153152
});
154153

155154
it('should emit the attachment event after everything is added to the DOM', () => {
156-
let state = new OverlayState();
157-
158-
state.hasBackdrop = true;
159-
155+
let state = new OverlayState({hasBackdrop: true});
160156
let overlayRef = overlay.create(state);
161157

162158
overlayRef.attachments().subscribe(() => {
@@ -415,9 +411,8 @@ describe('Overlay', () => {
415411

416412
describe('panelClass', () => {
417413
it('should apply a custom overlay pane class', () => {
418-
const config = new OverlayState();
414+
const config = new OverlayState({panelClass: 'custom-panel-class'});
419415

420-
config.panelClass = 'custom-panel-class';
421416
overlay.create(config).attach(componentPortal);
422417
viewContainerFixture.detectChanges();
423418

@@ -426,9 +421,8 @@ describe('Overlay', () => {
426421
});
427422

428423
it('should be able to apply multiple classes', () => {
429-
const config = new OverlayState();
424+
const config = new OverlayState({panelClass: ['custom-class-one', 'custom-class-two']});
430425

431-
config.panelClass = ['custom-class-one', 'custom-class-two'];
432426
overlay.create(config).attach(componentPortal);
433427
viewContainerFixture.detectChanges();
434428

@@ -445,8 +439,8 @@ describe('Overlay', () => {
445439
let overlayRef: OverlayRef;
446440

447441
beforeEach(() => {
448-
config = new OverlayState();
449-
fakeScrollStrategy = config.scrollStrategy = new FakeScrollStrategy();
442+
fakeScrollStrategy = new FakeScrollStrategy();
443+
config = new OverlayState({scrollStrategy: fakeScrollStrategy});
450444
overlayRef = overlay.create(config);
451445
});
452446

src/cdk/overlay/scroll/block-scroll-strategy.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ describe('BlockScrollStrategy', () => {
2323
}));
2424

2525
beforeEach(inject([Overlay, ViewportRuler], (overlay: Overlay, viewportRuler: ViewportRuler) => {
26-
let overlayState = new OverlayState();
26+
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.block()});
2727

28-
overlayState.scrollStrategy = overlay.scrollStrategies.block();
2928
overlayRef = overlay.create(overlayState);
3029
componentPortal = new ComponentPortal(FocacciaMsg);
3130

src/cdk/overlay/scroll/close-scroll-strategy.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ describe('CloseScrollStrategy', () => {
3333
}));
3434

3535
beforeEach(inject([Overlay], (overlay: Overlay) => {
36-
let overlayState = new OverlayState();
37-
overlayState.scrollStrategy = overlay.scrollStrategies.close();
36+
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.close()});
3837
overlayRef = overlay.create(overlayState);
3938
componentPortal = new ComponentPortal(MozarellaMsg);
4039
}));

src/cdk/overlay/scroll/reposition-scroll-strategy.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ describe('RepositionScrollStrategy', () => {
3333
}));
3434

3535
beforeEach(inject([Overlay], (overlay: Overlay) => {
36-
let overlayState = new OverlayState();
37-
overlayState.scrollStrategy = overlay.scrollStrategies.reposition();
36+
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.reposition()});
3837
overlayRef = overlay.create(overlayState);
3938
componentPortal = new ComponentPortal(PastaMsg);
4039
}));

src/cdk/overlay/scroll/scroll-strategy.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ scroll strategy, to the `OverlayState`. By default, all overlays will use the `n
1111
doesn't do anything. The other available strategies are `reposition`, `block` and `close`:
1212

1313
```ts
14-
let overlayState = new OverlayState();
14+
let overlayState = new OverlayState({
15+
scrollStrategy: overlay.scrollStrategies.block()
16+
});
1517

16-
overlayState.scrollStrategy = overlay.scrollStrategies.block();
1718
this._overlay.create(overlayState).attach(yourPortal);
1819
```
1920

src/demo-app/overlay/overlay-demo.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,9 @@ export class OverlayDemo {
7474
{originX: 'start', originY: 'bottom'},
7575
{overlayX: 'start', overlayY: 'top'} );
7676

77-
let config = new OverlayState();
78-
config.positionStrategy = strategy;
79-
77+
let config = new OverlayState({positionStrategy: strategy});
8078
let overlayRef = this.overlay.create(config);
79+
8180
overlayRef.attach(new ComponentPortal(SpagettiPanel, this.viewContainerRef));
8281
}
8382

@@ -88,22 +87,18 @@ export class OverlayDemo {
8887
{originX: 'start', originY: 'bottom'},
8988
{overlayX: 'end', overlayY: 'top'} );
9089

91-
let config = new OverlayState();
92-
config.positionStrategy = strategy;
93-
90+
let config = new OverlayState({positionStrategy: strategy});
9491
let overlayRef = this.overlay.create(config);
9592

9693
overlayRef.attach(this.tortelliniTemplate);
9794
}
9895

9996
openPanelWithBackdrop() {
100-
let config = new OverlayState();
101-
102-
config.positionStrategy = this.overlay.position()
103-
.global()
104-
.centerHorizontally();
105-
config.hasBackdrop = true;
106-
config.backdropClass = 'cdk-overlay-transparent-backdrop';
97+
let config = new OverlayState({
98+
hasBackdrop: true,
99+
backdropClass: 'cdk-overlay-transparent-backdrop',
100+
positionStrategy: this.overlay.position().global().centerHorizontally()
101+
});
107102

108103
let overlayRef = this.overlay.create(config);
109104
overlayRef.attach(this.templatePortals.first);

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,12 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
468468
}
469469

470470
private _getOverlayConfig(): OverlayState {
471-
const overlayState = new OverlayState();
472-
overlayState.positionStrategy = this._getOverlayPosition();
473-
overlayState.width = this._getHostWidth();
474-
overlayState.direction = this._dir ? this._dir.value : 'ltr';
475-
overlayState.scrollStrategy = this._scrollStrategy();
476-
return overlayState;
471+
return new OverlayState({
472+
positionStrategy: this._getOverlayPosition(),
473+
scrollStrategy: this._scrollStrategy(),
474+
width: this._getHostWidth(),
475+
direction: this._dir ? this._dir.value : 'ltr'
476+
});
477477
}
478478

479479
private _getOverlayPosition(): PositionStrategy {

src/lib/datepicker/datepicker.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,13 @@ export class MdDatepicker<D> implements OnDestroy {
321321

322322
/** Create the popup. */
323323
private _createPopup(): void {
324-
const overlayState = new OverlayState();
325-
overlayState.positionStrategy = this._createPopupPositionStrategy();
326-
overlayState.hasBackdrop = true;
327-
overlayState.backdropClass = 'md-overlay-transparent-backdrop';
328-
overlayState.direction = this._dir ? this._dir.value : 'ltr';
329-
overlayState.scrollStrategy = this._scrollStrategy();
324+
const overlayState = new OverlayState({
325+
positionStrategy: this._createPopupPositionStrategy(),
326+
hasBackdrop: true,
327+
backdropClass: 'md-overlay-transparent-backdrop',
328+
direction: this._dir ? this._dir.value : 'ltr',
329+
scrollStrategy: this._scrollStrategy()
330+
});
330331

331332
this._popupRef = this._overlay.create(overlayState);
332333
}

src/lib/dialog/dialog.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,19 @@ export class MdDialog {
186186
* @returns The overlay configuration.
187187
*/
188188
private _getOverlayState(dialogConfig: MdDialogConfig): OverlayState {
189-
const overlayState = new OverlayState();
190-
overlayState.panelClass = dialogConfig.panelClass;
191-
overlayState.hasBackdrop = dialogConfig.hasBackdrop;
192-
overlayState.scrollStrategy = this._scrollStrategy();
193-
overlayState.direction = dialogConfig.direction;
189+
const state = new OverlayState({
190+
positionStrategy: this._overlay.position().global(),
191+
scrollStrategy: this._scrollStrategy(),
192+
panelClass: dialogConfig.panelClass,
193+
hasBackdrop: dialogConfig.hasBackdrop,
194+
direction: dialogConfig.direction
195+
});
196+
194197
if (dialogConfig.backdropClass) {
195-
overlayState.backdropClass = dialogConfig.backdropClass;
198+
state.backdropClass = dialogConfig.backdropClass;
196199
}
197-
overlayState.positionStrategy = this._overlay.position().global();
198200

199-
return overlayState;
201+
return state;
200202
}
201203

202204
/**

src/lib/menu/menu-trigger.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,13 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
322322
* @returns OverlayState
323323
*/
324324
private _getOverlayConfig(): OverlayState {
325-
const overlayState = new OverlayState();
326-
overlayState.positionStrategy = this._getPosition();
327-
overlayState.hasBackdrop = !this.triggersSubmenu();
328-
overlayState.backdropClass = 'cdk-overlay-transparent-backdrop';
329-
overlayState.direction = this.dir;
330-
overlayState.scrollStrategy = this._scrollStrategy();
331-
return overlayState;
325+
return new OverlayState({
326+
positionStrategy: this._getPosition(),
327+
hasBackdrop: !this.triggersSubmenu(),
328+
backdropClass: 'cdk-overlay-transparent-backdrop',
329+
direction: this.dir,
330+
scrollStrategy: this._scrollStrategy()
331+
});
332332
}
333333

334334
/**

src/lib/snack-bar/snack-bar.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,11 @@ export class MdSnackBar {
153153
* @param config The user-specified snack bar config.
154154
*/
155155
private _createOverlay(config: MdSnackBarConfig): OverlayRef {
156-
const state = new OverlayState();
157-
state.direction = config.direction;
158-
state.positionStrategy = this._overlay.position().global().centerHorizontally().bottom('0');
156+
const state = new OverlayState({
157+
direction: config.direction,
158+
positionStrategy: this._overlay.position().global().centerHorizontally().bottom('0')
159+
});
160+
159161
return this._overlay.create(state);
160162
}
161163

src/lib/tooltip/tooltip.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,13 @@ export class MdTooltip implements OnDestroy {
279279

280280
/** Create the overlay config and position strategy */
281281
private _createOverlay(): OverlayRef {
282-
let origin = this._getOrigin();
283-
let position = this._getOverlayPosition();
282+
const origin = this._getOrigin();
283+
const position = this._getOverlayPosition();
284284

285285
// Create connected position strategy that listens for scroll events to reposition.
286286
// After position changes occur and the overlay is clipped by a parent scrollable then
287287
// close the tooltip.
288-
let strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
288+
const strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
289289
strategy.withScrollableContainers(this._scrollDispatcher.getScrollContainers(this._elementRef));
290290
strategy.onPositionChange.subscribe(change => {
291291
if (change.scrollableViewProperties.isOverlayClipped &&
@@ -294,12 +294,12 @@ export class MdTooltip implements OnDestroy {
294294
}
295295
});
296296

297-
let config = new OverlayState();
298-
299-
config.direction = this._dir ? this._dir.value : 'ltr';
300-
config.positionStrategy = strategy;
301-
config.panelClass = TOOLTIP_PANEL_CLASS;
302-
config.scrollStrategy = this._scrollStrategy();
297+
const config = new OverlayState({
298+
direction: this._dir ? this._dir.value : 'ltr',
299+
positionStrategy: strategy,
300+
panelClass: TOOLTIP_PANEL_CLASS,
301+
scrollStrategy: this._scrollStrategy()
302+
});
303303

304304
this._overlayRef = this._overlay.create(config);
305305

0 commit comments

Comments
 (0)