import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import { setDisabled } from '../../../lib/disabled.js';
import { UiElement } from '../../UiElement.js';
import { nanoid } from 'nanoid';
import '../../text-field/ui-outlined-text-field.js';
import '../../menu/ui-menu.js';
import '../../icons/ui-icon.js';
import '../../focus-ring/ui-focus-ring.js';
let UiSelect = (() => {
    let _classSuper = UiElement;
    let _instanceExtraInitializers = [];
    let _set_value_decorators;
    let _name_decorators;
    let _name_initializers = [];
    let _name_extraInitializers = [];
    let _label_decorators;
    let _label_initializers = [];
    let _label_extraInitializers = [];
    let _required_decorators;
    let _required_initializers = [];
    let _required_extraInitializers = [];
    let _invalid_decorators;
    let _invalid_initializers = [];
    let _invalid_extraInitializers = [];
    let _invalidText_decorators;
    let _invalidText_initializers = [];
    let _invalidText_extraInitializers = [];
    let _supportingText_decorators;
    let _supportingText_initializers = [];
    let _supportingText_extraInitializers = [];
    let _disabled_decorators;
    let _disabled_initializers = [];
    let _disabled_extraInitializers = [];
    let _open_decorators;
    let _open_initializers = [];
    let _open_extraInitializers = [];
    let _selectedOption_decorators;
    let _selectedOption_initializers = [];
    let _selectedOption_extraInitializers = [];
    let _menu_decorators;
    let _menu_initializers = [];
    let _menu_extraInitializers = [];
    return class UiSelect extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _set_value_decorators = [property({ type: String })];
            _name_decorators = [property({ type: String })];
            _label_decorators = [property({ type: String })];
            _required_decorators = [property({ type: Boolean })];
            _invalid_decorators = [property({ type: Boolean })];
            _invalidText_decorators = [property({ type: String })];
            _supportingText_decorators = [property({ type: String })];
            _disabled_decorators = [property({ type: Boolean, reflect: true })];
            _open_decorators = [property({ type: Boolean, reflect: true })];
            _selectedOption_decorators = [state()];
            _menu_decorators = [query('.menu')];
            __esDecorate(this, null, _set_value_decorators, { kind: "setter", name: "value", static: false, private: false, access: { has: obj => "value" in obj, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
            __esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
            __esDecorate(this, null, _required_decorators, { kind: "accessor", name: "required", static: false, private: false, access: { has: obj => "required" in obj, get: obj => obj.required, set: (obj, value) => { obj.required = value; } }, metadata: _metadata }, _required_initializers, _required_extraInitializers);
            __esDecorate(this, null, _invalid_decorators, { kind: "accessor", name: "invalid", static: false, private: false, access: { has: obj => "invalid" in obj, get: obj => obj.invalid, set: (obj, value) => { obj.invalid = value; } }, metadata: _metadata }, _invalid_initializers, _invalid_extraInitializers);
            __esDecorate(this, null, _invalidText_decorators, { kind: "accessor", name: "invalidText", static: false, private: false, access: { has: obj => "invalidText" in obj, get: obj => obj.invalidText, set: (obj, value) => { obj.invalidText = value; } }, metadata: _metadata }, _invalidText_initializers, _invalidText_extraInitializers);
            __esDecorate(this, null, _supportingText_decorators, { kind: "accessor", name: "supportingText", static: false, private: false, access: { has: obj => "supportingText" in obj, get: obj => obj.supportingText, set: (obj, value) => { obj.supportingText = value; } }, metadata: _metadata }, _supportingText_initializers, _supportingText_extraInitializers);
            __esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
            __esDecorate(this, null, _open_decorators, { kind: "accessor", name: "open", static: false, private: false, access: { has: obj => "open" in obj, get: obj => obj.open, set: (obj, value) => { obj.open = value; } }, metadata: _metadata }, _open_initializers, _open_extraInitializers);
            __esDecorate(this, null, _selectedOption_decorators, { kind: "accessor", name: "selectedOption", static: false, private: false, access: { has: obj => "selectedOption" in obj, get: obj => obj.selectedOption, set: (obj, value) => { obj.selectedOption = value; } }, metadata: _metadata }, _selectedOption_initializers, _selectedOption_extraInitializers);
            __esDecorate(this, null, _menu_decorators, { kind: "accessor", name: "menu", static: false, private: false, access: { has: obj => "menu" in obj, get: obj => obj.menu, set: (obj, value) => { obj.menu = value; } }, metadata: _metadata }, _menu_initializers, _menu_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static formAssociated = true;
        #internals = (__runInitializers(this, _instanceExtraInitializers), this.attachInternals());
        /**
         * The value has a private member so that we can set the value without triggering
         * the side effects.
         */
        #value;
        /**
         * Type-ahead search string accumulated from user typing
         */
        #typeAheadString = '';
        /**
         * Timer for resetting the type-ahead search string
         */
        #typeAheadTimer = null;
        /**
         * Timeout duration for type-ahead reset (in milliseconds)
         */
        static TYPE_AHEAD_TIMEOUT = 1000;
        /**
         * The currently selected value. Corresponds to the `value` attribute of the selected `ui-option`.
         * When set programmatically, it will update the selected option if a matching option exists.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select value="apple">
         *   <ui-option value="apple">Apple</ui-option>
         *   <ui-option value="banana">Banana</ui-option>
         * </ui-select>
         * ```
         */
        get value() {
            return this.#value;
        }
        set value(newValue) {
            const oldValue = this.#value;
            if (newValue === oldValue)
                return;
            this.#value = newValue;
            this.requestUpdate();
        }
        #name_accessor_storage = __runInitializers(this, _name_initializers, void 0);
        /**
         * The name attribute for form submission. This value will be used as the key
         * when the form is submitted.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select name="country" value="us">
         *   <ui-option value="us">United States</ui-option>
         * </ui-select>
         * ```
         */
        get name() { return this.#name_accessor_storage; }
        set name(value) { this.#name_accessor_storage = value; }
        #label_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _label_initializers, void 0));
        /**
         * The label text displayed in the select field. Provides accessible labeling
         * and is shown as the floating label in the outlined text field.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select label="Select a country">
         *   <ui-option value="us">United States</ui-option>
         * </ui-select>
         * ```
         */
        get label() { return this.#label_accessor_storage; }
        set label(value) { this.#label_accessor_storage = value; }
        #required_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _required_initializers, false
        /**
         * Whether the select is in an invalid state. This is typically set automatically
         * during validation, but can be set manually to indicate validation errors.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select invalid invalidText="Please select a valid option">
         *   <ui-option value="option1">Option 1</ui-option>
         * </ui-select>
         * ```
         */
        ));
        /**
         * Whether the select is required for form validation. When true, the select
         * must have a value selected for the form to be valid.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select required label="Required field">
         *   <ui-option value="option1">Option 1</ui-option>
         * </ui-select>
         * ```
         */
        get required() { return this.#required_accessor_storage; }
        set required(value) { this.#required_accessor_storage = value; }
        #invalid_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _invalid_initializers, void 0));
        /**
         * Whether the select is in an invalid state. This is typically set automatically
         * during validation, but can be set manually to indicate validation errors.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select invalid invalidText="Please select a valid option">
         *   <ui-option value="option1">Option 1</ui-option>
         * </ui-select>
         * ```
         */
        get invalid() { return this.#invalid_accessor_storage; }
        set invalid(value) { this.#invalid_accessor_storage = value; }
        #invalidText_accessor_storage = (__runInitializers(this, _invalid_extraInitializers), __runInitializers(this, _invalidText_initializers, void 0));
        /**
         * The error message to display when the select is invalid. This text is shown
         * below the select field when `invalid` is true.
         *
         * @attribute
         * @example
         * ```html
         * <ui-select invalid invalidText="This field is required">
         *   <ui-option value="option1">Option 1</ui-option>
         * </ui-select>
         * ```
         */
        get invalidText() { return this.#invalidText_accessor_storage; }
        set invalidText(value) { this.#invalidText_accessor_storage = value; }
        #supportingText_accessor_storage = (__runInitializers(this, _invalidText_extraInitializers), __runInitializers(this, _supportingText_initializers, void 0));
        /**
         * @attribute
         */
        get supportingText() { return this.#supportingText_accessor_storage; }
        set supportingText(value) { this.#supportingText_accessor_storage = value; }
        #disabled_accessor_storage = (__runInitializers(this, _supportingText_extraInitializers), __runInitializers(this, _disabled_initializers, false
        /**
         * Whether the dropdown menu is currently open. This property reflects the
         * current state of the dropdown and can be set programmatically to open/close it.
         *
         * @default false
         * @example
         * ```javascript
         * // Open the dropdown programmatically
         * selectElement.open = true;
         *
         * // Close the dropdown
         * selectElement.open = false;
         * ```
         */
        ));
        /**
         * Whether the select is disabled. When disabled, the select cannot be interacted
         * with and will not receive focus or respond to user input.
         *
         * @default false
         * @attribute
         * @example
         * ```html
         * <ui-select disabled label="Disabled select">
         *   <ui-option value="option1">Option 1</ui-option>
         * </ui-select>
         * ```
         */
        get disabled() { return this.#disabled_accessor_storage; }
        set disabled(value) { this.#disabled_accessor_storage = value; }
        #open_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _open_initializers, false));
        /**
         * Whether the dropdown menu is currently open. This property reflects the
         * current state of the dropdown and can be set programmatically to open/close it.
         *
         * @default false
         * @example
         * ```javascript
         * // Open the dropdown programmatically
         * selectElement.open = true;
         *
         * // Close the dropdown
         * selectElement.open = false;
         * ```
         */
        get open() { return this.#open_accessor_storage; }
        set open(value) { this.#open_accessor_storage = value; }
        #selectedOption_accessor_storage = (__runInitializers(this, _open_extraInitializers), __runInitializers(this, _selectedOption_initializers, null));
        get selectedOption() { return this.#selectedOption_accessor_storage; }
        set selectedOption(value) { this.#selectedOption_accessor_storage = value; }
        #menu_accessor_storage = (__runInitializers(this, _selectedOption_extraInitializers), __runInitializers(this, _menu_initializers, void 0));
        get menu() { return this.#menu_accessor_storage; }
        set menu(value) { this.#menu_accessor_storage = value; }
        /**
         * Returns the currently selected option element. This provides access to the
         * full `ui-option` element, not just its value.
         *
         * @readonly
         * @example
         * ```javascript
         * const select = document.querySelector('ui-select');
         * const selectedItem = select.selectedItem;
         * if (selectedItem) {
         *   console.log('Selected option:', selectedItem.textContent);
         * }
         * ```
         */
        get selectedItem() {
            return this.selectedOption;
        }
        /**
         * Returns the text content that should be displayed in the select field.
         * This is the rendered value of the currently selected option.
         *
         * @readonly
         * @example
         * ```javascript
         * const select = document.querySelector('ui-select');
         * console.log('Display text:', select.renderValue);
         * ```
         */
        get renderValue() {
            const item = this.selectedOption;
            return item ? item.renderValue : '';
        }
        /**
         * Returns the form element that contains this select, if any.
         * Part of the form-associated custom element API.
         *
         * @readonly
         */
        get form() {
            return this.#internals.form;
        }
        /**
         * Returns the validity state of the select element.
         * Part of the form-associated custom element API.
         *
         * @readonly
         */
        get validity() {
            return this.#internals.validity;
        }
        /**
         * Returns the validation message for the select element.
         * Part of the form-associated custom element API.
         *
         * @readonly
         */
        get validationMessage() {
            return this.#internals.validationMessage;
        }
        /**
         * Returns whether the select element will be validated when the form is submitted.
         * Part of the form-associated custom element API.
         *
         * @readonly
         */
        get willValidate() {
            return this.#internals.willValidate;
        }
        /**
         * Checks the validity of the select element and returns true if valid.
         * Part of the form-associated custom element API.
         *
         * @returns {boolean} True if the element is valid, false otherwise
         * @example
         * ```javascript
         * const select = document.querySelector('ui-select');
         * if (!select.checkValidity()) {
         *   console.log('Select is invalid:', select.validationMessage);
         * }
         * ```
         */
        checkValidity() {
            return this.#internals.checkValidity();
        }
        constructor() {
            super();
            __runInitializers(this, _menu_extraInitializers);
            this.addEventListener('click', this.handleClick.bind(this));
            this.addEventListener('blur', this.handleBlur.bind(this));
            this.addEventListener('keydown', this.handleKeydown.bind(this));
        }
        connectedCallback() {
            super.connectedCallback();
            this.setAttribute('role', 'combobox');
            this.setAttribute('aria-haspopup', 'listbox');
            this.setAttribute('aria-controls', 'menu');
            if (!this.disabled) {
                this.setAttribute('tabindex', '0');
            }
            if (!this.id) {
                this.id = `select-${nanoid(6)}`;
            }
        }
        disconnectedCallback() {
            super.disconnectedCallback();
            // Clean up the type-ahead timer
            if (this.#typeAheadTimer) {
                clearTimeout(this.#typeAheadTimer);
                this.#typeAheadTimer = null;
            }
        }
        /**
         * Resets the select to its initial state. Called automatically when the parent
         * form is reset. Part of the form-associated custom element API.
         *
         * @example
         * ```javascript
         * const select = document.querySelector('ui-select');
         * select.formResetCallback(); // Clears the selection
         * ```
         */
        formResetCallback() {
            this.value = undefined;
        }
        /**
         * Restores the select's state from saved form data. Called automatically when
         * the browser restores form state. Part of the form-associated custom element API.
         *
         * @param {string | null} state - The saved state to restore
         */
        formStateRestoreCallback(state) {
            this.value = state ?? undefined;
        }
        /**
         * Validates the select element and updates its validity state. This is called
         * automatically during property changes, but can be called manually to trigger validation.
         *
         * @example
         * ```javascript
         * const select = document.querySelector('ui-select');
         * select.validate();
         * if (select.invalid) {
         *   console.log('Validation failed:', select.invalidText);
         * }
         * ```
         */
        validate() {
            let message = '';
            if (this.required && !this.value) {
                message = 'Please select an item.';
                this.#internals.setValidity({ valueMissing: true }, message);
            }
            else {
                this.#internals.setValidity({});
            }
            this.invalid = !this.#internals.validity.valid;
            this.invalidText = message;
        }
        willUpdate(changedProperties) {
            super.willUpdate(changedProperties);
            if (changedProperties.has('disabled')) {
                setDisabled(this, this.disabled);
            }
            if (changedProperties.has('open')) {
                this.handleOpenChange();
            }
            if (changedProperties.has('value')) {
                this.setCurrentOption();
                this.#internals.setFormValue(this.value ?? null);
                this.validate();
            }
            if (changedProperties.has('label')) {
                if (this.label) {
                    this.setAttribute('aria-label', this.label);
                }
                else {
                    this.removeAttribute('aria-label');
                }
            }
        }
        firstUpdated(cp) {
            super.firstUpdated(cp);
            this.updateComplete.then(() => {
                this.setCurrentOption();
                this.#internals.setFormValue(this.value ?? null);
                // We need to update here as event with `value` and `selectedOption`
                // already set, the `renderValue` might have incorrect value
                // due to the DOM update.
                this.requestUpdate();
            });
        }
        setCurrentOption() {
            const options = this.querySelectorAll('ui-option');
            if (this.value) {
                this.selectedOption = Array.from(options).find((option) => option.value === this.value) || null;
            }
            else {
                const selected = Array.from(options).find((option) => option.selected);
                if (selected) {
                    this.selectedOption = selected;
                    this.#value = selected.value;
                }
                else {
                    this.selectedOption = null;
                }
            }
        }
        handleKeydown(e) {
            if (this.disabled || e.defaultPrevented)
                return;
            // Handle type-ahead for printable characters
            if (e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
                this.handleTypeAhead(e.key.toLowerCase());
                return;
            }
            if (this.open) {
                switch (e.key) {
                    case 'Tab': {
                        // If menu is open and Tab is pressed, close it and allow normal tab navigation
                        if (this.open) {
                            this.open = false;
                        }
                        break;
                    }
                    case 'Escape': {
                        if (this.open) {
                            e.preventDefault();
                            this.open = false;
                            this.focus(); // Return focus to the select element
                        }
                        break;
                    }
                    case 'ArrowDown':
                        e.preventDefault();
                        this.focusNextMenuItem();
                        return;
                    case 'ArrowUp':
                        e.preventDefault();
                        this.focusPreviousMenuItem();
                        return;
                    case 'Home':
                        e.preventDefault();
                        this.focusFirstMenuItem();
                        return;
                    case 'End':
                        e.preventDefault();
                        this.focusLastMenuItem();
                        return;
                    case 'Enter':
                    case ' ': {
                        const currentItem = this.querySelector(':focus');
                        if (currentItem && this.isOptionSelectable(currentItem)) {
                            e.preventDefault();
                            this.menu.notifySelect(currentItem);
                        }
                        return;
                    }
                }
            }
            else {
                switch (e.key) {
                    case 'Enter':
                    case ' ': {
                        if (!this.open) {
                            e.preventDefault();
                            this.open = true;
                        }
                        break;
                    }
                    case 'ArrowDown':
                    case 'ArrowUp': {
                        if (!this.open) {
                            e.preventDefault();
                            this.open = true;
                        }
                        // If menu is open, let the menu handle arrow keys
                        break;
                    }
                }
            }
        }
        handleBlur(e) {
            if (this.disabled)
                return;
            // Check if focus is moving to the menu or one of its children
            const relatedTarget = e.relatedTarget;
            if (relatedTarget && this.contains(relatedTarget)) {
                // Focus is moving to the menu, keep it open
                return;
            }
            // Close the menu when focus leaves the component
            this.open = false;
        }
        handleClick(e) {
            if (this.disabled || e.defaultPrevented)
                return;
            e.preventDefault();
            e.stopPropagation();
            if (this.open && e.target === this) {
                // If the select is already open and clicked again, close it
                this.open = false;
                return;
            }
            this.open = true;
        }
        async handleOpenChange() {
            const menu = this.menu;
            if (!menu) {
                // The status can be set before the menu is rendered
                return;
            }
            this.setAttribute('aria-expanded', String(this.open));
            if (this.open) {
                menu.showPopover();
                // Focus on the selected option or first selectable option when menu opens
                if (this.selectedOption && this.isOptionSelectable(this.selectedOption)) {
                    this.selectedOption.focus();
                    this.selectedOption.scrollIntoView({ behavior: 'instant', block: 'nearest', inline: 'nearest' });
                }
                else {
                    const firstSelectableOption = this.getFirstSelectableOption();
                    if (firstSelectableOption) {
                        firstSelectableOption.focus();
                        firstSelectableOption.scrollIntoView({ behavior: 'instant', block: 'nearest', inline: 'nearest' });
                    }
                }
                this.dispatchEvent(new CustomEvent('open'));
            }
            else {
                menu.hidePopover();
                this.dispatchEvent(new CustomEvent('close'));
                // Return focus to the select element when menu closes
                this.focus();
            }
        }
        /**
         * Focus the next menu item in the dropdown, skipping disabled options
         */
        focusNextMenuItem() {
            const currentItem = this.querySelector(':focus');
            const nextItem = currentItem ? this.getNextSelectableOption(currentItem) : this.getFirstSelectableOption();
            if (nextItem) {
                nextItem.focus();
            }
        }
        /**
         * Focus the previous menu item in the dropdown, skipping disabled options
         */
        focusPreviousMenuItem() {
            const currentItem = this.querySelector(':focus');
            const previousItem = currentItem ? this.getPreviousSelectableOption(currentItem) : this.getLastSelectableOption();
            if (previousItem) {
                previousItem.focus();
            }
        }
        /**
         * Focus the first menu item in the dropdown, skipping disabled options
         */
        focusFirstMenuItem() {
            const firstItem = this.getFirstSelectableOption();
            if (firstItem) {
                firstItem.focus();
            }
        }
        /**
         * Focus the last menu item in the dropdown, skipping disabled options
         */
        focusLastMenuItem() {
            const lastItem = this.getLastSelectableOption();
            if (lastItem) {
                lastItem.focus();
            }
        }
        /**
         * Gets the first selectable (non-disabled) option
         */
        getFirstSelectableOption() {
            const options = this.querySelectorAll('ui-option');
            for (const option of options) {
                if (this.isOptionSelectable(option)) {
                    return option;
                }
            }
            return null;
        }
        /**
         * Gets the last selectable (non-disabled) option
         */
        getLastSelectableOption() {
            const options = Array.from(this.querySelectorAll('ui-option')).reverse();
            for (const option of options) {
                if (this.isOptionSelectable(option)) {
                    return option;
                }
            }
            return null;
        }
        /**
         * Gets the next selectable option after the current one, wrapping around if needed
         */
        getNextSelectableOption(currentOption) {
            const options = Array.from(this.querySelectorAll('ui-option'));
            const currentIndex = options.indexOf(currentOption);
            if (currentIndex === -1) {
                return this.getFirstSelectableOption();
            }
            // Start from the next option and wrap around
            for (let i = 1; i < options.length; i++) {
                const nextIndex = (currentIndex + i) % options.length;
                const option = options[nextIndex];
                if (this.isOptionSelectable(option)) {
                    return option;
                }
            }
            return currentOption; // Return current if no other selectable option found
        }
        /**
         * Gets the previous selectable option before the current one, wrapping around if needed
         */
        getPreviousSelectableOption(currentOption) {
            const options = Array.from(this.querySelectorAll('ui-option'));
            const currentIndex = options.indexOf(currentOption);
            if (currentIndex === -1) {
                return this.getLastSelectableOption();
            }
            // Start from the previous option and wrap around
            for (let i = 1; i < options.length; i++) {
                const prevIndex = (currentIndex - i + options.length) % options.length;
                const option = options[prevIndex];
                if (this.isOptionSelectable(option)) {
                    return option;
                }
            }
            return currentOption; // Return current if no other selectable option found
        }
        /**
         * Checks if an option is selectable (not disabled and not hidden)
         */
        isOptionSelectable(option) {
            if (option.disabled) {
                return false;
            }
            if (option.hasAttribute('disabled')) {
                return false;
            }
            if (option.hidden && option.hasAttribute('hidden')) {
                return false;
            }
            return true;
        }
        /**
         * Handles type-ahead functionality for keyboard navigation
         */
        handleTypeAhead(char) {
            // Clear the existing timer
            if (this.#typeAheadTimer) {
                clearTimeout(this.#typeAheadTimer);
            }
            // Add the character to the search string
            this.#typeAheadString += char;
            // Find the matching option
            const matchingOption = this.findOptionByTypeAhead(this.#typeAheadString);
            if (matchingOption) {
                if (this.open) {
                    // If menu is open, focus the matching option
                    matchingOption.focus();
                }
                else {
                    // If menu is closed, select the matching option
                    this.selectOption(matchingOption);
                }
            }
            // Set a timer to reset the search string
            this.#typeAheadTimer = window.setTimeout(() => {
                this.#typeAheadString = '';
                this.#typeAheadTimer = null;
            }, UiSelect.TYPE_AHEAD_TIMEOUT);
        }
        /**
         * Finds an option that matches the type-ahead search string
         */
        findOptionByTypeAhead(searchString) {
            const options = this.querySelectorAll('ui-option');
            for (const option of options) {
                if (!this.isOptionSelectable(option)) {
                    continue;
                }
                // Get the option's text content for comparison
                const optionText = this.getOptionDisplayText(option).toLowerCase();
                if (optionText.startsWith(searchString)) {
                    return option;
                }
            }
            return null;
        }
        /**
         * Gets the display text for an option (either textContent or renderValue)
         */
        getOptionDisplayText(option) {
            // Use renderValue if available, otherwise fall back to textContent
            return option.renderValue || option.textContent?.trim() || '';
        }
        /**
         * Selects an option and updates the component state
         */
        selectOption(option) {
            if (this.selectedOption && this.selectedOption !== option) {
                this.selectedOption.selected = false;
            }
            option.selected = true;
            this.selectedOption = option;
            this.#value = option.value;
            this.#internals.setFormValue(this.value ?? null);
            this.dispatchChangeEvent(option);
        }
        handleSelect(e) {
            e.stopPropagation();
            const item = e.detail.item;
            if (this.selectedOption && this.selectedOption !== item) {
                this.selectedOption.selected = false;
            }
            item.selected = true;
            this.selectedOption = item;
            this.#value = item.value;
            this.#internals.setFormValue(this.value ?? null);
            this.open = false;
            // Dispatch change event
            this.dispatchChangeEvent(item);
            // Focus will be returned to select element by handleOpenChange when open=false
        }
        handleMenuClose() {
            this.open = false;
            // Focus will be returned to select element by handleOpenChange when open=false
        }
        handleMenuToggle(e) {
            if (e.newState === 'closed') {
                this.open = false;
            }
        }
        dispatchChangeEvent(item) {
            const changeEvent = new CustomEvent('change', {
                detail: { value: this.value, item },
                bubbles: false,
                composed: false,
            });
            this.dispatchEvent(changeEvent);
        }
        renderInput() {
            const styles = {
                'anchor-name': `--${this.id}`,
            };
            return html `<ui-outlined-text-field
      .name=${this.name}
      .label=${this.label}
      .value=${this.renderValue}
      .disabled=${this.disabled}
      .required=${this.required}
      readonly
      tabindex="-1"
      .inert=${true}
      aria-hidden="true"
      .invalid=${this.invalid}
      .invalidText=${this.invalidText || ''}
      .supportingText=${this.supportingText || ''}
      class="input"
      style=${styleMap(styles)}
      part="input"
    >
      <ui-icon part="icon" slot="suffix">arrow_drop_down</ui-icon>
    </ui-outlined-text-field>`;
        }
        renderMenu() {
            const styles = {
                'position-anchor': `--${this.id}`,
            };
            return html `<ui-menu
      id="menu"
      class="menu"
      part="menu"
      style=${styleMap(styles)}
      popover="auto"
      selector="ui-option"
      @select="${this.handleSelect}"
      @close="${this.handleMenuClose}"
      @toggle="${this.handleMenuToggle}"
    >
      <slot @slotchange="${this.handleSlotChange}"></slot>
    </ui-menu>`;
        }
        async handleSlotChange() {
            // When options change, re-evaluate the current selection
            // only if we don't have an explicit value set
            if (!this.value) {
                this.setCurrentOption();
                this.requestUpdate();
            }
        }
        renderFocusRing() {
            return html `<ui-focus-ring part="focus-ring" class="focus-ring" .control="${this}"></ui-focus-ring>`;
        }
        render() {
            const classes = classMap({
                'ui-select': true,
                'open': this.open,
                'disabled': this.disabled,
            });
            return html `${this.renderFocusRing()}
      <div class="${classes}">${this.renderInput()} ${this.renderMenu()}</div> `;
        }
    };
})();
/**
 * Material Design 3 Select component that behaves like an outlined text field with dropdown.
 *
 * @fires change - Dispatched when the selection changes. The event is non-bubbling and non-cancelable.
 *                 The `event.detail` object contains the `value` and `item` properties.
 * @fires open - Dispatched when the dropdown opens
 * @fires close - Dispatched when the dropdown closes
 */
export default UiSelect;
//# sourceMappingURL=Select.js.map