@progress/kendo-angular-navigation
Version:
Kendo UI Navigation for Angular
105 lines (104 loc) • 7.06 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Output, Input, EventEmitter, TemplateRef, ViewChildren, QueryList, ElementRef, NgZone } from '@angular/core';
import { fromEvent, merge } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { Keys } from '@progress/kendo-angular-common';
import { BREADCRUMB_ITEM_INDEX } from './models/constants';
import { BreadCrumbItemComponent } from './breadcrumb-item.component';
import { closestItem, itemIndex } from '../common/dom-queries';
import { isPresent } from '../common/util';
import { BreadCrumbSeparatorDirective } from './template-directives/separator.directive';
import { NgFor, NgIf } from '@angular/common';
import * as i0 from "@angular/core";
/**
* @hidden
*/
export class BreadCrumbListComponent {
el;
zone;
items = [];
itemTemplate;
collapseMode = 'auto';
separatorIcon;
separatorSVGIcon;
itemClick = new EventEmitter();
renderedItems;
isRootItemContainer;
domEventsSubscription;
constructor(el, zone) {
this.el = el;
this.zone = zone;
const element = this.el.nativeElement;
this.isRootItemContainer = element.classList.contains('k-breadcrumb-root-item-container');
this.zone.runOutsideAngular(() => {
const click$ = fromEvent(element, 'click');
const enterKey$ = fromEvent(element, 'keydown').pipe(filter((ev) => ev.code === Keys.Enter || ev.code === Keys.NumpadEnter));
this.domEventsSubscription = merge(click$, enterKey$)
.pipe(map((ev) => ev.target), filter(e => !e.classList.contains('k-breadcrumb-delimiter-icon')), // do not trigger handler when a separator is clicked
map(e => this.getItemIndex(e)), filter(isPresent), map(i => parseInt(i, 10)), map(i => this.items[i]), filter(item => !item.data.disabled && !item.context.isLast), map(item => item.data))
.subscribe(el => {
this.zone.run(() => this.itemClick.emit(el));
});
});
}
ngOnDestroy() {
this.domEventsSubscription.unsubscribe();
}
getItemIndex(target) {
const item = closestItem(target, BREADCRUMB_ITEM_INDEX, this.el.nativeElement);
if (item) {
return itemIndex(item, BREADCRUMB_ITEM_INDEX);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BreadCrumbListComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BreadCrumbListComponent, isStandalone: true, selector: "[kendoBreadCrumbList]", inputs: { items: "items", itemTemplate: "itemTemplate", collapseMode: "collapseMode", separatorIcon: "separatorIcon", separatorSVGIcon: "separatorSVGIcon" }, outputs: { itemClick: "itemClick" }, viewQueries: [{ propertyName: "renderedItems", predicate: BreadCrumbItemComponent, descendants: true }], ngImport: i0, template: "\n <ng-container *ngFor=\"let item of items; let i = index; let isFirst = first; let isLast = last\">\n <li\n #renderedItem\n kendoBreadCrumbItem\n *ngIf=\"!(collapseMode === 'wrap' && isFirst) || isRootItemContainer\"\n [attr.data-kendo-breadcrumb-index]=\"i\"\n [item]=\"item\"\n [index]=\"i\"\n [collapseMode]=\"collapseMode\"\n [itemTemplate]=\"itemTemplate\"\n >\n <span kendoBreadCrumbSeparator [icon]=\"separatorIcon\" [svgIcon]=\"separatorSVGIcon\" *ngIf=\"collapseMode === 'wrap' && !isFirst\"></span>\n <span\n kendoBreadCrumbSeparator\n [icon]=\"separatorIcon\"\n [svgIcon]=\"separatorSVGIcon\"\n *ngIf=\"collapseMode !== 'wrap' && !isLast && !(item?.context.collapsed && items[i + 1]?.context.collapsed)\"\n ></span>\n </li>\n </ng-container>\n ", isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: BreadCrumbItemComponent, selector: "[kendoBreadCrumbItem]", inputs: ["item", "collapseMode", "index", "itemTemplate"] }, { kind: "component", type: BreadCrumbSeparatorDirective, selector: "[kendoBreadCrumbSeparator]", inputs: ["icon", "svgIcon"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BreadCrumbListComponent, decorators: [{
type: Component,
args: [{
// eslint-disable-next-line @angular-eslint/component-selector
selector: '[kendoBreadCrumbList]',
template: `
<ng-container *ngFor="let item of items; let i = index; let isFirst = first; let isLast = last">
<li
#renderedItem
kendoBreadCrumbItem
*ngIf="!(collapseMode === 'wrap' && isFirst) || isRootItemContainer"
[attr.${BREADCRUMB_ITEM_INDEX}]="i"
[item]="item"
[index]="i"
[collapseMode]="collapseMode"
[itemTemplate]="itemTemplate"
>
<span kendoBreadCrumbSeparator [icon]="separatorIcon" [svgIcon]="separatorSVGIcon" *ngIf="collapseMode === 'wrap' && !isFirst"></span>
<span
kendoBreadCrumbSeparator
[icon]="separatorIcon"
[svgIcon]="separatorSVGIcon"
*ngIf="collapseMode !== 'wrap' && !isLast && !(item?.context.collapsed && items[i + 1]?.context.collapsed)"
></span>
</li>
</ng-container>
`,
standalone: true,
imports: [NgFor, NgIf, BreadCrumbItemComponent, BreadCrumbSeparatorDirective]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { items: [{
type: Input
}], itemTemplate: [{
type: Input
}], collapseMode: [{
type: Input
}], separatorIcon: [{
type: Input
}], separatorSVGIcon: [{
type: Input
}], itemClick: [{
type: Output
}], renderedItems: [{
type: ViewChildren,
args: [BreadCrumbItemComponent]
}] } });