@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
JavaScript
/**-----------------------------------------------------------------------------------------
* 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']
}] } });