import * as i0 from '@angular/core';
import { inject, Renderer2, Injector, ElementRef, ViewContainerRef, booleanAttribute, HostListener, Input, HostBinding, Component, forwardRef, Directive, NgModule } from '@angular/core';
import { NgControl, SelectControlValueAccessor, NG_VALUE_ACCESSOR, SelectMultipleControlValueAccessor, ɵNgSelectMultipleOption as _NgSelectMultipleOption, NgSelectOption } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { EuiInputTextComponent } from '@eui/components/eui-input-text';

class EuiSelectComponent {
    constructor() {
        this.ariaLabel = 'Select an option';
        this.renderer = inject(Renderer2);
        this.injector = inject(Injector);
        this.elementRef = inject(ElementRef);
        this.viewContainerRef = inject(ViewContainerRef);
    }
    get isInvalid() {
        return this._isInvalid || null;
    }
    set isInvalid(state) {
        this._isInvalid = coerceBooleanProperty(state);
        if (this._isInvalid) {
            this.renderer.addClass(this.elementRef.nativeElement, 'eui-select--invalid');
        }
        else {
            this.renderer.removeClass(this.elementRef.nativeElement, 'eui-select--invalid');
        }
    }
    ngOnInit() {
        this.renderer.addClass(this.elementRef.nativeElement, 'eui-select');
    }
    ngOnChanges(changes) {
        if (changes['readonly']) {
            if (this.readonly) {
                // hide select element
                this.renderer.setAttribute(this.elementRef.nativeElement, 'readonly', 'true');
                this.renderer.setAttribute(this.elementRef.nativeElement, 'hidden', '');
                // create an euiInputComponent to hold the value (for accessibility reasons)
                this.readonlyInput = this.createReadonlyElement();
                this.renderer.insertBefore(this.elementRef.nativeElement.parentElement, this.elementRef.nativeElement, this.readonlyInput.location.nativeElement);
                this.setReadonlyValue(this.readonlyInput);
            }
            else {
                this.readonlyInput?.destroy();
                this.renderer.removeAttribute(this.elementRef.nativeElement, 'readonly');
                this.renderer.removeAttribute(this.elementRef.nativeElement, 'hidden');
            }
        }
        if (changes['placeholder']) {
            this.control = this.injector.get(NgControl, undefined, { optional: true });
            if (!this.control) {
                // in case option Element already created update the value
                if (changes['placeholder'].currentValue === undefined) {
                    this.renderer.removeClass(this.elementRef.nativeElement, 'eui-select__placeholder');
                    // remove option element
                    if (this.placeholderOption) {
                        this.renderer.removeChild(this.elementRef.nativeElement, this.placeholderOption);
                        this.placeholderOption = undefined;
                    }
                }
                else if (this.placeholderOption) {
                    this.renderer.setProperty(this.placeholderOption, 'innerText', changes['placeholder'].currentValue);
                }
                else {
                    // create option Element
                    this.placeholderOption = this.renderer.createElement('option');
                    this.renderer.addClass(this.placeholderOption, 'eui-select__placeholder');
                    this.renderer.setProperty(this.placeholderOption, 'innerText', changes['placeholder'].currentValue);
                    // set attributes to act as a placeholder
                    if (!this.elementRef.nativeElement.value) {
                        this.renderer.setAttribute(this.placeholderOption, 'selected', '');
                    }
                    // append option element as the first of the select children
                    this.elementRef.nativeElement.insertBefore(this.placeholderOption, this.elementRef.nativeElement.firstChild);
                    if (this.elementRef.nativeElement.value === changes['placeholder'].currentValue) {
                        this.renderer.addClass(this.elementRef.nativeElement, 'eui-select__placeholder');
                    }
                }
            }
        }
    }
    ngDoCheck() {
        if (!this.control) {
            this.control = this.injector.get(NgControl, undefined, { optional: true });
        }
        this.isInvalid = this.control ? this.control.invalid && this.control.touched : this._isInvalid;
        /** while the optionList changes but there's no selected option and there's a placeholder, add the placeholder
         *  class. Otherwise, the placeholder will look selected but the color will be black. */
        if (this.placeholder && this.elementRef.nativeElement.selectedIndex === 0) {
            this.renderer.addClass(this.elementRef.nativeElement, 'eui-select__placeholder');
        }
    }
    onChange(value) {
        this.control = this.injector.get(NgControl, undefined, { optional: true });
        if (!this.control) {
            this.setPlaceholderClass(this.placeholder === value ? undefined : value);
        }
        this.syncReadOnlyValue();
    }
    syncReadOnlyValue() {
        this.setReadonlyValue(this.readonlyInput);
    }
    /**
     * set readonly value from selected options presented as comma separated string
     *
     * @param readonlyRef the input element to set the value
     * @private
     */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    setReadonlyValue(readonlyRef) {
        if (readonlyRef) {
            // eslint-disable-next-line prefer-spread
            const selectedOptions = Array.apply(null, this.elementRef.nativeElement.selectedOptions)
                .map((i) => i.text)
                .filter((i) => i !== this.placeholder)
                .join(', ');
            this.renderer.setProperty(readonlyRef.location.nativeElement, 'value', selectedOptions);
            this.renderer.setAttribute(readonlyRef.location.nativeElement, 'aria-label', selectedOptions);
        }
    }
    /**
     * create readonly element
     *
     * @private
     */
    createReadonlyElement() {
        const componentRef = this.viewContainerRef.createComponent(EuiInputTextComponent);
        componentRef.instance.readonly = true;
        return componentRef;
    }
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    setPlaceholderClass(value) {
        const placeholderOption = this.elementRef.nativeElement.options[0];
        if (!!this.placeholder && (value === undefined || value === null || value === '')) {
            this.renderer.setAttribute(placeholderOption, 'selected', '');
            this.renderer.addClass(this.elementRef.nativeElement, 'eui-select__placeholder');
        }
        else {
            this.renderer.removeClass(this.elementRef.nativeElement, 'eui-select__placeholder');
            this.renderer.removeAttribute(placeholderOption, 'selected');
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "19.2.17", type: EuiSelectComponent, isStandalone: true, selector: "select[euiSelect]", inputs: { ariaLabel: "ariaLabel", placeholder: "placeholder", readonly: ["readonly", "readonly", booleanAttribute], isInvalid: "isInvalid" }, host: { listeners: { "change": "onChange($event.target.value)" }, properties: { "attr.aria-label": "this.ariaLabel" } }, usesOnChanges: true, ngImport: i0, template: '<ng-content/>', isInline: true, styles: [".eui-19 :host.eui-select{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-select:not([hidden]){display:block}.eui-19 :host.eui-select::placeholder{color:var(--eui-c-text-lighter)!important;opacity:1}.eui-19 :host.eui-select[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-select[readonly]+.eui-feedback-message,.eui-19 :host.eui-select[readonly]+.eui-input-maxlength{appearance:none;display:none}.eui-19 :host.eui-select[disabled]:not([readonly]),.eui-19 :host.eui-select--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-select--invalid,.eui-19 :host.eui-select--danger{border:1px solid var(--eui-c-s-danger-border)}.eui-19 :host.eui-select--loading{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-select--loading-icon{align-items:center;display:flex}.eui-19 :host.eui-select--loading-icon:after,.eui-19 :host.eui-select--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-select--loading-icon:before{border:var(--eui-s-2xs) solid rgba(0,0,0,.35);border-radius:100%}.eui-19 :host.eui-select--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-select--loading-icon--sm:after,.eui-19 :host.eui-select--loading-icon--sm:before{height:var(--eui-s-m);width:var(--eui-s-m)}@keyframes loading{to{transform:rotate(360deg)}}.eui-19 :host.eui-select--clearable{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-select{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eui-19 :host.eui-select::-webkit-scrollbar{display:inherit;height:10px;width:10px;background-color:var(--eui-c-s-secondary-surface-light)}.eui-19 :host.eui-select::-webkit-scrollbar-thumb{background-color:var(--_eui-scrollbars-foreground-color);border-radius:5rem;background-clip:padding-box;border:2px solid transparent}.eui-19 :host.eui-select::-webkit-scrollbar-thumb:hover{background-color:var(--eui-c-s-secondary-surface);border:0;cursor:grab}.eui-19 :host.eui-select:focus::-webkit-scrollbar-thumb{background-color:var(--eui-c-s-primary-surface);outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important}.eui-19 :host.eui-select:focus-visible::-webkit-scrollbar-thumb{background-color:var(--eui-c-s-primary-surface);outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important}.eui-19 :host.eui-select::-webkit-scrollbar-track{background-color:var(--eui-c-s-secondary-surface-light);border-radius:0}@-moz-document url-prefix(){.eui-19 :host.eui-select{scrollbar-color:var(--eui-c-s-secondary-surface) var(--eui-c-s-secondary-surface-light);scrollbar-width:auto}}@-moz-document url-prefix(){.eui-19 :host.eui-select:focus,.eui-19 :host.eui-select:focus-visible{scrollbar-color:var(--eui-c-focus-visible) var(--eui-c-s-secondary-surface-light)}}.eui-19 :host.eui-select:focus:not([readonly]){outline:2px solid var(--eui-c-focus)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select:focus-visible:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select [tabindex=\"0\"]:focus:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select{color:var(--eui-c-text);overflow-y:auto}.eui-19 :host.eui-select[readonly][multiple=true] option:checked{background:none}.eui-19 :host.eui-select[hidden],.eui-19 :host.eui-select[readonly][multiple=true] :not(option:checked){display:none}.eui-19 :host.eui-select[multiple=true],.eui-19 :host.eui-select[size]:not([size=\"1\"]):not([size=\"0\"]){background-image:none;height:auto;overflow:auto;padding:var(--eui-s-2xs) 0}.eui-19 :host.eui-select__item{color:var(--eui-c-text)}.eui-19 :host.eui-select optgroup{font:var(--eui-f-m-bold)}.eui-19 :host.eui-select optgroup,.eui-19 :host.eui-select option{appearance:none;color:var(--eui-c-text);display:block;padding:var(--eui-s-2xs);white-space:pre}.eui-19 :host.eui-select optgroup.eui-select__placeholder,.eui-19 :host.eui-select option.eui-select__placeholder{color:var(--eui-c-text-lighter)}.eui-19 :host.eui-select optgroup:disabled,.eui-19 :host.eui-select option:disabled{color:var(--eui-c-disabled)}.eui-19 :host.eui-select:not([readonly]):not([multiple]),.eui-19 :host.eui-select[size=\"1\"],.eui-19 :host.eui-select[size=\"0\"]{appearance:none;background-color:var(--eui-c-surface-container);background-image:var(--eui-internal-icon-chevron-down-path);background-position:calc(100% - var(--eui-s-s)) center;background-repeat:no-repeat;background-size:var(--eui-s-m);padding-right:var(--eui-s-2xl)}\n"] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectComponent, decorators: [{
            type: Component,
            args: [{ selector: 'select[euiSelect]', template: '<ng-content/>', styles: [".eui-19 :host.eui-select{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-select:not([hidden]){display:block}.eui-19 :host.eui-select::placeholder{color:var(--eui-c-text-lighter)!important;opacity:1}.eui-19 :host.eui-select[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-select[readonly]+.eui-feedback-message,.eui-19 :host.eui-select[readonly]+.eui-input-maxlength{appearance:none;display:none}.eui-19 :host.eui-select[disabled]:not([readonly]),.eui-19 :host.eui-select--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-select--invalid,.eui-19 :host.eui-select--danger{border:1px solid var(--eui-c-s-danger-border)}.eui-19 :host.eui-select--loading{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-select--loading-icon{align-items:center;display:flex}.eui-19 :host.eui-select--loading-icon:after,.eui-19 :host.eui-select--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-select--loading-icon:before{border:var(--eui-s-2xs) solid rgba(0,0,0,.35);border-radius:100%}.eui-19 :host.eui-select--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-select--loading-icon--sm:after,.eui-19 :host.eui-select--loading-icon--sm:before{height:var(--eui-s-m);width:var(--eui-s-m)}@keyframes loading{to{transform:rotate(360deg)}}.eui-19 :host.eui-select--clearable{padding-right:var(--eui-s-4xl)}.eui-19 :host.eui-select{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eui-19 :host.eui-select::-webkit-scrollbar{display:inherit;height:10px;width:10px;background-color:var(--eui-c-s-secondary-surface-light)}.eui-19 :host.eui-select::-webkit-scrollbar-thumb{background-color:var(--_eui-scrollbars-foreground-color);border-radius:5rem;background-clip:padding-box;border:2px solid transparent}.eui-19 :host.eui-select::-webkit-scrollbar-thumb:hover{background-color:var(--eui-c-s-secondary-surface);border:0;cursor:grab}.eui-19 :host.eui-select:focus::-webkit-scrollbar-thumb{background-color:var(--eui-c-s-primary-surface);outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important}.eui-19 :host.eui-select:focus-visible::-webkit-scrollbar-thumb{background-color:var(--eui-c-s-primary-surface);outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important}.eui-19 :host.eui-select::-webkit-scrollbar-track{background-color:var(--eui-c-s-secondary-surface-light);border-radius:0}@-moz-document url-prefix(){.eui-19 :host.eui-select{scrollbar-color:var(--eui-c-s-secondary-surface) var(--eui-c-s-secondary-surface-light);scrollbar-width:auto}}@-moz-document url-prefix(){.eui-19 :host.eui-select:focus,.eui-19 :host.eui-select:focus-visible{scrollbar-color:var(--eui-c-focus-visible) var(--eui-c-s-secondary-surface-light)}}.eui-19 :host.eui-select:focus:not([readonly]){outline:2px solid var(--eui-c-focus)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select:focus-visible:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select [tabindex=\"0\"]:focus:not([readonly]){outline:2px solid var(--eui-c-focus-visible)!important;outline-offset:-2px!important;transition:none}.eui-19 :host.eui-select{color:var(--eui-c-text);overflow-y:auto}.eui-19 :host.eui-select[readonly][multiple=true] option:checked{background:none}.eui-19 :host.eui-select[hidden],.eui-19 :host.eui-select[readonly][multiple=true] :not(option:checked){display:none}.eui-19 :host.eui-select[multiple=true],.eui-19 :host.eui-select[size]:not([size=\"1\"]):not([size=\"0\"]){background-image:none;height:auto;overflow:auto;padding:var(--eui-s-2xs) 0}.eui-19 :host.eui-select__item{color:var(--eui-c-text)}.eui-19 :host.eui-select optgroup{font:var(--eui-f-m-bold)}.eui-19 :host.eui-select optgroup,.eui-19 :host.eui-select option{appearance:none;color:var(--eui-c-text);display:block;padding:var(--eui-s-2xs);white-space:pre}.eui-19 :host.eui-select optgroup.eui-select__placeholder,.eui-19 :host.eui-select option.eui-select__placeholder{color:var(--eui-c-text-lighter)}.eui-19 :host.eui-select optgroup:disabled,.eui-19 :host.eui-select option:disabled{color:var(--eui-c-disabled)}.eui-19 :host.eui-select:not([readonly]):not([multiple]),.eui-19 :host.eui-select[size=\"1\"],.eui-19 :host.eui-select[size=\"0\"]{appearance:none;background-color:var(--eui-c-surface-container);background-image:var(--eui-internal-icon-chevron-down-path);background-position:calc(100% - var(--eui-s-s)) center;background-repeat:no-repeat;background-size:var(--eui-s-m);padding-right:var(--eui-s-2xl)}\n"] }]
        }], propDecorators: { ariaLabel: [{
                type: HostBinding,
                args: ['attr.aria-label']
            }, {
                type: Input
            }], placeholder: [{
                type: Input
            }], readonly: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], isInvalid: [{
                type: Input
            }], onChange: [{
                type: HostListener,
                args: ['change', ['$event.target.value']]
            }] } });

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function _buildValueString$1(id, value) {
    if (id == null) {
        return `${value}`;
    }
    if (typeof value === 'string') {
        value = `'${value}'`;
    }
    if (value && typeof value === 'object') {
        value = 'Object';
    }
    return `${id}: ${value}`.slice(0, 50);
}
function _extractId(valueString) {
    return valueString.split(':')[0];
}

// eslint-disable-next-line @angular-eslint/directive-class-suffix
class EuiSelectControlValueAccessor extends SelectControlValueAccessor {
    constructor() {
        const _renderer = inject(Renderer2);
        const _elementRef = inject(ElementRef);
        super(_renderer, _elementRef);
        this.selectComponent = inject(EuiSelectComponent, { optional: true });
        this.injector = inject(Injector);
        this.elementRef = _elementRef;
        this.renderer = _renderer;
        this.onChange = (valueString) => {
            this.value = this['_getOptionValue'](valueString);
            this.setPlaceholderClass(this.value);
        };
    }
    ngDoCheck() {
        if (this.placeholder && this.elementRef.nativeElement.selectedIndex === 0) {
            this.renderer.addClass(this.placeholderOption, 'eui-select__placeholder');
        }
    }
    /**
     * Sets the "value" property on the select element.
     *
     * @nodoc
     */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    writeValue(value) {
        super.writeValue(value);
        this.setPlaceholderClass(value);
        this.selectComponent?.syncReadOnlyValue();
    }
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    registerOnChange(fn) {
        this.onChange = (valueString) => {
            this.value = this['_getOptionValue'](valueString);
            this.setPlaceholderClass(this.value);
            fn(this.value);
        };
    }
    setDisabledState(isDisabled) {
        if (isDisabled) {
            this.renderer.setAttribute(this.elementRef.nativeElement, 'disabled', '');
        }
        else {
            this.renderer.removeAttribute(this.elementRef.nativeElement, 'disabled');
        }
    }
    ngOnChanges(changes) {
        if (changes['placeholder']) {
            // in case option Element already created update the value
            if (changes['placeholder'].currentValue === undefined) {
                this.renderer.removeClass(this.elementRef.nativeElement, 'eui-select__placeholder');
                // remove option element
                if (this.placeholderOption) {
                    this.renderer.removeChild(this.elementRef.nativeElement, this.placeholderOption);
                    this.placeholderOption = undefined;
                }
            }
            else if (this.placeholderOption) {
                this.renderer.setProperty(this.placeholderOption, 'innerText', changes['placeholder'].currentValue);
            }
            else {
                // create option Element
                this.placeholderOption = this.renderer.createElement('option');
                // const option = new EuiNgSelectOptionDirective({nativeElement: this.placeholderOption}, this.renderer, this);
                // option.ngValue = null;
                const id = this['_registerOption']();
                this['_optionMap'].set(id, null);
                const selectControlValueAccessor = this.injector.get(SelectControlValueAccessor, undefined);
                selectControlValueAccessor['_idCounter'] = this['_idCounter'];
                selectControlValueAccessor['_optionMap'] = this['_optionMap'];
                this.renderer.setValue(this.placeholderOption, _buildValueString$1(id, null));
                this.renderer.setProperty(this.placeholderOption, 'value', _buildValueString$1(id, null));
                this.renderer.addClass(this.placeholderOption, 'eui-select__placeholder');
                this.renderer.setProperty(this.placeholderOption, 'innerText', changes['placeholder'].currentValue);
                // set attributes to act as a placeholder
                if (!this.elementRef.nativeElement.value) {
                    this.renderer.setAttribute(this.placeholderOption, 'selected', '');
                }
                // append option element as the first of the select children
                this.elementRef.nativeElement.insertBefore(this.placeholderOption, this.elementRef.nativeElement.firstChild);
                if (this.elementRef.nativeElement.value === changes['placeholder'].currentValue) {
                    this.renderer.addClass(this.elementRef.nativeElement, 'eui-select__placeholder');
                }
                if (!this.value) {
                    this.writeValue(undefined);
                }
            }
        }
    }
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    setPlaceholderClass(value) {
        if (!!this.placeholder && (value === undefined || value === null || value === '')) {
            try {
                this.elementRef.nativeElement.options[0].selected = true;
            }
            catch (e) {
                /* empty */
            }
            this.renderer.addClass(this.elementRef.nativeElement, 'eui-select__placeholder');
        }
        else {
            this.renderer.removeClass(this.elementRef.nativeElement, 'eui-select__placeholder');
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectControlValueAccessor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: EuiSelectControlValueAccessor, isStandalone: true, selector: "select:not([multiple])[formControlName][euiSelect],select:not([multiple])[formControl][euiSelect],select:not([multiple])[ngModel][euiSelect]", inputs: { placeholder: "placeholder" }, host: { listeners: { "blur": "onTouched()" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => EuiSelectControlValueAccessor),
                multi: true,
            },
        ], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectControlValueAccessor, decorators: [{
            type: Directive,
            args: [{
                    selector: 
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    'select:not([multiple])[formControlName][euiSelect],select:not([multiple])[formControl][euiSelect],select:not([multiple])[ngModel][euiSelect]',
                    host: { '(blur)': 'onTouched()' },
                    providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => EuiSelectControlValueAccessor),
                            multi: true,
                        },
                    ],
                }]
        }], ctorParameters: () => [], propDecorators: { placeholder: [{
                type: Input
            }] } });

const SELECT_MULTIPLE_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => EuiSelectMultipleControlValueAccessor),
    multi: true,
};
/** Mock interface for HTMLCollection */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class HTMLCollection {
}
/**
 * @description
 * The `ControlValueAccessor` for writing multi-select control values and listening to multi-select
 * control changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
 * `NgModel` directives.
 *
 * @see `EuiSelectControlValueAccessor`
 *
 * @usageNotes
 *
 * ### Using a multi-select control
 *
 * The follow example shows you how to use a multi-select control with a reactive form.
 *
 * ```ts
 * const countryControl = new FormControl();
 * ```
 *
 * ```
 * <select euiSelect multiple name="countries" [formControl]="countryControl">
 *   <option euiOption *ngFor="let country of countries" [ngValue]="country">
 *     {{ country.name }}
 *   </option>
 * </select>
 * ```
 *
 * ### Customizing option selection
 *
 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
 * See the `SelectControlValueAccessor` for usage.
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
// eslint-disable-next-line @angular-eslint/directive-class-suffix
class EuiSelectMultipleControlValueAccessor extends SelectMultipleControlValueAccessor {
    get isInvalid() {
        return this._isInvalid || null;
    }
    set isInvalid(state) {
        this._isInvalid = coerceBooleanProperty(state);
    }
    constructor() {
        const _renderer = inject(Renderer2);
        const _elementRef = inject(ElementRef);
        super(_renderer, _elementRef);
        /** @internal */
        this._optionMap = new Map();
        /** @internal */
        this._idCounter = 0;
        this.selectComponent = inject(EuiSelectComponent, { optional: true });
        this.injector = inject(Injector);
        this.elementRef = _elementRef;
        this.renderer = _renderer;
    }
    ngDoCheck() {
        if (!this.control) {
            this.control = this.injector.get(NgControl, undefined, { optional: true });
        }
        this._isInvalid = this.control ? this.control.invalid && this.control.touched : this._isInvalid;
    }
    /**
     * Sets the "value" property on one or of more of the select's options.
     *
     * @nodoc
     */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    writeValue(value) {
        this.value = value;
        // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let optionSelectedStateSetter;
        if (Array.isArray(value)) {
            // convert values to ids
            const ids = value.map((v) => this._getOptionId(v));
            optionSelectedStateSetter = (opt, o) => {
                opt._setSelected(ids.indexOf(o.toString()) > -1);
            };
        }
        else {
            optionSelectedStateSetter = (opt) => {
                opt._setSelected(false);
            };
        }
        this._optionMap.forEach(optionSelectedStateSetter);
        this.selectComponent?.syncReadOnlyValue();
    }
    /**
     * Registers a function called when the control value changes
     * and writes an array of the selected options.
     *
     * @nodoc
     */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    registerOnChange(fn) {
        this.onChange = (element) => {
            // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            const selected = [];
            const selectedOptions = element.selectedOptions;
            if (selectedOptions !== undefined) {
                const options = selectedOptions;
                // eslint-disable-next-line @typescript-eslint/prefer-for-of
                for (let i = 0; i < options.length; i++) {
                    const opt = options[i];
                    const val = this._getOptionValue(opt.value);
                    selected.push(val);
                }
            }
            else {
                const options = element.options;
                // eslint-disable-next-line @typescript-eslint/prefer-for-of
                for (let i = 0; i < options.length; i++) {
                    const opt = options[i];
                    if (opt.selected) {
                        const val = this._getOptionValue(opt.value);
                        selected.push(val);
                    }
                }
            }
            this.value = selected;
            fn(selected);
        };
    }
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    registerOnTouched(fn) {
        this.onTouched = () => {
            const control = this.injector.get(NgControl, undefined, { optional: true });
            this.isInvalid = control.invalid;
            if (this.isInvalid) {
                this.renderer.addClass(this.elementRef.nativeElement, 'eui-select--invalid');
            }
            fn();
        };
    }
    /** @internal */
    _registerOption(value) {
        const id = (this._idCounter++).toString();
        this._optionMap.set(id, value);
        return id;
    }
    /** @internal */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    _getOptionId(value) {
        for (const id of Array.from(this._optionMap.keys())) {
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            if (this['_compareWith'](this._optionMap.get(id)._value, value)) {
                return id;
            }
        }
        return null;
    }
    /** @internal */
    // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    _getOptionValue(valueString) {
        const id = _extractId(valueString);
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        return this._optionMap.has(id) ? this._optionMap.get(id)._value : valueString;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectMultipleControlValueAccessor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: EuiSelectMultipleControlValueAccessor, isStandalone: true, selector: "select[multiple][formControlName][euiSelect],select[multiple][formControl][euiSelect],select[multiple][ngModel][euiSelect]", inputs: { isInvalid: "isInvalid" }, host: { listeners: { "change": "onChange($event.target)", "blur": "onTouched()" } }, providers: [SELECT_MULTIPLE_VALUE_ACCESSOR], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectMultipleControlValueAccessor, decorators: [{
            type: Directive,
            args: [{
                    selector: 
                    // eslint-disable-next-line @angular-eslint/directive-selector,max-len
                    'select[multiple][formControlName][euiSelect],select[multiple][formControl][euiSelect],select[multiple][ngModel][euiSelect]',
                    host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' },
                    providers: [SELECT_MULTIPLE_VALUE_ACCESSOR],
                }]
        }], ctorParameters: () => [], propDecorators: { isInvalid: [{
                type: Input
            }] } });

/**
 * @description
 * Marks `<option>` as dynamic, so Angular can be notified when options change.
 *
 * @see `EuiSelectMultipleControlValueAccessor`
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
// eslint-disable-next-line @angular-eslint/directive-selector
// eslint-disable-next-line @angular-eslint/directive-class-suffix
class EuiSelectMultipleOption extends _NgSelectMultipleOption {
    constructor() {
        const _element = inject(ElementRef);
        const _renderer = inject(Renderer2);
        const _select = inject(EuiSelectMultipleControlValueAccessor, { optional: true, host: true });
        super(_element, _renderer, _select);
        this.element = _element;
        this.renderer = _renderer;
        this.select = _select;
    }
    /**
     * @description
     * Tracks the value bound to the option element. Unlike the value binding,
     * ngValue supports binding to objects.
     */
    set ngValue(value) {
        if (this.select == null) {
            return;
        }
        this._value = value;
        this._setElementValue(_buildValueString$1(this.id, value));
        this.select.writeValue(this.select.value);
    }
    /**
     * @description
     * Tracks simple string values bound to the option element.
     * For objects, use the `ngValue` input binding.
     */
    set value(value) {
        if (this.select) {
            this._value = value;
            this._setElementValue(_buildValueString$1(this.id, value));
            this.select.writeValue(this.select.value);
        }
        else {
            this._setElementValue(value);
        }
    }
    /** @internal */
    _setElementValue(value) {
        this.renderer.setProperty(this.element.nativeElement, 'value', value);
    }
    /** @internal */
    _setSelected(selected) {
        this.renderer.setProperty(this.element.nativeElement, 'selected', selected);
    }
    /** @nodoc */
    ngOnDestroy() {
        if (this.select) {
            this.select._optionMap.delete(this.id);
            this.select.writeValue(this.select.value);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectMultipleOption, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: EuiSelectMultipleOption, isStandalone: true, selector: "option, option[euiOption]", inputs: { ngValue: "ngValue", value: "value" }, usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectMultipleOption, decorators: [{
            type: Directive,
            args: [{ selector: 'option, option[euiOption]' }]
        }], ctorParameters: () => [], propDecorators: { ngValue: [{
                type: Input
            }], value: [{
                type: Input
            }] } });

// eslint-disable-next-line prefer-arrow/prefer-arrow-functions, @typescript-eslint/no-explicit-any
function _buildValueString(id, value) {
    if (id == null) {
        return `${value}`;
    }
    if (value && typeof value === 'object') {
        value = 'Object';
    }
    return `${id}: ${value}`.slice(0, 50);
}
/**
 * @description
 * Marks `<option>` as dynamic, so Angular can be notified when options change.
 *
 * @see `EuiSelectControlValueAccessor`
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
// TODO: remove that selector in eUI 17.x and replace it with `option[euiOption]` (this will be a breaking change)
// eslint-disable-next-line @angular-eslint/directive-selector
class EuiNgSelectOptionDirective extends NgSelectOption {
    constructor() {
        const _element = inject(ElementRef);
        const _renderer = inject(Renderer2);
        const _select = inject(EuiSelectControlValueAccessor, { optional: true, host: true });
        const _selectNative = inject(SelectControlValueAccessor, { optional: true, host: true });
        const _selectComponent = inject(EuiSelectComponent, { optional: true, host: true });
        super(_element, _renderer, _select);
        this.select = _select;
        this.selectNative = _selectNative;
        this.selectComponent = _selectComponent;
        this.element = _element;
        this.renderer = _renderer;
    }
    ngAfterViewInit() {
        this.selectComponent?.syncReadOnlyValue();
        if (this.selectNative && this.select && this.selectNative.value !== this.select.value) {
            // TODO: This causes issues when options array change from N to 1 and the option 1 is set through setValue()
            //       Investigate what are the regressions from the removal of this line. Issue is that the Native
            //       control value accessor holds a mapper not in sync with the EuiSelectControlValueAccessor.
            //
            // this.selectNative.writeValue(this.select.value);
        }
    }
    /**
     * @description
     * Tracks the value bound to the option element. Unlike the value binding,
     * ngValue supports binding to objects.
     */
    set ngValue(value) {
        if (this.select == null)
            return;
        this.selectNative['_idCounter'] = this.select['_idCounter'];
        this.select['_optionMap'].set(this.id, value);
        this.selectNative['_optionMap'] = this.select['_optionMap']; //.set(this.id, value);
        super['_setElementValue'](_buildValueString(this.id, value));
        this.select.writeValue(this.select.value);
        this.selectNative.writeValue(this.select.value);
    }
    ngOnChanges(changes) {
        if (changes.selected) {
            /**
             * in case there's a selected value, readonly attribute is true, sync it to the readonly input. The reason is
             * that the readonly input is not aware of the selected value until the render of the view completes.
             */
            switch (this.selected) {
                case true:
                    this.renderer.setAttribute(this.element.nativeElement, 'selected', '');
                    break;
                default:
                    this.renderer.removeAttribute(this.element.nativeElement, 'selected');
            }
            this.selectComponent?.syncReadOnlyValue();
        }
        if (changes.label) {
            this.renderer.setProperty(this.element.nativeElement, 'innerText', changes.label.currentValue);
            this.selectComponent?.syncReadOnlyValue();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiNgSelectOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.17", type: EuiNgSelectOptionDirective, isStandalone: true, selector: "option:not([eclSelectOption]):not([eclMultiselectOption]), option[euiOption]", inputs: { selected: ["selected", "selected", booleanAttribute], label: "label", ngValue: "ngValue" }, usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiNgSelectOptionDirective, decorators: [{
            type: Directive,
            args: [{ selector: 'option:not([eclSelectOption]):not([eclMultiselectOption]), option[euiOption]' }]
        }], ctorParameters: () => [], propDecorators: { selected: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], label: [{
                type: Input
            }], ngValue: [{
                type: Input
            }] } });

/**
 * @description
 * A module for the select component. This module imports the
 *
 * @deprecated Use the {@link EUI_SELECT} instead.
 */
class EuiSelectModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectModule, imports: [EuiSelectComponent,
            EuiNgSelectOptionDirective,
            EuiSelectControlValueAccessor,
            EuiSelectMultipleControlValueAccessor,
            EuiSelectMultipleOption], exports: [EuiSelectComponent,
            EuiNgSelectOptionDirective,
            EuiSelectControlValueAccessor,
            EuiSelectMultipleControlValueAccessor,
            EuiSelectMultipleOption] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EuiSelectModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        EuiSelectComponent,
                        EuiNgSelectOptionDirective,
                        EuiSelectControlValueAccessor,
                        EuiSelectMultipleControlValueAccessor,
                        EuiSelectMultipleOption,
                    ],
                    exports: [
                        EuiSelectComponent,
                        EuiNgSelectOptionDirective,
                        EuiSelectControlValueAccessor,
                        EuiSelectMultipleControlValueAccessor,
                        EuiSelectMultipleOption,
                    ],
                }]
        }] });

const EUI_SELECT = [
    EuiSelectComponent,
    EuiNgSelectOptionDirective,
    EuiSelectControlValueAccessor,
    EuiSelectMultipleControlValueAccessor,
    EuiSelectMultipleOption,
];

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

export { EUI_SELECT, EuiNgSelectOptionDirective, EuiSelectComponent, EuiSelectControlValueAccessor, EuiSelectModule, EuiSelectMultipleControlValueAccessor, EuiSelectMultipleOption, _buildValueString$1 as _buildValueString, _extractId };
//# sourceMappingURL=eui-components-eui-select.mjs.map
