aboutsummaryrefslogtreecommitdiffstats
path: root/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/core/overlay/position/global-position-strategy.ts
blob: 8e3204a97b2d64ef8a06aa085a3fc550e0be3130 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/* tslint:disable:array-type member-access variable-name typedef
 only-arrow-functions directive-class-suffix component-class-suffix
 component-selector no-unnecessary-type-assertion arrow-parens*/
import {PositionStrategy} from './position-strategy';


/**
 * A strategy for positioning overlays. Using this strategy, an overlay is given
 * an explicit position relative to the browser's viewport. We use flexbox,
 * instead of transforms, in order to avoid issues with subpixel rendering which
 * can cause the element to become blurry.
 */
export class GlobalPositionStrategy implements PositionStrategy {
  private _cssPosition = 'static';
  private _topOffset = '';
  private _bottomOffset = '';
  private _leftOffset = '';
  private _rightOffset = '';
  private _alignItems = '';
  private _justifyContent = '';
  private _width = '';
  private _height = '';

  /* A lazily-created wrapper for the overlay element that is used as a flex
   * container.  */
  private _wrapper: HTMLElement|null = null;

  /**
   * Sets the top position of the overlay. Clears any previously set vertical
   * position.
   * @param value New top offset.
   */
  top(value = ''): this {
	this._bottomOffset = '';
	this._topOffset = value;
	this._alignItems = 'flex-start';
	return this;
  }

  /**
   * Sets the left position of the overlay. Clears any previously set horizontal
   * position.
   * @param value New left offset.
   */
  left(value = ''): this {
	this._rightOffset = '';
	this._leftOffset = value;
	this._justifyContent = 'flex-start';
	return this;
  }

  /**
   * Sets the bottom position of the overlay. Clears any previously set vertical
   * position.
   * @param value New bottom offset.
   */
  bottom(value = ''): this {
	this._topOffset = '';
	this._bottomOffset = value;
	this._alignItems = 'flex-end';
	return this;
  }

  /**
   * Sets the right position of the overlay. Clears any previously set
   * horizontal position.
   * @param value New right offset.
   */
  right(value = ''): this {
	this._leftOffset = '';
	this._rightOffset = value;
	this._justifyContent = 'flex-end';
	return this;
  }

  /**
   * Sets the overlay width and clears any previously set width.
   * @param value New width for the overlay
   */
  width(value = ''): this {
	this._width = value;

    // When the width is 100%, we should reset the `left` and the offset,
    // in order to ensure that the element is flush against the viewport edge.
	if (value === '100%') {
		this.left('0px');
	}

	return this;
  }

  /**
   * Sets the overlay height and clears any previously set height.
   * @param value New height for the overlay
   */
  height(value = ''): this {
	this._height = value;

    // When the height is 100%, we should reset the `top` and the offset,
    // in order to ensure that the element is flush against the viewport edge.
	if (value === '100%') {
		this.top('0px');
	}

	return this;
  }

  /**
   * Centers the overlay horizontally with an optional offset.
   * Clears any previously set horizontal position.
   *
   * @param offset Overlay offset from the horizontal center.
   */
  centerHorizontally(offset = ''): this {
	this.left(offset);
	this._justifyContent = 'center';
	return this;
  }

  /**
   * Centers the overlay vertically with an optional offset.
   * Clears any previously set vertical position.
   *
   * @param offset Overlay offset from the vertical center.
   */
  centerVertically(offset = ''): this {
	this.top(offset);
	this._alignItems = 'center';
	return this;
  }

  /**
   * Apply the position to the element.
   * @docs-private
   *
   * @param element Element to which to apply the CSS.
   * @returns Resolved when the styles have been applied.
   */
  apply(element: HTMLElement): void {
	if (!this._wrapper && element.parentNode) {
		this._wrapper = document.createElement('div');
		this._wrapper.classList.add('cdk-global-overlay-wrapper');
		element.parentNode.insertBefore(this._wrapper, element);
		this._wrapper.appendChild(element);
	}

	const styles = element.style;
	const parentStyles = (element.parentNode as HTMLElement).style;

	styles.position = this._cssPosition;
	styles.marginTop = this._topOffset;
	styles.marginLeft = this._leftOffset;
	styles.marginBottom = this._bottomOffset;
	styles.marginRight = this._rightOffset;
	styles.width = this._width;
	styles.height = this._height;

	parentStyles.justifyContent = this._justifyContent;
	parentStyles.alignItems = this._alignItems;
  }

  /**
   * Removes the wrapper element from the DOM.
   */
  dispose(): void {
	if (this._wrapper && this._wrapper.parentNode) {
		this._wrapper.parentNode.removeChild(this._wrapper);
		this._wrapper = null;
	}
  }
}