import * as i0 from '@angular/core';
import { inject, ElementRef, Renderer2, Input, HostBinding, Component, input, booleanAttribute, output, ViewContainerRef, computed, effect, Directive, NgModule } from '@angular/core';
import { NgControl } from '@angular/forms';
import { InputDirective } from '@eui/components/shared';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import * as i1 from '@eui/components/directives';
import { EuiClearableDirective, EuiLoadingDirective } from '@eui/components/directives';
import { EuiIconSvgComponent } from '@eui/components/eui-icon';

/**
 * @description
 * A custom input text component that extends InputDirective and provides additional functionality
 * such as validation states, clearable input, and loading states.
 */
class EuiInputTextComponent extends InputDirective {
    constructor() {
        super(...arguments);
        this.control = inject(NgControl, { optional: true, self: true });
        this._elementRef = inject(ElementRef);
        this._renderer = inject(Renderer2);
    }
    /**
     * @description
     * Gets the CSS classes for the component, including validation state classes
     *
     * @returns {string} Space-separated string of CSS class names
     */
    get class() {
        return [super.getCssClasses('eui-input-text'), this._isInvalid ? 'eui-input-text--invalid' : ''].join(' ').trim();
    }
    /**
     * @description
     * Gets or sets the invalid state of the input
     * When used with NgControl, this state is automatically managed based on control state
     *
     * @returns {boolean} Current invalid state
     */
    get isInvalid() {
        return this._isInvalid || null;
    }
    /**
     * @param {BooleanInput} state - The invalid state to set
     */
    set isInvalid(state) {
        this.setInvalid(state);
    }
    /**
     * @description
     * Initializes the component and sets the root class name
     */
    ngOnInit() {
        super.ngOnInit();
        this._renderer.setProperty(this._elementRef.nativeElement, 'rootClassName', 'eui-input-text');
    }
    /**
     * @description
     * Cleans up component resources
     */
    ngOnDestroy() {
        super.ngOnDestroy();
    }
    /**
     * @description
     * Checks and updates the invalid state when using NgControl
     */
    ngDoCheck() {
        if (this.control) {
            this.isInvalid = this.control.invalid && this.control.touched;
        }
    }
    /**
     * @description
     * Sets the invalid state of the input and updates related properties
     *
     * @param {BooleanInput} state - The invalid state to set
     * @protected
     */
    setInvalid(state) {
        // in case it's controlled by NgControl override
        this._isInvalid = this.control ? this.control.invalid && this.control.touched : coerceBooleanProperty(state);
        // set BaseDirective Attribute
        this.euiDanger = this._isInvalid;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: EuiInputTextComponent, isStandalone: true, selector: "input[euiInputText]", inputs: { isInvalid: "isInvalid" }, host: { properties: { "class": "this.class" } }, usesInheritance: true, hostDirectives: [{ directive: i1.EuiClearableDirective, inputs: ["euiClearable", "euiClearable", "readonly", "readonly", "disabled", "disabled"] }, { directive: i1.EuiLoadingDirective, inputs: ["euiLoading", "euiLoading", "readonly", "readonly"] }], ngImport: i0, template: '', isInline: true, styles: [".eui-19 :host.eui-input-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--eui-f-m);appearance:none;background-color:var(--eui-c-surface-container);border:1px solid var(--eui-c-s-secondary-border-light);border-radius:var(--eui-br-m);box-shadow:none;color:var(--eui-c-text);padding:calc(var(--eui-s-xs) - 1px) calc(var(--eui-s-m) - 1px);width:100%}.eui-19 :host.eui-input-text:focus:not([readonly]){outline:2px solid var(--eui-c-focus)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text:focus-visible:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text [tabindex=\"0\"]:focus:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text:not([hidden]){display:block}.eui-19 :host.eui-input-text::placeholder{color:var(--eui-c-text-lighter)!important;opacity:1}.eui-19 :host.eui-input-text[readonly]{background-color:transparent;border-color:transparent;box-shadow:none;height:inherit;padding-left:0;padding-right:0;pointer-events:none}.eui-19 :host.eui-input-text[readonly]+.eui-feedback-message,.eui-19 :host.eui-input-text[readonly]+.eui-input-maxlength{appearance:none;display:none}.eui-19 :host.eui-input-text[disabled]:not([readonly]),.eui-19 :host.eui-input-text--disabled:not([readonly]){background-color:var(--eui-c-s-secondary-surface-light)!important;border:1px solid var(--eui-c-s-secondary-border-lighter);color:var(--eui-c-text-light);pointer-events:none}.eui-19 :host.eui-input-text--invalid,.eui-19 :host.eui-input-text--danger{border:1px solid var(--eui-c-s-danger-border)}.eui-19 :host.eui-input-text--loading{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-input-text--loading-icon{align-items:center;display:flex}.eui-19 :host.eui-input-text--loading-icon:after,.eui-19 :host.eui-input-text--loading-icon:before{content:\"\";height:var(--eui-s-l);position:absolute;right:var(--eui-s-s);width:var(--eui-s-l)}.eui-19 :host.eui-input-text--loading-icon:before{border:var(--eui-s-2xs) solid rgba(0,0,0,.35);border-radius:100%}.eui-19 :host.eui-input-text--loading-icon:after{animation:loading .6s linear;animation-iteration-count:infinite;border-color:var(--eui-c-white) transparent transparent;border-radius:100%;border-style:solid;border-width:var(--eui-s-2xs);box-shadow:0 0 0 1px transparent}.eui-19 :host.eui-input-text--loading-icon--sm:after,.eui-19 :host.eui-input-text--loading-icon--sm:before{height:var(--eui-s-m);width:var(--eui-s-m)}@keyframes loading{to{transform:rotate(360deg)}}.eui-19 :host.eui-input-text--clearable{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-input-text[readonly]{pointer-events:auto}.eui-19 :host.eui-input-text[type=search]::-webkit-search-cancel-button{display:none}\n"] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextComponent, decorators: [{
            type: Component,
            args: [{ selector: 'input[euiInputText]', template: '', hostDirectives: [
                        {
                            directive: EuiClearableDirective,
                            inputs: ['euiClearable', 'readonly', 'disabled'],
                        },
                        {
                            directive: EuiLoadingDirective,
                            inputs: ['euiLoading', 'readonly'],
                        },
                    ], styles: [".eui-19 :host.eui-input-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--eui-f-m);appearance:none;background-color:var(--eui-c-surface-container);border:1px solid var(--eui-c-s-secondary-border-light);border-radius:var(--eui-br-m);box-shadow:none;color:var(--eui-c-text);padding:calc(var(--eui-s-xs) - 1px) calc(var(--eui-s-m) - 1px);width:100%}.eui-19 :host.eui-input-text:focus:not([readonly]){outline:2px solid var(--eui-c-focus)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text:focus-visible:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text [tabindex=\"0\"]:focus:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-input-text:not([hidden]){display:block}.eui-19 :host.eui-input-text::placeholder{color:var(--eui-c-text-lighter)!important;opacity:1}.eui-19 :host.eui-input-text[readonly]{background-color:transparent;border-color:transparent;box-shadow:none;height:inherit;padding-left:0;padding-right:0;pointer-events:none}.eui-19 :host.eui-input-text[readonly]+.eui-feedback-message,.eui-19 :host.eui-input-text[readonly]+.eui-input-maxlength{appearance:none;display:none}.eui-19 :host.eui-input-text[disabled]:not([readonly]),.eui-19 :host.eui-input-text--disabled:not([readonly]){background-color:var(--eui-c-s-secondary-surface-light)!important;border:1px solid var(--eui-c-s-secondary-border-lighter);color:var(--eui-c-text-light);pointer-events:none}.eui-19 :host.eui-input-text--invalid,.eui-19 :host.eui-input-text--danger{border:1px solid var(--eui-c-s-danger-border)}.eui-19 :host.eui-input-text--loading{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-input-text--loading-icon{align-items:center;display:flex}.eui-19 :host.eui-input-text--loading-icon:after,.eui-19 :host.eui-input-text--loading-icon:before{content:\"\";height:var(--eui-s-l);position:absolute;right:var(--eui-s-s);width:var(--eui-s-l)}.eui-19 :host.eui-input-text--loading-icon:before{border:var(--eui-s-2xs) solid rgba(0,0,0,.35);border-radius:100%}.eui-19 :host.eui-input-text--loading-icon:after{animation:loading .6s linear;animation-iteration-count:infinite;border-color:var(--eui-c-white) transparent transparent;border-radius:100%;border-style:solid;border-width:var(--eui-s-2xs);box-shadow:0 0 0 1px transparent}.eui-19 :host.eui-input-text--loading-icon--sm:after,.eui-19 :host.eui-input-text--loading-icon--sm:before{height:var(--eui-s-m);width:var(--eui-s-m)}@keyframes loading{to{transform:rotate(360deg)}}.eui-19 :host.eui-input-text--clearable{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-input-text[readonly]{pointer-events:auto}.eui-19 :host.eui-input-text[type=search]::-webkit-search-cancel-button{display:none}\n"] }]
        }], propDecorators: { class: [{
                type: HostBinding,
                args: ['class']
            }], isInvalid: [{
                type: Input
            }] } });

/**
 * @description
 * Directive to add an icon to an eui-input-text element, allowing for click events too.
 *
 * @example
 * <input euiInputText euiIcon="eye:filled">
 */
class EuiIconDirective {
    get cssClasses() {
        return [this._cssClasses, this.euiIcon()?.icon ? `${this._elementRef.nativeElement.rootClassName}--loading` : ''].join(' ').trim();
    }
    set cssClasses(value) {
        this._cssClasses = value;
    }
    constructor() {
        this.euiIcon = input();
        this.readonly = input(null, { transform: booleanAttribute });
        this.iconClick = output();
        this._elementRef = inject(ElementRef);
        this._viewContainerRef = inject(ViewContainerRef);
        this._renderer = inject(Renderer2);
        this.listeners = [];
        this.clickable = computed(() => this.euiIcon()?.clickable ?? false);
        this.icon = computed(() => this.euiIcon()?.icon);
        this.iconColour = computed(() => this.euiIcon()?.colour);
        this.DEFAULT_ICON_COLOUR = 'neutral-lighter';
        effect(() => {
            this._readonly = this.readonly() ? '' : null;
            if (this.readonly()) {
                this.removeIcon();
                this.removeFlexWrapper();
            }
            else if (this.euiIcon()?.icon && this.readonly() === false) {
                // create wrapper
                this.createFlexWrapper();
                // dynamically create the icon
                this.createIcon();
                this._renderer.appendChild(this._euiUFlexWrapper, this._icon.location.nativeElement);
            }
        });
        effect(() => {
            const icon = this.icon();
            if (!icon) {
                this.removeIcon();
                this.removeFlexWrapper();
            }
            else if (!this._icon && !this.readonly()) {
                this.createFlexWrapper();
                this.createIcon();
            }
            else if (this._icon) {
                this._icon.setInput('icon', icon);
            }
        });
        effect(() => {
            const clickable = this.clickable();
            if (!clickable) {
                this._renderer.removeAttribute(this._icon.location.nativeElement, 'tabindex');
                this._renderer.setStyle(this._icon.location.nativeElement, 'pointer-events', 'none');
            }
            else {
                this._renderer.setAttribute(this._icon.location.nativeElement, 'tabindex', '0');
                this._icon.setInput('ariaHidden', false);
                this._icon.setInput('focusable', true);
                this._icon.setInput('aria-label', this.euiIcon()?.ariaLabel || 'Input icon');
                this._renderer.removeStyle(this._icon.location.nativeElement, 'pointer-events');
            }
        });
        effect(() => {
            const iconColour = this.iconColour();
            if (this._icon) {
                this._icon.setInput('fillColor', iconColour || this.DEFAULT_ICON_COLOUR);
            }
        });
    }
    ngOnDestroy() {
        // Clean up listeners
        this.listeners?.forEach(listener => listener());
        this.listeners = [];
    }
    /**
     * create a flex wrapper for the input to hold the icon
     *
     * @private
     */
    createFlexWrapper() {
        if (!this._euiUFlexWrapper && !this.doesParentHasAFlexWrapper()) {
            this._euiUFlexWrapper = this._renderer.createElement('div');
            this._renderer.addClass(this._euiUFlexWrapper, 'eui-u-flex');
            this._renderer.setAttribute(this._euiUFlexWrapper, 'flexWrapper', null);
            this._renderer.setStyle(this._euiUFlexWrapper, 'position', 'relative');
            this._renderer.insertBefore(this._elementRef.nativeElement.parentElement, this._euiUFlexWrapper, this._elementRef.nativeElement);
            this._renderer.appendChild(this._euiUFlexWrapper, this._elementRef.nativeElement);
        }
        if (!this._euiUFlexWrapper && this.doesParentHasAFlexWrapper()) {
            this._euiUFlexWrapper = this._elementRef.nativeElement.parentElement;
        }
    }
    /**
     * checks if the parent has a flexWrapper. This is used to avoid creating multiple flexWrappers
     *
     * @private
     */
    doesParentHasAFlexWrapper() {
        return this._elementRef.nativeElement.parentElement.hasAttribute('flexWrapper');
    }
    /**
     * removes the flexWrapper while keeping the input element intact
     *
     * @private
     */
    removeFlexWrapper() {
        if (this._euiUFlexWrapper) {
            this._renderer.insertBefore(this._euiUFlexWrapper.parentElement, this._elementRef.nativeElement, this._euiUFlexWrapper);
            this._renderer.removeChild(this._euiUFlexWrapper.parentElement, this._euiUFlexWrapper);
            this._euiUFlexWrapper.remove();
            this._euiUFlexWrapper = null;
        }
    }
    registerIconClickListener() {
        this.listeners.push(this._renderer.listen(this._icon.location.nativeElement, 'click', this.onIconClicked.bind(this)), this._renderer.listen(this._icon.location.nativeElement, 'keydown.enter', this.onIconClicked.bind(this)), this._renderer.listen(this._icon.location.nativeElement, 'focus', () => {
            if (!this.readonly() && this.euiIcon()?.clickable) {
                this._renderer.setStyle(this._icon.location.nativeElement, 'transition', 'none');
                this._renderer.setStyle(this._icon.location.nativeElement, 'outline-offset', '-2px !important');
                this._renderer.setStyle(this._icon.location.nativeElement, 'outline', '2px solid var(--eui-c-focus-visible) !important');
            }
        }), this._renderer.listen(this._icon.location.nativeElement, 'blur', () => {
            this._renderer.removeStyle(this._icon.location.nativeElement, 'outline');
            this._renderer.removeStyle(this._icon.location.nativeElement, 'outline-offset');
            this._renderer.removeStyle(this._icon.location.nativeElement, 'transition');
        }));
    }
    /**
     * creates the icon component
     *
     * @private
     */
    createIcon() {
        if (!this._icon) {
            this._icon = this._viewContainerRef.createComponent(EuiIconSvgComponent);
            this._icon.instance.isInputIcon = true;
            this._icon.instance.euiEnd = true;
            this._icon.instance.icon = this.euiIcon()?.icon;
            this._icon.instance.ariaLabel = this.euiIcon()?.ariaLabel;
            this._icon.instance.fillColor = this.euiIcon()?.colour || this.DEFAULT_ICON_COLOUR;
            this.registerIconClickListener();
            this._renderer.appendChild(this._euiUFlexWrapper, this._icon.location.nativeElement);
        }
    }
    /**
     * @description
     * Handles the click event on the icon.
     */
    onIconClicked() {
        this.iconClick.emit();
    }
    /**
     * removes the icon component
     *
     * @private
     */
    removeIcon() {
        if (this._icon) {
            const index = this._viewContainerRef.indexOf(this._icon.hostView);
            this._viewContainerRef.detach(index);
            this._icon = null;
            // Clean up listeners
            this.listeners.forEach(listener => listener());
            this.listeners = [];
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: EuiIconDirective, isStandalone: true, selector: "input[euiInputText][euiIcon]", inputs: { euiIcon: { classPropertyName: "euiIcon", publicName: "euiIcon", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, host: { properties: { "class": "this.cssClasses", "attr.readonly": "this._readonly" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiIconDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[euiInputText][euiIcon]',
                }]
        }], ctorParameters: () => [], propDecorators: { cssClasses: [{
                type: HostBinding,
                args: ['class']
            }], _readonly: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

/**
 * @description
 * Module that provides the EuiInputText component and its dependencies
 *
 * @deprecated
 * Use {@link `EuiInputTextComponent`} instead. This module is deprecated and
 * will be removed in the next major version of the library.
 */
class EuiInputTextModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextModule, imports: [EuiInputTextComponent], exports: [EuiInputTextComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiInputTextModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [EuiInputTextComponent],
                    exports: [EuiInputTextComponent],
                }]
        }] });

const EUI_INPUT_TEXT = [
    EuiInputTextComponent,
];
// export { EuiInputTextComponent as EuiInputText } from './eui-input-text.component';

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

export { EUI_INPUT_TEXT, EuiIconDirective, EuiInputTextComponent, EuiInputTextModule };
//# sourceMappingURL=eui-components-eui-input-text.mjs.map
