import { Host, h, forceUpdate, } from "@stencil/core";
import { getInputDescribedByText, getLabelFromValue, hasValidationStatus, inheritAttributes, onComponentRequiredPropUndefined, renderHiddenInput, isMobileOrTablet, getFilteredMenuOptions, getOptionsWithoutGroupTitlesCount, addFormResetListener, removeFormResetListener, removeDisabledFalse, checkSlotInChildMutations, } from "../../utils/helpers";
import { IC_INHERITED_ARIA } from "../../utils/constants";
import { IcInformationStatus, } from "../../utils/types";
import Expand from "./assets/Expand.svg";
import Clear from "./assets/Clear.svg";
let inputIds = 0;
const MUTABLE_ATTRIBUTES = [...IC_INHERITED_ARIA, "tabindex", "title"];
/**
 * @slot icon - Content will be placed to the left of the select text input.
 */
export class Select {
    constructor() {
        this.hasSetDefaultValue = false;
        this.inheritedAttributes = {};
        this.initialOptionsEmpty = false;
        this.inputId = `ic-select-input-${inputIds++}`;
        this.menuId = `${this.inputId}-menu`;
        this.searchableMenuItemSelected = false;
        this.ungroupedOptions = [];
        this.hostMutationObserver = null;
        this.clearButtonFocused = false;
        this.noOptions = null;
        this.open = false;
        this.pressedCharacters = "";
        this.searchableSelectInputValue = null;
        /**
         * If `true`, the disabled state will be set.
         */
        this.disabled = false;
        /**
         * If `true`, the built in filtering will be disabled for a searchable variant. For example, if options will already be filtered from external source.
         */
        this.disableAutoFiltering = false;
        /**
         * The text displayed when there are no options in the option list.
         */
        this.emptyOptionListText = "No results found";
        /**
         * If `true`, the select will fill the width of the container.
         */
        this.fullWidth = false;
        /**
         * The helper text that will be displayed for additional field guidance.
         */
        this.helperText = "";
        /**
         * If `true`, the label will be hidden and the required label value will be applied as an aria-label.
         */
        this.hideLabel = false;
        /**
         * If `true`, descriptions of options will be included when filtering options in a searchable select. Only applies to built in filtering.
         */
        this.includeDescriptionsInSearch = false;
        /**
         * If `true`, group titles of grouped options will be included when filtering options in a searchable select. Only applies to built in filtering.
         */
        this.includeGroupTitlesInSearch = false;
        /**
         * The message displayed when external loading times out.
         */
        this.loadingErrorLabel = "Loading Error";
        /**
         * The message displayed whilst the options are being loaded externally.
         */
        this.loadingLabel = "Loading...";
        /**
         * If `true`, multiple options can be selected.
         */
        this.multiple = false;
        /**
         * The name of the control, which is submitted with the form data.
         */
        this.name = this.inputId;
        /**
         * The placeholder value to be displayed.
         */
        this.placeholder = "Select an option";
        /**
         * If `true`, the readonly state will be set.
         */
        this.readonly = false;
        /**
         * If `true`, the select will require a value.
         */
        this.required = false;
        /**
         * If `true`, a searchable variant of the select will be displayed which can be typed in to filter options. This functionality is only available on the single-select variant of the select component.
         */
        this.searchable = false;
        /**
         * Whether the search string of the searchable select should match the start of or anywhere in the options. Only applies to built in filtering.
         */
        this.searchMatchPosition = "anywhere";
        /**
         * If `true`, the icOptionSelect event will be fired on enter instead of ArrowUp and ArrowDown on the single select.
         */
        this.selectOnEnter = false;
        /**
         * If `true`, a button which clears the select input when clicked will be displayed. The button will always appear on the searchable select.
         */
        this.showClearButton = false;
        /**
         * The size of the select.
         */
        this.size = "medium";
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        /**
         * The validation status - e.g. 'error' | 'warning' | 'success'.
         */
        this.validationStatus = "";
        /**
         * The text to display as the validation message.
         */
        this.validationText = "";
        /**
         * If `true`, the loading state will be triggered when fetching options asynchronously.
         */
        this.loading = false;
        /**
         * The possible selection options.
         */
        this.options = [];
        this.filteredOptions = this.options;
        this.uniqueOptions = this.options;
        /**
         * The amount of time, in milliseconds, to wait to trigger the `icInput` event after each keystroke.
         */
        this.debounce = 0;
        this.currDebounce = this.debounce;
        this.initialValue = this.value;
        this.inputValueToFilter = this.value;
        // triggered when attributes of host element change
        this.hostMutationCallback = (mutationList) => {
            let forceComponentUpdate = false;
            mutationList.forEach(({ attributeName, type, addedNodes, removedNodes }) => {
                if (attributeName) {
                    const attribute = this.el.getAttribute(attributeName);
                    if (attribute && MUTABLE_ATTRIBUTES.includes(attributeName)) {
                        this.inheritedAttributes[attributeName] = attribute;
                        forceComponentUpdate = true;
                    }
                }
                else if (type === "childList") {
                    forceComponentUpdate = checkSlotInChildMutations(addedNodes, removedNodes, "icon");
                }
            });
            if (forceComponentUpdate) {
                forceUpdate(this);
            }
        };
        this.handleRetry = (ev) => {
            var _a;
            if (ev.detail.keyPressed)
                (_a = this.searchableSelectElement) === null || _a === void 0 ? void 0 : _a.focus();
            this.blurredBecauseButtonPressed = true;
            this.retryButtonClick = true;
            this.hasSetDefaultValue = true;
            this.icRetryLoad.emit({
                value: this.searchable
                    ? this.searchableSelectInputValue
                    : this.hiddenInputValue,
            });
        };
        this.emitIcChange = (value) => {
            // If "Select all" button clicked, replace value with new value (array of all option values)
            if (this.multiple && !Array.isArray(value) && value !== null) {
                this.handleMultipleSelectChange(String(value));
            }
            else {
                this.value = value;
            }
            const valueToEmit = this.multiple ? this.value : value;
            this.icChange.emit({ value: valueToEmit || null });
        };
        this.emitIcInput = (value) => {
            clearTimeout(this.debounceIcInput);
            this.debounceIcInput = window.setTimeout(() => this.icInput.emit({ value }), this.currDebounce);
        };
        this.setOptions = () => {
            if (!this.hasTimedOut && this.options !== this.noOptions) {
                this.loading = false;
                clearTimeout(this.timeoutTimer);
                if (this.options.length > 0) {
                    this.setOptionsValuesFromLabels();
                    this.uniqueOptions = this.deduplicateOptions(this.options);
                    this.filteredOptions = this.uniqueOptions;
                }
                else {
                    this.noOptions = [{ label: this.emptyOptionListText, value: "" }];
                    this.uniqueOptions = this.noOptions;
                    this.filteredOptions = this.noOptions;
                }
                if (this.isExternalFiltering()) {
                    // When searchable select
                    this.noOptions = null;
                    this.updateSearchableSelectResultAriaLive();
                    this.setDefaultValue();
                }
                else {
                    if (this.initialOptionsEmpty) {
                        this.setDefaultValue();
                        this.initialOptionsEmpty = false;
                    }
                }
            }
            else {
                if (!this.searchable) {
                    this.options = this.noOptions || [];
                }
            }
        };
        /**
         * Processes the provided array of IcMenuOptions, removing duplicates and reporting them with a console.warn
         * @param options array of IcMenuOptions
         * @returns a new options object, with all entries possessing a duplicate 'value' field removed
         */
        this.deduplicateOptions = (options) => {
            const uniqueValues = [];
            const dedupedOptions = [];
            let dedupedChildren;
            options.forEach((option) => {
                if (option.children) {
                    //If an option has children, we will loop through them
                    dedupedChildren = [];
                    option.children.forEach((child) => {
                        if (uniqueValues.includes(child.value)) {
                            console.warn(`ic-select with label ${this.label} was populated with duplicate option (value: ${child.value}) which has been removed.`);
                        }
                        else {
                            uniqueValues.push(child.value);
                            dedupedChildren.push(child);
                        }
                    });
                    // construct a modified option, inserting the deduplicated children alongside the original information
                    const modifiedParent = Object.assign(Object.assign({}, option), { children: dedupedChildren });
                    dedupedOptions.push(modifiedParent);
                }
                else {
                    // If an option does not have children, assess to see if it's value has been included already
                    if (uniqueValues.includes(option.value)) {
                        console.warn(`ic-select with label ${this.label} was populated with duplicate option (value: ${option.value}) which has been removed.`);
                    }
                    else {
                        uniqueValues.push(option.value);
                        dedupedOptions.push(option);
                    }
                }
            });
            return dedupedOptions;
        };
        /**
         * Loop through options array and for all options with no value, infer it from the label
         */
        this.setOptionsValuesFromLabels = () => {
            if (this.options.length > 0) {
                this.options.map((option) => {
                    if (!option.value) {
                        option.value = option.label;
                    }
                });
            }
        };
        this.setUngroupedOptions = (event) => {
            this.ungroupedOptions = event.detail.options;
        };
        this.setTextColor = () => {
            if (this.nativeSelectElement) {
                if (this.nativeSelectElement.selectedIndex === 0) {
                    this.nativeSelectElement.className = "placeholder";
                }
                else {
                    this.nativeSelectElement.className = "select-option-selected";
                }
            }
        };
        this.setMenuChange = (open) => {
            if (this.open !== open) {
                this.open = open;
            }
        };
        this.getLabelFromValue = (value) => {
            return getLabelFromValue(value, this.uniqueOptions);
        };
        this.getMultipleOptionsString = (selectedValues) => {
            const selectedLabels = selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.map((value) => this.getLabelFromValue(value)).filter((label) => !!label);
            return selectedLabels === null || selectedLabels === void 0 ? void 0 : selectedLabels.join(", ");
        };
        this.getFilteredChildMenuOptions = (option) => {
            let children = option.children;
            if (option.children) {
                if (this.searchable) {
                    children = getFilteredMenuOptions(option.children, !!this.includeDescriptionsInSearch, this.searchableSelectInputValue || "", this.searchMatchPosition);
                }
                else {
                    children = getFilteredMenuOptions(option.children, false, this.pressedCharacters, "start");
                }
            }
            const newOption = Object.assign({}, option);
            newOption.children = children;
            return newOption;
        };
        // (For multi-select) get value array, i.e. selected option values, in order they appear in option list
        this.getValueSortedByOptions = (value) => {
            const valueArray = value;
            const valuesFromAllOptions = this.ungroupedOptions.map((option) => option.value);
            valueArray.sort((a, b) => valuesFromAllOptions.indexOf(a) - valuesFromAllOptions.indexOf(b));
            return valueArray;
        };
        this.handleNativeSelectChange = () => {
            if (this.nativeSelectElement) {
                this.icOptionSelect.emit({ value: this.nativeSelectElement.value });
                this.emitIcChange(this.nativeSelectElement.value);
            }
            this.setTextColor();
        };
        // Handle option select for when a custom input box and menu is rendered
        // (rather than native <select> - rendered when viewed on a mobile / tablet screen)
        this.handleCustomSelectChange = (event) => {
            var _a, _b;
            const value = event.detail.value;
            if (event.detail.label === this.emptyOptionListText) {
                (_a = this.searchableSelectElement) === null || _a === void 0 ? void 0 : _a.focus();
                return;
            }
            if (this.searchable) {
                this.value = value;
                this.searchableMenuItemSelected = true;
                // After editing the input, if selecting the same option as before, set the input value to label again
                if (this.value === this.currValue) {
                    this.searchableSelectInputValue =
                        this.getLabelFromValue(this.value) || null;
                }
                this.inputValueToFilter = null;
                this.hiddenInputValue =
                    this.getValueFromLabel(this.searchableSelectInputValue) || null;
            }
            if (this.multiple && ((_b = this.value) === null || _b === void 0 ? void 0 : _b.includes(value))) {
                this.icOptionDeselect.emit({ value });
            }
            else {
                this.icOptionSelect.emit({ value });
            }
            this.ariaActiveDescendant = event.detail.optionId;
            this.emitIcChange(value);
        };
        // Update selected options - adds / removes them, in order of option list
        // Create new array if value prop is undefined
        this.handleMultipleSelectChange = (value) => {
            if (this.value) {
                let valueArray = this.value.slice();
                if (this.value.includes(value)) {
                    const valueIndex = valueArray.indexOf(value);
                    valueArray.splice(valueIndex, 1);
                }
                else {
                    valueArray.push(value);
                    valueArray = this.getValueSortedByOptions(valueArray);
                }
                this.value = valueArray.length === 0 ? null : valueArray;
            }
            else {
                const valueArray = [];
                valueArray.push(value);
                this.value = valueArray;
            }
        };
        this.handleSelectAllChange = (event) => {
            const selectAllOptions = event.detail.select;
            const allEnabledOptions = this.ungroupedOptions.filter((option) => !option.disabled);
            const allValues = allEnabledOptions.map((option) => option.value);
            let newValue;
            if (selectAllOptions) {
                let unselectedValues;
                // Only emit icOptionSelect for all values that are newly selected
                if (this.value) {
                    unselectedValues = allValues.filter((value) => this.value && !this.value.includes(value));
                }
                else {
                    unselectedValues = allValues;
                }
                unselectedValues.forEach((value) => this.icOptionSelect.emit({ value }));
                newValue = allValues;
            }
            else {
                // Only emit icOptionDeselect for values that were selected
                this.value.forEach((value) => this.icOptionDeselect.emit({ value }));
                newValue = null;
            }
            this.emitIcChange(newValue);
        };
        this.handleMenuChange = (event) => {
            this.open = event.detail.open;
            this.pressedCharacters = "";
            this.searchable && this.handleFocusIndicatorDisplay();
        };
        // clears the debounce delay when navigating the menu with arrow keys etc
        // to prevent delay in change event, which should only occur when typing in input
        this.handleMenuKeyPress = (ev) => {
            ev.cancelBubble = true;
            if (!this.multiple) {
                this.handleCharacterKeyDown(ev.detail.key);
            }
        };
        this.handleFocusIndicatorDisplay = () => {
            var _a;
            const focusIndicator = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".focus-indicator");
            if (focusIndicator) {
                if (this.open) {
                    focusIndicator.classList.add("focus-indicator-enabled");
                }
                else {
                    focusIndicator.classList.remove("focus-indicator-enabled");
                }
            }
        };
        this.handleMouseDown = (event) => {
            if (!this.open) {
                event.preventDefault();
            }
        };
        this.isExternalFiltering = () => this.searchable && !!this.disableAutoFiltering;
        this.handleClick = (event) => {
            var _a, _b;
            if (!this.open && this.menu) {
                if (this.isExternalFiltering()) {
                    this.menu.options = this.filteredOptions;
                }
                else if (!this.hasTimedOut &&
                    !this.loading &&
                    !((_a = this.noOptions) === null || _a === void 0 ? void 0 : _a.length) &&
                    (!this.searchable || this.searchableMenuItemSelected)) {
                    this.noOptions = null;
                    this.menu.options = this.uniqueOptions;
                }
            }
            if (event.detail !== 0) {
                (_b = this.menu) === null || _b === void 0 ? void 0 : _b.handleClickOpen();
            }
        };
        this.handleExpandIconMouseDown = (event) => {
            var _a;
            if (!this.disabled) {
                event.preventDefault();
                (_a = this.searchableSelectElement) === null || _a === void 0 ? void 0 : _a.focus();
                this.handleClick(event);
            }
        };
        this.handleClear = (event) => {
            var _a, _b;
            event.stopPropagation();
            this.hasTimedOut = false;
            clearTimeout(this.timeoutTimer);
            this.clearInput();
            this.emitIcChange(null);
            this.icClear.emit();
            if (this.searchable) {
                this.hiddenInputValue = null;
                (_a = this.searchableSelectElement) === null || _a === void 0 ? void 0 : _a.focus();
            }
            else {
                (_b = this.customSelectElement) === null || _b === void 0 ? void 0 : _b.focus();
            }
        };
        this.handleCharacterKeyDown = (key) => {
            // Only close menu when space is pressed if not being used alongside character keys to quickly select options
            if (this.open && key === " " && this.pressedCharacters.length === 0) {
                this.setMenuChange(false);
            }
            if (key.length === 1 && !this.searchable) {
                window.clearTimeout(this.characterKeyPressTimer);
                this.characterKeyPressTimer = window.setTimeout(() => (this.pressedCharacters = ""), 1000);
                if (!(key === " " && !this.pressedCharacters)) {
                    this.pressedCharacters += key;
                    this.handleFilter();
                    if (!this.noOptions) {
                        this.emitIcChange(this.filteredOptions[0].value);
                    }
                }
            }
            else {
                this.pressedCharacters = "";
            }
        };
        this.handleNativeSelectKeyDown = (event) => {
            if ((event.key !== "Escape" && event.key !== "Tab") || this.open) {
                event.cancelBubble = true;
            }
            this.handleCharacterKeyDown(event.key);
        };
        this.handleKeyDown = (event) => {
            var _a;
            if ((event.key !== "Escape" && event.key !== "Tab") || this.open) {
                event.cancelBubble = true;
            }
            const isArrowKey = event.key === "ArrowDown" || event.key === "ArrowUp";
            if (this.menu && !this.open) {
                if (this.isExternalFiltering() && (event.key === "Enter" || isArrowKey)) {
                    this.menu.options = this.filteredOptions;
                }
                else {
                    if (!this.hasTimedOut) {
                        this.noOptions = null;
                        this.menu.options = this.uniqueOptions;
                    }
                }
            }
            if (this.open && event.key === "Enter") {
                this.setMenuChange(false);
            }
            else {
                if (!(isArrowKey && this.noOptions !== null)) {
                    if (!(event.key === " " && this.pressedCharacters.length > 0)) {
                        // Keyboard events get passed onto ic-menu
                        (_a = this.menu) === null || _a === void 0 ? void 0 : _a.handleKeyboardOpen(event);
                    }
                    if (!this.multiple) {
                        this.handleCharacterKeyDown(event.key);
                    }
                }
            }
        };
        this.handleClearButtonFocus = () => {
            this.clearButtonFocused = true;
        };
        this.handleClearButtonBlur = (ev) => {
            var _a;
            const retryButton = (_a = this.menu) === null || _a === void 0 ? void 0 : _a.querySelector("#retry-button");
            if (!(this.searchableSelectElement &&
                ev.relatedTarget === this.searchableSelectElement) &&
                !(retryButton && ev.relatedTarget === retryButton)) {
                this.setMenuChange(false);
                this.handleFocusIndicatorDisplay();
            }
            this.clearButtonFocused = false;
        };
        this.handleFilter = () => {
            var _a;
            const options = this.deduplicateOptions(this.searchable ? [...this.uniqueOptions] : this.ungroupedOptions);
            let isGrouped = false;
            let newFilteredOptions = [];
            options.map((option) => {
                if (option.children)
                    isGrouped = true;
            });
            let menuOptionsFiltered;
            if (this.searchable) {
                menuOptionsFiltered = getFilteredMenuOptions(options, !!this.includeDescriptionsInSearch, this.inputValueToFilter || "", this.searchMatchPosition);
                this.searchableMenuItemSelected = false;
            }
            else {
                menuOptionsFiltered = getFilteredMenuOptions(options, false, this.pressedCharacters, "start");
            }
            if (!isGrouped &&
                ((_a = menuOptionsFiltered[0]) === null || _a === void 0 ? void 0 : _a.label) !== this.emptyOptionListText) {
                newFilteredOptions = menuOptionsFiltered;
            }
            else if (isGrouped) {
                options.map((option) => {
                    if (this.includeGroupTitlesInSearch) {
                        if (menuOptionsFiltered.indexOf(option) !== -1) {
                            newFilteredOptions.push(option);
                        }
                        else {
                            newFilteredOptions.push(this.getFilteredChildMenuOptions(option));
                        }
                    }
                    else {
                        newFilteredOptions.push(this.getFilteredChildMenuOptions(option));
                    }
                });
            }
            let noChildOptionsWhenFiltered = false;
            if (isGrouped) {
                noChildOptionsWhenFiltered = true;
                newFilteredOptions.map((option) => {
                    if (option.children && option.children.length > 0) {
                        noChildOptionsWhenFiltered = false;
                    }
                });
            }
            if (newFilteredOptions.length > 0 && !noChildOptionsWhenFiltered) {
                this.noOptions = null;
                this.filteredOptions = newFilteredOptions;
            }
            else {
                this.noOptions = [{ label: this.emptyOptionListText, value: "" }];
                this.filteredOptions = this.noOptions;
            }
        };
        /**
         * Put the select component into loading state.
         * Replace options with the loading message. If timeout is enabled, set the timeout and once passed, replace options with the loading error message
         */
        this.triggerLoading = () => {
            this.hasTimedOut = false;
            this.noOptions = [{ label: this.loadingLabel, value: "", loading: true }];
            if (this.filteredOptions !== this.noOptions && this.searchable) {
                this.filteredOptions = this.noOptions;
            }
            else if (this.uniqueOptions !== this.noOptions && !this.searchable) {
                this.uniqueOptions = this.noOptions;
            }
            if (this.timeout) {
                this.timeoutTimer = window.setTimeout(() => {
                    this.loading = false;
                    this.hasTimedOut = true;
                    this.noOptions = [
                        { label: this.loadingErrorLabel, value: "", timedOut: true },
                    ];
                    this.filteredOptions = this.noOptions;
                    if (!this.searchable)
                        this.uniqueOptions = this.noOptions;
                }, this.timeout);
            }
        };
        this.getValueFromLabel = (label) => {
            var _a;
            return (label &&
                ((_a = this.uniqueOptions.find((option) => option.label === label)) === null || _a === void 0 ? void 0 : _a.value));
        };
        this.handleSearchableSelectInput = (event) => {
            this.searchableSelectInputValue = event.target.value;
            this.emitIcInput(this.searchableSelectInputValue);
            // De-select previous selection when input is edited
            // Only emit icChange once when editing input
            if (this.value != null) {
                this.emitIcChange(null);
            }
            this.hiddenInputValue = null;
            this.inputValueToFilter = this.searchableSelectInputValue;
            this.setMenuChange(true);
            if (!this.disableAutoFiltering) {
                this.handleFilter();
                this.debounceAriaLiveUpdate();
            }
        };
        this.updateSearchableSelectResultAriaLive = () => {
            var _a;
            const searchableSelectResultsStatusEl = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".searchable-select-results-status");
            if (searchableSelectResultsStatusEl) {
                if (this.noOptions !== null) {
                    searchableSelectResultsStatusEl.innerText = this.emptyOptionListText;
                }
                else {
                    searchableSelectResultsStatusEl.innerText = "";
                }
            }
        };
        this.updateMultiSelectedCountAriaLive = () => {
            var _a, _b;
            const multiSelectSelectedCountEl = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".multi-select-selected-count");
            const selectedCount = `${(_b = this.currValue) === null || _b === void 0 ? void 0 : _b.length} of ${getOptionsWithoutGroupTitlesCount(this.options)} selected`;
            if (multiSelectSelectedCountEl &&
                multiSelectSelectedCountEl.innerText !== selectedCount) {
                multiSelectSelectedCountEl.innerText = selectedCount;
            }
        };
        this.getDefaultValue = (value) => this.getLabelFromValue(value) || null;
        this.setDefaultValue = () => {
            if (!this.hasSetDefaultValue && this.currValue) {
                this.searchableSelectInputValue = this.searchable
                    ? this.getDefaultValue(this.currValue)
                    : null;
                this.initialValue = this.currValue;
                this.hasSetDefaultValue = true;
            }
        };
        this.onFocus = () => {
            this.icFocus.emit();
        };
        this.onBlur = ({ relatedTarget }) => {
            var _a;
            const target = relatedTarget;
            if (target !== null &&
                ((target.tagName === "UL" && target.className.includes("menu")) ||
                    (target.tagName === "LI" && target.className.includes("option")))) {
                return;
            }
            const retryButton = (_a = this.menu) === null || _a === void 0 ? void 0 : _a.querySelector("#retry-button");
            const isSearchableAndNoFocusedInternalElements = this.searchable &&
                !!this.menu &&
                target !== this.menu &&
                !Array.from(this.menu.querySelectorAll("[role='option']")).includes(target) &&
                !(this.clearButton && target === this.clearButton) &&
                !(retryButton && target === retryButton);
            if (isSearchableAndNoFocusedInternalElements) {
                if (!this.retryButtonClick) {
                    this.setMenuChange(false);
                    // Clear input field on blur when searchable if no option is selected
                    if (!this.value) {
                        this.clearInput();
                    }
                }
                this.handleFocusIndicatorDisplay();
            }
            this.retryButtonClick = false;
            this.icBlur.emit();
        };
        this.onTimeoutBlur = (ev) => {
            if (ev.detail.ev.relatedTarget !==
                this.searchableSelectElement &&
                !this.blurredBecauseButtonPressed) {
                this.setMenuChange(false);
                this.handleFocusIndicatorDisplay();
                this.icBlur.emit();
            }
            this.blurredBecauseButtonPressed = false;
        };
        this.handleFormReset = () => {
            this.value = this.initialValue;
            if (this.searchable) {
                this.searchableSelectInputValue = this.getDefaultValue(this.value);
                this.hiddenInputValue = this.value;
            }
        };
        this.clearInput = () => {
            var _a;
            this.noOptions = null;
            if (this.searchable) {
                (_a = this.searchableSelectElement) === null || _a === void 0 ? void 0 : _a.setAttribute("value", "");
                this.searchableSelectInputValue = null;
                this.filteredOptions = this.uniqueOptions;
            }
        };
    }
    watchDisabledHandler() {
        removeDisabledFalse(this.disabled, this.el);
    }
    loadingHandler(newValue) {
        newValue ? this.triggerLoading() : this.setOptions();
    }
    watchOptionsHandler() {
        this.setOptions();
    }
    debounceChangedHandler(newValue) {
        this.updateOnChangeDebounce(newValue);
    }
    valueChangedHandler() {
        if (this.value !== this.currValue) {
            if (this.value && this.multiple) {
                this.currValue = this.getMultipleOptionsString(this.value)
                    ? this.getValueSortedByOptions(this.value)
                    : null;
                this.updateMultiSelectedCountAriaLive();
            }
            else {
                this.currValue = this.getLabelFromValue(this.value)
                    ? this.value
                    : null;
            }
        }
        if (this.searchable && this.value) {
            // Only set if value not null - prevents whole input value being cleared when edited
            this.searchableSelectInputValue =
                this.getLabelFromValue(String(this.currValue)) || null;
        }
    }
    openChangedHandler() {
        this.open ? this.icOpen.emit() : this.icClose.emit();
    }
    disconnectedCallback() {
        var _a;
        removeFormResetListener(this.el, this.handleFormReset);
        (_a = this.hostMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
    }
    componentWillLoad() {
        const valueInOptions = this.multiple
            ? this.getMultipleOptionsString(this.value)
            : this.getLabelFromValue(this.value);
        this.currValue = valueInOptions ? this.value : null;
        this.inheritedAttributes = inheritAttributes(this.el, MUTABLE_ATTRIBUTES);
        removeDisabledFalse(this.disabled, this.el);
        this.setOptionsValuesFromLabels();
        addFormResetListener(this.el, this.handleFormReset);
        if (!this.options.length) {
            this.initialOptionsEmpty = true;
            this.noOptions = [{ label: this.emptyOptionListText, value: "" }];
            this.uniqueOptions = this.noOptions;
            this.filteredOptions = this.noOptions;
        }
        else {
            this.setDefaultValue();
            this.uniqueOptions = this.deduplicateOptions(this.options);
        }
    }
    componentDidLoad() {
        onComponentRequiredPropUndefined([{ prop: this.label, propName: "label" }], "Select");
        if (this.loading) {
            this.triggerLoading();
        }
        if (this.searchable) {
            this.hiddenInputValue = this.currValue;
        }
        this.hostMutationObserver = new MutationObserver(this.hostMutationCallback);
        this.hostMutationObserver.observe(this.el, {
            attributes: true,
            childList: true,
        });
    }
    componentDidRender() {
        if (this.nativeSelectElement && !this.disabled) {
            this.setTextColor();
        }
    }
    /**
     * Sets focus on the input box.
     */
    async setFocus() {
        if (this.nativeSelectElement) {
            this.nativeSelectElement.focus();
        }
        else if (this.customSelectElement) {
            this.customSelectElement.focus();
        }
        else if (this.searchableSelectElement) {
            this.searchableSelectElement.focus();
        }
    }
    updateOnChangeDebounce(newValue) {
        if (this.currDebounce !== newValue) {
            this.currDebounce = newValue;
        }
    }
    debounceAriaLiveUpdate() {
        clearTimeout(this.debounceAria);
        window.setTimeout(() => {
            this.updateSearchableSelectResultAriaLive();
        }, 800);
    }
    render() {
        const { size, disabled, fullWidth, helperText, hideLabel, label, menuId, multiple, name, options, placeholder, readonly, required, searchable, showClearButton, validationStatus, validationText, currValue, theme, } = this;
        // HTML inputs only accept 'string' for their value
        // Does not cause errors when it is a multi-select - sets value correctly, to a comma-separated string
        renderHiddenInput(this.el, this.searchable ? this.hiddenInputValue : currValue, name || this.inputId, disabled);
        const invalid = `${validationStatus === IcInformationStatus.Error}`;
        const describedBy = getInputDescribedByText(this.inputId, helperText !== "", hasValidationStatus(this.validationStatus, !!this.disabled)).trim();
        let showLeftIcon = !!this.el.querySelector(`[slot="icon"]`);
        if (showLeftIcon && (disabled || (readonly && !this.value))) {
            showLeftIcon = false;
        }
        const optionsSelectedCount = `${currValue === null || currValue === void 0 ? void 0 : currValue.length} of ${getOptionsWithoutGroupTitlesCount(this.options)} selected`;
        const valueLabelString = multiple
            ? this.getMultipleOptionsString(currValue)
            : this.getLabelFromValue(currValue);
        const isClearable = !disabled &&
            (searchable
                ? this.searchableSelectInputValue
                : currValue && !this.loading && showClearButton);
        return (h(Host, { key: '456f6fa40aca4f93fba6e0c43c57cc171c358ede', class: {
                "ic-select-disabled": !!disabled,
                "ic-select-searchable": !!searchable,
                [`ic-select-${size}`]: size !== "medium",
                "ic-select-full-width": !!fullWidth,
                [`ic-theme-${theme}`]: theme !== "inherit",
            }, onBlur: this.onBlur }, h("ic-input-container", { key: 'f97234577ffc014d5da69a0ebbf8abac0a97e034', readonly: readonly }, !hideLabel && (h("ic-input-label", { key: 'a6a1bf8152904b7a845de920bd9717c76ea47f2e', for: this.inputId, label: label, helperText: helperText, required: required, disabled: disabled, readonly: readonly })), h("ic-input-component-container", { key: '6515fb2dca1c45d6388123ea2d75f5de57f1bc36', ref: (el) => (this.anchorEl = el), class: { "menu-open": this.open }, size: size, fullWidth: fullWidth, disabled: disabled, readonly: readonly, validationStatus: validationStatus }, showLeftIcon && (h("span", { key: '0f70c956b1be70903d518c3dc787fc3980a0c205', slot: "left-icon", class: {
                ["readonly"]: !!readonly,
                ["has-value"]: !!this.value,
            } }, h("slot", { key: '7e602e257167e4397fc131b118da86b0e3d38583', name: "icon" }))), readonly ? (h("ic-typography", null, h("p", null, valueLabelString))) : isMobileOrTablet() && !multiple ? (h("select", Object.assign({ ref: (el) => (this.nativeSelectElement = el), disabled: disabled, onChange: this.handleNativeSelectChange, required: required, id: this.inputId, "aria-label": label, "aria-describedby": describedBy, "aria-invalid": invalid, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.handleNativeSelectKeyDown, form: this.form }, this.inheritedAttributes), h("option", { value: "", selected: true, disabled: !showClearButton }, placeholder), options.map((option) => {
            if (option.children) {
                return (h("optgroup", { label: option.label }, option.children.map((option) => (h("option", { value: option.value, disabled: option.disabled, selected: option.value === currValue }, option.label)))));
            }
            else {
                return (h("option", { value: option.value, disabled: option.disabled, selected: option.value === currValue }, option.label));
            }
        }))) : searchable ? (h("div", { class: "searchable-select-container" }, h("input", { class: {
                "select-input": true,
                "with-clear-button": !!this.searchableSelectInputValue,
            }, role: "combobox", autocomplete: "off", "aria-label": label, "aria-describedby": describedBy, "aria-activedescendant": this.ariaActiveDescendant, "aria-autocomplete": "list", "aria-expanded": `${this.open}`, "aria-invalid": invalid, "aria-required": `${required}`, "aria-controls": menuId, ref: (el) => (this.searchableSelectElement = el), id: this.inputId, value: this.searchableSelectInputValue || undefined, placeholder: placeholder, disabled: disabled, onInput: this.handleSearchableSelectInput, onClick: this.handleClick, onKeyDown: this.handleKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, form: this.form }), isClearable && (h("div", { class: "clear-button-container" }, h("ic-button", { id: "clear-button", ref: (el) => (this.clearButton = el), "aria-label": this.searchableSelectInputValue &&
                (currValue === null || this.loading)
                ? "Clear input"
                : "Clear selection", class: "clear-button", innerHTML: Clear, onClick: this.handleClear, onFocus: this.handleClearButtonFocus, onBlur: this.handleClearButtonBlur, size: size, variant: "icon", theme: this.clearButtonFocused ? "light" : "dark" }), h("div", { class: "divider" }))), h("span", { onMouseDown: this.handleExpandIconMouseDown, class: {
                "expand-icon": true,
                "expand-icon-open": this.open,
            }, innerHTML: Expand, "aria-hidden": "true" }), h("div", { "aria-live": "polite", role: "status", class: "searchable-select-results-status" }))) : (h("div", { class: "select-container" }, h("button", { class: "select-input", ref: (el) => (this.customSelectElement = el), id: this.inputId, "aria-label": `${label}, ${(multiple && currValue
                ? `${optionsSelectedCount}, ${valueLabelString}`
                : valueLabelString) || placeholder}${required ? ", required" : ""}`, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-haspopup": "listbox", "aria-expanded": this.open ? "true" : "false", "aria-owns": menuId, "aria-controls": menuId, disabled: disabled, onBlur: this.onBlur, onFocus: this.onFocus, onClick: this.handleClick, onMouseDown: this.handleMouseDown, onKeyDown: this.handleKeyDown }, h("ic-typography", { variant: "body", class: {
                "value-text": true,
                "with-clear-button": !!isClearable,
                placeholder: !this.loading && multiple
                    ? !this.value || this.value.length < 1
                    : !this.getLabelFromValue(currValue),
            } }, valueLabelString || placeholder), h("div", { class: "select-input-end" }, isClearable && h("div", { class: "divider" }), h("span", { class: {
                "expand-icon": true,
                "expand-icon-open": this.open,
            }, innerHTML: Expand, "aria-hidden": "true" }))), isClearable && (h("ic-button", { id: "clear-button", "aria-label": "Clear selection", class: "clear-button", innerHTML: Clear, onClick: this.handleClear, onFocus: this.handleClearButtonFocus, onBlur: this.handleClearButtonBlur, size: size, variant: "icon", theme: this.clearButtonFocused ? "light" : "dark" }))))), (!isMobileOrTablet() || multiple) && (h("ic-menu", { key: 'f54e79314035d2c04a47292eb9e8e2ecd4421545', class: {
                "no-results": this.loading ||
                    this.hasTimedOut ||
                    (this.noOptions !== null &&
                        this.noOptions[0] &&
                        this.noOptions[0].label === this.emptyOptionListText),
            }, ref: (el) => (this.menu = el), inputEl: (searchable
                ? this.searchableSelectElement
                : this.customSelectElement), inputLabel: label, anchorEl: this.anchorEl, size: size, menuId: menuId, open: this.open, options: searchable ? this.filteredOptions : this.uniqueOptions, value: multiple ? currValue : currValue, fullWidth: fullWidth, selectOnEnter: this.selectOnEnter, onMenuStateChange: this.handleMenuChange, onMenuOptionSelect: this.handleCustomSelectChange, onMenuOptionSelectAll: this.handleSelectAllChange, onMenuKeyPress: this.handleMenuKeyPress, onUngroupedOptionsSet: this.setUngroupedOptions, onRetryButtonClicked: this.handleRetry, parentEl: this.el, onTimeoutBlur: this.onTimeoutBlur, activationType: this.searchable || multiple || this.selectOnEnter
                ? "manual"
                : "automatic", closeOnSelect: !multiple })), this.multiple && (h("div", { key: 'b1a65d56087d6603846cdd9cfc8c086e49597001', "aria-live": "polite", role: "status", class: "multi-select-selected-count" })), hasValidationStatus(this.validationStatus, !!this.disabled) && (h("ic-input-validation", { key: 'e5553be7be57e5ae847bcd1a4d2525b18c4d1429', class: { "menu-open": this.open }, ariaLiveMode: "polite", status: validationStatus, message: validationText || "", for: this.inputId })))));
    }
    static get is() { return "ic-select"; }
    static get encapsulation() { return "shadow"; }
    static get delegatesFocus() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-select.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-select.css"]
        };
    }
    static get properties() {
        return {
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the disabled state will be set."
                },
                "getter": false,
                "setter": false,
                "attribute": "disabled",
                "reflect": true,
                "defaultValue": "false"
            },
            "disableAutoFiltering": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the built in filtering will be disabled for a searchable variant. For example, if options will already be filtered from external source."
                },
                "getter": false,
                "setter": false,
                "attribute": "disable-auto-filtering",
                "reflect": false,
                "defaultValue": "false"
            },
            "emptyOptionListText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The text displayed when there are no options in the option list."
                },
                "getter": false,
                "setter": false,
                "attribute": "empty-option-list-text",
                "reflect": false,
                "defaultValue": "\"No results found\""
            },
            "form": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The <form> element to associate the select with."
                },
                "getter": false,
                "setter": false,
                "attribute": "form",
                "reflect": false
            },
            "fullWidth": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the select will fill the width of the container."
                },
                "getter": false,
                "setter": false,
                "attribute": "full-width",
                "reflect": false,
                "defaultValue": "false"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The helper text that will be displayed for additional field guidance."
                },
                "getter": false,
                "setter": false,
                "attribute": "helper-text",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "hideLabel": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the label will be hidden and the required label value will be applied as an aria-label."
                },
                "getter": false,
                "setter": false,
                "attribute": "hide-label",
                "reflect": false,
                "defaultValue": "false"
            },
            "includeDescriptionsInSearch": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, descriptions of options will be included when filtering options in a searchable select. Only applies to built in filtering."
                },
                "getter": false,
                "setter": false,
                "attribute": "include-descriptions-in-search",
                "reflect": false,
                "defaultValue": "false"
            },
            "includeGroupTitlesInSearch": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, group titles of grouped options will be included when filtering options in a searchable select. Only applies to built in filtering."
                },
                "getter": false,
                "setter": false,
                "attribute": "include-group-titles-in-search",
                "reflect": false,
                "defaultValue": "false"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label for the select."
                },
                "getter": false,
                "setter": false,
                "attribute": "label",
                "reflect": false
            },
            "loadingErrorLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The message displayed when external loading times out."
                },
                "getter": false,
                "setter": false,
                "attribute": "loading-error-label",
                "reflect": false,
                "defaultValue": "\"Loading Error\""
            },
            "loadingLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The message displayed whilst the options are being loaded externally."
                },
                "getter": false,
                "setter": false,
                "attribute": "loading-label",
                "reflect": false,
                "defaultValue": "\"Loading...\""
            },
            "multiple": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, multiple options can be selected."
                },
                "getter": false,
                "setter": false,
                "attribute": "multiple",
                "reflect": false,
                "defaultValue": "false"
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The name of the control, which is submitted with the form data."
                },
                "getter": false,
                "setter": false,
                "attribute": "name",
                "reflect": false,
                "defaultValue": "this.inputId"
            },
            "placeholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The placeholder value to be displayed."
                },
                "getter": false,
                "setter": false,
                "attribute": "placeholder",
                "reflect": false,
                "defaultValue": "\"Select an option\""
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the readonly state will be set."
                },
                "getter": false,
                "setter": false,
                "attribute": "readonly",
                "reflect": false,
                "defaultValue": "false"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the select will require a value."
                },
                "getter": false,
                "setter": false,
                "attribute": "required",
                "reflect": false,
                "defaultValue": "false"
            },
            "searchable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, a searchable variant of the select will be displayed which can be typed in to filter options. This functionality is only available on the single-select variant of the select component."
                },
                "getter": false,
                "setter": false,
                "attribute": "searchable",
                "reflect": false,
                "defaultValue": "false"
            },
            "searchMatchPosition": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcSearchMatchPositions",
                    "resolved": "\"anywhere\" | \"start\" | undefined",
                    "references": {
                        "IcSearchMatchPositions": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcSearchMatchPositions"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Whether the search string of the searchable select should match the start of or anywhere in the options. Only applies to built in filtering."
                },
                "getter": false,
                "setter": false,
                "attribute": "search-match-position",
                "reflect": false,
                "defaultValue": "\"anywhere\""
            },
            "selectOnEnter": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the icOptionSelect event will be fired on enter instead of ArrowUp and ArrowDown on the single select."
                },
                "getter": false,
                "setter": false,
                "attribute": "select-on-enter",
                "reflect": false,
                "defaultValue": "false"
            },
            "showClearButton": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, a button which clears the select input when clicked will be displayed. The button will always appear on the searchable select."
                },
                "getter": false,
                "setter": false,
                "attribute": "show-clear-button",
                "reflect": false,
                "defaultValue": "false"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcSizes",
                    "resolved": "\"large\" | \"medium\" | \"small\" | undefined",
                    "references": {
                        "IcSizes": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcSizes"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The size of the select."
                },
                "getter": false,
                "setter": false,
                "attribute": "size",
                "reflect": false,
                "defaultValue": "\"medium\""
            },
            "timeout": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If using external filtering, set a timeout for when loading takes too long."
                },
                "getter": false,
                "setter": false,
                "attribute": "timeout",
                "reflect": false
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            },
            "validationStatus": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcInformationStatusOrEmpty",
                    "resolved": "\"\" | \"error\" | \"success\" | \"warning\" | undefined",
                    "references": {
                        "IcInformationStatusOrEmpty": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcInformationStatusOrEmpty"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The validation status - e.g. 'error' | 'warning' | 'success'."
                },
                "getter": false,
                "setter": false,
                "attribute": "validation-status",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "validationText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The text to display as the validation message."
                },
                "getter": false,
                "setter": false,
                "attribute": "validation-text",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "loading": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the loading state will be triggered when fetching options asynchronously."
                },
                "getter": false,
                "setter": false,
                "attribute": "loading",
                "reflect": false,
                "defaultValue": "false"
            },
            "options": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "IcMenuOption[]",
                    "resolved": "IcMenuOption[] | undefined",
                    "references": {
                        "IcMenuOption": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcMenuOption"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The possible selection options."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "debounce": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The amount of time, in milliseconds, to wait to trigger the `icInput` event after each keystroke."
                },
                "getter": false,
                "setter": false,
                "attribute": "debounce",
                "reflect": false,
                "defaultValue": "0"
            },
            "value": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string | string[] | null",
                    "resolved": "null | string | string[] | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The value of the select, reflected by the value of the currently selected option.\nFor the searchable variant, the value is also reflected by the user input.\nFor the multi-select variant, the value must be an array of option values."
                },
                "getter": false,
                "setter": false,
                "attribute": "value",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "ariaActiveDescendant": {},
            "clearButtonFocused": {},
            "debounceIcInput": {},
            "hiddenInputValue": {},
            "noOptions": {},
            "open": {},
            "pressedCharacters": {},
            "searchableSelectInputValue": {},
            "filteredOptions": {},
            "uniqueOptions": {},
            "currDebounce": {},
            "initialValue": {},
            "inputValueToFilter": {},
            "currValue": {}
        };
    }
    static get events() {
        return [{
                "method": "icBlur",
                "name": "icBlur",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the select loses focus."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icChange",
                "name": "icChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the value changes."
                },
                "complexType": {
                    "original": "IcMultiValueEventDetail",
                    "resolved": "IcMultiValueEventDetail",
                    "references": {
                        "IcMultiValueEventDetail": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcMultiValueEventDetail"
                        }
                    }
                }
            }, {
                "method": "icClear",
                "name": "icClear",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the clear or clear all button is clicked."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icClose",
                "name": "icClose",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the select options menu is closed."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icFocus",
                "name": "icFocus",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the select gains focus."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icInput",
                "name": "icInput",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when a keyboard input occurred."
                },
                "complexType": {
                    "original": "IcMultiValueEventDetail",
                    "resolved": "IcMultiValueEventDetail",
                    "references": {
                        "IcMultiValueEventDetail": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcMultiValueEventDetail"
                        }
                    }
                }
            }, {
                "method": "icOpen",
                "name": "icOpen",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the select options menu is opened."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icOptionSelect",
                "name": "icOptionSelect",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when an option is selected.\nSelecting an option will also trigger an `icChange/onIcChange` due to the value being updated."
                },
                "complexType": {
                    "original": "IcOptionSelectEventDetail",
                    "resolved": "IcOptionSelectEventDetail",
                    "references": {
                        "IcOptionSelectEventDetail": {
                            "location": "import",
                            "path": "../ic-menu/ic-menu.types",
                            "id": "src/components/ic-menu/ic-menu.types.ts::IcOptionSelectEventDetail"
                        }
                    }
                }
            }, {
                "method": "icOptionDeselect",
                "name": "icOptionDeselect",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when `multiple` is `true` and an option is deselected."
                },
                "complexType": {
                    "original": "IcOptionSelectEventDetail",
                    "resolved": "IcOptionSelectEventDetail",
                    "references": {
                        "IcOptionSelectEventDetail": {
                            "location": "import",
                            "path": "../ic-menu/ic-menu.types",
                            "id": "src/components/ic-menu/ic-menu.types.ts::IcOptionSelectEventDetail"
                        }
                    }
                }
            }, {
                "method": "icRetryLoad",
                "name": "icRetryLoad",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the 'retry loading' button is clicked for a searchable variant."
                },
                "complexType": {
                    "original": "IcMultiValueEventDetail",
                    "resolved": "IcMultiValueEventDetail",
                    "references": {
                        "IcMultiValueEventDetail": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcMultiValueEventDetail"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets focus on the input box.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "disabled",
                "methodName": "watchDisabledHandler"
            }, {
                "propName": "loading",
                "methodName": "loadingHandler"
            }, {
                "propName": "options",
                "methodName": "watchOptionsHandler"
            }, {
                "propName": "debounce",
                "methodName": "debounceChangedHandler"
            }, {
                "propName": "value",
                "methodName": "valueChangedHandler"
            }, {
                "propName": "open",
                "methodName": "openChangedHandler"
            }];
    }
}
//# sourceMappingURL=ic-select.js.map
