Merged PR 2056: fix(ui-tooltip): Integrated CloseOnScrollDirective to close tooltip on scrolling

fix(ui-tooltip): Integrated CloseOnScrollDirective to close tooltip on scrolling

Ref: #5510
This commit is contained in:
Nino Righi
2025-11-26 20:08:11 +00:00
committed by Lorenz Hilpert
parent 98fb863fc7
commit 4589146e31

View File

@@ -12,10 +12,12 @@ import {
inject,
input,
OnDestroy,
signal,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { TooltipComponent } from './tooltip.component';
import { CloseOnScrollDirective } from '@isa/ui/layout';
/**
* Defines the trigger events for the tooltip.
@@ -57,12 +59,19 @@ export type TooltipTrigger =
*/
@Directive({
selector: '[uiTooltip]',
hostDirectives: [
{
directive: CloseOnScrollDirective,
outputs: ['closeOnScroll'],
},
],
host: {
'(click)': 'onClickEvent($event)',
'(mouseenter)': 'onMouseEnter()',
'(mouseleave)': 'onMouseLeave()',
'(focus)': 'onFocusEvent()',
'(blur)': 'onBlurEvent()',
'(closeOnScroll)': 'onScrollClose()',
'tabindex': '0',
},
standalone: true,
@@ -73,10 +82,12 @@ export class TooltipDirective implements OnDestroy {
#elementRef = inject(ElementRef);
#viewContainerRef = inject(ViewContainerRef);
#positionBuilder = inject(OverlayPositionBuilder);
#closeOnScroll = inject(CloseOnScrollDirective, { self: true });
#overlayRef: OverlayRef | null = null;
#tooltipInstance: TooltipComponent | null = null;
#openTrigger: TooltipTrigger | null = null; // Tracks which trigger opened the tooltip
#isOpen = signal(false); // Internal signal to track open state for CloseOnScrollDirective
// Distance between tooltip and anchor element
readonly #offset = 8; // 0.5rem = 8px
@@ -124,6 +135,13 @@ export class TooltipDirective implements OnDestroy {
this.#tooltipInstance.variant.set(variantValue);
}
});
// Configure CloseOnScrollDirective: activate when tooltip is open (any trigger)
effect(() => {
const isOpen = this.#isOpen();
// Activate scroll-close behavior whenever tooltip is open
this.#closeOnScroll.closeOnScrollWhen.set(isOpen);
});
}
/**
@@ -230,6 +248,13 @@ export class TooltipDirective implements OnDestroy {
if (variantValue !== undefined) {
this.#tooltipInstance.variant.set(variantValue);
}
// Update open state for CloseOnScrollDirective
// Set exclude element first, then activate
this.#closeOnScroll.closeOnScrollExclude.set(
this.#overlayRef.overlayElement,
);
this.#isOpen.set(true);
}
/**
@@ -264,6 +289,9 @@ export class TooltipDirective implements OnDestroy {
this.#overlayRef = null;
this.#tooltipInstance = null;
this.#openTrigger = null;
// Update open state for CloseOnScrollDirective
this.#isOpen.set(false);
}
/**
@@ -341,6 +369,24 @@ export class TooltipDirective implements OnDestroy {
}
}
/**
* Handles the scroll close event from CloseOnScrollDirective.
* Closes the tooltip when user scrolls while tooltip is open.
* @internal
*/
onScrollClose() {
// Force close regardless of trigger since scroll should always close
if (this.#overlayRef) {
this.#isOpen.set(false);
this.#closeOnScroll.closeOnScrollExclude.set(undefined);
this.#overlayRef.detach();
this.#overlayRef.dispose();
this.#overlayRef = null;
this.#tooltipInstance = null;
this.#openTrigger = null;
}
}
/**
* Cleans up the tooltip when the directive is destroyed.
* Ensures the tooltip is hidden to prevent memory leaks.