@@ -19,15 +19,12 @@ import {OverlayReference} from '../overlay-reference';
19
19
export class GlobalPositionStrategy implements PositionStrategy {
20
20
/** The overlay to which this strategy is attached. */
21
21
private _overlayRef : OverlayReference ;
22
- private _cssPosition : string = 'static' ;
23
- private _topOffset : string = '' ;
24
- private _bottomOffset : string = '' ;
25
- private _leftOffset : string = '' ;
26
- private _rightOffset : string = '' ;
27
- private _alignItems : string = '' ;
28
- private _justifyContent : string = '' ;
29
22
private _width : string = '' ;
30
23
private _height : string = '' ;
24
+ private _yPosition : 'top' | 'bottom' | 'center' = 'center' ;
25
+ private _yOffset = '' ;
26
+ private _xPosition : 'left' | 'right' | 'start' | 'end' | 'center' = 'center' ;
27
+ private _xOffset = '' ;
31
28
32
29
attach ( overlayRef : OverlayReference ) : void {
33
30
const config = overlayRef . getConfig ( ) ;
@@ -46,46 +43,64 @@ export class GlobalPositionStrategy implements PositionStrategy {
46
43
}
47
44
48
45
/**
49
- * Sets the top position of the overlay. Clears any previously set vertical position .
50
- * @param value New top offset .
46
+ * Positions the overlay to the top of the viewport .
47
+ * @param offset Offset from the top of the viewport .
51
48
*/
52
- top ( value : string = '' ) : this {
53
- this . _bottomOffset = '' ;
54
- this . _topOffset = value ;
55
- this . _alignItems = 'flex-start' ;
49
+ top ( offset : string = '' ) : this {
50
+ this . _yOffset = offset ;
51
+ this . _yPosition = 'top' ;
56
52
return this ;
57
53
}
58
54
59
55
/**
60
- * Sets the left position of the overlay. Clears any previously set horizontal position .
61
- * @param value New left offset .
56
+ * Positions the overlay to the left of the viewport, no matter what layout direction it has .
57
+ * @param offset Offset from the left of the viewport .
62
58
*/
63
- left ( value : string = '' ) : this {
64
- this . _rightOffset = '' ;
65
- this . _leftOffset = value ;
66
- this . _justifyContent = 'flex-start' ;
59
+ left ( offset : string = '' ) : this {
60
+ this . _xOffset = offset ;
61
+ this . _xPosition = 'left' ;
67
62
return this ;
68
63
}
69
64
70
65
/**
71
- * Sets the bottom position of the overlay. Clears any previously set vertical position .
72
- * @param value New bottom offset .
66
+ * Positions the overlay to the bottom of the viewport .
67
+ * @param offset Offset from the bottom of the viewport .
73
68
*/
74
- bottom ( value : string = '' ) : this {
75
- this . _topOffset = '' ;
76
- this . _bottomOffset = value ;
77
- this . _alignItems = 'flex-end' ;
69
+ bottom ( offset : string = '' ) : this {
70
+ this . _yOffset = offset ;
71
+ this . _yPosition = 'bottom' ;
78
72
return this ;
79
73
}
80
74
81
75
/**
82
- * Sets the right position of the overlay. Clears any previously set horizontal position .
83
- * @param value New right offset .
76
+ * Positions the overlay to the right of the viewport, no matter what layout direction it has .
77
+ * @param offset Offset from the right of the viewport .
84
78
*/
85
- right ( value : string = '' ) : this {
86
- this . _leftOffset = '' ;
87
- this . _rightOffset = value ;
88
- this . _justifyContent = 'flex-end' ;
79
+ right ( offset : string = '' ) : this {
80
+ this . _xOffset = offset ;
81
+ this . _xPosition = 'right' ;
82
+ return this ;
83
+ }
84
+
85
+ /**
86
+ * Sets the overlay to the start of the viewport, depending on the overlay direction.
87
+ * This will be to the left in LTR layouts and to the right in RTL.
88
+ * @param offset Offset from the edge of the screen.
89
+ */
90
+ start ( offset : string = '' ) : this {
91
+ this . _xOffset = offset ;
92
+ this . _xPosition = 'start' ;
93
+ return this ;
94
+ }
95
+
96
+ /**
97
+ * Sets the overlay to the end of the viewport, depending on the overlay direction.
98
+ * This will be to the right in LTR layouts and to the left in RTL.
99
+ * @param offset Offset from the edge of the screen.
100
+ */
101
+ end ( offset : string = '' ) : this {
102
+ this . _xOffset = offset ;
103
+ this . _xPosition = 'end' ;
89
104
return this ;
90
105
}
91
106
@@ -122,26 +137,22 @@ export class GlobalPositionStrategy implements PositionStrategy {
122
137
}
123
138
124
139
/**
125
- * Centers the overlay horizontally with an optional offset.
126
- * Clears any previously set horizontal position.
127
- *
128
- * @param offset Overlay offset from the horizontal center.
140
+ * Centers the overlay horizontally in the viewport.
141
+ * @param offset Offset from the center of the viewport.
129
142
*/
130
143
centerHorizontally ( offset : string = '' ) : this {
131
- this . left ( offset ) ;
132
- this . _justifyContent = 'center' ;
144
+ this . _xOffset = offset ;
145
+ this . _xPosition = 'center' ;
133
146
return this ;
134
147
}
135
148
136
149
/**
137
- * Centers the overlay vertically with an optional offset.
138
- * Clears any previously set vertical position.
139
- *
140
- * @param offset Overlay offset from the vertical center.
150
+ * Centers the overlay vertically in the viewport.
151
+ * @param offset Offset from the center of the viewport.
141
152
*/
142
153
centerVertically ( offset : string = '' ) : this {
143
- this . top ( offset ) ;
144
- this . _alignItems = 'center' ;
154
+ this . _yPosition = 'center' ;
155
+ this . _yOffset = offset ;
145
156
return this ;
146
157
}
147
158
@@ -150,42 +161,96 @@ export class GlobalPositionStrategy implements PositionStrategy {
150
161
* @docs -private
151
162
*/
152
163
apply ( ) : void {
153
- // Since the overlay ref applies the strategy asynchronously, it could
154
- // have been disposed before it ends up being applied. If that is the
155
- // case, we shouldn't do anything.
164
+ // Since the overlay ref applies the strategy asynchronously, it could have been
165
+ // disposed before it gets applied. If that is the case, we shouldn't do anything.
156
166
if ( ! this . _overlayRef . hasAttached ( ) ) {
157
167
return ;
158
168
}
159
169
170
+ this . _overlayRef . overlayElement . style . position = 'static' ;
171
+ this . _applyYPosition ( ) ;
172
+ this . _applyXPosition ( ) ;
173
+ }
174
+
175
+ private _applyYPosition ( ) {
160
176
const styles = this . _overlayRef . overlayElement . style ;
161
177
const parentStyles = this . _overlayRef . hostElement . style ;
162
178
const config = this . _overlayRef . getConfig ( ) ;
163
179
164
- styles . position = this . _cssPosition ;
165
- styles . marginLeft = config . width === '100%' ? '0' : this . _leftOffset ;
166
- styles . marginTop = config . height === '100%' ? '0' : this . _topOffset ;
167
- styles . marginBottom = this . _bottomOffset ;
168
- styles . marginRight = this . _rightOffset ;
180
+ if ( config . height === '100%' ) {
181
+ parentStyles . alignItems = 'flex-start' ;
182
+ styles . marginTop = styles . marginBottom = '0' ;
183
+ return ;
184
+ }
185
+
186
+ switch ( this . _yPosition ) {
187
+ case 'top' :
188
+ case 'center' :
189
+ parentStyles . alignItems = this . _yPosition === 'center' ? 'center' : 'flex-start' ;
190
+ styles . marginTop = this . _yOffset ;
191
+ styles . marginBottom = '' ;
192
+ break ;
193
+
194
+ case 'bottom' :
195
+ parentStyles . alignItems = 'flex-end' ;
196
+ styles . marginTop = '' ;
197
+ styles . marginBottom = this . _yOffset ;
198
+ break ;
199
+
200
+ default :
201
+ throw Error ( `Unsupported Y axis position ${ this . _yPosition } .` ) ;
202
+ }
203
+ }
204
+
205
+ private _applyXPosition ( ) {
206
+ const styles = this . _overlayRef . overlayElement . style ;
207
+ const parentStyles = this . _overlayRef . hostElement . style ;
208
+ const config = this . _overlayRef . getConfig ( ) ;
209
+ const isRtl = this . _overlayRef . getConfig ( ) . direction === 'rtl' ;
169
210
170
211
if ( config . width === '100%' ) {
171
212
parentStyles . justifyContent = 'flex-start' ;
172
- } else if ( this . _justifyContent === 'center' ) {
213
+ styles . marginLeft = styles . marginRight = '0' ;
214
+ return ;
215
+ }
216
+
217
+ switch ( this . _xPosition ) {
218
+ // In RTL the browser will invert `flex-start` and `flex-end` automatically, but we don't
219
+ // want that if the positioning is explicitly `left` and `right`, hence why we do another
220
+ // inversion to ensure that the overlay stays in the same position.
221
+ case 'left' :
222
+ parentStyles . justifyContent = isRtl ? 'flex-end' : 'flex-start' ;
223
+ styles . marginLeft = this . _xOffset ;
224
+ styles . marginRight = '' ;
225
+ break ;
226
+
227
+ case 'right' :
228
+ parentStyles . justifyContent = isRtl ? 'flex-start' : 'flex-end' ;
229
+ styles . marginRight = this . _xOffset ;
230
+ styles . marginLeft = '' ;
231
+ break ;
232
+
233
+ case 'center' :
173
234
parentStyles . justifyContent = 'center' ;
174
- } else if ( this . _overlayRef . getConfig ( ) . direction === 'rtl' ) {
175
- // In RTL the browser will invert `flex-start` and `flex-end` automatically, but we
176
- // don't want that because our positioning is explicitly `left` and `right`, hence
177
- // why we do another inversion to ensure that the overlay stays in the same position.
178
- // TODO: reconsider this if we add `start` and `end` methods.
179
- if ( this . _justifyContent === 'flex-start' ) {
180
- parentStyles . justifyContent = 'flex-end' ;
181
- } else if ( this . _justifyContent === 'flex-end' ) {
235
+ styles . marginLeft = isRtl ? '' : this . _xOffset ;
236
+ styles . marginRight = isRtl ? this . _xOffset : '' ;
237
+ break ;
238
+
239
+ case 'start' :
182
240
parentStyles . justifyContent = 'flex-start' ;
183
- }
184
- } else {
185
- parentStyles . justifyContent = this . _justifyContent ;
186
- }
241
+ styles . marginLeft = isRtl ? '' : this . _xOffset ;
242
+ styles . marginRight = isRtl ? this . _xOffset : '' ;
243
+ break ;
244
+
245
+ case 'end' :
246
+ parentStyles . justifyContent = 'flex-end' ;
247
+ styles . marginLeft = isRtl ? this . _xOffset : '' ;
248
+ styles . marginRight = isRtl ? '' : this . _xOffset ;
249
+ break ;
187
250
188
- parentStyles . alignItems = config . height === '100%' ? 'flex-start' : this . _alignItems ;
251
+ default :
252
+ throw Error ( `Unsupported X axis position ${ this . _xPosition } .` ) ;
253
+ }
189
254
}
190
255
191
256
/**
0 commit comments