Skip to content
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(cdk/overlay): vertical positioning of flexible connected overlay on mobile #28425

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -144,6 +144,9 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
return this._preferredPositions;
}

/** Scrollbar width */
private _scrollbarWidth = 0;

constructor(
connectedTo: FlexibleConnectedPositionStrategyOrigin,
private _viewportRuler: ViewportRuler,
Expand Down Expand Up @@ -974,6 +977,26 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
extendStyles(this._pane.style, styles);
}

/** Get width scrollbar */
private _getScrollbarWidth(): number {
if (this._scrollbarWidth > 0) {
return this._scrollbarWidth;
}

const div = this._document.createElement('div');

div.style.overflowY = 'scroll';
div.style.width = '50px';
div.style.height = '50px';

this._document.body.append(div);
this._scrollbarWidth = div.offsetWidth - div.clientWidth;

div.remove();

return this._scrollbarWidth;
}

/** Gets the exact top/bottom for the overlay when not using flexible sizing or when pushing. */
private _getExactOverlayY(
position: ConnectedPosition,
Expand All @@ -994,8 +1017,18 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
if (position.overlayY === 'bottom') {
// When using `bottom`, we adjust the y position such that it is the distance
// from the bottom of the viewport rather than the top.
const documentHeight = this._document.documentElement!.clientHeight;
styles.bottom = `${documentHeight - (overlayPoint.y + this._overlayRect.height)}px`;
let scrollbarWidth = 0;
let documentHeight = this._document.defaultView!.innerHeight;

if (
this._document.documentElement.offsetHeight === this._document.documentElement.scrollHeight
) {
scrollbarWidth = this._getScrollbarWidth();
}

styles.bottom = coerceCssPixelValue(
documentHeight - scrollbarWidth - (overlayPoint.y + this._overlayRect.height),
);
} else {
styles.top = coerceCssPixelValue(overlayPoint.y);
}
Expand Down