import * as i0 from '@angular/core';
import { input, signal, inject, ElementRef, computed, TemplateRef, Component, Injectable, booleanAttribute, HostListener, Directive, NgModule } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { calculateOverlayArrowPosition, getPositionStrategy, getOverlay } from '@siemens/element-ng/common';
import { NgClass, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
import { SiTranslatePipe } from '@siemens/element-translate-ng/translate';

class TooltipComponent {
    /** @defaultValue '' */
    tooltip = input('');
    tooltipPositionClass = signal('');
    arrowPos = signal(undefined);
    /** @internal */
    id = input('');
    tooltipContext = input();
    elementRef = inject(ElementRef);
    tooltipText = computed(() => {
        const tooltip = this.tooltip();
        return typeof tooltip === 'string' ? tooltip : null;
    });
    tooltipTemplate = computed(() => {
        const tooltip = this.tooltip();
        return tooltip instanceof TemplateRef ? tooltip : null;
    });
    tooltipComponent = computed(() => {
        const tooltip = this.tooltip();
        return !(tooltip instanceof TemplateRef) && typeof tooltip !== 'string' ? tooltip : null;
    });
    /** @internal */
    updateTooltipPosition(change, anchor) {
        const arrowClassTooltip = `tooltip-${change.connectionPair.overlayX}-${change.connectionPair.overlayY}`;
        // need two updates as class changes affect the position
        if (arrowClassTooltip !== this.tooltipPositionClass()) {
            this.tooltipPositionClass.set(arrowClassTooltip);
        }
        const arrowPos = calculateOverlayArrowPosition(change, this.elementRef, anchor);
        this.arrowPos.set(arrowPos);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: TooltipComponent, isStandalone: true, selector: "si-tooltip", inputs: { tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, tooltipContext: { classPropertyName: "tooltipContext", publicName: "tooltipContext", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n  class=\"tooltip show position-relative\"\n  role=\"tooltip\"\n  [id]=\"id()\"\n  [ngClass]=\"tooltipPositionClass()\"\n>\n  <div\n    class=\"tooltip-arrow\"\n    [style.left.px]=\"arrowPos()?.left\"\n    [style.right.px]=\"arrowPos()?.right\"\n  ></div>\n  <div class=\"tooltip-inner\">\n    @if (tooltipText()) {\n      <div class=\"si-body\">{{ tooltipText() | translate }}</div>\n    } @else if (tooltipTemplate()) {\n      <ng-template\n        [ngTemplateOutlet]=\"tooltipTemplate()\"\n        [ngTemplateOutletContext]=\"tooltipContext()\"\n      />\n    } @else if (tooltipComponent()) {\n      <ng-container [ngComponentOutlet]=\"tooltipComponent()\" />\n    }\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: TooltipComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-tooltip', imports: [NgClass, NgTemplateOutlet, SiTranslatePipe, NgComponentOutlet], template: "<div\n  class=\"tooltip show position-relative\"\n  role=\"tooltip\"\n  [id]=\"id()\"\n  [ngClass]=\"tooltipPositionClass()\"\n>\n  <div\n    class=\"tooltip-arrow\"\n    [style.left.px]=\"arrowPos()?.left\"\n    [style.right.px]=\"arrowPos()?.right\"\n  ></div>\n  <div class=\"tooltip-inner\">\n    @if (tooltipText()) {\n      <div class=\"si-body\">{{ tooltipText() | translate }}</div>\n    } @else if (tooltipTemplate()) {\n      <ng-template\n        [ngTemplateOutlet]=\"tooltipTemplate()\"\n        [ngTemplateOutletContext]=\"tooltipContext()\"\n      />\n    } @else if (tooltipComponent()) {\n      <ng-container [ngComponentOutlet]=\"tooltipComponent()\" />\n    }\n  </div>\n</div>\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * TooltipRef is attached to a specific element.
 * Use it to show or hide a tooltip for that element.
 *
 * @internal
 */
class TooltipRef {
    overlayRef;
    element;
    describedBy;
    injector;
    constructor(overlayRef, element, describedBy, injector) {
        this.overlayRef = overlayRef;
        this.element = element;
        this.describedBy = describedBy;
        this.injector = injector;
    }
    subscription;
    show(content, tooltipContext) {
        if (this.overlayRef.hasAttached()) {
            return;
        }
        const toolTipPortal = new ComponentPortal(TooltipComponent, undefined, this.injector);
        const tooltipRef = this.overlayRef.attach(toolTipPortal);
        tooltipRef.setInput('tooltip', content);
        tooltipRef.setInput('id', this.describedBy);
        tooltipRef.setInput('tooltipContext', tooltipContext);
        const positionStrategy = getPositionStrategy(this.overlayRef);
        this.subscription?.unsubscribe();
        this.subscription = positionStrategy?.positionChanges.subscribe(change => tooltipRef.instance.updateTooltipPosition(change, this.element));
    }
    hide() {
        this.overlayRef.detach();
        this.subscription?.unsubscribe();
    }
    destroy() {
        this.overlayRef.dispose();
        this.subscription?.unsubscribe();
    }
}
/**
 * A service to create tooltips for specific elements.
 * Use this if the tooltip directive is not suitable.
 * Must not be used outside element-ng.
 *
 * @internal
 */
// We cannot provide this in root, as people may override the cdk overlay creation.
class SiTooltipService {
    overlay = inject(Overlay);
    createTooltip(config) {
        return new TooltipRef(getOverlay(config.element, this.overlay, false, config.placement), config.element, config.describedBy, config.injector);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipService, decorators: [{
            type: Injectable
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiTooltipDirective {
    static idCounter = 0;
    /**
     * The tooltip text to be displayed
     *
     * @defaultValue ''
     */
    siTooltip = input('');
    /**
     * The placement of the tooltip. One of 'top', 'start', end', 'bottom'
     *
     * @defaultValue 'auto'
     */
    placement = input('auto');
    /**
     * The trigger event on which the tooltip shall be displayed
     */
    triggers = input();
    /**
     * Allows the tooltip to be disabled
     *
     * @defaultValue false
     */
    isDisabled = input(false, { transform: booleanAttribute });
    /**
     * The context for the attached template
     */
    tooltipContext = input();
    describedBy = `__tooltip_${SiTooltipDirective.idCounter++}`;
    tooltipRef;
    tooltipService = inject(SiTooltipService);
    elementRef = inject(ElementRef);
    ngOnDestroy() {
        this.tooltipRef?.destroy();
    }
    showTooltip() {
        const siTooltip = this.siTooltip();
        if (this.isDisabled() || !siTooltip) {
            return;
        }
        this.tooltipRef ??= this.tooltipService.createTooltip({
            describedBy: this.describedBy,
            element: this.elementRef,
            placement: this.placement()
        });
        this.tooltipRef.show(this.siTooltip(), this.tooltipContext());
    }
    focusIn() {
        this.showTooltip();
    }
    show() {
        if (this.triggers() === 'focus') {
            return;
        }
        this.showTooltip();
    }
    hide() {
        this.tooltipRef?.hide();
    }
    mouseOut() {
        if (this.triggers() === 'focus') {
            return;
        }
        this.hide();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.6", type: SiTooltipDirective, isStandalone: true, selector: "[siTooltip]", inputs: { siTooltip: { classPropertyName: "siTooltip", publicName: "siTooltip", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, triggers: { classPropertyName: "triggers", publicName: "triggers", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, tooltipContext: { classPropertyName: "tooltipContext", publicName: "tooltipContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "focusIn()", "mouseenter": "show()", "touchstart": "hide()", "focusout": "hide()", "mouseleave": "mouseOut()" }, properties: { "attr.aria-describedby": "describedBy" } }, providers: [SiTooltipService], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[siTooltip]',
                    providers: [SiTooltipService],
                    host: {
                        '[attr.aria-describedby]': 'describedBy'
                    }
                }]
        }], propDecorators: { focusIn: [{
                type: HostListener,
                args: ['focus']
            }], show: [{
                type: HostListener,
                args: ['mouseenter']
            }], hide: [{
                type: HostListener,
                args: ['touchstart']
            }, {
                type: HostListener,
                args: ['focusout']
            }], mouseOut: [{
                type: HostListener,
                args: ['mouseleave']
            }] } });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiTooltipModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipModule, imports: [SiTooltipDirective], exports: [SiTooltipDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTooltipModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SiTooltipDirective],
                    exports: [SiTooltipDirective]
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */

/**
 * Generated bundle index. Do not edit.
 */

export { SiTooltipDirective, SiTooltipModule, SiTooltipService };
//# sourceMappingURL=siemens-element-ng-tooltip.mjs.map
