ngx-eagle
Version:
UI component infrastructure and Design components for mobile and desktop Angular web applications.
107 lines (87 loc) • 3.62 kB
text/typescript
import { Directive, ElementRef, HostBinding, Input, OnChanges, OnDestroy, OnInit, Renderer2, SimpleChanges } from '@angular/core';
import { Position } from './typings';
export class TooltipDirective implements OnInit, OnDestroy, OnChanges {
tooltipText: string = '';
tooltipPosition: Position = 'top';
private tooltipElement: HTMLElement | null = null;
private readonly tooltipClass = 'tooltiptext';
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnInit(): void {
if (this.tooltipText) {
this.init();
};
}
ngOnDestroy(): void {
this.removeTooltip();
}
ngOnChanges(changes: SimpleChanges): void {
if (this.tooltipElement) {
if (changes['tooltipPosition'] && !changes['tooltipPosition'].isFirstChange()) {
this.setPosition();
}
if (changes['tooltipText'] && !changes['tooltipText'].isFirstChange()) {
this.removeTooltip();
this.init();
}
}
}
init(): void {
this.createTooltip();
this.setPosition();
this.addEventListeners();
}
private createTooltip(): void {
const hostElement = this.el.nativeElement;
// Create tooltip container
this.tooltipElement = this.renderer.createElement('span');
this.renderer.addClass(this.tooltipElement, this.tooltipClass);
this.renderer.setStyle(this.tooltipElement, 'position', 'absolute');
this.renderer.setStyle(this.tooltipElement, 'opacity', '0');
this.renderer.setStyle(this.tooltipElement, 'visibility', 'hidden');
this.renderer.setStyle(this.tooltipElement, 'transition', 'opacity 0.3s ease, visibility 0.3s ease');
this.renderer.setProperty(this.tooltipElement, 'innerText', this.tooltipText);
// Append tooltip to host element
this.renderer.addClass(hostElement, 'tooltip');
this.renderer.addClass(hostElement, `tooltip-${this.tooltipPosition}`);
this.renderer.appendChild(hostElement, this.tooltipElement);
}
private setPosition(): void {
if (!this.tooltipElement) return;
// Remove any previous position classes
['tooltip-top', 'tooltip-bottom', 'tooltip-left', 'tooltip-right'].forEach(pos => {
this.renderer.removeClass(this.el.nativeElement, pos);
});
// Add new position class
this.renderer.addClass(this.el.nativeElement, `tooltip-${this.tooltipPosition}`);
}
private addEventListeners(): void {
const hostElement = this.el.nativeElement;
// Show tooltip on hover and focus
this.renderer.listen(hostElement, 'mouseenter', () => this.showTooltip());
this.renderer.listen(hostElement, 'focusin', () => this.showTooltip());
// Hide tooltip on mouse leave and blur
this.renderer.listen(hostElement, 'mouseleave', () => this.hideTooltip());
this.renderer.listen(hostElement, 'focusout', () => this.hideTooltip());
}
private showTooltip(): void {
if (this.tooltipElement) {
this.renderer.setStyle(this.tooltipElement, 'opacity', '1');
this.renderer.setStyle(this.tooltipElement, 'visibility', 'visible');
}
}
private hideTooltip(): void {
if (this.tooltipElement) {
this.renderer.setStyle(this.tooltipElement, 'opacity', '0');
this.renderer.setStyle(this.tooltipElement, 'visibility', 'hidden');
}
}
private removeTooltip(): void {
if (this.tooltipElement) {
this.renderer.removeChild(this.el.nativeElement, this.tooltipElement);
}
}
}