Select Git revision
tooltip.directive.ts
tooltip.directive.ts 3.02 KiB
import { isEscapeKey } from '@alfa-client/tech-shared';
import { InteractivityChecker } from '@angular/cdk/a11y';
import {
ComponentRef,
Directive,
ElementRef,
HostListener,
inject,
Input,
OnDestroy,
Renderer2,
ViewContainerRef,
} from '@angular/core';
import { uniqueId } from 'lodash-es';
import { TooltipComponent } from './tooltip.component';
@Directive({
selector: '[tooltip]',
standalone: true,
})
export class TooltipDirective implements OnDestroy {
@Input() tooltip: string = '';
componentRef: ComponentRef<TooltipComponent> = null;
focusableElement: HTMLElement = null;
tooltipId: string;
public viewContainerRef: ViewContainerRef = inject(ViewContainerRef);
public elementRef: ElementRef<HTMLElement> = inject(ElementRef);
public renderer: Renderer2 = inject(Renderer2);
public interactivityChecker: InteractivityChecker = inject(InteractivityChecker);
ngOnDestroy(): void {
this.destroy();
}
@HostListener('mouseenter')
@HostListener('focusin')
createTooltip(): void {
if (this.componentRef === null) {
const nativeElement: HTMLElement = this.elementRef.nativeElement;
const attachedToFocused: boolean = nativeElement.contains(document.activeElement);
this.componentRef = this.viewContainerRef.createComponent(TooltipComponent);
nativeElement.appendChild(this.componentRef.location.nativeElement);
this.setDescribedBy();
this.setTooltipProperties(attachedToFocused);
}
}
@HostListener('mouseleave')
@HostListener('window:scroll')
@HostListener('focusout')
destroyTooltip(): void {
this.destroy();
}
@HostListener('keydown', ['$event'])
onKeydown(e: KeyboardEvent): void {
if (isEscapeKey(e)) {
this.destroy();
}
}
setTooltipProperties(attachedToFocused = false): void {
if (this.componentRef !== null) {
const { left, right, bottom } = this.elementRef.nativeElement.getBoundingClientRect();
this.componentRef.instance.left = (right + left) / 2;
this.componentRef.instance.top = attachedToFocused ? bottom + 4 : bottom;
this.componentRef.instance.text = this.tooltip;
this.componentRef.instance.id = this.tooltipId;