Skip to content

Commit acd4c60

Browse files
authored
fix(popover): closing popover in tab (#DS-3525) (#708)
1 parent 04b11c6 commit acd4c60

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

packages/components/core/pop-up/pop-up-trigger.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Directionality } from '@angular/cdk/bidi';
22
import { coerceBooleanProperty } from '@angular/cdk/coercion';
33
import {
4+
CdkScrollable,
45
ConnectedOverlayPositionChange,
56
ConnectionPositionPair,
67
FlexibleConnectedPositionStrategy,
@@ -102,6 +103,7 @@ export abstract class KbqPopUpTrigger<T> implements OnInit, OnDestroy {
102103
protected readonly hostView: ViewContainerRef = inject(ViewContainerRef);
103104
protected readonly direction = inject(Directionality, { optional: true });
104105
protected readonly destroyRef = inject(DestroyRef);
106+
protected readonly scrollable = inject(CdkScrollable, { optional: true });
105107

106108
protected abstract scrollStrategy: () => ScrollStrategy;
107109

packages/components/popover/popover.component.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
EventEmitter,
1919
InjectionToken,
2020
Input,
21+
OnInit,
2122
Output,
2223
TemplateRef,
2324
Type,
@@ -160,7 +161,7 @@ export function getKbqPopoverInvalidPositionError(position: string) {
160161
'(touchend)': 'handleTouchend()'
161162
}
162163
})
163-
export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> implements AfterContentInit {
164+
export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> implements AfterContentInit, OnInit {
164165
protected scrollStrategy: () => ScrollStrategy = inject(KBQ_POPOVER_SCROLL_STRATEGY);
165166

166167
@Input('kbqPopoverVisible')
@@ -347,6 +348,15 @@ export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> impl
347348
};
348349
}
349350

351+
ngOnInit(): void {
352+
super.ngOnInit();
353+
354+
this.scrollable
355+
?.elementScrolled()
356+
.pipe(takeUntilDestroyed(this.destroyRef))
357+
.subscribe(this.hideIfNotInViewPort);
358+
}
359+
350360
ngAfterContentInit(): void {
351361
if (this.closeOnScroll === null) {
352362
this.scrollDispatcher.scrolled().subscribe((scrollable: CdkScrollable | void) => {
@@ -425,4 +435,22 @@ export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> impl
425435
closingActions() {
426436
return merge(...this.closingActionsForClick(), this.closeOnScroll ? this.scrollDispatcher.scrolled() : NEVER);
427437
}
438+
439+
private hideIfNotInViewPort = () => {
440+
if (!this.scrollable) return;
441+
442+
const rect = this.elementRef.nativeElement.getBoundingClientRect();
443+
const containerRect = this.scrollable.getElementRef().nativeElement.getBoundingClientRect();
444+
445+
if (
446+
!(
447+
rect.bottom >= containerRect.top &&
448+
rect.right >= containerRect.left &&
449+
rect.top <= containerRect.bottom &&
450+
rect.left <= containerRect.right
451+
)
452+
) {
453+
this.hide();
454+
}
455+
};
428456
}

tools/public_api_guard/components/core.api.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { AnimationTriggerMetadata } from '@angular/animations';
1313
import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler';
1414
import { BehaviorSubject } from 'rxjs';
1515
import { CdkConnectedOverlay } from '@angular/cdk/overlay';
16+
import { CdkScrollable } from '@angular/cdk/overlay';
1617
import { ChangeDetectorRef } from '@angular/core';
1718
import { ComponentPortal } from '@angular/cdk/portal';
1819
import { ConnectedOverlayPositionChange } from '@angular/cdk/overlay';
@@ -2333,6 +2334,8 @@ export abstract class KbqPopUpTrigger<T> implements OnInit, OnDestroy {
23332334
// (undocumented)
23342335
protected readonly scheduler: AsyncScheduler | undefined;
23352336
// (undocumented)
2337+
protected readonly scrollable: CdkScrollable | null;
2338+
// (undocumented)
23362339
protected readonly scrollDispatcher: ScrollDispatcher;
23372340
// (undocumented)
23382341
protected abstract scrollStrategy: () => ScrollStrategy;

tools/public_api_guard/components/popover.api.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { KbqComponentColors } from '@koobiq/components/core';
2323
import { KbqPopUp } from '@koobiq/components/core';
2424
import { KbqPopUpTrigger } from '@koobiq/components/core';
2525
import { Observable } from 'rxjs';
26+
import { OnInit } from '@angular/core';
2627
import { Overlay } from '@angular/cdk/overlay';
2728
import { OverlayConfig } from '@angular/cdk/overlay';
2829
import { PopUpPlacements } from '@koobiq/components/core';
@@ -154,15 +155,15 @@ export class KbqPopoverModule {
154155
export function kbqPopoverScrollStrategyFactory(overlay: Overlay): () => ScrollStrategy;
155156

156157
// @public (undocumented)
157-
export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> implements AfterContentInit {
158+
export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> implements AfterContentInit, OnInit {
158159
// (undocumented)
159160
arrow: boolean;
160161
// (undocumented)
161162
backdropClass: string;
162163
get closeOnScroll(): boolean | null;
163164
set closeOnScroll(value: boolean);
164165
// (undocumented)
165-
closingActions(): Observable<void | MouseEvent | CdkScrollable>;
166+
closingActions(): Observable<void | CdkScrollable | MouseEvent>;
166167
// (undocumented)
167168
closingActionsForClick(): Observable<MouseEvent>[];
168169
// (undocumented)
@@ -199,6 +200,8 @@ export class KbqPopoverTrigger extends KbqPopUpTrigger<KbqPopoverComponent> impl
199200
// (undocumented)
200201
ngAfterContentInit(): void;
201202
// (undocumented)
203+
ngOnInit(): void;
204+
// (undocumented)
202205
offset: number | null;
203206
// (undocumented)
204207
protected originSelector: string;

0 commit comments

Comments
 (0)