Skip to content

Commit a306a8e

Browse files
crisbetommalerba
authored andcommitted
fix(connected-position): error if none of the initial positions fit in viewport (#3189)
Fixes an error in the `recalculateLastPosition` method that gets thrown if none of the element's positions fit inside the viewport. These changes default to the first preferred position, if there was no previously-matched position. Relates #3183.
1 parent f8fde13 commit a306a8e

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,32 @@ describe('ConnectedPositionStrategy', () => {
261261
'Expected overlay to be re-aligned to the trigger in the previous position.');
262262
});
263263

264+
it('should default to the initial position, if no positions fit in the viewport', () => {
265+
// Use the fake viewport ruler because we don't know *exactly* how big the viewport is.
266+
fakeViewportRuler.fakeRect = {
267+
top: 0, left: 0, width: 500, height: 500, right: 500, bottom: 500
268+
};
269+
positionBuilder = new OverlayPositionBuilder(fakeViewportRuler);
270+
271+
// Make the origin element taller than the viewport.
272+
originElement.style.height = '1000px';
273+
originElement.style.top = '0';
274+
originRect = originElement.getBoundingClientRect();
275+
276+
strategy = positionBuilder.connectedTo(
277+
fakeElementRef,
278+
{originX: 'start', originY: 'top'},
279+
{overlayX: 'start', overlayY: 'bottom'});
280+
281+
strategy.apply(overlayElement);
282+
strategy.recalculateLastPosition();
283+
284+
let overlayRect = overlayElement.getBoundingClientRect();
285+
286+
expect(overlayRect.bottom).toBe(originRect.top,
287+
'Expected overlay to be re-aligned to the trigger in the initial position.');
288+
});
289+
264290
it('should position a panel properly when rtl', () => {
265291
// must make the overlay longer than the origin to properly test attachment
266292
overlayElement.style.width = `500px`;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ export class ConnectedPositionStrategy implements PositionStrategy {
151151
const originRect = this._origin.getBoundingClientRect();
152152
const overlayRect = this._pane.getBoundingClientRect();
153153
const viewportRect = this._viewportRuler.getViewportRect();
154+
const lastPosition = this._lastConnectedPosition || this._preferredPositions[0];
154155

155-
let originPoint = this._getOriginConnectionPoint(originRect, this._lastConnectedPosition);
156-
let overlayPoint =
157-
this._getOverlayPoint(originPoint, overlayRect, viewportRect, this._lastConnectedPosition);
156+
let originPoint = this._getOriginConnectionPoint(originRect, lastPosition);
157+
let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, viewportRect, lastPosition);
158158
this._setElementPosition(this._pane, overlayPoint);
159159
}
160160

0 commit comments

Comments
 (0)