@progress/kendo-angular-treelist
Version:
Kendo UI TreeList for Angular - Display hierarchical data in an Angular tree grid view that supports sorting, filtering, paging, and much more.
849 lines (848 loc) • 36.7 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, Input, Output, EventEmitter, HostBinding, ViewChild, ElementRef, Inject, InjectionToken, QueryList, NgZone, Renderer2, ViewChildren, ChangeDetectorRef } from '@angular/core';
import { Subscription, Subject, fromEvent, merge } from 'rxjs';
import { delay, map, filter, tap } from 'rxjs/operators';
import { LocalizationService } from '@progress/kendo-angular-l10n';
import { RowHeightService } from '../scrolling/row-height.service';
import { ScrollerService, PageAction, ScrollAction, ScrollBottomAction } from '../scrolling/scroller.service';
import { ScrollRequestService } from '../scrolling/scroll-request.service';
import { ColumnBase } from '../columns/column-base';
import { isChanged, isPresent, isUniversal, anyChanged, isNumber, requestAnimationFrame, cancelAnimationFrame } from '../utils';
import { ColumnsContainer } from '../columns/columns-container';
import { ChangeNotificationService } from '../data/change-notification.service';
import { syncRowsHeight } from '../layout/row-sync';
import { NoRecordsTemplateDirective } from './no-records-template.directive';
import { SuspendService } from '../scrolling/suspend.service';
import { expandColumns, sumColumnWidths } from "../columns/column-common";
import { ScrollSyncService } from "../scrolling/scroll-sync.service";
import { ResizeService } from "../layout/resize.service";
import { EventsOutsideAngularDirective, normalizeKeys, ResizeSensorComponent } from "@progress/kendo-angular-common";
import { BrowserSupportService } from "../layout/browser-support.service";
import { EditService } from '../editing/edit.service';
import { NavigationService } from '../navigation/navigation.service';
import { Keys } from '@progress/kendo-angular-common';
import { ColumnResizingService } from "../column-resizing/column-resizing.service";
import { defaultTrackBy } from '../common/default-track-by';
import { hasClasses, rtlScrollPosition } from './common/dom-queries';
import { PDFService } from '../pdf/pdf.service';
import { ColumnInfoService } from '../common/column-info.service';
import { NON_DATA_CELL_CLASSES } from './constants';
import { LoadingComponent } from './common/loading.component';
import { ResizableContainerDirective } from '../layout/resizable.directive';
import { TableBodyComponent } from './table-body.component';
import { ColGroupComponent } from './common/col-group.component';
import { TableDirective } from '../column-resizing/table.directive';
import * as i0 from "@angular/core";
import * as i1 from "../data/change-notification.service";
import * as i2 from "../scrolling/suspend.service";
import * as i3 from "../scrolling/scroll-sync.service";
import * as i4 from "../layout/resize.service";
import * as i5 from "../editing/edit.service";
import * as i6 from "../layout/browser-support.service";
import * as i7 from "../navigation/navigation.service";
import * as i8 from "../scrolling/scroll-request.service";
import * as i9 from "@progress/kendo-angular-l10n";
import * as i10 from "../column-resizing/column-resizing.service";
import * as i11 from "../pdf/pdf.service";
import * as i12 from "../common/column-info.service";
const elementAt = (index, elements, elementOffset) => {
for (let idx = 0, elementIdx = 0; idx < elements.length; idx++) {
const offset = elementOffset(elements[idx]);
if (elementIdx <= index && index <= elementIdx + offset - 1) {
return elements[idx];
}
elementIdx += offset;
}
};
const rowAt = (index, rows) => elementAt(index, rows, row => row.hasAttribute('data-treelist-view-index') ? 1 : 0);
const cellAt = (index, cells) => elementAt(index, cells, cell => !hasClasses(cell, NON_DATA_CELL_CLASSES) ? parseInt(cell.getAttribute('colSpan'), 10) || 1 : 0);
const EMPTY_OBJECT = {};
/**
* @hidden
*/
export const SCROLLER_FACTORY_TOKEN = new InjectionToken('treelist-scroll-service-factory');
/**
* @hidden
*/
export function DEFAULT_SCROLLER_FACTORY(observable) {
return new ScrollerService(observable);
}
const wheelDeltaY = (e) => {
const deltaY = e.wheelDeltaY;
if (e.wheelDelta && (deltaY === undefined || deltaY)) {
return e.wheelDelta;
}
else if (e.detail && e.axis === e.VERTICAL_AXIS) {
return (-e.detail) * 10;
}
return 0;
};
const preventLockedScroll = (args, element) => {
const delta = wheelDeltaY(args);
const scrollTop = element.scrollTop;
const allowScroll = (scrollTop === 0 && 0 < delta) || (element.scrollHeight <= element.offsetHeight + scrollTop && delta < 0);
if (!allowScroll) {
event.preventDefault();
}
};
const translateY = (renderer, value) => el => renderer.setStyle(el, "transform", `translateY(${value}px)`);
const maybeNativeElement = el => el ? el.nativeElement : null;
const hasScrollbar = (el, parent) => el.nativeElement.offsetWidth > parent.nativeElement.clientWidth;
const setHeight = renderer => ({ el, height }) => renderer.setStyle(el, "height", `${height}px`);
const bufferSize = 1;
/**
* @hidden
*/
export class ListComponent {
changeNotification;
suspendService;
ngZone;
renderer;
scrollSyncService;
resizeService;
editService;
supportService;
navigationService;
localization;
columnResizingService;
changeDetector;
pdfService;
columnInfo;
get hostClass() {
return true;
}
get hostRole() {
return 'presentation';
}
view;
total;
rowHeight;
take;
skip = 0;
columns = new ColumnsContainer(() => []);
noRecordsTemplate;
filterable;
rowClass;
loading;
trackBy = defaultTrackBy;
virtualColumns;
isVirtual;
expandIcons;
contentScroll = new EventEmitter();
pageChange = new EventEmitter();
scrollBottom = new EventEmitter();
totalHeight;
columnsStartIdx = 0;
get totalWidth() {
if (this.virtualColumns && this.columns.unlockedWidth) {
return this.columns.unlockedWidth;
}
}
container;
table;
lockedContainer;
lockedTable;
resizeSensors = new QueryList();
scroller;
subscriptions = new Subscription();
scrollerSubscription;
dispatcher = new Subject();
rowHeightService;
skipScroll;
rebind;
containerScrollTop = 0;
viewportColumns;
columnsEndIdx;
viewportColumnsWidth;
scrollLeft = 0;
get lockedLeafColumns() {
return this.columns.lockedLeafColumns;
}
get nonLockedLeafColumns() {
return this.columns.nonLockedLeafColumns;
}
get nonLockedColumnsToRender() {
if (this.virtualColumns && !this.pdfService.exporting) {
return this.viewportColumns;
}
return this.nonLockedLeafColumns;
}
get leafColumns() {
return this.columns.leafColumnsToRender;
}
get lockedWidth() {
return expandColumns(this.lockedLeafColumns.toArray()).reduce((prev, curr) => prev + (curr.width || 0), 0);
}
get nonLockedWidth() {
if ((!this.rtl && this.lockedLeafColumns.length) || this.virtualColumns) {
return sumColumnWidths(expandColumns(this.nonLockedColumnsToRender.toArray()));
}
return undefined;
}
get isLocked() {
return this.lockedLeafColumns.length > 0;
}
rtl = false;
columnUpdateFrame;
hasLockedContainer;
constructor(scrollerFactory, changeNotification, suspendService, ngZone, renderer, scrollSyncService, resizeService, editService, supportService, navigationService, scrollRequestService, localization, columnResizingService, changeDetector, pdfService, columnInfo) {
this.changeNotification = changeNotification;
this.suspendService = suspendService;
this.ngZone = ngZone;
this.renderer = renderer;
this.scrollSyncService = scrollSyncService;
this.resizeService = resizeService;
this.editService = editService;
this.supportService = supportService;
this.navigationService = navigationService;
this.localization = localization;
this.columnResizingService = columnResizingService;
this.changeDetector = changeDetector;
this.pdfService = pdfService;
this.columnInfo = columnInfo;
this.scroller = scrollerFactory(this.dispatcher);
this.subscriptions = scrollRequestService.requests.subscribe(x => this.scrollTo(x));
}
ngOnInit() {
this.init();
this.subscriptions.add(this.ngZone.runOutsideAngular(this.handleRowSync.bind(this)));
this.subscriptions.add(this.ngZone.runOutsideAngular(this.handleRowNavigationLocked.bind(this)));
this.subscriptions.add(merge(this.columns.changes, this.resizeService.changes).subscribe(() => {
if (this.virtualColumns) {
this.ngZone.run(() => {
this.updateViewportColumns();
this.changeDetector.markForCheck();
});
}
}));
this.subscriptions.add(this.localization.changes.subscribe(({ rtl }) => this.rtl = rtl));
}
ngOnChanges(changes) {
if (isChanged("skip", changes) && !this.rebind) {
this.skipScroll = true;
this.container.nativeElement.scrollTop = this.rowHeightService.offset(this.skip);
}
if (anyChanged(["total", "take"], changes)) {
this.init();
}
this.rebind = false;
}
ngDoCheck() {
if (this.virtualColumns && (!this.viewportColumns || this.viewportWidthChange())) {
this.updateViewportColumns();
}
}
ngAfterViewInit() {
if (this.skip && this.isVirtual) {
this.container.nativeElement.scrollTop = this.rowHeightService.offset(this.skip);
}
this.resetNavigationViewport();
this.attachContainerScroll();
this.initResizeService();
}
ngAfterViewChecked() {
const isLocked = this.isLocked;
if (isLocked && !this.hasLockedContainer) {
this.syncRowsHeight();
}
this.hasLockedContainer = isLocked;
}
syncRowsHeight() {
if (this.lockedContainer) {
syncRowsHeight(this.lockedTable.nativeElement, this.table.nativeElement);
}
}
ngOnDestroy() {
if (this.subscriptions) {
this.subscriptions.unsubscribe();
}
if (this.resizeService) {
this.resizeService.destroy();
}
this.cleanupScroller();
}
init() {
if (this.suspendService.scroll) {
return;
}
this.rowHeightService = new RowHeightService(this.total, this.rowHeight);
this.totalHeight = this.rowHeightService.totalHeight();
if (!isUniversal()) {
this.ngZone.runOutsideAngular(this.createScroller.bind(this));
}
}
lockedScroll() {
if (!this.suspendService.scroll) {
const lockedScrollTop = this.lockedContainer.nativeElement.scrollTop;
if (lockedScrollTop !== this.containerScrollTop) {
this.container.nativeElement.scrollTop = this.containerScrollTop = lockedScrollTop;
}
}
}
lockedMousewheel(args) {
if (!args.ctrlKey) {
preventLockedScroll(args, this.container.nativeElement);
const scrollDelta = wheelDeltaY(args);
this.container.nativeElement.scrollTop -= scrollDelta;
}
}
lockedKeydown(args) {
// on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
const code = normalizeKeys(args);
if (code === Keys.PageDown || code === Keys.PageUp) {
const dir = code === Keys.PageDown ? 1 : -1;
const element = this.container.nativeElement;
element.scrollTop += element.offsetHeight * dir * 0.8;
args.preventDefault();
}
}
updateViewportColumns(range) {
const columns = this.columns.nonLockedLeafColumns.toArray();
// eslint-disable-next-line prefer-const
let { startIdx, endIdx, offset } = range || this.calculateViewportColumns();
const start = Math.max(0, startIdx - bufferSize);
const end = Math.min(endIdx + bufferSize, columns.length - 1);
if (start < startIdx) {
for (let idx = startIdx - 1; idx >= start; idx--) {
offset -= columns[idx].width;
}
}
const currentColumns = columns.slice(start, end + 1);
this.viewportColumnsWidth = currentColumns.reduce((total, column) => total + column.width, 0);
if (start > 0) {
const offsetColumn = new ColumnBase();
offsetColumn.width = offset;
currentColumns.unshift(offsetColumn);
}
this.viewportColumns = new QueryList();
this.viewportColumns.reset(currentColumns);
this.columnsStartIdx = start;
this.columnsEndIdx = end;
this.columnInfo.columnRangeChange.emit({ start, end, offset });
if (!range) {
this.updateColumnViewport(startIdx, endIdx);
}
}
attachContainerScroll() {
if (isUniversal()) {
return;
}
this.ngZone.runOutsideAngular(() => {
this.subscriptions.add(fromEvent(this.container.nativeElement, 'scroll').pipe(map((event) => event.target), filter(() => !this.suspendService.scroll), tap((target) => {
this.onContainerScroll(target);
this.resetNavigationViewport();
if (this.virtualColumns) {
this.handleColumnScroll();
}
const rowViewport = this.navigationService.viewport || EMPTY_OBJECT;
const columnViewport = this.navigationService.columnViewport || EMPTY_OBJECT;
this.contentScroll.emit({
scrollLeft: target.scrollLeft,
scrollTop: target.scrollTop,
startRow: rowViewport.firstItemIndex,
endRow: rowViewport.lastItemIndex,
startColumn: columnViewport.firstItemIndex,
endColumn: columnViewport.lastItemIndex
});
})).subscribe(this.dispatcher));
});
this.scrollSyncService.registerEmitter(this.container.nativeElement, "body");
}
createScroller() {
this.cleanupScroller();
const observable = this.scroller
.create(this.rowHeightService, this.skip, this.take, this.total, this.containerScrollTop);
this.skipScroll = false;
this.scrollerSubscription = observable.pipe(filter((x) => x instanceof PageAction), filter(() => {
const temp = this.skipScroll;
this.skipScroll = false;
return !temp;
}), tap(() => this.rebind = true))
.subscribe((x) => this.ngZone.run(() => this.pageChange.emit(x)));
this.scrollerSubscription.add(observable.pipe(filter((x) => x instanceof ScrollAction))
.subscribe(this.scroll.bind(this)));
this.scrollerSubscription.add(observable.pipe(filter((x) => x instanceof ScrollBottomAction))
.subscribe(() => this.scrollBottom.emit()));
}
scroll({ offset = 0 }) {
if (this.isVirtual) {
[
maybeNativeElement(this.table),
maybeNativeElement(this.lockedTable)
].filter(isPresent).forEach(translateY(this.renderer, offset));
}
this.resetNavigationViewport();
}
onContainerScroll({ scrollTop }) {
this.containerScrollTop = scrollTop;
if (this.lockedContainer) {
this.lockedContainer.nativeElement.scrollTop = scrollTop;
}
}
handleRowSync() {
const isLocked = () => isPresent(this.lockedContainer);
return merge(this.changeNotification.changes, this.editService.changed, this.resizeService.changes, this.columnResizingService.changes
.pipe(filter(change => change.type === 'end')), this.supportService.changes)
.pipe(tap(() => this.resetNavigationViewport()), filter(isLocked))
.subscribe(() => {
const scrollTop = this.container.nativeElement.scrollTop;
const scrollLeft = this.container.nativeElement.scrollLeft;
this.syncRowsHeight();
this.syncContainerHeight();
this.lockedContainer.nativeElement.scrollTop = this.container.nativeElement.scrollTop = scrollTop;
// fixes scroll left position in IE when editing
this.container.nativeElement.scrollLeft = scrollLeft;
this.resizeSensors.forEach(sensor => sensor.acceptSize());
});
}
handleRowNavigationLocked() {
return this.navigationService.changes.pipe(filter(() => isPresent(this.lockedContainer)), delay(10)).subscribe((args) => {
if (this.lockedLeafColumns.length <= args.prevColIndex && args.colIndex < this.lockedLeafColumns.length) {
const cell = this.navigationService.activeCell;
if (cell && cell.colIndex + cell.colSpan < args.prevColIndex) {
this.container.nativeElement.scrollLeft = 0;
}
}
});
}
scrollToVirtualRow(itemIndex) {
const offset = this.rowHeightService.offset(itemIndex);
this.container.nativeElement.scrollTop = offset;
this.resetNavigationViewport();
}
scrollTo({ row, column }) {
if (isNumber(row)) {
if (this.isVirtual) {
this.scrollToVirtualRow(row);
}
else {
const element = rowAt(row, this.table.nativeElement.rows);
if (element) {
this.container.nativeElement.scrollTop = element.offsetTop;
}
}
}
if (isNumber(column)) {
column -= this.lockedLeafColumns.length;
if (this.virtualColumns) {
const columns = this.columns.leafColumnsToRender;
let offset = 0;
for (let idx = 0; idx < column; idx++) {
offset += columns[idx].width || 0;
}
this.container.nativeElement.scrollLeft = this.normalizeScrollLeft(offset);
}
else {
const firstRow = rowAt(0, this.table.nativeElement.rows);
if (firstRow) {
const element = cellAt(column, firstRow.cells);
if (element) {
this.container.nativeElement.scrollLeft = this.elementScrollLeft(element);
}
}
}
}
}
resetNavigationViewport() {
if (!this.container ||
!this.navigationService.needsViewport() || this.view.length === 0) {
return;
}
const { scrollTop, offsetHeight } = this.container.nativeElement;
const scrollBottom = scrollTop + offsetHeight;
const firstItemIndex = this.rowHeightService.index(scrollTop);
let lastItemIndex = this.rowHeightService.index(scrollBottom);
const lastItemOffset = this.rowHeightService.offset(lastItemIndex);
const lastItemOverflows = lastItemOffset + this.rowHeight > scrollBottom;
if (lastItemIndex > 0 && lastItemOverflows) {
lastItemIndex--;
}
this.navigationService.setViewport(firstItemIndex, lastItemIndex);
}
cleanupScroller() {
if (this.scrollerSubscription) {
this.scrollerSubscription.unsubscribe();
}
if (this.scroller) {
this.scroller.destroy();
}
}
initResizeService() {
this.resizeService.connect(merge(...this.resizeSensors.map(sensor => sensor.resize)));
}
syncContainerHeight() {
[maybeNativeElement(this.lockedContainer)]
.filter(isPresent)
.map(el => {
el.style.height = '';
let height = this.container.nativeElement.offsetHeight;
if (hasScrollbar(this.table, this.container)) {
height -= this.supportService.scrollbarWidth;
}
return { el, height };
})
.forEach(setHeight(this.renderer));
}
handleColumnScroll() {
const container = this.container.nativeElement;
const scrollLeft = container.scrollLeft;
if (this.scrollLeft !== scrollLeft) {
this.scrollLeft = scrollLeft;
const range = this.calculateViewportColumns();
this.updateColumnViewport(range.startIdx, range.endIdx);
if (range.startIdx < this.columnsStartIdx || this.columnsEndIdx < range.endIdx) {
cancelAnimationFrame(this.columnUpdateFrame);
this.columnUpdateFrame = requestAnimationFrame(() => {
this.ngZone.run(() => {
this.updateViewportColumns(range);
this.changeDetector.markForCheck();
});
});
}
}
}
updateColumnViewport(startIdx, endIdx) {
const lockedCount = this.lockedLeafColumns.length;
const leafColumns = this.nonLockedLeafColumns.toArray();
const viewportStart = lockedCount + startIdx;
let viewportEnd = lockedCount + endIdx;
for (let idx = 0; idx < leafColumns.length; idx++) {
const column = leafColumns[idx];
if (column.isSpanColumn) {
viewportEnd += column.childColumns.length;
}
}
this.navigationService.setColumnViewport(viewportStart, viewportEnd);
}
calculateViewportColumns() {
const { scrollLeft, clientWidth } = this.container.nativeElement;
const columns = this.columns.nonLockedLeafColumns.toArray();
const normalizedScrollLeft = this.normalizeScrollLeft(scrollLeft);
const viewportEnd = normalizedScrollLeft + clientWidth;
let startIdx;
let endIdx = 0;
let current = 0;
let offset = 0;
let idx;
for (idx = 0; idx < columns.length; idx++) {
const column = columns[idx];
current += column.width || 0;
if (startIdx === undefined && current > normalizedScrollLeft) {
startIdx = idx;
offset = current - (column.width || 0);
}
if (current >= viewportEnd) {
endIdx = idx;
break;
}
}
if (!endIdx && idx > 0) {
endIdx = columns.length - 1;
}
return { startIdx, endIdx, offset };
}
viewportWidthChange() {
const currentWidth = this.viewportColumns.toArray().reduce((total, column) => total + column.width, 0);
return currentWidth !== this.viewportColumnsWidth;
}
normalizeScrollLeft(position) {
return this.rtl ? rtlScrollPosition(position, this.container.nativeElement, this.supportService.rtlScrollLeft) : position;
}
elementScrollLeft(element) {
if (this.rtl) {
return this.normalizeScrollLeft(this.container.nativeElement.scrollWidth - element.offsetLeft - element.offsetWidth);
}
return element.offsetLeft;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListComponent, deps: [{ token: SCROLLER_FACTORY_TOKEN }, { token: i1.ChangeNotificationService }, { token: i2.SuspendService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i3.ScrollSyncService }, { token: i4.ResizeService }, { token: i5.EditService }, { token: i6.BrowserSupportService }, { token: i7.NavigationService }, { token: i8.ScrollRequestService }, { token: i9.LocalizationService }, { token: i10.ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: i11.PDFService }, { token: i12.ColumnInfoService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ListComponent, isStandalone: true, selector: "kendo-treelist-list", inputs: { view: "view", total: "total", rowHeight: "rowHeight", take: "take", skip: "skip", columns: "columns", noRecordsTemplate: "noRecordsTemplate", filterable: "filterable", rowClass: "rowClass", loading: "loading", trackBy: "trackBy", virtualColumns: "virtualColumns", isVirtual: "isVirtual", expandIcons: "expandIcons" }, outputs: { contentScroll: "contentScroll", pageChange: "pageChange", scrollBottom: "scrollBottom" }, host: { properties: { "class.k-grid-container": "this.hostClass", "attr.role": "this.hostRole" } }, providers: [
{
provide: SCROLLER_FACTORY_TOKEN,
useValue: DEFAULT_SCROLLER_FACTORY
}
], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true, static: true }, { propertyName: "lockedContainer", first: true, predicate: ["lockedContainer"], descendants: true }, { propertyName: "lockedTable", first: true, predicate: ["lockedTable"], descendants: true }, { propertyName: "resizeSensors", predicate: ResizeSensorComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
@if (isLocked) {
<div #lockedContainer class="k-grid-content-locked" role="presentation"
[style.width.px]="lockedWidth"
[kendoEventsOutsideAngular]="{
keydown: lockedKeydown,
scroll: lockedScroll,
mousewheel: lockedMousewheel,
DOMMouseScroll: lockedMousewheel
}"
[scope]="this">
<div role="presentation">
<table
kendoTreeListResizableTable
[locked]="true"
#lockedTable
class="k-table k-grid-table k-table-md"
role="presentation"
[style.width.px]="lockedWidth">
<colgroup
kendoTreeListColGroup
[columns]="$any(lockedLeafColumns)">
</colgroup>
<tbody kendoTreeListTableBody
role="presentation"
[isLocked]="true"
[view]="view"
[noRecordsText]="''"
[columns]="$any(lockedLeafColumns)"
[totalColumnsCount]="leafColumns.length"
[totalColumns]="columns"
[skip]="skip"
[trackBy]="trackBy"
[filterable]="filterable"
[rowClass]="rowClass"
[expandIcons]="expandIcons">
</tbody>
</table>
<kendo-resize-sensor></kendo-resize-sensor>
</div>
@if (isVirtual) {
<div class="k-height-container" role="presentation">
<div [style.height.px]="totalHeight"></div>
</div>
}
</div>
}
<div
#container
class="k-grid-content k-virtual-content"
[kendoTreeListResizableContainer]="lockedLeafColumns.length > 0"
[lockedWidth]="lockedWidth + 1"
>
<div role="presentation">
<table
[style.width.px]="nonLockedWidth"
#table
kendoTreeListResizableTable
[virtualColumns]="virtualColumns"
class="k-table k-grid-table k-table-md"
role="presentation">
<colgroup
kendoTreeListColGroup
[columns]="$any(nonLockedColumnsToRender)">
</colgroup>
<tbody kendoTreeListTableBody
role="rowgroup"
[view]="view"
[columns]="$any(nonLockedColumnsToRender)"
[allColumns]="$any(nonLockedLeafColumns)"
[noRecordsTemplate]="noRecordsTemplate"
[lockedColumnsCount]="lockedLeafColumns.length"
[totalColumnsCount]="leafColumns.length"
[totalColumns]="columns"
[skip]="skip"
[trackBy]="trackBy"
[filterable]="filterable"
[rowClass]="rowClass"
[virtualColumns]="virtualColumns"
[expandIcons]="expandIcons">
</tbody>
</table>
@if (isLocked) {
<kendo-resize-sensor></kendo-resize-sensor>
}
</div>
@if (isLocked || virtualColumns) {
<kendo-resize-sensor></kendo-resize-sensor>
}
@if (isVirtual) {
<div class="k-height-container" role="presentation">
<div [style.height.px]="totalHeight"></div>
</div>
}
@if (virtualColumns) {
<div class="k-width-container" role="presentation">
<div [style.width.px]="totalWidth"></div>
</div>
}
</div>
@if (loading) {
<div kendoTreeListLoading>
</div>
}
`, isInline: true, dependencies: [{ kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: TableDirective, selector: "[kendoTreeListResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoTreeListColGroup]", inputs: ["columns"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoTreeListTableBody]", inputs: ["columns", "allColumns", "noRecordsTemplate", "view", "skip", "filterable", "noRecordsText", "isLocked", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "expandIcons", "trackBy", "totalColumns", "rowClass"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoTreeListResizableContainer]", inputs: ["lockedWidth", "kendoTreeListResizableContainer"] }, { kind: "component", type: LoadingComponent, selector: "[kendoTreeListLoading]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListComponent, decorators: [{
type: Component,
args: [{
providers: [
{
provide: SCROLLER_FACTORY_TOKEN,
useValue: DEFAULT_SCROLLER_FACTORY
}
],
selector: 'kendo-treelist-list',
template: `
@if (isLocked) {
<div #lockedContainer class="k-grid-content-locked" role="presentation"
[style.width.px]="lockedWidth"
[kendoEventsOutsideAngular]="{
keydown: lockedKeydown,
scroll: lockedScroll,
mousewheel: lockedMousewheel,
DOMMouseScroll: lockedMousewheel
}"
[scope]="this">
<div role="presentation">
<table
kendoTreeListResizableTable
[locked]="true"
#lockedTable
class="k-table k-grid-table k-table-md"
role="presentation"
[style.width.px]="lockedWidth">
<colgroup
kendoTreeListColGroup
[columns]="$any(lockedLeafColumns)">
</colgroup>
<tbody kendoTreeListTableBody
role="presentation"
[isLocked]="true"
[view]="view"
[noRecordsText]="''"
[columns]="$any(lockedLeafColumns)"
[totalColumnsCount]="leafColumns.length"
[totalColumns]="columns"
[skip]="skip"
[trackBy]="trackBy"
[filterable]="filterable"
[rowClass]="rowClass"
[expandIcons]="expandIcons">
</tbody>
</table>
<kendo-resize-sensor></kendo-resize-sensor>
</div>
@if (isVirtual) {
<div class="k-height-container" role="presentation">
<div [style.height.px]="totalHeight"></div>
</div>
}
</div>
}
<div
#container
class="k-grid-content k-virtual-content"
[kendoTreeListResizableContainer]="lockedLeafColumns.length > 0"
[lockedWidth]="lockedWidth + 1"
>
<div role="presentation">
<table
[style.width.px]="nonLockedWidth"
#table
kendoTreeListResizableTable
[virtualColumns]="virtualColumns"
class="k-table k-grid-table k-table-md"
role="presentation">
<colgroup
kendoTreeListColGroup
[columns]="$any(nonLockedColumnsToRender)">
</colgroup>
<tbody kendoTreeListTableBody
role="rowgroup"
[view]="view"
[columns]="$any(nonLockedColumnsToRender)"
[allColumns]="$any(nonLockedLeafColumns)"
[noRecordsTemplate]="noRecordsTemplate"
[lockedColumnsCount]="lockedLeafColumns.length"
[totalColumnsCount]="leafColumns.length"
[totalColumns]="columns"
[skip]="skip"
[trackBy]="trackBy"
[filterable]="filterable"
[rowClass]="rowClass"
[virtualColumns]="virtualColumns"
[expandIcons]="expandIcons">
</tbody>
</table>
@if (isLocked) {
<kendo-resize-sensor></kendo-resize-sensor>
}
</div>
@if (isLocked || virtualColumns) {
<kendo-resize-sensor></kendo-resize-sensor>
}
@if (isVirtual) {
<div class="k-height-container" role="presentation">
<div [style.height.px]="totalHeight"></div>
</div>
}
@if (virtualColumns) {
<div class="k-width-container" role="presentation">
<div [style.width.px]="totalWidth"></div>
</div>
}
</div>
@if (loading) {
<div kendoTreeListLoading>
</div>
}
`,
standalone: true,
imports: [EventsOutsideAngularDirective, TableDirective, ColGroupComponent, TableBodyComponent, ResizeSensorComponent, ResizableContainerDirective, LoadingComponent]
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [SCROLLER_FACTORY_TOKEN]
}] }, { type: i1.ChangeNotificationService }, { type: i2.SuspendService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i3.ScrollSyncService }, { type: i4.ResizeService }, { type: i5.EditService }, { type: i6.BrowserSupportService }, { type: i7.NavigationService }, { type: i8.ScrollRequestService }, { type: i9.LocalizationService }, { type: i10.ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: i11.PDFService }, { type: i12.ColumnInfoService }], propDecorators: { hostClass: [{
type: HostBinding,
args: ["class.k-grid-container"]
}], hostRole: [{
type: HostBinding,
args: ["attr.role"]
}], view: [{
type: Input
}], total: [{
type: Input
}], rowHeight: [{
type: Input
}], take: [{
type: Input
}], skip: [{
type: Input
}], columns: [{
type: Input
}], noRecordsTemplate: [{
type: Input
}], filterable: [{
type: Input
}], rowClass: [{
type: Input
}], loading: [{
type: Input
}], trackBy: [{
type: Input
}], virtualColumns: [{
type: Input
}], isVirtual: [{
type: Input
}], expandIcons: [{
type: Input
}], contentScroll: [{
type: Output
}], pageChange: [{
type: Output
}], scrollBottom: [{
type: Output
}], container: [{
type: ViewChild,
args: ['container', { static: true }]
}], table: [{
type: ViewChild,
args: ['table', { static: true }]
}], lockedContainer: [{
type: ViewChild,
args: ['lockedContainer', { static: false }]
}], lockedTable: [{
type: ViewChild,
args: ['lockedTable', { static: false }]
}], resizeSensors: [{
type: ViewChildren,
args: [ResizeSensorComponent]
}] } });