UNPKG

primeng

Version:

PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,

991 lines (987 loc) 157 kB
export * from 'primeng/types/multiselect'; import { NgTemplateOutlet } from '@angular/common'; import * as i0 from '@angular/core'; import { InjectionToken, Injectable, inject, input, booleanAttribute, numberAttribute, output, computed, ViewEncapsulation, Component, forwardRef, model, viewChild, contentChild, signal, effect, untracked, ChangeDetectionStrategy, NgModule } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import * as i1 from '@angular/forms'; import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { uuid, isNotEmpty, isArray, deepEquals, equals, focus, findLastIndex, resolveFieldData, isPrintableCharacter, getFirstFocusableElement, getLastFocusableElement, findSingle, getFocusableElements } from '@primeuix/utils'; import { SharedModule, Footer, Header, FilterService, OverlayService, TranslationKeys } from 'primeng/api'; import { AutoFocus } from 'primeng/autofocus'; import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent'; import { BaseEditableHolder } from 'primeng/baseeditableholder'; import * as i1$1 from 'primeng/bind'; import { Bind, BindModule } from 'primeng/bind'; import { Checkbox } from 'primeng/checkbox'; import { Chip } from 'primeng/chip'; import { DomHandler, unblockBodyScroll } from 'primeng/dom'; import { Fluid } from 'primeng/fluid'; import { IconField } from 'primeng/iconfield'; import { Check } from '@primeicons/angular/check'; import { ChevronDown } from '@primeicons/angular/chevron-down'; import { Search } from '@primeicons/angular/search'; import { Times } from '@primeicons/angular/times'; import { InputIcon } from 'primeng/inputicon'; import { InputText } from 'primeng/inputtext'; import { Overlay } from 'primeng/overlay'; import { Scroller } from 'primeng/scroller'; import { Tooltip } from 'primeng/tooltip'; import { ObjectUtils } from 'primeng/utils'; import { style } from '@primeuix/styles/multiselect'; import { BaseStyle } from 'primeng/base'; const MULTISELECT_INSTANCE = new InjectionToken('MULTISELECT_INSTANCE'); const MULTISELECT_ITEM_INSTANCE = new InjectionToken('MULTISELECT_ITEM_INSTANCE'); const inlineStyles = { root: ({ instance }) => ({ position: instance.$appendTo() === 'self' ? 'relative' : undefined }) }; const classes = { root: ({ instance }) => [ 'p-multiselect p-component p-inputwrapper', { 'p-multiselect-display-chip': instance.display() === 'chip', 'p-disabled': instance.$disabled(), 'p-invalid': instance.invalid(), 'p-variant-filled': instance.$variant() === 'filled', 'p-focus': instance.focused, 'p-inputwrapper-filled': instance.$filled(), 'p-inputwrapper-focus': instance.focused || instance.overlayVisible(), 'p-multiselect-open': instance.overlayVisible(), 'p-multiselect-fluid': instance.hasFluid, 'p-multiselect-sm p-inputfield-sm': instance.size() === 'small', 'p-multiselect-lg p-inputfield-lg': instance.size() === 'large' } ], labelContainer: 'p-multiselect-label-container', label: ({ instance }) => ({ 'p-multiselect-label': true, 'p-placeholder': instance.label() === instance.placeholder(), 'p-multiselect-label-empty': !instance.placeholder() && (!instance.modelValue() || instance.modelValue().length === 0) }), clearIcon: 'p-multiselect-clear-icon', chipItem: 'p-multiselect-chip-item', pcChip: 'p-multiselect-chip', chipIcon: 'p-multiselect-chip-icon', dropdown: 'p-multiselect-dropdown', loadingIcon: 'p-multiselect-loading-icon', dropdownIcon: 'p-multiselect-dropdown-icon', overlay: 'p-multiselect-overlay p-component-overlay p-component', header: 'p-multiselect-header', pcFilterContainer: 'p-multiselect-filter-container', pcFilter: 'p-multiselect-filter', listContainer: 'p-multiselect-list-container', list: 'p-multiselect-list', optionGroup: 'p-multiselect-option-group', option: ({ instance }) => ({ 'p-multiselect-option': true, 'p-multiselect-option-selected': instance.selected() && instance.highlightOnSelect(), 'p-disabled': instance.disabled(), 'p-focus': instance.focused() }), emptyMessage: 'p-multiselect-empty-message' }; class MultiSelectStyle extends BaseStyle { name = 'multiselect'; style = style; classes = classes; inlineStyles = inlineStyles; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectStyle, decorators: [{ type: Injectable }] }); /** * * MultiSelect is used to select multiple items from a collection. * * [Live Demo](https://www.primeng.org/multiselect/) * * @module multiselectstyle * */ var MultiSelectClasses; (function (MultiSelectClasses) { /** * Class name of the root element */ MultiSelectClasses["root"] = "p-multiselect"; /** * Class name of the label container element */ MultiSelectClasses["labelContainer"] = "p-multiselect-label-container"; /** * Class name of the label element */ MultiSelectClasses["label"] = "p-multiselect-label"; /** * Class name of the chip item element */ MultiSelectClasses["chipItem"] = "p-multiselect-chip-item"; /** * Class name of the chip element */ MultiSelectClasses["pcChip"] = "p-multiselect-chip"; /** * Class name of the chip icon element */ MultiSelectClasses["chipIcon"] = "p-multiselect-chip-icon"; /** * Class name of the dropdown element */ MultiSelectClasses["dropdown"] = "p-multiselect-dropdown"; /** * Class name of the loading icon element */ MultiSelectClasses["loadingIcon"] = "p-multiselect-loading-icon"; /** * Class name of the dropdown icon element */ MultiSelectClasses["dropdownIcon"] = "p-multiselect-dropdown-icon"; /** * Class name of the overlay element */ MultiSelectClasses["overlay"] = "p-multiselect-overlay"; /** * Class name of the header element */ MultiSelectClasses["header"] = "p-multiselect-header"; /** * Class name of the filter container element */ MultiSelectClasses["pcFilterContainer"] = "p-multiselect-filter-container"; /** * Class name of the filter element */ MultiSelectClasses["pcFilter"] = "p-multiselect-filter"; /** * Class name of the list container element */ MultiSelectClasses["listContainer"] = "p-multiselect-list-container"; /** * Class name of the list element */ MultiSelectClasses["list"] = "p-multiselect-list"; /** * Class name of the option group element */ MultiSelectClasses["optionGroup"] = "p-multiselect-option-group"; /** * Class name of the option element */ MultiSelectClasses["option"] = "p-multiselect-option"; /** * Class name of the empty message element */ MultiSelectClasses["emptyMessage"] = "p-multiselect-empty-message"; /** * Class name of the clear icon */ MultiSelectClasses["clearIcon"] = "p-autocomplete-clear-icon"; })(MultiSelectClasses || (MultiSelectClasses = {})); class MultiSelectItem extends BaseComponent { $pcMultiSelectItem = inject(MULTISELECT_ITEM_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; hostName = 'MultiSelect'; getPTOptions(key) { return this.ptm(key, { context: { selected: this.selected(), focused: this.focused(), disabled: this.disabled() } }); } option = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "option" }] : /* istanbul ignore next */ [])); selected = input(undefined, { ...(ngDevMode ? { debugName: "selected" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); label = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ [])); disabled = input(undefined, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); itemSize = input(undefined, { ...(ngDevMode ? { debugName: "itemSize" } : /* istanbul ignore next */ {}), transform: numberAttribute }); focused = input(undefined, { ...(ngDevMode ? { debugName: "focused" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); ariaPosInset = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "ariaPosInset" }] : /* istanbul ignore next */ [])); ariaSetSize = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "ariaSetSize" }] : /* istanbul ignore next */ [])); variant = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "variant" }] : /* istanbul ignore next */ [])); template = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "template" }] : /* istanbul ignore next */ [])); checkIconTemplate = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "checkIconTemplate" }] : /* istanbul ignore next */ [])); itemCheckboxIconTemplate = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "itemCheckboxIconTemplate" }] : /* istanbul ignore next */ [])); highlightOnSelect = input(undefined, { ...(ngDevMode ? { debugName: "highlightOnSelect" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); onClick = output(); onMouseEnter = output(); _componentStyle = inject(MultiSelectStyle); templateContext = computed(() => ({ $implicit: this.option() }), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "templateContext" }] : /* istanbul ignore next */ [])); getCheckboxIconContext(klass) { return { checked: this.selected(), class: klass }; } onOptionClick(event) { this.onClick.emit({ originalEvent: event, option: this.option(), selected: this.selected() ?? false }); event.stopPropagation(); event.preventDefault(); } onOptionMouseEnter(event) { this.onMouseEnter.emit({ originalEvent: event, option: this.option(), selected: this.selected() ?? false }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectItem, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MultiSelectItem, isStandalone: true, selector: "li[pMultiSelectItem]", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, focused: { classPropertyName: "focused", publicName: "focused", isSignal: true, isRequired: false, transformFunction: null }, ariaPosInset: { classPropertyName: "ariaPosInset", publicName: "ariaPosInset", isSignal: true, isRequired: false, transformFunction: null }, ariaSetSize: { classPropertyName: "ariaSetSize", publicName: "ariaSetSize", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, checkIconTemplate: { classPropertyName: "checkIconTemplate", publicName: "checkIconTemplate", isSignal: true, isRequired: false, transformFunction: null }, itemCheckboxIconTemplate: { classPropertyName: "itemCheckboxIconTemplate", publicName: "itemCheckboxIconTemplate", isSignal: true, isRequired: false, transformFunction: null }, highlightOnSelect: { classPropertyName: "highlightOnSelect", publicName: "highlightOnSelect", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick", onMouseEnter: "onMouseEnter" }, host: { attributes: { "role": "option" }, listeners: { "click": "onOptionClick($event)", "mouseenter": "onOptionMouseEnter($event)" }, properties: { "style.height.px": "itemSize()", "attr.aria-label": "label()", "attr.aria-setsize": "ariaSetSize()", "attr.aria-posinset": "ariaPosInset()", "attr.aria-selected": "selected()", "attr.data-p-selected": "selected()", "attr.data-p-focused": "focused()", "attr.data-p-highlight": "selected()", "attr.data-p-disabled": "disabled()", "attr.aria-checked": "selected()", "class": "cx('option')" } }, providers: [MultiSelectStyle], usesInheritance: true, ngImport: i0, template: ` <p-checkbox [disabled]="disabled() ?? false" [ngModel]="selected()" [binary]="true" [tabindex]="-1" [variant]="variant()" [ariaLabel]="label()" [pt]="getPTOptions('pcOptionCheckbox')" [unstyled]="unstyled()"> @if (itemCheckboxIconTemplate()) { <ng-template #icon let-klass="class"> <ng-container *ngTemplateOutlet="itemCheckboxIconTemplate(); context: getCheckboxIconContext(klass)"></ng-container> </ng-template> } </p-checkbox> @if (!template()) { <span>{{ label() ?? 'empty' }}</span> } <ng-container *ngTemplateOutlet="template(); context: templateContext()"></ng-container> `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Checkbox, selector: "p-checkbox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }], encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectItem, decorators: [{ type: Component, args: [{ selector: 'li[pMultiSelectItem]', standalone: true, imports: [NgTemplateOutlet, Checkbox, FormsModule, SharedModule], template: ` <p-checkbox [disabled]="disabled() ?? false" [ngModel]="selected()" [binary]="true" [tabindex]="-1" [variant]="variant()" [ariaLabel]="label()" [pt]="getPTOptions('pcOptionCheckbox')" [unstyled]="unstyled()"> @if (itemCheckboxIconTemplate()) { <ng-template #icon let-klass="class"> <ng-container *ngTemplateOutlet="itemCheckboxIconTemplate(); context: getCheckboxIconContext(klass)"></ng-container> </ng-template> } </p-checkbox> @if (!template()) { <span>{{ label() ?? 'empty' }}</span> } <ng-container *ngTemplateOutlet="template(); context: templateContext()"></ng-container> `, encapsulation: ViewEncapsulation.None, providers: [MultiSelectStyle], host: { '[style.height.px]': 'itemSize()', '[attr.aria-label]': 'label()', role: 'option', '[attr.aria-setsize]': 'ariaSetSize()', '[attr.aria-posinset]': 'ariaPosInset()', '[attr.aria-selected]': 'selected()', '[attr.data-p-selected]': 'selected()', '[attr.data-p-focused]': 'focused()', '[attr.data-p-highlight]': 'selected()', '[attr.data-p-disabled]': 'disabled()', '[attr.aria-checked]': 'selected()', '(click)': 'onOptionClick($event)', '(mouseenter)': 'onOptionMouseEnter($event)', '[class]': "cx('option')" } }] }], propDecorators: { option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], itemSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemSize", required: false }] }], focused: [{ type: i0.Input, args: [{ isSignal: true, alias: "focused", required: false }] }], ariaPosInset: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaPosInset", required: false }] }], ariaSetSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaSetSize", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], template: [{ type: i0.Input, args: [{ isSignal: true, alias: "template", required: false }] }], checkIconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkIconTemplate", required: false }] }], itemCheckboxIconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemCheckboxIconTemplate", required: false }] }], highlightOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightOnSelect", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }], onMouseEnter: [{ type: i0.Output, args: ["onMouseEnter"] }] } }); const MULTISELECT_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MultiSelect), multi: true }; /** * MultiSelect is used to select multiple items from a collection. * @group Components * @deprecated Use Select component with `multiple` property instead. */ class MultiSelect extends BaseEditableHolder { componentName = 'MultiSelect'; /** * Unique identifier of the component * @group Props */ id = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ [])); /** * Defines a string that labels the input for accessibility. * @group Props */ ariaLabel = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ [])); /** * Inline style of the overlay panel. * @group Props */ panelStyle = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "panelStyle" }] : /* istanbul ignore next */ [])); /** * Style class of the overlay panel element. * @group Props */ panelStyleClass = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "panelStyleClass" }] : /* istanbul ignore next */ [])); /** * Identifier of the focus input to match a label defined for the component. * @group Props */ inputId = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "inputId" }] : /* istanbul ignore next */ [])); /** * When present, it specifies that the component cannot be edited. * @group Props */ readonly = input(undefined, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether to display options as grouped when nested options are provided. * @group Props */ group = input(undefined, { ...(ngDevMode ? { debugName: "group" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When specified, displays an input field to filter the items on keyup. * @group Props */ filter = input(true, { ...(ngDevMode ? { debugName: "filter" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Defines placeholder of the filter input. * @group Props */ filterPlaceHolder = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "filterPlaceHolder" }] : /* istanbul ignore next */ [])); /** * Locale to use in filtering. The default locale is the host environment's current locale. * @group Props */ filterLocale = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "filterLocale" }] : /* istanbul ignore next */ [])); /** * Specifies the visibility of the options panel. * @group Props */ overlayVisible = model(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "overlayVisible" }] : /* istanbul ignore next */ [])); /** * Index of the element in tabbing order. * @group Props */ tabindex = input(0, { ...(ngDevMode ? { debugName: "tabindex" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * A property to uniquely identify a value in options. * @group Props */ dataKey = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "dataKey" }] : /* istanbul ignore next */ [])); /** * Establishes relationships between the component and label(s) where its value should be one or more element IDs. * @group Props */ ariaLabelledBy = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "ariaLabelledBy" }] : /* istanbul ignore next */ [])); /** * Whether to show labels of selected item labels or use default label. * @group Props * @defaultValue true */ displaySelectedLabel = input(true, { ...(ngDevMode ? { debugName: "displaySelectedLabel" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Decides how many selected item labels to show at most. * @group Props * @defaultValue 3 */ maxSelectedLabels = input(3, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maxSelectedLabels" }] : /* istanbul ignore next */ [])); /** * Maximum number of selectable items. * @group Props */ selectionLimit = input(undefined, { ...(ngDevMode ? { debugName: "selectionLimit" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * Label to display after exceeding max selected labels e.g. ({0} items selected), defaults "ellipsis" keyword to indicate a text-overflow. * @group Props */ selectedItemsLabel = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "selectedItemsLabel" }] : /* istanbul ignore next */ [])); /** * Whether to show the checkbox at header to toggle all items at once. * @group Props */ showToggleAll = input(true, { ...(ngDevMode ? { debugName: "showToggleAll" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Text to display when filtering does not return any results. * @group Props */ emptyFilterMessage = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "emptyFilterMessage" }] : /* istanbul ignore next */ [])); /** * Text to display when there is no data. Defaults to global value in i18n translation configuration. * @group Props */ emptyMessage = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ [])); /** * Clears the filter value when hiding the dropdown. * @group Props */ resetFilterOnHide = input(false, { ...(ngDevMode ? { debugName: "resetFilterOnHide" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Icon class of the dropdown icon. * @group Props */ dropdownIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "dropdownIcon" }] : /* istanbul ignore next */ [])); /** * Icon class of the chip icon. * @group Props */ chipIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "chipIcon" }] : /* istanbul ignore next */ [])); /** * Name of the label field of an option. * @group Props */ optionLabel = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "optionLabel" }] : /* istanbul ignore next */ [])); /** * Name of the value field of an option. * @group Props */ optionValue = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "optionValue" }] : /* istanbul ignore next */ [])); /** * Name of the disabled field of an option. * @group Props */ optionDisabled = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "optionDisabled" }] : /* istanbul ignore next */ [])); /** * Name of the label field of an option group. * @group Props */ optionGroupLabel = input('label', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "optionGroupLabel" }] : /* istanbul ignore next */ [])); /** * Name of the options field of an option group. * @group Props */ optionGroupChildren = input('items', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "optionGroupChildren" }] : /* istanbul ignore next */ [])); /** * Whether to show the header. * @group Props */ showHeader = input(true, { ...(ngDevMode ? { debugName: "showHeader" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When filtering is enabled, filterBy decides which field or fields (comma separated) to search against. * @group Props */ filterBy = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "filterBy" }] : /* istanbul ignore next */ [])); /** * Height of the viewport in pixels, a scrollbar is defined if height of list exceeds this value. * @group Props */ scrollHeight = input('200px', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "scrollHeight" }] : /* istanbul ignore next */ [])); /** * Defines if data is loaded and interacted with in lazy manner. * @group Props */ lazy = input(false, { ...(ngDevMode ? { debugName: "lazy" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether the data should be loaded on demand during scroll. * @group Props */ virtualScroll = input(undefined, { ...(ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether the multiselect is in loading state. * @group Props */ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Height of an item in the list for VirtualScrolling. * @group Props */ virtualScrollItemSize = input(undefined, { ...(ngDevMode ? { debugName: "virtualScrollItemSize" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * Icon to display in loading state. * @group Props */ loadingIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "loadingIcon" }] : /* istanbul ignore next */ [])); /** * Whether to use the scroller feature. The properties of scroller component can be used like an object in it. * @group Props */ virtualScrollOptions = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "virtualScrollOptions" }] : /* istanbul ignore next */ [])); /** * Whether to use overlay API feature. The properties of overlay API can be used like an object in it. * @group Props */ overlayOptions = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "overlayOptions" }] : /* istanbul ignore next */ [])); /** * Defines a string that labels the filter input. * @group Props */ ariaFilterLabel = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "ariaFilterLabel" }] : /* istanbul ignore next */ [])); /** * Defines how the items are filtered. * @group Props */ filterMatchMode = input('contains', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "filterMatchMode" }] : /* istanbul ignore next */ [])); /** * Advisory information to display in a tooltip on hover. * @group Props */ tooltip = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ [])); /** * Position of the tooltip. * @group Props */ tooltipPosition = input('right', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ [])); /** * Type of CSS position. * @group Props */ tooltipPositionStyle = input('absolute', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "tooltipPositionStyle" }] : /* istanbul ignore next */ [])); /** * Style class of the tooltip. * @group Props */ tooltipStyleClass = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "tooltipStyleClass" }] : /* istanbul ignore next */ [])); /** * Applies focus to the filter element when the overlay is shown. * @group Props */ autofocusFilter = input(false, { ...(ngDevMode ? { debugName: "autofocusFilter" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Defines how the selected items are displayed. * @group Props */ display = input('comma', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ [])); /** * Defines the autocomplete is active. * @group Props */ autocomplete = input('off', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ [])); /** * When enabled, a clear icon is displayed to clear the value. * @group Props */ showClear = input(false, { ...(ngDevMode ? { debugName: "showClear" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When present, it specifies that the component should automatically get focus on load. * @group Props */ autofocus = input(undefined, { ...(ngDevMode ? { debugName: "autofocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Label to display when there are no selections. * @group Props */ placeholder = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ [])); /** * An array of objects to display as the available options. * @group Props */ options = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "options" }] : /* istanbul ignore next */ [])); /** * When specified, filter displays with this value. * @group Props */ filterValue = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "filterValue" }] : /* istanbul ignore next */ [])); /** * Whether all data is selected. * @group Props */ selectAll = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "selectAll" }] : /* istanbul ignore next */ [])); /** * Indicates whether to focus on options when hovering over them, defaults to optionLabel. * @group Props */ focusOnHover = input(true, { ...(ngDevMode ? { debugName: "focusOnHover" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Fields used when filtering the options, defaults to optionLabel. * @group Props */ filterFields = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "filterFields" }] : /* istanbul ignore next */ [])); /** * Determines if the option will be selected on focus. * @group Props */ selectOnFocus = input(false, { ...(ngDevMode ? { debugName: "selectOnFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether to focus on the first visible or selected element when the overlay panel is shown. * @group Props */ autoOptionFocus = input(false, { ...(ngDevMode ? { debugName: "autoOptionFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether the selected option will be add highlight class. * @group Props */ highlightOnSelect = input(true, { ...(ngDevMode ? { debugName: "highlightOnSelect" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Specifies the size of the component. * @defaultValue undefined * @group Props */ size = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ [])); /** * Specifies the input variant of the component. * @defaultValue undefined * @group Props */ variant = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "variant" }] : /* istanbul ignore next */ [])); /** * Spans 100% width of the container when enabled. * @defaultValue undefined * @group Props */ fluid = input(undefined, { ...(ngDevMode ? { debugName: "fluid" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name). * @defaultValue 'self' * @group Props */ appendTo = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "appendTo" }] : /* istanbul ignore next */ [])); /** * The motion options. * @group Props */ motionOptions = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "motionOptions" }] : /* istanbul ignore next */ [])); /** * Callback to invoke when value changes. * @param {MultiSelectChangeEvent} event - Custom change event. * @group Emits */ onChange = output(); /** * Callback to invoke when data is filtered. * @param {MultiSelectFilterEvent} event - Custom filter event. * @group Emits */ onFilter = output(); /** * Callback to invoke when multiselect receives focus. * @param {MultiSelectFocusEvent} event - Custom focus event. * @group Emits */ onFocus = output(); /** * Callback to invoke when multiselect loses focus. * @param {MultiSelectBlurEvent} event - Custom blur event. * @group Emits */ onBlur = output(); /** * Callback to invoke when component is clicked. * @param {Event} event - Browser event. * @group Emits */ onClick = output(); /** * Callback to invoke when input field is cleared. * @group Emits */ onClear = output(); /** * Callback to invoke when overlay panel becomes visible. * @param {AnimationEvent} event - Animation event. * @group Emits */ onPanelShow = output(); /** * Callback to invoke when overlay panel becomes hidden. * @param {AnimationEvent} event - Animation event. * @group Emits */ onPanelHide = output(); /** * Callback to invoke in lazy mode to load new data. * @param {MultiSelectLazyLoadEvent} event - Lazy load event. * @group Emits */ onLazyLoad = output(); /** * Callback to invoke in lazy mode to load new data. * @param {MultiSelectRemoveEvent} event - Remove event. * @group Emits */ onRemove = output(); /** * Callback to invoke when all data is selected. * @param {MultiSelectSelectAllChangeEvent} event - Custom select event. * @group Emits */ onSelectAllChange = output(); overlayViewChild = viewChild('overlay', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "overlayViewChild" }] : /* istanbul ignore next */ [])); filterInputChild = viewChild('filterInput', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "filterInputChild" }] : /* istanbul ignore next */ [])); focusInputViewChild = viewChild('focusInput', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "focusInputViewChild" }] : /* istanbul ignore next */ [])); itemsViewChild = viewChild('items', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "itemsViewChild" }] : /* istanbul ignore next */ [])); scroller = viewChild('scroller', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ [])); lastHiddenFocusableElementOnOverlay = viewChild('lastHiddenFocusableEl', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "lastHiddenFocusableElementOnOverlay" }] : /* istanbul ignore next */ [])); firstHiddenFocusableElementOnOverlay = viewChild('firstHiddenFocusableEl', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "firstHiddenFocusableElementOnOverlay" }] : /* istanbul ignore next */ [])); headerCheckboxViewChild = viewChild('headerCheckbox', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "headerCheckboxViewChild" }] : /* istanbul ignore next */ [])); footerFacet = contentChild(Footer, { ...(ngDevMode ? { debugName: "footerFacet" } : /* istanbul ignore next */ {}), descendants: false }); headerFacet = contentChild(Header, { ...(ngDevMode ? { debugName: "headerFacet" } : /* istanbul ignore next */ {}), descendants: false }); _componentStyle = inject(MultiSelectStyle); bindDirectiveInstance = inject(Bind, { self: true }); searchValue; searchTimeout = null; _disableTooltip = false; value; _filteredOptions; focus; filtered; /** * Custom item template. * @group Templates */ itemTemplate = contentChild('item', { ...(ngDevMode ? { debugName: "itemTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom group template. * @group Templates */ groupTemplate = contentChild('group', { ...(ngDevMode ? { debugName: "groupTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom loader template. * @group Templates */ loaderTemplate = contentChild('loader', { ...(ngDevMode ? { debugName: "loaderTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom header template. * @group Templates */ headerTemplate = contentChild('header', { ...(ngDevMode ? { debugName: "headerTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom filter template. * @group Templates */ filterTemplate = contentChild('filter', { ...(ngDevMode ? { debugName: "filterTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom footer template. * @group Templates */ footerTemplate = contentChild('footer', { ...(ngDevMode ? { debugName: "footerTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom empty filter template. * @group Templates */ emptyFilterTemplate = contentChild('emptyfilter', { ...(ngDevMode ? { debugName: "emptyFilterTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom empty template. * @group Templates */ emptyTemplate = contentChild('empty', { ...(ngDevMode ? { debugName: "emptyTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom selected items template. * @group Templates */ selectedItemsTemplate = contentChild('selecteditems', { ...(ngDevMode ? { debugName: "selectedItemsTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom loading icon template. * @group Templates */ loadingIconTemplate = contentChild('loadingicon', { ...(ngDevMode ? { debugName: "loadingIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom filter icon template. * @group Templates */ filterIconTemplate = contentChild('filtericon', { ...(ngDevMode ? { debugName: "filterIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom remove token icon template. * @group Templates */ removeTokenIconTemplate = contentChild('removetokenicon', { ...(ngDevMode ? { debugName: "removeTokenIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom chip icon template. * @group Templates */ chipIconTemplate = contentChild('chipicon', { ...(ngDevMode ? { debugName: "chipIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom clear icon template. * @group Templates */ clearIconTemplate = contentChild('clearicon', { ...(ngDevMode ? { debugName: "clearIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom dropdown icon template. * @group Templates */ dropdownIconTemplate = contentChild('dropdownicon', { ...(ngDevMode ? { debugName: "dropdownIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom item checkbox icon template. * @group Templates */ itemCheckboxIconTemplate = contentChild('itemcheckboxicon', { ...(ngDevMode ? { debugName: "itemCheckboxIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom header checkbox icon template. * @group Templates */ headerCheckboxIconTemplate = contentChild('headercheckboxicon', { ...(ngDevMode ? { debugName: "headerCheckboxIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); $variant = computed(() => this.variant() || this.config.inputVariant(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "$variant" }] : /* istanbul ignore next */ [])); $appendTo = computed(() => this.appendTo() || this.config.overlayAppendTo(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "$appendTo" }] : /* istanbul ignore next */ [])); internalId = uuid('pn_id_'); $id = computed(() => this.id() || this.internalId, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "$id" }] : /* istanbul ignore next */ [])); $pcMultiSelect = inject(MULTISELECT_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; pcFluid = inject(Fluid, { optional: true, host: true, skipSelf: true }); translation = toSignal(this.config.translationObserver, { initialValue: this.config.translation }); get hasFluid() { return this.fluid() ?? !!this.pcFluid; } headerCheckboxFocus; filterOptions; preventModelTouched; focused = false; itemsWrapper = null; modelValue = signal(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "modelValue" }] : /* istanbul ignore next */ [])); _filterValue = signal(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "_filterValue" }] : /* istanbul ignore next */ [])); _options = signal([], /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ [])); startRangeIndex = signal(-1, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "startRangeIndex" }] : /* istanbul ignore next */ [])); focusedOptionIndex = signal(-1, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "focusedOptionIndex" }] : /* istanbul ignore next */ [])); selectedOptions = signal(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ [])); clickInProgress = false; emptyMessageLabel = computed(() => { const t = this.translation(); return this.emptyMessage() || t?.emptyMessage || ''; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "emptyMessageLabel" }] : /* istanbul ignore next */ [])); emptyFilterMessageLabel = computed(() => { const t = this.translation(); return this.emptyFilterMessage() || t?.emptyFilterMessage || ''; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "emptyFilterMessageLabel" }] : /* istanbul ignore next */ [])); isVisibleClearIcon = computed(() => { return this.modelValue() != null && this.modelValue() !== '' && isNotEmpty(this.modelValue()) && this.showClear() && !this.$disabled() && !this.readonly() && this.$filled(); }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isVisibleClearIcon" }] : /* istanbul ignore next */ [])); toggleAllAriaLabel = computed(() => { const t = this.translation(); return t?.aria ? t.aria[this.allSelected() ? 'selectAll' : 'unselectAll'] : undefined; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "toggleAllAriaLabel" }] : /* istanbul ignore next */ [])); listLabel = computed(() => { const t = this.translation(); return t?.aria?.listLabel || ''; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "listLabel" }] : /* istanbul ignore next */ [])); placeholderLabel = computed(() => this.placeholder() || 'empty', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "placeholderLabel" }] : /* istanbul ignore next */ [])); labelDisplay = computed(() => this.label() || 'empty', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "labelDisplay" }] : /* istanbul ignore next */ [])); listId = computed(() => this.$id() + '_list', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "listId" }] : /* istanbul ignore next */ [])); getAllVisibleAndNonVisibleOptions() { const group = this.group(); const options = this.options(); return group ? this.flatOptions(options) : options || []; } visibleOptions = computed(() => { const options = this.getAllVisibleAndNonVisibleOptions(); const isArrayOfObjects = isArray(options) && ObjectUtils.isObject(options[0]); const filterVal = this.filterValue() ?? this._filterValue(); const group = this.group(); const filterMatchMode = this.filterMatchMode(); const filterLocale = this.filterLocale(); const optionGroupChildren = this.optionGroupChildren(); if (filterVal) { let filteredOptions; if (isArrayOfObjects) { filteredOptions = this.filterService.filter(options, this.searchFields(), filterVal, filterMatchMode, filterLocale); } else { filteredOptions = options.filter((option) => option.toString().toLocaleLowerCase().includes(filterVal.toLocaleLowerCase())); } if (group) { const optionGroups = this.options() || []; const filtered = []; optionGroups.forEach((grp) => { const groupChildren = this.getOptionGroupChildren(grp); const filteredItems = groupChildren.filter((item) => filteredOptions.includes(item)); if (filteredItems.length > 0) filtered.push({ ...grp, [typeof optionGroupChildren === 'string' ? optionGroupChildren : 'items']: [...filteredItems] }); }); return this.flatOptions(filtered); } return filteredOptions; } return options; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "visibleOptions" }] : /* istanbul ignore next */ [])); label = computed(() => { let label; const modelValue = this.modelValue(); const displaySelectedLabel = this.displaySelectedLabel(); const maxSelectedLabels = this.maxSelectedLabels(); if (modelValue && modelValue?.length && displaySelectedLabel) { if (isNotEmpty(maxSelectedLabels) && modelValue?.length > (maxSelectedLabels || 0)) { return this.getSelectedItemsLabel(); } else { label = ''; for (let i = 0; i < modelValue.length; i++) { if (i !== 0) { label += ', '; } label += this.getLabelByValue(modelValue[i]); } } } else { label = this.placeholder() || ''; } return label; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ [])); chipSelectedItems = computed(() => { const maxSelectedLabels = this.maxSelectedLabels(); return isNotEmpty(maxSelectedLabels) && this.modelValue() && this.modelValue()?.length > (maxSelectedLabels || 0) ? this.modelValue()?.slice(0, maxSelectedLabels) : this.modelValue(); }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "chipSelectedItems" }] : /* istanbul ignore next */ [])); filterService = inject(FilterService); overlayService = inject(OverlayService); constructor() { super(); // Sync options input to internal signal effect(() => { const opts = thi