UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

817 lines 109 kB
/** * Copyright (c) 2025 Visa, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ContentChild, ContentChildren, Directive, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, QueryList, Renderer2 } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { AppReadyService } from '../_utilities/services/app-stable-check.service'; import { UUIDService } from '../_utilities/services/uuid.service'; import { FloatingUIContainer } from '../floating-ui-container/floating-ui-container.directive'; import { InputContainerComponent } from '../input-container/input-container.component'; import { InputDirective } from '../input/input.directive'; import { LabelDirective } from '../label/label.directive'; import { ListboxContainerDirective } from '../listbox-container/listbox-container.directive'; import { ListboxDirective } from '../listbox/listbox.directive'; import { ListboxService } from '../listbox/listbox.service'; import { BACKSPACE_KEY, DOWN_ARROW_KEY, ENTER_KEY, LEFT_ARROW_KEY, RIGHT_ARROW_KEY, TAB_KEY, UP_ARROW_KEY } from '../nova-lib.constants'; import { NovaLibService } from '../nova-lib.service'; import { ComboboxFilterType } from './combobox.constants'; import { ButtonDirective } from '../button/button.directive'; import { ChipDirective } from '../chip/chip.directive'; import * as i0 from "@angular/core"; import * as i1 from "../nova-lib.service"; import * as i2 from "../listbox/listbox.service"; import * as i3 from "../_utilities/services/app-stable-check.service"; import * as i4 from "../_utilities/services/uuid.service"; import * as i5 from "../floating-ui-container/floating-ui-container.directive"; var STATE; (function (STATE) { STATE["READONLY"] = "readonly"; STATE["DISABLED"] = "disabled"; STATE["INVALID"] = "invalid"; STATE["REQUIRED"] = "required"; })(STATE || (STATE = {})); export class ComboboxDirective { /** * Provides custom class&#40;es&#41; for custom styling. * @default .v-combobox */ get class() { return [this._class, 'v-combobox'].join(' '); } set class(value) { this._class = value; } get hostClass() { return this.class; } /** * Removes appended screenreader readonly text when true. <br> * By default &#40;when <code>removeReadonlyText="false"</code>&#41;, if a combobox is readonly, a span element with text '&#40;readonly&#41;' will be appended to the label element for screenreader support. * @default false */ get removeReadonlyText() { return this._removeReadonlyText; } set removeReadonlyText(value) { this._removeReadonlyText = coerceBooleanProperty(value); } /** * Temporary prop to opt into new **multiselect** behavior. <br> * Will be deprecated and defaulted to in the next breaking change release. */ get EXPERIMENTAL_ADA_OPT_IN() { return this._EXPERIMENTAL_ADA_OPT_IN; } set EXPERIMENTAL_ADA_OPT_IN(value) { this._EXPERIMENTAL_ADA_OPT_IN = coerceBooleanProperty(value); } /** * Sets component as readonly when true. * @default false */ get readonly() { return this._readonly; } set readonly(value) { this._readonly = coerceBooleanProperty(value); if (!this.removeReadonlyText) this.appendReadonlyText(); this.updateChildrenStates(STATE.READONLY); } /** * Sets component as disabled when true. * @default false */ get disabled() { return this._disabled; } set disabled(value) { this._disabled = coerceBooleanProperty(value); this.updateChildrenStates(STATE.DISABLED); } get hostDisabled() { return this.disabled ? 'disabled' : null; } /** Fires when a formControl's disabled state updates */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * Marks component as invalid when true. * @default false */ get invalid() { return this._invalid; } set invalid(value) { this._invalid = coerceBooleanProperty(value); this.updateChildrenStates(STATE.INVALID); } get ariaInvalid() { return this.invalid; } /** * Marks component as required when true. * @default false */ get required() { return this._required; } set required(value) { this._required = coerceBooleanProperty(value); this.updateChildrenStates(STATE.REQUIRED); } /** * Value of combobox. */ get value() { return this._value; } set value(value) { this.updateValue(value); } // keep val for backwards compatibility get val() { return this._value; } set val(value) { this.updateValue(value); } updateValue(value) { this._value = value; if (this.input && this.listbox) { if (value && !this._fromInput && ((value['label'] && this.input.value !== value['label']) || (value['value'] && this.listbox.value !== value['value']))) { const selectIndex = this.getList()?.findIndex((item) => item.value === value['value']); if (selectIndex != -1) { this.selectItem(selectIndex); } else { // deselect also reset aria active descendant if (this._activeIndex) { this.novaLibService.deselectItem(this.getList(), this._activeIndex, 'active'); this._activeIndex = null; if (this.input) this.input.ariaActiveDescendant = null; if (this.listbox) this.listbox.ariaActiveDescendant.set(null); } } } else if (!value) { this.clearCombobox(); } } this.onChange(value); } constructor(novaLibService, listboxService, appReadyService, renderer, UUIDService, floatingContainer) { this.novaLibService = novaLibService; this.listboxService = listboxService; this.appReadyService = appReadyService; this.renderer = renderer; this.UUIDService = UUIDService; this.floatingContainer = floatingContainer; this._highlightedIndex = null; this._activeIndex = null; this._fromInput = false; this._inputFocused = false; this._class = ''; this._removeReadonlyText = false; this._EXPERIMENTAL_ADA_OPT_IN = false; this._readonly = false; this._disabled = false; this._invalid = false; this._required = false; this._value = null; /** * Emits value of selected item(s). */ this.itemSelected = new EventEmitter(); /** * Emitted when a listbox item is selected, when an input value is entered, and when the combobox is reset. <br /> * Subscribe to provide your own filter function when this event is emitted. <br /> * Emits { type: 'selection' | 'input' | 'reset'; listbox: string; input: string } where type is the type of filter event, listbox is the value of the selected item(s), and input is the value of the input. */ this.filter = new EventEmitter(); /** * Emits the filtered array of ListboxItemComponents when the list is filtered by ComboboxService. */ this.filteredListEmitter = new EventEmitter(); this.onChange = (_) => { }; this.onTouched = (_) => { }; } handleFocus(event) { this.onTouched(event); } ngOnInit() { if (this.floatingContainer) { this.floatingContainer._isCombobox = true; if (!this.floatingContainer.eventsArray) { this.floatingContainer.eventsArray = []; } } } ngAfterContentInit() { if (this.input) { this.setUpInput(); } if (this.listbox) { if (!this.listbox.multiselect) { this.listbox.value = ''; } this.initialListItems = this.listbox.listItems.toArray(); this.currentListItems = this.listbox.listItems; this.setUpListItems(); this.listbox.listItems.changes.subscribe(() => { if (!this.listbox.multiselect) { // remove previous subscription this.listboxSubscription.unsubscribe(); this.setUpListItems(); } }); } if (this.inputContainer?.buttons.length > 0 && this.floatingContainer) { // last button should be toggle button this.inputContainer.buttons.last._inCombobox = true; this.inputContainer.buttons.last.clicked.subscribe(() => { this.input?.el.nativeElement.focus(); this.floatingContainer?.floatingUIService.toggleFloatingUI(); }); } if (this.floatingContainer) { this.setUpFloatingContainer(); } if (this.chips) { this.chips.changes.subscribe(() => { if (this.chips.length === 0 && this.appReadyService.isBrowserAndDomAvailable()) { this.input?.el.nativeElement.focus(); } }); } this.setState(); } setUpInput() { this.input._inCombobox = true; this.input.role = this.input.role ? this.input.role : 'combobox'; this.input.inputEvent.subscribe((val) => { this.filter.emit({ type: ComboboxFilterType.INPUT, listbox: this.listbox?.value || [], input: this.input.value }); this._fromInput = true; // if the listbox has a value (probably only multiselect..), retain that value if ((!this.listbox?.multiselect && this.listbox.value) || (this.listbox?.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0)) { this.writeValue({ label: this.input.value, value: this.listbox.value }); } else { //otherwise pass the input value to the value this.writeValue({ value: this.input.value }); } this.floatingContainer?.floatingUIService.showfloatingUI(); this._fromInput = false; }); if (this.listboxContainer) { this.input.ariaOwns = this.listboxContainer.id; } if (this.label) { this.label.for = this.input.id; } this.input.focused.subscribe(() => { this._inputFocused = true; }); this.input.blurred.subscribe(() => { this._inputFocused = false; }); this.input.communicateState.subscribe((state) => { if (this.readonly !== state.readonly) { this.readonly = state.readonly; } if (this.disabled !== state.disabled) { this.disabled = state.disabled; } if (this.invalid !== state.invalid) { this.invalid = state.invalid; } if (this.required !== state.required) { this.required = state.required; } }); } setUpListItems() { this.listbox._inCombobox = true; this.listboxSubscription = this.listbox.valueUpdated.subscribe((val) => { if (!this.listbox.multiselect && !val) return; // wait for app to be ready before accessing list item native elements if (this.appReadyService.isBrowserAndDomAvailable()) { if (this.listbox?.multiselect && Array.isArray(val) && val.length > 0) { if (this.input.value) this.input.value = ''; // make optional? } else if (!this.listbox?.multiselect && val) { const index = this.listbox.listItems.toArray().findIndex((item) => item.value === val); this.input.value = this.getListItem(index)?.el.nativeElement.innerText.trim(); } this.writeValue({ label: this.input.value || '', value: this.listbox.value }); this.filter.emit({ type: ComboboxFilterType.SELECTION, listbox: this.listbox.value, input: this.input.value || '' }); // @TODO: remove first if statement in next major release if (this.listbox.multiselect && Array.isArray(this.listbox.value) && !this.EXPERIMENTAL_ADA_OPT_IN) { return; // handled in docs } else if (this.listbox?.multiselect && this.input?.value) { // if a multiselect still has a value, that means no item is selected and the user is typing; return. return; } else { this.itemSelected.emit(this.listbox.value); } } }); this.listbox.listItems.forEach((item, index) => { item.clicked.subscribe(() => { if (this.appReadyService.isBrowserAndDomAvailable()) { // wait for app to be ready before accessing input native elements this.input?.el.nativeElement.focus(); } }); item.itemChanged.subscribe((isSelected) => { // any time an item is clicked, entered, or programmatically selected, the below will set the value of the combobox if (!this.listbox?.multiselect && isSelected && this.getListItem(index)) { this.novaLibService.deselectItems(this.getList(), index, 'highlighted'); this._activeIndex = index; } }); }); this.setInitialValue(); if (this._highlightedIndex !== null) this.highlightIndex(this._highlightedIndex); } setUpFloatingContainer() { if (this.input) this.input.ariaExpanded = this.floatingContainer.isShown; this.floatingContainer.floatingUIService.isShownEmitter.subscribe((isShown) => { if (this.input) this.input.ariaExpanded = isShown; if (!isShown) { // when menu is closed, unhighlight all items if (this._highlightedIndex !== null) this._lastHighlightedOnClose = this._highlightedIndex; this._highlightedIndex = null; this.listbox?.listItems.forEach((item) => { item.highlighted = false; }); // remove aria-controls from input and reset aria-activeDescendant to null or active item id if (this.input) { this.input.ariaControls = null; const listItem = this.getListItem(this._activeIndex); if (this._activeIndex === null) { if (this.input) this.input.ariaActiveDescendant = null; if (this.listbox) this.listbox.ariaActiveDescendant.set(null); } else if (this.listbox && listItem) { this.input.ariaActiveDescendant = listItem.id; this.listbox.ariaActiveDescendant.set(listItem.id); } } } else { if (this.input) this.input.ariaControls = this.listbox?.id; } }); } setInitialValue() { let selectedIndex = -1; // note that initial value precedence is combobox initial value, input initial value, and then listbox if (this.value) { // initial value given to combobox directly if (this.listbox) { if (this.listbox.multiselect) { if (Array.isArray(this.value['value'])) { const selectedItems = this.value['value'].filter((val) => { return this.getList()?.some((item) => item.value === val); }); this.listbox.value = selectedItems; } else { // allow a non-array value (single value) to propagate the multiselect selectedIndex = this.getList()?.findIndex((item) => item.value === this.value['value']); if (selectedIndex > -1) { this.selectItem(selectedIndex); } } if (this.value['label']) { this.input.value = this.value['label']; } } else { selectedIndex = this.getList()?.findIndex((item) => item.value === this.value['value']); // check is within if statement? // allow input to still have initial value even if it doesn't match a listbox item if (selectedIndex < 0 && this.value['label']) { this.input.value = this.value['label']; } } } } else if (this.input?.value) { // initial value given to input selectedIndex = this.findListItem(this.input.value); } else if (this.listbox?.value) { if (this.listbox.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0) { // if value is an array, select all items that match the value return; } else { // initial value given to listbox selectedIndex = this.getList()?.findIndex((item) => item.active); } } // if the item is already selected, no need to select it again if (selectedIndex > -1 && !this.getListItem(selectedIndex)?.active) { this.selectItem(selectedIndex); } } setState() { if (this.input && this.listbox) { // set initial state of input and listbox based on what's passed to combobox // if input or listbox is readonly or disabled, set combobox to readonly or disabled if (this.readonly) { this.input.readonly = true; } else if (this.input.readonly) { this.readonly = true; } if (this.disabled) { this.input.disabled = true; this.listbox.disabled = true; } else if (this.input.disabled) { this.disabled = true; } else if (this.listbox.disabled) { this.disabled = true; } if (this.invalid) { this.input.invalid = true; this.listbox.invalid = true; } else if (this.input.invalid) { this.invalid = true; } else if (this.listbox.invalid) { this.invalid = true; } if (this.required) { this.input.required = true; this.listbox.required = true; } else if (this.input.required) { this.required = true; } else if (this.listbox.required) { this.required = true; } } } hostKeyDown(event) { // don't perform any keboard functions if readonly or disabled // also don't open menu if no floating container exists if (this.input.readonly || this.input.disabled || !this._inputFocused || !this.floatingContainer) { return; } if (event.key === DOWN_ARROW_KEY || event.key === RIGHT_ARROW_KEY) { // highlight next item and show menu if (event.key === DOWN_ARROW_KEY) event.preventDefault(); // allow right arrow to navigate through input this.highlightNextPrevItem('next'); if (!this.floatingContainer?.isShown) this.floatingContainer.floatingUIService.showfloatingUI(); if (this._highlightedIndex !== null && this.listbox) this.listboxService.scrollItemIntoView(this.listbox, this._highlightedIndex); } else if (event.key === UP_ARROW_KEY || event.key === LEFT_ARROW_KEY) { // highlight previous item and show menu if (event.key === UP_ARROW_KEY) event.preventDefault(); // allow left arrow to navigate through input this.highlightNextPrevItem('prev'); if (!this.floatingContainer?.isShown) this.floatingContainer.floatingUIService.showfloatingUI(); if (this._highlightedIndex !== null && this.listbox) { this.listboxService.scrollItemIntoView(this.listbox, this._highlightedIndex); } } else if (event.key === ENTER_KEY) { if (this.floatingContainer?.isShown) { event.preventDefault(); // prevent form submission if enter is triggered on list item } // select currently highlighted item if (this._highlightedIndex !== null) { this.selectItem(this._highlightedIndex); this.getListItem(this._highlightedIndex)?.clicked.emit(); // emit click event (closes item when close on click is called) } } else if (event.key === TAB_KEY && event.shiftKey) { if (this.listbox?.multiselect && this.chips.length > 0) { // if shift+tab is pressed and there is a chip (aka a value), close the menu // @note, possibly make this optional by providing an opt-out input this._highlightedIndex = null; this.floatingContainer.floatingUIService.hidefloatingUI(); } } else if (event.key === BACKSPACE_KEY) { if (this.listbox?.multiselect && !this.input.value && this.chips.length > 0) { // remove last chip if backspace is pressed on empty input and there are chips (aka a value) // I know there's a better way to do this but it's not working?? const lastValue = this.value.value[this.value.value.length - 1]; const lastItem = this.listbox?.listItems?.find((item) => item.value === lastValue); lastItem?.selectItem(); } } } hostKeyup(event) { if (event.key === BACKSPACE_KEY && !this.listbox?.multiselect) { // remove highlight for any backspace event? if (this.input.value === '' || !this.input.value) { if (this.value) this.value = ''; } const selectedItems = this.getList()?.filter((item) => item.active); if (selectedItems) { selectedItems.forEach((item) => (item.active = false)); if (this.listbox) this.listbox.value = this.listbox.multiselect ? [] : null; } } } documentKeydown(event) { if ( // if we press escape while on this combobox event.key === 'Escape' && this.floatingContainer?.el.nativeElement.contains(event.target)) { // return focus to input when escape is pressed and menu (was) open if (!this._inputFocused && this.floatingContainer?.isShown) { this.input?.el.nativeElement.focus(); } else if (!this.floatingContainer?.isShown) { // if menu is already closed, do not select "highlighted" option this._highlightedIndex = null; this._lastHighlightedOnClose = null; } } } /** * Highlight next enabled item or previous enabled item depending on type. * @param type 'next' | 'prev' */ highlightNextPrevItem(type) { let filteredIndex = null; if (this._highlightedIndex !== null) { // find next item given current item if (type === 'next') filteredIndex = this.novaLibService.nextEnabledItem(this.getList(), this._highlightedIndex); if (type === 'prev') filteredIndex = this.novaLibService.previousEnabledItem(this.getList(), this._highlightedIndex); } else if (this._activeIndex !== null) { filteredIndex = this._activeIndex; } else { // find next item initially if (type === 'next') filteredIndex = this.novaLibService.nextEnabledItem(this.getList()); if (type === 'prev') filteredIndex = this.novaLibService.previousEnabledItem(this.getList()); } if (filteredIndex !== null) this.highlightIndex(filteredIndex); } highlightIndex(index) { if (this.getListItem(index)) { this._highlightedIndex = index; const item = this.getListItem(this._highlightedIndex); if (item) { if (this.input) this.input.ariaActiveDescendant = item.id; if (this.listbox) this.listbox.ariaActiveDescendant.set(item.id); } if (this._highlightedIndex !== null) { this.novaLibService.selectItem(this.getList(), this._highlightedIndex, 'highlighted'); this.novaLibService.deselectItems(this.getList(), this._highlightedIndex, 'highlighted'); } } } selectItem(index) { this.getListItem(index)?.selectItem(); } /** * @param index * @returns ListboxItemComponent at index given. */ getListItem(index) { if (index === null || !this.currentListItems?.toArray()[index]) { return; } return this.currentListItems.toArray()[index]; } /** * Update children (input and listbox) state based on parent state. */ updateChildrenStates(prop) { if (!this.input || !this.listbox) return; switch (prop) { case STATE.READONLY: this.input.readonly = this.readonly; break; case STATE.DISABLED: this.input.disabled = this.disabled; this.listbox.disabled = this.disabled; break; case STATE.INVALID: this.input.invalid = this.invalid; this.listbox.invalid = this.invalid; break; case STATE.REQUIRED: this.input.required = this.required; this.listbox.required = this.required; break; default: break; } } appendReadonlyText() { if (this.appReadyService.isBrowserAndDomAvailable()) { if (this.readonly) { const span = this.renderer.createElement('span'); this.renderer.addClass(span, 'v-sr'); this.currentID = this.UUIDService.getUUID('v-label-'); this.renderer.setAttribute(span, 'id', this.currentID); const text = this.renderer.createText(' (read-only)'); this.renderer.appendChild(span, text); this.renderer.appendChild(this.label.el.nativeElement, span); } else { this.renderer.removeChild(this.label.el.nativeElement, document.getElementById(this.currentID)); } } } clearCombobox() { this._activeIndex = null; this._highlightedIndex = null; this._prevActiveItem = null; // unhighlight items, listbox will set all active items to false if (this.input && this.listbox) { this.input.ariaActiveDescendant = null; this.listbox.ariaActiveDescendant.set(null); } this.novaLibService.deselectItems(this.getList(), undefined, 'highlighted'); if (this.input && this.input.value !== '') { this.input.value = ''; } if (this.listbox) { if (this.listbox.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0) { this.listbox.value = []; } else if (this.listbox.value) { this.listbox.value = null; } } this.filter.emit({ type: ComboboxFilterType.RESET, listbox: this.listbox?.value || [], input: this.input?.value || '' }); } /** * @returns ListboxDirective */ getList() { return this.currentListItems?.toArray() || []; } findListItem(text) { if (!this.appReadyService.isBrowserAndDomAvailable()) return -1; // return if app is not bootstrapped and therefore we cannot access item native element return this.currentListItems ?.toArray() .findIndex((item) => item.el.nativeElement.innerText.trim().toLowerCase() == text.toLowerCase()); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } writeValue(value) { this.value = value; this.onChange(value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxDirective, deps: [{ token: i1.NovaLibService }, { token: i2.ListboxService }, { token: i3.AppReadyService }, { token: i0.Renderer2 }, { token: i4.UUIDService }, { token: i5.FloatingUIContainer }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ComboboxDirective, isStandalone: true, selector: "[v-combobox]", inputs: { class: "class", removeReadonlyText: "removeReadonlyText", EXPERIMENTAL_ADA_OPT_IN: "EXPERIMENTAL_ADA_OPT_IN", readonly: "readonly", disabled: "disabled", invalid: "invalid", required: "required", value: "value" }, outputs: { itemSelected: "itemSelected", filter: "filter", filteredListEmitter: "filteredListEmitter" }, host: { listeners: { "focus": "handleFocus($event)", "keydown": "hostKeyDown($event)", "keyup": "hostKeyup($event)", "document:keydown": "documentKeydown($event)" }, properties: { "class": "this.hostClass", "attr.disabled": "this.hostDisabled", "attr.aria-invalid": "this.ariaInvalid" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ComboboxDirective), multi: true } ], queries: [{ propertyName: "inputContainer", first: true, predicate: InputContainerComponent, descendants: true }, { propertyName: "input", first: true, predicate: InputDirective, descendants: true }, { propertyName: "listboxContainer", first: true, predicate: ListboxContainerDirective, descendants: true }, { propertyName: "listbox", first: true, predicate: ListboxDirective, descendants: true }, { propertyName: "label", first: true, predicate: LabelDirective, descendants: true }, { propertyName: "interactiveChildren", predicate: ButtonDirective, descendants: true }, { propertyName: "chips", predicate: ChipDirective, descendants: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[v-combobox]', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ComboboxDirective), multi: true } ] }] }], ctorParameters: () => [{ type: i1.NovaLibService }, { type: i2.ListboxService }, { type: i3.AppReadyService }, { type: i0.Renderer2 }, { type: i4.UUIDService }, { type: i5.FloatingUIContainer }], propDecorators: { inputContainer: [{ type: ContentChild, args: [InputContainerComponent] }], input: [{ type: ContentChild, args: [InputDirective] }], listboxContainer: [{ type: ContentChild, args: [ListboxContainerDirective] }], listbox: [{ type: ContentChild, args: [ListboxDirective] }], label: [{ type: ContentChild, args: [LabelDirective] }], interactiveChildren: [{ type: ContentChildren, args: [ButtonDirective, { descendants: true }] }], chips: [{ type: ContentChildren, args: [ChipDirective, { descendants: true }] }], class: [{ type: Input }], hostClass: [{ type: HostBinding, args: ['class'] }], removeReadonlyText: [{ type: Input }], EXPERIMENTAL_ADA_OPT_IN: [{ type: Input }], readonly: [{ type: Input }], disabled: [{ type: Input }], hostDisabled: [{ type: HostBinding, args: ['attr.disabled'] }], invalid: [{ type: Input }], ariaInvalid: [{ type: HostBinding, args: ['attr.aria-invalid'] }], required: [{ type: Input }], value: [{ type: Input }], itemSelected: [{ type: Output }], filter: [{ type: Output }], filteredListEmitter: [{ type: Output }], handleFocus: [{ type: HostListener, args: ['focus', ['$event']] }], hostKeyDown: [{ type: HostListener, args: ['keydown', ['$event']] }], hostKeyup: [{ type: HostListener, args: ['keyup', ['$event']] }], documentKeydown: [{ type: HostListener, args: ['document:keydown', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm9ib3guZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL2NvbWJvYm94L2NvbWJvYm94LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUVMLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUNsRixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDL0YsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUU3RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUNMLGFBQWEsRUFDYixjQUFjLEVBQ2QsU0FBUyxFQUNULGNBQWMsRUFDZCxlQUFlLEVBQ2YsT0FBTyxFQUNQLFlBQVks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