UNPKG

@ng-select/ng-select

Version:

Angular ng-select - All in One UI Select, Multiselect and Autocomplete

1,115 lines (1,114 loc) 107 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, forwardRef, ChangeDetectorRef, Input, Output, EventEmitter, ContentChild, TemplateRef, ViewEncapsulation, HostListener, HostBinding, ViewChild, ElementRef, ChangeDetectionStrategy, Inject, ContentChildren, QueryList, InjectionToken, Attribute } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { takeUntil, startWith, tap, debounceTime, map, filter } from 'rxjs/operators'; import { Subject, merge } from 'rxjs'; import { NgOptionTemplateDirective, NgLabelTemplateDirective, NgHeaderTemplateDirective, NgFooterTemplateDirective, NgOptgroupTemplateDirective, NgNotFoundTemplateDirective, NgTypeToSearchTemplateDirective, NgLoadingTextTemplateDirective, NgMultiLabelTemplateDirective, NgTagTemplateDirective } from './ng-templates.directive'; import { ConsoleService } from './console.service'; import { isDefined, isFunction, isPromise, isObject } from './value-utils'; import { ItemsList } from './items-list'; import { KeyCode } from './ng-select.types'; import { newId } from './id'; import { NgDropdownPanelComponent } from './ng-dropdown-panel.component'; import { NgOptionComponent } from './ng-option.component'; /** @type {?} */ export const NG_SELECT_DEFAULT_CONFIG = new InjectionToken('ng-select-default-options'); /** @type {?} */ export const SELECTION_MODEL_FACTORY = new InjectionToken('ng-select-selection-model'); /** @typedef {?} */ var DropdownPosition; export { DropdownPosition }; /** @typedef {?} */ var AddTagFn; export { AddTagFn }; /** @typedef {?} */ var CompareWithFn; export { CompareWithFn }; export class NgSelectComponent { /** * @param {?} classes * @param {?} tabIndex * @param {?} config * @param {?} newSelectionModel * @param {?} _elementRef * @param {?} _cd * @param {?} _console */ constructor(classes, tabIndex, config, newSelectionModel, _elementRef, _cd, _console) { this.classes = classes; this.tabIndex = tabIndex; this._cd = _cd; this._console = _console; // inputs this.items = []; this.clearable = true; this.markFirst = true; this.dropdownPosition = 'auto'; this.loading = false; this.closeOnSelect = true; this.hideSelected = false; this.selectOnTab = false; this.bufferAmount = 4; this.virtualScroll = false; this.selectableGroup = false; this.selectableGroupAsModel = true; this.searchFn = null; this.clearSearchOnAdd = true; this.labelForId = null; this.multiple = false; this.addTag = false; this.searchable = true; this.isOpen = false; // output events this.blurEvent = new EventEmitter(); this.focusEvent = new EventEmitter(); this.changeEvent = new EventEmitter(); this.openEvent = new EventEmitter(); this.closeEvent = new EventEmitter(); this.searchEvent = new EventEmitter(); this.clearEvent = new EventEmitter(); this.addEvent = new EventEmitter(); this.removeEvent = new EventEmitter(); this.scroll = new EventEmitter(); this.scrollToEnd = new EventEmitter(); this.disabled = false; this.viewPortItems = []; this.filterValue = null; this.dropdownId = newId(); this.selectedItemId = 0; this._defaultLabel = 'label'; this._pressedKeys = []; this._destroy$ = new Subject(); this._keyPress$ = new Subject(); this._onChange = (_) => { }; this._onTouched = () => { }; this.clearItem = (item) => { /** @type {?} */ const option = this.selectedItems.find(x => x.value === item); this.unselect(option); }; this._mergeGlobalConfig(config); this.itemsList = new ItemsList(this, newSelectionModel()); this.element = _elementRef.nativeElement; } /** * @return {?} */ get compareWith() { return this._compareWith; } /** * @param {?} fn * @return {?} */ set compareWith(fn) { if (!isFunction(fn)) { throw Error('`compareWith` must be a function.'); } this._compareWith = fn; } /** * @return {?} */ get filtered() { return !!this.filterValue && this.searchable; } ; /** * @return {?} */ get selectedItems() { return this.itemsList.selectedItems; } /** * @return {?} */ get selectedValues() { return this.selectedItems.map(x => x.value); } /** * @return {?} */ get hasValue() { return this.selectedItems.length > 0; } /** * @return {?} */ ngOnInit() { this._handleKeyPresses(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes["multiple"]) { this.itemsList.clearSelected(); } if (changes["items"]) { this._setItems(changes["items"].currentValue || []); } if (changes["isOpen"]) { this._manualOpen = true; } } /** * @return {?} */ ngAfterViewInit() { if (this.items && this.items.length === 0) { this._setItemsFromNgOptions(); } } /** * @return {?} */ ngOnDestroy() { this._destroy$.next(); this._destroy$.complete(); } /** * @param {?} $event * @return {?} */ handleKeyDown($event) { if (KeyCode[$event.which]) { switch ($event.which) { case KeyCode.ArrowDown: this._handleArrowDown($event); break; case KeyCode.ArrowUp: this._handleArrowUp($event); break; case KeyCode.Space: this._handleSpace($event); break; case KeyCode.Enter: this._handleEnter($event); break; case KeyCode.Tab: this._handleTab($event); break; case KeyCode.Esc: this.close(); $event.preventDefault(); $event.stopPropagation(); break; case KeyCode.Backspace: this._handleBackspace(); break; } } else if ($event.key && $event.key.length === 1) { this._keyPress$.next($event.key.toLocaleLowerCase()); } } /** * @param {?} $event * @return {?} */ handleMousedown($event) { /** @type {?} */ const target = /** @type {?} */ ($event.target); if (target.tagName !== 'INPUT') { $event.preventDefault(); } $event.stopPropagation(); if (target.className === 'ng-clear') { this.handleClearClick(); return; } if (target.className === 'ng-arrow-wrapper') { this.handleArrowClick(); return; } if (target.className.includes('ng-value-icon')) { return; } if (!this.focused) { this.focus(); } if (this.searchable) { this.open(); } else { this.toggle(); } } /** * @return {?} */ handleArrowClick() { if (this.isOpen) { this.close(); } else { this.open(); } } /** * @return {?} */ handleClearClick() { if (this.hasValue) { this.clearModel(); } this._clearSearch(); this.focus(); if (this._isTypeahead) { this.typeahead.next(null); } this.clearEvent.emit(); } /** * @return {?} */ clearModel() { if (!this.clearable) { return; } this.itemsList.clearSelected(); this._updateNgModel(); } /** * @param {?} value * @return {?} */ writeValue(value) { this.itemsList.clearSelected(); this._handleWriteValue(value); this._cd.markForCheck(); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this._onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this._onTouched = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; this._cd.markForCheck(); } /** * @return {?} */ toggle() { if (!this.isOpen) { this.open(); } else { this.close(); } } /** * @return {?} */ open() { if (this.disabled || this.isOpen || this.itemsList.maxItemsSelected || this._manualOpen) { return; } if (!this._isTypeahead && !this.addTag && this.itemsList.noItemsToSelect) { return; } this.isOpen = true; this.itemsList.markSelectedOrDefault(this.markFirst); this.openEvent.emit(); if (!this.filterValue) { this.focus(); } this.detectChanges(); } /** * @return {?} */ close() { if (!this.isOpen || this._manualOpen) { return; } this.isOpen = false; this._clearSearch(); this._onTouched(); this.closeEvent.emit(); this._cd.markForCheck(); } /** * @param {?} item * @return {?} */ toggleItem(item) { if (!item || item.disabled || this.disabled) { return; } if (this.multiple && item.selected) { this.unselect(item); } else { this.select(item); } } /** * @param {?} item * @return {?} */ select(item) { if (!item.selected) { this.itemsList.select(item); if (this.clearSearchOnAdd) { this._clearSearch(); } if (this.multiple) { this.addEvent.emit(item.value); } this._updateNgModel(); } if (this.closeOnSelect || this.itemsList.noItemsToSelect) { this.close(); } } /** * @return {?} */ focus() { this.filterInput.nativeElement.focus(); } /** * @param {?} item * @return {?} */ unselect(item) { this.itemsList.unselect(item); this.focus(); this._updateNgModel(); this.removeEvent.emit(item); } /** * @return {?} */ selectTag() { /** @type {?} */ let tag; if (isFunction(this.addTag)) { tag = (/** @type {?} */ (this.addTag))(this.filterValue); } else { tag = this._primitive ? this.filterValue : { [this.bindLabel]: this.filterValue }; } /** @type {?} */ const handleTag = (item) => this._isTypeahead ? this.itemsList.mapItem(item, null) : this.itemsList.addItem(item); if (isPromise(tag)) { tag.then(item => this.select(handleTag(item))).catch(() => { }); } else if (tag) { this.select(handleTag(tag)); } } /** * @return {?} */ showClear() { return this.clearable && (this.hasValue || this.filterValue) && !this.disabled; } /** * @return {?} */ get showAddTag() { if (!this.filterValue) { return false; } /** @type {?} */ const term = this.filterValue.toLowerCase(); return this.addTag && (!this.itemsList.filteredItems.some(x => x.label.toLowerCase() === term) && (!this.hideSelected || !this.selectedItems.some(x => x.label.toLowerCase() === term))) && !this.loading; } /** * @return {?} */ showNoItemsFound() { /** @type {?} */ const empty = this.itemsList.filteredItems.length === 0; return ((empty && !this._isTypeahead && !this.loading) || (empty && this._isTypeahead && this.filterValue && !this.loading)) && !this.showAddTag; } /** * @return {?} */ showTypeToSearch() { /** @type {?} */ const empty = this.itemsList.filteredItems.length === 0; return empty && this._isTypeahead && !this.filterValue && !this.loading; } /** * @param {?} term * @return {?} */ filter(term) { this.filterValue = term; this.open(); if (this._isTypeahead) { this.typeahead.next(this.filterValue); } else { this.itemsList.filter(this.filterValue); if (this.isOpen) { this.itemsList.markSelectedOrDefault(this.markFirst); } } this.searchEvent.emit(term); } /** * @param {?} $event * @return {?} */ onInputFocus($event) { if (this.focused) { return; } this.element.classList.add('ng-select-focused'); this.focusEvent.emit($event); this.focused = true; } /** * @param {?} $event * @return {?} */ onInputBlur($event) { this.element.classList.remove('ng-select-focused'); this.blurEvent.emit($event); if (!this.isOpen && !this.disabled) { this._onTouched(); } this.focused = false; } /** * @param {?} item * @return {?} */ onItemHover(item) { if (item.disabled) { return; } this.itemsList.markItem(item); } /** * @return {?} */ detectChanges() { if (!(/** @type {?} */ (this._cd)).destroyed) { this._cd.detectChanges(); } } /** * @return {?} */ updateDropdownPosition() { if (this.dropdownPanel) { this.dropdownPanel.updateDropdownPosition(); } } /** * @param {?} items * @return {?} */ _setItems(items) { /** @type {?} */ const firstItem = items[0]; this.bindLabel = this.bindLabel || this._defaultLabel; this._primitive = !firstItem ? this._primitive : !isObject(firstItem); this.itemsList.setItems(items); if (items.length > 0 && this.hasValue) { this.itemsList.mapSelectedItems(); } if (this.isOpen && isDefined(this.filterValue) && !this._isTypeahead) { this.itemsList.filter(this.filterValue); } if (this._isTypeahead || this.isOpen) { this.itemsList.markSelectedOrDefault(this.markFirst); } } /** * @return {?} */ _setItemsFromNgOptions() { /** @type {?} */ const handleNgOptions = (options) => { this.items = options.map(option => ({ $ngOptionValue: option.value, $ngOptionLabel: option.elementRef.nativeElement.innerHTML, disabled: option.disabled })); this.itemsList.setItems(this.items); if (this.hasValue) { this.itemsList.mapSelectedItems(); } this.detectChanges(); }; /** @type {?} */ const handleOptionChange = () => { /** @type {?} */ const changedOrDestroyed = merge(this.ngOptions.changes, this._destroy$); merge(...this.ngOptions.map(option => option.stateChange$)) .pipe(takeUntil(changedOrDestroyed)) .subscribe(option => { /** @type {?} */ const item = this.itemsList.findItem(option.value); item.disabled = option.disabled; this._cd.markForCheck(); }); }; this.ngOptions.changes .pipe(startWith(this.ngOptions), takeUntil(this._destroy$), filter((items) => !!items.length)) .subscribe(options => { this.bindLabel = this._defaultLabel; handleNgOptions(options); handleOptionChange(); }); } /** * @param {?} value * @return {?} */ _isValidWriteValue(value) { if (!isDefined(value) || (this.multiple && value === '') || Array.isArray(value) && value.length === 0) { return false; } /** @type {?} */ const validateBinding = (item) => { if (isObject(item) && this.bindValue) { this._console.warn(`Binding object(${JSON.stringify(item)}) with bindValue is not allowed.`); return false; } return true; }; if (this.multiple) { if (!Array.isArray(value)) { this._console.warn('Multiple select ngModel should be array.'); return false; } return value.every(item => validateBinding(item)); } else { return validateBinding(value); } } /** * @param {?} ngModel * @return {?} */ _handleWriteValue(ngModel) { if (!this._isValidWriteValue(ngModel)) { return; } /** @type {?} */ const select = (val) => { /** @type {?} */ let item = this.itemsList.findItem(val); if (item) { this.itemsList.select(item); } else { /** @type {?} */ const isValObject = isObject(val); /** @type {?} */ const isPrimitive = !isValObject && !this.bindValue; if ((isValObject || isPrimitive)) { this.itemsList.select(this.itemsList.mapItem(val, null)); } else if (this.bindValue) { item = { [this.bindLabel]: null, [this.bindValue]: val }; this.itemsList.select(this.itemsList.mapItem(item, null)); } } }; if (this.multiple) { (/** @type {?} */ (ngModel)).forEach(item => select(item)); } else { select(ngModel); } } /** * @return {?} */ _handleKeyPresses() { if (this.searchable) { return; } this._keyPress$ .pipe(takeUntil(this._destroy$), tap(letter => this._pressedKeys.push(letter)), debounceTime(200), filter(() => this._pressedKeys.length > 0), map(() => this._pressedKeys.join(''))) .subscribe(term => { /** @type {?} */ const item = this.itemsList.findByLabel(term); if (item) { if (this.isOpen) { this.itemsList.markItem(item); this._cd.markForCheck(); } else { this.select(item); } } this._pressedKeys = []; }); } /** * @return {?} */ _updateNgModel() { /** @type {?} */ const model = []; for (const item of this.selectedItems) { if (this.bindValue) { /** @type {?} */ let resolvedValue = null; if (item.children) { resolvedValue = item.value[this.groupBy]; } else { resolvedValue = this.itemsList.resolveNested(item.value, this.bindValue); } model.push(resolvedValue); } else { model.push(item.value); } } /** @type {?} */ const selected = this.selectedItems.map(x => x.value); if (this.multiple) { this._onChange(model); this.changeEvent.emit(selected); } else { this._onChange(isDefined(model[0]) ? model[0] : null); this.changeEvent.emit(selected[0]); } this._cd.markForCheck(); } /** * @return {?} */ _clearSearch() { if (!this.filterValue) { return; } this.filterValue = null; this.itemsList.resetFilteredItems(); } /** * @return {?} */ _scrollToMarked() { if (!this.isOpen || !this.dropdownPanel) { return; } this.dropdownPanel.scrollInto(this.itemsList.markedItem); } /** * @return {?} */ _scrollToTag() { if (!this.isOpen || !this.dropdownPanel) { return; } this.dropdownPanel.scrollIntoTag(); } /** * @param {?} $event * @return {?} */ _handleTab($event) { if (!this.isOpen) { return; } if (this.selectOnTab) { if (this.itemsList.markedItem) { this.toggleItem(this.itemsList.markedItem); $event.preventDefault(); } else if (this.showAddTag) { this.selectTag(); $event.preventDefault(); } else { this.close(); } } else { this.close(); } } /** * @param {?} $event * @return {?} */ _handleEnter($event) { if (this.isOpen || this._manualOpen) { if (this.itemsList.markedItem) { this.toggleItem(this.itemsList.markedItem); } else if (this.showAddTag) { this.selectTag(); } } else { this.open(); } $event.preventDefault(); $event.stopPropagation(); } /** * @param {?} $event * @return {?} */ _handleSpace($event) { if (this.isOpen || this._manualOpen) { return; } this.open(); $event.preventDefault(); } /** * @param {?} $event * @return {?} */ _handleArrowDown($event) { if (this._nextItemIsTag(+1)) { this.itemsList.unmarkItem(); this._scrollToTag(); } else { this.itemsList.markNextItem(); this._scrollToMarked(); } this.open(); $event.preventDefault(); } /** * @param {?} $event * @return {?} */ _handleArrowUp($event) { if (!this.isOpen) { return; } if (this._nextItemIsTag(-1)) { this.itemsList.unmarkItem(); this._scrollToTag(); } else { this.itemsList.markPreviousItem(); this._scrollToMarked(); } $event.preventDefault(); } /** * @param {?} nextStep * @return {?} */ _nextItemIsTag(nextStep) { /** @type {?} */ const nextIndex = this.itemsList.markedIndex + nextStep; return this.addTag && this.filterValue && this.itemsList.markedItem && (nextIndex < 0 || nextIndex === this.itemsList.filteredItems.length); } /** * @return {?} */ _handleBackspace() { if (this.filterValue || !this.clearable || !this.hasValue) { return; } if (this.multiple) { this.unselect(this.itemsList.lastSelectedItem); } else { this.clearModel(); } } /** * @return {?} */ get _isTypeahead() { return this.typeahead && this.typeahead.observers.length > 0; } /** * @param {?} config * @return {?} */ _mergeGlobalConfig(config) { this.placeholder = this.placeholder || config.placeholder; this.notFoundText = this.notFoundText || config.notFoundText; this.typeToSearchText = this.typeToSearchText || config.typeToSearchText; this.addTagText = this.addTagText || config.addTagText; this.loadingText = this.loadingText || config.loadingText; this.clearAllText = this.clearAllText || config.clearAllText; } } NgSelectComponent.decorators = [ { type: Component, args: [{ selector: 'ng-select', template: "<div (mousedown)=\"handleMousedown($event)\" [class.ng-has-value]=\"hasValue\" class=\"ng-select-container\">\n <div class=\"ng-value-container\">\n <div class=\"ng-placeholder\">{{placeholder}}</div>\n\n <ng-container *ngIf=\"!multiLabelTemplate && selectedItems.length > 0\">\n <div [class.ng-value-disabled]=\"item.disabled\" class=\"ng-value\" *ngFor=\"let item of selectedItems\">\n <ng-template #defaultLabelTemplate>\n <span class=\"ng-value-icon left\" (click)=\"unselect(item);\" aria-hidden=\"true\">\u00D7</span>\n <span class=\"ng-value-label\">{{item.label}}</span>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"labelTemplate || defaultLabelTemplate\"\n [ngTemplateOutletContext]=\"{ item: item.value, clear: clearItem, label: item.label }\">\n </ng-template>\n </div>\n </ng-container>\n\n <ng-template *ngIf=\"multiLabelTemplate && selectedValues.length > 0\"\n [ngTemplateOutlet]=\"multiLabelTemplate\"\n [ngTemplateOutletContext]=\"{ items: selectedValues, clear: clearItem }\">\n </ng-template>\n\n <div class=\"ng-input\">\n <input #filterInput\n type=\"text\"\n autocomplete=\"{{dropdownId}}\"\n [attr.id]=\"labelForId\"\n [attr.tabindex]=\"tabIndex\"\n [readOnly]=\"!searchable\"\n [disabled]=\"disabled\"\n [value]=\"filterValue\"\n (input)=\"filter(filterInput.value)\"\n (focus)=\"onInputFocus($event)\"\n (blur)=\"onInputBlur($event)\"\n (change)=\"$event.stopPropagation()\"\n role=\"combobox\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-owns]=\"isOpen ? dropdownId : null\"\n [attr.aria-activedescendant]=\"isOpen ? itemsList?.markedItem?.htmlId : null\">\n </div>\n </div>\n\n <div class=\"ng-spinner-loader\" *ngIf=\"loading\"></div>\n\n <span *ngIf=\"showClear()\" class=\"ng-clear-wrapper\" title=\"{{clearAllText}}\">\n <span class=\"ng-clear\" aria-hidden=\"true\">\u00D7</span>\n </span>\n\n <span class=\"ng-arrow-wrapper\">\n <span class=\"ng-arrow\"></span>\n </span>\n</div>\n\n<ng-dropdown-panel *ngIf=\"isOpen\"\n class=\"ng-dropdown-panel\"\n [virtualScroll]=\"virtualScroll\"\n [bufferAmount]=\"bufferAmount\"\n [appendTo]=\"appendTo\"\n [position]=\"dropdownPosition\"\n [headerTemplate]=\"headerTemplate\"\n [footerTemplate]=\"footerTemplate\"\n [items]=\"itemsList.filteredItems\"\n [markedItem]=\"itemsList.markedItem\"\n (update)=\"viewPortItems = $event\"\n (scroll)=\"scroll.emit($event)\"\n (scrollToEnd)=\"scrollToEnd.emit($event)\"\n (outsideClick)=\"close()\"\n [class.ng-select-multiple]=\"multiple\"\n [ngClass]=\"classes\"\n [id]=\"dropdownId\">\n\n <ng-container>\n <div class=\"ng-option\" [attr.role]=\"item.children ? 'group' : 'option'\" (click)=\"toggleItem(item)\" (mousedown)=\"$event.preventDefault()\" (mouseover)=\"onItemHover(item)\"\n *ngFor=\"let item of viewPortItems\"\n [class.ng-option-disabled]=\"item.disabled\"\n [class.ng-option-selected]=\"item.selected\"\n [class.ng-optgroup]=\"item.children\"\n [class.ng-option]=\"!item.children\"\n [class.ng-option-child]=\"!!item.parent\"\n [class.ng-option-marked]=\"item === itemsList.markedItem\"\n [attr.id]=\"item?.htmlId\">\n\n <ng-template #defaultOptionTemplate>\n <span class=\"ng-option-label\">{{item.label}}</span>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"item.children ? (optgroupTemplate || defaultOptionTemplate) : (optionTemplate || defaultOptionTemplate)\"\n [ngTemplateOutletContext]=\"{ item: item.value, item$:item, index: item.index, searchTerm: filterValue }\">\n </ng-template>\n </div>\n\n <div class=\"ng-option\" [class.ng-option-marked]=\"!itemsList.markedItem\" (mouseover)=\"itemsList.unmarkItem()\" role=\"option\" (click)=\"selectTag()\" *ngIf=\"showAddTag\">\n <ng-template #defaultTagTemplate>\n <span><span class=\"ng-tag-label\">{{addTagText}}</span>\"{{filterValue}}\"</span>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"tagTemplate || defaultTagTemplate\"\n [ngTemplateOutletContext]=\"{ searchTerm: filterValue }\">\n </ng-template>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"showNoItemsFound()\">\n <ng-template #defaultNotFoundTemplate>\n <div class=\"ng-option ng-option-disabled\">{{notFoundText}}</div>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"notFoundTemplate || defaultNotFoundTemplate\"\n [ngTemplateOutletContext]=\"{ searchTerm: filterValue }\">\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"showTypeToSearch()\">\n <ng-template #defaultTypeToSearchTemplate>\n <div class=\"ng-option ng-option-disabled\">{{typeToSearchText}}</div>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"typeToSearchTemplate || defaultTypeToSearchTemplate\">\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"loading && itemsList.filteredItems.length === 0\">\n <ng-template #defaultLoadingTextTemplate>\n <div class=\"ng-option ng-option-disabled\">{{loadingText}}</div>\n </ng-template>\n\n <ng-template\n [ngTemplateOutlet]=\"loadingTextTemplate || defaultLoadingTextTemplate\"\n [ngTemplateOutletContext]=\"{ searchTerm: filterValue }\">\n </ng-template>\n </ng-container>\n\n</ng-dropdown-panel>\n", providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgSelectComponent), multi: true }], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { 'role': 'listbox', 'class': 'ng-select', '[class.ng-select-single]': '!multiple', }, styles: [".ng-select{position:relative;display:block;box-sizing:border-box}.ng-select div,.ng-select input,.ng-select span{box-sizing:border-box}.ng-select [hidden]{display:none}.ng-select.ng-select-searchable .ng-select-container .ng-value-container .ng-input{opacity:1}.ng-select.ng-select-opened .ng-select-container{z-index:1001}.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-placeholder,.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-value{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.ng-select.ng-select-disabled .ng-arrow-wrapper{cursor:default}.ng-select.ng-select-filtered .ng-placeholder{display:none}.ng-select .ng-select-container{color:#333;cursor:default;display:flex;outline:0;overflow:hidden;position:relative;width:100%}.ng-select .ng-select-container .ng-value-container{display:flex;flex:1}.ng-select .ng-select-container .ng-value-container .ng-input{opacity:0}.ng-select .ng-select-container .ng-value-container .ng-input>input{box-sizing:content-box;background:none;border:0;box-shadow:none;outline:0;cursor:default;width:100%}.ng-select .ng-select-container .ng-value-container .ng-input>input::-ms-clear{display:none}.ng-select .ng-select-container .ng-value-container .ng-input>input[readonly]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:0;padding:0}.ng-select.ng-select-single.ng-select-filtered .ng-select-container .ng-value-container .ng-value{visibility:hidden}.ng-select.ng-select-single .ng-select-container .ng-value-container,.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{position:absolute;left:0;width:100%}.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container{flex-wrap:wrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{white-space:nowrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon{cursor:pointer}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input{flex:1;z-index:2}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{position:absolute;z-index:1}.ng-select .ng-clear-wrapper{cursor:pointer;position:relative;width:17px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ng-select .ng-clear-wrapper .ng-clear{display:inline-block;font-size:18px;line-height:1}.ng-select .ng-spinner-loader{border-radius:50%;width:17px;height:17px;margin-right:5px;font-size:10px;position:relative;text-indent:-9999em;border-top:2px solid rgba(66,66,66,.2);border-right:2px solid rgba(66,66,66,.2);border-bottom:2px solid rgba(66,66,66,.2);border-left:2px solid #424242;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-animation:.8s linear infinite load8;animation:.8s linear infinite load8}.ng-select .ng-spinner-loader:after{border-radius:50%;width:17px;height:17px}@-webkit-keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ng-select .ng-arrow-wrapper{cursor:pointer;position:relative;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ng-select .ng-arrow-wrapper .ng-arrow{pointer-events:none;display:inline-block;height:0;width:0;position:relative}"] }] } ]; /** @nocollapse */ NgSelectComponent.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['class',] }] }, { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] }, { type: undefined, decorators: [{ type: Inject, args: [NG_SELECT_DEFAULT_CONFIG,] }] }, { type: undefined, decorators: [{ type: Inject, args: [SELECTION_MODEL_FACTORY,] }] }, { type: ElementRef }, { type: ChangeDetectorRef }, { type: ConsoleService } ]; NgSelectComponent.propDecorators = { items: [{ type: Input }], bindLabel: [{ type: Input }], bindValue: [{ type: Input }], clearable: [{ type: Input }], markFirst: [{ type: Input }], placeholder: [{ type: Input }], notFoundText: [{ type: Input }], typeToSearchText: [{ type: Input }], addTagText: [{ type: Input }], loadingText: [{ type: Input }], clearAllText: [{ type: Input }], dropdownPosition: [{ type: Input }], appendTo: [{ type: Input }], loading: [{ type: Input }], closeOnSelect: [{ type: Input }], hideSelected: [{ type: Input }], selectOnTab: [{ type: Input }], maxSelectedItems: [{ type: Input }], groupBy: [{ type: Input }], bufferAmount: [{ type: Input }], virtualScroll: [{ type: Input }], selectableGroup: [{ type: Input }], selectableGroupAsModel: [{ type: Input }], searchFn: [{ type: Input }], clearSearchOnAdd: [{ type: Input }], labelForId: [{ type: Input }], typeahead: [{ type: Input }, { type: HostBinding, args: ['class.ng-select-typeahead',] }], multiple: [{ type: Input }, { type: HostBinding, args: ['class.ng-select-multiple',] }], addTag: [{ type: Input }, { type: HostBinding, args: ['class.ng-select-taggable',] }], searchable: [{ type: Input }, { type: HostBinding, args: ['class.ng-select-searchable',] }], isOpen: [{ type: Input }, { type: HostBinding, args: ['class.ng-select-opened',] }], compareWith: [{ type: Input }], blurEvent: [{ type: Output, args: ['blur',] }], focusEvent: [{ type: Output, args: ['focus',] }], changeEvent: [{ type: Output, args: ['change',] }], openEvent: [{ type: Output, args: ['open',] }], closeEvent: [{ type: Output, args: ['close',] }], searchEvent: [{ type: Output, args: ['search',] }], clearEvent: [{ type: Output, args: ['clear',] }], addEvent: [{ type: Output, args: ['add',] }], removeEvent: [{ type: Output, args: ['remove',] }], scroll: [{ type: Output, args: ['scroll',] }], scrollToEnd: [{ type: Output, args: ['scrollToEnd',] }], optionTemplate: [{ type: ContentChild, args: [NgOptionTemplateDirective, { read: TemplateRef },] }], optgroupTemplate: [{ type: ContentChild, args: [NgOptgroupTemplateDirective, { read: TemplateRef },] }], labelTemplate: [{ type: ContentChild, args: [NgLabelTemplateDirective, { read: TemplateRef },] }], multiLabelTemplate: [{ type: ContentChild, args: [NgMultiLabelTemplateDirective, { read: TemplateRef },] }], headerTemplate: [{ type: ContentChild, args: [NgHeaderTemplateDirective, { read: TemplateRef },] }], footerTemplate: [{ type: ContentChild, args: [NgFooterTemplateDirective, { read: TemplateRef },] }], notFoundTemplate: [{ type: ContentChild, args: [NgNotFoundTemplateDirective, { read: TemplateRef },] }], typeToSearchTemplate: [{ type: ContentChild, args: [NgTypeToSearchTemplateDirective, { read: TemplateRef },] }], loadingTextTemplate: [{ type: ContentChild, args: [NgLoadingTextTemplateDirective, { read: TemplateRef },] }], tagTemplate: [{ type: ContentChild, args: [NgTagTemplateDirective, { read: TemplateRef },] }], dropdownPanel: [{ type: ViewChild, args: [forwardRef(() => NgDropdownPanelComponent),] }], ngOptions: [{ type: ContentChildren, args: [NgOptionComponent, { descendants: true },] }], filterInput: [{ type: ViewChild, args: ['filterInput',] }], disabled: [{ type: HostBinding, args: ['class.ng-select-disabled',] }], filtered: [{ type: HostBinding, args: ['class.ng-select-filtered',] }], handleKeyDown: [{ type: HostListener, args: ['keydown', ['$event'],] }] }; if (false) { /** @type {?} */ NgSelectComponent.prototype.items; /** @type {?} */ NgSelectComponent.prototype.bindLabel; /** @type {?} */ NgSelectComponent.prototype.bindValue; /** @type {?} */ NgSelectComponent.prototype.clearable; /** @type {?} */ NgSelectComponent.prototype.markFirst; /** @type {?} */ NgSelectComponent.prototype.placeholder; /** @type {?} */ NgSelectComponent.prototype.notFoundText; /** @type {?} */ NgSelectComponent.prototype.typeToSearchText; /** @type {?} */ NgSelectComponent.prototype.addTagText; /** @type {?} */ NgSelectComponent.prototype.loadingText; /** @type {?} */ NgSelectComponent.prototype.clearAllText; /** @type {?} */ NgSelectComponent.prototype.dropdownPosition; /** @type {?} */ NgSelectComponent.prototype.appendTo; /** @type {?} */ NgSelectComponent.prototype.loading; /** @type {?} */ NgSelectComponent.prototype.closeOnSelect; /** @type {?} */ NgSelectComponent.prototype.hideSelected; /** @type {?} */ NgSelectComponent.prototype.selectOnTab; /** @type {?} */ NgSelectComponent.prototype.maxSelectedItems; /** @type {?} */ NgSelectComponent.prototype.groupBy; /** @type {?} */ NgSelectComponent.prototype.bufferAmount; /** @type {?} */ NgSelectComponent.prototype.virtualScroll; /** @type {?} */ NgSelectComponent.prototype.selectableGroup; /** @type {?} */ NgSelectComponent.prototype.selectableGroupAsModel; /** @type {?} */ NgSelectComponent.prototype.searchFn; /** @type {?} */ NgSelectComponent.prototype.clearSearchOnAdd; /** @type {?} */ NgSelectComponent.prototype.labelForId; /** @type {?} */ NgSelectComponent.prototype.typeahead; /** @type {?} */ NgSelectComponent.prototype.multiple; /** @type {?} */ NgSelectComponent.prototype.addTag; /** @type {?} */ NgSelectComponent.prototype.searchable; /** @type {?} */ NgSelectComponent.prototype.isOpen; /** @type {?} */ NgSelectComponent.prototype.blurEvent; /** @type {?} */ NgSelectComponent.prototype.focusEvent; /** @type {?} */ NgSelectComponent.prototype.changeEvent; /** @type {?} */ NgSelectComponent.prototype.openEvent; /** @type {?} */ NgSelectComponent.prototype.closeEvent; /** @type {?} */ NgSelectComponent.prototype.searchEvent; /** @type {?} */ NgSelectComponent.prototype.clearEvent; /** @type {?} */ NgSelectComponent.prototype.addEvent; /** @type {?} */ NgSelectComponent.prototype.removeEvent; /** @type {?} */ NgSelectComponent.prototype.scroll; /** @type {?} */ NgSelectComponent.prototype.scrollToEnd; /** @type {?} */ NgSelectComponent.prototype.optionTemplate; /** @type {?} */ NgSelectComponent.prototype.optgroupTemplate; /** @type {?} */ NgSelectComponent.prototype.labelTemplate; /** @type {?} */ NgSelectComponent.prototype.multiLabelTemplate; /** @type {?} */ NgSelectComponent.prototype.headerTemplate; /** @type {?} */ NgSelectComponent.prototype.footerTemplate; /** @type {?} */ NgSelectComponent.prototype.notFoundTemplate; /** @type {?} */ NgSelectComponent.prototype.typeToSearchTemplate; /** @type {?} */ NgSelectComponent.prototype.loadingTextTemplate; /** @type {?} */ NgSelectComponent.prototype.tagTemplate; /** @type {?} */ NgSelectComponent.prototype.dropdownPanel; /** @type {?} */ NgSelectComponent.prototype.ngOptions; /** @type {?} */ NgSelectComponent.prototype.filterInput; /** @type {?} */ NgSelectComponent.prototype.disabled; /** @type {?} */ NgSelectComponent.prototype.itemsList; /** @type {?} */ NgSelectComponent.prototype.viewPortItems; /** @type {?} */ NgSelectComponent.prototype.filterValue; /** @type {?} */ NgSelectComponent.prototype.dropdownId; /** @type {?} */ NgSelectComponent.prototype.selectedItemId; /** @type {?} */ NgSelectComponent.prototype.element; /** @type {?} */ NgSelectComponent.prototype.focused; /** @type {?} */ NgSelectComponent.prototype._defaultLabel; /** @type {?} */ NgSelectComponent.prototype._primitive; /** @type {?} */ NgSelectComponent.prototype._manualOpen; /** @type {?} */ NgSelectComponent.prototype._pressedKeys; /** @type {?} */ NgSelectComponent.prototype._compareWith; /** @type {?} */ NgSelectComponent.prototype._destroy$; /** @type {?} */ NgSelectComponent.prototype._keyPress$; /** @type {?} */ NgSelectComponent.prototype._onChange; /** @type {?} */ NgSelectComponent.prototype._onTouched; /** @type {?} */ NgSelectComponent.prototype.clearItem; /** @type {?} */ NgSelectComponent.prototype.classes; /** @type {?} */ NgSelectComponent.prototype.tabIndex; /** @type {?} */ NgSelectComponent.prototype._cd; /** @type {?} */ NgSelectComponent.prototype._console; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctc2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BuZy1zZWxlY3Qvbmctc2VsZWN0LyIsInNvdXJjZXMiOlsibmctc2VsZWN0L25nLXNlbGVjdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDSCxTQUFTLEVBSVQsVUFBVSxFQUNWLGlCQUFpQixFQUNqQixLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixZQUFZLEVBQ1osV0FBVyxFQUNYLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osV0FBVyxFQUNYLFNBQVMsRUFDVCxVQUFVLEVBQ1YsdUJBQXVCLEVBQ3ZCLE1BQU0sRUFFTixlQUFlLEVBQ2YsU0FBUyxFQUNULGNBQWMsRUFDZCxTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXRDLE9BQU8sRUFDSCx5QkFBeUIsRUFDekIsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6Qix5QkFBeUIsRUFDekIsMkJBQTJCLEVBQzNCLDJCQUEyQixFQUMzQiwrQkFBK0IsRUFDL0IsOEJBQThCLEVBQzlCLDZCQUE2QixFQUM3QixzQkFBc0IsRUFDekIsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FB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