@ng-select/ng-select
Version:
Angular ng-select - All in One UI Select, Multiselect and Autocomplete
1,115 lines (1,114 loc) • 107 kB
JavaScript
/**
* @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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