UNPKG

@progress/kendo-angular-tooltip

Version:

Kendo UI Tooltip for Angular - A highly customizable and easily themeable tooltip from the creators developers trust for professional Angular components.

273 lines (264 loc) 11.5 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, HostBinding, Input, ElementRef, TemplateRef, Output, EventEmitter } from '@angular/core'; import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n'; import { getCenterOffset, getId } from '../utils'; import { xIcon } from '@progress/kendo-svg-icons'; import { NgIf, NgTemplateOutlet, NgClass } from '@angular/common'; import { LocalizedMessagesDirective } from './../localization/localized-messages.directive'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-l10n"; /** * @hidden */ export class TooltipContentComponent { content; localizationService; /** * @hidden */ xIcon = xIcon; /** * @hidden */ direction; close = new EventEmitter(); get cssClasses() { return 'k-tooltip'; } hostRole = 'tooltip'; get hostId() { return this.tooltipId; } get className() { return this.closable; } get cssPosition() { return 'relative'; } tooltipWidth = null; tooltipHeight = null; titleTemplate; anchor; closable; templateRef; templateString; closeTitle; callout = true; position; /** * @hidden */ tooltipId; dynamicRTLSubscription; constructor(content, localizationService) { this.content = content; this.localizationService = localizationService; this.direction = localizationService.rtl ? 'rtl' : 'ltr'; } ngOnInit() { this.tooltipId = getId('tooltip'); this.dynamicRTLSubscription = this.localizationService.changes .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr'); } ngOnDestroy() { if (this.dynamicRTLSubscription) { this.dynamicRTLSubscription.unsubscribe(); } } get closeButtonTitle() { return this.closeTitle || this.localizationService.get('closeTitle'); } calloutPositionClass() { return { 'top': 'k-callout-s', 'left': 'k-callout-e', 'bottom': 'k-callout-n', 'right': 'k-callout-w' }[this.position]; } onCloseClick(event) { event.preventDefault(); this.close.emit(); } updateCalloutPosition(position, isFlip) { if (!this.callout) { return; } const callout = this.content.nativeElement.querySelector('.k-callout'); const isVertical = position === 'top' || position === 'bottom'; const size = isVertical ? 'width' : 'height'; const dir = isVertical ? 'left' : 'top'; const offsetProperty = isVertical ? 'marginLeft' : 'marginTop'; const calloutSize = callout.getBoundingClientRect()[size]; const anchorCenter = getCenterOffset(this.anchor.nativeElement, dir, size); const contentCenter = getCenterOffset(this.content.nativeElement, dir, size); const diff = Math.abs(contentCenter - anchorCenter); if (diff > 1 || diff === 0 || Math.round(diff) === 0) { const newMargin = contentCenter - anchorCenter + (calloutSize / 2); callout.style[offsetProperty] = `${-newMargin}px`; } const calloutStyles = this.calloutStyles(position, calloutSize, isFlip); Object.keys(calloutStyles).forEach((style) => { callout.style[style] = calloutStyles[style]; }); } calloutStyles = (position, calloutSize, isFlip) => { const styles = {}; const isVertical = position === 'top' || position === 'bottom'; const flipDeg = '180deg'; const zeroDeg = '0deg'; if (!isFlip) { styles.transform = isVertical ? `rotateX(${zeroDeg})` : `rotateY(${zeroDeg})`; return styles; } if (position === 'top') { styles.bottom = 'unset'; } else if (position === 'bottom') { styles.top = 'unset'; } else if (position === 'left') { styles.right = 'unset'; } else if (position === 'right') { styles.left = 'unset'; } styles[position] = `${-calloutSize}px`; styles.transform = isVertical ? `rotateX(${flipDeg})` : `rotateY(${flipDeg})`; return styles; }; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TooltipContentComponent, deps: [{ token: i0.ElementRef }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TooltipContentComponent, isStandalone: true, selector: "kendo-tooltip", inputs: { tooltipWidth: "tooltipWidth", tooltipHeight: "tooltipHeight", titleTemplate: "titleTemplate", anchor: "anchor", closable: "closable", templateRef: "templateRef", templateString: "templateString" }, outputs: { close: "close" }, host: { properties: { "attr.dir": "this.direction", "class": "this.cssClasses", "attr.role": "this.hostRole", "attr.id": "this.hostId", "class.k-tooltip-closable": "this.className", "style.position": "this.cssPosition", "style.width.px": "this.tooltipWidth", "style.height.px": "this.tooltipHeight" } }, providers: [ LocalizationService, { provide: L10N_PREFIX, useValue: 'kendo.tooltip' } ], ngImport: i0, template: ` <ng-container kendoTooltipLocalizedMessages i18n-closeTitle="kendo.tooltip.closeTitle|The title of the close button" closeTitle="Close" > </ng-container> <div class="k-tooltip-content"> <div class="k-tooltip-title" *ngIf="titleTemplate"> <ng-template [ngIf]="titleTemplate" [ngTemplateOutlet]="titleTemplate" [ngTemplateOutletContext]="{ $implicit: anchor, anchor: anchor }"> </ng-template> </div> <ng-template [ngIf]="templateRef" [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ $implicit: anchor, anchor: anchor }"> </ng-template> <ng-template [ngIf]="templateString"> {{ templateString }} </ng-template> </div> <div *ngIf="closable" [attr.aria-hidden]="true" class="k-tooltip-button" (click)="onCloseClick($event)"> <a href="#" [attr.title]="closeButtonTitle" class="k-icon"> <kendo-icon-wrapper name="x" [svgIcon]="xIcon"> </kendo-icon-wrapper> </a> </div> <div class="k-callout" *ngIf="callout" [ngClass]="calloutPositionClass()"></div> `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoTooltipLocalizedMessages]", inputs: ["closeTitle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TooltipContentComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-tooltip', template: ` <ng-container kendoTooltipLocalizedMessages i18n-closeTitle="kendo.tooltip.closeTitle|The title of the close button" closeTitle="Close" > </ng-container> <div class="k-tooltip-content"> <div class="k-tooltip-title" *ngIf="titleTemplate"> <ng-template [ngIf]="titleTemplate" [ngTemplateOutlet]="titleTemplate" [ngTemplateOutletContext]="{ $implicit: anchor, anchor: anchor }"> </ng-template> </div> <ng-template [ngIf]="templateRef" [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ $implicit: anchor, anchor: anchor }"> </ng-template> <ng-template [ngIf]="templateString"> {{ templateString }} </ng-template> </div> <div *ngIf="closable" [attr.aria-hidden]="true" class="k-tooltip-button" (click)="onCloseClick($event)"> <a href="#" [attr.title]="closeButtonTitle" class="k-icon"> <kendo-icon-wrapper name="x" [svgIcon]="xIcon"> </kendo-icon-wrapper> </a> </div> <div class="k-callout" *ngIf="callout" [ngClass]="calloutPositionClass()"></div> `, providers: [ LocalizationService, { provide: L10N_PREFIX, useValue: 'kendo.tooltip' } ], standalone: true, imports: [LocalizedMessagesDirective, NgIf, NgTemplateOutlet, IconWrapperComponent, NgClass] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.LocalizationService }]; }, propDecorators: { direction: [{ type: HostBinding, args: ['attr.dir'] }], close: [{ type: Output }], cssClasses: [{ type: HostBinding, args: ['class'] }], hostRole: [{ type: HostBinding, args: ['attr.role'] }], hostId: [{ type: HostBinding, args: ['attr.id'] }], className: [{ type: HostBinding, args: ['class.k-tooltip-closable'] }], cssPosition: [{ type: HostBinding, args: ['style.position'] }], tooltipWidth: [{ type: HostBinding, args: ['style.width.px'] }, { type: Input }], tooltipHeight: [{ type: HostBinding, args: ['style.height.px'] }, { type: Input }], titleTemplate: [{ type: Input }], anchor: [{ type: Input }], closable: [{ type: Input }], templateRef: [{ type: Input }], templateString: [{ type: Input }] } });