mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(overlay): incorrectly calculating centered position on a scrolled page with pushing (#13185)
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.
This commit is contained in:
committed by
vivian-hu
parent
38e7dd24cf
commit
f5dd24aab5
@@ -1744,6 +1744,40 @@ describe('FlexibleConnectedPositionStrategy', () => {
|
||||
expect(Math.floor(overlayRect.top)).toBe(viewportMargin);
|
||||
});
|
||||
|
||||
it('should center flexible overlay with push on a scrolled page', () => {
|
||||
const veryLargeElement = document.createElement('div');
|
||||
|
||||
originElement.style.left = '200px';
|
||||
originElement.style.top = '200px';
|
||||
|
||||
veryLargeElement.style.width = '100%';
|
||||
veryLargeElement.style.height = '2000px';
|
||||
document.body.appendChild(veryLargeElement);
|
||||
window.scroll(0, 250);
|
||||
|
||||
positionStrategy
|
||||
.withFlexibleDimensions()
|
||||
.withPush(true)
|
||||
.withPositions([{
|
||||
overlayY: 'top',
|
||||
overlayX: 'center',
|
||||
originY: 'bottom',
|
||||
originX: 'center'
|
||||
}]);
|
||||
|
||||
attachOverlay({positionStrategy});
|
||||
|
||||
const overlayRect = overlayRef.overlayElement.getBoundingClientRect();
|
||||
const originRect = originElement.getBoundingClientRect();
|
||||
|
||||
expect(Math.floor(overlayRect.left - overlayRect.width / 2))
|
||||
.toBe(Math.floor(originRect.left - originRect.width / 2));
|
||||
|
||||
window.scroll(0, 0);
|
||||
document.body.removeChild(veryLargeElement);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('onPositionChange with scrollable view properties', () => {
|
||||
|
||||
@@ -718,10 +718,13 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
|
||||
bottom = viewport.height - origin.y + this._viewportMargin * 2;
|
||||
height = viewport.height - bottom + this._viewportMargin;
|
||||
} else {
|
||||
// If neither top nor bottom, it means that the overlay
|
||||
// is vertically centered on the origin point.
|
||||
// If neither top nor bottom, it means that the overlay is vertically centered on the
|
||||
// origin point. Note that we want the position relative to the viewport, rather than
|
||||
// the page, which is why we don't use something like `viewport.bottom - origin.y` and
|
||||
// `origin.y - viewport.top`.
|
||||
const smallestDistanceToViewportEdge =
|
||||
Math.min(viewport.bottom - origin.y, origin.y - viewport.left);
|
||||
Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
|
||||
|
||||
const previousHeight = this._lastBoundingBoxSize.height;
|
||||
|
||||
height = smallestDistanceToViewportEdge * 2;
|
||||
@@ -751,10 +754,12 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
|
||||
left = origin.x;
|
||||
width = viewport.right - origin.x;
|
||||
} else {
|
||||
// If neither start nor end, it means that the overlay
|
||||
// is horizontally centered on the origin point.
|
||||
// If neither start nor end, it means that the overlay is horizontally centered on the
|
||||
// origin point. Note that we want the position relative to the viewport, rather than
|
||||
// the page, which is why we don't use something like `viewport.right - origin.x` and
|
||||
// `origin.x - viewport.left`.
|
||||
const smallestDistanceToViewportEdge =
|
||||
Math.min(viewport.right - origin.x, origin.x - viewport.top);
|
||||
Math.min(viewport.right - origin.x + viewport.left, origin.x);
|
||||
const previousWidth = this._lastBoundingBoxSize.width;
|
||||
|
||||
width = smallestDistanceToViewportEdge * 2;
|
||||
|
||||
Reference in New Issue
Block a user