import { LitElement, PropertyValues, TemplateResult } from 'lit';
import type UiListbox from '../../../md/listbox/internals/Listbox.js';
/**
 * An accessible and performant autocomplete component that enhances a text input with a list of suggestions.
 *
 * The `autocomplete-input` component provides a flexible way to add autocomplete functionality
 * to any text input. It works by coordinating a slotted input element with a slotted `ui-listbox`
 * containing suggestions.
 *
 * Key Features:
 *
 * - **Popover Management**: Automatically shows and hides the suggestions popover based on input focus
 *   and user interaction.
 * - **Keyboard Navigation**: Allows users to navigate suggestions using ArrowUp, ArrowDown keys directly
 *   from the input. Enter selects a suggestion, and Escape closes the popover.
 *   The suggestion list itself never gains focus.
 * - **Dynamic Filtering**: Filters the list of suggestions as the user types into the input. Items not matching
 *   the query are hidden (not removed).
 *   - By default, filtering checks `item.dataset.value` and then `item.textContent`.
 *   - If a `ui-list-item` has a `data-index` attribute (e.g., `data-index="name email"`), filtering will search
 *     within the specified `data-*` attributes (e.g., `data-name`, `data-email`).
 * - **Mutation Awareness**: Reacts to changes in slotted suggestions, re-filtering them if necessary.
 * - **Event-Driven**: Notifies the application via an `autocomplete` event when a suggestion is selected.
 *   The component itself does not modify the input's value, giving the application author full control.
 *
 * ### Accessibility
 *
 * The `autocomplete-input` component is designed with accessibility at its core:
 * - **Keyboard Navigation**: Full keyboard support for navigating suggestions (ArrowUp, ArrowDown),
 *   selecting (Enter), and closing (Escape), all while focus remains on the input field.
 * - **ARIA Attributes**: While the `autocomplete-input` manages ARIA attributes related to the popover's
 *   state, the slotted `ui-listbox` is responsible for its internal ARIA roles and states
 *   (e.g., `role="listbox"`, `aria-activedescendant`).
 * - **Labeling Suggestions**: It is **crucial** for accessibility that the slotted `ui-listbox`
 *   has an `aria-label` attribute. This provides a descriptive name for the list of suggestions,
 *   which is announced by screen readers.
 *
 * The component uses CSS anchor positioning to place the suggestions popover relative to the input.
 * Ensure your `ui-listbox` is styled appropriately for popover display (e.g., `popover="manual"`, `position-anchor`).
 * The component will manage `showPopover()` and `hidePopover()` calls.
 *
 * @slot input - The input element that will be used for autocomplete. This element should be an `HTMLInputElement`
 *               or behave like one (have a `value` property and dispatch `input`, `focus`, `blur`, and `keydown`
 *               events).
 * @slot suggestions - The `ui-listbox` element containing `ui-list-item` elements as suggestions.
 * @slot anchor - An optional element that points to element that will be used as the anchor for the popover.
 *                This is useful if you want to position the suggestions relative to a different element than the input.
 *                If not provided, the input element will be used as the anchor.
 * @slot Any additional content that should be rendered inside the component.
 *
 * @fires autocomplete - Dispatched when a suggestion is selected by the user (e.g., via click or Enter key).
 * The `event.detail` object contains:
 *   - `item`: The selected `UiListItem` instance.
 *
 * @example
 * ```html
 * <autocomplete-input @autocomplete="${this.handleAutocompleteSelection}">
 *   <input slot="input" type="text" placeholder="Search fruits..." />
 *   <ui-listbox slot="suggestions">
 *     <ui-list-item data-value="apple">Apple</ui-list-item>
 *     <ui-list-item data-value="banana">Banana</ui-list-item>
 *     <ui-list-item data-value="cherry">Cherry</ui-list-item>
 *   </ui-listbox>
 *   <!-- With aria-label for accessibility -->
 *   <ui-listbox slot="suggestions" aria-label="Fruit suggestions">
 *     <ui-list-item data-value="apple">Apple</ui-list-item>
 *     <ui-list-item data-value="banana">Banana</ui-list-item>
 *     <ui-list-item data-value="cherry">Cherry</ui-list-item>
 *   </ui-listbox>
 * </autocomplete-input>
 *
 * <script>
 *   // In your component/script
 *   handleAutocompleteSelection(event) {
 *     const selectedItem = event.detail.item;
 *     const inputElement = this.shadowRoot.querySelector('input[slot="input"]');
 *     if (inputElement) {
 *       inputElement.value = selectedItem.dataset.value || selectedItem.textContent;
 *     }
 *     console.log('Selected:', selectedItem.dataset.value);
 *   }
 * </script>
 * ```
 *
 * @example Dynamic filtering with `data-index`
 * ```html
 * <autocomplete-input @autocomplete="${this.handleUserSelection}">
 *   <input slot="input" type="text" placeholder="Search users..." />
 *   <ui-listbox slot="suggestions" aria-label="User suggestions">
 *     <ui-list-item data-id="1" data-name="Alice Wonderland" data-email="alice@example.com" data-index="name email">
 *       Alice Wonderland
 *       <span slot="supporting-text">alice@example.com</span>
 *     </ui-list-item>
 *     <ui-list-item data-id="2" data-name="Bob The Builder" data-email="bob@example.com" data-index="name email">
 *       Bob The Builder
 *       <span slot="supporting-text">bob@example.com</span>
 *     </ui-list-item>
 *   </ui-listbox>
 * </autocomplete-input>
 *
 * <script>
 *   // In your component/script
 *   handleUserSelection(event) {
 *     const selectedItem = event.detail.item;
 *     const inputElement = this.shadowRoot.querySelector('input[slot="input"]');
 *     if (inputElement) {
 *       // You might want to display the name, but store the ID
 *       inputElement.value = selectedItem.dataset.name;
 *     }
 *     console.log('Selected user ID:', selectedItem.dataset.id);
 *   }
 * </script>
 * ```
 */
export default class Autocomplete extends LitElement {
    protected createRenderRoot(): HTMLElement | DocumentFragment;
    /**
     * The MutationObserver instance used to watch for changes in slotted children.
     */
    protected observer?: MutationObserver;
    /**
     * The ID of the input element, generated if not provided.
     * This is used for CSS anchoring and to ensure unique IDs for accessibility.
     */
    protected accessor inputId: string;
    /**
     * The position area for the suggestions popover.
     * This can be 'bottom' or 'top', depending on available space.
     * Default is 'bottom'.
     *
     * Note, this is set dynamically based on available space
     * and the position of the input element. This only sets the initial value.
     *
     * @attribute
     * @type {'bottom' | 'top'}
     * @default 'bottom'
     */
    accessor positionArea: 'bottom' | 'top';
    /**
     * The reference to the slotted input element.
     * This should be an `HTMLInputElement` or behave like one.
     */
    protected inputRef?: HTMLInputElement | HTMLElement | null;
    /**
     * The reference to the slotted suggestions element, which should be a `ui-listbox`.
     * This is used to manage the suggestions popover and filtering.
     */
    protected suggestionsRef?: UiListbox | null;
    /**
     * Checks if the suggestions popover is currently open.
     */
    get opened(): boolean;
    connectedCallback(): void;
    disconnectedCallback(): void;
    protected firstUpdated(cp: PropertyValues): void;
    /**
     * Performs initial setup after the first update, ensuring that slotted input
     * and suggestions elements are configured.
     */
    firstSetup(): Promise<void>;
    /**
     * Handles mutations observed on the component's slotted children.
     * This is used to set up or tear down input and suggestions elements when they are added or removed.
     * @param mutations An array of MutationRecord objects.
     */
    protected handleMutations(mutations: MutationRecord[]): void;
    /**
     * Clears event listeners from the current input reference and resets it.
     */
    protected clearInputListeners(): void;
    /**
     * Clears event listeners from the current suggestions reference and resets it.
     */
    protected clearSuggestionsListeners(): void;
    /**
     * Sets up the slotted input element.
     * Assigns an ID if necessary, sets up CSS anchoring, and attaches event listeners.
     * @param input The HTMLElement to be used as the input.
     */
    protected setupInput(input: HTMLElement): void;
    /**
     * Sets up the slotted suggestions element (assumed to be a `UiListbox`).
     * Configures popover behavior, CSS anchoring, and attaches event listeners.
     * @param suggestionsElement The `UiListbox` element to be used for suggestions.
     */
    protected setupSuggestions(suggestionsElement: UiListbox): void;
    /**
     * Handles the focus event on the input element.
     * Opens the suggestions popover if there are items to display.
     */
    protected handleInputFocus(): void;
    /**
     * Handles the input event on the input element.
     * Filters suggestions based on the input query and opens/closes the popover accordingly.
     * @param event The input event.
     */
    protected handleInput(event: Event): void;
    /**
     * Handles keydown events on the input element for navigating and selecting suggestions.
     * - ArrowDown/ArrowUp: Navigates the suggestion list.
     * - Enter: Selects the highlighted suggestion.
     * - Escape: Closes the suggestions popover.
     * @param event The keyboard event.
     */
    protected handleKeydown(event: KeyboardEvent): void;
    /**
     * Navigates the suggestion list based on the pressed key.
     * @param key The key that was pressed (ArrowDown or ArrowUp).
     */
    protected navigateList(key: string): void;
    /**
     * Handles the blur event on the input element.
     * Closes the suggestions popover if focus moves outside the autocomplete component.
     */
    protected handleInputBlur(): void;
    /**
     * Handles the `select` event dispatched by the `ui-listbox` when a suggestion is chosen.
     * Dispatches an `autocomplete` event and closes the popover.
     * @param event The custom event from `ui-listbox`.
     */
    protected handleSuggestionSelect(event: CustomEvent): void;
    /**
     * Handles the `itemschange` event dispatched by the `ui-listbox` when its slotted items change.
     * Re-filters the suggestions.
     */
    protected handleSuggestionsSlotChange(): void;
    /**
     * Opens the suggestions popover if it's not already open and there are visible items.
     */
    protected openSuggestions(): void;
    /**
     * Decides the position area for the popover based on available space.
     * It checks if there is enough space below or above the anchor element and decides accordingly.
     *
     * We need to do this because we set the popover height to `100%`, `-webkit-fill-available`, or `-moz-available`
     * and it makes the popover to always open at the bottom, even if there is no space. The `position-try-fallbacks`
     * will not work in this case, because from its perspective there is always enough space, even if that will cause
     * the popover to have a height of just a few pixels.
     *
     * @param popover The popover element to position.
     * @param anchor The anchor element relative to which the popover will be positioned.
     * @returns 'top' or 'bottom' based on available space.
     */
    protected decidePositionArea(popover: HTMLElement, anchor: HTMLElement): 'top' | 'bottom';
    /**
     * Closes the suggestions popover if it's open and clears any highlighted item.
     */
    protected closeSuggestions(): void;
    /**
     * Filters the suggestions based on the provided query.
     * Hides items that do not match and manages the highlighted item state.
     * @param query The search query string.
     */
    protected filterSuggestions(query: string): void;
    protected render(): TemplateResult;
}
//# sourceMappingURL=autocomplete.d.ts.map