import * as i0 from '@angular/core';
import { input, booleanAttribute, computed, inject, ElementRef, Renderer2, ViewContainerRef, effect, TemplateRef, Directive, NgModule } from '@angular/core';
import { FD_ICON_COMPONENT } from '@fundamental-ngx/core/icon';
import { buildPopoverConfig, PopoverService } from '@fundamental-ngx/core/popover';

const INLINE_HELP_CLASS = 'fd-popover__body--inline-help fd-inline-help__content';
const INLINE_HELP_ICON_CLASS = 'fd-popover__body--inline-help-with-icon';
/** Default trigger configuration for inline help */
const DEFAULT_TRIGGERS = [
    { trigger: 'mouseenter', openAction: true, closeAction: false },
    { trigger: 'mouseleave', openAction: false, closeAction: true },
    { trigger: 'focusin', openAction: true, closeAction: false },
    { trigger: 'focusout', openAction: false, closeAction: true }
];
let inlineHelpId = 0;
/**
 * The component that represents an inline-help.
 * Inline help is used to display help text in a popover, often inline with headers, body text and form labels.
 */
class InlineHelpDirective {
    /** @hidden */
    constructor() {
        /** Inline help text to display inside generated popover */
        this.inlineHelpContent = input('', { ...(ngDevMode ? { debugName: "inlineHelpContent" } : {}), alias: 'fd-inline-help' });
        /** Popover placement */
        this.placement = input(null, ...(ngDevMode ? [{ debugName: "placement" }] : []));
        /**
         * The trigger events that will open/close the inline help component.
         * Accepts any HTML DOM Events or TriggerConfig objects.
         * @default mouseenter/mouseleave and focusin/focusout
         */
        this.triggers = input(DEFAULT_TRIGGERS, ...(ngDevMode ? [{ debugName: "triggers" }] : []));
        /** Whether the popover should close when a click is made outside its boundaries. */
        this.closeOnOutsideClick = input(false, { ...(ngDevMode ? { debugName: "closeOnOutsideClick" } : {}), transform: booleanAttribute });
        /** Additional CSS class(es) to apply to the popover body. */
        this.additionalBodyClass = input(null, ...(ngDevMode ? [{ debugName: "additionalBodyClass" }] : []));
        /** Whether the inline help is disabled. */
        this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), transform: booleanAttribute });
        /** ID for the Inline Help Popover body */
        this.bodyId = input(`fd-inline-help-${inlineHelpId++}`, ...(ngDevMode ? [{ debugName: "bodyId" }] : []));
        /** aria-role for the Inline Help Popover body */
        this.bodyRole = input('tooltip', ...(ngDevMode ? [{ debugName: "bodyRole" }] : []));
        /** Whether the popover should have an arrow. */
        this.noArrow = input(false, { ...(ngDevMode ? { debugName: "noArrow" } : {}), transform: booleanAttribute });
        /** Whether the popover should close when the escape key is pressed. */
        this.closeOnEscapeKey = input(false, { ...(ngDevMode ? { debugName: "closeOnEscapeKey" } : {}), transform: booleanAttribute });
        /** Whether to close the popover on router navigation start. */
        this.closeOnNavigation = input(true, { ...(ngDevMode ? { debugName: "closeOnNavigation" } : {}), transform: booleanAttribute });
        /** Whether to restore focus to the previously focused element when the popover closes. */
        this.restoreFocusOnClose = input(true, { ...(ngDevMode ? { debugName: "restoreFocusOnClose" } : {}), transform: booleanAttribute });
        /** The element to which the overlay is attached. By default it is body. */
        this.appendTo = input(null, ...(ngDevMode ? [{ debugName: "appendTo" }] : []));
        /** Whether position should remain fixed when approaching page corners. */
        this.fixedPosition = input(false, { ...(ngDevMode ? { debugName: "fixedPosition" } : {}), transform: booleanAttribute });
        /** Maximum width of popover body in px. */
        this.maxWidth = input(null, ...(ngDevMode ? [{ debugName: "maxWidth" }] : []));
        /** CDK scroll strategy applied to the inline help overlay. */
        this.scrollStrategy = input(null, ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : []));
        /** @hidden Combined internal + user-provided body classes. */
        this.combinedBodyClass = computed(() => {
            const parts = [this._additionalBodyClass];
            const userClass = this.additionalBodyClass();
            if (userClass) {
                parts.push(userClass);
            }
            return parts.join(' ');
        }, ...(ngDevMode ? [{ debugName: "combinedBodyClass" }] : []));
        /** @hidden Popover configuration computed from all inputs. */
        this.popoverConfig = buildPopoverConfig({
            placement: () => this.placement() ?? 'bottom',
            triggers: this.triggers,
            noArrow: this.noArrow,
            closeOnEscapeKey: this.closeOnEscapeKey,
            closeOnOutsideClick: this.closeOnOutsideClick,
            closeOnNavigation: this.closeOnNavigation,
            restoreFocusOnClose: this.restoreFocusOnClose,
            appendTo: this.appendTo,
            fixedPosition: this.fixedPosition,
            maxWidth: this.maxWidth,
            scrollStrategy: this.scrollStrategy,
            additionalBodyClass: this.combinedBodyClass,
            disabled: this.disabled,
            bodyRole: this.bodyRole,
            bodyId: this.bodyId
        });
        /** @hidden */
        this._popoverService = inject(PopoverService);
        /** @hidden */
        this._elementRef = inject(ElementRef);
        /** @hidden */
        this._renderer = inject(Renderer2);
        /** @hidden */
        this._viewContainerRef = inject(ViewContainerRef);
        /** @hidden */
        this._icon = inject(FD_ICON_COMPONENT, { optional: true, self: true });
        /** @hidden */
        this._additionalBodyClass = '';
        /** @hidden */
        this._srViewRef = null;
        /** @hidden */
        this._initialised = false;
        this._applyAdditionalInlineHelpClass();
        // Effect to initialise and reactively update the popover config
        effect(() => {
            const config = this.popoverConfig();
            if (!this._initialised) {
                this._popoverService.initialise(this._elementRef, config);
                this._initialised = true;
            }
            else {
                this._popoverService.refreshConfiguration(config);
            }
        });
        // Effect to watch for content changes
        effect(() => {
            const content = this.inlineHelpContent();
            const text = typeof content === 'string' ? content : null;
            const template = content instanceof TemplateRef ? content : null;
            this._popoverService.updateContent(text, template);
            this._setupScreenreaderElement(content);
        });
    }
    /** @hidden */
    _applyAdditionalInlineHelpClass() {
        let classes = INLINE_HELP_CLASS;
        // If connected to the icon, but not button, then apply additional class
        // That will change the arrow's position a bit
        if (this._icon) {
            classes += ' ' + INLINE_HELP_ICON_CLASS;
        }
        this._additionalBodyClass = classes;
    }
    /** @hidden */
    _setupScreenreaderElement(content) {
        this._viewContainerRef.clear();
        // Destroy previous embedded view if any
        if (this._srViewRef) {
            this._srViewRef.destroy();
            this._srViewRef = null;
        }
        let srElement = this._renderer.createElement('span');
        if (typeof content === 'string') {
            srElement.innerText = content;
        }
        else if (content) {
            this._srViewRef = content.createEmbeddedView(null);
            if (this._srViewRef.rootNodes[0] instanceof Text) {
                srElement.innerText = this._srViewRef.rootNodes[0].textContent;
            }
            else {
                srElement = this._srViewRef.rootNodes[0];
            }
        }
        if (srElement.style) {
            srElement.style.cssText = `position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px);`;
        }
        this._renderer.appendChild(this._elementRef.nativeElement, srElement);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: InlineHelpDirective, isStandalone: true, selector: "[fd-inline-help]:not([fd-inline-help-template]), [fd-inline-help-template]:not([fd-inline-help])", inputs: { inlineHelpContent: { classPropertyName: "inlineHelpContent", publicName: "fd-inline-help", 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 }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, additionalBodyClass: { classPropertyName: "additionalBodyClass", publicName: "additionalBodyClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, bodyId: { classPropertyName: "bodyId", publicName: "bodyId", isSignal: true, isRequired: false, transformFunction: null }, bodyRole: { classPropertyName: "bodyRole", publicName: "bodyRole", isSignal: true, isRequired: false, transformFunction: null }, noArrow: { classPropertyName: "noArrow", publicName: "noArrow", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeKey: { classPropertyName: "closeOnEscapeKey", publicName: "closeOnEscapeKey", isSignal: true, isRequired: false, transformFunction: null }, closeOnNavigation: { classPropertyName: "closeOnNavigation", publicName: "closeOnNavigation", isSignal: true, isRequired: false, transformFunction: null }, restoreFocusOnClose: { classPropertyName: "restoreFocusOnClose", publicName: "restoreFocusOnClose", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, fixedPosition: { classPropertyName: "fixedPosition", publicName: "fixedPosition", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, scrollStrategy: { classPropertyName: "scrollStrategy", publicName: "scrollStrategy", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.fd-inline-help__trigger": "true", "attr.aria-describedby": "bodyId()" } }, providers: [PopoverService], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpDirective, decorators: [{
            type: Directive,
            args: [{
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    selector: '[fd-inline-help]:not([fd-inline-help-template]), [fd-inline-help-template]:not([fd-inline-help])',
                    providers: [PopoverService],
                    host: {
                        '[class.fd-inline-help__trigger]': 'true',
                        '[attr.aria-describedby]': 'bodyId()'
                    }
                }]
        }], ctorParameters: () => [], propDecorators: { inlineHelpContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "fd-inline-help", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], triggers: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggers", required: false }] }], closeOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsideClick", required: false }] }], additionalBodyClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalBodyClass", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], bodyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyId", required: false }] }], bodyRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyRole", required: false }] }], noArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "noArrow", required: false }] }], closeOnEscapeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscapeKey", required: false }] }], closeOnNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnNavigation", required: false }] }], restoreFocusOnClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocusOnClose", required: false }] }], appendTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendTo", required: false }] }], fixedPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fixedPosition", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], scrollStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStrategy", required: false }] }] } });

/**
 * @deprecated
 * Use direct imports of components and directives.
 */
class InlineHelpModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpModule, imports: [InlineHelpDirective], exports: [InlineHelpDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InlineHelpModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [InlineHelpDirective],
                    exports: [InlineHelpDirective]
                }]
        }] });

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

export { InlineHelpDirective, InlineHelpModule };
//# sourceMappingURL=fundamental-ngx-core-inline-help.mjs.map
