UNPKG

primeng

Version:

[![npm version](https://badge.fury.io/js/primeng.svg)](https://badge.fury.io/js/primeng) [![npm downloads](https://img.shields.io/npm/dm/primeng.svg)](https://www.npmjs.com/package/primeng) [![Actions CI](https://github.com/primefaces/primeng/workflows/No

976 lines 113 kB
import { NgModule, Component, Input, Output, EventEmitter, ContentChildren, ContentChild, forwardRef, ViewChild, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule, PrimeTemplate, Footer, Header, TranslationKeys } from 'primeng/api'; import { DomHandler } from 'primeng/dom'; import { ObjectUtils } from 'primeng/utils'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { RippleModule } from 'primeng/ripple'; import { SearchIcon } from 'primeng/icons/search'; import { CheckIcon } from 'primeng/icons/check'; import * as i0 from "@angular/core"; import * as i1 from "primeng/api"; import * as i2 from "@angular/common"; import * as i3 from "primeng/ripple"; export const LISTBOX_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Listbox), multi: true }; /** * ListBox is used to select one or more values from a list of items. * @group Components */ class Listbox { el; cd; filterService; config; /** * When specified, allows selecting multiple values. * @group Props */ multiple; /** * Inline style of the container. * @group Props */ style; /** * Style class of the container. * @group Props */ styleClass; /** * Inline style of the list element. * @group Props */ listStyle; /** * Style class of the list element. * @group Props */ listStyleClass; /** * When present, it specifies that the element value cannot be changed. * @group Props */ readonly; /** * When present, it specifies that the element should be disabled. * @group Props */ disabled; /** * When specified, allows selecting items with checkboxes. * @group Props */ checkbox = false; /** * When specified, displays a filter input at header. * @group Props */ filter = false; /** * When filtering is enabled, filterBy decides which field or fields (comma separated) to search against. * @group Props */ filterBy; /** * Defines how the items are filtered. * @group Props */ filterMatchMode = 'contains'; /** * Locale to use in filtering. The default locale is the host environment's current locale. * @group Props */ filterLocale; /** * Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. * @group Props */ metaKeySelection = true; /** * A property to uniquely identify a value in options. * @group Props */ dataKey; /** * Whether header checkbox is shown in multiple mode. * @group Props */ showToggleAll = true; /** * Name of the label field of an option. * @group Props */ optionLabel; /** * Name of the value field of an option. * @group Props */ optionValue; /** * Name of the options field of an option group. * @group Props */ optionGroupChildren = 'items'; /** * Name of the label field of an option group. * @group Props */ optionGroupLabel; /** * Name of the disabled field of an option. * @group Props */ optionDisabled; /** * Defines a string that labels the filter input. * @group Props */ ariaFilterLabel; /** * Defines placeholder of the filter input. * @group Props */ filterPlaceHolder; /** * Text to display when filtering does not return any results. * @group Props */ emptyFilterMessage; /** * Text to display when there is no data. Defaults to global value in i18n translation configuration. * @group Props */ emptyMessage; /** * Whether to display options as grouped when nested options are provided. * @group Props */ group; /** * An array of selectitems to display as the available options. * @group Props */ get options() { return this._options; } set options(val) { this._options = val; if (this.hasFilter()) this.activateFilter(); } /** * When specified, filter displays with this value. * @group Props */ get filterValue() { return this._filterValue; } set filterValue(val) { this._filterValue = val; this.activateFilter(); } /** * Callback to invoke on value change. * @param {ListboxChangeEvent} event - Custom change event. * @group Emits */ onChange = new EventEmitter(); /** * Callback to invoke when option is clicked. * @param {ListboxClickEvent} event - Custom click event. * @group Emits */ onClick = new EventEmitter(); /** * Callback to invoke when option is double clicked. * @param {ListboxDoubleClickEvent} event - Custom double click event. * @group Emits */ onDblClick = new EventEmitter(); headerCheckboxViewChild; filterViewChild; headerFacet; footerFacet; templates; _options; itemTemplate; groupTemplate; headerTemplate; filterTemplate; footerTemplate; emptyFilterTemplate; emptyTemplate; filterIconTemplate; checkIconTemplate; _filterValue; _filteredOptions; filterOptions; filtered; value; onModelChange = () => { }; onModelTouched = () => { }; optionTouched; focus; headerCheckboxFocus; translationSubscription; constructor(el, cd, filterService, config) { this.el = el; this.cd = cd; this.filterService = filterService; this.config = config; } ngOnInit() { this.translationSubscription = this.config.translationObserver.subscribe(() => { this.cd.markForCheck(); }); if (this.filterBy) { this.filterOptions = { filter: (value) => this.onFilter(value), reset: () => this.resetFilter() }; } } ngAfterContentInit() { this.templates.forEach((item) => { switch (item.getType()) { case 'item': this.itemTemplate = item.template; break; case 'group': this.groupTemplate = item.template; break; case 'header': this.headerTemplate = item.template; break; case 'filter': this.filterTemplate = item.template; break; case 'footer': this.footerTemplate = item.template; break; case 'empty': this.emptyTemplate = item.template; break; case 'emptyfilter': this.emptyFilterTemplate = item.template; break; case 'filtericon': this.filterIconTemplate = item.template; break; case 'checkicon': this.checkIconTemplate = item.template; break; default: this.itemTemplate = item.template; break; } }); } getOptionLabel(option) { return this.optionLabel ? ObjectUtils.resolveFieldData(option, this.optionLabel) : option.label != undefined ? option.label : option; } getOptionGroupChildren(optionGroup) { return this.optionGroupChildren ? ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren) : optionGroup.items; } getOptionGroupLabel(optionGroup) { return this.optionGroupLabel ? ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel) : optionGroup.label != undefined ? optionGroup.label : optionGroup; } getOptionValue(option) { return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : this.optionLabel || option.value === undefined ? option : option.value; } isOptionDisabled(option) { return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : option.disabled !== undefined ? option.disabled : false; } writeValue(value) { this.value = value; this.cd.markForCheck(); } registerOnChange(fn) { this.onModelChange = fn; } registerOnTouched(fn) { this.onModelTouched = fn; } setDisabledState(val) { this.disabled = val; this.cd.markForCheck(); } onOptionClick(event, option) { if (this.disabled || this.isOptionDisabled(option) || this.readonly) { return; } if (this.multiple) { if (this.checkbox) this.onOptionClickCheckbox(event, option); else this.onOptionClickMultiple(event, option); } else { this.onOptionClickSingle(event, option); } this.onClick.emit({ originalEvent: event, option: option, value: this.value }); this.optionTouched = false; } onOptionTouchEnd(option) { if (this.disabled || this.isOptionDisabled(option) || this.readonly) { return; } this.optionTouched = true; } onOptionDoubleClick(event, option) { if (this.disabled || this.isOptionDisabled(option) || this.readonly) { return; } this.onDblClick.emit({ originalEvent: event, option: option, value: this.value }); } onOptionClickSingle(event, option) { let selected = this.isSelected(option); let valueChanged = false; let metaSelection = this.optionTouched ? false : this.metaKeySelection; if (metaSelection) { let metaKey = event.metaKey || event.ctrlKey; if (selected) { if (metaKey) { this.value = null; valueChanged = true; } } else { this.value = this.getOptionValue(option); valueChanged = true; } } else { this.value = selected ? null : this.getOptionValue(option); valueChanged = true; } if (valueChanged) { this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); } } onOptionClickMultiple(event, option) { let selected = this.isSelected(option); let valueChanged = false; let metaSelection = this.optionTouched ? false : this.metaKeySelection; if (metaSelection) { let metaKey = event.metaKey || event.ctrlKey; if (selected) { if (metaKey) { this.removeOption(option); } else { this.value = [this.getOptionValue(option)]; } valueChanged = true; } else { this.value = metaKey ? this.value || [] : []; this.value = [...this.value, this.getOptionValue(option)]; valueChanged = true; } } else { if (selected) { this.removeOption(option); } else { this.value = [...(this.value || []), this.getOptionValue(option)]; } valueChanged = true; } if (valueChanged) { this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); } } onOptionClickCheckbox(event, option) { if (this.disabled || this.readonly) { return; } let selected = this.isSelected(option); if (selected) { this.removeOption(option); } else { this.value = this.value ? this.value : []; this.value = [...this.value, this.getOptionValue(option)]; } this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); } removeOption(option) { this.value = this.value.filter((val) => !ObjectUtils.equals(val, this.getOptionValue(option), this.dataKey)); } isSelected(option) { let selected = false; let optionValue = this.getOptionValue(option); if (this.multiple) { if (this.value) { for (let val of this.value) { if (ObjectUtils.equals(val, optionValue, this.dataKey)) { selected = true; break; } } } } else { selected = ObjectUtils.equals(this.value, optionValue, this.dataKey); } return selected; } get allChecked() { let optionsToRender = this.optionsToRender; if (!optionsToRender || optionsToRender.length === 0) { return false; } else { let selectedDisabledItemsLength = 0; let unselectedDisabledItemsLength = 0; let selectedEnabledItemsLength = 0; let visibleOptionsLength = this.group ? 0 : this.optionsToRender.length; for (let option of optionsToRender) { if (!this.group) { let disabled = this.isOptionDisabled(option); let selected = this.isSelected(option); if (disabled) { if (selected) selectedDisabledItemsLength++; else unselectedDisabledItemsLength++; } else { if (selected) selectedEnabledItemsLength++; else return false; } } else { for (let opt of this.getOptionGroupChildren(option)) { let disabled = this.isOptionDisabled(opt); let selected = this.isSelected(opt); if (disabled) { if (selected) selectedDisabledItemsLength++; else unselectedDisabledItemsLength++; } else { if (selected) selectedEnabledItemsLength++; else { return false; } } visibleOptionsLength++; } } } return (visibleOptionsLength === selectedDisabledItemsLength || visibleOptionsLength === selectedEnabledItemsLength || (selectedEnabledItemsLength && visibleOptionsLength === selectedEnabledItemsLength + unselectedDisabledItemsLength + selectedDisabledItemsLength)); } } get optionsToRender() { return this._filteredOptions || this.options; } get emptyMessageLabel() { return this.emptyMessage || this.config.getTranslation(TranslationKeys.EMPTY_MESSAGE); } get emptyFilterMessageLabel() { return this.emptyFilterMessage || this.config.getTranslation(TranslationKeys.EMPTY_FILTER_MESSAGE); } hasFilter() { return this._filterValue && this._filterValue.trim().length > 0; } isEmpty() { return !this.optionsToRender || (this.optionsToRender && this.optionsToRender.length === 0); } onFilter(event) { this._filterValue = event.target.value; this.activateFilter(); } activateFilter() { if (this.hasFilter() && this._options) { if (this.group) { let searchFields = (this.filterBy || this.optionLabel || 'label').split(','); let filteredGroups = []; for (let optgroup of this.options) { let filteredSubOptions = this.filterService.filter(this.getOptionGroupChildren(optgroup), searchFields, this.filterValue, this.filterMatchMode, this.filterLocale); if (filteredSubOptions && filteredSubOptions.length) { filteredGroups.push({ ...optgroup, ...{ [this.optionGroupChildren]: filteredSubOptions } }); } } this._filteredOptions = filteredGroups; } else { this._filteredOptions = this._options.filter((option) => this.filterService.filters[this.filterMatchMode](this.getOptionLabel(option), this._filterValue, this.filterLocale)); } } else { this._filteredOptions = null; } } resetFilter() { if (this.filterViewChild && this.filterViewChild.nativeElement) { this.filterViewChild.nativeElement.value = ''; } this._filterValue = null; this._filteredOptions = null; } get toggleAllDisabled() { let optionsToRender = this.optionsToRender; if (!optionsToRender || optionsToRender.length === 0) { return true; } else { for (let option of optionsToRender) { if (!this.isOptionDisabled(option)) return false; } return true; } } toggleAll(event) { if (this.disabled || this.toggleAllDisabled || this.readonly) { return; } let allChecked = this.allChecked; if (allChecked) this.uncheckAll(); else this.checkAll(); this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); event.preventDefault(); } checkAll() { let optionsToRender = this.optionsToRender; let val = []; optionsToRender.forEach((opt) => { if (!this.group) { let optionDisabled = this.isOptionDisabled(opt); if (!optionDisabled || (optionDisabled && this.isSelected(opt))) { val.push(this.getOptionValue(opt)); } } else { let subOptions = this.getOptionGroupChildren(opt); if (subOptions) { subOptions.forEach((option) => { let optionDisabled = this.isOptionDisabled(option); if (!optionDisabled || (optionDisabled && this.isSelected(option))) { val.push(this.getOptionValue(option)); } }); } } }); this.value = val; } uncheckAll() { let optionsToRender = this.optionsToRender; let val = []; optionsToRender.forEach((opt) => { if (!this.group) { let optionDisabled = this.isOptionDisabled(opt); if (optionDisabled && this.isSelected(opt)) { val.push(this.getOptionValue(opt)); } } else { if (opt.items) { opt.items.forEach((option) => { let optionDisabled = this.isOptionDisabled(option); if (optionDisabled && this.isSelected(option)) { val.push(this.getOptionValue(option)); } }); } } }); this.value = val; } onOptionKeyDown(event, option) { if (this.readonly) { return; } let item = event.currentTarget; switch (event.which) { //down case 40: var nextItem = this.findNextItem(item); if (nextItem) { nextItem.focus(); } event.preventDefault(); break; //up case 38: var prevItem = this.findPrevItem(item); if (prevItem) { prevItem.focus(); } event.preventDefault(); break; //enter case 13: this.onOptionClick(event, option); event.preventDefault(); break; } } findNextItem(item) { let nextItem = item.nextElementSibling; if (nextItem) return DomHandler.hasClass(nextItem, 'p-disabled') || DomHandler.isHidden(nextItem) || DomHandler.hasClass(nextItem, 'p-listbox-item-group') ? this.findNextItem(nextItem) : nextItem; else return null; } findPrevItem(item) { let prevItem = item.previousElementSibling; if (prevItem) return DomHandler.hasClass(prevItem, 'p-disabled') || DomHandler.isHidden(prevItem) || DomHandler.hasClass(prevItem, 'p-listbox-item-group') ? this.findPrevItem(prevItem) : prevItem; else return null; } onHeaderCheckboxFocus() { this.headerCheckboxFocus = true; } onHeaderCheckboxBlur() { this.headerCheckboxFocus = false; } ngOnDestroy() { if (this.translationSubscription) { this.translationSubscription.unsubscribe(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: Listbox, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.FilterService }, { token: i1.PrimeNGConfig }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: Listbox, selector: "p-listbox", inputs: { multiple: "multiple", style: "style", styleClass: "styleClass", listStyle: "listStyle", listStyleClass: "listStyleClass", readonly: "readonly", disabled: "disabled", checkbox: "checkbox", filter: "filter", filterBy: "filterBy", filterMatchMode: "filterMatchMode", filterLocale: "filterLocale", metaKeySelection: "metaKeySelection", dataKey: "dataKey", showToggleAll: "showToggleAll", optionLabel: "optionLabel", optionValue: "optionValue", optionGroupChildren: "optionGroupChildren", optionGroupLabel: "optionGroupLabel", optionDisabled: "optionDisabled", ariaFilterLabel: "ariaFilterLabel", filterPlaceHolder: "filterPlaceHolder", emptyFilterMessage: "emptyFilterMessage", emptyMessage: "emptyMessage", group: "group", options: "options", filterValue: "filterValue" }, outputs: { onChange: "onChange", onClick: "onClick", onDblClick: "onDblClick" }, host: { classAttribute: "p-element" }, providers: [LISTBOX_VALUE_ACCESSOR], queries: [{ propertyName: "headerFacet", first: true, predicate: Header, descendants: true }, { propertyName: "footerFacet", first: true, predicate: Footer, descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "headerCheckboxViewChild", first: true, predicate: ["headerchkbox"], descendants: true }, { propertyName: "filterViewChild", first: true, predicate: ["filter"], descendants: true }], ngImport: i0, template: ` <div [ngClass]="{ 'p-listbox p-component': true, 'p-disabled': disabled }" [ngStyle]="style" [class]="styleClass"> <div class="p-listbox-header" *ngIf="headerFacet || headerTemplate"> <ng-content select="p-header"></ng-content> <ng-container *ngTemplateOutlet="headerTemplate"></ng-container> </div> <div class="p-listbox-header" *ngIf="(checkbox && multiple && showToggleAll) || filter"> <div class="p-checkbox p-component" *ngIf="checkbox && multiple && showToggleAll" [ngClass]="{ 'p-checkbox-disabled': disabled || toggleAllDisabled }"> <div class="p-hidden-accessible"> <input type="checkbox" readonly="readonly" [checked]="allChecked" (focus)="onHeaderCheckboxFocus()" (blur)="onHeaderCheckboxBlur()" (keydown.space)="toggleAll($event)" [disabled]="disabled || toggleAllDisabled" /> </div> <div #headerchkbox class="p-checkbox-box" [ngClass]="{ 'p-highlight': allChecked, 'p-focus': headerCheckboxFocus, 'p-disabled': disabled || toggleAllDisabled }" (click)="toggleAll($event)"> <ng-container *ngIf="allChecked"> <CheckIcon [styleClass]="'p-checkbox-icon'" *ngIf="!checkIconTemplate" /> <span *ngIf="checkIconTemplate" class="p-checkbox-icon"> <ng-template *ngTemplateOutlet="checkIconTemplate"></ng-template> </span> </ng-container> </div> </div> <ng-container *ngIf="filterTemplate; else builtInFilterElement"> <ng-container *ngTemplateOutlet="filterTemplate; context: { options: filterOptions }"></ng-container> </ng-container> <ng-template #builtInFilterElement> <div class="p-listbox-filter-container" *ngIf="filter"> <input #filter type="text" [value]="filterValue || ''" (input)="onFilter($event)" class="p-listbox-filter p-inputtext p-component" [disabled]="disabled" [attr.placeholder]="filterPlaceHolder" [attr.aria-label]="ariaFilterLabel" /> <SearchIcon *ngIf="!filterIconTemplate" [styleClass]="'p-listbox-filter-icon'" /> <span *ngIf="filterIconTemplate" class="p-listbox-filter-icon"> <ng-template *ngTemplateOutlet="filterIconTemplate"></ng-template> </span> </div> </ng-template> </div> <div [ngClass]="'p-listbox-list-wrapper'" [ngStyle]="listStyle" [class]="listStyleClass"> <ul class="p-listbox-list" role="listbox" [attr.aria-multiselectable]="multiple"> <ng-container *ngIf="group"> <ng-template ngFor let-optgroup [ngForOf]="optionsToRender"> <li class="p-listbox-item-group"> <span *ngIf="!groupTemplate">{{ getOptionGroupLabel(optgroup) || 'empty' }}</span> <ng-container *ngTemplateOutlet="groupTemplate; context: { $implicit: optgroup }"></ng-container> </li> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: getOptionGroupChildren(optgroup) }"></ng-container> </ng-template> </ng-container> <ng-container *ngIf="!group"> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: optionsToRender }"></ng-container> </ng-container> <ng-template #itemslist let-optionsToDisplay> <li *ngFor="let option of optionsToDisplay; let i = index" [attr.tabindex]="disabled || isOptionDisabled(option) ? null : '0'" pRipple [ngClass]="{ 'p-listbox-item': true, 'p-highlight': isSelected(option), 'p-disabled': this.isOptionDisabled(option) }" role="option" [attr.aria-label]="getOptionLabel(option)" [attr.aria-selected]="isSelected(option)" (click)="onOptionClick($event, option)" (dblclick)="onOptionDoubleClick($event, option)" (touchend)="onOptionTouchEnd(option)" (keydown)="onOptionKeyDown($event, option)" > <div class="p-checkbox p-component" *ngIf="checkbox && multiple" [ngClass]="{ 'p-checkbox-disabled': disabled || isOptionDisabled(option) }"> <div class="p-checkbox-box" [ngClass]="{ 'p-highlight': isSelected(option) }"> <ng-container *ngIf="isSelected(option)"> <CheckIcon [styleClass]="'p-checkbox-icon'" *ngIf="!checkIconTemplate" /> <span *ngIf="checkIconTemplate" class="p-checkbox-icon"> <ng-template *ngTemplateOutlet="checkIconTemplate"></ng-template> </span> </ng-container> </div> </div> <span *ngIf="!itemTemplate">{{ getOptionLabel(option) }}</span> <ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: option, index: i }"></ng-container> </li> </ng-template> <li *ngIf="hasFilter() && isEmpty()" class="p-listbox-empty-message"> <ng-container *ngIf="!emptyFilterTemplate && !emptyTemplate; else emptyFilter"> {{ emptyFilterMessageLabel }} </ng-container> <ng-container #emptyFilter *ngTemplateOutlet="emptyFilterTemplate || emptyTemplate"></ng-container> </li> <li *ngIf="!hasFilter() && isEmpty()" class="p-listbox-empty-message"> <ng-container *ngIf="!emptyTemplate; else empty"> {{ emptyMessageLabel }} </ng-container> <ng-container #empty *ngTemplateOutlet="emptyTemplate"></ng-container> </li> </ul> </div> <div class="p-listbox-footer" *ngIf="footerFacet || footerTemplate"> <ng-content select="p-footer"></ng-content> <ng-container *ngTemplateOutlet="footerTemplate"></ng-container> </div> </div> `, isInline: true, styles: ["@layer primeng{.p-listbox-list-wrapper{overflow:auto}.p-listbox-list{list-style-type:none;margin:0;padding:0}.p-listbox-item{cursor:pointer;position:relative;overflow:hidden;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.p-listbox-header{display:flex;align-items:center}.p-listbox-filter-container{position:relative;flex:1 1 auto}.p-listbox-filter-icon{position:absolute;top:50%;margin-top:-.5rem}.p-listbox-filter{width:100%}}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(function () { return i3.Ripple; }), selector: "[pRipple]" }, { kind: "component", type: i0.forwardRef(function () { return SearchIcon; }), selector: "SearchIcon" }, { kind: "component", type: i0.forwardRef(function () { return CheckIcon; }), selector: "CheckIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } export { Listbox }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: Listbox, decorators: [{ type: Component, args: [{ selector: 'p-listbox', template: ` <div [ngClass]="{ 'p-listbox p-component': true, 'p-disabled': disabled }" [ngStyle]="style" [class]="styleClass"> <div class="p-listbox-header" *ngIf="headerFacet || headerTemplate"> <ng-content select="p-header"></ng-content> <ng-container *ngTemplateOutlet="headerTemplate"></ng-container> </div> <div class="p-listbox-header" *ngIf="(checkbox && multiple && showToggleAll) || filter"> <div class="p-checkbox p-component" *ngIf="checkbox && multiple && showToggleAll" [ngClass]="{ 'p-checkbox-disabled': disabled || toggleAllDisabled }"> <div class="p-hidden-accessible"> <input type="checkbox" readonly="readonly" [checked]="allChecked" (focus)="onHeaderCheckboxFocus()" (blur)="onHeaderCheckboxBlur()" (keydown.space)="toggleAll($event)" [disabled]="disabled || toggleAllDisabled" /> </div> <div #headerchkbox class="p-checkbox-box" [ngClass]="{ 'p-highlight': allChecked, 'p-focus': headerCheckboxFocus, 'p-disabled': disabled || toggleAllDisabled }" (click)="toggleAll($event)"> <ng-container *ngIf="allChecked"> <CheckIcon [styleClass]="'p-checkbox-icon'" *ngIf="!checkIconTemplate" /> <span *ngIf="checkIconTemplate" class="p-checkbox-icon"> <ng-template *ngTemplateOutlet="checkIconTemplate"></ng-template> </span> </ng-container> </div> </div> <ng-container *ngIf="filterTemplate; else builtInFilterElement"> <ng-container *ngTemplateOutlet="filterTemplate; context: { options: filterOptions }"></ng-container> </ng-container> <ng-template #builtInFilterElement> <div class="p-listbox-filter-container" *ngIf="filter"> <input #filter type="text" [value]="filterValue || ''" (input)="onFilter($event)" class="p-listbox-filter p-inputtext p-component" [disabled]="disabled" [attr.placeholder]="filterPlaceHolder" [attr.aria-label]="ariaFilterLabel" /> <SearchIcon *ngIf="!filterIconTemplate" [styleClass]="'p-listbox-filter-icon'" /> <span *ngIf="filterIconTemplate" class="p-listbox-filter-icon"> <ng-template *ngTemplateOutlet="filterIconTemplate"></ng-template> </span> </div> </ng-template> </div> <div [ngClass]="'p-listbox-list-wrapper'" [ngStyle]="listStyle" [class]="listStyleClass"> <ul class="p-listbox-list" role="listbox" [attr.aria-multiselectable]="multiple"> <ng-container *ngIf="group"> <ng-template ngFor let-optgroup [ngForOf]="optionsToRender"> <li class="p-listbox-item-group"> <span *ngIf="!groupTemplate">{{ getOptionGroupLabel(optgroup) || 'empty' }}</span> <ng-container *ngTemplateOutlet="groupTemplate; context: { $implicit: optgroup }"></ng-container> </li> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: getOptionGroupChildren(optgroup) }"></ng-container> </ng-template> </ng-container> <ng-container *ngIf="!group"> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: optionsToRender }"></ng-container> </ng-container> <ng-template #itemslist let-optionsToDisplay> <li *ngFor="let option of optionsToDisplay; let i = index" [attr.tabindex]="disabled || isOptionDisabled(option) ? null : '0'" pRipple [ngClass]="{ 'p-listbox-item': true, 'p-highlight': isSelected(option), 'p-disabled': this.isOptionDisabled(option) }" role="option" [attr.aria-label]="getOptionLabel(option)" [attr.aria-selected]="isSelected(option)" (click)="onOptionClick($event, option)" (dblclick)="onOptionDoubleClick($event, option)" (touchend)="onOptionTouchEnd(option)" (keydown)="onOptionKeyDown($event, option)" > <div class="p-checkbox p-component" *ngIf="checkbox && multiple" [ngClass]="{ 'p-checkbox-disabled': disabled || isOptionDisabled(option) }"> <div class="p-checkbox-box" [ngClass]="{ 'p-highlight': isSelected(option) }"> <ng-container *ngIf="isSelected(option)"> <CheckIcon [styleClass]="'p-checkbox-icon'" *ngIf="!checkIconTemplate" /> <span *ngIf="checkIconTemplate" class="p-checkbox-icon"> <ng-template *ngTemplateOutlet="checkIconTemplate"></ng-template> </span> </ng-container> </div> </div> <span *ngIf="!itemTemplate">{{ getOptionLabel(option) }}</span> <ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: option, index: i }"></ng-container> </li> </ng-template> <li *ngIf="hasFilter() && isEmpty()" class="p-listbox-empty-message"> <ng-container *ngIf="!emptyFilterTemplate && !emptyTemplate; else emptyFilter"> {{ emptyFilterMessageLabel }} </ng-container> <ng-container #emptyFilter *ngTemplateOutlet="emptyFilterTemplate || emptyTemplate"></ng-container> </li> <li *ngIf="!hasFilter() && isEmpty()" class="p-listbox-empty-message"> <ng-container *ngIf="!emptyTemplate; else empty"> {{ emptyMessageLabel }} </ng-container> <ng-container #empty *ngTemplateOutlet="emptyTemplate"></ng-container> </li> </ul> </div> <div class="p-listbox-footer" *ngIf="footerFacet || footerTemplate"> <ng-content select="p-footer"></ng-content> <ng-container *ngTemplateOutlet="footerTemplate"></ng-container> </div> </div> `, providers: [LISTBOX_VALUE_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'p-element' }, styles: ["@layer primeng{.p-listbox-list-wrapper{overflow:auto}.p-listbox-list{list-style-type:none;margin:0;padding:0}.p-listbox-item{cursor:pointer;position:relative;overflow:hidden;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.p-listbox-header{display:flex;align-items:center}.p-listbox-filter-container{position:relative;flex:1 1 auto}.p-listbox-filter-icon{position:absolute;top:50%;margin-top:-.5rem}.p-listbox-filter{width:100%}}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.FilterService }, { type: i1.PrimeNGConfig }]; }, propDecorators: { multiple: [{ type: Input }], style: [{ type: Input }], styleClass: [{ type: Input }], listStyle: [{ type: Input }], listStyleClass: [{ type: Input }], readonly: [{ type: Input }], disabled: [{ type: Input }], checkbox: [{ type: Input }], filter: [{ type: Input }], filterBy: [{ type: Input }], filterMatchMode: [{ type: Input }], filterLocale: [{ type: Input }], metaKeySelection: [{ type: Input }], dataKey: [{ type: Input }], showToggleAll: [{ type: Input }], optionLabel: [{ type: Input }], optionValue: [{ type: Input }], optionGroupChildren: [{ type: Input }], optionGroupLabel: [{ type: Input }], optionDisabled: [{ type: Input }], ariaFilterLabel: [{ type: Input }], filterPlaceHolder: [{ type: Input }], emptyFilterMessage: [{ type: Input }], emptyMessage: [{ type: Input }], group: [{ type: Input }], options: [{ type: Input }], filterValue: [{ type: Input }], onChange: [{ type: Output }], onClick: [{ type: Output }], onDblClick: [{ type: Output }], headerCheckboxViewChild: [{ type: ViewChild, args: ['headerchkbox'] }], filterViewChild: [{ type: ViewChild, args: ['filter'] }], headerFacet: [{ type: ContentChild, args: [Header] }], footerFacet: [{ type: ContentChild, args: [Footer] }], templates: [{ type: ContentChildren, args: [PrimeTemplate] }] } }); class ListboxModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: ListboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.2", ngImport: i0, type: ListboxModule, declarations: [Listbox], imports: [CommonModule, SharedModule, RippleModule, SearchIcon, CheckIcon], exports: [Listbox, SharedModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: ListboxModule, imports: [CommonModule, SharedModule, RippleModule, SearchIcon, CheckIcon, SharedModule] }); } export { ListboxModule }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: ListboxModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, SharedModule, RippleModule, SearchIcon, CheckIcon], exports: [Listbox, SharedModule], declarations: [Listbox] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdGJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50cy9saXN0Ym94L2xpc3Rib3gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFFBQVEsRUFDUixTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBRVosZUFBZSxFQUNmLFlBQVksRUFHWixVQUFVLEVBRVYsU0FBUyxFQUNULHVCQUF1QixFQUN2QixpQkFBaUIsRUFHcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQWlCLGVBQWUsRUFBaUIsTUFBTSxhQUFhLENBQUM7QUFDekgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxpQkFBaUIsRUFBd0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7QUFJaEQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQVE7SUFDdkMsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQztJQUN0QyxLQUFLLEVBQUUsSUFBSTtDQUNkLENBQUM7QUFDRjs7O0dBR0c7QUFDSCxNQWtIYSxPQUFPO0lBNE5HO0lBQXVCO0lBQThCO0lBQXFDO0lBM043Rzs7O09BR0c7SUFDTSxRQUFRLENBQXNCO0lBQ3ZDOzs7T0FHRztJQUNNLEtBQUssQ0FBOEM7SUFDNUQ7OztPQUdHO0lBQ00sVUFBVSxDQUFxQjtJQUN4Qzs7O09BR0c7SUFDTSxTQUFTLENBQThDO0lBQ2hFOzs7T0FHRztJQUNNLGNBQWMsQ0FBcUI7SUFDNUM7OztPQUdHO0lBQ00sUUFBUSxDQUFzQjtJQUN2Qzs7O09BR0c7SUFDTSxRQUFRLENBQXNCO0lBQ3ZDOzs7T0FHRztJQUNNLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDbkM7OztPQUdHO0lBQ00sTUFBTSxHQUFZLEtBQUssQ0FBQztJQUNqQzs7O09BR0c7SUFDTSxRQUFRLENBQXFCO0lBQ3RDOzs7T0FHRztJQUNNLGVBQWUsR0FBeUcsVUFBVSxDQUFDO0lBQzVJOzs7T0FHRztJQUNNLFlBQVksQ0FBcUI7SUFDMUM7OztPQUdHO0lBQ00sZ0JBQWdCLEdBQVksSUFBSSxDQUFDO0lBQzFDOzs7T0FHRztJQUNNLE9BQU8sQ0FBcUI7SUFDckM7OztPQUdHO0lBQ00sYUFBYSxHQUFZLElBQUksQ0FBQztJQUN2Qzs7O09BR0c7SUFDTSxXQUFXLENBQXFCO0lBQ3pDOzs7T0FHRztJQUNNLFdBQVcsQ0FBcUI7SUFDekM7OztPQUdHO0lBQ00sbUJBQW1CLEdBQXVCLE9BQU8sQ0FBQztJQUMzRDs7O09BR0c7SUFDTSxnQkFBZ0IsQ0FBcUI7SUFDOUM7OztPQUdHO0lBQ00sY0FBYyxDQUFxQjtJQUM1Qzs7O09BR0c7SUFDTSxlQUFlLENBQXFCO0lBQzdDOzs7T0FHRztJQUNNLGlCQUFpQixDQUFxQjtJQUMvQzs7O09BR0c7SUFDTSxrQkFBa0IsQ0FBcUI7SUFDaEQ7OztPQUdHO0lBQ00sWUFBWSxDQUFxQjtJQUMxQzs7O09BR0c7SUFDTSxLQUFLLENBQXNCO0lBQ3BDOzs7T0FHRztJQUNILElBQWEsT0FBTztRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFpQixDQUFDO0lBQ2xDLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxHQUFVO1FBQ2xCLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO1FBRXBCLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0lBQ0Q7OztPQUdHO0lBQ0gsSUFBYSxXQUFXO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFlBQXNCLENBQUM7SUFDdkMsQ0FBQztJQUNELElBQUksV0FBVyxDQUFDLEdBQVc7UUFDdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUM7UUFDeEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFDRDs7OztPQUlHO0lBQ08sUUFBUSxHQUFxQyxJQUFJLFlBQVksRUFBc0IsQ0FBQztJQUM5Rjs7OztPQUlHO0lBQ08sT0FBTyxHQUFvQyxJQUFJLFlBQVksRUFBcUIsQ0FBQztJQUMzRjs7OztPQUlHO0lBQ08sVUFBVSxHQUEwQyxJQUFJLFlBQVksRUFBMkIsQ0FBQztJQUUvRSx1QkFBdUIsQ0FBdUI7SUFFcEQsZUFBZSxDQUF1QjtJQUVyQyxXQUFXLENBQTZCO0lBRXhDLFdBQVcsQ0FBNkI7SUFFOUIsU0FBUyxDQUE0QjtJQUU5RCxRQUFRLENBQTJCO0lBRW5DLFlBQVksQ0FBK0I7SUFFM0MsYUFBYSxDQUErQjtJQUU1QyxjQUFjLENBQStCO0lBRTdDLGNBQWMsQ0FBK0I7SUFFN0MsY0FBYyxDQUErQjtJQUU3QyxtQkFBbUIsQ0FBK0I7SUFFbEQsYUFBYSxDQUErQjtJQUVuRCxrQkFBa0IsQ0FBK0I7SUFFakQsaUJBQWlCLENBQStCO0lBRXpDLFlBQVksQ0FBNEI7SUFFeEMsZ0JBQWdCLENBQTJCO0lBRWxELGFBQWEsQ0FBbUM7SUFFekMsUUFBUSxDQUE2QjtJQUVyQyxLQUFLLENBQXlCO0lBRTlCLGFBQWEsR0FBYSxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7SUFFbkMsY0FBYyxHQUFhLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQUVwQyxhQUFhLENBQTZCO0lBRTFDLEtBQUssQ0FBNkI7SUFFbEMsbUJBQW1CLENBQTZCO0lBRXZELHVCQUF1QixDQUF5QjtJQUVoRCxZQUFtQixFQUFjLEVBQVMsRUFBcUIsRUFBUyxhQUE0QixFQUFTLE1BQXFCO1FBQS9HLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBUyxPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUFTLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQVMsV0FBTSxHQUFOLE1BQU0sQ0FBZTtJQUFHLENBQUM7SUFFdEksUUFBUTtRQUNKLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDMUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLElBQUksQ0FBQyxhQUFhLEdBQUc7Z0JBQ2pCLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7Z0JBQ3ZDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO2FBQ2xDLENBQUM7U0FDTDtJQUNMLENBQUM7SUFFRCxrQkFBa0I7UUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQzVCLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNwQixLQUFLLE1BQU07b0JBQ1AsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNsQyxNQUFNO2dCQUVWLEtBQUssT0FBTztvQkFDUixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ25DLE1BQU07Z0JBRVYsS0FBSyxRQUFRO29CQUNULElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDcEMsTUFBTTtnQkFFVixLQUFLLFFBQVE7b0JBQ1QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNwQyxNQUFNO2dCQUVWLEtBQUssUUFBUTtvQkFDVCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ3BDLE1BQU07Z0JBRVYsS0FBSyxPQUFPO29CQUNSLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDbkMsTUFBTTtnQkFFVixLQUFLLGFBQWE7b0JBQ2QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ3pDLE1BQU07Z0JBRVYsS0FBSyxZQUFZO29CQUNiLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUN4QyxNQUFNO2dCQUVWLEtBQUssV0FBVztvQkFDWixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDdkMsTUFBTTtnQkFFVjtvQkFDSSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ2xDLE1BQU07YUFDYjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0F