@progress/kendo-angular-treeview
Version:
Kendo UI TreeView for Angular
746 lines (745 loc) • 34.2 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, HostBinding, Input, TemplateRef, ChangeDetectorRef, Renderer2 } from '@angular/core';
import { trigger, style, animate, transition } from '@angular/animations';
import { getter } from '@progress/kendo-common';
import { ExpandStateService } from './expand-state.service';
import { IndexBuilderService } from './index-builder.service';
import { TreeViewLookupService } from './treeview-lookup.service';
import { NavigationService } from './navigation/navigation.service';
import { NodeChildrenService } from './node-children.service';
import { isPresent, isArray } from './utils';
import { LoadingNotificationService } from './loading-notification.service';
import { Subscription, EMPTY, of } from 'rxjs';
import { catchError, tap, finalize, filter } from 'rxjs/operators';
import { DataChangeNotificationService } from './data-change-notification.service';
import { caretAltDownIcon, caretAltLeftIcon, caretAltRightIcon } from '@progress/kendo-svg-icons';
import { LocalizationService } from '@progress/kendo-angular-l10n';
import { TreeViewItemContentDirective } from './treeview-item-content.directive';
import { LoadingIndicatorDirective } from './loading-indicator.directive';
import { TreeViewItemDirective } from './treeview-item.directive';
import { NgFor, NgClass, NgIf, NgSwitch, NgSwitchCase, NgTemplateOutlet, NgSwitchDefault } from '@angular/common';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { CheckBoxComponent } from '@progress/kendo-angular-inputs';
import * as i0 from "@angular/core";
import * as i1 from "./expand-state.service";
import * as i2 from "./loading-notification.service";
import * as i3 from "./index-builder.service";
import * as i4 from "./treeview-lookup.service";
import * as i5 from "./navigation/navigation.service";
import * as i6 from "./node-children.service";
import * as i7 from "./data-change-notification.service";
import * as i8 from "@progress/kendo-angular-l10n";
const TOP_ITEM = 'k-treeview-top';
const MID_ITEM = 'k-treeview-mid';
const BOT_ITEM = 'k-treeview-bot';
/**
* @hidden
*/
export class TreeViewGroupComponent {
expandService;
loadingService;
indexBuilder;
treeViewLookupService;
navigationService;
nodeChildrenService;
dataChangeNotification;
changeDetectorRef;
localization;
renderer;
/**
* @hidden
*/
caretAltDownIcon = caretAltDownIcon;
/**
* @hidden
*/
caretAltRightIcon = caretAltRightIcon;
/**
* @hidden
*/
caretAltLeftIcon = caretAltLeftIcon;
/**
* @hidden
*/
loadMoreTitle;
kGroupClass = true;
get role() {
return this.parentIndex ? 'group' : 'tree';
}
checkboxes;
expandIcons;
disabled;
selectable;
touchActions;
disableParentNodesOnly;
loadOnDemand = true;
trackBy;
nodes;
textField = "";
parentDataItem;
parentIndex;
nodeTemplateRef;
loadMoreButtonTemplateRef;
loadMoreService;
size = 'medium';
expandDisabledNodes;
initialNodesLoaded = false;
loadingMoreNodes = false;
isItemExpandable = (node, index) => this.expandDisabledNodes || !this.isItemDisabled(node, index);
getFontIcon(node, index) {
return this.isExpanded(node, index) ? 'caret-alt-down' : !this.localization.rtl ? 'caret-alt-right' : 'caret-alt-left';
}
getSvgIcon(node, index) {
return this.isExpanded(node, index) ? caretAltDownIcon : !this.localization.rtl ? caretAltRightIcon : caretAltLeftIcon;
}
get moreNodesAvailable() {
if (!isPresent(this.loadMoreService) || this.data.length === 0) {
return false;
}
return this.pageSize < this.totalNodesCount;
}
get pageSize() {
if (!isPresent(this.loadMoreService)) {
return null;
}
return this.loadMoreService.getGroupSize(this.parentDataItem);
}
set pageSize(pageSize) {
this.loadMoreService.setGroupSize(this.parentDataItem, pageSize);
}
get data() {
if (isPresent(this.pageSize)) {
const normalizedSizeValue = this.pageSize > 0 ? this.pageSize : 0;
return this._data.slice(0, normalizedSizeValue);
}
return this._data;
}
set data(data) {
this._data = data;
this.registerLoadedNodes(this.data);
}
get loadMoreButtonIndex() {
if (!this.loadMoreService) {
return null;
}
return this.nodeIndex(this.data.length);
}
/**
* Represents the total number of nodes for the current level.
*/
get totalNodesCount() {
if (!this.loadMoreService) {
return this.data.length;
}
return this.loadMoreService.getTotalNodesCount(this.parentDataItem, this._data.length);
}
_data = [];
nodesSubscription;
loadMoreNodesSubscription;
singleRecordSubscriptions = new Subscription();
localizationSubscriptions = new Subscription();
constructor(expandService, loadingService, indexBuilder, treeViewLookupService, navigationService, nodeChildrenService, dataChangeNotification, changeDetectorRef, localization, renderer) {
this.expandService = expandService;
this.loadingService = loadingService;
this.indexBuilder = indexBuilder;
this.treeViewLookupService = treeViewLookupService;
this.navigationService = navigationService;
this.nodeChildrenService = nodeChildrenService;
this.dataChangeNotification = dataChangeNotification;
this.changeDetectorRef = changeDetectorRef;
this.localization = localization;
this.renderer = renderer;
}
isChecked = () => 'none';
isDisabled = () => false;
hasCheckbox = () => true;
isExpanded = () => false;
isVisible = () => true;
isSelected = () => false;
children = () => of([]);
hasChildren = () => false;
get hasTemplate() {
return isPresent(this.nodeTemplateRef);
}
expandNode(index, dataItem, expand) {
if (expand) {
this.expandService.expand(index, dataItem);
}
else {
this.expandService.collapse(index, dataItem);
}
}
checkNode(index, checkBox) {
this.navigationService.checkIndex(index);
this.navigationService.activateIndex(index);
if (checkBox?.input) {
this.renderer.removeClass(checkBox.input.nativeElement, 'k-focus');
}
}
nodeIndex(index) {
return this.indexBuilder.nodeIndex(index.toString(), this.parentIndex);
}
nodeText(dataItem) {
const textField = isArray(this.textField) ? this.textField[0] : this.textField;
return getter(textField)(dataItem);
}
getCheckBoxState(item, index) {
const state = this.isChecked(item, index);
if (state === 'indeterminate') {
return state;
}
return state === 'checked';
}
getCheckboxAttributes(index) {
return { 'aria-hidden': 'true', role: 'none', 'aria-labelledby': this.nodeIndex(index) };
}
ngOnDestroy() {
if (isPresent(this.nodesSubscription)) {
this.nodesSubscription.unsubscribe();
}
if (isPresent(this.loadMoreNodesSubscription)) {
this.loadMoreNodesSubscription.unsubscribe();
}
this.singleRecordSubscriptions.unsubscribe();
this.localizationSubscriptions.unsubscribe();
}
ngOnInit() {
this.subscribeToNodesChange();
this.singleRecordSubscriptions.add(this.dataChangeNotification
.changes
.subscribe(this.subscribeToNodesChange.bind(this)));
this.singleRecordSubscriptions.add(this.navigationService.loadMore
.pipe(filter(index => index === this.loadMoreButtonIndex))
.subscribe(this.loadMoreNodes.bind(this)));
this.localizationSubscriptions.add(this.localization.changes.subscribe(this.l10nChange.bind(this)));
}
ngOnChanges(changes) {
if (changes.parentIndex && this.loadOnDemand) {
this.setNodeChildren(this.mapToTreeItem(this.data));
}
if (this.localization.get('loadMore')) {
this.loadMoreTitle = this.localization.get('loadMore');
}
}
l10nChange() {
if (this.localization.get('loadMore')) {
this.loadMoreTitle = this.localization.get('loadMore');
}
this.changeDetectorRef.markForCheck();
}
fetchChildren(node, index) {
return this.children(node)
.pipe(catchError(() => {
this.loadingService.notifyLoaded(index);
return EMPTY;
}), tap(() => this.loadingService.notifyLoaded(index)));
}
get nextFields() {
if (isArray(this.textField)) {
return this.textField.length > 1 ? this.textField.slice(1) : this.textField;
}
return [this.textField];
}
loadMoreNodes() {
if (isPresent(this.loadMoreService.loadMoreNodes)) {
this.fetchMoreNodes();
}
else {
this.loadMoreLocalNodes();
}
}
/**
* @hidden
*/
isItemDisabled(node, index) {
return (this.disabled && !this.disableParentNodesOnly) || this.isDisabled(node, this.nodeIndex(index));
}
/**
* @hidden
*/
setItemClasses(dataLength, index) {
if (dataLength === 1) {
return this.parentIndex ? BOT_ITEM : `${TOP_ITEM} ${BOT_ITEM}`;
}
if (index === 0) {
return TOP_ITEM;
}
if (index > 0 && index < dataLength - 1) {
return MID_ITEM;
}
return index === this.totalNodesCount - 1 ? BOT_ITEM : MID_ITEM;
}
loadMoreLocalNodes() {
const initialLoadMoreButtonIndex = this.loadMoreButtonIndex;
this.pageSize += this.loadMoreService.getInitialPageSize(this.parentDataItem);
this.registerLoadedNodes(this.data);
// forces the new items to be registered before the focus is changed
this.changeDetectorRef.detectChanges();
this.reselectItemAt(initialLoadMoreButtonIndex);
}
fetchMoreNodes() {
if (this.loadingMoreNodes) {
return;
}
this.loadingMoreNodes = true;
if (isPresent(this.loadMoreNodesSubscription)) {
this.loadMoreNodesSubscription.unsubscribe();
}
this.loadMoreNodesSubscription = this.loadMoreService
.loadMoreNodes({
dataItem: this.parentDataItem,
skip: this.data.length,
take: this.loadMoreService.getInitialPageSize(this.parentDataItem)
})
.pipe(finalize(() => this.loadingMoreNodes = false))
.subscribe(items => {
if (!(Array.isArray(items) && items.length > 0)) {
return;
}
const initialLoadMoreButtonIndex = this.loadMoreButtonIndex;
this.pageSize += items.length;
this.data = this.data.concat(items);
if (this.navigationService.isActive(initialLoadMoreButtonIndex)) {
// forces the new items to be registered before the focus is changed
this.changeDetectorRef.detectChanges();
this.reselectItemAt(initialLoadMoreButtonIndex);
}
});
}
setNodeChildren(children) {
this.treeViewLookupService.registerChildren(this.parentIndex, children);
}
mapToTreeItem(data) {
if (!this.parentIndex) {
return [];
}
return data.map((dataItem, idx) => ({ dataItem, index: this.nodeIndex(idx) }));
}
emitChildrenLoaded(children) {
if (!this.parentIndex) {
return;
}
// ignores the registered load-more button
const contentChildren = children.filter(item => item.dataItem);
this.nodeChildrenService.childrenLoaded({ dataItem: this.parentDataItem, index: this.parentIndex }, contentChildren);
}
subscribeToNodesChange() {
if (this.nodesSubscription) {
this.nodesSubscription.unsubscribe();
}
this.nodesSubscription = this.nodes(this.parentDataItem, this.parentIndex)
.subscribe(data => {
this.data = data;
this.initialNodesLoaded = true;
});
}
reselectItemAt(index) {
if (!isPresent(index)) {
return;
}
// make sure the old index is cleared first
this.navigationService.deactivate();
this.navigationService.activateIndex(index);
}
registerLoadedNodes(nodes = []) {
const mappedChildren = this.mapToTreeItem(nodes);
if (this.loadOnDemand) {
this.setNodeChildren(mappedChildren);
}
this.emitChildrenLoaded(mappedChildren);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeViewGroupComponent, deps: [{ token: i1.ExpandStateService }, { token: i2.LoadingNotificationService }, { token: i3.IndexBuilderService }, { token: i4.TreeViewLookupService }, { token: i5.NavigationService }, { token: i6.NodeChildrenService }, { token: i7.DataChangeNotificationService }, { token: i0.ChangeDetectorRef }, { token: i8.LocalizationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TreeViewGroupComponent, isStandalone: true, selector: "[kendoTreeViewGroup]", inputs: { checkboxes: "checkboxes", expandIcons: "expandIcons", disabled: "disabled", selectable: "selectable", touchActions: "touchActions", disableParentNodesOnly: "disableParentNodesOnly", loadOnDemand: "loadOnDemand", trackBy: "trackBy", nodes: "nodes", textField: "textField", parentDataItem: "parentDataItem", parentIndex: "parentIndex", nodeTemplateRef: "nodeTemplateRef", loadMoreButtonTemplateRef: "loadMoreButtonTemplateRef", loadMoreService: "loadMoreService", size: "size", expandDisabledNodes: "expandDisabledNodes", isChecked: "isChecked", isDisabled: "isDisabled", hasCheckbox: "hasCheckbox", isExpanded: "isExpanded", isVisible: "isVisible", isSelected: "isSelected", children: "children", hasChildren: "hasChildren" }, host: { properties: { "class.k-treeview-group": "this.kGroupClass", "attr.role": "this.role" } }, usesOnChanges: true, ngImport: i0, template: `
<li
*ngFor="let node of data; let index = index; trackBy: trackBy"
class="k-treeview-item"
[class.k-hidden]="!isVisible(node, nodeIndex(index))"
kendoTreeViewItem
[attr.aria-setsize]="totalNodesCount"
[dataItem]="node"
[index]="nodeIndex(index)"
[parentDataItem]="parentDataItem"
[parentIndex]="parentIndex"
[loadOnDemand]="loadOnDemand"
[checkable]="checkboxes"
[isChecked]="isChecked(node, nodeIndex(index))"
[isDisabled]="isItemDisabled(node, index)"
[isVisible]="isVisible(node, nodeIndex(index))"
[expandable]="expandIcons && hasChildren(node)"
[isExpanded]="isExpanded(node, nodeIndex(index))"
[selectable]="selectable"
[isSelected]="isSelected(node, nodeIndex(index))"
[attr.data-treeindex]="nodeIndex(index)"
>
<div [ngClass]="setItemClasses(data.length, index)">
<span
[class.k-disabled]="!isItemExpandable(node, index)"
class="k-treeview-toggle"
[kendoTreeViewLoading]="nodeIndex(index)"
(click)="expandNode(nodeIndex(index), node, !isExpanded(node, nodeIndex(index)))"
*ngIf="expandIcons && hasChildren(node)"
>
<kendo-icon-wrapper
[name]="getFontIcon(node, nodeIndex(index))"
[svgIcon]="getSvgIcon(node, nodeIndex(index))">
</kendo-icon-wrapper>
</span>
<kendo-checkbox
#checkbox
*ngIf="checkboxes && hasCheckbox(node, nodeIndex(index))"
[disabled]="isItemDisabled(node, index)"
[size]="size"
[checkedState]="getCheckBoxState(node, nodeIndex(index))"
(checkedStateChange)="checkNode(nodeIndex(index), checkbox)"
[tabindex]="-1"
[inputAttributes]="getCheckboxAttributes(index)"
></kendo-checkbox>
<span kendoTreeViewItemContent
[id]="nodeIndex(index)"
[attr.data-treeindex]="nodeIndex(index)"
[dataItem]="node"
[index]="nodeIndex(index)"
[initialSelection]="isSelected(node, nodeIndex(index))"
[isSelected]="isSelected"
class="k-treeview-leaf"
[style.touch-action]="touchActions ? '' : 'none'"
[class.k-disabled]="isItemDisabled(node, index)"
>
<span class="k-treeview-leaf-text">
<ng-container [ngSwitch]="hasTemplate">
<ng-container *ngSwitchCase="true">
<ng-template
[ngTemplateOutlet]="nodeTemplateRef"
[ngTemplateOutletContext]="{
$implicit: node,
index: nodeIndex(index)
}"
>
</ng-template>
</ng-container>
<ng-container *ngSwitchDefault>
{{nodeText(node)}}
</ng-container>
</ng-container>
</span>
</span>
</div>
<ul
*ngIf="isExpanded(node, nodeIndex(index)) && hasChildren(node)"
kendoTreeViewGroup
role="group"
[size]="size"
[nodes]="fetchChildren"
[loadOnDemand]="loadOnDemand"
[checkboxes]="checkboxes"
[expandIcons]="expandIcons"
[selectable]="selectable"
[touchActions]="touchActions"
[children]="children"
[hasChildren]="hasChildren"
[isChecked]="isChecked"
[isDisabled]="isDisabled"
[hasCheckbox]="hasCheckbox"
[disabled]="isItemDisabled(node, index)"
[expandDisabledNodes]="expandDisabledNodes"
[isExpanded]="isExpanded"
[isSelected]="isSelected"
[isVisible]="isVisible"
[nodeTemplateRef]="nodeTemplateRef"
[loadMoreButtonTemplateRef]="loadMoreButtonTemplateRef"
[parentIndex]="nodeIndex(index)"
[parentDataItem]="node"
[textField]="nextFields"
[loadMoreService]="loadMoreService"
[@toggle]="true"
[trackBy]="trackBy"
[disableParentNodesOnly]="disableParentNodesOnly"
>
</ul>
</li>
<li
*ngIf="initialNodesLoaded && moreNodesAvailable"
class="k-treeview-item"
[class.k-treeview-load-more-checkboxes-container]="checkboxes"
kendoTreeViewItem
role="button"
[selectable]="false"
[checkable]="false"
[expandable]="false"
[index]="loadMoreButtonIndex"
[parentDataItem]="parentDataItem"
[parentIndex]="parentIndex"
[attr.data-treeindex]="loadMoreButtonIndex"
>
<div class="k-treeview-bot">
<span
*ngIf="loadingMoreNodes"
class="k-icon k-i-loading"
>
</span>
<span
class="k-treeview-leaf k-treeview-load-more-button"
[attr.data-treeindex]="loadMoreButtonIndex"
kendoTreeViewItemContent
[index]="loadMoreButtonIndex"
>
<span class="k-treeview-leaf-text">
<ng-template
*ngIf="loadMoreButtonTemplateRef"
[ngTemplateOutlet]="loadMoreButtonTemplateRef"
[ngTemplateOutletContext]="{
index: loadMoreButtonIndex
}"
>
</ng-template>
<ng-container *ngIf="!loadMoreButtonTemplateRef">
{{ loadMoreTitle }}
</ng-container>
</span>
</span>
</div>
</li>
`, isInline: true, dependencies: [{ kind: "component", type: TreeViewGroupComponent, selector: "[kendoTreeViewGroup]", inputs: ["checkboxes", "expandIcons", "disabled", "selectable", "touchActions", "disableParentNodesOnly", "loadOnDemand", "trackBy", "nodes", "textField", "parentDataItem", "parentIndex", "nodeTemplateRef", "loadMoreButtonTemplateRef", "loadMoreService", "size", "expandDisabledNodes", "isChecked", "isDisabled", "hasCheckbox", "isExpanded", "isVisible", "isSelected", "children", "hasChildren"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: TreeViewItemDirective, selector: "[kendoTreeViewItem]", inputs: ["dataItem", "index", "parentDataItem", "parentIndex", "role", "loadOnDemand", "checkable", "selectable", "expandable", "isChecked", "isDisabled", "isVisible", "isExpanded", "isSelected"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: LoadingIndicatorDirective, selector: "[kendoTreeViewLoading]", inputs: ["kendoTreeViewLoading"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }, { kind: "directive", type: TreeViewItemContentDirective, selector: "[kendoTreeViewItemContent]", inputs: ["dataItem", "index", "initialSelection", "isSelected"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }], animations: [
trigger('toggle', [
transition('void => *', [
style({ height: 0 }),
animate('0.1s ease-in', style({ height: "*" }))
]),
transition('* => void', [
style({ height: "*" }),
animate('0.1s ease-in', style({ height: 0 }))
])
])
] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeViewGroupComponent, decorators: [{
type: Component,
args: [{
animations: [
trigger('toggle', [
transition('void => *', [
style({ height: 0 }),
animate('0.1s ease-in', style({ height: "*" }))
]),
transition('* => void', [
style({ height: "*" }),
animate('0.1s ease-in', style({ height: 0 }))
])
])
],
// eslint-disable-next-line
selector: '[kendoTreeViewGroup]',
template: `
<li
*ngFor="let node of data; let index = index; trackBy: trackBy"
class="k-treeview-item"
[class.k-hidden]="!isVisible(node, nodeIndex(index))"
kendoTreeViewItem
[attr.aria-setsize]="totalNodesCount"
[dataItem]="node"
[index]="nodeIndex(index)"
[parentDataItem]="parentDataItem"
[parentIndex]="parentIndex"
[loadOnDemand]="loadOnDemand"
[checkable]="checkboxes"
[isChecked]="isChecked(node, nodeIndex(index))"
[isDisabled]="isItemDisabled(node, index)"
[isVisible]="isVisible(node, nodeIndex(index))"
[expandable]="expandIcons && hasChildren(node)"
[isExpanded]="isExpanded(node, nodeIndex(index))"
[selectable]="selectable"
[isSelected]="isSelected(node, nodeIndex(index))"
[attr.data-treeindex]="nodeIndex(index)"
>
<div [ngClass]="setItemClasses(data.length, index)">
<span
[class.k-disabled]="!isItemExpandable(node, index)"
class="k-treeview-toggle"
[kendoTreeViewLoading]="nodeIndex(index)"
(click)="expandNode(nodeIndex(index), node, !isExpanded(node, nodeIndex(index)))"
*ngIf="expandIcons && hasChildren(node)"
>
<kendo-icon-wrapper
[name]="getFontIcon(node, nodeIndex(index))"
[svgIcon]="getSvgIcon(node, nodeIndex(index))">
</kendo-icon-wrapper>
</span>
<kendo-checkbox
#checkbox
*ngIf="checkboxes && hasCheckbox(node, nodeIndex(index))"
[disabled]="isItemDisabled(node, index)"
[size]="size"
[checkedState]="getCheckBoxState(node, nodeIndex(index))"
(checkedStateChange)="checkNode(nodeIndex(index), checkbox)"
[tabindex]="-1"
[inputAttributes]="getCheckboxAttributes(index)"
></kendo-checkbox>
<span kendoTreeViewItemContent
[id]="nodeIndex(index)"
[attr.data-treeindex]="nodeIndex(index)"
[dataItem]="node"
[index]="nodeIndex(index)"
[initialSelection]="isSelected(node, nodeIndex(index))"
[isSelected]="isSelected"
class="k-treeview-leaf"
[style.touch-action]="touchActions ? '' : 'none'"
[class.k-disabled]="isItemDisabled(node, index)"
>
<span class="k-treeview-leaf-text">
<ng-container [ngSwitch]="hasTemplate">
<ng-container *ngSwitchCase="true">
<ng-template
[ngTemplateOutlet]="nodeTemplateRef"
[ngTemplateOutletContext]="{
$implicit: node,
index: nodeIndex(index)
}"
>
</ng-template>
</ng-container>
<ng-container *ngSwitchDefault>
{{nodeText(node)}}
</ng-container>
</ng-container>
</span>
</span>
</div>
<ul
*ngIf="isExpanded(node, nodeIndex(index)) && hasChildren(node)"
kendoTreeViewGroup
role="group"
[size]="size"
[nodes]="fetchChildren"
[loadOnDemand]="loadOnDemand"
[checkboxes]="checkboxes"
[expandIcons]="expandIcons"
[selectable]="selectable"
[touchActions]="touchActions"
[children]="children"
[hasChildren]="hasChildren"
[isChecked]="isChecked"
[isDisabled]="isDisabled"
[hasCheckbox]="hasCheckbox"
[disabled]="isItemDisabled(node, index)"
[expandDisabledNodes]="expandDisabledNodes"
[isExpanded]="isExpanded"
[isSelected]="isSelected"
[isVisible]="isVisible"
[nodeTemplateRef]="nodeTemplateRef"
[loadMoreButtonTemplateRef]="loadMoreButtonTemplateRef"
[parentIndex]="nodeIndex(index)"
[parentDataItem]="node"
[textField]="nextFields"
[loadMoreService]="loadMoreService"
[@toggle]="true"
[trackBy]="trackBy"
[disableParentNodesOnly]="disableParentNodesOnly"
>
</ul>
</li>
<li
*ngIf="initialNodesLoaded && moreNodesAvailable"
class="k-treeview-item"
[class.k-treeview-load-more-checkboxes-container]="checkboxes"
kendoTreeViewItem
role="button"
[selectable]="false"
[checkable]="false"
[expandable]="false"
[index]="loadMoreButtonIndex"
[parentDataItem]="parentDataItem"
[parentIndex]="parentIndex"
[attr.data-treeindex]="loadMoreButtonIndex"
>
<div class="k-treeview-bot">
<span
*ngIf="loadingMoreNodes"
class="k-icon k-i-loading"
>
</span>
<span
class="k-treeview-leaf k-treeview-load-more-button"
[attr.data-treeindex]="loadMoreButtonIndex"
kendoTreeViewItemContent
[index]="loadMoreButtonIndex"
>
<span class="k-treeview-leaf-text">
<ng-template
*ngIf="loadMoreButtonTemplateRef"
[ngTemplateOutlet]="loadMoreButtonTemplateRef"
[ngTemplateOutletContext]="{
index: loadMoreButtonIndex
}"
>
</ng-template>
<ng-container *ngIf="!loadMoreButtonTemplateRef">
{{ loadMoreTitle }}
</ng-container>
</span>
</span>
</div>
</li>
`,
standalone: true,
imports: [NgFor, TreeViewItemDirective, NgClass, NgIf, LoadingIndicatorDirective, IconWrapperComponent, CheckBoxComponent, TreeViewItemContentDirective, NgSwitch, NgSwitchCase, NgTemplateOutlet, NgSwitchDefault]
}]
}], ctorParameters: function () { return [{ type: i1.ExpandStateService }, { type: i2.LoadingNotificationService }, { type: i3.IndexBuilderService }, { type: i4.TreeViewLookupService }, { type: i5.NavigationService }, { type: i6.NodeChildrenService }, { type: i7.DataChangeNotificationService }, { type: i0.ChangeDetectorRef }, { type: i8.LocalizationService }, { type: i0.Renderer2 }]; }, propDecorators: { kGroupClass: [{
type: HostBinding,
args: ["class.k-treeview-group"]
}], role: [{
type: HostBinding,
args: ["attr.role"]
}], checkboxes: [{
type: Input
}], expandIcons: [{
type: Input
}], disabled: [{
type: Input
}], selectable: [{
type: Input
}], touchActions: [{
type: Input
}], disableParentNodesOnly: [{
type: Input
}], loadOnDemand: [{
type: Input
}], trackBy: [{
type: Input
}], nodes: [{
type: Input
}], textField: [{
type: Input
}], parentDataItem: [{
type: Input
}], parentIndex: [{
type: Input
}], nodeTemplateRef: [{
type: Input
}], loadMoreButtonTemplateRef: [{
type: Input
}], loadMoreService: [{
type: Input
}], size: [{
type: Input
}], expandDisabledNodes: [{
type: Input
}], isChecked: [{
type: Input
}], isDisabled: [{
type: Input
}], hasCheckbox: [{
type: Input
}], isExpanded: [{
type: Input
}], isVisible: [{
type: Input
}], isSelected: [{
type: Input
}], children: [{
type: Input
}], hasChildren: [{
type: Input
}] } });