import * as i0 from '@angular/core';
import { viewChild, signal, input, numberAttribute, booleanAttribute, output, computed, HostListener, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { elementSearch, elementCancel } from '@siemens/element-icons';
import { addIcons, SiIconComponent } from '@siemens/element-ng/icon';
import { t, SiTranslatePipe } from '@siemens/element-translate-ng/translate';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiSearchBarComponent {
    inputRef = viewChild.required('inputRef');
    debouncer = new Subject();
    disabledNgControl = signal(false, ...(ngDevMode ? [{ debugName: "disabledNgControl" }] : []));
    /**
     * Time unit change of search input takes effect.
     *
     * @defaultValue 400
     */
    debounceTime = input(400, { ...(ngDevMode ? { debugName: "debounceTime" } : {}), transform: numberAttribute });
    /**
     * Prohibited characters restricting search.
     */
    prohibitedCharacters = input(...(ngDevMode ? [undefined, { debugName: "prohibitedCharacters" }] : []));
    /**
     * Define search input placeholder.
     *
     * @defaultValue ''
     */
    placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
    /**
     * Display search icon before search input.
     *
     * @defaultValue false
     */
    showIcon = input(false, { ...(ngDevMode ? { debugName: "showIcon" } : {}), transform: booleanAttribute });
    /**
     * Whether the search is tabbable or not.
     *
     * @defaultValue true
     */
    tabbable = input(true, { ...(ngDevMode ? { debugName: "tabbable" } : {}), transform: booleanAttribute });
    /**
     * Define search input content.
     */
    value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
    /** @defaultValue false */
    readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : {}), transform: booleanAttribute });
    /**
     * Color to use for component background
     *
     * @defaultValue 'base-1'
     */
    colorVariant = input('base-1', ...(ngDevMode ? [{ debugName: "colorVariant" }] : []));
    /** @defaultValue false */
    // eslint-disable-next-line @angular-eslint/no-input-rename
    disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled', transform: booleanAttribute });
    /**
     * Aria label for the clear button.
     *
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_SEARCH_BAR.CLEAR_BUTTON:clear`)
     * ```
     */
    clearButtonAriaLabel = input(t(() => $localize `:@@SI_SEARCH_BAR.CLEAR_BUTTON:clear`), ...(ngDevMode ? [{ debugName: "clearButtonAriaLabel" }] : []));
    /**
     * Output callback event will provide you with search term if search input changes.
     */
    searchChange = output();
    isInvalid = false;
    inFocus = false;
    onChange = (val) => { };
    onTouch = () => { };
    disabled = computed(() => this.disabledInput() || this.disabledNgControl(), ...(ngDevMode ? [{ debugName: "disabled" }] : []));
    searchValue = signal('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
    icons = addIcons({ elementCancel, elementSearch });
    /** @internal */
    writeValue(value) {
        this.writeSearchValue(value ?? '');
    }
    /** @internal */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /** @internal */
    registerOnTouched(fn) {
        this.onTouch = fn;
    }
    /** @internal */
    setDisabledState(disabled) {
        this.disabledNgControl.set(disabled);
    }
    ngOnChanges(changes) {
        if (changes.value) {
            this.writeSearchValue(changes.value.currentValue ?? '');
        }
    }
    ngOnInit() {
        this.debouncer.pipe(debounceTime(this.debounceTime())).subscribe(value => {
            this.setSearch(value);
        });
    }
    ngOnDestroy() {
        this.debouncer.complete();
    }
    setSearch(value) {
        value ??= '';
        if (value !== this.searchValue()) {
            this.searchValue.set(value);
            this.inputRef().nativeElement.value = value;
            this.onChange(value);
            this.searchChange.emit(value);
        }
    }
    isProhibitedCharactersUsed(searchString) {
        const prohibitedCharacters = this.prohibitedCharacters();
        if (!prohibitedCharacters || !searchString) {
            return false;
        }
        for (const prohibitedCharacter of prohibitedCharacters) {
            if (searchString.includes(prohibitedCharacter)) {
                return true;
            }
        }
        return false;
    }
    /** @internal */
    focus() {
        this.inputRef().nativeElement.focus();
    }
    onCancelFocus(event) {
        event.stopPropagation();
    }
    input(event) {
        const value = event.target.value;
        if (!this.isProhibitedCharactersUsed(value)) {
            if (this.debounceTime() > 0) {
                this.debouncer.next(value);
            }
            else {
                this.setSearch(value);
            }
        }
    }
    onBlur() {
        this.inFocus = false;
        this.onTouch();
    }
    resetForm() {
        this.setSearch('');
    }
    writeSearchValue(value) {
        this.searchValue.set(value);
        this.inputRef().nativeElement.value = value;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSearchBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSearchBarComponent, isStandalone: true, selector: "si-search-bar", inputs: { debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null }, prohibitedCharacters: { classPropertyName: "prohibitedCharacters", publicName: "prohibitedCharacters", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, tabbable: { classPropertyName: "tabbable", publicName: "tabbable", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, colorVariant: { classPropertyName: "colorVariant", publicName: "colorVariant", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, clearButtonAriaLabel: { classPropertyName: "clearButtonAriaLabel", publicName: "clearButtonAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchChange: "searchChange" }, host: { listeners: { "focus": "focus()" }, properties: { "class.readonly": "readonly()" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: SiSearchBarComponent,
                multi: true
            }
        ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative\" [class.disabled]=\"disabled()\" [class.focus]=\"inFocus\">\n  @if (showIcon()) {\n    <si-icon class=\"search-bar-icon icon text-secondary\" [icon]=\"icons.elementSearch\" />\n  }\n  <input\n    #inputRef\n    type=\"text\"\n    class=\"form-control\"\n    [disabled]=\"disabled()\"\n    [placeholder]=\"placeholder()\"\n    [class.dark-background]=\"colorVariant() === 'base-0'\"\n    [class.icon-start]=\"showIcon()\"\n    [class.is-invalid]=\"isInvalid\"\n    [class.icon-end]=\"searchValue()\"\n    [attr.tabindex]=\"tabbable() ? '' : '-1'\"\n    [readonly]=\"readonly()\"\n    (focus)=\"inFocus = true\"\n    (blur)=\"onBlur()\"\n    (input)=\"input($event)\"\n  />\n  @if (searchValue()) {\n    <button\n      type=\"button\"\n      class=\"btn btn-icon btn-sm btn-ghost cancel-button\"\n      [attr.aria-label]=\"clearButtonAriaLabel() | translate\"\n      [disabled]=\"disabled() || readonly()\"\n      (click)=\"resetForm()\"\n      (focusin)=\"onCancelFocus($event)\"\n    >\n      <si-icon [icon]=\"icons.elementCancel\" />\n    </button>\n  }\n</div>\n", styles: [":host{--search-bar-icon-color: var(--element-text-secondary);--input-background-color: var(--element-base-1);--input-background-hover-color: var(--element-base-1)}:host div:hover .search-bar-icon,:host div:hover ::placeholder,:host div.focus .search-bar-icon,:host div.focus ::placeholder{color:var(--element-text-primary)!important}.dark-background{--input-background-color: var(--element-base-4);--input-background-hover-color: var(--element-ui-4)}input{transition:none;background-color:var(--input-background-color);border-radius:4px;border-width:0}input.form-control:focus-visible{background-color:var(--input-background-color)}.cancel-button{position:absolute;inset-block:0;inset-inline-end:4px;margin-block:auto}.is-invalid~.cancel-button{color:var(--element-status-danger)}.search-bar-icon{position:absolute;inset-block:0;inset-inline-start:6px;align-items:center;color:var(--search-bar-icon-color)}.icon-start{padding-inline-start:calc(1.25rem + 12px)}.icon-end{padding-inline-end:1.25rem}::placeholder{color:var(--element-text-secondary);padding-inline-start:2px}.disabled .search-bar-icon,.disabled input,.disabled .cancel-button,.disabled ::placeholder{color:var(--element-text-disabled)}.disabled input{background-color:var(--input-background-color)}\n"], dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSearchBarComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-search-bar', imports: [SiIconComponent, SiTranslatePipe], providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: SiSearchBarComponent,
                            multi: true
                        }
                    ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        '[class.readonly]': 'readonly()'
                    }, template: "<div class=\"position-relative\" [class.disabled]=\"disabled()\" [class.focus]=\"inFocus\">\n  @if (showIcon()) {\n    <si-icon class=\"search-bar-icon icon text-secondary\" [icon]=\"icons.elementSearch\" />\n  }\n  <input\n    #inputRef\n    type=\"text\"\n    class=\"form-control\"\n    [disabled]=\"disabled()\"\n    [placeholder]=\"placeholder()\"\n    [class.dark-background]=\"colorVariant() === 'base-0'\"\n    [class.icon-start]=\"showIcon()\"\n    [class.is-invalid]=\"isInvalid\"\n    [class.icon-end]=\"searchValue()\"\n    [attr.tabindex]=\"tabbable() ? '' : '-1'\"\n    [readonly]=\"readonly()\"\n    (focus)=\"inFocus = true\"\n    (blur)=\"onBlur()\"\n    (input)=\"input($event)\"\n  />\n  @if (searchValue()) {\n    <button\n      type=\"button\"\n      class=\"btn btn-icon btn-sm btn-ghost cancel-button\"\n      [attr.aria-label]=\"clearButtonAriaLabel() | translate\"\n      [disabled]=\"disabled() || readonly()\"\n      (click)=\"resetForm()\"\n      (focusin)=\"onCancelFocus($event)\"\n    >\n      <si-icon [icon]=\"icons.elementCancel\" />\n    </button>\n  }\n</div>\n", styles: [":host{--search-bar-icon-color: var(--element-text-secondary);--input-background-color: var(--element-base-1);--input-background-hover-color: var(--element-base-1)}:host div:hover .search-bar-icon,:host div:hover ::placeholder,:host div.focus .search-bar-icon,:host div.focus ::placeholder{color:var(--element-text-primary)!important}.dark-background{--input-background-color: var(--element-base-4);--input-background-hover-color: var(--element-ui-4)}input{transition:none;background-color:var(--input-background-color);border-radius:4px;border-width:0}input.form-control:focus-visible{background-color:var(--input-background-color)}.cancel-button{position:absolute;inset-block:0;inset-inline-end:4px;margin-block:auto}.is-invalid~.cancel-button{color:var(--element-status-danger)}.search-bar-icon{position:absolute;inset-block:0;inset-inline-start:6px;align-items:center;color:var(--search-bar-icon-color)}.icon-start{padding-inline-start:calc(1.25rem + 12px)}.icon-end{padding-inline-end:1.25rem}::placeholder{color:var(--element-text-secondary);padding-inline-start:2px}.disabled .search-bar-icon,.disabled input,.disabled .cancel-button,.disabled ::placeholder{color:var(--element-text-disabled)}.disabled input{background-color:var(--input-background-color)}\n"] }]
        }], propDecorators: { inputRef: [{ type: i0.ViewChild, args: ['inputRef', { isSignal: true }] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], prohibitedCharacters: [{ type: i0.Input, args: [{ isSignal: true, alias: "prohibitedCharacters", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], showIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcon", required: false }] }], tabbable: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabbable", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], colorVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorVariant", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearButtonAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearButtonAriaLabel", required: false }] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], focus: [{
                type: HostListener,
                args: ['focus']
            }] } });

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

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

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

export { SiSearchBarComponent, SiSearchBarModule };
//# sourceMappingURL=siemens-element-ng-search-bar.mjs.map
