Skip to content

Commit 8bb60ad

Browse files
committed
feat(overlay): add connected position strategy
1 parent 320329b commit 8bb60ad

19 files changed

+849
-68
lines changed

firebase.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
"deploy",
1010
"typings"
1111
],
12+
"headers": [{
13+
"source": "*",
14+
"headers": [{
15+
"key": "Cache-Control",
16+
"value": "no-cache"
17+
}]
18+
}],
1219
"rewrites": [{
1320
"source": "/**/!(*.@(js|ts|html|css|json|svg|png|jpg|jpeg))",
1421
"destination": "/index.html"

src/core/overlay/overlay-ref.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import {PortalHost, Portal} from '../portal/portal';
2+
import {OverlayState} from './overlay-state';
23

34
/**
45
* Reference to an overlay that has been created with the Overlay service.
56
* Used to manipulate or dispose of said overlay.
67
*/
78
export class OverlayRef implements PortalHost {
8-
constructor(private _portalHost: PortalHost) { }
9+
constructor(
10+
private _portalHost: PortalHost,
11+
private _pane: HTMLElement,
12+
private _state: OverlayState) { }
913

1014
attach(portal: Portal<any>): Promise<any> {
11-
return this._portalHost.attach(portal);
15+
return this._portalHost.attach(portal).then(() => {
16+
this._updatePosition();
17+
});
1218
}
1319

1420
detach(): Promise<any> {
@@ -23,5 +29,12 @@ export class OverlayRef implements PortalHost {
2329
return this._portalHost.hasAttached();
2430
}
2531

32+
/** Updates the position of the overlay based on the position strategy. */
33+
private _updatePosition() {
34+
if (this._state.positionStrategy) {
35+
this._state.positionStrategy.apply(this._pane);
36+
}
37+
}
38+
2639
// TODO(jelbourn): add additional methods for manipulating the overlay.
2740
}

src/core/overlay/overlay.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
.md-overlay-pane {
1717
position: absolute;
1818
pointer-events: auto;
19+
box-sizing: border-box;
1920
}

src/core/overlay/overlay.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {Overlay, OVERLAY_CONTAINER_TOKEN} from './overlay';
2121
import {OverlayRef} from './overlay-ref';
2222
import {OverlayState} from './overlay-state';
2323
import {PositionStrategy} from './position/position-strategy';
24+
import {OverlayPositionBuilder} from './position/overlay-position-builder';
25+
import {ViewportRuler} from './position/viewport-ruler';
2426

2527

2628
export function main() {
@@ -33,6 +35,8 @@ export function main() {
3335

3436
beforeEachProviders(() => [
3537
Overlay,
38+
OverlayPositionBuilder,
39+
ViewportRuler,
3640
provide(OVERLAY_CONTAINER_TOKEN, {useFactory: () => {
3741
overlayContainerElement = document.createElement('div');
3842
return overlayContainerElement;

src/core/overlay/overlay.ts

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {
44
OpaqueToken,
55
Inject,
66
Injectable,
7-
ElementRef
87
} from 'angular2/core';
98
import {OverlayState} from './overlay-state';
109
import {DomPortalHost} from '../portal/dom-portal-host';
1110
import {OverlayRef} from './overlay-ref';
12-
import {GlobalPositionStrategy} from './position/global-position-strategy';
13-
import {RelativePositionStrategy} from './position/relative-position-strategy';
11+
12+
import {OverlayPositionBuilder} from './position/overlay-position-builder';
13+
import {ViewportRuler} from './position/viewport-ruler';
1414

1515

1616
// Re-export overlay-related modules so they can be imported directly from here.
@@ -41,7 +41,8 @@ export class Overlay {
4141
constructor(
4242
@Inject(OVERLAY_CONTAINER_TOKEN) private _overlayContainerElement: HTMLElement,
4343
private _dynamicComponentLoader: DynamicComponentLoader,
44-
private _appViewManager: AppViewManager) {
44+
private _appViewManager: AppViewManager,
45+
private _positionBuilder: OverlayPositionBuilder) {
4546
}
4647

4748
/**
@@ -50,44 +51,31 @@ export class Overlay {
5051
* @returns A reference to the created overlay.
5152
*/
5253
create(state: OverlayState = defaultState): Promise<OverlayRef> {
53-
return this._createPaneElement(state).then(pane => this._createOverlayRef(pane));
54+
return this._createPaneElement().then(pane => this._createOverlayRef(pane, state));
5455
}
5556

5657
/**
5758
* Returns a position builder that can be used, via fluent API,
5859
* to construct and configure a position strategy.
5960
*/
6061
position() {
61-
return POSITION_BUILDER;
62+
return this._positionBuilder;
6263
}
6364

6465
/**
65-
* Creates the DOM element for an overlay.
66-
* @param state State to apply to the created element.
66+
* Creates the DOM element for an overlay and appends it to the overlay container.
6767
* @returns Promise resolving to the created element.
6868
*/
69-
private _createPaneElement(state: OverlayState): Promise<HTMLElement> {
69+
private _createPaneElement(): Promise<HTMLElement> {
7070
var pane = document.createElement('div');
71-
pane.id = `md-overlay-${nextUniqueId++}`;
71+
pane.id = `md-overlay-${nextUniqueId++}`;
7272
pane.classList.add('md-overlay-pane');
7373

74-
this.applyState(pane, state);
7574
this._overlayContainerElement.appendChild(pane);
7675

7776
return Promise.resolve(pane);
7877
}
7978

80-
/**
81-
* Applies a given state to the given pane element.
82-
* @param pane The pane to modify.
83-
* @param state The state to apply.
84-
*/
85-
applyState(pane: HTMLElement, state: OverlayState) {
86-
if (state.positionStrategy != null) {
87-
state.positionStrategy.apply(pane);
88-
}
89-
}
90-
9179
/**
9280
* Create a DomPortalHost into which the overlay content can be loaded.
9381
* @param pane The DOM element to turn into a portal host.
@@ -103,26 +91,18 @@ export class Overlay {
10391
/**
10492
* Creates an OverlayRef for an overlay in the given DOM element.
10593
* @param pane DOM element for the overlay
94+
* @param state
10695
* @returns {OverlayRef}
10796
*/
108-
private _createOverlayRef(pane: HTMLElement): OverlayRef {
109-
return new OverlayRef(this._createPortalHost(pane));
97+
private _createOverlayRef(pane: HTMLElement, state: OverlayState): OverlayRef {
98+
return new OverlayRef(this._createPortalHost(pane), pane, state);
11099
}
111100
}
112101

113102

114-
/** Builder for overlay position strategy. */
115-
export class OverlayPositionBuilder {
116-
/** Creates a global position strategy. */
117-
global() {
118-
return new GlobalPositionStrategy();
119-
}
120-
121-
/** Creates a relative position strategy. */
122-
relativeTo(elementRef: ElementRef) {
123-
return new RelativePositionStrategy(elementRef);
124-
}
125-
}
126-
127-
// We only ever need one position builder.
128-
let POSITION_BUILDER: OverlayPositionBuilder = new OverlayPositionBuilder();
103+
/** Providers for Overlay and its related injectables. */
104+
export const OVERLAY_PROVIDERS = [
105+
ViewportRuler,
106+
OverlayPositionBuilder,
107+
Overlay,
108+
];

0 commit comments

Comments
 (0)