@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
JavaScript
/**-----------------------------------------------------------------------------------------
* 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
}] } });