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.

173 lines (172 loc) 6.8 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Directive, ElementRef, NgZone, Renderer2 } from "@angular/core"; import { closest } from "@progress/kendo-angular-common"; import { PopupService } from "@progress/kendo-angular-popup"; import { filter, take } from "rxjs/operators"; import { PopoverDirectivesBase } from "./directives-base"; import { PopoverService } from "./popover.service"; import { Subscription } from "rxjs"; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-popup"; import * as i2 from "./popover.service"; /** * Represents the [`kendoPopoverAnchor`](slug:configuration_popover#toc-popover-anchor) directive. * It is used to target an element, which should display a popover on interaction. * * @example * ```ts-no-run * <button kendoPopoverAnchor [popover]="myPopover">Show Popover</button> * ``` */ export class PopoverAnchorDirective extends PopoverDirectivesBase { hostEl; ngZone; popupService; renderer; popoverService; constructor(hostEl, ngZone, popupService, renderer, popoverService) { super(ngZone, popupService, renderer); this.hostEl = hostEl; this.ngZone = ngZone; this.popupService = popupService; this.renderer = renderer; this.popoverService = popoverService; this._popoverService = this.popoverService; } ngOnChanges(changes) { if (changes['showOn'] && !changes['showOn'].isFirstChange()) { this.subs.unsubscribe(); if (this.disposeClickListener) { this.disposeClickListener(); } this.subs = new Subscription(); this.manageEvents(); } } /** * Shows the Popover. [See example]({% slug programmaticcontrol_popover %}) */ show() { if (this.popupRef) { return; } this.ngZone.run(() => { this.openPopup(this.hostEl); }); this.popupRef.popupAnchorViewportLeave .pipe(take(1)) .subscribe(() => this.hide()); } /** * Toggles the visibility of the Popover. [See example]({% slug programmaticcontrol_popover %}) */ toggle() { if (this.popupRef) { this.hide(); } else { this.show(); } } subscribeToShowEvents(arr) { const hostEl = this.hostEl.nativeElement; this.subs.add(this.renderer.listen(hostEl, arr[0].name, () => { this.popoverService.emitAnchorState(true, hostEl); arr[0].handler(); })); this.subs.add(this.renderer.listen(hostEl, arr[1].name, (e) => { this.popoverService.emitAnchorState(false, null); arr[1].handler({ domEvent: e }); })); } subscribeClick() { if (this.disposeClickListener) { this.disposeClickListener(); } this.disposeClickListener = this.renderer.listen(document, 'click', (e) => { this.onClick(e); }); } mouseenterHandler = () => { this.controlVisibility(this.hostEl.nativeElement, true); }; mouseleaveHandler = () => { if (this.isPrevented(this.hostEl.nativeElement, false)) { return; } if (!this._hideSub) { this._hideSub = this.popoverService.hidePopover.subscribe((val) => { const [isPopoverHovered, isAnchorHovered] = val; if (!isPopoverHovered && !isAnchorHovered) { this.hide(); } }); } }; focusHandler = () => { this.controlVisibility(this.hostEl.nativeElement, true); }; blurHandler = (args) => { const event = args.domEvent; if (this.isPrevented(this.hostEl.nativeElement, false)) { return; } // from anchor to popup focus check const isFocusInside = !!closest(event.relatedTarget, (node) => node.classList && node.classList.contains('k-popover')); if (!isFocusInside) { this.hide(); } if (!this._focusInsideSub) { // inside popup focus check this._focusInsideSub = this.popoverService.isFocusInsidePopover.pipe(filter(v => v !== null)).subscribe((val) => { if (!val) { this.hide(); } }); } }; /** * @hidden */ onClick(event) { const isInsidePopup = !!closest(event.target, (node) => node.classList && node.classList.contains('k-popup')); const isAnchor = !!closest(event.target, (node) => node === this.hostEl.nativeElement); if (isInsidePopup || (this.popupRef && isAnchor)) { return; } if (isAnchor) { // on opening this.controlVisibility(this.hostEl.nativeElement, true); } else { // on closing this.controlVisibility(this.hostEl.nativeElement, false); } } controlVisibility(anchor, show) { if (this.isPrevented(anchor, show)) { return; } if (show) { this.show(); } else { this.hide(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PopoverAnchorDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.PopupService }, { token: i0.Renderer2 }, { token: i2.PopoverService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: PopoverAnchorDirective, isStandalone: true, selector: "[kendoPopoverAnchor]", providers: [PopoverService], exportAs: ["kendoPopoverAnchor"], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PopoverAnchorDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoPopoverAnchor]', exportAs: 'kendoPopoverAnchor', providers: [PopoverService], standalone: true }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.PopupService }, { type: i0.Renderer2 }, { type: i2.PopoverService }]; } });