Skip to content

Commit 6469e37

Browse files
committed
fix(overlay): incorrectly calculating centered position on a scrolled page with pushing
Fixes a centered flexible overlay with pushing, on a scrolled page, not calculating the position properly. There were a couple of issues: * We were using the `top` viewport offset to calculate along the X axis, as well as `left` to calculate along Y. * We weren't accounting correctly for the scroll position. Fixes #11868.
1 parent f69f930 commit 6469e37

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,40 @@ describe('FlexibleConnectedPositionStrategy', () => {
17041704
expect(Math.floor(overlayRect.top)).toBe(viewportMargin);
17051705
});
17061706

1707+
it('should center flexible overlay with push on a scrolled page', () => {
1708+
const veryLargeElement = document.createElement('div');
1709+
1710+
originElement.style.left = '200px';
1711+
originElement.style.top = '200px';
1712+
1713+
veryLargeElement.style.width = '100%';
1714+
veryLargeElement.style.height = '2000px';
1715+
document.body.appendChild(veryLargeElement);
1716+
window.scroll(0, 250);
1717+
1718+
positionStrategy
1719+
.withFlexibleDimensions()
1720+
.withPush(true)
1721+
.withPositions([{
1722+
overlayY: 'top',
1723+
overlayX: 'center',
1724+
originY: 'bottom',
1725+
originX: 'center'
1726+
}]);
1727+
1728+
attachOverlay({positionStrategy});
1729+
1730+
const overlayRect = overlayRef.overlayElement.getBoundingClientRect();
1731+
const originRect = originElement.getBoundingClientRect();
1732+
1733+
expect(Math.floor(overlayRect.left - overlayRect.width / 2))
1734+
.toBe(Math.floor(originRect.left - originRect.width / 2));
1735+
1736+
window.scroll(0, 0);
1737+
document.body.removeChild(veryLargeElement);
1738+
});
1739+
1740+
17071741
});
17081742

17091743
describe('onPositionChange with scrollable view properties', () => {

src/cdk/overlay/position/flexible-connected-position-strategy.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,9 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
689689
} else {
690690
// If neither top nor bottom, it means that the overlay
691691
// is vertically centered on the origin point.
692-
const smallestDistanceToViewportEdge =
693-
Math.min(viewport.bottom - origin.y, origin.y - viewport.left);
692+
const smallestDistanceToViewportEdge = Math.min(
693+
viewport.bottom - origin.y + viewport.top, origin.y);
694+
694695
const previousHeight = this._lastBoundingBoxSize.height;
695696

696697
height = smallestDistanceToViewportEdge * 2;
@@ -722,8 +723,8 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
722723
} else {
723724
// If neither start nor end, it means that the overlay
724725
// is horizontally centered on the origin point.
725-
const smallestDistanceToViewportEdge =
726-
Math.min(viewport.right - origin.x, origin.x - viewport.top);
726+
const smallestDistanceToViewportEdge = Math.min(
727+
viewport.right - origin.x + viewport.left, origin.x);
727728
const previousWidth = this._lastBoundingBoxSize.width;
728729

729730
width = smallestDistanceToViewportEdge * 2;

0 commit comments

Comments
 (0)