import { A, Z, ZERO, NINE, SPACE, HOME, END, ENTER, ESCAPE, UP_ARROW, DOWN_ARROW } from '@angular/cdk/keycodes';
import * as i1 from '@angular/cdk/scrolling';
import * as i0 from '@angular/core';
import { InjectionToken, EventEmitter, forwardRef, ElementRef, Component, ChangeDetectionStrategy, Inject, Optional, Input, Output, ViewChild, ContentChild, NgModule } from '@angular/core';
import * as i3 from '@angular/forms';
import { FormControl, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i12 from '@angular/material/core';
import { MatOption } from '@angular/material/core';
import * as i13 from '@angular/material/form-field';
import { MatFormField } from '@angular/material/form-field';
import * as i11 from '@angular/material/select';
import { MatSelect } from '@angular/material/select';
import { AswSelectSearchClearDirective, AswSelectNoEntriesFoundDirective, MaterialModule, AswPipeModule, AswDirectiveModule } from '@asoftwareworld/form-builder-pro/common';
import { BehaviorSubject, of, combineLatest, Subject } from 'rxjs';
import { switchMap, map, startWith, delay, takeUntil, take, tap, filter } from 'rxjs/operators';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i4 from '@angular/material/button';
import * as i5 from '@angular/material/checkbox';
import * as i6 from '@angular/material/divider';
import * as i7 from '@angular/material/input';
import * as i8 from '@angular/material/tooltip';
import * as i9 from '@angular/material/icon';
import * as i10 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { AswTranslateModule } from '@asoftwareworld/form-builder-pro/core';
import { AswConfirmDialogModule } from '@asoftwareworld/form-builder-pro/form-control/confirm-dialog';
import { AswSharedDialogModule } from '@asoftwareworld/form-builder-pro/form-control/shared';

const configurableDefaultOptions = [
    'ariaLabel',
    'clearSearchInput',
    'closeIcon',
    'closeSvgIcon',
    'disableInitialFocus',
    'disableScrollToActiveOnOptionsChanged',
    'enableClearOnEscapePressed',
    'hideClearSearchButton',
    'noEntriesFoundLabel',
    'placeholderLabel',
    'preventHomeEndKeyPropagation',
    'searching'
];
/**
 * InjectionToken that can be used to specify global options. e.g.
 *
 * ```typescript
 * providers: [
 *   {
 *     provide: ASW_SELECTSEARCH_DEFAULT_OPTIONS,
 *     useValue: <AswSelectSearchOptions>{
 *       closeIcon: 'delete',
 *       noEntriesFoundLabel: 'No options found'
 *     }
 *   }
 * ]
 * ```
 *
 * See the corresponding inputs of `AswSelectSearch` for documentation.
 */
const ASW_SELECTSEARCH_DEFAULT_OPTIONS = new InjectionToken('asw-selectsearch-default-options');

class AswSelectSearch {
    matSelect;
    changeDetectorRef;
    _viewportRuler;
    matOption;
    matFormField;
    /** Label of the search placeholder */
    placeholderLabel = 'Search';
    /** Type of the search input field */
    type = 'text';
    /** Font-based icon used for displaying Close-Icon */
    closeIcon = 'close';
    /** Svg-based icon used for displaying Close-Icon. If set, closeIcon is overridden */
    closeSvgIcon = '';
    /** Label to be shown when no entries are found. Set to null if no message should be shown. */
    noEntriesFoundLabel = 'No results found';
    /**
     * Whether or not the search field should be cleared after the dropdown menu is closed.
     */
    clearSearchInput = true;
    /** Whether to show the search-in-progress indicator */
    searching = false;
    /** Disables initial focusing of the input field */
    disableInitialFocus = false;
    /** Enable clear input on escape pressed */
    enableClearOnEscapePressed = false;
    /**
     * Prevents home / end key being propagated to mat-select,
     * allowing to move the cursor within the search input instead of navigating the options
     */
    preventHomeEndKeyPropagation = false;
    /** Disables scrolling to active options when option list changes. Useful for server-side search */
    disableScrollToActiveOnOptionsChanged = false;
    /** Adds 508 screen reader support for search box */
    ariaLabel = 'dropdown search';
    /** Whether to show Select All Checkbox (for mat-select[multi=true]) */
    showToggleAllCheckbox = false;
    /** select all checkbox checked state */
    toggleAllCheckboxChecked = false;
    /** select all checkbox indeterminate state */
    toggleAllCheckboxIndeterminate = false;
    /** Display a message in a tooltip on the toggle-all checkbox */
    toggleAllCheckboxTooltipMessage = '';
    /** Define the position of the tooltip on the toggle-all checkbox. */
    toggleAllCheckboxTooltipPosition = 'below';
    /** Show/Hide the search clear button of the search input */
    hideClearSearchButton = false;
    /**
     * Always restore selected options on selectionChange for mode multi (e.g. for lazy loading/infinity scrolling).
     * Defaults to false, so selected options are only restored while filtering is active.
     */
    alwaysRestoreSelectedOptionsMulti = false;
    /** Output emitter to send to parent component with the toggle all boolean */
    toggleAll = new EventEmitter();
    /** Reference to the search input field */
    searchSelectInput;
    /** Reference to the search input field */
    innerSelectSearch;
    /** Reference to custom search input clear icon */
    clearIcon;
    /** Reference to custom no entries found element */
    noEntriesFound;
    /** Current search value */
    get value() {
        return this._formControl.value;
    }
    _lastExternalInputValue;
    onTouched = (_) => { };
    /** Reference to the MatSelect options */
    set _options(_options) {
        this._options$.next(_options);
    }
    get _options() {
        return this._options$.getValue();
    }
    _options$ = new BehaviorSubject(null);
    optionsList$ = this._options$.pipe(switchMap((_options) => _options
        ? _options.changes.pipe(map((options) => options.toArray()), startWith(_options.toArray()))
        : of(null)));
    optionsLength$ = this.optionsList$.pipe(map((options) => (options ? options.length : 0)));
    /** Previously selected values when using <mat-select [multiple]="true">*/
    previousSelectedValues = [];
    _formControl = new FormControl('');
    /** whether to show the no entries found message */
    _showNoEntriesFound$ = combineLatest([this._formControl.valueChanges, this.optionsLength$]).pipe(map(([value, optionsLength]) => this.noEntriesFoundLabel && value && optionsLength === this.getOptionsLengthOffset()));
    /** Subject that emits when the component has been destroyed. */
    _onDestroy = new Subject();
    /** Reference to active descendant for ARIA Support. */
    activeDescendant;
    constructor(matSelect, changeDetectorRef, _viewportRuler, matOption, matFormField, defaultOptions) {
        this.matSelect = matSelect;
        this.changeDetectorRef = changeDetectorRef;
        this._viewportRuler = _viewportRuler;
        this.matOption = matOption;
        this.matFormField = matFormField;
        this.applyDefaultOptions(defaultOptions);
    }
    applyDefaultOptions(defaultOptions) {
        if (!defaultOptions) {
            return;
        }
        for (const key of configurableDefaultOptions) {
            if (defaultOptions.hasOwnProperty(key)) {
                this[key] = defaultOptions[key];
            }
        }
    }
    ngOnInit() {
        // set custom mat-option class if the component was placed inside a mat-option
        if (this.matOption) {
            this.matOption.disabled = true;
            this.matOption._getHostElement().classList.add('contains-mat-select-search');
            this.matOption._getHostElement().setAttribute('aria-hidden', 'true');
        }
        else {
            console.error('<asw-select-search> must be placed inside a <mat-option> element');
        }
        // when the select dropdown panel is opened or closed
        this.matSelect.openedChange.pipe(delay(1), takeUntil(this._onDestroy)).subscribe((opened) => {
            if (opened) {
                this.updateInputWidth();
                // focus the search field when opening
                if (!this.disableInitialFocus) {
                    this._focus();
                }
            }
            else {
                // clear it when closing
                if (this.clearSearchInput) {
                    this._reset();
                }
            }
        });
        // set the first item active after the options changed
        this.matSelect.openedChange
            .pipe(take(1), switchMap((_) => {
            this._options = this.matSelect.options;
            // Closure variable for tracking the most recent first option.
            // In order to avoid avoid causing the list to
            // scroll to the top when options are added to the bottom of
            // the list (eg: infinite scroll), we compare only
            // the changes to the first options to determine if we
            // should set the first item as active.
            // This prevents unnecessary scrolling to the top of the list
            // when options are appended, but allows the first item
            // in the list to be set as active by default when there
            // is no active selection
            let previousFirstOption = this._options.toArray()[this.getOptionsLengthOffset()];
            return this._options.changes.pipe(tap(() => {
                // avoid "expression has been changed" error
                setTimeout(() => {
                    // Convert the QueryList to an array
                    const options = this._options.toArray();
                    // The true first item is offset by 1
                    const currentFirstOption = options[this.getOptionsLengthOffset()];
                    const keyManager = this.matSelect._keyManager;
                    if (keyManager && this.matSelect.panelOpen) {
                        // set first item active and input width
                        // Check to see if the first option in these changes is different from the previous.
                        const firstOptionIsChanged = !this.matSelect.compareWith(previousFirstOption, currentFirstOption);
                        // CASE: The first option is different now.
                        // Indiciates we should set it as active and scroll to the top.
                        if (firstOptionIsChanged || !keyManager.activeItem || !options.find((option) => this.matSelect.compareWith(option, keyManager.activeItem))) {
                            keyManager.setFirstItemActive();
                        }
                        // wait for panel width changes
                        setTimeout(() => {
                            this.updateInputWidth();
                        });
                    }
                    // Update our reference
                    previousFirstOption = currentFirstOption;
                });
            }));
        }))
            .pipe(takeUntil(this._onDestroy))
            .subscribe();
        // add or remove css class depending on whether to show the no entries found message
        // note: this is hacky
        this._showNoEntriesFound$.pipe(takeUntil(this._onDestroy)).subscribe((showNoEntriesFound) => {
            // set no entries found class on mat option
            if (this.matOption) {
                if (showNoEntriesFound) {
                    this.matOption._getHostElement().classList.add('mat-select-search-no-entries-found');
                }
                else {
                    this.matOption._getHostElement().classList.remove('mat-select-search-no-entries-found');
                }
            }
        });
        // resize the input width when the viewport is resized, i.e. the trigger width could potentially be resized
        this._viewportRuler
            .change()
            .pipe(takeUntil(this._onDestroy))
            .subscribe(() => {
            if (this.matSelect.panelOpen) {
                this.updateInputWidth();
            }
        });
        this.initMultipleHandling();
        this.optionsList$.pipe(takeUntil(this._onDestroy)).subscribe(() => {
            // update view when available options change
            this.changeDetectorRef.markForCheck();
        });
    }
    _emitSelectAllBooleanToParent(state) {
        this.toggleAll.emit(state);
    }
    ngOnDestroy() {
        this._onDestroy.next();
        this._onDestroy.complete();
    }
    _isToggleAllCheckboxVisible() {
        return this.matSelect.multiple && this.showToggleAllCheckbox;
    }
    /**
     * Handles the key down event with MatSelect.
     * Allows e.g. selecting with enter key, navigation with arrow keys, etc.
     * @param event
     */
    _handleKeydown(event) {
        // Prevent propagation for all alphanumeric characters in order to avoid selection issues
        if ((event.key && event.key.length === 1) ||
            (event.keyCode >= A && event.keyCode <= Z) ||
            (event.keyCode >= ZERO && event.keyCode <= NINE) ||
            event.keyCode === SPACE ||
            (this.preventHomeEndKeyPropagation && (event.keyCode === HOME || event.keyCode === END))) {
            event.stopPropagation();
        }
        if (this.matSelect.multiple && event.key && event.keyCode === ENTER) {
            // Regain focus after multiselect, so we can further type
            setTimeout(() => this._focus());
        }
        // Special case if click Escape, if input is empty, close the dropdown, if not, empty out the search field
        if (this.enableClearOnEscapePressed === true && event.keyCode === ESCAPE && this.value) {
            this._reset(true);
            event.stopPropagation();
        }
    }
    /**
     * Handles the key up event with MatSelect.
     * Allows e.g. the announcing of the currently activeDescendant by screen readers.
     */
    _handleKeyup(event) {
        if (event.keyCode === UP_ARROW || event.keyCode === DOWN_ARROW) {
            const ariaActiveDescendantId = this.matSelect._getAriaActiveDescendant();
            const index = this._options.toArray().findIndex((item) => item.id === ariaActiveDescendantId);
            if (index !== -1) {
                this.unselectActiveDescendant();
                this.activeDescendant = this._options.toArray()[index]._getHostElement();
                this.activeDescendant.setAttribute('aria-selected', 'true');
                this.searchSelectInput?.nativeElement.setAttribute('aria-activedescendant', ariaActiveDescendantId);
            }
        }
    }
    writeValue(value) {
        this._lastExternalInputValue = value;
        this._formControl.setValue(value);
        this.changeDetectorRef.markForCheck();
    }
    onBlur() {
        this.unselectActiveDescendant();
        this.onTouched();
    }
    registerOnChange(fn) {
        this._formControl.valueChanges
            .pipe(filter((value) => value !== this._lastExternalInputValue), tap(() => (this._lastExternalInputValue = undefined)), takeUntil(this._onDestroy))
            .subscribe(fn);
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    /**
     * Focuses the search input field
     */
    _focus() {
        if (!this.searchSelectInput || !this.matSelect.panel) {
            return;
        }
        // save and restore scrollTop of panel, since it will be reset by focus()
        // note: this is hacky
        const panel = this.matSelect.panel.nativeElement;
        const scrollTop = panel.scrollTop;
        // focus
        this.searchSelectInput.nativeElement.focus();
        panel.scrollTop = scrollTop;
    }
    /**
     * Resets the current search value
     * @param focus whether to focus after resetting
     */
    _reset(focus) {
        this._formControl.setValue('');
        if (focus) {
            this._focus();
        }
    }
    /**
     * Initializes handling <mat-select [multiple]="true">
     * Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
     */
    initMultipleHandling() {
        if (!this.matSelect.ngControl) {
            if (this.matSelect.multiple) {
                // note: the access to matSelect.ngControl (instead of matSelect.value / matSelect.valueChanges)
                // is necessary to properly work in multi-selection mode.
                console.error('the mat-select containing asw-select-search must have a ngModel or formControl directive when multiple=true');
            }
            return;
        }
        // if <mat-select [multiple]="true">
        // store previously selected values and restore them when they are deselected
        // because the option is not available while we are currently filtering
        this.previousSelectedValues = this.matSelect.ngControl.value;
        this.matSelect.ngControl.valueChanges?.pipe(takeUntil(this._onDestroy)).subscribe((values) => {
            let restoreSelectedValues = false;
            if (this.matSelect.multiple) {
                if ((this.alwaysRestoreSelectedOptionsMulti || (this._formControl.value && this._formControl.value.length)) && this.previousSelectedValues && Array.isArray(this.previousSelectedValues)) {
                    if (!values || !Array.isArray(values)) {
                        values = [];
                    }
                    const optionValues = this.matSelect.options.map((option) => option.value);
                    this.previousSelectedValues.forEach((previousValue) => {
                        if (!values.some((v) => this.matSelect.compareWith(v, previousValue)) && !optionValues.some((v) => this.matSelect.compareWith(v, previousValue))) {
                            // if a value that was selected before is deselected and not found in the options, it was deselected
                            // due to the filtering, so we restore it.
                            values.push(previousValue);
                            restoreSelectedValues = true;
                        }
                    });
                }
            }
            this.previousSelectedValues = values;
            if (restoreSelectedValues) {
                this.matSelect._onChange(values);
            }
        });
    }
    /**
     *  Set the width of the innerSelectSearch to fit even custom scrollbars
     *  And support all Operation Systems
     */
    updateInputWidth() {
        if (!this.innerSelectSearch || !this.innerSelectSearch.nativeElement) {
            return;
        }
        let element = this.innerSelectSearch.nativeElement;
        let panelElement;
        while ((element = element?.parentElement)) {
            if (element.classList.contains('mat-select-panel')) {
                panelElement = element;
                break;
            }
        }
        // if (panelElement) {
        //     this.innerSelectSearch.nativeElement.style.width = panelElement.clientWidth + 'px';
        // }
    }
    /**
     * Determine the offset to length that can be caused by the optional matOption used as a search input.
     */
    getOptionsLengthOffset() {
        if (this.matOption) {
            return 1;
        }
        else {
            return 0;
        }
    }
    unselectActiveDescendant() {
        this.activeDescendant?.removeAttribute('aria-selected');
        this.searchSelectInput?.nativeElement.removeAttribute('aria-activedescendant');
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearch, deps: [{ token: MatSelect }, { token: i0.ChangeDetectorRef }, { token: i1.ViewportRuler }, { token: MatOption, optional: true }, { token: MatFormField, optional: true }, { token: ASW_SELECTSEARCH_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.2", type: AswSelectSearch, selector: "asw-select-search", inputs: { placeholderLabel: "placeholderLabel", type: "type", closeIcon: "closeIcon", closeSvgIcon: "closeSvgIcon", noEntriesFoundLabel: "noEntriesFoundLabel", clearSearchInput: "clearSearchInput", searching: "searching", disableInitialFocus: "disableInitialFocus", enableClearOnEscapePressed: "enableClearOnEscapePressed", preventHomeEndKeyPropagation: "preventHomeEndKeyPropagation", disableScrollToActiveOnOptionsChanged: "disableScrollToActiveOnOptionsChanged", ariaLabel: "ariaLabel", showToggleAllCheckbox: "showToggleAllCheckbox", toggleAllCheckboxChecked: "toggleAllCheckboxChecked", toggleAllCheckboxIndeterminate: "toggleAllCheckboxIndeterminate", toggleAllCheckboxTooltipMessage: "toggleAllCheckboxTooltipMessage", toggleAllCheckboxTooltipPosition: "toggleAllCheckboxTooltipPosition", hideClearSearchButton: "hideClearSearchButton", alwaysRestoreSelectedOptionsMulti: "alwaysRestoreSelectedOptionsMulti" }, outputs: { toggleAll: "toggleAll" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => AswSelectSearch),
                multi: true
            }
        ], queries: [{ propertyName: "clearIcon", first: true, predicate: AswSelectSearchClearDirective, descendants: true }, { propertyName: "noEntriesFound", first: true, predicate: AswSelectNoEntriesFoundDirective, descendants: true }], viewQueries: [{ propertyName: "searchSelectInput", first: true, predicate: ["searchSelectInput"], descendants: true, read: ElementRef, static: true }, { propertyName: "innerSelectSearch", first: true, predicate: ["innerSelectSearch"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<input matInput class=\"mat-select-search-input mat-select-search-hidden\" />\r\n\r\n<!-- Note: the  mat-datepicker-content mat-tab-header are needed to inherit the material theme colors, see PR #22 -->\r\n<div #innerSelectSearch class=\"mat-select-search-inner mat-typography mat-datepicker-content mat-tab-header\"\r\n    [ngClass]=\"{'mat-select-search-inner-multiple': matSelect.multiple, 'mat-select-search-inner-toggle-all': _isToggleAllCheckboxVisible() }\">\r\n\r\n    <mat-checkbox *ngIf=\"_isToggleAllCheckboxVisible()\" [color]=\"matFormField.color\"\r\n        class=\"mat-select-search-toggle-all-checkbox\" [checked]=\"toggleAllCheckboxChecked\"\r\n        [indeterminate]=\"toggleAllCheckboxIndeterminate\" [matTooltip]=\"toggleAllCheckboxTooltipMessage\"\r\n        matTooltipClass=\"asw-select-search-toggle-all-tooltip\"\r\n        [matTooltipPosition]=\"toggleAllCheckboxTooltipPosition\"\r\n        (change)=\"_emitSelectAllBooleanToParent($event.checked)\"></mat-checkbox>\r\n\r\n    <input class=\"mat-select-search-input\" autocomplete=\"off\" [type]=\"type\" [formControl]=\"_formControl\"\r\n        #searchSelectInput (keydown)=\"_handleKeydown($event)\" (keyup)=\"_handleKeyup($event)\" (blur)=\"onBlur()\"\r\n        [placeholder]=\"placeholderLabel\" [attr.aria-label]=\"ariaLabel\" />\r\n    <mat-spinner *ngIf=\"searching\" class=\"mat-select-search-spinner\" diameter=\"16\"></mat-spinner>\r\n\r\n    <button *ngIf=\"!hideClearSearchButton && value && !searching\" mat-icon-button aria-label=\"Clear\"\r\n        (click)=\"_reset(true)\" class=\"mat-select-search-clear\">\r\n        <ng-content *ngIf=\"clearIcon; else defaultIcon\" select=\"[aswSelectSearchClear]\"></ng-content>\r\n        <ng-template #defaultIcon>\r\n            <mat-icon [svgIcon]=\"closeSvgIcon\">\r\n                {{!closeSvgIcon ? closeIcon : null}}\r\n            </mat-icon>\r\n        </ng-template>\r\n    </button>\r\n\r\n    <ng-content select=\".mat-select-search-custom-header-content\"></ng-content>\r\n\r\n    <mat-divider></mat-divider>\r\n</div>\r\n\r\n<div *ngIf=\"_showNoEntriesFound$ | async\" class=\"mat-select-search-no-entries-found\">\r\n    <ng-content *ngIf=\"noEntriesFound; else defaultNoEntriesFound\" select=\"[aswSelectNoEntriesFound]\"></ng-content>\r\n    <ng-template #defaultNoEntriesFound>{{noEntriesFoundLabel}}</ng-template>\r\n</div>", styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;left:0;width:100%;z-index:100;font-size:inherit;box-shadow:none}.mat-select-search-inner.mat-select-search-inner-multiple.mat-select-search-inner-toggle-all{display:flex;align-items:center}.mat-select-search-input{box-sizing:border-box;width:100%;border:none;font-family:inherit;font-size:inherit;color:currentColor;outline:none;background:none;padding:0 44px 0 16px;height:calc(3em - 1px);line-height:calc(3em - 1px)}:host-context([dir=rtl]) .mat-select-search-input{padding-right:16px;padding-left:44px}.mat-select-search-inner-toggle-all .mat-select-search-input{padding-left:5px}.mat-select-search-no-entries-found{padding-top:8px}.mat-select-search-clear{position:absolute;right:4px;top:0}:host-context([dir=rtl]) .mat-select-search-clear{right:auto;left:4px}.mat-select-search-spinner{position:absolute;right:16px;top:calc(50% - 8px)}:host-context([dir=rtl]) .mat-select-search-spinner{right:auto;left:16px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search{position:sticky;top:-8px;z-index:1;opacity:1;margin-top:-8px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0;margin-left:0}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search mat-pseudo-checkbox{display:none}.mat-select-search-toggle-all-checkbox{padding-left:5px}:host-context([dir=rtl]) .mat-select-search-toggle-all-checkbox{padding-left:0;padding-right:5px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl],      input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearch, decorators: [{
            type: Component,
            args: [{ selector: 'asw-select-search', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => AswSelectSearch),
                            multi: true
                        }
                    ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<input matInput class=\"mat-select-search-input mat-select-search-hidden\" />\r\n\r\n<!-- Note: the  mat-datepicker-content mat-tab-header are needed to inherit the material theme colors, see PR #22 -->\r\n<div #innerSelectSearch class=\"mat-select-search-inner mat-typography mat-datepicker-content mat-tab-header\"\r\n    [ngClass]=\"{'mat-select-search-inner-multiple': matSelect.multiple, 'mat-select-search-inner-toggle-all': _isToggleAllCheckboxVisible() }\">\r\n\r\n    <mat-checkbox *ngIf=\"_isToggleAllCheckboxVisible()\" [color]=\"matFormField.color\"\r\n        class=\"mat-select-search-toggle-all-checkbox\" [checked]=\"toggleAllCheckboxChecked\"\r\n        [indeterminate]=\"toggleAllCheckboxIndeterminate\" [matTooltip]=\"toggleAllCheckboxTooltipMessage\"\r\n        matTooltipClass=\"asw-select-search-toggle-all-tooltip\"\r\n        [matTooltipPosition]=\"toggleAllCheckboxTooltipPosition\"\r\n        (change)=\"_emitSelectAllBooleanToParent($event.checked)\"></mat-checkbox>\r\n\r\n    <input class=\"mat-select-search-input\" autocomplete=\"off\" [type]=\"type\" [formControl]=\"_formControl\"\r\n        #searchSelectInput (keydown)=\"_handleKeydown($event)\" (keyup)=\"_handleKeyup($event)\" (blur)=\"onBlur()\"\r\n        [placeholder]=\"placeholderLabel\" [attr.aria-label]=\"ariaLabel\" />\r\n    <mat-spinner *ngIf=\"searching\" class=\"mat-select-search-spinner\" diameter=\"16\"></mat-spinner>\r\n\r\n    <button *ngIf=\"!hideClearSearchButton && value && !searching\" mat-icon-button aria-label=\"Clear\"\r\n        (click)=\"_reset(true)\" class=\"mat-select-search-clear\">\r\n        <ng-content *ngIf=\"clearIcon; else defaultIcon\" select=\"[aswSelectSearchClear]\"></ng-content>\r\n        <ng-template #defaultIcon>\r\n            <mat-icon [svgIcon]=\"closeSvgIcon\">\r\n                {{!closeSvgIcon ? closeIcon : null}}\r\n            </mat-icon>\r\n        </ng-template>\r\n    </button>\r\n\r\n    <ng-content select=\".mat-select-search-custom-header-content\"></ng-content>\r\n\r\n    <mat-divider></mat-divider>\r\n</div>\r\n\r\n<div *ngIf=\"_showNoEntriesFound$ | async\" class=\"mat-select-search-no-entries-found\">\r\n    <ng-content *ngIf=\"noEntriesFound; else defaultNoEntriesFound\" select=\"[aswSelectNoEntriesFound]\"></ng-content>\r\n    <ng-template #defaultNoEntriesFound>{{noEntriesFoundLabel}}</ng-template>\r\n</div>", styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;left:0;width:100%;z-index:100;font-size:inherit;box-shadow:none}.mat-select-search-inner.mat-select-search-inner-multiple.mat-select-search-inner-toggle-all{display:flex;align-items:center}.mat-select-search-input{box-sizing:border-box;width:100%;border:none;font-family:inherit;font-size:inherit;color:currentColor;outline:none;background:none;padding:0 44px 0 16px;height:calc(3em - 1px);line-height:calc(3em - 1px)}:host-context([dir=rtl]) .mat-select-search-input{padding-right:16px;padding-left:44px}.mat-select-search-inner-toggle-all .mat-select-search-input{padding-left:5px}.mat-select-search-no-entries-found{padding-top:8px}.mat-select-search-clear{position:absolute;right:4px;top:0}:host-context([dir=rtl]) .mat-select-search-clear{right:auto;left:4px}.mat-select-search-spinner{position:absolute;right:16px;top:calc(50% - 8px)}:host-context([dir=rtl]) .mat-select-search-spinner{right:auto;left:16px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search{position:sticky;top:-8px;z-index:1;opacity:1;margin-top:-8px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0;margin-left:0}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search mat-pseudo-checkbox{display:none}.mat-select-search-toggle-all-checkbox{padding-left:5px}:host-context([dir=rtl]) .mat-select-search-toggle-all-checkbox{padding-left:0;padding-right:5px}\n"] }]
        }], ctorParameters: function () { return [{ type: i11.MatSelect, decorators: [{
                    type: Inject,
                    args: [MatSelect]
                }] }, { type: i0.ChangeDetectorRef }, { type: i1.ViewportRuler }, { type: i12.MatOption, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MatOption]
                }] }, { type: i13.MatFormField, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MatFormField]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [ASW_SELECTSEARCH_DEFAULT_OPTIONS]
                }] }]; }, propDecorators: { placeholderLabel: [{
                type: Input
            }], type: [{
                type: Input
            }], closeIcon: [{
                type: Input
            }], closeSvgIcon: [{
                type: Input
            }], noEntriesFoundLabel: [{
                type: Input
            }], clearSearchInput: [{
                type: Input
            }], searching: [{
                type: Input
            }], disableInitialFocus: [{
                type: Input
            }], enableClearOnEscapePressed: [{
                type: Input
            }], preventHomeEndKeyPropagation: [{
                type: Input
            }], disableScrollToActiveOnOptionsChanged: [{
                type: Input
            }], ariaLabel: [{
                type: Input
            }], showToggleAllCheckbox: [{
                type: Input
            }], toggleAllCheckboxChecked: [{
                type: Input
            }], toggleAllCheckboxIndeterminate: [{
                type: Input
            }], toggleAllCheckboxTooltipMessage: [{
                type: Input
            }], toggleAllCheckboxTooltipPosition: [{
                type: Input
            }], hideClearSearchButton: [{
                type: Input
            }], alwaysRestoreSelectedOptionsMulti: [{
                type: Input
            }], toggleAll: [{
                type: Output
            }], searchSelectInput: [{
                type: ViewChild,
                args: ['searchSelectInput', { read: ElementRef, static: true }]
            }], innerSelectSearch: [{
                type: ViewChild,
                args: ['innerSelectSearch', { read: ElementRef, static: true }]
            }], clearIcon: [{
                type: ContentChild,
                args: [AswSelectSearchClearDirective]
            }], noEntriesFound: [{
                type: ContentChild,
                args: [AswSelectNoEntriesFoundDirective]
            }] } });

/**
 * @license
 * Copyright ASW (A Software World) All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file
 */
class AswSelectSearchModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearchModule, declarations: [AswSelectSearch], imports: [CommonModule, FormsModule, ReactiveFormsModule, MaterialModule, AswConfirmDialogModule, AswSharedDialogModule, AswTranslateModule, AswPipeModule, MatProgressSpinnerModule, AswDirectiveModule], exports: [AswSelectSearch] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearchModule, imports: [CommonModule, FormsModule, ReactiveFormsModule, MaterialModule, AswConfirmDialogModule, AswSharedDialogModule, AswTranslateModule, AswPipeModule, MatProgressSpinnerModule, AswDirectiveModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: AswSelectSearchModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule, FormsModule, ReactiveFormsModule, MaterialModule, AswConfirmDialogModule, AswSharedDialogModule, AswTranslateModule, AswPipeModule, MatProgressSpinnerModule, AswDirectiveModule],
                    declarations: [AswSelectSearch],
                    exports: [AswSelectSearch]
                }]
        }] });

/**
 * @license
 * Copyright ASW (A Software World) All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file
 */

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

export { ASW_SELECTSEARCH_DEFAULT_OPTIONS, AswSelectSearch, AswSelectSearchModule, configurableDefaultOptions };
//# sourceMappingURL=asoftwareworld-form-builder-pro-form-control-select-search.mjs.map
