UNPKG

primeng

Version:

PrimeNG is an open source UI library for Angular featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeB

2,430 lines 105 kB
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { Injectable, forwardRef, EventEmitter, inject, signal, computed, effect, booleanAttribute, numberAttribute, ContentChildren, ContentChild, ViewChild, Output, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { resolveFieldData, isNotEmpty, uuid, findLastIndex, equals, focus, isEmpty, findSingle } from '@primeuix/utils';
import * as i1 from 'primeng/api';
import { TranslationKeys, SharedModule, PrimeTemplate } from 'primeng/api';
import { AutoFocus } from 'primeng/autofocus';
import { BaseComponent } from 'primeng/basecomponent';
import { Chip } from 'primeng/chip';
import { PrimeNG } from 'primeng/config';
import { TimesCircleIcon, SpinnerIcon, TimesIcon, ChevronDownIcon } from 'primeng/icons';
import { InputText } from 'primeng/inputtext';
import { Overlay } from 'primeng/overlay';
import { Ripple } from 'primeng/ripple';
import { Scroller } from 'primeng/scroller';
import { BaseStyle } from 'primeng/base';

const theme = ({ dt }) => `
.p-autocomplete {
    display: inline-flex;
}

.p-autocomplete-loader {
    position: absolute;
    top: 50%;
    margin-top: -0.5rem;
    inset-inline-end: ${dt('autocomplete.padding.x')};
}

.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-loader {
    inset-inline-end: calc(${dt('autocomplete.dropdown.width')} + ${dt('autocomplete.padding.x')});
}

.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input {
    flex: 1 1 auto;
    width: 1%;
}

.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input,
.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input-multiple {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.p-autocomplete-dropdown {
    cursor: pointer;
    display: inline-flex;
    user-select: none;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    width: ${dt('autocomplete.dropdown.width')};
    border-start-end-radius: ${dt('autocomplete.dropdown.border.radius')};
    border-end-end-radius: ${dt('autocomplete.dropdown.border.radius')};
    background: ${dt('autocomplete.dropdown.background')};
    border: 1px solid ${dt('autocomplete.dropdown.border.color')};
    border-inline-start: 0 none;
    color: ${dt('autocomplete.dropdown.color')};
    transition: background ${dt('autocomplete.transition.duration')}, color ${dt('autocomplete.transition.duration')}, border-color ${dt('autocomplete.transition.duration')}, outline-color ${dt('autocomplete.transition.duration')}, box-shadow ${dt('autocomplete.transition.duration')};
    outline-color: transparent;
}

.p-autocomplete-dropdown:not(:disabled):hover {
    background: ${dt('autocomplete.dropdown.hover.background')};
    border-color: ${dt('autocomplete.dropdown.hover.border.color')};
    color: ${dt('autocomplete.dropdown.hover.color')};
}

.p-autocomplete-dropdown:not(:disabled):active {
    background: ${dt('autocomplete.dropdown.active.background')};
    border-color: ${dt('autocomplete.dropdown.active.border.color')};
    color: ${dt('autocomplete.dropdown.active.color')};
}

.p-autocomplete-dropdown:focus-visible {
    box-shadow: ${dt('autocomplete.dropdown.focus.ring.shadow')};
    outline: ${dt('autocomplete.dropdown.focus.ring.width')} ${dt('autocomplete.dropdown.focus.ring.style')} ${dt('autocomplete.dropdown.focus.ring.color')};
    outline-offset: ${dt('autocomplete.dropdown.focus.ring.offset')};
}

.p-autocomplete .p-autocomplete-overlay {
    min-width: 100%;
}

.p-autocomplete-overlay {
    background: ${dt('autocomplete.overlay.background')};
    color: ${dt('autocomplete.overlay.color')};
    border: 1px solid ${dt('autocomplete.overlay.border.color')};
    border-radius: ${dt('autocomplete.overlay.border.radius')};
    box-shadow: ${dt('autocomplete.overlay.shadow')};
}

.p-autocomplete-list-container {
    overflow: auto;
}

.p-autocomplete-list {
    margin: 0;
    list-style-type: none;
    display: flex;
    flex-direction: column;
    gap: ${dt('autocomplete.list.gap')};
    padding: ${dt('autocomplete.list.padding')};
}

.p-autocomplete-option {
    cursor: pointer;
    white-space: nowrap;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    padding: ${dt('autocomplete.option.padding')};
    border: 0 none;
    color: ${dt('autocomplete.option.color')};
    background: transparent;
    transition: background ${dt('autocomplete.transition.duration')}, color ${dt('autocomplete.transition.duration')}, border-color ${dt('autocomplete.transition.duration')};
    border-radius: ${dt('autocomplete.option.border.radius')};
}

.p-autocomplete-option:not(.p-autocomplete-option-selected):not(.p-disabled).p-focus {
    background: ${dt('autocomplete.option.focus.background')};
    color: ${dt('autocomplete.option.focus.color')};
}

.p-autocomplete-option-selected {
    background: ${dt('autocomplete.option.selected.background')};
    color: ${dt('autocomplete.option.selected.color')};
}

.p-autocomplete-option-selected.p-focus {
    background: ${dt('autocomplete.option.selected.focus.background')};
    color: ${dt('autocomplete.option.selected.focus.color')};
}

.p-autocomplete-option-group {
    margin: 0;
    padding: ${dt('autocomplete.option.group.padding')};
    color: ${dt('autocomplete.option.group.color')};
    background: ${dt('autocomplete.option.group.background')};
    font-weight: ${dt('autocomplete.option.group.font.weight')};
}

.p-autocomplete-input-multiple {
    margin: 0;
    list-style-type: none;
    cursor: text;
    overflow: hidden;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    padding: calc(${dt('autocomplete.padding.y')} / 2) ${dt('autocomplete.padding.x')};
    gap: calc(${dt('autocomplete.padding.y')} / 2);
    color: ${dt('autocomplete.color')};
    background: ${dt('autocomplete.background')};
    border: 1px solid ${dt('autocomplete.border.color')};
    border-radius: ${dt('autocomplete.border.radius')};
    width: 100%;
    transition: background ${dt('autocomplete.transition.duration')}, color ${dt('autocomplete.transition.duration')}, border-color ${dt('autocomplete.transition.duration')}, outline-color ${dt('autocomplete.transition.duration')}, box-shadow ${dt('autocomplete.transition.duration')};
    outline-color: transparent;
    box-shadow: ${dt('autocomplete.shadow')};
}

.p-autocomplete:not(.p-disabled):hover .p-autocomplete-input-multiple {
    border-color: ${dt('autocomplete.hover.border.color')};
}

.p-autocomplete:not(.p-disabled).p-focus .p-autocomplete-input-multiple {
    border-color: ${dt('autocomplete.focus.border.color')};
    box-shadow: ${dt('autocomplete.focus.ring.shadow')};
    outline: ${dt('autocomplete.focus.ring.width')} ${dt('autocomplete.focus.ring.style')} ${dt('autocomplete.focus.ring.color')};
    outline-offset: ${dt('autocomplete.focus.ring.offset')};
}

.p-autocomplete.p-invalid .p-autocomplete-input-multiple {
    border-color: ${dt('autocomplete.invalid.border.color')};
}

.p-variant-filled.p-autocomplete-input-multiple {
    background: ${dt('autocomplete.filled.background')};
}

.p-autocomplete:not(.p-disabled):hover .p-variant-filled.p-autocomplete-input-multiple {
    background: ${dt('autocomplete.filled.hover.background')};
}

.p-autocomplete:not(.p-disabled).p-focus .p-variant-filled.p-autocomplete-input-multiple  {
    background: ${dt('autocomplete.filled.focus.background')};
}

.p-autocomplete.p-disabled {
    opacity: 1;
}

.p-autocomplete.p-disabled .p-autocomplete-input-multiple {
    opacity: 1;
    background: ${dt('autocomplete.disabled.background')};
    color: ${dt('autocomplete.disabled.color')};
}

.p-autocomplete-chip.p-chip {
    padding-block-start: calc(${dt('autocomplete.padding.y')} / 2);
    padding-block-end: calc(${dt('autocomplete.padding.y')} / 2);
    border-radius: ${dt('autocomplete.chip.border.radius')};
}

.p-autocomplete-input-multiple:has(.p-autocomplete-chip) {
    padding-inline-start: calc(${dt('autocomplete.padding.y')} / 2);
    padding-inline-end: calc(${dt('autocomplete.padding.y')} / 2);
}

.p-autocomplete-chip-item.p-focus .p-autocomplete-chip {
    background: ${dt('autocomplete.chip.focus.background')};
    color: ${dt('autocomplete.chip.focus.color')};
}

.p-autocomplete-input-chip {
    flex: 1 1 auto;
    display: inline-flex;
    padding-block-start: calc(${dt('autocomplete.padding.y')} / 2);
    padding-block-end: calc(${dt('autocomplete.padding.y')} / 2);
}

.p-autocomplete-input-chip input {
    border: 0 none;
    outline: 0 none;
    background: transparent;
    margin: 0;
    padding: 0;
    box-shadow: none;
    border-radius: 0;
    width: 100%;
    font-family: inherit;
    font-feature-settings: inherit;
    font-size: 1rem;
    color: inherit;
}

.p-autocomplete-input-chip input::placeholder {
    color: ${dt('autocomplete.placeholder.color')};
}

.p-autocomplete-empty-message {
    padding: ${dt('autocomplete.empty.message.padding')};
}

.p-autocomplete-fluid {
    display: flex;
}

.p-autocomplete-fluid:has(.p-autocomplete-dropdown) .p-autocomplete-input {
    width: 1%;
}

.p-autocomplete:has(.p-inputtext-sm) .p-autocomplete-dropdown {
    width: ${dt('autocomplete.dropdown.sm.width')};
}

.p-autocomplete:has(.p-inputtext-sm) .p-autocomplete-dropdown .p-icon {
    font-size: ${dt('form.field.sm.font.size')};
    width: ${dt('form.field.sm.font.size')};
    height: ${dt('form.field.sm.font.size')};
}

.p-autocomplete:has(.p-inputtext-lg) .p-autocomplete-dropdown {
    width: ${dt('autocomplete.dropdown.lg.width')};
}

.p-autocomplete:has(.p-inputtext-lg) .p-autocomplete-dropdown .p-icon {
    font-size: ${dt('form.field.lg.font.size')};
    width: ${dt('form.field.lg.font.size')};
    height: ${dt('form.field.lg.font.size')};
}

.p-autocomplete-clear-icon {
    position: absolute;
    top: 50%;
    margin-top: -0.5rem;
    cursor: pointer;
    right: ${dt('autocomplete.padding.x')};
    color: ${dt('autocomplete.dropdown.color')};
}

.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-clear-icon {
    right: calc(${dt('autocomplete.padding.x')} + ${dt('autocomplete.dropdown.width')});
}
p-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input,
p-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input-multiple,
p-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input,
p-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input-multiple
p-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input,
p-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input-multiple {
    border-color: ${dt('autocomplete.invalid.border.color')};
}
p-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,
p-autoComplete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple,
p-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,
p-auto-complete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple,
p-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,
p-autocomplete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple {
    border-color: ${dt('autocomplete.focus.border.color')};
}
p-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder,
p-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder,
p-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder {
    color: ${dt('autocomplete.invalid.placeholder.color')};
}

p-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder,
p-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder,
p-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder {
    color: ${dt('autocomplete.invalid.placeholder.color')};
}`;
const inlineStyles = {
    root: { position: 'relative' }
};
const classes = {
    root: ({ instance }) => ({
        'p-autocomplete p-component p-inputwrapper': true,
        'p-disabled': instance.disabled,
        'p-focus': instance.focused,
        'p-inputwrapper-filled': instance.filled,
        'p-inputwrapper-focus': (instance.focused && !instance.disabled) || instance.autofocus || instance.overlayVisible,
        'p-autocomplete-open': instance.overlayVisible,
        'p-autocomplete-clearable': instance.showClear && !instance.disabled,
        // 'p-invalid': instance.invalid,
        'p-autocomplete-fluid': instance.hasFluid
    }),
    pcInput: 'p-autocomplete-input',
    inputMultiple: ({ instance }) => ({
        'p-autocomplete-input-multiple': true,
        'p-variant-filled': (instance.variant ?? (instance.config.inputStyle() || instance.config.inputVariant())) === 'filled'
    }),
    chipItem: ({ instance, i }) => [
        'p-autocomplete-chip-item',
        {
            'p-focus': instance.focusedMultipleOptionIndex === i
        }
    ],
    pcChip: 'p-autocomplete-chip',
    chipIcon: 'p-autocomplete-chip-icon',
    inputChip: 'p-autocomplete-input-chip',
    loader: 'p-autocomplete-loader',
    dropdown: 'p-autocomplete-dropdown',
    overlay: 'p-autocomplete-overlay p-component',
    list: 'p-autocomplete-list',
    optionGroup: 'p-autocomplete-option-group',
    option: ({ instance, option, i, getItemOptions }) => ({
        'p-autocomplete-option': true,
        'p-autocomplete-option-selected': instance.isSelected(option),
        'p-focus': instance.focusedOptionIndex === instance.getOptionIndex(i, getItemOptions),
        'p-disabled': instance.isOptionDisabled(option)
    }),
    emptyMessage: 'p-autocomplete-empty-message'
};
class AutoCompleteStyle extends BaseStyle {
    name = 'autocomplete';
    theme = theme;
    classes = classes;
    inlineStyles = inlineStyles;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteStyle });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteStyle, decorators: [{
            type: Injectable
        }] });
/**
 *
 * AutoComplete is an input component that provides real-time suggestions while being typed.
 *
 * [Live Demo](https://www.primeng.org/autocomplete/)
 *
 * @module autocompletestyle
 *
 */
var AutoCompleteClasses;
(function (AutoCompleteClasses) {
    /**
     * Class name of the root element
     */
    AutoCompleteClasses["root"] = "p-autocomplete";
    /**
     * Class name of the input element
     */
    AutoCompleteClasses["pcInput"] = "p-autocomplete-input";
    /**
     * Class name of the input multiple element
     */
    AutoCompleteClasses["inputMultiple"] = "p-autocomplete-input-multiple";
    /**
     * Class name of the chip item element
     */
    AutoCompleteClasses["chipItem"] = "p-autocomplete-chip-item";
    /**
     * Class name of the chip element
     */
    AutoCompleteClasses["pcChip"] = "p-autocomplete-chip";
    /**
     * Class name of the chip icon element
     */
    AutoCompleteClasses["chipIcon"] = "p-autocomplete-chip-icon";
    /**
     * Class name of the input chip element
     */
    AutoCompleteClasses["inputChip"] = "p-autocomplete-input-chip";
    /**
     * Class name of the loader element
     */
    AutoCompleteClasses["loader"] = "p-autocomplete-loader";
    /**
     * Class name of the dropdown element
     */
    AutoCompleteClasses["dropdown"] = "p-autocomplete-dropdown";
    /**
     * Class name of the panel element
     */
    AutoCompleteClasses["panel"] = "p-autocomplete-overlay";
    /**
     * Class name of the list element
     */
    AutoCompleteClasses["list"] = "p-autocomplete-list";
    /**
     * Class name of the option group element
     */
    AutoCompleteClasses["optionGroup"] = "p-autocomplete-option-group";
    /**
     * Class name of the option element
     */
    AutoCompleteClasses["option"] = "p-autocomplete-option";
    /**
     * Class name of the empty message element
     */
    AutoCompleteClasses["emptyMessage"] = "p-autocomplete-empty-message";
})(AutoCompleteClasses || (AutoCompleteClasses = {}));

const AUTOCOMPLETE_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => AutoComplete),
    multi: true
};
/**
 * AutoComplete is an input component that provides real-time suggestions when being typed.
 * @group Components
 */
class AutoComplete extends BaseComponent {
    overlayService;
    zone;
    /**
     * Minimum number of characters to initiate a search.
     * @group Props
     */
    minLength = 1;
    /**
     * Delay between keystrokes to wait before sending a query.
     * @group Props
     */
    delay = 300;
    /**
     * Inline style of the component.
     * @group Props
     */
    style;
    /**
     * Inline style of the overlay panel element.
     * @group Props
     */
    panelStyle;
    /**
     * Style class of the component.
     * @group Props
     */
    styleClass;
    /**
     * Style class of the overlay panel element.
     * @group Props
     */
    panelStyleClass;
    /**
     * Inline style of the input field.
     * @group Props
     */
    inputStyle;
    /**
     * Identifier of the focus input to match a label defined for the component.
     * @group Props
     */
    inputId;
    /**
     * Inline style of the input field.
     * @group Props
     */
    inputStyleClass;
    /**
     * Hint text for the input field.
     * @group Props
     */
    placeholder;
    /**
     * When present, it specifies that the input cannot be typed.
     * @group Props
     */
    readonly;
    /**
     * When present, it specifies that the component should be disabled.
     * @group Props
     */
    disabled;
    /**
     * Maximum height of the suggestions panel.
     * @group Props
     */
    scrollHeight = '200px';
    /**
     * Defines if data is loaded and interacted with in lazy manner.
     * @group Props
     */
    lazy = false;
    /**
     * Whether the data should be loaded on demand during scroll.
     * @group Props
     */
    virtualScroll;
    /**
     * Height of an item in the list for VirtualScrolling.
     * @group Props
     */
    virtualScrollItemSize;
    /**
     * Whether to use the scroller feature. The properties of scroller component can be used like an object in it.
     * @group Props
     */
    virtualScrollOptions;
    /**
     * Maximum number of character allows in the input field.
     * @group Props
     */
    maxlength;
    /**
     * Name of the input element.
     * @group Props
     */
    name;
    /**
     * When present, it specifies that an input field must be filled out before submitting the form.
     * @group Props
     */
    required;
    /**
     * Defines the size of the component.
     * @group Props
     */
    size;
    /**
     * Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name).
     * @group Props
     */
    appendTo;
    /**
     * When enabled, highlights the first item in the list by default.
     * @group Props
     */
    autoHighlight;
    /**
     * When present, autocomplete clears the manual input if it does not match of the suggestions to force only accepting values from the suggestions.
     * @group Props
     */
    forceSelection;
    /**
     * Type of the input, defaults to "text".
     * @group Props
     */
    type = 'text';
    /**
     * Whether to automatically manage layering.
     * @group Props
     */
    autoZIndex = true;
    /**
     * Base zIndex value to use in layering.
     * @group Props
     */
    baseZIndex = 0;
    /**
     * Defines a string that labels the input for accessibility.
     * @group Props
     */
    ariaLabel;
    /**
     * Defines a string that labels the dropdown button for accessibility.
     * @group Props
     */
    dropdownAriaLabel;
    /**
     * Specifies one or more IDs in the DOM that labels the input field.
     * @group Props
     */
    ariaLabelledBy;
    /**
     * Icon class of the dropdown icon.
     * @group Props
     */
    dropdownIcon;
    /**
     * Ensures uniqueness of selected items on multiple mode.
     * @group Props
     */
    unique = true;
    /**
     * Whether to display options as grouped when nested options are provided.
     * @group Props
     */
    group;
    /**
     * Whether to run a query when input receives focus.
     * @group Props
     */
    completeOnFocus = false;
    /**
     * When enabled, a clear icon is displayed to clear the value.
     * @group Props
     */
    showClear = false;
    /**
     * Field of a suggested object to resolve and display.
     * @group Props
     * @deprecated use optionLabel property instead
     */
    field;
    /**
     * Displays a button next to the input field when enabled.
     * @group Props
     */
    dropdown;
    /**
     * Whether to show the empty message or not.
     * @group Props
     */
    showEmptyMessage = true;
    /**
     * Specifies the behavior dropdown button. Default "blank" mode sends an empty string and "current" mode sends the input value.
     * @group Props
     */
    dropdownMode = 'blank';
    /**
     * Specifies if multiple values can be selected.
     * @group Props
     */
    multiple;
    /**
     * Index of the element in tabbing order.
     * @group Props
     */
    tabindex;
    /**
     * A property to uniquely identify a value in options.
     * @group Props
     */
    dataKey;
    /**
     * Text to display when there is no data. Defaults to global value in i18n translation configuration.
     * @group Props
     */
    emptyMessage;
    /**
     * Transition options of the show animation.
     * @group Props
     */
    showTransitionOptions = '.12s cubic-bezier(0, 0, 0.2, 1)';
    /**
     * Transition options of the hide animation.
     * @group Props
     */
    hideTransitionOptions = '.1s linear';
    /**
     * When present, it specifies that the component should automatically get focus on load.
     * @group Props
     */
    autofocus;
    /**
     * Used to define a string that autocomplete attribute the current element.
     * @group Props
     */
    autocomplete = 'off';
    /**
     * Name of the options field of an option group.
     * @group Props
     */
    optionGroupChildren = 'items';
    /**
     * Name of the label field of an option group.
     * @group Props
     */
    optionGroupLabel = 'label';
    /**
     * Options for the overlay element.
     * @group Props
     */
    overlayOptions;
    /**
     * An array of suggestions to display.
     * @group Props
     */
    get suggestions() {
        return this._suggestions();
    }
    set suggestions(value) {
        this._suggestions.set(value);
        this.handleSuggestionsChange();
    }
    /**
     * Element dimensions of option for virtual scrolling.
     * @group Props
     * @deprecated use virtualScrollItemSize property instead.
     */
    get itemSize() {
        return this._itemSize;
    }
    set itemSize(val) {
        this._itemSize = val;
        console.log('The itemSize property is deprecated, use virtualScrollItemSize property instead.');
    }
    /**
     * Property name or getter function to use as the label of an option.
     * @group Props
     */
    optionLabel;
    /**
     * Property name or getter function to use as the value of an option.
     * @group Props
     */
    optionValue;
    /**
     * Unique identifier of the component.
     * @group Props
     */
    id;
    /**
     * Text to display when the search is active. Defaults to global value in i18n translation configuration.
     * @group Props
     * @defaultValue '{0} results are available'
     */
    searchMessage;
    /**
     * Text to display when filtering does not return any results. Defaults to global value in i18n translation configuration.
     * @group Props
     * @defaultValue 'No selected item'
     */
    emptySelectionMessage;
    /**
     * Text to be displayed in hidden accessible field when options are selected. Defaults to global value in i18n translation configuration.
     * @group Props
     * @defaultValue '{0} items selected'
     */
    selectionMessage;
    /**
     * Whether to focus on the first visible or selected element when the overlay panel is shown.
     * @group Props
     */
    autoOptionFocus = false;
    /**
     * When enabled, the focused option is selected.
     * @group Props
     */
    selectOnFocus;
    /**
     * Locale to use in searching. The default locale is the host environment's current locale.
     * @group Props
     */
    searchLocale;
    /**
     * Property name or getter function to use as the disabled flag of an option, defaults to false when not defined.
     * @group Props
     */
    optionDisabled;
    /**
     * When enabled, the hovered option will be focused.
     * @group Props
     */
    focusOnHover = true;
    /**
     * Whether typeahead is active or not.
     * @defaultValue true
     * @group Props
     */
    typeahead = true;
    /**
     * Specifies the input variant of the component.
     * @group Props
     */
    variant;
    /**
     * Spans 100% width of the container when enabled.
     * @group Props
     */
    fluid = false;
    /**
     * Callback to invoke to search for suggestions.
     * @param {AutoCompleteCompleteEvent} event - Custom complete event.
     * @group Emits
     */
    completeMethod = new EventEmitter();
    /**
     * Callback to invoke when a suggestion is selected.
     * @param {AutoCompleteSelectEvent} event - custom select event.
     * @group Emits
     */
    onSelect = new EventEmitter();
    /**
     * Callback to invoke when a selected value is removed.
     * @param {AutoCompleteUnselectEvent} event - custom unselect event.
     * @group Emits
     */
    onUnselect = new EventEmitter();
    /**
     * Callback to invoke when the component receives focus.
     * @param {Event} event - Browser event.
     * @group Emits
     */
    onFocus = new EventEmitter();
    /**
     * Callback to invoke when the component loses focus.
     * @param {Event} event - Browser event.
     * @group Emits
     */
    onBlur = new EventEmitter();
    /**
     * Callback to invoke to when dropdown button is clicked.
     * @param {AutoCompleteDropdownClickEvent} event - custom dropdown click event.
     * @group Emits
     */
    onDropdownClick = new EventEmitter();
    /**
     * Callback to invoke when clear button is clicked.
     * @param {Event} event - Browser event.
     * @group Emits
     */
    onClear = new EventEmitter();
    /**
     * Callback to invoke on input key up.
     * @param {KeyboardEvent} event - Keyboard event.
     * @group Emits
     */
    onKeyUp = new EventEmitter();
    /**
     * Callback to invoke on overlay is shown.
     * @param {Event} event - Browser event.
     * @group Emits
     */
    onShow = new EventEmitter();
    /**
     * Callback to invoke on overlay is hidden.
     * @param {Event} event - Browser event.
     * @group Emits
     */
    onHide = new EventEmitter();
    /**
     * Callback to invoke on lazy load data.
     * @param {AutoCompleteLazyLoadEvent} event - Lazy load event.
     * @group Emits
     */
    onLazyLoad = new EventEmitter();
    containerEL;
    inputEL;
    multiInputEl;
    multiContainerEL;
    dropdownButton;
    itemsViewChild;
    scroller;
    overlayViewChild;
    _itemSize;
    itemsWrapper;
    /**
     * Custom item template.
     * @group Templates
     */
    itemTemplate;
    /**
     * Custom empty message template.
     * @group Templates
     */
    emptyTemplate;
    /**
     * Custom header template.
     * @group Templates
     */
    headerTemplate;
    /**
     * Custom footer template.
     * @group Templates
     */
    footerTemplate;
    /**
     * Custom selected item template.
     * @group Templates
     */
    selectedItemTemplate;
    /**
     * Custom group item template.
     * @group Templates
     */
    groupTemplate;
    /**
     * Custom loader template.
     * @group Templates
     */
    loaderTemplate;
    /**
     * Custom remove icon template.
     * @group Templates
     */
    removeIconTemplate;
    /**
     * Custom loading icon template.
     * @group Templates
     */
    loadingIconTemplate;
    /**
     * Custom clear icon template.
     * @group Templates
     */
    clearIconTemplate;
    /**
     * Custom dropdown icon template.
     * @group Templates
     */
    dropdownIconTemplate;
    primeng = inject(PrimeNG);
    value;
    _suggestions = signal(null);
    onModelChange = () => { };
    onModelTouched = () => { };
    timeout;
    overlayVisible;
    suggestionsUpdated;
    highlightOption;
    highlightOptionChanged;
    focused = false;
    _filled;
    get filled() {
        return this._filled;
    }
    set filled(value) {
        this._filled = value;
    }
    loading;
    scrollHandler;
    listId;
    searchTimeout;
    dirty = false;
    _itemTemplate;
    _groupTemplate;
    _selectedItemTemplate;
    _headerTemplate;
    _emptyTemplate;
    _footerTemplate;
    _loaderTemplate;
    _removeIconTemplate;
    _loadingIconTemplate;
    _clearIconTemplate;
    _dropdownIconTemplate;
    modelValue = signal(null);
    focusedMultipleOptionIndex = signal(-1);
    focusedOptionIndex = signal(-1);
    _componentStyle = inject(AutoCompleteStyle);
    visibleOptions = computed(() => {
        return this.group ? this.flatOptions(this._suggestions()) : this._suggestions() || [];
    });
    inputValue = computed(() => {
        const modelValue = this.modelValue();
        const selectedOption = this.optionValueSelected ? (this.suggestions || []).find((item) => resolveFieldData(item, this.optionValue) === modelValue) : modelValue;
        if (isNotEmpty(modelValue)) {
            if (typeof modelValue === 'object' || this.optionValueSelected) {
                const label = this.getOptionLabel(selectedOption);
                return label != null ? label : modelValue;
            }
            else {
                return modelValue;
            }
        }
        else {
            return '';
        }
    });
    get focusedMultipleOptionId() {
        return this.focusedMultipleOptionIndex() !== -1 ? `${this.id}_multiple_option_${this.focusedMultipleOptionIndex()}` : null;
    }
    get focusedOptionId() {
        return this.focusedOptionIndex() !== -1 ? `${this.id}_${this.focusedOptionIndex()}` : null;
    }
    get rootClass() {
        return this._componentStyle.classes.root({ instance: this });
    }
    get inputMultipleClass() {
        return this._componentStyle.classes.inputMultiple({ instance: this });
    }
    get panelClass() {
        return {
            'p-autocomplete-overlay p-component': true,
            'p-input-filled': this.config.inputStyle() === 'filled' || this.config.inputVariant() === 'filled',
            'p-ripple-disabled': this.config.ripple() === false
        };
    }
    get inputClass() {
        return {
            'p-autocomplete-input': !this.multiple,
            'p-autocomplete-dd-input': this.dropdown
        };
    }
    get searchResultMessageText() {
        return isNotEmpty(this.visibleOptions()) && this.overlayVisible ? this.searchMessageText.replaceAll('{0}', this.visibleOptions().length) : this.emptySearchMessageText;
    }
    get searchMessageText() {
        return this.searchMessage || this.config.translation.searchMessage || '';
    }
    get emptySearchMessageText() {
        return this.emptyMessage || this.config.translation.emptySearchMessage || '';
    }
    get selectionMessageText() {
        return this.selectionMessage || this.config.translation.selectionMessage || '';
    }
    get emptySelectionMessageText() {
        return this.emptySelectionMessage || this.config.translation.emptySelectionMessage || '';
    }
    get selectedMessageText() {
        return this.hasSelectedOption() ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.modelValue().length : '1') : this.emptySelectionMessageText;
    }
    get ariaSetSize() {
        return this.visibleOptions().filter((option) => !this.isOptionGroup(option)).length;
    }
    get listLabel() {
        return this.config.getTranslation(TranslationKeys.ARIA)['listLabel'];
    }
    get virtualScrollerDisabled() {
        return !this.virtualScroll;
    }
    get optionValueSelected() {
        return typeof this.modelValue() === 'string' && this.optionValue;
    }
    chipItemClass(index) {
        return this._componentStyle.classes.chipItem({ instance: this, i: index });
    }
    optionClass(option, i, scrollerOptions) {
        return {
            'p-autocomplete-option': true,
            'p-autocomplete-option-selected': this.isSelected(option),
            'p-focus': this.focusedOptionIndex() === this.getOptionIndex(i, scrollerOptions),
            'p-disabled': this.isOptionDisabled(option)
        };
    }
    constructor(overlayService, zone) {
        super();
        this.overlayService = overlayService;
        this.zone = zone;
        effect(() => {
            this.filled = isNotEmpty(this.modelValue());
        });
    }
    ngOnInit() {
        super.ngOnInit();
        this.id = this.id || uuid('pn_id_');
        this.cd.detectChanges();
    }
    templates;
    ngAfterContentInit() {
        this.templates.forEach((item) => {
            switch (item.getType()) {
                case 'item':
                    this._itemTemplate = item.template;
                    break;
                case 'group':
                    this._groupTemplate = item.template;
                    break;
                case 'selecteditem':
                    this._selectedItemTemplate = item.template;
                    break;
                case 'selectedItem':
                    this._selectedItemTemplate = item.template;
                    break;
                case 'header':
                    this._headerTemplate = item.template;
                    break;
                case 'empty':
                    this._emptyTemplate = item.template;
                    break;
                case 'footer':
                    this._footerTemplate = item.template;
                    break;
                case 'loader':
                    this._loaderTemplate = item.template;
                    break;
                case 'removetokenicon':
                    this._removeIconTemplate = item.template;
                    break;
                case 'loadingicon':
                    this._loadingIconTemplate = item.template;
                    break;
                case 'clearicon':
                    this._clearIconTemplate = item.template;
                    break;
                case 'dropdownicon':
                    this._dropdownIconTemplate = item.template;
                    break;
                default:
                    this._itemTemplate = item.template;
                    break;
            }
        });
    }
    ngAfterViewChecked() {
        //Use timeouts as since Angular 4.2, AfterViewChecked is broken and not called after panel is updated
        if (this.suggestionsUpdated && this.overlayViewChild) {
            this.zone.runOutsideAngular(() => {
                setTimeout(() => {
                    if (this.overlayViewChild) {
                        this.overlayViewChild.alignOverlay();
                    }
                }, 1);
                this.suggestionsUpdated = false;
            });
        }
    }
    handleSuggestionsChange() {
        if (this.loading) {
            this._suggestions()?.length > 0 || this.showEmptyMessage || !!this.emptyTemplate ? this.show() : this.hide();
            const focusedOptionIndex = this.overlayVisible && this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
            this.focusedOptionIndex.set(focusedOptionIndex);
            this.suggestionsUpdated = true;
            this.loading = false;
            this.cd.markForCheck();
        }
    }
    flatOptions(options) {
        return (options || []).reduce((result, option, index) => {
            result.push({ optionGroup: option, group: true, index });
            const optionGroupChildren = this.getOptionGroupChildren(option);
            optionGroupChildren && optionGroupChildren.forEach((o) => result.push(o));
            return result;
        }, []);
    }
    isOptionGroup(option) {
        return this.optionGroupLabel && option.optionGroup && option.group;
    }
    findFirstOptionIndex() {
        return this.visibleOptions().findIndex((option) => this.isValidOption(option));
    }
    findLastOptionIndex() {
        return findLastIndex(this.visibleOptions(), (option) => this.isValidOption(option));
    }
    findFirstFocusedOptionIndex() {
        const selectedIndex = this.findSelectedOptionIndex();
        return selectedIndex < 0 ? this.findFirstOptionIndex() : selectedIndex;
    }
    findLastFocusedOptionIndex() {
        const selectedIndex = this.findSelectedOptionIndex();
        return selectedIndex < 0 ? this.findLastOptionIndex() : selectedIndex;
    }
    findSelectedOptionIndex() {
        return this.hasSelectedOption() ? this.visibleOptions().findIndex((option) => this.isValidSelectedOption(option)) : -1;
    }
    findNextOptionIndex(index) {
        const matchedOptionIndex = index < this.visibleOptions().length - 1
            ? this.visibleOptions()
                .slice(index + 1)
                .findIndex((option) => this.isValidOption(option))
            : -1;
        return matchedOptionIndex > -1 ? matchedOptionIndex + index + 1 : index;
    }
    findPrevOptionIndex(index) {
        const matchedOptionIndex = index > 0 ? findLastIndex(this.visibleOptions().slice(0, index), (option) => this.isValidOption(option)) : -1;
        return matchedOptionIndex > -1 ? matchedOptionIndex : index;
    }
    isValidSelectedOption(option) {
        return this.isValidOption(option) && this.isSelected(option);
    }
    isValidOption(option) {
        return option && !(this.isOptionDisabled(option) || this.isOptionGroup(option));
    }
    isOptionDisabled(option) {
        return this.optionDisabled ? resolveFieldData(option, this.optionDisabled) : false;
    }
    isSelected(option) {
        if (this.multiple) {
            return this.unique ? this.modelValue()?.find((model) => equals(model, this.getOptionValue(option), this.equalityKey())) : false;
        }
        return equals(this.modelValue(), this.getOptionValue(option), this.equalityKey());
    }
    isOptionMatched(option, value) {
        return this.isValidOption(option) && this.getOptionLabel(option).toLocaleLowerCase(this.searchLocale) === value.toLocaleLowerCase(this.searchLocale);
    }
    isInputClicked(event) {
        return event.target === this.inputEL.nativeElement;
    }
    isDropdownClicked(event) {
        return this.dropdownButton?.nativeElement ? event.target === this.dropdownButton.nativeElement || this.dropdownButton.nativeElement.contains(event.target) : false;
    }
    equalityKey() {
        return this.dataKey; // TODO: The 'optionValue' properties can be added.
    }
    onContainerClick(event) {
        if (this.disabled || this.loading || this.isInputClicked(event) || this.isDropdownClicked(event)) {
            return;
        }
        if (!this.overlayViewChild || !this.overlayViewChild.overlayViewChild?.nativeElement.contains(event.target)) {
            focus(this.inputEL.nativeElement);
        }
    }
    handleDropdownClick(event) {
        let query = undefined;
        if (this.overlayVisible) {
            this.hide(true);
        }
        else {
            focus(this.inputEL.nativeElement);
            query = this.inputEL.nativeElement.value;
            if (this.dropdownMode === 'blank')
                this.search(event, '', 'dropdown');
            else if (this.dropdownMode === 'current')
                this.search(event, query, 'dropdown');
        }
        this.onDropdownClick.emit({ originalEvent: event, query });
    }
    onInput(event) {
        if (this.typeahead) {
            if (this.searchTimeout) {
                clearTimeout(this.searchTimeout);
            }
            let query = event.target.value;
            if (this.maxlength !== null) {
                query = query.split('').slice(0, this.maxlength).join('');
            }
            if (!this.multiple && !this.forceSelection) {
                this.updateModel(query);
            }
            if (query.length === 0 && !this.multiple) {
                this.onClear.emit();
                setTimeout(() => {
                    this.hide();
                }, this.delay / 2);
            }
            else {
                if (query.length >= this.minLength) {
                    this.focusedOptionIndex.set(-1);
                    this.searchTimeout = setTimeout(() => {
                        this.search(event, query, 'input');
                    }, this.delay);
                }
                else {
                    this.hide();
                }
            }
        }
    }
    onInputChange(event) {
        if (this.forceSelection) {
            let valid = false;
            if (this.visibleOptions()) {
                const matchedValue = this.visibleOptions().find((option) => this.isOptionMatched(option, this.inputEL.nativeElement.value || ''));
                if (matchedValue !== undefined) {
                    valid = true;
                    !this.isSelected(matchedValue) && this.onOptionSelect(event, matchedValue);
                }
            }
            if (!valid) {
                this.inputEL.nativeElement.value = '';
                !this.multiple && this.updateModel(null);
            }
        }
    }
    onInputFocus(event) {
        if (this.disabled) {
            // For ScreenReaders
            return;
        }
        if (!this.dirty && this.completeOnFocus) {
            this.search(event, event.target.value, 'focus');
        }
        this.dirty = true;
        this.focused = true;
        const focusedOptionIndex = this.focusedOptionIndex() !== -1 ? this.focusedOptionIndex() : this.overlayVisible && this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
        this.focusedOptionIndex.set(focusedOptionIndex);
        this.overlayVisible && this.scrollInView(this.focusedOptionIndex());
        this.onFocus.emit(event);
    }
    onMultipleContainerFocus(event) {
        if (this.disabled) {
            // For ScreenReaders
            return;
        }
        this.focused = true;
    }
    onMultipleContainerBlur(event) {
        this.focusedMultipleOptionIndex.set(-1);
        this.focused = false;
    }
    onMultipleContainerKeyDown(event) {
        if (this.disabled) {
            event.preventDefault();
            return;
        }
        switch (event.code) {
            case 'ArrowLeft':
                this.onArrowLeftKeyOnMultiple(event);
                break;
            case 'ArrowRight':
                this.onArrowRightKeyOnMultiple(event);
                break;
            case 'Backspace':
                this.onBackspaceKeyOnMultiple(event);
                break;
            default:
                break;
        }
    }
    onInputBlur(event) {
        this.dirty = false;
        this.focused = false;
        this.focusedOptionIndex.set(-1);
        this.onModelTouched();
        this.onBlur.emit(event);
    }
    onInputPaste(event) {
        this.onKeyDown(event);
    }
    onInputKeyUp(event) {
        this.onKeyUp.emit(event);
    }
    onKeyDown(event) {
        if (this.disabled) {
            event.preventDefault();
            return;
        }
        switch (event.code) {
            case 'ArrowDown':
                this.onArrowDownKey(event);
                break;
            case 'ArrowUp':
                this.onArrowUpKey(event);
                break;
            case 'ArrowLeft':
                this.onArrowLeftKey(event);
                break;
            case 'ArrowRight':
                this.onArrowRightKey(event);
                break;
            case 'Home':
                this.onHomeKey(event);
                break;
            case 'End':
                this.onEndKey(event);
                break;
            case 'PageDown':
                this.onPageDownKey(event);
                break;
            case 'PageUp':
                this.onPageUpKey(event);
                break;
            case 'Enter':
            case 'NumpadEnter':
                this.onEnterKey(event);
                break;
            case 'Escape':
                this.onEscapeKey(event);
                break;
            case 'Tab':
                this.onTabKey(event);
                break;
            case 'Backspace':
                this.onBackspaceKey(event);
                break;
            case 'ShiftLeft':
            case 'ShiftRight':
                //NOOP
                break;
            default:
                break;
        }
    }
    onArrowDownKey(event) {
        if (!this.overlayVisible) {
            return;
        }
        const optionIndex = this.focusedOptionIndex() !== -1 ? this.findNextOptionIndex(this.focusedOptionIndex()) : this.findFirstFocusedOptionIndex();
        this.changeFocusedOptionIndex(event, optionIndex);
        event.preventDefault();
        event.stopPropagation();
    }
    onArrowUpKey(event) {
        if (!this.overlayVisible) {
            return;
        }
        if (event.altKey) {
            if (this.focusedOptionIndex() !== -1) {
                this.onOptionSelect(event, this.visibleOptions()[this.focusedOptionIndex()]);
            }
            this.overlayVisible && this.hide();
            event.preventDefault();
        }
        else {
            const optionIndex = this.focusedOptionIndex() !== -1 ? this.findPrevOptionIndex(this.focusedOptionIndex()) : this.findLastFocusedOptionIndex();
            this.changeFocusedOptionIndex(event, optionIndex);
            event.preventDefault();
            event.stopPropagation();
        }
    }
    get hasFluid() {
        const nativeElement = this.el.nativeElement;
        const fluidComponent = nativeElement.closest('p-fluid');
        return this.fluid || !!fluidComponent;
    }
    onArrowLeftKey(event) {
        const target = event.currentTarget;
        this.focusedOptionIndex.set(-1);
        if (this.multiple) {
            if (isEmpty(target.value) && this.hasSelectedOption()) {
                focus(this.multiContainerEL.nativeElement);
                this.focusedMultipleOptionIndex.set(this.modelValue().length);
            }
            else {
                event.stopPropagation(); // To prevent onArrowLeftKeyOnMultiple method
            }
        }
    }
    onArrowRightKey(event) {
        this.focusedOptionIndex.set(-1);
        this.multiple && event.stopPropagation(); // To prevent onArrowRightKeyOnMultiple method
    }
    onHomeKey(event) {
        const { currentTarget } = event;
        const len = currentTarget.value.length;
        currentTarget.setSelectionRange(0, event.shiftKey ? len : 0);
        this.focusedOptionIndex.set(-1);
        event.preventDefault();
    }
    onEndKey(event) {
        const { currentTarget } = event;
        const len = currentTarget.value.length;
        currentTarget.setSelectionRange(event.shiftKey ? 0 : len, len);
        this.focusedOptionIndex.set(-1);
        event.preventDefault();
    }
    onPageDownKey(event) {
        this.scrollInView(this.visibleOptions().length - 1);
        event.preventDefault();
    }
    onPageUpKey(event) {
        this.scrollInView(0);
        event.preventDefault();
    }
    onEnterKey(event) {
        if (!this.typeahead) {
            if (this.multiple) {
                this.updateModel([...(this.modelValue() || []), event.target.value]);
                this.inputEL.nativeElement.value = '';
            }
        }
        if (!this.overlayVisible) {
            this.onArrowDownKey(event);
        }
        else {
            if (this.focusedOptionIndex() !== -1) {
                this.onOptionSelect(event, this.visibleOptions()[this.focusedOptionIndex()]);
            }
            this.hide();
        }
        event.preventDefault();
    }
    onEscapeKey(event) {
        this.overlayVisible && this.hide(true);
        event.preventDefault();
    }
    onTabKey(event) {
        if (this.focusedOptionIndex() !== -1) {
            this.onOptionSelect(event, this.visibleOptions()[this.focusedOptionIndex()]);
        }
        this.overlayVisible && this.hide();
    }
    onBackspaceKey(event) {
        if (this.multiple) {
            if (isNotEmpty(this.modelValue()) && !this.inputEL.nativeElement.value) {
                const removedValue = this.modelValue()[this.modelValue().length - 1];
                const newValue = this.modelValue().slice(0, -1);
                this.updateModel(newValue);
                this.onUnselect.emit({ originalEvent: event, value: removedValue });
            }
            event.stopPropagation(); // To prevent onBackspaceKeyOnMultiple method
        }
        if (!this.multiple && this.showClear && this.findSelectedOptionIndex() != -1) {
            this.clear();
        }
    }
    onArrowLeftKeyOnMultiple(event) {
        const optionIndex = this.focusedMultipleOptionIndex() < 1 ? 0 : this.focusedMultipleOptionIndex() - 1;
        this.focusedMultipleOptionIndex.set(optionIndex);
    }
    onArrowRightKeyOnMultiple(event) {
        let optionIndex = this.focusedMultipleOptionIndex();
        optionIndex++;
        this.focusedMultipleOptionIndex.set(optionIndex);
        if (optionIndex > this.modelValue().length - 1) {
            this.focusedMultipleOptionIndex.set(-1);
            focus(this.inputEL.nativeElement);
        }
    }
    onBackspaceKeyOnMultiple(event) {
        if (this.focusedMultipleOptionIndex() !== -1) {
            this.removeOption(event, this.focusedMultipleOptionIndex());
        }
    }
    onOptionSelect(event, option, isHide = true) {
        const value = this.getOptionValue(option);
        if (this.multiple) {
            this.inputEL.nativeElement.value = '';
            if (!this.isSelected(option)) {
                this.updateModel([...(this.modelValue() || []), value]);
            }
        }
        else {
            this.updateModel(value);
        }
        this.onSelect.emit({ originalEvent: event, value: option });
        isHide && this.hide(true);
    }
    onOptionMouseEnter(event, index) {
        if (this.focusOnHover) {
            this.changeFocusedOptionIndex(event, index);
        }
    }
    search(event, query, source) {
        //allow empty string but not undefined or null
        if (query === undefined || query === null) {
            return;
        }
        //do not search blank values on input change
        if (source === 'input' && query.trim().length === 0) {
            return;
        }
        this.loading = true;
        this.completeMethod.emit({ originalEvent: event, query });
    }
    removeOption(event, index) {
        event.stopPropagation();
        const removedOption = this.modelValue()[index];
        const value = this.modelValue()
            .filter((_, i) => i !== index)
            .map((option) => this.getOptionValue(option));
        this.updateModel(value);
        this.onUnselect.emit({ originalEvent: event, value: removedOption });
        focus(this.inputEL.nativeElement);
    }
    updateModel(value) {
        this.value = value;
        this.modelValue.set(value);
        this.onModelChange(value);
        this.updateInputValue();
        this.cd.markForCheck();
    }
    updateInputValue() {
        if (this.inputEL && this.inputEL.nativeElement) {
            if (!this.multiple) {
                this.inputEL.nativeElement.value = this.inputValue();
            }
            else {
                this.inputEL.nativeElement.value = '';
            }
        }
    }
    autoUpdateModel() {
        if ((this.selectOnFocus || this.autoHighlight) && this.autoOptionFocus && !this.hasSelectedOption()) {
            const focusedOptionIndex = this.findFirstFocusedOptionIndex();
            this.focusedOptionIndex.set(focusedOptionIndex);
            this.onOptionSelect(null, this.visibleOptions()[this.focusedOptionIndex()], false);
        }
    }
    scrollInView(index = -1) {
        const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
        if (this.itemsViewChild && this.itemsViewChild.nativeElement) {
            const element = findSingle(this.itemsViewChild.nativeElement, `li[id="${id}"]`);
            if (element) {
                element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'nearest' });
            }
            else if (!this.virtualScrollerDisabled) {
                setTimeout(() => {
                    this.virtualScroll && this.scroller?.scrollToIndex(index !== -1 ? index : this.focusedOptionIndex());
                }, 0);
            }
        }
    }
    changeFocusedOptionIndex(event, index) {
        if (this.focusedOptionIndex() !== index) {
            this.focusedOptionIndex.set(index);
            this.scrollInView();
            if (this.selectOnFocus) {
                this.onOptionSelect(event, this.visibleOptions()[index], false);
            }
        }
    }
    show(isFocus = false) {
        this.dirty = true;
        this.overlayVisible = true;
        const focusedOptionIndex = this.focusedOptionIndex() !== -1 ? this.focusedOptionIndex() : this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
        this.focusedOptionIndex.set(focusedOptionIndex);
        isFocus && focus(this.inputEL.nativeElement);
        if (isFocus) {
            focus(this.inputEL.nativeElement);
        }
        this.onShow.emit();
        this.cd.markForCheck();
    }
    hide(isFocus = false) {
        const _hide = () => {
            this.dirty = isFocus;
            this.overlayVisible = false;
            this.focusedOptionIndex.set(-1);
            isFocus && focus(this.inputEL.nativeElement);
            this.onHide.emit();
            this.cd.markForCheck();
        };
        setTimeout(() => {
            _hide();
        }, 0); // For ScreenReaders
    }
    clear() {
        this.updateModel(null);
        this.inputEL.nativeElement.value = '';
        this.onClear.emit();
    }
    writeValue(value) {
        this.value = value;
        this.modelValue.set(value);
        this.updateInputValue();
        this.cd.markForCheck();
    }
    hasSelectedOption() {
        return isNotEmpty(this.modelValue());
    }
    getAriaPosInset(index) {
        return ((this.optionGroupLabel
            ? index -
                this.visibleOptions()
                    .slice(0, index)
                    .filter((option) => this.isOptionGroup(option)).length
            : index) + 1);
    }
    getOptionLabel(option) {
        return this.field || this.optionLabel ? resolveFieldData(option, this.field || this.optionLabel) : option && option.label != undefined ? option.label : option;
    }
    getOptionValue(option) {
        return this.optionValue ? resolveFieldData(option, this.optionValue) : option && option.value != undefined ? option.value : option;
    }
    getOptionIndex(index, scrollerOptions) {
        return this.virtualScrollerDisabled ? index : scrollerOptions && scrollerOptions.getItemOptions(index)['index'];
    }
    getOptionGroupLabel(optionGroup) {
        return this.optionGroupLabel ? resolveFieldData(optionGroup, this.optionGroupLabel) : optionGroup && optionGroup.label != undefined ? optionGroup.label : optionGroup;
    }
    getOptionGroupChildren(optionGroup) {
        return this.optionGroupChildren ? resolveFieldData(optionGroup, this.optionGroupChildren) : optionGroup.items;
    }
    registerOnChange(fn) {
        this.onModelChange = fn;
    }
    registerOnTouched(fn) {
        this.onModelTouched = fn;
    }
    setDisabledState(val) {
        this.disabled = val;
        this.cd.markForCheck();
    }
    onOverlayAnimationStart(event) {
        if (event.toState === 'visible') {
            this.itemsWrapper = findSingle(this.overlayViewChild.overlayViewChild?.nativeElement, this.virtualScroll ? '.p-scroller' : '.p-autocomplete-panel');
            if (this.virtualScroll) {
                this.scroller?.setContentEl(this.itemsViewChild?.nativeElement);
                this.scroller.viewInit();
            }
            if (this.visibleOptions() && this.visibleOptions().length) {
                if (this.virtualScroll) {
                    const selectedIndex = this.modelValue() ? this.focusedOptionIndex() : -1;
                    if (selectedIndex !== -1) {
                        this.scroller?.scrollToIndex(selectedIndex);
                    }
                }
                else {
                    let selectedListItem = findSingle(this.itemsWrapper, '.p-autocomplete-item.p-highlight');
                    if (selectedListItem) {
                        selectedListItem.scrollIntoView({ block: 'nearest', inline: 'center' });
                    }
                }
            }
        }
    }
    ngOnDestroy() {
        if (this.scrollHandler) {
            this.scrollHandler.destroy();
            this.scrollHandler = null;
        }
        super.ngOnDestroy();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoComplete, deps: [{ token: i1.OverlayService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "19.2.2", type: AutoComplete, isStandalone: true, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: { minLength: ["minLength", "minLength", numberAttribute], delay: ["delay", "delay", numberAttribute], style: "style", panelStyle: "panelStyle", styleClass: "styleClass", panelStyleClass: "panelStyleClass", inputStyle: "inputStyle", inputId: "inputId", inputStyleClass: "inputStyleClass", placeholder: "placeholder", readonly: ["readonly", "readonly", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], scrollHeight: "scrollHeight", lazy: ["lazy", "lazy", booleanAttribute], virtualScroll: ["virtualScroll", "virtualScroll", booleanAttribute], virtualScrollItemSize: ["virtualScrollItemSize", "virtualScrollItemSize", numberAttribute], virtualScrollOptions: "virtualScrollOptions", maxlength: ["maxlength", "maxlength", (value) => numberAttribute(value, null)], name: "name", required: ["required", "required", booleanAttribute], size: "size", appendTo: "appendTo", autoHighlight: ["autoHighlight", "autoHighlight", booleanAttribute], forceSelection: ["forceSelection", "forceSelection", booleanAttribute], type: "type", autoZIndex: ["autoZIndex", "autoZIndex", booleanAttribute], baseZIndex: ["baseZIndex", "baseZIndex", numberAttribute], ariaLabel: "ariaLabel", dropdownAriaLabel: "dropdownAriaLabel", ariaLabelledBy: "ariaLabelledBy", dropdownIcon: "dropdownIcon", unique: ["unique", "unique", booleanAttribute], group: ["group", "group", booleanAttribute], completeOnFocus: ["completeOnFocus", "completeOnFocus", booleanAttribute], showClear: ["showClear", "showClear", booleanAttribute], field: "field", dropdown: ["dropdown", "dropdown", booleanAttribute], showEmptyMessage: ["showEmptyMessage", "showEmptyMessage", booleanAttribute], dropdownMode: "dropdownMode", multiple: ["multiple", "multiple", booleanAttribute], tabindex: ["tabindex", "tabindex", numberAttribute], dataKey: "dataKey", emptyMessage: "emptyMessage", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions", autofocus: ["autofocus", "autofocus", booleanAttribute], autocomplete: "autocomplete", optionGroupChildren: "optionGroupChildren", optionGroupLabel: "optionGroupLabel", overlayOptions: "overlayOptions", suggestions: "suggestions", itemSize: "itemSize", optionLabel: "optionLabel", optionValue: "optionValue", id: "id", searchMessage: "searchMessage", emptySelectionMessage: "emptySelectionMessage", selectionMessage: "selectionMessage", autoOptionFocus: ["autoOptionFocus", "autoOptionFocus", booleanAttribute], selectOnFocus: ["selectOnFocus", "selectOnFocus", booleanAttribute], searchLocale: ["searchLocale", "searchLocale", booleanAttribute], optionDisabled: "optionDisabled", focusOnHover: ["focusOnHover", "focusOnHover", booleanAttribute], typeahead: ["typeahead", "typeahead", booleanAttribute], variant: "variant", fluid: ["fluid", "fluid", booleanAttribute] }, outputs: { completeMethod: "completeMethod", onSelect: "onSelect", onUnselect: "onUnselect", onFocus: "onFocus", onBlur: "onBlur", onDropdownClick: "onDropdownClick", onClear: "onClear", onKeyUp: "onKeyUp", onShow: "onShow", onHide: "onHide", onLazyLoad: "onLazyLoad" }, providers: [AUTOCOMPLETE_VALUE_ACCESSOR, AutoCompleteStyle], queries: [{ propertyName: "itemTemplate", first: true, predicate: ["item"], descendants: true }, { propertyName: "emptyTemplate", first: true, predicate: ["empty"], descendants: true }, { propertyName: "headerTemplate", first: true, predicate: ["header"], descendants: true }, { propertyName: "footerTemplate", first: true, predicate: ["footer"], descendants: true }, { propertyName: "selectedItemTemplate", first: true, predicate: ["selecteditem"], descendants: true }, { propertyName: "groupTemplate", first: true, predicate: ["group"], descendants: true }, { propertyName: "loaderTemplate", first: true, predicate: ["loader"], descendants: true }, { propertyName: "removeIconTemplate", first: true, predicate: ["removeicon"], descendants: true }, { propertyName: "loadingIconTemplate", first: true, predicate: ["loadingicon"], descendants: true }, { propertyName: "clearIconTemplate", first: true, predicate: ["clearicon"], descendants: true }, { propertyName: "dropdownIconTemplate", first: true, predicate: ["dropdownicon"], descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "containerEL", first: true, predicate: ["container"], descendants: true }, { propertyName: "inputEL", first: true, predicate: ["focusInput"], descendants: true }, { propertyName: "multiInputEl", first: true, predicate: ["multiIn"], descendants: true }, { propertyName: "multiContainerEL", first: true, predicate: ["multiContainer"], descendants: true }, { propertyName: "dropdownButton", first: true, predicate: ["ddBtn"], descendants: true }, { propertyName: "itemsViewChild", first: true, predicate: ["items"], descendants: true }, { propertyName: "scroller", first: true, predicate: ["scroller"], descendants: true }, { propertyName: "overlayViewChild", first: true, predicate: ["overlay"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
        <div #container [ngClass]="rootClass" [ngStyle]="style" style="position: relative;" [class]="styleClass" (click)="onContainerClick($event)">
            <input
                *ngIf="!multiple"
                #focusInput
                [pAutoFocus]="autofocus"
                pInputText
                [ngClass]="'p-autocomplete-input'"
                [ngStyle]="inputStyle"
                [class]="inputStyleClass"
                [type]="type"
                [attr.value]="inputValue()"
                [variant]="variant"
                [attr.id]="inputId"
                [autocomplete]="autocomplete"
                [required]="required"
                [name]="name"
                aria-autocomplete="list"
                role="combobox"
                [attr.placeholder]="placeholder"
                [pSize]="size"
                [attr.maxlength]="maxlength"
                [tabindex]="!disabled ? tabindex : -1"
                [readonly]="readonly"
                [disabled]="disabled"
                [attr.aria-label]="ariaLabel"
                [attr.aria-labelledby]="ariaLabelledBy"
                [attr.aria-required]="required"
                [attr.aria-expanded]="overlayVisible ?? false"
                [attr.aria-controls]="overlayVisible ? id + '_list' : null"
                [attr.aria-activedescendant]="focused ? focusedOptionId : undefined"
                (input)="onInput($event)"
                (keydown)="onKeyDown($event)"
                (change)="onInputChange($event)"
                (focus)="onInputFocus($event)"
                (blur)="onInputBlur($event)"
                (paste)="onInputPaste($event)"
                (keyup)="onInputKeyUp($event)"
                [fluid]="hasFluid"
            />
            <ng-container *ngIf="filled && !disabled && showClear && !loading">
                <TimesIcon *ngIf="!clearIconTemplate && !_clearIconTemplate" [styleClass]="'p-autocomplete-clear-icon'" (click)="clear()" [attr.aria-hidden]="true" />
                <span *ngIf="clearIconTemplate || _clearIconTemplate" class="p-autocomplete-clear-icon" (click)="clear()" [attr.aria-hidden]="true">
                    <ng-template *ngTemplateOutlet="clearIconTemplate || _clearIconTemplate"></ng-template>
                </span>
            </ng-container>

            <ul
                *ngIf="multiple"
                #multiContainer
                [ngClass]="inputMultipleClass"
                [tabindex]="-1"
                role="listbox"
                [attr.aria-orientation]="'horizontal'"
                [attr.aria-activedescendant]="focused ? focusedMultipleOptionId : undefined"
                (focus)="onMultipleContainerFocus($event)"
                (blur)="onMultipleContainerBlur($event)"
                (keydown)="onMultipleContainerKeyDown($event)"
            >
                <li
                    #token
                    *ngFor="let option of modelValue(); let i = index"
                    [ngClass]="{ 'p-autocomplete-chip-item': true, 'p-focus': focusedMultipleOptionIndex() === i }"
                    [attr.id]="id + '_multiple_option_' + i"
                    role="option"
                    [attr.aria-label]="getOptionLabel(option)"
                    [attr.aria-setsize]="modelValue().length"
                    [attr.aria-posinset]="i + 1"
                    [attr.aria-selected]="true"
                >
                    <ng-container *ngTemplateOutlet="selectedItemTemplate || _selectedItemTemplate; context: { $implicit: option }"></ng-container>
                    <p-chip styleClass="p-autocomplete-chip" *ngIf="!selectedItemTemplate && !_selectedItemTemplate" [label]="getOptionLabel(option)" [removable]="true">
                        <ng-container *ngIf="!removeIconTemplate && !_removeIconTemplate">
                            <ng-template #removeicon>
                                <span class="p-autocomplete-chip-icon" (click)="!readonly ? removeOption($event, i) : ''">
                                    <TimesCircleIcon [styleClass]="'p-autocomplete-chip-icon'" [attr.aria-hidden]="true" />
                                </span>
                            </ng-template>
                        </ng-container>
                    </p-chip>
                    <span *ngIf="removeIconTemplate || _removeIconTemplate" [attr.aria-hidden]="true">
                        <ng-template *ngTemplateOutlet="removeIconTemplate || _removeIconTemplate; context: { class: 'p-autocomplete-chip-icon' }"></ng-template>
                    </span>
                </li>
                <li class="p-autocomplete-input-chip" role="option">
                    <input
                        #focusInput
                        [pAutoFocus]="autofocus"
                        [ngClass]="inputClass"
                        [ngStyle]="inputStyle"
                        [class]="inputStyleClass"
                        [attr.type]="type"
                        [attr.id]="inputId"
                        [autocomplete]="autocomplete"
                        [required]="required"
                        [attr.name]="name"
                        role="combobox"
                        [attr.placeholder]="!filled ? placeholder : null"
                        aria-autocomplete="list"
                        [attr.maxlength]="maxlength"
                        [tabindex]="!disabled ? tabindex : -1"
                        [readonly]="readonly"
                        [disabled]="disabled"
                        [attr.aria-label]="ariaLabel"
                        [attr.aria-labelledby]="ariaLabelledBy"
                        [attr.aria-required]="required"
                        [attr.aria-expanded]="overlayVisible ?? false"
                        [attr.aria-controls]="overlayVisible ? id + '_list' : null"
                        [attr.aria-activedescendant]="focused ? focusedOptionId : undefined"
                        (input)="onInput($event)"
                        (keydown)="onKeyDown($event)"
                        (change)="onInputChange($event)"
                        (focus)="onInputFocus($event)"
                        (blur)="onInputBlur($event)"
                        (paste)="onInputPaste($event)"
                        (keyup)="onInputKeyUp($event)"
                    />
                </li>
            </ul>
            <ng-container *ngIf="loading">
                <SpinnerIcon *ngIf="!loadingIconTemplate && !_loadingIconTemplate" [styleClass]="'p-autocomplete-loader'" [spin]="true" [attr.aria-hidden]="true" />
                <span *ngIf="loadingIconTemplate || _loadingIconTemplate" class="p-autocomplete-loader pi-spin " [attr.aria-hidden]="true">
                    <ng-template *ngTemplateOutlet="loadingIconTemplate || _loadingIconTemplate"></ng-template>
                </span>
            </ng-container>
            <button #ddBtn type="button" [attr.aria-label]="dropdownAriaLabel" class="p-autocomplete-dropdown" [disabled]="disabled" pRipple (click)="handleDropdownClick($event)" *ngIf="dropdown" [attr.tabindex]="tabindex">
                <span *ngIf="dropdownIcon" [ngClass]="dropdownIcon" [attr.aria-hidden]="true"></span>
                <ng-container *ngIf="!dropdownIcon">
                    <ChevronDownIcon *ngIf="!dropdownIconTemplate && !_dropdownIconTemplate" />
                    <ng-template *ngTemplateOutlet="dropdownIconTemplate || _dropdownIconTemplate"></ng-template>
                </ng-container>
            </button>
            <p-overlay
                #overlay
                [(visible)]="overlayVisible"
                [options]="overlayOptions"
                [target]="'@parent'"
                [appendTo]="appendTo"
                [showTransitionOptions]="showTransitionOptions"
                [hideTransitionOptions]="hideTransitionOptions"
                (onAnimationStart)="onOverlayAnimationStart($event)"
                (onHide)="hide()"
            >
                <ng-template #content>
                    <div [ngClass]="panelClass" [ngStyle]="panelStyle" [class]="panelStyleClass">
                        <ng-container *ngTemplateOutlet="headerTemplate || _headerTemplate"></ng-container>
                        <div class="p-autocomplete-list-container" [style.max-height]="virtualScroll ? 'auto' : scrollHeight">
                            <p-scroller
                                *ngIf="virtualScroll"
                                #scroller
                                [items]="visibleOptions()"
                                [style]="{ height: scrollHeight }"
                                [itemSize]="virtualScrollItemSize || _itemSize"
                                [autoSize]="true"
                                [lazy]="lazy"
                                (onLazyLoad)="onLazyLoad.emit($event)"
                                [options]="virtualScrollOptions"
                            >
                                <ng-template #content let-items let-scrollerOptions="options">
                                    <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: items, options: scrollerOptions }"></ng-container>
                                </ng-template>
                                <ng-container *ngIf="loaderTemplate || _loaderTemplate">
                                    <ng-template #loader let-scrollerOptions="options">
                                        <ng-container *ngTemplateOutlet="loaderTemplate || _loaderTemplate; context: { options: scrollerOptions }"></ng-container>
                                    </ng-template>
                                </ng-container>
                            </p-scroller>
                            <ng-container *ngIf="!virtualScroll">
                                <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: visibleOptions(), options: {} }"></ng-container>
                            </ng-container>
                        </div>

                        <ng-template #buildInItems let-items let-scrollerOptions="options">
                            <ul #items class="p-autocomplete-list" [ngClass]="scrollerOptions.contentStyleClass" [style]="scrollerOptions.contentStyle" role="listbox" [attr.id]="id + '_list'" [attr.aria-label]="listLabel">
                                <ng-template ngFor let-option [ngForOf]="items" let-i="index">
                                    <ng-container *ngIf="isOptionGroup(option)">
                                        <li [attr.id]="id + '_' + getOptionIndex(i, scrollerOptions)" class="p-autocomplete-option-group" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }" role="option">
                                            <span *ngIf="!groupTemplate">{{ getOptionGroupLabel(option.optionGroup) }}</span>
                                            <ng-container *ngTemplateOutlet="groupTemplate; context: { $implicit: option.optionGroup }"></ng-container>
                                        </li>
                                    </ng-container>
                                    <ng-container *ngIf="!isOptionGroup(option)">
                                        <li
                                            pRipple
                                            [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }"
                                            [ngClass]="optionClass(option, i, scrollerOptions)"
                                            [attr.id]="id + '_' + getOptionIndex(i, scrollerOptions)"
                                            role="option"
                                            [attr.aria-label]="getOptionLabel(option)"
                                            [attr.aria-selected]="isSelected(option)"
                                            [attr.aria-disabled]="isOptionDisabled(option)"
                                            [attr.data-p-focused]="focusedOptionIndex() === getOptionIndex(i, scrollerOptions)"
                                            [attr.aria-setsize]="ariaSetSize"
                                            [attr.aria-posinset]="getAriaPosInset(getOptionIndex(i, scrollerOptions))"
                                            (click)="onOptionSelect($event, option)"
                                            (mouseenter)="onOptionMouseEnter($event, getOptionIndex(i, scrollerOptions))"
                                        >
                                            <span *ngIf="!itemTemplate && !_itemTemplate">{{ getOptionLabel(option) }}</span>
                                            <ng-container
                                                *ngTemplateOutlet="
                                                    itemTemplate || _itemTemplate;
                                                    context: {
                                                        $implicit: option,
                                                        index: scrollerOptions.getOptions ? scrollerOptions.getOptions(i) : i
                                                    }
                                                "
                                            ></ng-container>
                                        </li>
                                    </ng-container>
                                </ng-template>
                                <li *ngIf="!items || (items && items.length === 0 && showEmptyMessage)" class="p-autocomplete-empty-message" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }" role="option">
                                    <ng-container *ngIf="!emptyTemplate && !_emptyTemplate; else empty">
                                        {{ searchResultMessageText }}
                                    </ng-container>
                                    <ng-container #empty *ngTemplateOutlet="emptyTemplate || _emptyTemplate"></ng-container>
                                </li>
                            </ul>
                        </ng-template>
                        <ng-container *ngTemplateOutlet="footerTemplate || _footerTemplate"></ng-container>
                    </div>
                    <span role="status" aria-live="polite" class="p-hidden-accessible">
                        {{ selectedMessageText }}
                    </span>
                </ng-template>
            </p-overlay>
        </div>
    `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: Overlay, selector: "p-overlay", inputs: ["visible", "mode", "style", "styleClass", "contentStyle", "contentStyleClass", "target", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "listener", "responsive", "options"], outputs: ["visibleChange", "onBeforeShow", "onShow", "onBeforeHide", "onHide", "onAnimationStart", "onAnimationDone"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "directive", type: Ripple, selector: "[pRipple]" }, { kind: "component", type: Scroller, selector: "p-scroller, p-virtualscroller, p-virtual-scroller, p-virtualScroller", inputs: ["id", "style", "styleClass", "tabindex", "items", "itemSize", "scrollHeight", "scrollWidth", "orientation", "step", "delay", "resizeDelay", "appendOnly", "inline", "lazy", "disabled", "loaderDisabled", "columns", "showSpacer", "showLoader", "numToleratedItems", "loading", "autoSize", "trackBy", "options"], outputs: ["onLazyLoad", "onScroll", "onScrollIndexChange"] }, { kind: "directive", type: AutoFocus, selector: "[pAutoFocus]", inputs: ["autofocus", "pAutoFocus"] }, { kind: "component", type: TimesCircleIcon, selector: "TimesCircleIcon" }, { kind: "component", type: SpinnerIcon, selector: "SpinnerIcon" }, { kind: "component", type: TimesIcon, selector: "TimesIcon" }, { kind: "component", type: ChevronDownIcon, selector: "ChevronDownIcon" }, { kind: "component", type: Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "style", "styleClass", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "ngmodule", type: SharedModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoComplete, decorators: [{
            type: Component,
            args: [{
                    selector: 'p-autoComplete, p-autocomplete, p-auto-complete',
                    standalone: true,
                    imports: [CommonModule, Overlay, InputText, Ripple, Scroller, AutoFocus, TimesCircleIcon, SpinnerIcon, TimesIcon, ChevronDownIcon, Chip, SharedModule],
                    template: `
        <div #container [ngClass]="rootClass" [ngStyle]="style" style="position: relative;" [class]="styleClass" (click)="onContainerClick($event)">
            <input
                *ngIf="!multiple"
                #focusInput
                [pAutoFocus]="autofocus"
                pInputText
                [ngClass]="'p-autocomplete-input'"
                [ngStyle]="inputStyle"
                [class]="inputStyleClass"
                [type]="type"
                [attr.value]="inputValue()"
                [variant]="variant"
                [attr.id]="inputId"
                [autocomplete]="autocomplete"
                [required]="required"
                [name]="name"
                aria-autocomplete="list"
                role="combobox"
                [attr.placeholder]="placeholder"
                [pSize]="size"
                [attr.maxlength]="maxlength"
                [tabindex]="!disabled ? tabindex : -1"
                [readonly]="readonly"
                [disabled]="disabled"
                [attr.aria-label]="ariaLabel"
                [attr.aria-labelledby]="ariaLabelledBy"
                [attr.aria-required]="required"
                [attr.aria-expanded]="overlayVisible ?? false"
                [attr.aria-controls]="overlayVisible ? id + '_list' : null"
                [attr.aria-activedescendant]="focused ? focusedOptionId : undefined"
                (input)="onInput($event)"
                (keydown)="onKeyDown($event)"
                (change)="onInputChange($event)"
                (focus)="onInputFocus($event)"
                (blur)="onInputBlur($event)"
                (paste)="onInputPaste($event)"
                (keyup)="onInputKeyUp($event)"
                [fluid]="hasFluid"
            />
            <ng-container *ngIf="filled && !disabled && showClear && !loading">
                <TimesIcon *ngIf="!clearIconTemplate && !_clearIconTemplate" [styleClass]="'p-autocomplete-clear-icon'" (click)="clear()" [attr.aria-hidden]="true" />
                <span *ngIf="clearIconTemplate || _clearIconTemplate" class="p-autocomplete-clear-icon" (click)="clear()" [attr.aria-hidden]="true">
                    <ng-template *ngTemplateOutlet="clearIconTemplate || _clearIconTemplate"></ng-template>
                </span>
            </ng-container>

            <ul
                *ngIf="multiple"
                #multiContainer
                [ngClass]="inputMultipleClass"
                [tabindex]="-1"
                role="listbox"
                [attr.aria-orientation]="'horizontal'"
                [attr.aria-activedescendant]="focused ? focusedMultipleOptionId : undefined"
                (focus)="onMultipleContainerFocus($event)"
                (blur)="onMultipleContainerBlur($event)"
                (keydown)="onMultipleContainerKeyDown($event)"
            >
                <li
                    #token
                    *ngFor="let option of modelValue(); let i = index"
                    [ngClass]="{ 'p-autocomplete-chip-item': true, 'p-focus': focusedMultipleOptionIndex() === i }"
                    [attr.id]="id + '_multiple_option_' + i"
                    role="option"
                    [attr.aria-label]="getOptionLabel(option)"
                    [attr.aria-setsize]="modelValue().length"
                    [attr.aria-posinset]="i + 1"
                    [attr.aria-selected]="true"
                >
                    <ng-container *ngTemplateOutlet="selectedItemTemplate || _selectedItemTemplate; context: { $implicit: option }"></ng-container>
                    <p-chip styleClass="p-autocomplete-chip" *ngIf="!selectedItemTemplate && !_selectedItemTemplate" [label]="getOptionLabel(option)" [removable]="true">
                        <ng-container *ngIf="!removeIconTemplate && !_removeIconTemplate">
                            <ng-template #removeicon>
                                <span class="p-autocomplete-chip-icon" (click)="!readonly ? removeOption($event, i) : ''">
                                    <TimesCircleIcon [styleClass]="'p-autocomplete-chip-icon'" [attr.aria-hidden]="true" />
                                </span>
                            </ng-template>
                        </ng-container>
                    </p-chip>
                    <span *ngIf="removeIconTemplate || _removeIconTemplate" [attr.aria-hidden]="true">
                        <ng-template *ngTemplateOutlet="removeIconTemplate || _removeIconTemplate; context: { class: 'p-autocomplete-chip-icon' }"></ng-template>
                    </span>
                </li>
                <li class="p-autocomplete-input-chip" role="option">
                    <input
                        #focusInput
                        [pAutoFocus]="autofocus"
                        [ngClass]="inputClass"
                        [ngStyle]="inputStyle"
                        [class]="inputStyleClass"
                        [attr.type]="type"
                        [attr.id]="inputId"
                        [autocomplete]="autocomplete"
                        [required]="required"
                        [attr.name]="name"
                        role="combobox"
                        [attr.placeholder]="!filled ? placeholder : null"
                        aria-autocomplete="list"
                        [attr.maxlength]="maxlength"
                        [tabindex]="!disabled ? tabindex : -1"
                        [readonly]="readonly"
                        [disabled]="disabled"
                        [attr.aria-label]="ariaLabel"
                        [attr.aria-labelledby]="ariaLabelledBy"
                        [attr.aria-required]="required"
                        [attr.aria-expanded]="overlayVisible ?? false"
                        [attr.aria-controls]="overlayVisible ? id + '_list' : null"
                        [attr.aria-activedescendant]="focused ? focusedOptionId : undefined"
                        (input)="onInput($event)"
                        (keydown)="onKeyDown($event)"
                        (change)="onInputChange($event)"
                        (focus)="onInputFocus($event)"
                        (blur)="onInputBlur($event)"
                        (paste)="onInputPaste($event)"
                        (keyup)="onInputKeyUp($event)"
                    />
                </li>
            </ul>
            <ng-container *ngIf="loading">
                <SpinnerIcon *ngIf="!loadingIconTemplate && !_loadingIconTemplate" [styleClass]="'p-autocomplete-loader'" [spin]="true" [attr.aria-hidden]="true" />
                <span *ngIf="loadingIconTemplate || _loadingIconTemplate" class="p-autocomplete-loader pi-spin " [attr.aria-hidden]="true">
                    <ng-template *ngTemplateOutlet="loadingIconTemplate || _loadingIconTemplate"></ng-template>
                </span>
            </ng-container>
            <button #ddBtn type="button" [attr.aria-label]="dropdownAriaLabel" class="p-autocomplete-dropdown" [disabled]="disabled" pRipple (click)="handleDropdownClick($event)" *ngIf="dropdown" [attr.tabindex]="tabindex">
                <span *ngIf="dropdownIcon" [ngClass]="dropdownIcon" [attr.aria-hidden]="true"></span>
                <ng-container *ngIf="!dropdownIcon">
                    <ChevronDownIcon *ngIf="!dropdownIconTemplate && !_dropdownIconTemplate" />
                    <ng-template *ngTemplateOutlet="dropdownIconTemplate || _dropdownIconTemplate"></ng-template>
                </ng-container>
            </button>
            <p-overlay
                #overlay
                [(visible)]="overlayVisible"
                [options]="overlayOptions"
                [target]="'@parent'"
                [appendTo]="appendTo"
                [showTransitionOptions]="showTransitionOptions"
                [hideTransitionOptions]="hideTransitionOptions"
                (onAnimationStart)="onOverlayAnimationStart($event)"
                (onHide)="hide()"
            >
                <ng-template #content>
                    <div [ngClass]="panelClass" [ngStyle]="panelStyle" [class]="panelStyleClass">
                        <ng-container *ngTemplateOutlet="headerTemplate || _headerTemplate"></ng-container>
                        <div class="p-autocomplete-list-container" [style.max-height]="virtualScroll ? 'auto' : scrollHeight">
                            <p-scroller
                                *ngIf="virtualScroll"
                                #scroller
                                [items]="visibleOptions()"
                                [style]="{ height: scrollHeight }"
                                [itemSize]="virtualScrollItemSize || _itemSize"
                                [autoSize]="true"
                                [lazy]="lazy"
                                (onLazyLoad)="onLazyLoad.emit($event)"
                                [options]="virtualScrollOptions"
                            >
                                <ng-template #content let-items let-scrollerOptions="options">
                                    <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: items, options: scrollerOptions }"></ng-container>
                                </ng-template>
                                <ng-container *ngIf="loaderTemplate || _loaderTemplate">
                                    <ng-template #loader let-scrollerOptions="options">
                                        <ng-container *ngTemplateOutlet="loaderTemplate || _loaderTemplate; context: { options: scrollerOptions }"></ng-container>
                                    </ng-template>
                                </ng-container>
                            </p-scroller>
                            <ng-container *ngIf="!virtualScroll">
                                <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: visibleOptions(), options: {} }"></ng-container>
                            </ng-container>
                        </div>

                        <ng-template #buildInItems let-items let-scrollerOptions="options">
                            <ul #items class="p-autocomplete-list" [ngClass]="scrollerOptions.contentStyleClass" [style]="scrollerOptions.contentStyle" role="listbox" [attr.id]="id + '_list'" [attr.aria-label]="listLabel">
                                <ng-template ngFor let-option [ngForOf]="items" let-i="index">
                                    <ng-container *ngIf="isOptionGroup(option)">
                                        <li [attr.id]="id + '_' + getOptionIndex(i, scrollerOptions)" class="p-autocomplete-option-group" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }" role="option">
                                            <span *ngIf="!groupTemplate">{{ getOptionGroupLabel(option.optionGroup) }}</span>
                                            <ng-container *ngTemplateOutlet="groupTemplate; context: { $implicit: option.optionGroup }"></ng-container>
                                        </li>
                                    </ng-container>
                                    <ng-container *ngIf="!isOptionGroup(option)">
                                        <li
                                            pRipple
                                            [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }"
                                            [ngClass]="optionClass(option, i, scrollerOptions)"
                                            [attr.id]="id + '_' + getOptionIndex(i, scrollerOptions)"
                                            role="option"
                                            [attr.aria-label]="getOptionLabel(option)"
                                            [attr.aria-selected]="isSelected(option)"
                                            [attr.aria-disabled]="isOptionDisabled(option)"
                                            [attr.data-p-focused]="focusedOptionIndex() === getOptionIndex(i, scrollerOptions)"
                                            [attr.aria-setsize]="ariaSetSize"
                                            [attr.aria-posinset]="getAriaPosInset(getOptionIndex(i, scrollerOptions))"
                                            (click)="onOptionSelect($event, option)"
                                            (mouseenter)="onOptionMouseEnter($event, getOptionIndex(i, scrollerOptions))"
                                        >
                                            <span *ngIf="!itemTemplate && !_itemTemplate">{{ getOptionLabel(option) }}</span>
                                            <ng-container
                                                *ngTemplateOutlet="
                                                    itemTemplate || _itemTemplate;
                                                    context: {
                                                        $implicit: option,
                                                        index: scrollerOptions.getOptions ? scrollerOptions.getOptions(i) : i
                                                    }
                                                "
                                            ></ng-container>
                                        </li>
                                    </ng-container>
                                </ng-template>
                                <li *ngIf="!items || (items && items.length === 0 && showEmptyMessage)" class="p-autocomplete-empty-message" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }" role="option">
                                    <ng-container *ngIf="!emptyTemplate && !_emptyTemplate; else empty">
                                        {{ searchResultMessageText }}
                                    </ng-container>
                                    <ng-container #empty *ngTemplateOutlet="emptyTemplate || _emptyTemplate"></ng-container>
                                </li>
                            </ul>
                        </ng-template>
                        <ng-container *ngTemplateOutlet="footerTemplate || _footerTemplate"></ng-container>
                    </div>
                    <span role="status" aria-live="polite" class="p-hidden-accessible">
                        {{ selectedMessageText }}
                    </span>
                </ng-template>
            </p-overlay>
        </div>
    `,
                    providers: [AUTOCOMPLETE_VALUE_ACCESSOR, AutoCompleteStyle],
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    encapsulation: ViewEncapsulation.None
                }]
        }], ctorParameters: () => [{ type: i1.OverlayService }, { type: i0.NgZone }], propDecorators: { minLength: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], delay: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], style: [{
                type: Input
            }], panelStyle: [{
                type: Input
            }], styleClass: [{
                type: Input
            }], panelStyleClass: [{
                type: Input
            }], inputStyle: [{
                type: Input
            }], inputId: [{
                type: Input
            }], inputStyleClass: [{
                type: Input
            }], placeholder: [{
                type: Input
            }], readonly: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], disabled: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], scrollHeight: [{
                type: Input
            }], lazy: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], virtualScroll: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], virtualScrollItemSize: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], virtualScrollOptions: [{
                type: Input
            }], maxlength: [{
                type: Input,
                args: [{ transform: (value) => numberAttribute(value, null) }]
            }], name: [{
                type: Input
            }], required: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], size: [{
                type: Input
            }], appendTo: [{
                type: Input
            }], autoHighlight: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], forceSelection: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], type: [{
                type: Input
            }], autoZIndex: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], baseZIndex: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], ariaLabel: [{
                type: Input
            }], dropdownAriaLabel: [{
                type: Input
            }], ariaLabelledBy: [{
                type: Input
            }], dropdownIcon: [{
                type: Input
            }], unique: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], group: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], completeOnFocus: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], showClear: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], field: [{
                type: Input
            }], dropdown: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], showEmptyMessage: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], dropdownMode: [{
                type: Input
            }], multiple: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], tabindex: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], dataKey: [{
                type: Input
            }], emptyMessage: [{
                type: Input
            }], showTransitionOptions: [{
                type: Input
            }], hideTransitionOptions: [{
                type: Input
            }], autofocus: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], autocomplete: [{
                type: Input
            }], optionGroupChildren: [{
                type: Input
            }], optionGroupLabel: [{
                type: Input
            }], overlayOptions: [{
                type: Input
            }], suggestions: [{
                type: Input
            }], itemSize: [{
                type: Input
            }], optionLabel: [{
                type: Input
            }], optionValue: [{
                type: Input
            }], id: [{
                type: Input
            }], searchMessage: [{
                type: Input
            }], emptySelectionMessage: [{
                type: Input
            }], selectionMessage: [{
                type: Input
            }], autoOptionFocus: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], selectOnFocus: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], searchLocale: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], optionDisabled: [{
                type: Input
            }], focusOnHover: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], typeahead: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], variant: [{
                type: Input
            }], fluid: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], completeMethod: [{
                type: Output
            }], onSelect: [{
                type: Output
            }], onUnselect: [{
                type: Output
            }], onFocus: [{
                type: Output
            }], onBlur: [{
                type: Output
            }], onDropdownClick: [{
                type: Output
            }], onClear: [{
                type: Output
            }], onKeyUp: [{
                type: Output
            }], onShow: [{
                type: Output
            }], onHide: [{
                type: Output
            }], onLazyLoad: [{
                type: Output
            }], containerEL: [{
                type: ViewChild,
                args: ['container']
            }], inputEL: [{
                type: ViewChild,
                args: ['focusInput']
            }], multiInputEl: [{
                type: ViewChild,
                args: ['multiIn']
            }], multiContainerEL: [{
                type: ViewChild,
                args: ['multiContainer']
            }], dropdownButton: [{
                type: ViewChild,
                args: ['ddBtn']
            }], itemsViewChild: [{
                type: ViewChild,
                args: ['items']
            }], scroller: [{
                type: ViewChild,
                args: ['scroller']
            }], overlayViewChild: [{
                type: ViewChild,
                args: ['overlay']
            }], itemTemplate: [{
                type: ContentChild,
                args: ['item']
            }], emptyTemplate: [{
                type: ContentChild,
                args: ['empty']
            }], headerTemplate: [{
                type: ContentChild,
                args: ['header']
            }], footerTemplate: [{
                type: ContentChild,
                args: ['footer']
            }], selectedItemTemplate: [{
                type: ContentChild,
                args: ['selecteditem']
            }], groupTemplate: [{
                type: ContentChild,
                args: ['group']
            }], loaderTemplate: [{
                type: ContentChild,
                args: ['loader']
            }], removeIconTemplate: [{
                type: ContentChild,
                args: ['removeicon']
            }], loadingIconTemplate: [{
                type: ContentChild,
                args: ['loadingicon']
            }], clearIconTemplate: [{
                type: ContentChild,
                args: ['clearicon']
            }], dropdownIconTemplate: [{
                type: ContentChild,
                args: ['dropdownicon']
            }], templates: [{
                type: ContentChildren,
                args: [PrimeTemplate]
            }] } });
class AutoCompleteModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteModule, imports: [AutoComplete], exports: [AutoComplete, SharedModule] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteModule, imports: [AutoComplete, SharedModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AutoCompleteModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [AutoComplete],
                    exports: [AutoComplete, SharedModule]
                }]
        }] });

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

export { AUTOCOMPLETE_VALUE_ACCESSOR, AutoComplete, AutoCompleteClasses, AutoCompleteModule, AutoCompleteStyle };
//# sourceMappingURL=primeng-autocomplete.mjs.map