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 a60d03642088..4609aaad4349 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts @@ -1927,6 +1927,82 @@ describe('FlexibleConnectedPositionStrategy', () => { expect(Math.floor(overlayRect.bottom)).toBe(Math.floor(originRect.bottom)); }); + it('should position an overlay that is flowing to the left correctly on a page that is ' + + 'scrolled horizontally', () => { + const veryLargeElement: HTMLElement = document.createElement('div'); + veryLargeElement.style.width = '4000px'; + veryLargeElement.style.height = '4000px'; + document.body.appendChild(veryLargeElement); + window.scroll(2100, 0); + + originElement.style.position = 'absolute'; + originElement.style.top = '100px'; + originElement.style.left = '300px'; + + positionStrategy + .withFlexibleDimensions() + .withPush(false) + .withPositions([{ + overlayY: 'top', + overlayX: 'end', + originY: 'top', + originX: 'end' + }]); + + attachOverlay({positionStrategy}); + + const originRect = originElement.getBoundingClientRect(); + const overlayRect = overlayRef.overlayElement.getBoundingClientRect(); + + expect(Math.floor(overlayRect.right)).toBe(Math.floor(originRect.right)); + expect(Math.floor(overlayRect.top)).toBe(Math.floor(originRect.top)); + + window.scroll(0, 0); + document.body.removeChild(veryLargeElement); + }); + + it('should size the bounding box that is flowing to the left correctly on a page that is ' + + 'scrolled horizontally', () => { + const veryLargeElement: HTMLElement = document.createElement('div'); + veryLargeElement.style.width = '4000px'; + veryLargeElement.style.height = '4000px'; + document.body.appendChild(veryLargeElement); + window.scroll(100, 0); + + originElement.style.position = 'absolute'; + originElement.style.top = '100px'; + originElement.style.left = '300px'; + + positionStrategy + .withFlexibleDimensions() + .withPush(false) + .withPositions([{ + overlayY: 'top', + overlayX: 'end', + originY: 'top', + originX: 'end' + }]); + + attachOverlay({positionStrategy}); + + let originRect = originElement.getBoundingClientRect(); + let boundingBoxRect = overlayRef.hostElement.getBoundingClientRect(); + + expect(Math.floor(originRect.right)).toBe(Math.floor(boundingBoxRect.width)); + + window.scroll(200, 0); + overlayRef.updatePosition(); + + originRect = originElement.getBoundingClientRect(); + boundingBoxRect = overlayRef.hostElement.getBoundingClientRect(); + + expect(Math.floor(originRect.right)).toBe(Math.floor(boundingBoxRect.width)); + + window.scroll(0, 0); + document.body.removeChild(veryLargeElement); + }); + + }); 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 5ffae629a00f..d213cf9af07d 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -741,8 +741,8 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { let width: number, left: number, right: number; if (isBoundedByLeftViewportEdge) { - right = viewport.right - origin.x + this._viewportMargin; - width = origin.x - viewport.left; + right = viewport.width - origin.x + this._viewportMargin; + width = origin.x - this._viewportMargin; } else if (isBoundedByRightViewportEdge) { left = origin.x; width = viewport.right - origin.x;