3 * Copyright Google Inc. All Rights Reserved.
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
8 /* tslint:disable:array-type member-access variable-name typedef
9 only-arrow-functions directive-class-suffix component-class-suffix
10 component-selector no-unnecessary-type-assertion arrow-parens*/
11 import {PositionStrategy} from './position-strategy';
15 * A strategy for positioning overlays. Using this strategy, an overlay is given
16 * an explicit position relative to the browser's viewport. We use flexbox,
17 * instead of transforms, in order to avoid issues with subpixel rendering which
18 * can cause the element to become blurry.
20 export class GlobalPositionStrategy implements PositionStrategy {
21 private _cssPosition = 'static';
22 private _topOffset = '';
23 private _bottomOffset = '';
24 private _leftOffset = '';
25 private _rightOffset = '';
26 private _alignItems = '';
27 private _justifyContent = '';
31 /* A lazily-created wrapper for the overlay element that is used as a flex
33 private _wrapper: HTMLElement|null = null;
36 * Sets the top position of the overlay. Clears any previously set vertical
38 * @param value New top offset.
40 top(value = ''): this {
41 this._bottomOffset = '';
42 this._topOffset = value;
43 this._alignItems = 'flex-start';
48 * Sets the left position of the overlay. Clears any previously set horizontal
50 * @param value New left offset.
52 left(value = ''): this {
53 this._rightOffset = '';
54 this._leftOffset = value;
55 this._justifyContent = 'flex-start';
60 * Sets the bottom position of the overlay. Clears any previously set vertical
62 * @param value New bottom offset.
64 bottom(value = ''): this {
66 this._bottomOffset = value;
67 this._alignItems = 'flex-end';
72 * Sets the right position of the overlay. Clears any previously set
73 * horizontal position.
74 * @param value New right offset.
76 right(value = ''): this {
77 this._leftOffset = '';
78 this._rightOffset = value;
79 this._justifyContent = 'flex-end';
84 * Sets the overlay width and clears any previously set width.
85 * @param value New width for the overlay
87 width(value = ''): this {
90 // When the width is 100%, we should reset the `left` and the offset,
91 // in order to ensure that the element is flush against the viewport edge.
92 if (value === '100%') {
100 * Sets the overlay height and clears any previously set height.
101 * @param value New height for the overlay
103 height(value = ''): this {
104 this._height = value;
106 // When the height is 100%, we should reset the `top` and the offset,
107 // in order to ensure that the element is flush against the viewport edge.
108 if (value === '100%') {
116 * Centers the overlay horizontally with an optional offset.
117 * Clears any previously set horizontal position.
119 * @param offset Overlay offset from the horizontal center.
121 centerHorizontally(offset = ''): this {
123 this._justifyContent = 'center';
128 * Centers the overlay vertically with an optional offset.
129 * Clears any previously set vertical position.
131 * @param offset Overlay offset from the vertical center.
133 centerVertically(offset = ''): this {
135 this._alignItems = 'center';
140 * Apply the position to the element.
143 * @param element Element to which to apply the CSS.
144 * @returns Resolved when the styles have been applied.
146 apply(element: HTMLElement): void {
147 if (!this._wrapper && element.parentNode) {
148 this._wrapper = document.createElement('div');
149 this._wrapper.classList.add('cdk-global-overlay-wrapper');
150 element.parentNode.insertBefore(this._wrapper, element);
151 this._wrapper.appendChild(element);
154 const styles = element.style;
155 const parentStyles = (element.parentNode as HTMLElement).style;
157 styles.position = this._cssPosition;
158 styles.marginTop = this._topOffset;
159 styles.marginLeft = this._leftOffset;
160 styles.marginBottom = this._bottomOffset;
161 styles.marginRight = this._rightOffset;
162 styles.width = this._width;
163 styles.height = this._height;
165 parentStyles.justifyContent = this._justifyContent;
166 parentStyles.alignItems = this._alignItems;
170 * Removes the wrapper element from the DOM.
173 if (this._wrapper && this._wrapper.parentNode) {
174 this._wrapper.parentNode.removeChild(this._wrapper);
175 this._wrapper = null;