-
Notifications
You must be signed in to change notification settings - Fork 6.8k
fix(connected-overlay): better handling of dynamic content #4250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(connected-overlay): better handling of dynamic content #4250
Conversation
44eea9b to
098f44d
Compare
|
This one's ready to go now @jelbourn. |
| // (top, left) coordinate for the overlay at `pos`. | ||
| let originPoint = this._getOriginConnectionPoint(originRect, pos); | ||
| let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, viewportRect, pos); | ||
| let overlayDimensions = this._getCSSDimensions(overlayRect, overlayPoint, pos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's weird to have both overlayPoint and overlayDimensions since they're both kind of the same thing and it would be very easy to use the wrong one.
What if we leave the calculations they way they are now, but then also pass the ConnectionPositionPair and the overlay ClientRect to _setElementPosition which figures out if it should set bottom/right there? I think it might be better, since then you're deferring the calculation until you have to know and don't have to create a type to pass it around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. FWIW, I had it in a separate method, because the logic used to be a bit longer.
| } else { | ||
| element.style[prop] = null; | ||
| } | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than making a bunch of comments trying to communicate what I meant, I just tweaked the source a bit for comments and naming:
private _setElementPosition(
element: HTMLElement,
overlayRect: ClientRect,
overlayPoint: Point,
pos: ConnectionPositionPair) {
const viewport = this._viewportRuler.getViewportRect();
// We want to set either `top` or `bottom` based on whether the overlay wants to appear above
// or below the origin.
let verticalStyleProperty = pos.overlayY === 'bottom' ? 'bottom' : 'top';
// When using `bottom`, we adjust the y position such that it is the distance
// from the bottom of the viewport rather than the top.
let y = verticalStyleProperty === 'top' ?
overlayPoint.y :
viewport.height - (overlayPoint.y + overlayRect.height);
// We want to set either `left` or `right` based on whether the overlay wants to appear "before"
// or "after" the origin. For the horizontal axis, the meaning of "before" and "after" change
// based on whether the page is in RTL or LTR.
let horizontalStyleProperty: string;
if (this._dir === 'rtl') {
horizontalStyleProperty = pos.overlayX === 'end' ? 'left' : 'right';
} else {
horizontalStyleProperty = pos.overlayX === 'end' ? 'right' : 'left';
}
// When we're setting `right`, we adjust the x position such that it is the distance
// from the right edge of the viewport rather than the left edge.
let x = horizontalStyleProperty === 'left' ?
overlayPoint.x :
viewport.width - (overlayPoint.x + overlayRect.width);
// Reset any existing styles. This is necessary in case the preferred position has
// changed since the last `apply`.
['top', 'bottom', 'left', 'right'].forEach(p => { element.style[p] = null; });
element.style[verticalStyleProperty] = y;
element.style[horizontalStyleProperty] = x;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done with some slight tweaks to the comments to mention that the property determines which direction the element will expand to.
99f269b to
607e3a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
607e3a2 to
ae7ebf3
Compare
|
Needs rebase |
* Refactors the `ConnectedPositionStrategy` to be able to use `right` and `bottom` to position the panel. This will allow the element to keep its position automatically, even if the element's size changes. * Removes the uses of the `FakeViewportRuler` in some of the unit tests since it doesn't work very well when the element is positioned relatively to the right edge of the screen. * Rounds down the values when testing positioning. This is necessary, because some browsers (particularly Chrome on Windows) can have some subpixel deviations. Fixes angular#4155.
ae7ebf3 to
ad153c2
Compare
|
Rebased @andrewseguin. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
ConnectedPositionStrategyto be able to userightandbottomto position the panel. This will allow the element to keep its position automatically, even if the element's size changes.FakeViewportRulerin some of the unit tests since it doesn't work very well when the element is positioned relatively to the right edge of the screen.Fixes #4155.