mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(menu): wrong offset for nested menu in a fallback position (#7562)
* Adds the ability to set offsets on connected position fallbacks. * Fixes wrong positioning of nested menu if they're in a fallback position. Fixes #7549.
This commit is contained in:
committed by
Andrew Seguin
parent
f0f6a7468f
commit
074f6cea62
@@ -326,6 +326,28 @@ describe('ConnectedPositionStrategy', () => {
|
||||
expect(Math.floor(overlayRect.left)).toBe(Math.floor(originRect.left));
|
||||
});
|
||||
|
||||
it('should allow for the fallback positions to specify their own offsets', () => {
|
||||
originElement.style.bottom = '0';
|
||||
originRect = originElement.getBoundingClientRect();
|
||||
strategy = positionBuilder
|
||||
.connectedTo(
|
||||
fakeElementRef,
|
||||
{originX: 'start', originY: 'top'},
|
||||
{overlayX: 'start', overlayY: 'top'})
|
||||
.withFallbackPosition(
|
||||
{originX: 'start', originY: 'top'},
|
||||
{overlayX: 'start', overlayY: 'bottom'},
|
||||
-100, -100);
|
||||
|
||||
strategy.withOffsetY(50).withOffsetY(50);
|
||||
strategy.attach(fakeOverlayRef(overlayElement));
|
||||
strategy.apply();
|
||||
|
||||
let overlayRect = overlayElement.getBoundingClientRect();
|
||||
expect(Math.floor(overlayRect.bottom)).toBe(Math.floor(originRect.top - 100));
|
||||
expect(Math.floor(overlayRect.left)).toBe(Math.floor(originRect.left - 100));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should emit onPositionChange event when position changes', () => {
|
||||
|
||||
@@ -192,8 +192,12 @@ export class ConnectedPositionStrategy implements PositionStrategy {
|
||||
*/
|
||||
withFallbackPosition(
|
||||
originPos: OriginConnectionPosition,
|
||||
overlayPos: OverlayConnectionPosition): this {
|
||||
this._preferredPositions.push(new ConnectionPositionPair(originPos, overlayPos));
|
||||
overlayPos: OverlayConnectionPosition,
|
||||
offsetX?: number,
|
||||
offsetY?: number): this {
|
||||
|
||||
const position = new ConnectionPositionPair(originPos, overlayPos, offsetX, offsetY);
|
||||
this._preferredPositions.push(position);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -296,9 +300,13 @@ export class ConnectedPositionStrategy implements PositionStrategy {
|
||||
overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
|
||||
}
|
||||
|
||||
// The (x, y) offsets of the overlay based on the current position.
|
||||
let offsetX = typeof pos.offsetX === 'undefined' ? this._offsetX : pos.offsetX;
|
||||
let offsetY = typeof pos.offsetY === 'undefined' ? this._offsetY : pos.offsetY;
|
||||
|
||||
// The (x, y) coordinates of the overlay.
|
||||
let x = originPoint.x + overlayStartX + this._offsetX;
|
||||
let y = originPoint.y + overlayStartY + this._offsetY;
|
||||
let x = originPoint.x + overlayStartX + offsetX;
|
||||
let y = originPoint.y + overlayStartY + offsetY;
|
||||
|
||||
// How much the overlay would overflow at this position, on each side.
|
||||
let leftOverflow = 0 - x;
|
||||
|
||||
@@ -33,7 +33,12 @@ export class ConnectionPositionPair {
|
||||
overlayX: HorizontalConnectionPos;
|
||||
overlayY: VerticalConnectionPos;
|
||||
|
||||
constructor(origin: OriginConnectionPosition, overlay: OverlayConnectionPosition) {
|
||||
constructor(
|
||||
origin: OriginConnectionPosition,
|
||||
overlay: OverlayConnectionPosition,
|
||||
public offsetX?: number,
|
||||
public offsetY?: number) {
|
||||
|
||||
this.originX = origin.originX;
|
||||
this.originY = origin.originY;
|
||||
this.overlayX = overlay.overlayX;
|
||||
|
||||
@@ -354,9 +354,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
|
||||
// to the edges of the trigger, instead of overlapping it.
|
||||
overlayFallbackX = originX = this.menu.xPosition === 'before' ? 'start' : 'end';
|
||||
originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
|
||||
|
||||
// TODO(crisbeto): this should be a function, once the overlay supports it.
|
||||
// Right now it will be wrong for the fallback positions.
|
||||
offsetY = overlayY === 'bottom' ? MENU_PANEL_TOP_PADDING : -MENU_PANEL_TOP_PADDING;
|
||||
} else if (!this.menu.overlapTrigger) {
|
||||
originY = overlayY === 'top' ? 'bottom' : 'top';
|
||||
@@ -372,10 +369,12 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
|
||||
{overlayX: overlayFallbackX, overlayY})
|
||||
.withFallbackPosition(
|
||||
{originX, originY: originFallbackY},
|
||||
{overlayX, overlayY: overlayFallbackY})
|
||||
{overlayX, overlayY: overlayFallbackY},
|
||||
undefined, -offsetY)
|
||||
.withFallbackPosition(
|
||||
{originX: originFallbackX, originY: originFallbackY},
|
||||
{overlayX: overlayFallbackX, overlayY: overlayFallbackY});
|
||||
{overlayX: overlayFallbackX, overlayY: overlayFallbackY},
|
||||
undefined, -offsetY);
|
||||
}
|
||||
|
||||
/** Cleans up the active subscriptions. */
|
||||
|
||||
Reference in New Issue
Block a user