Skip to content

Commit 607e3a2

Browse files
committed
refactor: move new logic into _setElementPosition method
1 parent 098f44d commit 607e3a2

File tree

1 file changed

+44
-55
lines changed

1 file changed

+44
-55
lines changed

src/lib/core/overlay/position/connected-position-strategy.ts

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,10 @@ export class ConnectedPositionStrategy implements PositionStrategy {
117117
// (top, left) coordinate for the overlay at `pos`.
118118
let originPoint = this._getOriginConnectionPoint(originRect, pos);
119119
let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, viewportRect, pos);
120-
let overlayDimensions = this._getCSSDimensions(overlayRect, overlayPoint, pos);
121120

122121
// If the overlay in the calculated position fits on-screen, put it there and we're done.
123122
if (overlayPoint.fitsInViewport) {
124-
this._setElementPosition(element, overlayDimensions);
123+
this._setElementPosition(element, overlayRect, overlayPoint, pos);
125124

126125
// Save the last connected position in case the position needs to be re-calculated.
127126
this._lastConnectedPosition = pos;
@@ -140,8 +139,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
140139

141140
// If none of the preferred positions were in the viewport, take the one
142141
// with the largest visible area.
143-
let fallbackDimensions = this._getCSSDimensions(overlayRect, fallbackPoint, fallbackPosition);
144-
this._setElementPosition(element, fallbackDimensions);
142+
this._setElementPosition(element, overlayRect, fallbackPoint, fallbackPosition);
145143

146144
return Promise.resolve(null);
147145
}
@@ -159,8 +157,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
159157

160158
let originPoint = this._getOriginConnectionPoint(originRect, lastPosition);
161159
let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, viewportRect, lastPosition);
162-
let overlayPosition = this._getCSSDimensions(overlayRect, overlayPoint, lastPosition);
163-
this._setElementPosition(this._pane, overlayPosition);
160+
this._setElementPosition(this._pane, overlayRect, overlayPoint, lastPosition);
164161
}
165162

166163
/**
@@ -304,39 +301,6 @@ export class ConnectedPositionStrategy implements PositionStrategy {
304301
return {x, y, fitsInViewport, visibleArea};
305302
}
306303

307-
/**
308-
* Determines which CSS properties to use when positioning the overlay,
309-
* depending on the direction the element would expand in, if extra content
310-
* was added.
311-
*/
312-
private _getCSSDimensions(overlayRect: ClientRect, overlayPoint: Point,
313-
pos: ConnectionPositionPair): CSSDimensionPair {
314-
315-
const viewport = this._viewportRuler.getViewportRect();
316-
const x: CSSDimension = { property: null, value: null };
317-
const y: CSSDimension = { property: pos.overlayY === 'bottom' ? 'bottom' : 'top', value: null };
318-
319-
if (this._dir === 'rtl') {
320-
x.property = pos.overlayX === 'end' ? 'left' : 'right';
321-
} else {
322-
x.property = pos.overlayX === 'end' ? 'right' : 'left';
323-
}
324-
325-
if (x.property === 'left') {
326-
x.value = overlayPoint.x;
327-
} else {
328-
x.value = viewport.width - (overlayPoint.x + overlayRect.width);
329-
}
330-
331-
if (y.property === 'top') {
332-
y.value = overlayPoint.y;
333-
} else {
334-
y.value = viewport.height - (overlayPoint.y + overlayRect.height);
335-
}
336-
337-
return {x, y};
338-
}
339-
340304
/**
341305
* Gets the view properties of the trigger and overlay, including whether they are clipped
342306
* or completely outside the view of any of the strategy's scrollables.
@@ -385,10 +349,47 @@ export class ConnectedPositionStrategy implements PositionStrategy {
385349
}
386350

387351
/** Physically positions the overlay element to the given coordinate. */
388-
private _setElementPosition(element: HTMLElement, dimensions: CSSDimensionPair) {
389-
['top', 'bottom', 'left', 'right'].forEach(prop => element.style[prop] = null);
390-
element.style[dimensions.x.property] = dimensions.x.value + 'px';
391-
element.style[dimensions.y.property] = dimensions.y.value + 'px';
352+
private _setElementPosition(
353+
element: HTMLElement,
354+
overlayRect: ClientRect,
355+
overlayPoint: Point,
356+
pos: ConnectionPositionPair) {
357+
const viewport = this._viewportRuler.getViewportRect();
358+
359+
// We want to set either `top` or `bottom` based on whether the overlay wants to appear above
360+
// or below the origin and the direction in which the element will expand.
361+
let verticalStyleProperty = pos.overlayY === 'bottom' ? 'bottom' : 'top';
362+
363+
// When using `bottom`, we adjust the y position such that it is the distance
364+
// from the bottom of the viewport rather than the top.
365+
let y = verticalStyleProperty === 'top' ?
366+
overlayPoint.y :
367+
viewport.height - (overlayPoint.y + overlayRect.height);
368+
369+
// We want to set either `left` or `right` based on whether the overlay wants to appear "before"
370+
// or "after" the origin, which determines the direction in which the element will expand.
371+
// For the horizontal axis, the meaning of "before" and "after" change based on whether the
372+
// page is in RTL or LTR.
373+
let horizontalStyleProperty: string;
374+
if (this._dir === 'rtl') {
375+
horizontalStyleProperty = pos.overlayX === 'end' ? 'left' : 'right';
376+
} else {
377+
horizontalStyleProperty = pos.overlayX === 'end' ? 'right' : 'left';
378+
}
379+
380+
// When we're setting `right`, we adjust the x position such that it is the distance
381+
// from the right edge of the viewport rather than the left edge.
382+
let x = horizontalStyleProperty === 'left' ?
383+
overlayPoint.x :
384+
viewport.width - (overlayPoint.x + overlayRect.width);
385+
386+
387+
// Reset any existing styles. This is necessary in case the preferred position has
388+
// changed since the last `apply`.
389+
['top', 'bottom', 'left', 'right'].forEach(p => element.style[p] = null);
390+
391+
element.style[verticalStyleProperty] = y;
392+
element.style[horizontalStyleProperty] = x;
392393
}
393394

394395
/** Returns the bounding positions of the provided element with respect to the viewport. */
@@ -427,15 +428,3 @@ interface OverlayPoint extends Point {
427428
visibleArea?: number;
428429
fitsInViewport?: boolean;
429430
}
430-
431-
/** Key-value pair, representing a CSS dimension. */
432-
interface CSSDimension {
433-
property: 'top' | 'bottom' | 'left' | 'right';
434-
value: number;
435-
}
436-
437-
/** A combination of CSS dimensions for the x and y axis. */
438-
interface CSSDimensionPair {
439-
x: CSSDimension;
440-
y: CSSDimension;
441-
}

0 commit comments

Comments
 (0)