UNPKG

@progress/kendo-angular-dropdowns

Version:

A wide variety of native Angular dropdown components including AutoComplete, ComboBox, DropDownList, DropDownTree, MultiColumnComboBox, MultiSelect, and MultiSelectTree

282 lines (281 loc) 13 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, Input, Output, EventEmitter, HostBinding, Renderer2, ElementRef } from '@angular/core'; import { TagTemplateDirective } from '../common/templates/tag-template.directive'; import { GroupTagTemplateDirective } from '../common/templates/group-tag-template.directive'; import { getSizeClass, getter, isPresent } from '../common/util'; import { xCircleIcon } from '@progress/kendo-svg-icons'; import { NgFor, NgClass, NgIf } from '@angular/common'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import { TemplateContextDirective } from '@progress/kendo-angular-common'; import * as i0 from "@angular/core"; /** * @hidden */ export class TagListComponent { renderer; hostElement; /** * @hidden */ xCircleIcon = xCircleIcon; tags; textField; valueField; valueDepth; focused; template; groupTemplate; disabled; tagPrefix; id; set size(size) { this.renderer.removeClass(this.hostElement.nativeElement, getSizeClass('chip-list', this.size)); if (size) { this.renderer.addClass(this.hostElement.nativeElement, getSizeClass('chip-list', size)); } this._size = size; } get size() { return this._size; } rounded = 'medium'; fillMode = 'solid'; /** * A collection with the disabled tags' indices. */ disabledIndices = new Set(); removeTag = new EventEmitter(); hostClass = true; get hostId() { return this.id; } taglistRole = 'listbox'; multiselectable = true; _size = 'medium'; constructor(renderer, hostElement) { this.renderer = renderer; this.hostElement = hostElement; } tagProp(tag, prop, index) { const propField = prop && this.getPropField(tag, prop, index); return getter(tag, propField); } isTagDisabled(tag, positionIndex) { if (this.isGroupTag(tag)) { /** The `positionIndex` is used to determine after how many single tags is the group tag displayed => * => it is used to increment the indices inside the group tag so that we determine the actual position index * of each group tag item as they appear in the `value` (important to check against `disabledIndices`) * e.g. `disabledIndices = [0, 1]` && `tags = ['Small', ['Medium', 'Large']]` => without the incrementation with * `positionIndex`, the group tag would yield [0, 1] as indices, while it should yield [1, 2] */ return tag.every((_tag, index) => this.disabledIndices.has(index + positionIndex)); } return this.disabledIndices.has(positionIndex); } deleteTag(event, tag, index) { event.preventDefault(); event.stopImmediatePropagation(); if (!this.disabled && event.which === 1) { this.removeTag.emit({ tag, index }); } } itemId(tag, index) { if (tag) { //because of custom values return this.tagPrefix + "-" + index; } } isGroupTag(tag) { return tag instanceof Array; } tagAriaHidden(index) { return isPresent(this.focused) && this.focused !== index; } getPropField(tag, prop, index) { // Needed for MultiSelectTree value binding (Heterogeneous Data) const fieldsCount = prop.length - 1; if (typeof prop === 'string') { return prop; } else if (this.valueDepth) { const depth = this.valueDepth[index]; return fieldsCount < depth ? prop[fieldsCount] : prop[depth]; } else { return prop.find(item => item in tag); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TagListComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TagListComponent, isStandalone: true, selector: "kendo-taglist", inputs: { tags: "tags", textField: "textField", valueField: "valueField", valueDepth: "valueDepth", focused: "focused", template: "template", groupTemplate: "groupTemplate", disabled: "disabled", tagPrefix: "tagPrefix", id: "id", size: "size", rounded: "rounded", fillMode: "fillMode", disabledIndices: "disabledIndices" }, outputs: { removeTag: "removeTag" }, host: { properties: { "class.k-chip-list": "this.hostClass", "attr.id": "this.hostId", "attr.role": "this.taglistRole", "attr.aria-multiselectable": "this.multiselectable" } }, ngImport: i0, template: ` <div *ngFor="let tag of tags; let index = index;" [attr.id]="itemId(tag, index)" [attr.aria-selected]="true" [attr.role]="'option'" class="k-chip" [ngClass]="{ 'k-focus': index === focused, 'k-disabled': isTagDisabled(tag, index), 'k-chip-sm': size === 'small', 'k-chip-md': size === 'medium', 'k-chip-lg': size === 'large', 'k-rounded-sm': rounded === 'small', 'k-rounded-md': rounded === 'medium', 'k-rounded-lg': rounded === 'large', 'k-rounded-full': rounded === 'full', 'k-chip-solid k-chip-solid-base': fillMode === 'solid', 'k-chip-flat k-chip-flat-base': fillMode === 'flat', 'k-chip-outline k-chip-outline-base': fillMode === 'outline' }" > <span class="k-chip-content"> <ng-template *ngIf="isGroupTag(tag); then groupTag else singleTag"></ng-template> <ng-template #groupTag> <span class="k-chip-label k-text-ellipsis"> <ng-template *ngIf="groupTemplate" [templateContext]="{ templateRef: groupTemplate.templateRef, $implicit: tag }"> </ng-template> <ng-template [ngIf]="!groupTemplate">{{ tag.length }} {{ tag.length === 1 ? 'item' : 'items' }} selected</ng-template> </span> </ng-template> <ng-template #singleTag> <span class="k-chip-label k-text-ellipsis"> <ng-template *ngIf="template" [templateContext]="{ templateRef: template.templateRef, $implicit: tag }"> </ng-template> <ng-template [ngIf]="!template">{{ tagProp(tag, textField, index) }}</ng-template> </span> </ng-template> </span> <span class="k-chip-actions"> <span aria-label="delete" [attr.aria-hidden]="index !== focused" class="k-chip-action k-chip-remove-action"> <kendo-icon-wrapper (mousedown)="deleteTag($event, tag, index)" name="x-circle" [svgIcon]="xCircleIcon" > </kendo-icon-wrapper> </span> </span> </div> <ng-content></ng-content> `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TagListComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-taglist', template: ` <div *ngFor="let tag of tags; let index = index;" [attr.id]="itemId(tag, index)" [attr.aria-selected]="true" [attr.role]="'option'" class="k-chip" [ngClass]="{ 'k-focus': index === focused, 'k-disabled': isTagDisabled(tag, index), 'k-chip-sm': size === 'small', 'k-chip-md': size === 'medium', 'k-chip-lg': size === 'large', 'k-rounded-sm': rounded === 'small', 'k-rounded-md': rounded === 'medium', 'k-rounded-lg': rounded === 'large', 'k-rounded-full': rounded === 'full', 'k-chip-solid k-chip-solid-base': fillMode === 'solid', 'k-chip-flat k-chip-flat-base': fillMode === 'flat', 'k-chip-outline k-chip-outline-base': fillMode === 'outline' }" > <span class="k-chip-content"> <ng-template *ngIf="isGroupTag(tag); then groupTag else singleTag"></ng-template> <ng-template #groupTag> <span class="k-chip-label k-text-ellipsis"> <ng-template *ngIf="groupTemplate" [templateContext]="{ templateRef: groupTemplate.templateRef, $implicit: tag }"> </ng-template> <ng-template [ngIf]="!groupTemplate">{{ tag.length }} {{ tag.length === 1 ? 'item' : 'items' }} selected</ng-template> </span> </ng-template> <ng-template #singleTag> <span class="k-chip-label k-text-ellipsis"> <ng-template *ngIf="template" [templateContext]="{ templateRef: template.templateRef, $implicit: tag }"> </ng-template> <ng-template [ngIf]="!template">{{ tagProp(tag, textField, index) }}</ng-template> </span> </ng-template> </span> <span class="k-chip-actions"> <span aria-label="delete" [attr.aria-hidden]="index !== focused" class="k-chip-action k-chip-remove-action"> <kendo-icon-wrapper (mousedown)="deleteTag($event, tag, index)" name="x-circle" [svgIcon]="xCircleIcon" > </kendo-icon-wrapper> </span> </span> </div> <ng-content></ng-content> `, standalone: true, imports: [NgFor, NgClass, NgIf, TemplateContextDirective, IconWrapperComponent] }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { tags: [{ type: Input }], textField: [{ type: Input }], valueField: [{ type: Input }], valueDepth: [{ type: Input }], focused: [{ type: Input }], template: [{ type: Input }], groupTemplate: [{ type: Input }], disabled: [{ type: Input }], tagPrefix: [{ type: Input }], id: [{ type: Input }], size: [{ type: Input }], rounded: [{ type: Input }], fillMode: [{ type: Input }], disabledIndices: [{ type: Input }], removeTag: [{ type: Output }], hostClass: [{ type: HostBinding, args: ['class.k-chip-list'] }], hostId: [{ type: HostBinding, args: ['attr.id'] }], taglistRole: [{ type: HostBinding, args: ['attr.role'] }], multiselectable: [{ type: HostBinding, args: ['attr.aria-multiselectable'] }] } });