UNPKG

@progress/kendo-angular-treeview

Version:
928 lines (927 loc) 39.5 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input, NgZone, Output, Renderer2, ViewChild, ViewContainerRef, isDevMode, forwardRef, ChangeDetectorRef } from '@angular/core'; import { anyChanged, hasObservers, isDocumentAvailable } from '@progress/kendo-angular-common'; import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n'; import { BehaviorSubject, of, Subscription } from 'rxjs'; import { validatePackage } from '@progress/kendo-licensing'; import { packageMetadata } from './package-metadata'; import { DataChangeNotificationService } from './data-change-notification.service'; import { hasCheckbox, hasChildren, isChecked, isDisabled, isExpanded, isSelected, isVisible, trackBy } from './default-callbacks'; import { ExpandStateService } from './expand-state.service'; import { IndexBuilderService } from './index-builder.service'; import { LoadingNotificationService } from './loading-notification.service'; import { NavigationService } from './navigation/navigation.service'; import { NodeChildrenService } from './node-children.service'; import { NodeTemplateDirective } from './node-template.directive'; import { LoadMoreButtonTemplateDirective } from './load-more/load-more-button-template.directive'; import { DataBoundComponent } from './data-bound-component'; import { ExpandableComponent } from './expandable-component'; import { SelectionService } from './selection/selection.service'; import { TreeViewLookupService } from './treeview-lookup.service'; import { closestNode, focusableNode, hasParent, isContent, isFocusable, match, nodeId, isLoadMoreButton, isPresent, nodeIndex, buildTreeItem, getSizeClass } from './utils'; import { searchIcon } from '@progress/kendo-svg-icons'; import { TextBoxComponent, TextBoxPrefixTemplateDirective } from '@progress/kendo-angular-inputs'; import { TreeViewGroupComponent } from './treeview-group.component'; import { NgIf } from '@angular/common'; import { LocalizedMessagesDirective } from './localization/localized-messages.directive'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import * as i0 from "@angular/core"; import * as i1 from "./expand-state.service"; import * as i2 from "./navigation/navigation.service"; import * as i3 from "./node-children.service"; import * as i4 from "./selection/selection.service"; import * as i5 from "./treeview-lookup.service"; import * as i6 from "./data-change-notification.service"; import * as i7 from "@progress/kendo-angular-l10n"; let nextId = 0; const LOAD_MORE_DOC_LINK = 'https://www.telerik.com/kendo-angular-ui/components/treeview/load-more-button/'; const providers = [ ExpandStateService, IndexBuilderService, TreeViewLookupService, LoadingNotificationService, NodeChildrenService, NavigationService, SelectionService, DataChangeNotificationService, LocalizationService, { provide: L10N_PREFIX, useValue: 'kendo.treeview' }, { provide: DataBoundComponent, useExisting: forwardRef(() => TreeViewComponent) }, { provide: ExpandableComponent, useExisting: forwardRef(() => TreeViewComponent) } ]; /** * Represents the [Kendo UI TreeView component for Angular]({% slug overview_treeview %}). * */ export class TreeViewComponent { element; changeDetectorRef; expandService; navigationService; nodeChildrenService; selectionService; treeViewLookupService; ngZone; renderer; dataChangeNotification; localization; /** * @hidden */ searchIcon = searchIcon; classNames = true; /** @hidden */ get direction() { return this.localization.rtl ? 'rtl' : 'ltr'; } /** * @hidden */ assetsContainer; /** * @hidden */ searchbox; /** * The hint which is displayed when the component is empty. */ filterInputPlaceholder = ""; /** * Determines whether to allow expanding disabled nodes. * @default false */ expandDisabledNodes; /** * Determines whether the content animation is enabled. */ set animate(value) { this._animate = value; } get animate() { return !this._animate; } /** @hidden */ fetchNodes = () => this.data; /** * Fires when the children of the expanded node are loaded. */ childrenLoaded = new EventEmitter(); /** * Fires when the user blurs the component. */ onBlur = new EventEmitter(); /** * Fires when the user focuses the component. */ onFocus = new EventEmitter(); /** * Fires when the user expands a TreeView node. */ expand = new EventEmitter(); /** * Fires when the user collapses a TreeView node. */ collapse = new EventEmitter(); /** * Fires just before the dragging of the node starts ([see example]({% slug draganddrop_treeview %}#toc-setup)). This event is preventable. * If you prevent the event default, no drag hint will be created and the subsequent drag-related events will not be fired. */ nodeDragStart = new EventEmitter(); /** * Fires when an item is being dragged ([see example]({% slug draganddrop_treeview %}#toc-setup)). */ nodeDrag = new EventEmitter(); /** * Emits when the built-in filtering mechanism in the data-binding directives updates the node's visibility. * Used for the built-in auto-expand functionalities of the component and available for custom implementations. */ filterStateChange = new EventEmitter(); /** * Fires on the target TreeView when a dragged item is dropped ([see example]({% slug draganddrop_treeview %}#toc-setup)). * This event is preventable. If you prevent the event default (`event.preventDefualt()`) or invalidate its state (`event.setValid(false)`), * the `addItem` and `removeItem` events will not be triggered. * * Both operations cancel the default drop operation, but the indication to the user is different. `event.setValid(false)` indicates that the operation was * unsuccessful by animating the drag clue to its original position. `event.preventDefault()` simply removes the clue, as if it has been dropped successfully. * As a general rule, use `preventDefault` to manually handle the add and remove operations, and `setValid(false)` to indicate the operation was unsuccessful. */ nodeDrop = new EventEmitter(); /** * Fires on the source TreeView after the dragged item has been dropped ([see example]({% slug draganddrop_treeview %}#toc-setup)). */ nodeDragEnd = new EventEmitter(); /** * Fires after a dragged item is dropped ([see example]({% slug draganddrop_treeview %}#toc-setup)). * Called on the TreeView where the item is dropped. */ addItem = new EventEmitter(); /** * Fires after a dragged item is dropped ([see example]({% slug draganddrop_treeview %}#toc-setup)). * Called on the TreeView from where the item is dragged. */ removeItem = new EventEmitter(); /** * Fires when the user selects a TreeView node checkbox * ([see example]({% slug checkboxes_treeview %}#toc-modifying-the-checked-state)). */ checkedChange = new EventEmitter(); /** * Fires when the user selects a TreeView node * ([see example]({% slug selection_treeview %}#toc-modifying-the-selection)). */ selectionChange = new EventEmitter(); /** * Fires when the value of the built-in filter input element changes. */ filterChange = new EventEmitter(); /** * Fires when the user clicks a TreeView node. */ nodeClick = new EventEmitter(); /** * Fires when the user double clicks a TreeView node. */ nodeDblClick = new EventEmitter(); /** * @hidden * * Queries the template for a node template declaration. * Ignored if a `[nodeTemplate]` value is explicitly provided. */ nodeTemplateQuery; /** * @hidden * * Defines the template for each node. * Takes precedence over nested templates in the TreeView tag. */ set nodeTemplateRef(template) { this._nodeTemplateRef = template; } get nodeTemplateRef() { return this._nodeTemplateRef || this.nodeTemplateQuery; } /** * @hidden * * Queries the template for a load-more button template declaration. * Ignored if a `[loadMoreButtonTemplate]` value is explicitly provided. */ loadMoreButtonTemplateQuery; /** * @hidden * * Defines the template for each load-more button. * Takes precedence over nested templates in the TreeView tag. */ set loadMoreButtonTemplateRef(template) { this._loadMoreButtonTemplateRef = template; } get loadMoreButtonTemplateRef() { return this._loadMoreButtonTemplateRef || this.loadMoreButtonTemplateQuery; } /** * A function that defines how to track node changes. * By default, the TreeView tracks the nodes by data item object reference. * * @example * ```ts * @Component({ * selector: 'my-app', * template: ` * <kendo-treeview * [nodes]="data" * textField="text" * [trackBy]="trackBy" * > * </kendo-treeview> * ` * }) * export class AppComponent { * public data: any[] = [ * { text: "Furniture" }, * { text: "Decor" } * ]; * * public trackBy(index: number, item: any): any { * return item.text; * } * } * ``` */ trackBy = trackBy; /** * The nodes which will be displayed by the TreeView * ([see example]({% slug databinding_treeview %})). */ set nodes(value) { this.data.next(value || []); this.dataChangeNotification.notify(); } get nodes() { return this.data.value; } /** * The fields of the data item that provide the text content of the nodes * ([see example]({% slug databinding_treeview %})). If the `textField` input is set * to an array, each hierarchical level uses the field that corresponds to the same * index in the array, or the last item in the array. */ textField; /** * A function which determines if a specific node has child nodes * ([see example]({% slug databinding_treeview %})). */ get hasChildren() { return this._hasChildren || hasChildren; } set hasChildren(callback) { this._hasChildren = callback; this.expandIcons = Boolean(this._isExpanded && this._hasChildren); } /** * A function which determines if a specific node is checked * ([see example]({% slug checkboxes_treeview %}#toc-modifying-the-checked-state)). */ get isChecked() { return this._isChecked || isChecked; } set isChecked(callback) { this._isChecked = callback; this.checkboxes = Boolean(this._isChecked); } /** * A function which determines if a specific node is disabled. */ isDisabled = isDisabled; /** * A function which determines if a specific node has a checkbox. * * > If there is no checkbox for a node, then this node is not checkable and is excluded from any built-in check functionality. */ hasCheckbox = hasCheckbox; /** * A function which determines if a specific node is expanded. */ get isExpanded() { return this._isExpanded || isExpanded; } set isExpanded(callback) { this._isExpanded = callback; this.expandIcons = Boolean(this._isExpanded && this._hasChildren); } /** * A function which determines if a specific node is selected * ([see example]({% slug selection_treeview %}#toc-modifying-the-selection)). */ get isSelected() { return this._isSelected || isSelected; } set isSelected(callback) { this._isSelected = callback; this.selectable = Boolean(this._isSelected); } /** * A callback which determines whether a TreeView node should be rendered as hidden. The utility .k-hidden class is used to hide the nodes. * Useful for custom filtering implementations. */ isVisible = isVisible; /** * Determines whether the TreeView keyboard navigable is enabled. */ navigable = true; /** * A function which provides the child nodes for a given parent node * ([see example]({% slug databinding_treeview %})). */ children = () => of([]); /** * Indicates whether the child nodes will be fetched on node expand or will be initially prefetched. * @default true */ loadOnDemand = true; /** * Renders the built-in input element for filtering the TreeView. * If set to `true`, the component emits the `filterChange` event, which can be used to [filter the TreeView manually]({% slug filtering_treeview %}#toc-manual-filtering). * A built-in filtering implementation is available to use with the [`kendoTreeViewHierarchyBinding`]({% slug api_treeview_hierarchybindingdirective %}) and [`kendoTreeViewFlatDataBinding`]({% slug api_treeview_flatdatabindingdirective %}) directives. */ filterable = false; /** * Sets an initial value of the built-in input element used for filtering. */ filter = ''; /** * Sets the size of the component. * * The possible values are: * * `small` * * `medium` (default) * * `large` * * `none` */ set size(size) { const newSize = size ? size : 'medium'; if (this.size !== 'none') { this.renderer.removeClass(this.element.nativeElement, getSizeClass('treeview', this.size)); } this.renderer.addClass(this.element.nativeElement, getSizeClass('treeview', newSize)); this._size = size; } get size() { return this._size; } get isActive() { return this.navigationService.isTreeViewActive; } /** * @hidden */ get treeviewId() { return `treeview_${this._nextId}`; } /** * Indicates whether only parent nodes should be disabled or their child nodes as well * @default false */ disableParentNodesOnly = false; /** * @hidden */ loadMoreService; /** * @hidden */ editService; checkboxes = false; expandIcons = false; selectable = false; touchActions = true; data = new BehaviorSubject([]); _animate = true; _isChecked; _isExpanded; _isSelected; _hasChildren; _nodeTemplateRef; _loadMoreButtonTemplateRef; _size = 'medium'; subscriptions = new Subscription(); domSubscriptions = []; _nextId = nextId; constructor(element, changeDetectorRef, expandService, navigationService, nodeChildrenService, selectionService, treeViewLookupService, ngZone, renderer, dataChangeNotification, localization) { this.element = element; this.changeDetectorRef = changeDetectorRef; this.expandService = expandService; this.navigationService = navigationService; this.nodeChildrenService = nodeChildrenService; this.selectionService = selectionService; this.treeViewLookupService = treeViewLookupService; this.ngZone = ngZone; this.renderer = renderer; this.dataChangeNotification = dataChangeNotification; this.localization = localization; validatePackage(packageMetadata); nextId++; } ngOnChanges(changes) { this.navigationService.navigable = Boolean(this.navigable); // TODO: should react to changes.loadOnDemand as well - should preload the data or clear the already cached items if (anyChanged(['nodes', 'children', 'hasChildren', 'loadOnDemand'], changes, false) && !this.loadOnDemand) { this.preloadChildNodes(); } } ngOnDestroy() { this.subscriptions.unsubscribe(); this.domSubscriptions.forEach(subscription => subscription()); } ngOnInit() { this.subscriptions.add(this.nodeChildrenService .changes .subscribe((x) => this.childrenLoaded.emit(x))); this.subscriptions.add(this.expandService.changes .subscribe(({ index, dataItem, expand }) => expand ? this.expand.emit({ index, dataItem }) : this.collapse.emit({ index, dataItem }))); this.subscriptions.add(this.navigationService.checks .subscribe((x) => this.checkedChange.emit(this.treeViewLookupService.itemLookup(x)))); this.subscriptions.add(this.selectionService.changes .subscribe((x) => { if (hasObservers(this.selectionChange)) { this.ngZone.run(() => { this.selectionChange.emit(x); }); } })); if (this.element) { this.ngZone.runOutsideAngular(() => { this.attachDomHandlers(); }); } if (this.size) { this.renderer.addClass(this.element.nativeElement, getSizeClass('treeview', this.size)); } } ngAfterViewInit() { if (this.searchbox) { this.renderer.setAttribute(this.searchbox.input.nativeElement, 'role', 'searchbox'); this.renderer.setAttribute(this.searchbox.input.nativeElement, 'aria-controls', this.treeviewId); this.renderer.setAttribute(this.searchbox.input.nativeElement, 'aria-label', 'searchbar'); } } /** * Blurs the focused TreeView item. */ blur() { if (!isDocumentAvailable()) { return; } const target = focusableNode(this.element); if (document.activeElement === target) { target.blur(); } } /** * Focuses the first focusable item in the TreeView component if no hierarchical index is provided. * * @example * ```ts * import { Component } from '@angular/core'; * * @Component({ * selector: 'my-app', * template: ` * <button (click)="treeview.focus('1')">Focuses the second node</button> * <kendo-treeview * #treeview * [nodes]="data" * textField="text" * > * </kendo-treeview> * ` * }) * export class AppComponent { * public data: any[] = [ * { text: "Furniture" }, * { text: "Decor" } * ]; * } * ``` */ focus(index) { const focusIndex = index || nodeIndex(this.navigationService.focusableItem); this.navigationService.activateIndex(focusIndex); const target = focusableNode(this.element); if (target) { target.focus(); } } /** * Based on the specified index, returns the TreeItemLookup node. * * @param index - The index of the node. * @returns {TreeItemLookup} - The item that was searched (looked up). */ itemLookup(index) { return this.treeViewLookupService.itemLookup(index); } /** * Triggers the [`children`]({% slug api_treeview_treeviewcomponent %}#toc-children) function for every expanded node, * causing all rendered child nodes to be fetched again. */ rebindChildren() { this.dataChangeNotification.notify(); } /** * Triggers the `expand` event for the provided node and displays it's loading indicator. */ expandNode(item, index) { this.expandService.expand(index, item); } /** * Triggers the `collapse` event for the provided node. */ collapseNode(item, index) { this.expandService.collapse(index, item); } /** * Gets the current page size of the checked data item children collection * ([see example]({% slug loadmorebutton_treeview %}#toc-managing-page-sizes)). * * > Since the root nodes collection is not associated with any parent data item, pass `null` as `dataItem` param to get its page size. * * @param dataItem {any} - The parent data item of the targeted collection. * @returns {number} - The page size of the checked data item children collection. */ getNodePageSize(dataItem) { this.verifyLoadMoreService(); return this.loadMoreService.getGroupSize(dataItem); } /** * Sets the page size of the targeted data item children collection * ([see example]({% slug loadmorebutton_treeview %}#toc-managing-page-sizes)). * * > Since the root nodes collection is not associated with any parent data item, pass `null` as `dataItem` param to target its page size. * * @param dataItem {any} - The parent data item of the targeted collection. * @param pageSize {number} - The new page size. */ setNodePageSize(dataItem, pageSize) { this.verifyLoadMoreService(); this.loadMoreService.setGroupSize(dataItem, pageSize); } /** * @hidden * * Clears the current TreeViewLookupService node map and re-registers all nodes anew. * Child nodes are acquired through the provided `children` callback. */ preloadChildNodes() { this.treeViewLookupService.reset(); this.registerLookupItems(this.nodes); } attachDomHandlers() { const element = this.element.nativeElement; this.clickHandler = this.clickHandler.bind(this); this.domSubscriptions.push(this.renderer.listen(element, 'contextmenu', this.clickHandler), this.renderer.listen(element, 'click', this.clickHandler), this.renderer.listen(element, 'dblclick', this.clickHandler), this.renderer.listen(element, 'focusin', this.focusHandler.bind(this)), this.renderer.listen(element, 'focusout', this.blurHandler.bind(this)), this.renderer.listen(element, 'keydown', this.keydownHandler.bind(this))); } focusHandler(e) { let focusItem; if (match(e.target, '.k-treeview-item')) { focusItem = e.target; } else if (!isFocusable(e.target)) { // with compliments to IE focusItem = closestNode(e.target); } if (focusItem) { const nodeIndex = nodeId(e.target); if (this.navigationService.isDisabled(nodeIndex)) { return; } this.navigationService.activateIndex(nodeIndex); if (!this.isActive && hasObservers(this.onFocus)) { this.ngZone.run(() => { this.onFocus.emit(); }); } this.navigationService.isTreeViewActive = true; } } blurHandler(e) { if (this.isActive && match(e.target, '.k-treeview-item') && (!e.relatedTarget || !match(e.relatedTarget, '.k-treeview-item') || !hasParent(e.relatedTarget, this.element.nativeElement))) { this.navigationService.deactivate(); this.navigationService.isTreeViewActive = false; if (hasObservers(this.onBlur)) { this.ngZone.run(() => { this.onBlur.emit(); }); } } } clickHandler(e) { const target = e.target; if ((e.type === 'contextmenu' && !hasObservers(this.nodeClick)) || (e.type === 'click' && !hasObservers(this.nodeClick) && !hasObservers(this.selectionChange) && !isLoadMoreButton(target)) || (e.type === 'dblclick' && !hasObservers(this.nodeDblClick)) || isFocusable(target) || (!isContent(target) && !isLoadMoreButton(target)) || !hasParent(target, this.element.nativeElement)) { return; } const index = nodeId(closestNode(target)); // the disabled check is probably not needed due to the k-disabled styles if (!index || this.navigationService.isDisabled(index)) { return; } this.ngZone.run(() => { // record this value before emitting selectionChange (`this.navigationService.selectIndex`), as the treeview state may be changed on its emission const lookup = this.treeViewLookupService.itemLookup(index); if (e.type === 'click') { const loadMoreButton = this.navigationService.model.findNode(index).loadMoreButton; if (loadMoreButton) { this.navigationService.notifyLoadMore(index); return; } else { this.navigationService.selectIndex(index); } } const emitter = e.type === 'dblclick' ? this.nodeDblClick : this.nodeClick; emitter.emit({ item: lookup.item, originalEvent: e, type: e.type }); }); } keydownHandler(e) { if (this.isActive && this.navigable) { this.ngZone.run(() => { this.navigationService.move(e); }); } } verifyLoadMoreService() { if (isDevMode() && !isPresent(this.loadMoreService)) { throw new Error(`To use the TreeView paging functionality, you need to assign the \`kendoTreeViewLoadMore\` directive. See ${LOAD_MORE_DOC_LINK}.`); } } registerLookupItems(data, parentItem = null) { if (!isPresent(data) || data.length === 0) { return; } const parentIndex = nodeIndex(parentItem); const treeItems = data.map((node, index) => buildTreeItem(node, index, parentIndex)); if (isPresent(parentItem)) { this.treeViewLookupService.registerChildren(parentIndex, treeItems); } treeItems.forEach(item => { this.treeViewLookupService.registerItem(item, parentItem); if (this.hasChildren(item.dataItem)) { this.children(item.dataItem) .subscribe(children => this.registerLookupItems(children, item)); } }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeViewComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.ExpandStateService }, { token: i2.NavigationService }, { token: i3.NodeChildrenService }, { token: i4.SelectionService }, { token: i5.TreeViewLookupService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i6.DataChangeNotificationService }, { token: i7.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TreeViewComponent, isStandalone: true, selector: "kendo-treeview", inputs: { filterInputPlaceholder: "filterInputPlaceholder", expandDisabledNodes: "expandDisabledNodes", animate: "animate", nodeTemplateRef: ["nodeTemplate", "nodeTemplateRef"], loadMoreButtonTemplateRef: ["loadMoreButtonTemplate", "loadMoreButtonTemplateRef"], trackBy: "trackBy", nodes: "nodes", textField: "textField", hasChildren: "hasChildren", isChecked: "isChecked", isDisabled: "isDisabled", hasCheckbox: "hasCheckbox", isExpanded: "isExpanded", isSelected: "isSelected", isVisible: "isVisible", navigable: "navigable", children: "children", loadOnDemand: "loadOnDemand", filterable: "filterable", filter: "filter", size: "size", disableParentNodesOnly: "disableParentNodesOnly" }, outputs: { childrenLoaded: "childrenLoaded", onBlur: "blur", onFocus: "focus", expand: "expand", collapse: "collapse", nodeDragStart: "nodeDragStart", nodeDrag: "nodeDrag", filterStateChange: "filterStateChange", nodeDrop: "nodeDrop", nodeDragEnd: "nodeDragEnd", addItem: "addItem", removeItem: "removeItem", checkedChange: "checkedChange", selectionChange: "selectionChange", filterChange: "filterChange", nodeClick: "nodeClick", nodeDblClick: "nodeDblClick" }, host: { properties: { "class.k-treeview": "this.classNames", "attr.dir": "this.direction", "@.disabled": "this.animate" } }, providers: providers, queries: [{ propertyName: "nodeTemplateQuery", first: true, predicate: NodeTemplateDirective, descendants: true }, { propertyName: "loadMoreButtonTemplateQuery", first: true, predicate: LoadMoreButtonTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "assetsContainer", first: true, predicate: ["assetsContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "searchbox", first: true, predicate: ["searchbox"], descendants: true }], exportAs: ["kendoTreeView"], usesOnChanges: true, ngImport: i0, template: ` <ng-container kendoTreeViewLocalizedMessages i18n-loadMore="kendo.treeview.loadMore|The title of the Load More button" loadMore="Load more..." > </ng-container> <span class="k-treeview-filter" *ngIf="filterable" > <kendo-textbox #searchbox [size]="size" [value]="filter" [clearButton]="true" (valueChange)="filterChange.emit($event)" [placeholder]="filterInputPlaceholder" > <ng-template kendoTextBoxPrefixTemplate> <kendo-icon-wrapper innerCssClass="k-input-icon" name="search" [svgIcon]="searchIcon" > </kendo-icon-wrapper> </ng-template> </kendo-textbox> </span> <ul class="k-treeview-lines" kendoTreeViewGroup [attr.id]="treeviewId" role="tree" [size]="size" [loadOnDemand]="loadOnDemand" [checkboxes]="checkboxes" [expandIcons]="expandIcons" [selectable]="selectable" [touchActions]="touchActions" [children]="children" [hasChildren]="hasChildren" [isChecked]="isChecked" [isDisabled]="isDisabled" [hasCheckbox]="hasCheckbox" [disableParentNodesOnly]="disableParentNodesOnly" [isExpanded]="isExpanded" [isSelected]="isSelected" [isVisible]="isVisible" [nodeTemplateRef]="nodeTemplateRef?.templateRef" [loadMoreButtonTemplateRef]="loadMoreButtonTemplateRef?.templateRef" [textField]="textField" [nodes]="fetchNodes" [loadMoreService]="loadMoreService" [trackBy]="trackBy" [expandDisabledNodes]="expandDisabledNodes" > </ul> <ng-container #assetsContainer></ng-container> `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoTreeViewLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: TextBoxPrefixTemplateDirective, selector: "[kendoTextBoxPrefixTemplate]", inputs: ["showSeparator"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.Default }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeViewComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.Default, exportAs: 'kendoTreeView', providers: providers, selector: 'kendo-treeview', template: ` <ng-container kendoTreeViewLocalizedMessages i18n-loadMore="kendo.treeview.loadMore|The title of the Load More button" loadMore="Load more..." > </ng-container> <span class="k-treeview-filter" *ngIf="filterable" > <kendo-textbox #searchbox [size]="size" [value]="filter" [clearButton]="true" (valueChange)="filterChange.emit($event)" [placeholder]="filterInputPlaceholder" > <ng-template kendoTextBoxPrefixTemplate> <kendo-icon-wrapper innerCssClass="k-input-icon" name="search" [svgIcon]="searchIcon" > </kendo-icon-wrapper> </ng-template> </kendo-textbox> </span> <ul class="k-treeview-lines" kendoTreeViewGroup [attr.id]="treeviewId" role="tree" [size]="size" [loadOnDemand]="loadOnDemand" [checkboxes]="checkboxes" [expandIcons]="expandIcons" [selectable]="selectable" [touchActions]="touchActions" [children]="children" [hasChildren]="hasChildren" [isChecked]="isChecked" [isDisabled]="isDisabled" [hasCheckbox]="hasCheckbox" [disableParentNodesOnly]="disableParentNodesOnly" [isExpanded]="isExpanded" [isSelected]="isSelected" [isVisible]="isVisible" [nodeTemplateRef]="nodeTemplateRef?.templateRef" [loadMoreButtonTemplateRef]="loadMoreButtonTemplateRef?.templateRef" [textField]="textField" [nodes]="fetchNodes" [loadMoreService]="loadMoreService" [trackBy]="trackBy" [expandDisabledNodes]="expandDisabledNodes" > </ul> <ng-container #assetsContainer></ng-container> `, standalone: true, imports: [LocalizedMessagesDirective, NgIf, TextBoxComponent, TextBoxPrefixTemplateDirective, IconWrapperComponent, TreeViewGroupComponent] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.ExpandStateService }, { type: i2.NavigationService }, { type: i3.NodeChildrenService }, { type: i4.SelectionService }, { type: i5.TreeViewLookupService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i6.DataChangeNotificationService }, { type: i7.LocalizationService }]; }, propDecorators: { classNames: [{ type: HostBinding, args: ["class.k-treeview"] }], direction: [{ type: HostBinding, args: ["attr.dir"] }], assetsContainer: [{ type: ViewChild, args: ['assetsContainer', { read: ViewContainerRef, static: true }] }], searchbox: [{ type: ViewChild, args: ['searchbox'] }], filterInputPlaceholder: [{ type: Input }], expandDisabledNodes: [{ type: Input }], animate: [{ type: Input }, { type: HostBinding, args: ['@.disabled'] }], childrenLoaded: [{ type: Output }], onBlur: [{ type: Output, args: ['blur'] }], onFocus: [{ type: Output, args: ['focus'] }], expand: [{ type: Output }], collapse: [{ type: Output }], nodeDragStart: [{ type: Output }], nodeDrag: [{ type: Output }], filterStateChange: [{ type: Output }], nodeDrop: [{ type: Output }], nodeDragEnd: [{ type: Output }], addItem: [{ type: Output }], removeItem: [{ type: Output }], checkedChange: [{ type: Output }], selectionChange: [{ type: Output }], filterChange: [{ type: Output }], nodeClick: [{ type: Output }], nodeDblClick: [{ type: Output }], nodeTemplateQuery: [{ type: ContentChild, args: [NodeTemplateDirective, { static: false }] }], nodeTemplateRef: [{ type: Input, args: ['nodeTemplate'] }], loadMoreButtonTemplateQuery: [{ type: ContentChild, args: [LoadMoreButtonTemplateDirective, { static: false }] }], loadMoreButtonTemplateRef: [{ type: Input, args: ['loadMoreButtonTemplate'] }], trackBy: [{ type: Input }], nodes: [{ type: Input }], textField: [{ type: Input }], hasChildren: [{ type: Input }], isChecked: [{ type: Input }], isDisabled: [{ type: Input }], hasCheckbox: [{ type: Input }], isExpanded: [{ type: Input }], isSelected: [{ type: Input }], isVisible: [{ type: Input }], navigable: [{ type: Input }], children: [{ type: Input }], loadOnDemand: [{ type: Input }], filterable: [{ type: Input }], filter: [{ type: Input }], size: [{ type: Input }], disableParentNodesOnly: [{ type: Input }] } });