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
1 lines • 129 kB
Source Map (JSON)
{"version":3,"file":"primeng-autocomplete.mjs","sources":["../../src/autocomplete/style/autocompletestyle.ts","../../src/autocomplete/autocomplete.ts","../../src/autocomplete/primeng-autocomplete.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BaseStyle } from 'primeng/base';\n\nconst theme = ({ dt }) => `\n.p-autocomplete {\n display: inline-flex;\n}\n\n.p-autocomplete-loader {\n position: absolute;\n top: 50%;\n margin-top: -0.5rem;\n inset-inline-end: ${dt('autocomplete.padding.x')};\n}\n\n.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-loader {\n inset-inline-end: calc(${dt('autocomplete.dropdown.width')} + ${dt('autocomplete.padding.x')});\n}\n\n.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input {\n flex: 1 1 auto;\n width: 1%;\n}\n\n.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input,\n.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-input-multiple {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n}\n\n.p-autocomplete-dropdown {\n cursor: pointer;\n display: inline-flex;\n user-select: none;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n position: relative;\n width: ${dt('autocomplete.dropdown.width')};\n border-start-end-radius: ${dt('autocomplete.dropdown.border.radius')};\n border-end-end-radius: ${dt('autocomplete.dropdown.border.radius')};\n background: ${dt('autocomplete.dropdown.background')};\n border: 1px solid ${dt('autocomplete.dropdown.border.color')};\n border-inline-start: 0 none;\n color: ${dt('autocomplete.dropdown.color')};\n 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(\n 'autocomplete.transition.duration'\n )};\n outline-color: transparent;\n}\n\n.p-autocomplete-dropdown:not(:disabled):hover {\n background: ${dt('autocomplete.dropdown.hover.background')};\n border-color: ${dt('autocomplete.dropdown.hover.border.color')};\n color: ${dt('autocomplete.dropdown.hover.color')};\n}\n\n.p-autocomplete-dropdown:not(:disabled):active {\n background: ${dt('autocomplete.dropdown.active.background')};\n border-color: ${dt('autocomplete.dropdown.active.border.color')};\n color: ${dt('autocomplete.dropdown.active.color')};\n}\n\n.p-autocomplete-dropdown:focus-visible {\n box-shadow: ${dt('autocomplete.dropdown.focus.ring.shadow')};\n outline: ${dt('autocomplete.dropdown.focus.ring.width')} ${dt('autocomplete.dropdown.focus.ring.style')} ${dt('autocomplete.dropdown.focus.ring.color')};\n outline-offset: ${dt('autocomplete.dropdown.focus.ring.offset')};\n}\n\n.p-autocomplete .p-autocomplete-overlay {\n min-width: 100%;\n}\n\n.p-autocomplete-overlay {\n background: ${dt('autocomplete.overlay.background')};\n color: ${dt('autocomplete.overlay.color')};\n border: 1px solid ${dt('autocomplete.overlay.border.color')};\n border-radius: ${dt('autocomplete.overlay.border.radius')};\n box-shadow: ${dt('autocomplete.overlay.shadow')};\n}\n\n.p-autocomplete-list-container {\n overflow: auto;\n}\n\n.p-autocomplete-list {\n margin: 0;\n list-style-type: none;\n display: flex;\n flex-direction: column;\n gap: ${dt('autocomplete.list.gap')};\n padding: ${dt('autocomplete.list.padding')};\n}\n\n.p-autocomplete-option {\n cursor: pointer;\n white-space: nowrap;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n padding: ${dt('autocomplete.option.padding')};\n border: 0 none;\n color: ${dt('autocomplete.option.color')};\n background: transparent;\n transition: background ${dt('autocomplete.transition.duration')}, color ${dt('autocomplete.transition.duration')}, border-color ${dt('autocomplete.transition.duration')};\n border-radius: ${dt('autocomplete.option.border.radius')};\n}\n\n.p-autocomplete-option:not(.p-autocomplete-option-selected):not(.p-disabled).p-focus {\n background: ${dt('autocomplete.option.focus.background')};\n color: ${dt('autocomplete.option.focus.color')};\n}\n\n.p-autocomplete-option-selected {\n background: ${dt('autocomplete.option.selected.background')};\n color: ${dt('autocomplete.option.selected.color')};\n}\n\n.p-autocomplete-option-selected.p-focus {\n background: ${dt('autocomplete.option.selected.focus.background')};\n color: ${dt('autocomplete.option.selected.focus.color')};\n}\n\n.p-autocomplete-option-group {\n margin: 0;\n padding: ${dt('autocomplete.option.group.padding')};\n color: ${dt('autocomplete.option.group.color')};\n background: ${dt('autocomplete.option.group.background')};\n font-weight: ${dt('autocomplete.option.group.font.weight')};\n}\n\n.p-autocomplete-input-multiple {\n margin: 0;\n list-style-type: none;\n cursor: text;\n overflow: hidden;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n padding: calc(${dt('autocomplete.padding.y')} / 2) ${dt('autocomplete.padding.x')};\n gap: calc(${dt('autocomplete.padding.y')} / 2);\n color: ${dt('autocomplete.color')};\n background: ${dt('autocomplete.background')};\n border: 1px solid ${dt('autocomplete.border.color')};\n border-radius: ${dt('autocomplete.border.radius')};\n width: 100%;\n 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(\n 'autocomplete.transition.duration'\n )};\n outline-color: transparent;\n box-shadow: ${dt('autocomplete.shadow')};\n}\n\n.p-autocomplete:not(.p-disabled):hover .p-autocomplete-input-multiple {\n border-color: ${dt('autocomplete.hover.border.color')};\n}\n\n.p-autocomplete:not(.p-disabled).p-focus .p-autocomplete-input-multiple {\n border-color: ${dt('autocomplete.focus.border.color')};\n box-shadow: ${dt('autocomplete.focus.ring.shadow')};\n outline: ${dt('autocomplete.focus.ring.width')} ${dt('autocomplete.focus.ring.style')} ${dt('autocomplete.focus.ring.color')};\n outline-offset: ${dt('autocomplete.focus.ring.offset')};\n}\n\n.p-autocomplete.p-invalid .p-autocomplete-input-multiple {\n border-color: ${dt('autocomplete.invalid.border.color')};\n}\n\n.p-variant-filled.p-autocomplete-input-multiple {\n background: ${dt('autocomplete.filled.background')};\n}\n\n.p-autocomplete:not(.p-disabled):hover .p-variant-filled.p-autocomplete-input-multiple {\n background: ${dt('autocomplete.filled.hover.background')};\n}\n\n.p-autocomplete:not(.p-disabled).p-focus .p-variant-filled.p-autocomplete-input-multiple {\n background: ${dt('autocomplete.filled.focus.background')};\n}\n\n.p-autocomplete.p-disabled {\n opacity: 1;\n}\n\n.p-autocomplete.p-disabled .p-autocomplete-input-multiple {\n opacity: 1;\n background: ${dt('autocomplete.disabled.background')};\n color: ${dt('autocomplete.disabled.color')};\n}\n\n.p-autocomplete-chip.p-chip {\n padding-block-start: calc(${dt('autocomplete.padding.y')} / 2);\n padding-block-end: calc(${dt('autocomplete.padding.y')} / 2);\n border-radius: ${dt('autocomplete.chip.border.radius')};\n}\n\n.p-autocomplete-input-multiple:has(.p-autocomplete-chip) {\n padding-inline-start: calc(${dt('autocomplete.padding.y')} / 2);\n padding-inline-end: calc(${dt('autocomplete.padding.y')} / 2);\n}\n\n.p-autocomplete-chip-item.p-focus .p-autocomplete-chip {\n background: ${dt('autocomplete.chip.focus.background')};\n color: ${dt('autocomplete.chip.focus.color')};\n}\n\n.p-autocomplete-input-chip {\n flex: 1 1 auto;\n display: inline-flex;\n padding-block-start: calc(${dt('autocomplete.padding.y')} / 2);\n padding-block-end: calc(${dt('autocomplete.padding.y')} / 2);\n}\n\n.p-autocomplete-input-chip input {\n border: 0 none;\n outline: 0 none;\n background: transparent;\n margin: 0;\n padding: 0;\n box-shadow: none;\n border-radius: 0;\n width: 100%;\n font-family: inherit;\n font-feature-settings: inherit;\n font-size: 1rem;\n color: inherit;\n}\n\n.p-autocomplete-input-chip input::placeholder {\n color: ${dt('autocomplete.placeholder.color')};\n}\n\n.p-autocomplete-empty-message {\n padding: ${dt('autocomplete.empty.message.padding')};\n}\n\n.p-autocomplete-fluid {\n display: flex;\n}\n\n.p-autocomplete-fluid:has(.p-autocomplete-dropdown) .p-autocomplete-input {\n width: 1%;\n}\n\n.p-autocomplete:has(.p-inputtext-sm) .p-autocomplete-dropdown {\n width: ${dt('autocomplete.dropdown.sm.width')};\n}\n\n.p-autocomplete:has(.p-inputtext-sm) .p-autocomplete-dropdown .p-icon {\n font-size: ${dt('form.field.sm.font.size')};\n width: ${dt('form.field.sm.font.size')};\n height: ${dt('form.field.sm.font.size')};\n}\n\n.p-autocomplete:has(.p-inputtext-lg) .p-autocomplete-dropdown {\n width: ${dt('autocomplete.dropdown.lg.width')};\n}\n\n.p-autocomplete:has(.p-inputtext-lg) .p-autocomplete-dropdown .p-icon {\n font-size: ${dt('form.field.lg.font.size')};\n width: ${dt('form.field.lg.font.size')};\n height: ${dt('form.field.lg.font.size')};\n}\n\n.p-autocomplete-clear-icon {\n position: absolute;\n top: 50%;\n margin-top: -0.5rem;\n cursor: pointer;\n right: ${dt('autocomplete.padding.x')};\n color: ${dt('autocomplete.dropdown.color')};\n}\n\n.p-autocomplete:has(.p-autocomplete-dropdown) .p-autocomplete-clear-icon {\n right: calc(${dt('autocomplete.padding.x')} + ${dt('autocomplete.dropdown.width')});\n}\np-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input,\np-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input-multiple,\np-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input,\np-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input-multiple\np-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input,\np-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input-multiple {\n border-color: ${dt('autocomplete.invalid.border.color')};\n}\np-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,\np-autoComplete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple,\np-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,\np-auto-complete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple,\np-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input:enabled:focus,\np-autocomplete.ng-invalid.ng-dirty:not(.p-disabled).p-focus .p-autocomplete-input-multiple {\n border-color: ${dt('autocomplete.focus.border.color')};\n}\np-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder,\np-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder,\np-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input-chip input::placeholder {\n color: ${dt('autocomplete.invalid.placeholder.color')};\n}\n\np-autoComplete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder,\np-auto-complete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder,\np-autocomplete.ng-invalid.ng-dirty .p-autocomplete-input::placeholder {\n color: ${dt('autocomplete.invalid.placeholder.color')};\n}`;\n\nconst inlineStyles = {\n root: { position: 'relative' }\n};\n\nconst classes = {\n root: ({ instance }) => ({\n 'p-autocomplete p-component p-inputwrapper': true,\n 'p-disabled': instance.disabled,\n 'p-focus': instance.focused,\n 'p-inputwrapper-filled': instance.filled,\n 'p-inputwrapper-focus': (instance.focused && !instance.disabled) || instance.autofocus || instance.overlayVisible,\n 'p-autocomplete-open': instance.overlayVisible,\n 'p-autocomplete-clearable': instance.showClear && !instance.disabled,\n // 'p-invalid': instance.invalid,\n 'p-autocomplete-fluid': instance.hasFluid\n }),\n pcInput: 'p-autocomplete-input',\n inputMultiple: ({ instance }) => ({\n 'p-autocomplete-input-multiple': true,\n 'p-variant-filled': (instance.variant ?? (instance.config.inputStyle() || instance.config.inputVariant())) === 'filled'\n }),\n chipItem: ({ instance, i }) => [\n 'p-autocomplete-chip-item',\n {\n 'p-focus': instance.focusedMultipleOptionIndex === i\n }\n ],\n pcChip: 'p-autocomplete-chip',\n chipIcon: 'p-autocomplete-chip-icon',\n inputChip: 'p-autocomplete-input-chip',\n loader: 'p-autocomplete-loader',\n dropdown: 'p-autocomplete-dropdown',\n overlay: 'p-autocomplete-overlay p-component',\n list: 'p-autocomplete-list',\n optionGroup: 'p-autocomplete-option-group',\n option: ({ instance, option, i, getItemOptions }) => ({\n 'p-autocomplete-option': true,\n 'p-autocomplete-option-selected': instance.isSelected(option),\n 'p-focus': instance.focusedOptionIndex === instance.getOptionIndex(i, getItemOptions),\n 'p-disabled': instance.isOptionDisabled(option)\n }),\n emptyMessage: 'p-autocomplete-empty-message'\n};\n\n@Injectable()\nexport class AutoCompleteStyle extends BaseStyle {\n name = 'autocomplete';\n\n theme = theme;\n\n classes = classes;\n\n inlineStyles = inlineStyles;\n}\n\n/**\n *\n * AutoComplete is an input component that provides real-time suggestions while being typed.\n *\n * [Live Demo](https://www.primeng.org/autocomplete/)\n *\n * @module autocompletestyle\n *\n */\nexport enum AutoCompleteClasses {\n /**\n * Class name of the root element\n */\n root = 'p-autocomplete',\n /**\n * Class name of the input element\n */\n pcInput = 'p-autocomplete-input',\n /**\n * Class name of the input multiple element\n */\n inputMultiple = 'p-autocomplete-input-multiple',\n /**\n * Class name of the chip item element\n */\n chipItem = 'p-autocomplete-chip-item',\n /**\n * Class name of the chip element\n */\n pcChip = 'p-autocomplete-chip',\n /**\n * Class name of the chip icon element\n */\n chipIcon = 'p-autocomplete-chip-icon',\n /**\n * Class name of the input chip element\n */\n inputChip = 'p-autocomplete-input-chip',\n /**\n * Class name of the loader element\n */\n loader = 'p-autocomplete-loader',\n /**\n * Class name of the dropdown element\n */\n dropdown = 'p-autocomplete-dropdown',\n /**\n * Class name of the panel element\n */\n panel = 'p-autocomplete-overlay',\n /**\n * Class name of the list element\n */\n list = 'p-autocomplete-list',\n /**\n * Class name of the option group element\n */\n optionGroup = 'p-autocomplete-option-group',\n /**\n * Class name of the option element\n */\n option = 'p-autocomplete-option',\n /**\n * Class name of the empty message element\n */\n emptyMessage = 'p-autocomplete-empty-message'\n}\n\nexport interface AutoCompleteStyle extends BaseStyle {}\n","import { AnimationEvent } from '@angular/animations';\nimport { CommonModule } from '@angular/common';\nimport {\n AfterContentInit,\n AfterViewChecked,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChild,\n ContentChildren,\n effect,\n ElementRef,\n EventEmitter,\n forwardRef,\n inject,\n Input,\n NgModule,\n NgZone,\n numberAttribute,\n OnDestroy,\n Output,\n QueryList,\n signal,\n TemplateRef,\n ViewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { equals, findLastIndex, findSingle, focus, isEmpty, isNotEmpty, resolveFieldData, uuid } from '@primeuix/utils';\nimport { OverlayOptions, OverlayService, PrimeTemplate, ScrollerOptions, SharedModule, TranslationKeys } from 'primeng/api';\nimport { AutoFocus } from 'primeng/autofocus';\nimport { BaseComponent } from 'primeng/basecomponent';\nimport { Chip } from 'primeng/chip';\nimport { PrimeNG } from 'primeng/config';\nimport { ConnectedOverlayScrollHandler } from 'primeng/dom';\nimport { ChevronDownIcon, SpinnerIcon, TimesCircleIcon, TimesIcon } from 'primeng/icons';\nimport { InputText } from 'primeng/inputtext';\nimport { Overlay } from 'primeng/overlay';\nimport { Ripple } from 'primeng/ripple';\nimport { Scroller } from 'primeng/scroller';\nimport { Nullable } from 'primeng/ts-helpers';\nimport { AutoCompleteCompleteEvent, AutoCompleteDropdownClickEvent, AutoCompleteLazyLoadEvent, AutoCompleteSelectEvent, AutoCompleteUnselectEvent } from './autocomplete.interface';\nimport { AutoCompleteStyle } from './style/autocompletestyle';\n\nexport const AUTOCOMPLETE_VALUE_ACCESSOR: any = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => AutoComplete),\n multi: true\n};\n/**\n * AutoComplete is an input component that provides real-time suggestions when being typed.\n * @group Components\n */\n@Component({\n selector: 'p-autoComplete, p-autocomplete, p-auto-complete',\n standalone: true,\n imports: [CommonModule, Overlay, InputText, Ripple, Scroller, AutoFocus, TimesCircleIcon, SpinnerIcon, TimesIcon, ChevronDownIcon, Chip, SharedModule],\n template: `\n <div #container [ngClass]=\"rootClass\" [ngStyle]=\"style\" style=\"position: relative;\" [class]=\"styleClass\" (click)=\"onContainerClick($event)\">\n <input\n *ngIf=\"!multiple\"\n #focusInput\n [pAutoFocus]=\"autofocus\"\n pInputText\n [ngClass]=\"'p-autocomplete-input'\"\n [ngStyle]=\"inputStyle\"\n [class]=\"inputStyleClass\"\n [type]=\"type\"\n [attr.value]=\"inputValue()\"\n [variant]=\"variant\"\n [attr.id]=\"inputId\"\n [autocomplete]=\"autocomplete\"\n [required]=\"required\"\n [name]=\"name\"\n aria-autocomplete=\"list\"\n role=\"combobox\"\n [attr.placeholder]=\"placeholder\"\n [pSize]=\"size\"\n [attr.maxlength]=\"maxlength\"\n [tabindex]=\"!disabled ? tabindex : -1\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-required]=\"required\"\n [attr.aria-expanded]=\"overlayVisible ?? false\"\n [attr.aria-controls]=\"overlayVisible ? id + '_list' : null\"\n [attr.aria-activedescendant]=\"focused ? focusedOptionId : undefined\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (change)=\"onInputChange($event)\"\n (focus)=\"onInputFocus($event)\"\n (blur)=\"onInputBlur($event)\"\n (paste)=\"onInputPaste($event)\"\n (keyup)=\"onInputKeyUp($event)\"\n [fluid]=\"hasFluid\"\n />\n <ng-container *ngIf=\"filled && !disabled && showClear && !loading\">\n <TimesIcon *ngIf=\"!clearIconTemplate && !_clearIconTemplate\" [styleClass]=\"'p-autocomplete-clear-icon'\" (click)=\"clear()\" [attr.aria-hidden]=\"true\" />\n <span *ngIf=\"clearIconTemplate || _clearIconTemplate\" class=\"p-autocomplete-clear-icon\" (click)=\"clear()\" [attr.aria-hidden]=\"true\">\n <ng-template *ngTemplateOutlet=\"clearIconTemplate || _clearIconTemplate\"></ng-template>\n </span>\n </ng-container>\n\n <ul\n *ngIf=\"multiple\"\n #multiContainer\n [ngClass]=\"inputMultipleClass\"\n [tabindex]=\"-1\"\n role=\"listbox\"\n [attr.aria-orientation]=\"'horizontal'\"\n [attr.aria-activedescendant]=\"focused ? focusedMultipleOptionId : undefined\"\n (focus)=\"onMultipleContainerFocus($event)\"\n (blur)=\"onMultipleContainerBlur($event)\"\n (keydown)=\"onMultipleContainerKeyDown($event)\"\n >\n <li\n #token\n *ngFor=\"let option of modelValue(); let i = index\"\n [ngClass]=\"{ 'p-autocomplete-chip-item': true, 'p-focus': focusedMultipleOptionIndex() === i }\"\n [attr.id]=\"id + '_multiple_option_' + i\"\n role=\"option\"\n [attr.aria-label]=\"getOptionLabel(option)\"\n [attr.aria-setsize]=\"modelValue().length\"\n [attr.aria-posinset]=\"i + 1\"\n [attr.aria-selected]=\"true\"\n >\n <ng-container *ngTemplateOutlet=\"selectedItemTemplate || _selectedItemTemplate; context: { $implicit: option }\"></ng-container>\n <p-chip styleClass=\"p-autocomplete-chip\" *ngIf=\"!selectedItemTemplate && !_selectedItemTemplate\" [label]=\"getOptionLabel(option)\" [removable]=\"true\" (onRemove)=\"!readonly ? removeOption($event, i) : ''\">\n <ng-container *ngIf=\"!removeIconTemplate && !_removeIconTemplate\">\n <ng-template #removeicon>\n <span class=\"p-autocomplete-chip-icon\" (click)=\"!readonly ? removeOption($event, i) : ''\">\n <TimesCircleIcon [styleClass]=\"'p-autocomplete-chip-icon'\" [attr.aria-hidden]=\"true\" />\n </span>\n </ng-template>\n </ng-container>\n </p-chip>\n <span *ngIf=\"removeIconTemplate || _removeIconTemplate\">\n <ng-template *ngTemplateOutlet=\"removeIconTemplate || _removeIconTemplate; context: { class: 'p-autocomplete-chip-icon', removeCallback: removeOption.bind(this), index: i }\"></ng-template>\n </span>\n </li>\n <li class=\"p-autocomplete-input-chip\" role=\"option\">\n <input\n #focusInput\n [pAutoFocus]=\"autofocus\"\n [ngClass]=\"inputClass\"\n [ngStyle]=\"inputStyle\"\n [class]=\"inputStyleClass\"\n [attr.type]=\"type\"\n [attr.id]=\"inputId\"\n [autocomplete]=\"autocomplete\"\n [required]=\"required\"\n [attr.name]=\"name\"\n role=\"combobox\"\n [attr.placeholder]=\"!filled ? placeholder : null\"\n aria-autocomplete=\"list\"\n [attr.maxlength]=\"maxlength\"\n [tabindex]=\"!disabled ? tabindex : -1\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-required]=\"required\"\n [attr.aria-expanded]=\"overlayVisible ?? false\"\n [attr.aria-controls]=\"overlayVisible ? id + '_list' : null\"\n [attr.aria-activedescendant]=\"focused ? focusedOptionId : undefined\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (change)=\"onInputChange($event)\"\n (focus)=\"onInputFocus($event)\"\n (blur)=\"onInputBlur($event)\"\n (paste)=\"onInputPaste($event)\"\n (keyup)=\"onInputKeyUp($event)\"\n />\n </li>\n </ul>\n <ng-container *ngIf=\"loading\">\n <SpinnerIcon *ngIf=\"!loadingIconTemplate && !_loadingIconTemplate\" [styleClass]=\"'p-autocomplete-loader'\" [spin]=\"true\" [attr.aria-hidden]=\"true\" />\n <span *ngIf=\"loadingIconTemplate || _loadingIconTemplate\" class=\"p-autocomplete-loader pi-spin \" [attr.aria-hidden]=\"true\">\n <ng-template *ngTemplateOutlet=\"loadingIconTemplate || _loadingIconTemplate\"></ng-template>\n </span>\n </ng-container>\n <button #ddBtn type=\"button\" [attr.aria-label]=\"dropdownAriaLabel\" class=\"p-autocomplete-dropdown\" [disabled]=\"disabled\" pRipple (click)=\"handleDropdownClick($event)\" *ngIf=\"dropdown\" [attr.tabindex]=\"tabindex\">\n <span *ngIf=\"dropdownIcon\" [ngClass]=\"dropdownIcon\" [attr.aria-hidden]=\"true\"></span>\n <ng-container *ngIf=\"!dropdownIcon\">\n <ChevronDownIcon *ngIf=\"!dropdownIconTemplate && !_dropdownIconTemplate\" />\n <ng-template *ngTemplateOutlet=\"dropdownIconTemplate || _dropdownIconTemplate\"></ng-template>\n </ng-container>\n </button>\n <p-overlay\n #overlay\n [(visible)]=\"overlayVisible\"\n [options]=\"overlayOptions\"\n [target]=\"'@parent'\"\n [appendTo]=\"appendTo\"\n [showTransitionOptions]=\"showTransitionOptions\"\n [hideTransitionOptions]=\"hideTransitionOptions\"\n (onAnimationStart)=\"onOverlayAnimationStart($event)\"\n (onHide)=\"hide()\"\n >\n <ng-template #content>\n <div [ngClass]=\"panelClass\" [ngStyle]=\"panelStyle\" [class]=\"panelStyleClass\">\n <ng-container *ngTemplateOutlet=\"headerTemplate || _headerTemplate\"></ng-container>\n <div class=\"p-autocomplete-list-container\" [style.max-height]=\"virtualScroll ? 'auto' : scrollHeight\">\n <p-scroller\n *ngIf=\"virtualScroll\"\n #scroller\n [items]=\"visibleOptions()\"\n [style]=\"{ height: scrollHeight }\"\n [itemSize]=\"virtualScrollItemSize || _itemSize\"\n [autoSize]=\"true\"\n [lazy]=\"lazy\"\n (onLazyLoad)=\"onLazyLoad.emit($event)\"\n [options]=\"virtualScrollOptions\"\n >\n <ng-template #content let-items let-scrollerOptions=\"options\">\n <ng-container *ngTemplateOutlet=\"buildInItems; context: { $implicit: items, options: scrollerOptions }\"></ng-container>\n </ng-template>\n <ng-container *ngIf=\"loaderTemplate || _loaderTemplate\">\n <ng-template #loader let-scrollerOptions=\"options\">\n <ng-container *ngTemplateOutlet=\"loaderTemplate || _loaderTemplate; context: { options: scrollerOptions }\"></ng-container>\n </ng-template>\n </ng-container>\n </p-scroller>\n <ng-container *ngIf=\"!virtualScroll\">\n <ng-container *ngTemplateOutlet=\"buildInItems; context: { $implicit: visibleOptions(), options: {} }\"></ng-container>\n </ng-container>\n </div>\n\n <ng-template #buildInItems let-items let-scrollerOptions=\"options\">\n <ul #items class=\"p-autocomplete-list\" [ngClass]=\"scrollerOptions.contentStyleClass\" [style]=\"scrollerOptions.contentStyle\" role=\"listbox\" [attr.id]=\"id + '_list'\" [attr.aria-label]=\"listLabel\">\n <ng-template ngFor let-option [ngForOf]=\"items\" let-i=\"index\">\n <ng-container *ngIf=\"isOptionGroup(option)\">\n <li [attr.id]=\"id + '_' + getOptionIndex(i, scrollerOptions)\" class=\"p-autocomplete-option-group\" [ngStyle]=\"{ height: scrollerOptions.itemSize + 'px' }\" role=\"option\">\n <span *ngIf=\"!groupTemplate\">{{ getOptionGroupLabel(option.optionGroup) }}</span>\n <ng-container *ngTemplateOutlet=\"groupTemplate; context: { $implicit: option.optionGroup }\"></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"!isOptionGroup(option)\">\n <li\n pRipple\n [ngStyle]=\"{ height: scrollerOptions.itemSize + 'px' }\"\n [ngClass]=\"optionClass(option, i, scrollerOptions)\"\n [attr.id]=\"id + '_' + getOptionIndex(i, scrollerOptions)\"\n role=\"option\"\n [attr.aria-label]=\"getOptionLabel(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isOptionDisabled(option)\"\n [attr.data-p-focused]=\"focusedOptionIndex() === getOptionIndex(i, scrollerOptions)\"\n [attr.aria-setsize]=\"ariaSetSize\"\n [attr.aria-posinset]=\"getAriaPosInset(getOptionIndex(i, scrollerOptions))\"\n (click)=\"onOptionSelect($event, option)\"\n (mouseenter)=\"onOptionMouseEnter($event, getOptionIndex(i, scrollerOptions))\"\n >\n <span *ngIf=\"!itemTemplate && !_itemTemplate\">{{ getOptionLabel(option) }}</span>\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || _itemTemplate;\n context: {\n $implicit: option,\n index: scrollerOptions.getOptions ? scrollerOptions.getOptions(i) : i\n }\n \"\n ></ng-container>\n </li>\n </ng-container>\n </ng-template>\n <li *ngIf=\"!items || (items && items.length === 0 && showEmptyMessage)\" class=\"p-autocomplete-empty-message\" [ngStyle]=\"{ height: scrollerOptions.itemSize + 'px' }\" role=\"option\">\n <ng-container *ngIf=\"!emptyTemplate && !_emptyTemplate; else empty\">\n {{ searchResultMessageText }}\n </ng-container>\n <ng-container #empty *ngTemplateOutlet=\"emptyTemplate || _emptyTemplate\"></ng-container>\n </li>\n </ul>\n </ng-template>\n <ng-container *ngTemplateOutlet=\"footerTemplate || _footerTemplate\"></ng-container>\n </div>\n <span role=\"status\" aria-live=\"polite\" class=\"p-hidden-accessible\">\n {{ selectedMessageText }}\n </span>\n </ng-template>\n </p-overlay>\n </div>\n `,\n providers: [AUTOCOMPLETE_VALUE_ACCESSOR, AutoCompleteStyle],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class AutoComplete extends BaseComponent implements AfterViewChecked, AfterContentInit, OnDestroy, ControlValueAccessor {\n /**\n * Minimum number of characters to initiate a search.\n * @group Props\n */\n @Input({ transform: numberAttribute }) minLength: number = 1;\n /**\n * Delay between keystrokes to wait before sending a query.\n * @group Props\n */\n @Input({ transform: numberAttribute }) delay: number = 300;\n /**\n * Inline style of the component.\n * @group Props\n */\n @Input() style: { [klass: string]: any } | null | undefined;\n /**\n * Inline style of the overlay panel element.\n * @group Props\n */\n @Input() panelStyle: { [klass: string]: any } | null | undefined;\n /**\n * Style class of the component.\n * @group Props\n */\n @Input() styleClass: string | undefined;\n /**\n * Style class of the overlay panel element.\n * @group Props\n */\n @Input() panelStyleClass: string | undefined;\n /**\n * Inline style of the input field.\n * @group Props\n */\n @Input() inputStyle: { [klass: string]: any } | null | undefined;\n /**\n * Identifier of the focus input to match a label defined for the component.\n * @group Props\n */\n @Input() inputId: string | undefined;\n /**\n * Inline style of the input field.\n * @group Props\n */\n @Input() inputStyleClass: string | undefined;\n /**\n * Hint text for the input field.\n * @group Props\n */\n @Input() placeholder: string | undefined;\n /**\n * When present, it specifies that the input cannot be typed.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) readonly: boolean | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) disabled: boolean | undefined;\n /**\n * Maximum height of the suggestions panel.\n * @group Props\n */\n @Input() scrollHeight: string = '200px';\n /**\n * Defines if data is loaded and interacted with in lazy manner.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) lazy: boolean = false;\n /**\n * Whether the data should be loaded on demand during scroll.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) virtualScroll: boolean | undefined;\n /**\n * Height of an item in the list for VirtualScrolling.\n * @group Props\n */\n @Input({ transform: numberAttribute }) virtualScrollItemSize: number | undefined;\n /**\n * Whether to use the scroller feature. The properties of scroller component can be used like an object in it.\n * @group Props\n */\n @Input() virtualScrollOptions: ScrollerOptions | undefined;\n /**\n * Maximum number of character allows in the input field.\n * @group Props\n */\n @Input({ transform: (value: unknown) => numberAttribute(value, null) }) maxlength: number | undefined;\n /**\n * Name of the input element.\n * @group Props\n */\n @Input() name: string | undefined;\n /**\n * When present, it specifies that an input field must be filled out before submitting the form.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) required: boolean | undefined;\n /**\n * Defines the size of the component.\n * @group Props\n */\n @Input() size: 'large' | 'small';\n /**\n * 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).\n * @group Props\n */\n @Input() appendTo: HTMLElement | ElementRef | TemplateRef<any> | string | null | undefined | any;\n /**\n * When enabled, highlights the first item in the list by default.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) autoHighlight: boolean | undefined;\n /**\n * When present, autocomplete clears the manual input if it does not match of the suggestions to force only accepting values from the suggestions.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) forceSelection: boolean | undefined;\n /**\n * Type of the input, defaults to \"text\".\n * @group Props\n */\n @Input() type: string = 'text';\n /**\n * Whether to automatically manage layering.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) autoZIndex: boolean = true;\n /**\n * Base zIndex value to use in layering.\n * @group Props\n */\n @Input({ transform: numberAttribute }) baseZIndex: number = 0;\n /**\n * Defines a string that labels the input for accessibility.\n * @group Props\n */\n @Input() ariaLabel: string | undefined;\n /**\n * Defines a string that labels the dropdown button for accessibility.\n * @group Props\n */\n @Input() dropdownAriaLabel: string | undefined;\n /**\n * Specifies one or more IDs in the DOM that labels the input field.\n * @group Props\n */\n @Input() ariaLabelledBy: string | undefined;\n /**\n * Icon class of the dropdown icon.\n * @group Props\n */\n @Input() dropdownIcon: string | undefined;\n /**\n * Ensures uniqueness of selected items on multiple mode.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) unique: boolean = true;\n /**\n * Whether to display options as grouped when nested options are provided.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) group: boolean | undefined;\n /**\n * Whether to run a query when input receives focus.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) completeOnFocus: boolean = false;\n /**\n * When enabled, a clear icon is displayed to clear the value.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) showClear: boolean = false;\n /**\n * Field of a suggested object to resolve and display.\n * @group Props\n * @deprecated use optionLabel property instead\n */\n @Input() field: string | undefined;\n /**\n * Displays a button next to the input field when enabled.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) dropdown: boolean | undefined;\n /**\n * Whether to show the empty message or not.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) showEmptyMessage: boolean | undefined = true;\n /**\n * Specifies the behavior dropdown button. Default \"blank\" mode sends an empty string and \"current\" mode sends the input value.\n * @group Props\n */\n @Input() dropdownMode: string = 'blank';\n /**\n * Specifies if multiple values can be selected.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) multiple: boolean | undefined;\n /**\n * Index of the element in tabbing order.\n * @group Props\n */\n @Input({ transform: numberAttribute }) tabindex: number | undefined;\n /**\n * A property to uniquely identify a value in options.\n * @group Props\n */\n @Input() dataKey: string | undefined;\n /**\n * Text to display when there is no data. Defaults to global value in i18n translation configuration.\n * @group Props\n */\n @Input() emptyMessage: string | undefined;\n /**\n * Transition options of the show animation.\n * @group Props\n */\n @Input() showTransitionOptions: string = '.12s cubic-bezier(0, 0, 0.2, 1)';\n /**\n * Transition options of the hide animation.\n * @group Props\n */\n @Input() hideTransitionOptions: string = '.1s linear';\n /**\n * When present, it specifies that the component should automatically get focus on load.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) autofocus: boolean | undefined;\n /**\n * Used to define a string that autocomplete attribute the current element.\n * @group Props\n */\n @Input() autocomplete: string = 'off';\n /**\n * Name of the options field of an option group.\n * @group Props\n */\n @Input() optionGroupChildren: string | undefined = 'items';\n /**\n * Name of the label field of an option group.\n * @group Props\n */\n @Input() optionGroupLabel: string | undefined = 'label';\n /**\n * Options for the overlay element.\n * @group Props\n */\n @Input() overlayOptions: OverlayOptions | undefined;\n /**\n * An array of suggestions to display.\n * @group Props\n */\n @Input() get suggestions(): any[] {\n return this._suggestions();\n }\n set suggestions(value: any[]) {\n this._suggestions.set(value);\n this.handleSuggestionsChange();\n }\n /**\n * Element dimensions of option for virtual scrolling.\n * @group Props\n * @deprecated use virtualScrollItemSize property instead.\n */\n @Input() get itemSize(): number {\n return this._itemSize as number;\n }\n set itemSize(val: number) {\n this._itemSize = val;\n console.log('The itemSize property is deprecated, use virtualScrollItemSize property instead.');\n }\n /**\n * Property name or getter function to use as the label of an option.\n * @group Props\n */\n @Input() optionLabel: string | ((item: any) => string) | undefined;\n /**\n * Property name or getter function to use as the value of an option.\n * @group Props\n */\n @Input() optionValue: string | ((item: any) => string) | undefined;\n /**\n * Unique identifier of the component.\n * @group Props\n */\n @Input() id: string | undefined;\n /**\n * Text to display when the search is active. Defaults to global value in i18n translation configuration.\n * @group Props\n * @defaultValue '{0} results are available'\n */\n @Input() searchMessage: string | undefined;\n /**\n * Text to display when filtering does not return any results. Defaults to global value in i18n translation configuration.\n * @group Props\n * @defaultValue 'No selected item'\n */\n @Input() emptySelectionMessage: string | undefined;\n /**\n * Text to be displayed in hidden accessible field when options are selected. Defaults to global value in i18n translation configuration.\n * @group Props\n * @defaultValue '{0} items selected'\n */\n @Input() selectionMessage: string | undefined;\n /**\n * Whether to focus on the first visible or selected element when the overlay panel is shown.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) autoOptionFocus: boolean | undefined = false;\n /**\n * When enabled, the focused option is selected.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) selectOnFocus: boolean | undefined;\n /**\n * Locale to use in searching. The default locale is the host environment's current locale.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) searchLocale: boolean | undefined;\n /**\n * Property name or getter function to use as the disabled flag of an option, defaults to false when not defined.\n * @group Props\n */\n @Input() optionDisabled: string | ((item: any) => string) | undefined;\n /**\n * When enabled, the hovered option will be focused.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) focusOnHover: boolean | undefined = true;\n /**\n * Whether typeahead is active or not.\n * @defaultValue true\n * @group Props\n */\n @Input({ transform: booleanAttribute }) typeahead: boolean = true;\n /**\n * Specifies the input variant of the component.\n * @group Props\n */\n @Input() variant: 'filled' | 'outlined';\n /**\n * Spans 100% width of the container when enabled.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) fluid: boolean = false;\n /**\n * Callback to invoke to search for suggestions.\n * @param {AutoCompleteCompleteEvent} event - Custom complete event.\n * @group Emits\n */\n @Output() completeMethod: EventEmitter<AutoCompleteCompleteEvent> = new EventEmitter<AutoCompleteCompleteEvent>();\n /**\n * Callback to invoke when a suggestion is selected.\n * @param {AutoCompleteSelectEvent} event - custom select event.\n * @group Emits\n */\n @Output() onSelect: EventEmitter<AutoCompleteSelectEvent> = new EventEmitter<AutoCompleteSelectEvent>();\n /**\n * Callback to invoke when a selected value is removed.\n * @param {AutoCompleteUnselectEvent} event - custom unselect event.\n * @group Emits\n */\n @Output() onUnselect: EventEmitter<AutoCompleteUnselectEvent> = new EventEmitter<AutoCompleteUnselectEvent>();\n /**\n * Callback to invoke when the component receives focus.\n * @param {Event} event - Browser event.\n * @group Emits\n */\n @Output() onFocus: EventEmitter<Event> = new EventEmitter();\n /**\n * Callback to invoke when the component loses focus.\n * @param {Event} event - Browser event.\n * @group Emits\n */\n @Output() onBlur: EventEmitter<Event> = new EventEmitter();\n /**\n * Callback to invoke to when dropdown button is clicked.\n * @param {AutoCompleteDropdownClickEvent} event - custom dropdown click event.\n * @group Emits\n */\n @Output() onDropdownClick: EventEmitter<AutoCompleteDropdownClickEvent> = new EventEmitter<AutoCompleteDropdownClickEvent>();\n /**\n * Callback to invoke when clear button is clicked.\n * @param {Event} event - Browser event.\n * @group Emits\n */\n @Output() onClear: EventEmitter<Event | undefined> = new EventEmitter<Event | undefined>();\n /**\n * Callback to invoke on input key up.\n * @param {KeyboardEvent} event - Keyboard event.\n * @group Emits\n */\n @Output() onKeyUp: EventEmitter<KeyboardEvent> = new EventEmitter();\n /**\n * Callback to invoke on overlay is shown.\n * @param {Event} event - Browser event.\n * @group Emits\n */\n @Output() onShow: EventEmitter<Event> = new EventEmitter<Event>();\n /**\n * Callback to invoke on overlay is hidden.\n * @param {Event} event - Browser event.\n * @group Emits\n */\n @Output() onHide: EventEmitter<Event> = new EventEmitter<Event>();\n /**\n * Callback to invoke on lazy load data.\n * @param {AutoCompleteLazyLoadEvent} event - Lazy load event.\n * @group Emits\n */\n @Output() onLazyLoad: EventEmitter<AutoCompleteLazyLoadEvent> = new EventEmitter<AutoCompleteLazyLoadEvent>();\n\n @ViewChild('container') containerEL: Nullable<ElementRef>;\n\n @ViewChild('focusInput') inputEL: Nullable<ElementRef>;\n\n @ViewChild('multiIn') multiInputEl: Nullable<ElementRef>;\n\n @ViewChild('multiContainer') multiContainerEL: Nullable<ElementRef>;\n\n @ViewChild('ddBtn') dropdownButton: Nullable<ElementRef>;\n\n @ViewChild('items') itemsViewChild: Nullable<ElementRef>;\n\n @ViewChild('scroller') scroller: Nullable<Scroller>;\n\n @ViewChild('overlay') overlayViewChild!: Overlay;\n\n _itemSize: Nullable<number>;\n\n itemsWrapper: Nullable<HTMLDivElement>;\n\n /**\n * Custom item template.\n * @group Templates\n */\n @ContentChild('item') itemTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom empty message template.\n * @group Templates\n */\n @ContentChild('empty') emptyTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom header template.\n * @group Templates\n */\n @ContentChild('header') headerTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom footer template.\n * @group Templates\n */\n @ContentChild('footer') footerTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom selected item template.\n * @group Templates\n */\n @ContentChild('selecteditem') selectedItemTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom group item template.\n * @group Templates\n */\n @ContentChild('group') groupTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom loader template.\n * @group Templates\n */\n @ContentChild('loader') loaderTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom remove icon template.\n * @group Templates\n */\n @ContentChild('removeicon') removeIconTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom loading icon template.\n * @group Templates\n */\n @ContentChild('loadingicon') loadingIconTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom clear icon template.\n * @group Templates\n */\n @ContentChild('clearicon') clearIconTemplate: Nullable<TemplateRef<any>>;\n\n /**\n * Custom dropdown icon template.\n