Skip to content

Commit

Permalink
popover scroll reposition fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Pop John committed Oct 24, 2024
1 parent 7eef2a7 commit d1388c1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,38 @@ export const DEFAUlT_POPOVER_HEIGHT: PopoverCSSSize = '80px';
export const DEFAULT_POPOVER_POSITION_VALUE: 'top' | 'bottom' | 'left' | 'right' = 'top';

export const DEFAULT_POPOVER_FADE_IN_OUT_ANIMATION_DURATION: number = 150;

export const POPOVER_POSITIONS: Record<string, any> = {
top: {
originX: 'center',
originY: 'top',
overlayX: 'center',
overlayY: 'bottom',
offsetY: -24,
offsetX: -9
},
bottom: {
originX: 'center',
originY: 'bottom',
overlayX: 'center',
overlayY: 'top',
offsetY: 4,
offsetX: -7
},
left: {
originX: 'start',
originY: 'center',
overlayX: 'end',
overlayY: 'center',
offsetX: -22,
offsetY: -12
},
right: {
originX: 'end',
originY: 'center',
overlayX: 'start',
overlayY: 'center',
offsetX: 8,
offsetY: -10
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ export class PopoverRef {
public afterClosed(): Observable<any> {
return this.afterClosedSubject.asObservable();
}

public updatePosition(): void {
this.overlayRef.updatePosition();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//
// SPDX-License-Identifier: Apache-2.0

import { Overlay } from '@angular/cdk/overlay';
import { Overlay, ScrollDispatcher } from '@angular/cdk/overlay';
import { ComponentPortal, ComponentType } from '@angular/cdk/portal';
import { ElementRef, Injectable, Injector } from '@angular/core';
import { PopoverRef } from '../popover.ref';
Expand All @@ -23,15 +23,17 @@ import { POPOVER_DATA } from '../popover.tokens';
import {
DEFAUlT_POPOVER_HEIGHT,
DEFAULT_POPOVER_POSITION_VALUE,
DEFAUlT_POPOVER_WIDTH
DEFAUlT_POPOVER_WIDTH,
POPOVER_POSITIONS
} from '../models/constants/popover.constants';
import { PopoverConfig } from '../models/interfaces/popover-config.interface';

@Injectable()
export class PopoverService {
constructor(
private overlay: Overlay,
private injector: Injector
private injector: Injector,
private scrollDispatcher: ScrollDispatcher
) {}

open<T>(component: ComponentType<T>, origin: HTMLElement | ElementRef, config?: PopoverConfig): PopoverRef {
Expand Down Expand Up @@ -65,54 +67,25 @@ export class PopoverService {
const portal = new ComponentPortal(component, null, injector);
overlayRef.attach(portal);

// Handle scroll events by re-positioning the popover
this.scrollDispatcher.scrolled().subscribe(() => {
popoverRef.updatePosition();
});

return popoverRef;
}

private getPositionStrategy(origin: HTMLElement | ElementRef, position: 'top' | 'bottom' | 'left' | 'right') {
const element = origin instanceof ElementRef ? origin.nativeElement : origin;

const positions: Record<string, any> = {
top: {
originX: 'center',
originY: 'top',
overlayX: 'center',
overlayY: 'bottom',
offsetY: -24,
offsetX: -9
},
bottom: {
originX: 'center',
originY: 'bottom',
overlayX: 'center',
overlayY: 'top',
offsetY: 4,
offsetX: -7
},
left: {
originX: 'start',
originY: 'center',
overlayX: 'end',
overlayY: 'center',
offsetX: -22,
offsetY: -12
},
right: {
originX: 'end',
originY: 'center',
overlayX: 'start',
overlayY: 'center',
offsetX: 8,
offsetY: -10
}
};

const selectedPosition = positions[position];
const selectedPosition = POPOVER_POSITIONS[position];

return this.overlay
.position()
.flexibleConnectedTo(element)
.withFlexibleDimensions(false)
.withPush(false)
.withPositions([selectedPosition]);
.withPositions([selectedPosition])
.withViewportMargin(0);
}
}

0 comments on commit d1388c1

Please sign in to comment.