/// /// Copyright 2015-2026 Micro Focus or one of its affiliates. /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// import { CdkObserveContent } from '@angular/cdk/observers'; import { NgClass, NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnDestroy, TemplateRef, } from '@angular/core'; import { Subject } from 'rxjs'; import { AnchorAlignment, AnchorPlacement } from '../../common/overlay/index'; let uniqueTooltipId = 0; @Component({ selector: 'ux-tooltip', templateUrl: './tooltip.component.html', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, CdkObserveContent, NgTemplateOutlet], }) export class TooltipComponent implements OnDestroy { protected readonly _changeDetectorRef = inject(ChangeDetectorRef); /** Define a unique id for each tooltip */ id: string = `ux-tooltip-${++uniqueTooltipId}`; /** Define the tooltip role */ role: string = 'tooltip'; /** The content of the tooltip, either a string or a TemplateRef for further customization */ @Input() content: string | TemplateRef; /** Allow the user to supply a context for the tooltip TemplateRef */ @Input() context: T; /** The position the tooltip should display relative to the associated element */ @Input() placement: AnchorPlacement; /** The position the callout should display relative to the popover element */ @Input() alignment: AnchorAlignment; /** Allow a custom class to be added to the tooltip to allow custom styling */ customClass: string = ''; /** Emit when the tooltip need to update it's position */ reposition$ = new Subject(); /** Indicates whether or not the content is a string or a TemplateRef */ get isTemplateRef(): boolean { return this.content instanceof TemplateRef; } /** The name of the css class to use for the tooltip direction */ _positionClass: string = ''; get positionClass(): string { return this._positionClass; } set positionClass(positionClass: string) { this._positionClass = positionClass; this._changeDetectorRef.detectChanges(); } /** Cleanup after the component is destroyed */ ngOnDestroy(): void { this.reposition$.complete(); } /** Inform the parent directive that it needs to recalulate the position */ reposition(): void { this.reposition$.next(); } /** This will update the content of the tooltip and trigger change detection */ setContent(content: string | TemplateRef): void { this.content = content; this._changeDetectorRef.markForCheck(); } /** This will update the tooltip placement and trigger change detection */ setPlacement(placement: AnchorPlacement) { if (!placement) { return; } this.placement = placement; this._changeDetectorRef.markForCheck(); } /** This will update the tooltip alignment and trigger change detection */ setAlignment(alignment: AnchorAlignment) { if (!alignment) { return; } this.alignment = alignment; this._changeDetectorRef.markForCheck(); } /** This will set a custom class on the tooltip and trigger change detection */ setClass(customClass: string): void { if (!customClass) { return; } this.customClass = customClass; this._changeDetectorRef.markForCheck(); } /** Updates the context used by the TemplateRef */ setContext(context: T): void { if (!context) { return; } this.context = context; this._changeDetectorRef.markForCheck(); } /** Specify the tooltip role attribute */ setRole(role: string): void { if (!role) { return; } this.role = role; this._changeDetectorRef.markForCheck(); } }