From cd72c9dc856ab25151ff9949b839ddb73839ca39 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 30 Jan 2019 22:59:54 +0100 Subject: [PATCH] fix(overlay): unnecessarily pushing overlay if it is exactly as wide as the viewport (#14975) Fixes the flexible position strategy pushing the overlay when it doesn't have to, if it's exactly as wide as the viewport. Fixes #14968. --- ...exible-connected-position-strategy.spec.ts | 58 +++++++++++++++++++ .../flexible-connected-position-strategy.ts | 4 +- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts index 2925191c49d..cd9c152be74 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts @@ -1261,6 +1261,9 @@ describe('FlexibleConnectedPositionStrategy', () => { ]); attachOverlay({ + // Set a large max-width to override the one that comes from the + // overlay structural styles. Otherwise the `width` will stop at the viewport width. + maxWidth: '200vw', width: viewport.getViewportRect().width + 100, positionStrategy }); @@ -1292,6 +1295,9 @@ describe('FlexibleConnectedPositionStrategy', () => { ]); attachOverlay({ + // Set a large max-width to override the one that comes from the + // overlay structural styles. Otherwise the `width` will stop at the viewport width. + maxWidth: '200vw', width: viewport.getViewportRect().width + 100, positionStrategy }); @@ -1869,6 +1875,58 @@ describe('FlexibleConnectedPositionStrategy', () => { document.body.removeChild(veryLargeElement); }); + it('should not push the overlay if it is exactly as wide as the viewport', () => { + originElement.style.position = 'fixed'; + originElement.style.top = '100px'; + originElement.style.right = '0'; + + positionStrategy + .withFlexibleDimensions() + .withPush(true) + .withPositions([{ + originX: 'center', + originY: 'bottom', + overlayX: 'center', + overlayY: 'top', + }]); + + attachOverlay({ + width: viewport.getViewportRect().width, + positionStrategy + }); + + const originRect = originElement.getBoundingClientRect(); + const overlayRect = overlayRef.overlayElement.getBoundingClientRect(); + + expect(Math.floor(overlayRect.right)).toBe(Math.floor(originRect.right)); + }); + + it('should not push the overlay if it is exactly as tall as the viewport', () => { + originElement.style.position = 'fixed'; + originElement.style.left = '100px'; + originElement.style.bottom = '0'; + + positionStrategy + .withFlexibleDimensions() + .withPush(true) + .withPositions([{ + originX: 'start', + originY: 'bottom', + overlayX: 'start', + overlayY: 'bottom', + }]); + + attachOverlay({ + width: viewport.getViewportRect().height, + positionStrategy + }); + + const originRect = originElement.getBoundingClientRect(); + const overlayRect = overlayRef.overlayElement.getBoundingClientRect(); + + expect(Math.floor(overlayRect.bottom)).toBe(Math.floor(originRect.bottom)); + }); + }); describe('onPositionChange with scrollable view properties', () => { diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.ts index ce83075ab35..7915de81562 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -630,13 +630,13 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { // If the overlay fits completely within the bounds of the viewport, push it from whichever // direction is goes off-screen. Otherwise, push the top-left corner such that its in the // viewport and allow for the trailing end of the overlay to go out of bounds. - if (overlay.width < viewport.width) { + if (overlay.width <= viewport.width) { pushX = overflowLeft || -overflowRight; } else { pushX = start.x < this._viewportMargin ? (viewport.left - scrollPosition.left) - start.x : 0; } - if (overlay.height < viewport.height) { + if (overlay.height <= viewport.height) { pushY = overflowTop || -overflowBottom; } else { pushY = start.y < this._viewportMargin ? (viewport.top - scrollPosition.top) - start.y : 0;