@clr/angular
Version:
Angular components for Clarity
88 lines • 11.9 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component, ContentChildren, Input, } from '@angular/core';
import { fromEvent } from 'rxjs';
import { TREE_FEATURES_PROVIDER } from './tree-features.service';
import { TreeFocusManagerService } from './tree-focus-manager.service';
import { ClrTreeNode } from './tree-node';
import * as i0 from "@angular/core";
import * as i1 from "./tree-features.service";
import * as i2 from "./tree-focus-manager.service";
import * as i3 from "@angular/common";
import * as i4 from "./recursive-children";
export class ClrTree {
constructor(featuresService, focusManagerService, { nativeElement }, renderer, ngZone) {
this.featuresService = featuresService;
this.focusManagerService = focusManagerService;
this.subscriptions = [];
const subscription = ngZone.runOutsideAngular(() => fromEvent(nativeElement, 'focusin').subscribe((event) => {
if (event.target === nativeElement) {
// After discussing with the team, I've made it so that when the tree receives focus, the first visible node will be focused.
// This will prevent from the page scrolling abruptly to the first selected node if it exist in a deeply nested tree.
this.focusManagerService.focusFirstVisibleNode();
// when the first child gets focus,
// tree should no longer have tabindex of 0.
renderer.removeAttribute(nativeElement, 'tabindex');
}
}));
this.subscriptions.push(subscription);
}
set lazy(value) {
this.featuresService.eager = !value;
}
get isMultiSelectable() {
return this.featuresService.selectable && this.rootNodes.length > 0;
}
ngAfterContentInit() {
this.setRootNodes();
this.subscriptions.push(this.rootNodes.changes.subscribe(() => {
this.setRootNodes();
}));
}
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
setRootNodes() {
// if node has no parent, it's a root node
// for recursive tree, this.rootNodes registers also nested children
// so we have to use filter to extract the ones that are truly root nodes
this.focusManagerService.rootNodeModels = this.rootNodes.map(node => node._model).filter(node => !node.parent);
}
}
ClrTree.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTree, deps: [{ token: i1.TreeFeaturesService }, { token: i2.TreeFocusManagerService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
ClrTree.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTree, selector: "clr-tree", inputs: { lazy: ["clrLazy", "lazy"] }, host: { attributes: { "tabindex": "0" }, properties: { "attr.role": "\"tree\"", "attr.aria-multiselectable": "isMultiSelectable" } }, providers: [TREE_FEATURES_PROVIDER, TreeFocusManagerService], queries: [{ propertyName: "rootNodes", predicate: ClrTreeNode }], ngImport: i0, template: `
<ng-content></ng-content>
<clr-recursive-children
*ngIf="featuresService.recursion"
[children]="featuresService.recursion.root"
></clr-recursive-children>
`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.RecursiveChildren, selector: "clr-recursive-children", inputs: ["parent", "children"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTree, decorators: [{
type: Component,
args: [{
selector: 'clr-tree',
template: `
<ng-content></ng-content>
<clr-recursive-children
*ngIf="featuresService.recursion"
[children]="featuresService.recursion.root"
></clr-recursive-children>
`,
providers: [TREE_FEATURES_PROVIDER, TreeFocusManagerService],
host: {
tabindex: '0',
'[attr.role]': '"tree"',
'[attr.aria-multiselectable]': 'isMultiSelectable',
},
}]
}], ctorParameters: function () { return [{ type: i1.TreeFeaturesService }, { type: i2.TreeFocusManagerService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { rootNodes: [{
type: ContentChildren,
args: [ClrTreeNode]
}], lazy: [{
type: Input,
args: ['clrLazy']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL2RhdGEvdHJlZS12aWV3L3RyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFFTCxTQUFTLEVBQ1QsZUFBZSxFQUVmLEtBQUssR0FLTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUUvQyxPQUFPLEVBQUUsc0JBQXNCLEVBQXVCLE1BQU0seUJBQXlCLENBQUM7QUFDdEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7Ozs7O0FBa0IxQyxNQUFNLE9BQU8sT0FBTztJQUtsQixZQUNTLGVBQXVDLEVBQ3RDLG1CQUErQyxFQUN2RCxFQUFFLGFBQWEsRUFBMkIsRUFDMUMsUUFBbUIsRUFDbkIsTUFBYztRQUpQLG9CQUFlLEdBQWYsZUFBZSxDQUF3QjtRQUN0Qyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQTRCO1FBSmpELGtCQUFhLEdBQW1CLEVBQUUsQ0FBQztRQVN6QyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQ2pELFNBQVMsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBaUIsRUFBRSxFQUFFO1lBQ2xFLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxhQUFhLEVBQUU7Z0JBQ2xDLDZIQUE2SDtnQkFDN0gscUhBQXFIO2dCQUNySCxJQUFJLENBQUMsbUJBQW1CLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQkFDakQsbUNBQW1DO2dCQUNuQyw0Q0FBNEM7Z0JBQzVDLFFBQVEsQ0FBQyxlQUFlLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3JEO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxJQUNJLElBQUksQ0FBQyxLQUFjO1FBQ3JCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNuQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNwQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRU8sWUFBWTtRQUNsQiwwQ0FBMEM7UUFDMUMsb0VBQW9FO1FBQ3BFLHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2pILENBQUM7O29HQXZEVSxPQUFPO3dGQUFQLE9BQU8sZ05BUFAsQ0FBQyxzQkFBc0IsRUFBRSx1QkFBdUIsQ0FBQyxvREFRM0MsV0FBVyw2QkFmbEI7Ozs7OztHQU1UOzJGQVFVLE9BQU87a0JBaEJuQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxVQUFVO29CQUNwQixRQUFRLEVBQUU7Ozs7OztHQU1UO29CQUNELFNBQVMsRUFBRSxDQUFDLHNCQUFzQixFQUFFLHVCQUF1QixDQUFDO29CQUM1RCxJQUFJLEVBQUU7d0JBQ0osUUFBUSxFQUFFLEdBQUc7d0JBQ2IsYUFBYSxFQUFFLFFBQVE7d0JBQ3ZCLDZCQUE2QixFQUFFLG1CQUFtQjtxQkFDbkQ7aUJBQ0Y7c05BRXVDLFNBQVM7c0JBQTlDLGVBQWU7dUJBQUMsV0FBVztnQkE0QnhCLElBQUk7c0JBRFAsS0FBSzt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDIzIFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAqIFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBUUkVFX0ZFQVRVUkVTX1BST1ZJREVSLCBUcmVlRmVhdHVyZXNTZXJ2aWNlIH0gZnJvbSAnLi90cmVlLWZlYXR1cmVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgVHJlZUZvY3VzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuL3RyZWUtZm9jdXMtbWFuYWdlci5zZXJ2aWNlJztcbmltcG9ydCB7IENsclRyZWVOb2RlIH0gZnJvbSAnLi90cmVlLW5vZGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjbHItdHJlZScsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDxjbHItcmVjdXJzaXZlLWNoaWxkcmVuXG4gICAgICAqbmdJZj1cImZlYXR1cmVzU2VydmljZS5yZWN1cnNpb25cIlxuICAgICAgW2NoaWxkcmVuXT1cImZlYXR1cmVzU2VydmljZS5yZWN1cnNpb24ucm9vdFwiXG4gICAgPjwvY2xyLXJlY3Vyc2l2ZS1jaGlsZHJlbj5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbVFJFRV9GRUFUVVJFU19QUk9WSURFUiwgVHJlZUZvY3VzTWFuYWdlclNlcnZpY2VdLFxuICBob3N0OiB7XG4gICAgdGFiaW5kZXg6ICcwJyxcbiAgICAnW2F0dHIucm9sZV0nOiAnXCJ0cmVlXCInLFxuICAgICdbYXR0ci5hcmlhLW11bHRpc2VsZWN0YWJsZV0nOiAnaXNNdWx0aVNlbGVjdGFibGUnLFxuICB9LFxufSlcbmV4cG9ydCBjbGFzcyBDbHJUcmVlPFQ+IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgQENvbnRlbnRDaGlsZHJlbihDbHJUcmVlTm9kZSkgcHJpdmF0ZSByb290Tm9kZXM6IFF1ZXJ5TGlzdDxDbHJUcmVlTm9kZTxUPj47XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBmZWF0dXJlc1NlcnZpY2U6IFRyZWVGZWF0dXJlc1NlcnZpY2U8VD4sXG4gICAgcHJpdmF0ZSBmb2N1c01hbmFnZXJTZXJ2aWNlOiBUcmVlRm9jdXNNYW5hZ2VyU2VydmljZTxUPixcbiAgICB7IG5hdGl2ZUVsZW1lbnQgfTogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBuZ1pvbmU6IE5nWm9uZVxuICApIHtcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT5cbiAgICAgIGZyb21FdmVudChuYXRpdmVFbGVtZW50LCAnZm9jdXNpbicpLnN1YnNjcmliZSgoZXZlbnQ6IEZvY3VzRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gbmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgIC8vIEFmdGVyIGRpc2N1c3Npbmcgd2l0aCB0aGUgdGVhbSwgSSd2ZSBtYWRlIGl0IHNvIHRoYXQgd2hlbiB0aGUgdHJlZSByZWNlaXZlcyBmb2N1cywgdGhlIGZpcnN0IHZpc2libGUgbm9kZSB3aWxsIGJlIGZvY3VzZWQuXG4gICAgICAgICAgLy8gVGhpcyB3aWxsIHByZXZlbnQgZnJvbSB0aGUgcGFnZSBzY3JvbGxpbmcgYWJydXB0bHkgdG8gdGhlIGZpcnN0IHNlbGVjdGVkIG5vZGUgaWYgaXQgZXhpc3QgaW4gYSBkZWVwbHkgbmVzdGVkIHRyZWUuXG4gICAgICAgICAgdGhpcy5mb2N1c01hbmFnZXJTZXJ2aWNlLmZvY3VzRmlyc3RWaXNpYmxlTm9kZSgpO1xuICAgICAgICAgIC8vIHdoZW4gdGhlIGZpcnN0IGNoaWxkIGdldHMgZm9jdXMsXG4gICAgICAgICAgLy8gdHJlZSBzaG91bGQgbm8gbG9uZ2VyIGhhdmUgdGFiaW5kZXggb2YgMC5cbiAgICAgICAgICByZW5kZXJlci5yZW1vdmVBdHRyaWJ1dGUobmF0aXZlRWxlbWVudCwgJ3RhYmluZGV4Jyk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKHN1YnNjcmlwdGlvbik7XG4gIH1cblxuICBASW5wdXQoJ2NsckxhenknKVxuICBzZXQgbGF6eSh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuZmVhdHVyZXNTZXJ2aWNlLmVhZ2VyID0gIXZhbHVlO1xuICB9XG5cbiAgZ2V0IGlzTXVsdGlTZWxlY3RhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzU2VydmljZS5zZWxlY3RhYmxlICYmIHRoaXMucm9vdE5vZGVzLmxlbmd0aCA+IDA7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgdGhpcy5zZXRSb290Tm9kZXMoKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMucm9vdE5vZGVzLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRSb290Tm9kZXMoKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHN1YiA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gIH1cblxuICBwcml2YXRlIHNldFJvb3ROb2RlcygpOiB2b2lkIHtcbiAgICAvLyBpZiBub2RlIGhhcyBubyBwYXJlbnQsIGl0J3MgYSByb290IG5vZGVcbiAgICAvLyBmb3IgcmVjdXJzaXZlIHRyZWUsIHRoaXMucm9vdE5vZGVzIHJlZ2lzdGVycyBhbHNvIG5lc3RlZCBjaGlsZHJlblxuICAgIC8vIHNvIHdlIGhhdmUgdG8gdXNlIGZpbHRlciB0byBleHRyYWN0IHRoZSBvbmVzIHRoYXQgYXJlIHRydWx5IHJvb3Qgbm9kZXNcbiAgICB0aGlzLmZvY3VzTWFuYWdlclNlcnZpY2Uucm9vdE5vZGVNb2RlbHMgPSB0aGlzLnJvb3ROb2Rlcy5tYXAobm9kZSA9PiBub2RlLl9tb2RlbCkuZmlsdGVyKG5vZGUgPT4gIW5vZGUucGFyZW50KTtcbiAgfVxufVxuIl19