Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(overlay): add connected position strategy #335

Merged
merged 1 commit into from
May 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
"deploy",
"typings"
],
"headers": [{
"source": "*",
"headers": [{
"key": "Cache-Control",
"value": "no-cache"
}]
}],
"rewrites": [{
"source": "/**/!(*.@(js|ts|html|css|json|svg|png|jpg|jpeg))",
"destination": "/index.html"
Expand Down
17 changes: 15 additions & 2 deletions src/core/overlay/overlay-ref.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import {PortalHost, Portal} from '../portal/portal';
import {OverlayState} from './overlay-state';

/**
* Reference to an overlay that has been created with the Overlay service.
* Used to manipulate or dispose of said overlay.
*/
export class OverlayRef implements PortalHost {
constructor(private _portalHost: PortalHost) { }
constructor(
private _portalHost: PortalHost,
private _pane: HTMLElement,
private _state: OverlayState) { }

attach(portal: Portal<any>): Promise<any> {
return this._portalHost.attach(portal);
return this._portalHost.attach(portal).then(() => {
this._updatePosition();
});
}

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

/** Updates the position of the overlay based on the position strategy. */
private _updatePosition() {
if (this._state.positionStrategy) {
this._state.positionStrategy.apply(this._pane);
}
}

// TODO(jelbourn): add additional methods for manipulating the overlay.
}
1 change: 1 addition & 0 deletions src/core/overlay/overlay.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
.md-overlay-pane {
position: absolute;
pointer-events: auto;
box-sizing: border-box;
}
4 changes: 4 additions & 0 deletions src/core/overlay/overlay.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {Overlay, OVERLAY_CONTAINER_TOKEN} from './overlay';
import {OverlayRef} from './overlay-ref';
import {OverlayState} from './overlay-state';
import {PositionStrategy} from './position/position-strategy';
import {OverlayPositionBuilder} from './position/overlay-position-builder';
import {ViewportRuler} from './position/viewport-ruler';


export function main() {
Expand All @@ -32,6 +34,8 @@ export function main() {

beforeEachProviders(() => [
Overlay,
OverlayPositionBuilder,
ViewportRuler,
provide(OVERLAY_CONTAINER_TOKEN, {useFactory: () => {
overlayContainerElement = document.createElement('div');
return overlayContainerElement;
Expand Down
58 changes: 19 additions & 39 deletions src/core/overlay/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import {
OpaqueToken,
Inject,
Injectable,
ElementRef
} from '@angular/core';
import {OverlayState} from './overlay-state';
import {DomPortalHost} from '../portal/dom-portal-host';
import {OverlayRef} from './overlay-ref';
import {GlobalPositionStrategy} from './position/global-position-strategy';
import {RelativePositionStrategy} from './position/relative-position-strategy';

import {OverlayPositionBuilder} from './position/overlay-position-builder';
import {ViewportRuler} from './position/viewport-ruler';


// Re-export overlay-related modules so they can be imported directly from here.
Expand Down Expand Up @@ -39,7 +39,8 @@ let defaultState = new OverlayState();
export class Overlay {
constructor(
@Inject(OVERLAY_CONTAINER_TOKEN) private _overlayContainerElement: HTMLElement,
private _dynamicComponentLoader: DynamicComponentLoader) {
private _dynamicComponentLoader: DynamicComponentLoader,
private _positionBuilder: OverlayPositionBuilder) {
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single line for { } for consistency?


/**
Expand All @@ -48,44 +49,31 @@ export class Overlay {
* @returns A reference to the created overlay.
*/
create(state: OverlayState = defaultState): Promise<OverlayRef> {
return this._createPaneElement(state).then(pane => this._createOverlayRef(pane));
return this._createPaneElement().then(pane => this._createOverlayRef(pane, state));
}

/**
* Returns a position builder that can be used, via fluent API,
* to construct and configure a position strategy.
*/
position() {
return POSITION_BUILDER;
return this._positionBuilder;
}

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

this.applyState(pane, state);
this._overlayContainerElement.appendChild(pane);

return Promise.resolve(pane);
}

/**
* Applies a given state to the given pane element.
* @param pane The pane to modify.
* @param state The state to apply.
*/
applyState(pane: HTMLElement, state: OverlayState) {
if (state.positionStrategy != null) {
state.positionStrategy.apply(pane);
}
}

/**
* Create a DomPortalHost into which the overlay content can be loaded.
* @param pane The DOM element to turn into a portal host.
Expand All @@ -100,26 +88,18 @@ export class Overlay {
/**
* Creates an OverlayRef for an overlay in the given DOM element.
* @param pane DOM element for the overlay
* @param state
* @returns {OverlayRef}
*/
private _createOverlayRef(pane: HTMLElement): OverlayRef {
return new OverlayRef(this._createPortalHost(pane));
private _createOverlayRef(pane: HTMLElement, state: OverlayState): OverlayRef {
return new OverlayRef(this._createPortalHost(pane), pane, state);
}
}


/** Builder for overlay position strategy. */
export class OverlayPositionBuilder {
/** Creates a global position strategy. */
global() {
return new GlobalPositionStrategy();
}

/** Creates a relative position strategy. */
relativeTo(elementRef: ElementRef) {
return new RelativePositionStrategy(elementRef);
}
}

// We only ever need one position builder.
let POSITION_BUILDER: OverlayPositionBuilder = new OverlayPositionBuilder();
/** Providers for Overlay and its related injectables. */
export const OVERLAY_PROVIDERS = [
ViewportRuler,
OverlayPositionBuilder,
Overlay,
];
Loading