UNPKG

igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,147 lines (1,140 loc) 46.2 kB
import * as i3 from 'igniteui-angular/input-group'; import { IgxPrefixDirective, IgxSuffixDirective } from 'igniteui-angular/input-group'; import * as i0 from '@angular/core'; import { inject, ChangeDetectorRef, ElementRef, Renderer2, DOCUMENT, EventEmitter, TemplateRef, booleanAttribute, HostListener, ViewChild, HostBinding, Output, Input, Component, IterableDiffers, ContentChildren, NgModule } from '@angular/core'; import { IgxDropDirective, IgxDragDirective } from 'igniteui-angular/directives'; import { getCurrentResourceStrings, ChipResourceStringsEN, ɵSize as _Size, rem } from 'igniteui-angular/core'; import { Subject } from 'rxjs'; import { IgxIconComponent } from 'igniteui-angular/icon'; import { NgClass, NgTemplateOutlet } from '@angular/common'; import { takeUntil } from 'rxjs/operators'; const IgxChipTypeVariant = { PRIMARY: 'primary', INFO: 'info', SUCCESS: 'success', WARNING: 'warning', DANGER: 'danger' }; let CHIP_ID = 0; /** * Chip is compact visual component that displays information in an obround. * * @igxModule IgxChipsModule * * @igxTheme igx-chip-theme * * @igxKeywords chip * * @igxGroup display * * @remarks * The Ignite UI Chip can be templated, deleted, and selected. * Multiple chips can be reordered and visually connected to each other. * Chips reside in a container called chips area which is responsible for managing the interactions between the chips. * * @example * ```html * <igx-chip class="chipStyle" [id]="901" [draggable]="true" [removable]="true" (remove)="chipRemoved($event)"> * <igx-avatar class="chip-avatar-resized" igxPrefix></igx-avatar> * </igx-chip> * ``` */ class IgxChipComponent { constructor() { this.cdr = inject(ChangeDetectorRef); this.ref = inject(ElementRef); this.renderer = inject(Renderer2); this.document = inject(DOCUMENT); /** * Sets the value of `id` attribute. If not provided it will be automatically generated. * * @example * ```html * <igx-chip [id]="'igx-chip-1'"></igx-chip> * ``` */ this.id = `igx-chip-${CHIP_ID++}`; /** * Returns the `role` attribute of the chip. * * @example * ```typescript * let chipRole = this.chip.role; * ``` */ this.role = 'option'; /** * Defines if the `IgxChipComponent` can be dragged in order to change it's position. * By default it is set to false. * * @example * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true"></igx-chip> * ``` */ this.draggable = false; /** * Enables/disables the draggable element animation when the element is released. * By default it's set to true. * * @example * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [animateOnRelease]="false"></igx-chip> * ``` */ this.animateOnRelease = true; /** * Enables/disables the hiding of the base element that has been dragged. * By default it's set to true. * * @example * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [hideBaseOnDrag]="false"></igx-chip> * ``` */ this.hideBaseOnDrag = true; /** * Defines if the `IgxChipComponent` should render remove button and throw remove events. * By default it is set to false. * * @example * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [removable]="true"></igx-chip> * ``` */ this.removable = false; /** * Defines if the `IgxChipComponent` can be selected on click or through navigation, * By default it is set to false. * * @example * ```html * <igx-chip [id]="chip.id" [draggable]="true" [removable]="true" [selectable]="true"></igx-chip> * ``` */ this.selectable = false; /** * @hidden * @internal */ this.class = ''; /** * Disables the `IgxChipComponent`. When disabled it restricts user interactions * like focusing on click or tab, selection on click or Space, dragging. * By default it is set to false. * * @example * ```html * <igx-chip [id]="chip.id" [disabled]="true"></igx-chip> * ``` */ this.disabled = false; /** * @hidden * @internal */ this.selectedChange = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` moving starts. * Returns the moving `IgxChipComponent`. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (moveStart)="moveStarted($event)"> * ``` */ this.moveStart = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` moving ends. * Returns the moved `IgxChipComponent`. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (moveEnd)="moveEnded($event)"> * ``` */ this.moveEnd = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` is removed. * Returns the removed `IgxChipComponent`. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (remove)="remove($event)"> * ``` */ this.remove = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` is clicked. * Returns the clicked `IgxChipComponent`, whether the event should be canceled. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (click)="chipClick($event)"> * ``` */ this.chipClick = new EventEmitter(); /** * Emits event when the `IgxChipComponent` is selected/deselected. * Returns the selected chip reference, whether the event should be canceled, what is the next selection state and * when the event is triggered by interaction `originalEvent` is provided, otherwise `originalEvent` is `null`. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (selectedChanging)="chipSelect($event)"> * ``` */ this.selectedChanging = new EventEmitter(); /** * Emits event when the `IgxChipComponent` is selected/deselected and any related animations and transitions also end. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (selectedChanged)="chipSelectEnd($event)"> * ``` */ this.selectedChanged = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` keyboard navigation is being used. * Returns the focused/selected `IgxChipComponent`, whether the event should be canceled, * if the `alt`, `shift` or `control` key is pressed and the pressed key name. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (keyDown)="chipKeyDown($event)"> * ``` */ this.keyDown = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` has entered the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragEnter)="chipEnter($event)"> * ``` */ this.dragEnter = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` has left the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragLeave)="chipLeave($event)"> * ``` */ this.dragLeave = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` is over the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragOver)="chipOver($event)"> * ``` */ this.dragOver = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` has been dropped in the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragDrop)="chipLeave($event)"> * ``` */ this.dragDrop = new EventEmitter(); this.defaultClass = 'igx-chip'; /** * @hidden * @internal */ this.hideBaseElement = false; /** * @hidden * @internal */ this.destroy$ = new Subject(); this._tabIndex = null; this._selected = false; this._selectedItemClass = 'igx-chip__item--selected'; this._movedWhileRemoving = false; this._resourceStrings = getCurrentResourceStrings(ChipResourceStringsEN); } /** * Sets the value of `tabindex` attribute. If not provided it will use the element's tabindex if set. * * @example * ```html * <igx-chip [id]="'igx-chip-1'" [tabIndex]="1"></igx-chip> * ``` */ set tabIndex(value) { this._tabIndex = value; } get tabIndex() { if (this._tabIndex !== null) { return this._tabIndex; } return !this.disabled ? 0 : null; } /** * Sets the `IgxChipComponent` selected state. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [selected]="true"> * ``` * * Two-way data binding: * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [(selected)]="model.isSelected"> * ``` */ set selected(newValue) { this.changeSelection(newValue); } /** * Returns if the `IgxChipComponent` is selected. * * @example * ```typescript * @ViewChild('myChip') * public chip: IgxChipComponent; * selectedChip(){ * let selectedChip = this.chip.selected; * } * ``` */ get selected() { return this._selected; } /** * Sets the `IgxChipComponent` background color. * The `color` property supports string, rgb, hex. * * @example * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [color]="'#ff0000'"></igx-chip> * ``` */ set color(newColor) { this.chipArea.nativeElement.style.backgroundColor = newColor; } /** * Returns the background color of the `IgxChipComponent`. * * @example * ```typescript * @ViewChild('myChip') * public chip: IgxChipComponent; * ngAfterViewInit(){ * let chipColor = this.chip.color; * } * ``` */ get color() { return this.chipArea.nativeElement.style.backgroundColor; } /** * An accessor that sets the resource strings. * By default it uses EN resources. */ set resourceStrings(value) { this._resourceStrings = Object.assign({}, this._resourceStrings, value); } /** * An accessor that returns the resource strings. */ get resourceStrings() { return this._resourceStrings; } get isPrimary() { return this.variant === IgxChipTypeVariant.PRIMARY; } get isInfo() { return this.variant === IgxChipTypeVariant.INFO; } get isSuccess() { return this.variant === IgxChipTypeVariant.SUCCESS; } get isWarning() { return this.variant === IgxChipTypeVariant.WARNING; } get isDanger() { return this.variant === IgxChipTypeVariant.DANGER; } /** * @hidden * @internal */ get removeButtonTemplate() { if (!this.disabled) { return this.removeIcon || this.defaultRemoveIcon; } } /** * @hidden * @internal */ get selectIconTemplate() { return this.selectIcon || this.defaultSelectIcon; } /** * @hidden * @internal */ get ghostStyles() { return { '--ig-size': `${this.chipSize}` }; } /** @hidden @internal */ get nativeElement() { return this.ref.nativeElement; } get chipSize() { return this.computedStyles?.getPropertyValue('--ig-size') || _Size.Medium; } /** * @hidden * @internal */ keyEvent(event) { this.onChipKeyDown(event); } /** * @hidden * @internal */ selectClass(condition) { const SELECT_CLASS = 'igx-chip__select'; return { [SELECT_CLASS]: condition, [`${SELECT_CLASS}--hidden`]: !condition }; } onSelectTransitionDone(event) { if (event.target.tagName) { // Trigger onSelectionDone on when `width` property is changed and the target is valid element(not comment). this.selectedChanged.emit({ owner: this, originalEvent: event }); } } /** * @hidden * @internal */ onChipKeyDown(event) { const keyDownArgs = { originalEvent: event, owner: this, cancel: false }; this.keyDown.emit(keyDownArgs); if (keyDownArgs.cancel) { return; } if ((event.key === 'Delete' || event.key === 'Del') && this.removable) { this.remove.emit({ originalEvent: event, owner: this }); } if ((event.key === ' ' || event.key === 'Spacebar') && this.selectable && !this.disabled) { this.changeSelection(!this.selected, event); } if (event.key !== 'Tab') { event.preventDefault(); } } /** * @hidden * @internal */ onRemoveBtnKeyDown(event) { if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') { this.remove.emit({ originalEvent: event, owner: this }); event.preventDefault(); event.stopPropagation(); } } onRemoveMouseDown(event) { event.stopPropagation(); } /** * @hidden * @internal */ onRemoveClick(event) { this.remove.emit({ originalEvent: event, owner: this }); } /** * @hidden * @internal */ onRemoveTouchMove() { // We don't remove chip if user starting touch interacting on the remove button moves the chip this._movedWhileRemoving = true; } /** * @hidden * @internal */ onRemoveTouchEnd(event) { if (!this._movedWhileRemoving) { this.onRemoveClick(event); } this._movedWhileRemoving = false; } /** * @hidden * @internal */ // ----------------------------- // Start chip igxDrag behavior onChipDragStart(event) { this.moveStart.emit({ originalEvent: event, owner: this }); event.cancel = !this.draggable || this.disabled; } /** * @hidden * @internal */ onChipDragEnd() { if (this.animateOnRelease) { this.dragDirective.transitionToOrigin(); } } /** * @hidden * @internal */ onChipMoveEnd(event) { // moveEnd is triggered after return animation has finished. This happen when we drag and release the chip. this.moveEnd.emit({ originalEvent: event, owner: this }); if (this.selected) { this.chipArea.nativeElement.focus(); } } /** * @hidden * @internal */ onChipGhostCreate() { this.hideBaseElement = this.hideBaseOnDrag; } /** * @hidden * @internal */ onChipGhostDestroy() { this.hideBaseElement = false; } /** * @hidden * @internal */ onChipDragClicked(event) { const clickEventArgs = { originalEvent: event, owner: this, cancel: false }; this.chipClick.emit(clickEventArgs); if (!clickEventArgs.cancel && this.selectable && !this.disabled) { this.changeSelection(!this.selected, event); } } // End chip igxDrag behavior /** * @hidden * @internal */ // ----------------------------- // Start chip igxDrop behavior onChipDragEnterHandler(event) { if (this.dragDirective === event.drag) { return; } const eventArgs = { owner: this, dragChip: event.drag.data?.chip, originalEvent: event }; this.dragEnter.emit(eventArgs); } /** * @hidden * @internal */ onChipDragLeaveHandler(event) { if (this.dragDirective === event.drag) { return; } const eventArgs = { owner: this, dragChip: event.drag.data?.chip, originalEvent: event }; this.dragLeave.emit(eventArgs); } /** * @hidden * @internal */ onChipDrop(event) { // Cancel the default drop logic event.cancel = true; if (this.dragDirective === event.drag) { return; } const eventArgs = { owner: this, dragChip: event.drag.data?.chip, originalEvent: event }; this.dragDrop.emit(eventArgs); } /** * @hidden * @internal */ onChipOverHandler(event) { if (this.dragDirective === event.drag) { return; } const eventArgs = { owner: this, dragChip: event.drag.data?.chip, originalEvent: event }; this.dragOver.emit(eventArgs); } // End chip igxDrop behavior changeSelection(newValue, srcEvent = null) { const onSelectArgs = { originalEvent: srcEvent, owner: this, selected: false, cancel: false }; if (newValue && !this._selected) { onSelectArgs.selected = true; this.selectedChanging.emit(onSelectArgs); if (!onSelectArgs.cancel) { this.renderer.addClass(this.chipArea.nativeElement, this._selectedItemClass); this._selected = newValue; this.selectedChange.emit(this._selected); this.selectedChanged.emit({ owner: this, originalEvent: srcEvent }); } } else if (!newValue && this._selected) { this.selectedChanging.emit(onSelectArgs); if (!onSelectArgs.cancel) { this.renderer.removeClass(this.chipArea.nativeElement, this._selectedItemClass); this._selected = newValue; this.selectedChange.emit(this._selected); this.selectedChanged.emit({ owner: this, originalEvent: srcEvent }); } } } ngOnInit() { this.computedStyles = this.document.defaultView.getComputedStyle(this.nativeElement); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.2", type: IgxChipComponent, isStandalone: true, selector: "igx-chip", inputs: { variant: "variant", id: "id", tabIndex: "tabIndex", data: "data", draggable: ["draggable", "draggable", booleanAttribute], animateOnRelease: ["animateOnRelease", "animateOnRelease", booleanAttribute], hideBaseOnDrag: ["hideBaseOnDrag", "hideBaseOnDrag", booleanAttribute], removable: ["removable", "removable", booleanAttribute], removeIcon: "removeIcon", selectable: ["selectable", "selectable", booleanAttribute], selectIcon: "selectIcon", class: "class", disabled: ["disabled", "disabled", booleanAttribute], selected: ["selected", "selected", booleanAttribute], color: "color", resourceStrings: "resourceStrings" }, outputs: { selectedChange: "selectedChange", moveStart: "moveStart", moveEnd: "moveEnd", remove: "remove", chipClick: "chipClick", selectedChanging: "selectedChanging", selectedChanged: "selectedChanged", keyDown: "keyDown", dragEnter: "dragEnter", dragLeave: "dragLeave", dragOver: "dragOver", dragDrop: "dragDrop" }, host: { listeners: { "keydown": "keyEvent($event)" }, properties: { "attr.id": "this.id", "attr.role": "this.role", "attr.tabIndex": "this.tabIndex", "class.igx-chip--disabled": "this.disabled", "attr.aria-selected": "this.selected", "class.igx-chip": "this.defaultClass", "class.igx-chip--primary": "this.isPrimary", "class.igx-chip--info": "this.isInfo", "class.igx-chip--success": "this.isSuccess", "class.igx-chip--warning": "this.isWarning", "class.igx-chip--danger": "this.isDanger" } }, viewQueries: [{ propertyName: "dragDirective", first: true, predicate: ["chipArea"], descendants: true, read: IgxDragDirective, static: true }, { propertyName: "chipArea", first: true, predicate: ["chipArea"], descendants: true, read: ElementRef, static: true }, { propertyName: "defaultRemoveIcon", first: true, predicate: ["defaultRemoveIcon"], descendants: true, read: TemplateRef, static: true }, { propertyName: "defaultSelectIcon", first: true, predicate: ["defaultSelectIcon"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<div #chipArea class=\"igx-chip__item\"\n [igxDrag]=\"{chip: this}\"\n [style.visibility]='hideBaseElement ? \"hidden\" : \"visible\"'\n ghostClass=\"igx-chip__ghost\"\n [ghostStyle]=\"ghostStyles\"\n (dragStart)=\"onChipDragStart($event)\"\n (ghostCreate)=\"onChipGhostCreate()\"\n (ghostDestroy)=\"onChipGhostDestroy()\"\n (dragEnd)=\"onChipDragEnd()\"\n (transitioned)=\"onChipMoveEnd($event)\"\n (dragClick)=\"onChipDragClicked($event)\"\n igxDrop\n (enter)=\"onChipDragEnterHandler($event)\"\n (leave)=\"onChipDragLeaveHandler($event)\"\n (over)=\"onChipOverHandler($event)\"\n (dropped)=\"onChipDrop($event)\">\n\n <div class=\"igx-chip__start\" #selectContainer>\n @if (selected) {\n <div [ngClass]=\"selectClass(selected)\">\n <ng-container *ngTemplateOutlet=\"selectIconTemplate\"></ng-container>\n </div>\n }\n\n <ng-content select=\"igx-prefix,[igxPrefix]\"></ng-content>\n </div>\n\n <div class=\"igx-chip__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"igx-chip__end\">\n <ng-content select=\"igx-suffix,[igxSuffix]\"></ng-content>\n\n @if (removable) {\n <div class=\"igx-chip__remove\"\n [attr.tabIndex]=\"tabIndex\"\n (keydown)=\"onRemoveBtnKeyDown($event)\"\n (pointerdown)=\"onRemoveMouseDown($event)\"\n (mousedown)=\"onRemoveMouseDown($event)\"\n (click)=\"onRemoveClick($event)\"\n (touchmove)=\"onRemoveTouchMove()\"\n (touchend)=\"onRemoveTouchEnd($event)\">\n <ng-container *ngTemplateOutlet=\"removeButtonTemplate\"></ng-container>\n </div>\n }\n </div>\n</div>\n\n<ng-template #defaultSelectIcon>\n <igx-icon\n [attr.aria-label]=\"resourceStrings.igx_chip_select\"\n family=\"default\"\n name=\"selected\"\n ></igx-icon>\n</ng-template>\n\n<ng-template #defaultRemoveIcon>\n <igx-icon\n [attr.aria-label]=\"resourceStrings.igx_chip_remove\"\n family=\"default\"\n name=\"remove\"\n ></igx-icon>\n</ng-template>\n", dependencies: [{ kind: "directive", type: IgxDropDirective, selector: "[igxDrop]", inputs: ["igxDrop", "dropChannel", "dropStrategy"], outputs: ["enter", "over", "leave", "dropped"], exportAs: ["drop"] }, { kind: "directive", type: IgxDragDirective, selector: "[igxDrag]", inputs: ["igxDrag", "dragTolerance", "dragDirection", "dragChannel", "ghost", "ghostClass", "ghostStyle", "ghostTemplate", "ghostHost", "scrollContainer", "ghostOffsetX", "ghostOffsetY"], outputs: ["dragStart", "dragMove", "dragEnd", "dragClick", "ghostCreate", "ghostDestroy", "transitioned"], exportAs: ["drag"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IgxIconComponent, selector: "igx-icon", inputs: ["ariaHidden", "family", "name", "active"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipComponent, decorators: [{ type: Component, args: [{ selector: 'igx-chip', imports: [IgxDropDirective, IgxDragDirective, NgClass, NgTemplateOutlet, IgxIconComponent], template: "<div #chipArea class=\"igx-chip__item\"\n [igxDrag]=\"{chip: this}\"\n [style.visibility]='hideBaseElement ? \"hidden\" : \"visible\"'\n ghostClass=\"igx-chip__ghost\"\n [ghostStyle]=\"ghostStyles\"\n (dragStart)=\"onChipDragStart($event)\"\n (ghostCreate)=\"onChipGhostCreate()\"\n (ghostDestroy)=\"onChipGhostDestroy()\"\n (dragEnd)=\"onChipDragEnd()\"\n (transitioned)=\"onChipMoveEnd($event)\"\n (dragClick)=\"onChipDragClicked($event)\"\n igxDrop\n (enter)=\"onChipDragEnterHandler($event)\"\n (leave)=\"onChipDragLeaveHandler($event)\"\n (over)=\"onChipOverHandler($event)\"\n (dropped)=\"onChipDrop($event)\">\n\n <div class=\"igx-chip__start\" #selectContainer>\n @if (selected) {\n <div [ngClass]=\"selectClass(selected)\">\n <ng-container *ngTemplateOutlet=\"selectIconTemplate\"></ng-container>\n </div>\n }\n\n <ng-content select=\"igx-prefix,[igxPrefix]\"></ng-content>\n </div>\n\n <div class=\"igx-chip__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"igx-chip__end\">\n <ng-content select=\"igx-suffix,[igxSuffix]\"></ng-content>\n\n @if (removable) {\n <div class=\"igx-chip__remove\"\n [attr.tabIndex]=\"tabIndex\"\n (keydown)=\"onRemoveBtnKeyDown($event)\"\n (pointerdown)=\"onRemoveMouseDown($event)\"\n (mousedown)=\"onRemoveMouseDown($event)\"\n (click)=\"onRemoveClick($event)\"\n (touchmove)=\"onRemoveTouchMove()\"\n (touchend)=\"onRemoveTouchEnd($event)\">\n <ng-container *ngTemplateOutlet=\"removeButtonTemplate\"></ng-container>\n </div>\n }\n </div>\n</div>\n\n<ng-template #defaultSelectIcon>\n <igx-icon\n [attr.aria-label]=\"resourceStrings.igx_chip_select\"\n family=\"default\"\n name=\"selected\"\n ></igx-icon>\n</ng-template>\n\n<ng-template #defaultRemoveIcon>\n <igx-icon\n [attr.aria-label]=\"resourceStrings.igx_chip_remove\"\n family=\"default\"\n name=\"remove\"\n ></igx-icon>\n</ng-template>\n" }] }], propDecorators: { variant: [{ type: Input }], id: [{ type: HostBinding, args: ['attr.id'] }, { type: Input }], role: [{ type: HostBinding, args: ['attr.role'] }], tabIndex: [{ type: HostBinding, args: ['attr.tabIndex'] }, { type: Input }], data: [{ type: Input }], draggable: [{ type: Input, args: [{ transform: booleanAttribute }] }], animateOnRelease: [{ type: Input, args: [{ transform: booleanAttribute }] }], hideBaseOnDrag: [{ type: Input, args: [{ transform: booleanAttribute }] }], removable: [{ type: Input, args: [{ transform: booleanAttribute }] }], removeIcon: [{ type: Input }], selectable: [{ type: Input, args: [{ transform: booleanAttribute }] }], selectIcon: [{ type: Input }], class: [{ type: Input }], disabled: [{ type: HostBinding, args: ['class.igx-chip--disabled'] }, { type: Input, args: [{ transform: booleanAttribute }] }], selected: [{ type: HostBinding, args: ['attr.aria-selected'] }, { type: Input, args: [{ transform: booleanAttribute }] }], selectedChange: [{ type: Output }], color: [{ type: Input }], resourceStrings: [{ type: Input }], moveStart: [{ type: Output }], moveEnd: [{ type: Output }], remove: [{ type: Output }], chipClick: [{ type: Output }], selectedChanging: [{ type: Output }], selectedChanged: [{ type: Output }], keyDown: [{ type: Output }], dragEnter: [{ type: Output }], dragLeave: [{ type: Output }], dragOver: [{ type: Output }], dragDrop: [{ type: Output }], defaultClass: [{ type: HostBinding, args: ['class.igx-chip'] }], isPrimary: [{ type: HostBinding, args: ['class.igx-chip--primary'] }], isInfo: [{ type: HostBinding, args: ['class.igx-chip--info'] }], isSuccess: [{ type: HostBinding, args: ['class.igx-chip--success'] }], isWarning: [{ type: HostBinding, args: ['class.igx-chip--warning'] }], isDanger: [{ type: HostBinding, args: ['class.igx-chip--danger'] }], dragDirective: [{ type: ViewChild, args: ['chipArea', { read: IgxDragDirective, static: true }] }], chipArea: [{ type: ViewChild, args: ['chipArea', { read: ElementRef, static: true }] }], defaultRemoveIcon: [{ type: ViewChild, args: ['defaultRemoveIcon', { read: TemplateRef, static: true }] }], defaultSelectIcon: [{ type: ViewChild, args: ['defaultSelectIcon', { read: TemplateRef, static: true }] }], keyEvent: [{ type: HostListener, args: ['keydown', ['$event']] }] } }); /** * The chip area allows you to perform more complex scenarios with chips that require interaction, * like dragging, selection, navigation, etc. * * @igxModule IgxChipsModule * * @igxTheme igx-chip-theme * * @igxKeywords chip area, chip * * @igxGroup display * * @example * ```html * <igx-chips-area> * <igx-chip *ngFor="let chip of chipList" [id]="chip.id"> * <span>{{chip.text}}</span> * </igx-chip> * </igx-chips-area> * ``` */ class IgxChipsAreaComponent { /** @hidden @internal */ get _widthToRem() { return rem(this.width); } /** @hidden @internal */ get _heightToRem() { return rem(this.height); } constructor() { this.cdr = inject(ChangeDetectorRef); this.element = inject(ElementRef); this._iterableDiffers = inject(IterableDiffers); /** * Returns the `role` attribute of the chips area. * * @example * ```typescript * let chipsAreaRole = this.chipsArea.role; * ``` */ this.role = 'listbox'; /** * Returns the `aria-label` attribute of the chips area. * * @example * ```typescript * let ariaLabel = this.chipsArea.ariaLabel; * ``` * */ this.ariaLabel = 'chip area'; /** * Emits an event when `IgxChipComponent`s in the `IgxChipsAreaComponent` should be reordered. * Returns an array of `IgxChipComponent`s. * * @example * ```html * <igx-chips-area #chipsArea [width]="'300'" [height]="'10'" (onReorder)="changedOrder($event)"></igx-chips-area> * ``` */ this.reorder = new EventEmitter(); /** * Emits an event when an `IgxChipComponent` in the `IgxChipsAreaComponent` is selected/deselected. * Fired after the chips area is initialized if there are initially selected chips as well. * Returns an array of selected `IgxChipComponent`s and the `IgxChipAreaComponent`. * * @example * ```html * <igx-chips-area #chipsArea [width]="'300'" [height]="'10'" (selectionChange)="selection($event)"></igx-chips-area> * ``` */ this.selectionChange = new EventEmitter(); /** * Emits an event when an `IgxChipComponent` in the `IgxChipsAreaComponent` is moved. * * @example * ```html * <igx-chips-area #chipsArea [width]="'300'" [height]="'10'" (moveStart)="moveStart($event)"></igx-chips-area> * ``` */ this.moveStart = new EventEmitter(); /** * Emits an event after an `IgxChipComponent` in the `IgxChipsAreaComponent` is moved. * * @example * ```html * <igx-chips-area #chipsArea [width]="'300'" [height]="'10'" (moveEnd)="moveEnd($event)"></igx-chips-area> * ``` */ this.moveEnd = new EventEmitter(); this.destroy$ = new Subject(); this.hostClass = 'igx-chip-area'; this._differ = null; this._differ = this._iterableDiffers.find([]).create(null); } /** * @hidden * @internal */ ngAfterViewInit() { // If we have initially selected chips through their inputs, we need to get them, because we cannot listen to their events yet. if (this.chipsList.length) { const selectedChips = this.chipsList.filter((item) => item.selected); if (selectedChips.length) { this.selectionChange.emit({ originalEvent: null, newSelection: selectedChips, owner: this }); } } } /** * @hidden * @internal */ ngDoCheck() { if (this.chipsList) { const changes = this._differ.diff(this.chipsList.toArray()); if (changes) { changes.forEachAddedItem((addedChip) => { addedChip.item.moveStart.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { this.onChipMoveStart(args); }); addedChip.item.moveEnd.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { this.onChipMoveEnd(args); }); addedChip.item.dragEnter.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { this.onChipDragEnter(args); }); addedChip.item.keyDown.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { this.onChipKeyDown(args); }); if (addedChip.item.selectable) { addedChip.item.selectedChanging.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { this.onChipSelectionChange(args); }); } }); this.modifiedChipsArray = this.chipsList.toArray(); } } } /** * @hidden * @internal */ ngOnDestroy() { this.destroy$.next(true); this.destroy$.complete(); } /** * @hidden * @internal */ onChipKeyDown(event) { let orderChanged = false; const chipsArray = this.chipsList.toArray(); const dragChipIndex = chipsArray.findIndex((el) => el === event.owner); if (event.originalEvent.shiftKey === true) { if (event.originalEvent.key === 'ArrowLeft' || event.originalEvent.key === 'Left') { orderChanged = this.positionChipAtIndex(dragChipIndex, dragChipIndex - 1, false, event.originalEvent); if (orderChanged) { setTimeout(() => { this.chipsList.get(dragChipIndex - 1).nativeElement.focus(); }); } } else if (event.originalEvent.key === 'ArrowRight' || event.originalEvent.key === 'Right') { orderChanged = this.positionChipAtIndex(dragChipIndex, dragChipIndex + 1, true, event.originalEvent); } } else { if ((event.originalEvent.key === 'ArrowLeft' || event.originalEvent.key === 'Left') && dragChipIndex > 0) { chipsArray[dragChipIndex - 1].nativeElement.focus(); } else if ((event.originalEvent.key === 'ArrowRight' || event.originalEvent.key === 'Right') && dragChipIndex < chipsArray.length - 1) { chipsArray[dragChipIndex + 1].nativeElement.focus(); } } } /** * @hidden * @internal */ onChipMoveStart(event) { this.moveStart.emit({ originalEvent: event.originalEvent, owner: this }); } /** * @hidden * @internal */ onChipMoveEnd(event) { this.moveEnd.emit({ originalEvent: event.originalEvent, owner: this }); } /** * @hidden * @internal */ onChipDragEnter(event) { const dropChipIndex = this.chipsList.toArray().findIndex((el) => el === event.owner); const dragChipIndex = this.chipsList.toArray().findIndex((el) => el === event.dragChip); if (dragChipIndex < dropChipIndex) { // from the left to right this.positionChipAtIndex(dragChipIndex, dropChipIndex, true, event.originalEvent); } else { // from the right to left this.positionChipAtIndex(dragChipIndex, dropChipIndex, false, event.originalEvent); } } /** * @hidden * @internal */ positionChipAtIndex(chipIndex, targetIndex, shiftRestLeft, originalEvent) { if (chipIndex < 0 || this.chipsList.length <= chipIndex || targetIndex < 0 || this.chipsList.length <= targetIndex) { return false; } const chipsArray = this.chipsList.toArray(); const result = []; for (let i = 0; i < chipsArray.length; i++) { if (shiftRestLeft) { if (chipIndex <= i && i < targetIndex) { result.push(chipsArray[i + 1]); } else if (i === targetIndex) { result.push(chipsArray[chipIndex]); } else { result.push(chipsArray[i]); } } else { if (targetIndex < i && i <= chipIndex) { result.push(chipsArray[i - 1]); } else if (i === targetIndex) { result.push(chipsArray[chipIndex]); } else { result.push(chipsArray[i]); } } } this.modifiedChipsArray = result; const eventData = { chipsArray: this.modifiedChipsArray, originalEvent, owner: this }; this.reorder.emit(eventData); return true; } /** * @hidden * @internal */ onChipSelectionChange(event) { let selectedChips = this.chipsList.filter((chip) => chip.selected); if (event.selected && !selectedChips.includes(event.owner)) { selectedChips.push(event.owner); } else if (!event.selected && selectedChips.includes(event.owner)) { selectedChips = selectedChips.filter((chip) => chip.id !== event.owner.id); } this.selectionChange.emit({ originalEvent: event.originalEvent, newSelection: selectedChips, owner: this }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsAreaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.2", type: IgxChipsAreaComponent, isStandalone: true, selector: "igx-chips-area", inputs: { width: "width", height: "height" }, outputs: { reorder: "reorder", selectionChange: "selectionChange", moveStart: "moveStart", moveEnd: "moveEnd" }, host: { properties: { "attr.role": "this.role", "attr.aria-label": "this.ariaLabel", "style.width.rem": "this._widthToRem", "style.height.rem": "this._heightToRem", "class": "this.hostClass" } }, queries: [{ propertyName: "chipsList", predicate: IgxChipComponent, descendants: true }], ngImport: i0, template: "<ng-content></ng-content>\n" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsAreaComponent, decorators: [{ type: Component, args: [{ selector: 'igx-chips-area', standalone: true, template: "<ng-content></ng-content>\n" }] }], ctorParameters: () => [], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }], ariaLabel: [{ type: HostBinding, args: ['attr.aria-label'] }], width: [{ type: Input }], _widthToRem: [{ type: HostBinding, args: ['style.width.rem'] }], height: [{ type: Input }], _heightToRem: [{ type: HostBinding, args: ['style.height.rem'] }], reorder: [{ type: Output }], selectionChange: [{ type: Output }], moveStart: [{ type: Output }], moveEnd: [{ type: Output }], chipsList: [{ type: ContentChildren, args: [IgxChipComponent, { descendants: true }] }], hostClass: [{ type: HostBinding, args: ['class'] }] } }); /* NOTE: Chips directives collection for ease-of-use import in standalone components scenario */ const IGX_CHIPS_DIRECTIVES = [ IgxChipsAreaComponent, IgxChipComponent, IgxPrefixDirective, IgxSuffixDirective ]; /** * @hidden * IMPORTANT: The following is NgModule exported for backwards-compatibility before standalone components */ class IgxChipsModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsModule, imports: [IgxChipsAreaComponent, IgxChipComponent, i3.IgxPrefixDirective, i3.IgxSuffixDirective], exports: [IgxChipsAreaComponent, IgxChipComponent, i3.IgxPrefixDirective, i3.IgxSuffixDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsModule, imports: [IgxChipComponent] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChipsModule, decorators: [{ type: NgModule, args: [{ exports: [ ...IGX_CHIPS_DIRECTIVES ], imports: [ ...IGX_CHIPS_DIRECTIVES ] }] }] }); /** * Generated bundle index. Do not edit. */ export { IGX_CHIPS_DIRECTIVES, IgxChipComponent, IgxChipTypeVariant, IgxChipsAreaComponent, IgxChipsModule }; //# sourceMappingURL=igniteui-angular-chips.mjs.map