UNPKG

@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.

188 lines (187 loc) 7.81 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Directive, ElementRef, HostBinding, Input, NgZone, Renderer2 } from '@angular/core'; import { FocusGroup } from './focus-group'; import { FocusRoot } from './focus-root'; import { NavigationService } from './navigation.service'; import { ColumnInfoService } from '../common/column-info.service'; import { IdService } from '../common/id.service'; import * as i0 from "@angular/core"; import * as i1 from "./focus-group"; import * as i2 from "../common/column-info.service"; import * as i3 from "../common/id.service"; import * as i4 from "./navigation.service"; let id = 0; function nextId() { return id++; } /** * @hidden */ export class LogicalCellDirective { focusGroup; element; columnInfoService; idService; navigationService; renderer; zone; logicalColIndex; logicalRowIndex; logicalSlaveCell = false; column; colIndex; colSpan = 1; rowSpan = 1; dataRowIndex = -1; dataItem; expandable = false; headerLabelText; uid = nextId(); get id() { if (!this.logicalSlaveCell && this.columnInfoService.isLocked) { return this.idService.cellId(this.logicalRowIndex, this.logicalColIndex); } } get ariaColIndex() { if (this.logicalSlaveCell || this.logicalColIndex === -1) { return undefined; } return this.logicalColIndex + 1; } navigationChange; constructor(focusGroup, element, columnInfoService, idService, navigationService, renderer, zone) { this.focusGroup = focusGroup; this.element = element; this.columnInfoService = columnInfoService; this.idService = idService; this.navigationService = navigationService; this.renderer = renderer; this.zone = zone; } ngOnInit() { if (!this.navigationService.enabled) { return; } this.navigationChange = this.navigationService.changes.subscribe((e) => this.onNavigationChange(e)); } ngDoCheck() { if (!this.navigationService.enabled || this.logicalColIndex === -1) { return; } this.registerNoChanges(); } ngOnChanges(changes) { if (!this.navigationService.enabled) { return; } if (this.logicalColIndex === -1) { return; } const indexChange = changes['logicalColIndex']; const rowIndexChange = changes['logicalRowIndex']; const index = indexChange && !indexChange.isFirstChange() ? indexChange.previousValue : this.logicalColIndex; const rowIndex = rowIndexChange && !rowIndexChange.isFirstChange() ? rowIndexChange.previousValue : this.logicalRowIndex; this.navigationService.unregisterCell(index, rowIndex, this); this.registerChanges(); this.updateElement(); } ngOnDestroy() { if (this.navigationChange) { this.navigationChange.unsubscribe(); } this.navigationService.unregisterCell(this.logicalColIndex, this.logicalRowIndex, this); } onNavigationChange(e) { const active = this.logicalColIndex === e.colIndex && this.logicalRowIndex === e.rowIndex; const wasActive = this.logicalColIndex === e.prevColIndex && this.logicalRowIndex === e.prevRowIndex; if (active || wasActive) { this.updateElement(); } } updateElement() { const el = this.element.nativeElement; this.renderer.setAttribute(el, 'tabIndex', this.isFocusable() && !this.logicalSlaveCell ? '0' : '-1'); if (this.isFocused()) { if (this.focusGroup.isNavigable()) { this.focusGroup.focus(); } else { if (!this.logicalSlaveCell && this.navigationService.autoFocusCell(this.logicalColIndex, this.logicalColIndex + this.colSpan - 1)) { this.microtask(() => this.isFocused() && el.focus()); } this.renderer.addClass(el, 'k-focus'); } } else { this.renderer.removeClass(el, 'k-focus'); } } microtask(callback) { this.zone.runOutsideAngular(() => Promise.resolve(null).then(callback)); } registerChanges() { if (!this.logicalSlaveCell) { this.navigationService.registerCell(this); } } registerNoChanges() { if (!this.logicalSlaveCell) { this.navigationService.registerCellOnCurrentRow(this); } } isFocusable() { return this.navigationService.isCellFocusable(this); } isFocused() { return this.navigationService.isCellFocused(this); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LogicalCellDirective, deps: [{ token: i1.FocusGroup }, { token: i0.ElementRef }, { token: i2.ColumnInfoService }, { token: i3.IdService }, { token: i4.NavigationService }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: LogicalCellDirective, isStandalone: true, selector: "[kendoTreeListLogicalCell]", inputs: { logicalColIndex: "logicalColIndex", logicalRowIndex: "logicalRowIndex", logicalSlaveCell: "logicalSlaveCell", column: "column", colIndex: "colIndex", colSpan: "colSpan", rowSpan: "rowSpan", dataRowIndex: "dataRowIndex", dataItem: "dataItem", expandable: "expandable", headerLabelText: "headerLabelText" }, host: { properties: { "attr.id": "this.id", "attr.aria-colindex": "this.ariaColIndex" } }, providers: [{ provide: FocusGroup, deps: [FocusRoot], useClass: FocusGroup }], usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LogicalCellDirective, decorators: [{ type: Directive, args: [{ providers: [{ provide: FocusGroup, deps: [FocusRoot], useClass: FocusGroup }], selector: '[kendoTreeListLogicalCell]', standalone: true }] }], ctorParameters: function () { return [{ type: i1.FocusGroup }, { type: i0.ElementRef }, { type: i2.ColumnInfoService }, { type: i3.IdService }, { type: i4.NavigationService }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { logicalColIndex: [{ type: Input }], logicalRowIndex: [{ type: Input }], logicalSlaveCell: [{ type: Input }], column: [{ type: Input }], colIndex: [{ type: Input }], colSpan: [{ type: Input }], rowSpan: [{ type: Input }], dataRowIndex: [{ type: Input }], dataItem: [{ type: Input }], expandable: [{ type: Input }], headerLabelText: [{ type: Input }], id: [{ type: HostBinding, args: ['attr.id'] }], ariaColIndex: [{ type: HostBinding, args: ['attr.aria-colindex'] }] } });