UNPKG

carbon-components-angular

Version:
182 lines 16.8 kB
import { DOCUMENT } from "@angular/common"; import { Component, Input, Output, EventEmitter, Inject, ViewChild } from "@angular/core"; import { TreeViewService } from "./treeview.service"; import * as i0 from "@angular/core"; import * as i1 from "./treeview.service"; import * as i2 from "@angular/common"; import * as i3 from "./tree-node.component"; /** * Get started with importing the module: * * ```typescript * import { TreeviewModule } from 'carbon-components-angular'; * ``` * * [See demo](../../?path=/story/components-tree-view--basic) */ export class TreeViewComponent { constructor(document, treeViewService, elementRef) { this.document = document; this.treeViewService = treeViewService; this.elementRef = elementRef; this.id = `tree-view-${TreeViewComponent.treeViewCount++}`; /** * Specify the size of the list items in the tree */ this.size = "sm"; this.select = new EventEmitter(); this._tree = []; } /** * Pass `Node[]` array to have tree view render the nodes * Passing value will disregard projected content */ set tree(treeNodes) { this._tree = treeNodes.map((node) => Object.assign({}, node)); this.treeViewService.contentProjected = false; } get tree() { return this._tree; } /** * **Experimental** - Enable to select multiple nodes */ set isMultiSelect(isMulti) { this.treeViewService.isMultiSelect = isMulti; } /** * Subscribe for node selection */ ngOnInit() { this.subscription = this.treeViewService.selectionObservable.subscribe((nodesMap) => { // Get all values from the map to emit const nodes = [...nodesMap.values()]; // Update focus to reset arrow key traversal // Select the current highlight node as the last node, since we preserve order in map this.treeWalker.currentNode = this.elementRef.nativeElement.querySelector(`#${CSS.escape(nodes[nodes.length - 1].id)}`); this.select.emit(this.treeViewService.isMultiSelect ? nodes : nodes[0]); }); } ngOnDestroy() { this.subscription.unsubscribe(); } /** * Initialize tree walker to support keyboard navigation */ ngAfterViewInit() { this.treeWalker = this.document.createTreeWalker(this.root.nativeElement, NodeFilter.SHOW_ELEMENT, { acceptNode: function (node) { if (node.classList.contains(`cds--tree-node--disabled`)) { return NodeFilter.FILTER_REJECT; } if (node.matches(`div.cds--tree-node`)) { return NodeFilter.FILTER_ACCEPT; } return NodeFilter.FILTER_SKIP; } }); } /** * Navigate tree using tree walker * @param event - KeyboardEvent */ navigateTree(event) { if (event.key === "ArrowUp") { this.treeWalker.previousNode()?.focus(); } if (event.key === "ArrowDown") { this.treeWalker.nextNode()?.focus(); } } isProjected() { return this.treeViewService.contentProjected; } } TreeViewComponent.treeViewCount = 0; TreeViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TreeViewComponent, deps: [{ token: DOCUMENT }, { token: i1.TreeViewService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); TreeViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TreeViewComponent, selector: "cds-tree-view", inputs: { tree: "tree", id: "id", label: "label", size: "size", isMultiSelect: "isMultiSelect" }, outputs: { select: "select" }, providers: [TreeViewService], viewQueries: [{ propertyName: "root", first: true, predicate: ["treeWrapper"], descendants: true }], ngImport: i0, template: ` <label *ngIf="label" [id]="id" class="cds--label"> {{label}} </label> <div class="cds--tree" [ngClass]="{ 'cds--tree--sm': size === 'sm', 'cds--tree--xs': size === 'xs' }" [attr.aria-label]="label ? label : null" [attr.aria-labelledby]="!label ? id : null" [attr.aria-multiselectable]="isMultiSelect || null" role="tree" (keydown)="navigateTree($event)" #treeWrapper> <ng-container *ngIf="isProjected(); else notProjected"> <ng-content></ng-content> </ng-container> <ng-template #notProjected> <cds-tree-node *ngFor="let node of tree" [node]="node"> </cds-tree-node> </ng-template> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.TreeNodeComponent, selector: "cds-tree-node", inputs: ["id", "active", "disabled", "expanded", "label", "selected", "value", "icon", "children", "depth", "node"], outputs: ["nodeFocus", "nodeBlur", "nodeSelect", "nodetoggle"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TreeViewComponent, decorators: [{ type: Component, args: [{ selector: "cds-tree-view", template: ` <label *ngIf="label" [id]="id" class="cds--label"> {{label}} </label> <div class="cds--tree" [ngClass]="{ 'cds--tree--sm': size === 'sm', 'cds--tree--xs': size === 'xs' }" [attr.aria-label]="label ? label : null" [attr.aria-labelledby]="!label ? id : null" [attr.aria-multiselectable]="isMultiSelect || null" role="tree" (keydown)="navigateTree($event)" #treeWrapper> <ng-container *ngIf="isProjected(); else notProjected"> <ng-content></ng-content> </ng-container> <ng-template #notProjected> <cds-tree-node *ngFor="let node of tree" [node]="node"> </cds-tree-node> </ng-template> </div> `, providers: [TreeViewService] }] }], ctorParameters: function () { return [{ type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i1.TreeViewService }, { type: i0.ElementRef }]; }, propDecorators: { tree: [{ type: Input }], id: [{ type: Input }], label: [{ type: Input }], size: [{ type: Input }], isMultiSelect: [{ type: Input }], select: [{ type: Output }], root: [{ type: ViewChild, args: ["treeWrapper"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZXZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RyZWV2aWV3L3RyZWV2aWV3LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNOLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUVOLFlBQVksRUFFWixNQUFNLEVBQ04sU0FBUyxFQUlULE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7QUFFckQ7Ozs7Ozs7O0dBUUc7QUFtQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQXVDN0IsWUFDMkIsUUFBa0IsRUFDbEMsZUFBZ0MsRUFDbEMsVUFBc0I7UUFGSixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xDLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNsQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBMUJ0QixPQUFFLEdBQUcsYUFBYSxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1FBSy9EOztXQUVHO1FBQ00sU0FBSSxHQUFnQixJQUFJLENBQUM7UUFReEIsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFpQixDQUFDO1FBSTdDLFVBQUssR0FBVyxFQUFFLENBQUM7SUFPeEIsQ0FBQztJQTFDSjs7O09BR0c7SUFDSCxJQUFhLElBQUksQ0FBQyxTQUFpQjtRQUNsQyxJQUFJLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFDL0MsQ0FBQztJQUVELElBQUksSUFBSTtRQUNQLE9BQU8sSUFBSSxD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QUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFJTyxhQUFhO3NCQUF6QixLQUFLO2dCQUlJLE1BQU07c0JBQWYsTUFBTTtnQkFDbUIsSUFBSTtzQkFBN0IsU0FBUzt1QkFBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1xuXHRDb21wb25lbnQsXG5cdElucHV0LFxuXHRPdXRwdXQsXG5cdFRlbXBsYXRlUmVmLFxuXHRFdmVudEVtaXR0ZXIsXG5cdEFmdGVyVmlld0luaXQsXG5cdEluamVjdCxcblx0Vmlld0NoaWxkLFxuXHRFbGVtZW50UmVmLFxuXHRPbkluaXQsXG5cdE9uRGVzdHJveVxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IE5vZGUgfSBmcm9tIFwiLi90cmVlLW5vZGUudHlwZXNcIjtcbmltcG9ydCB7IFRyZWVWaWV3U2VydmljZSB9IGZyb20gXCIuL3RyZWV2aWV3LnNlcnZpY2VcIjtcblxuLyoqXG4gKiBHZXQgc3RhcnRlZCB3aXRoIGltcG9ydGluZyB0aGUgbW9kdWxlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFRyZWV2aWV3TW9kdWxlIH0gZnJvbSAnY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhcic7XG4gKiBgYGBcbiAqXG4gKiBbU2VlIGRlbW9dKC4uLy4uLz9wYXRoPS9zdG9yeS9jb21wb25lbnRzLXRyZWUtdmlldy0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtdHJlZS12aWV3XCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGxhYmVsXG5cdFx0XHQqbmdJZj1cImxhYmVsXCJcblx0XHRcdFtpZF09XCJpZFwiXG5cdFx0XHRjbGFzcz1cImNkcy0tbGFiZWxcIj5cblx0XHRcdHt7bGFiZWx9fVxuXHRcdDwvbGFiZWw+XG5cdFx0PGRpdlxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRyZWVcIlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS10cmVlLS1zbSc6IHNpemUgPT09ICdzbScsXG5cdFx0XHRcdCdjZHMtLXRyZWUtLXhzJzogc2l6ZSA9PT0gJ3hzJ1xuXHRcdFx0fVwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImxhYmVsID8gbGFiZWwgOiBudWxsXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCIhbGFiZWwgPyBpZCA6IG51bGxcIlxuXHRcdFx0W2F0dHIuYXJpYS1tdWx0aXNlbGVjdGFibGVdPVwiaXNNdWx0aVNlbGVjdCB8fCBudWxsXCJcblx0XHRcdHJvbGU9XCJ0cmVlXCJcblx0XHRcdChrZXlkb3duKT1cIm5hdmlnYXRlVHJlZSgkZXZlbnQpXCJcblx0XHRcdCN0cmVlV3JhcHBlcj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1Byb2plY3RlZCgpOyBlbHNlIG5vdFByb2plY3RlZFwiPlxuXHRcdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDxuZy10ZW1wbGF0ZSAjbm90UHJvamVjdGVkPlxuXHRcdFx0XHQ8Y2RzLXRyZWUtbm9kZVxuXHRcdFx0XHRcdCpuZ0Zvcj1cImxldCBub2RlIG9mIHRyZWVcIlxuXHRcdFx0XHRcdFtub2RlXT1cIm5vZGVcIj5cblx0XHRcdFx0PC9jZHMtdHJlZS1ub2RlPlxuXHRcdFx0PC9uZy10ZW1wbGF0ZT5cblx0XHQ8L2Rpdj5cblx0YCxcblx0cHJvdmlkZXJzOiBbVHJlZVZpZXdTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBUcmVlVmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uSW5pdCwgT25EZXN0cm95IHtcblx0LyoqXG5cdCAqIFBhc3MgYE5vZGVbXWAgYXJyYXkgdG8gaGF2ZSB0cmVlIHZpZXcgcmVuZGVyIHRoZSBub2Rlc1xuXHQgKiBQYXNzaW5nIHZhbHVlIHdpbGwgZGlzcmVnYXJkIHByb2plY3RlZCBjb250ZW50XG5cdCAqL1xuXHRASW5wdXQoKSBzZXQgdHJlZSh0cmVlTm9kZXM6IE5vZGVbXSkge1xuXHRcdHRoaXMuX3RyZWUgPSB0cmVlTm9kZXMubWFwKChub2RlKSA9PiBPYmplY3QuYXNzaWduKHt9LCBub2RlKSk7XG5cdFx0dGhpcy50cmVlVmlld1NlcnZpY2UuY29udGVudFByb2plY3RlZCA9IGZhbHNlO1xuXHR9XG5cblx0Z2V0IHRyZWUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3RyZWU7XG5cdH1cblxuXHRzdGF0aWMgdHJlZVZpZXdDb3VudCA9IDA7XG5cblx0QElucHV0KCkgaWQgPSBgdHJlZS12aWV3LSR7VHJlZVZpZXdDb21wb25lbnQudHJlZVZpZXdDb3VudCsrfWA7XG5cdC8qKlxuXHQgKiBUcmVlIHZpZXcgbGFiZWxcblx0ICovXG5cdEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHQvKipcblx0ICogU3BlY2lmeSB0aGUgc2l6ZSBvZiB0aGUgbGlzdCBpdGVtcyBpbiB0aGUgdHJlZVxuXHQgKi9cblx0QElucHV0KCkgc2l6ZTogXCJ4c1wiIHwgXCJzbVwiID0gXCJzbVwiO1xuXHQvKipcblx0ICogKipFeHBlcmltZW50YWwqKiAtIEVuYWJsZSB0byBzZWxlY3QgbXVsdGlwbGUgbm9kZXNcblx0ICovXG5cdEBJbnB1dCgpIHNldCBpc011bHRpU2VsZWN0KGlzTXVsdGk6IGJvb2xlYW4pIHtcblx0XHR0aGlzLnRyZWVWaWV3U2VydmljZS5pc011bHRpU2VsZWN0ID0gaXNNdWx0aTtcblx0fVxuXG5cdEBPdXRwdXQoKSBzZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPE5vZGUgfCBOb2RlW10+KCk7XG5cdEBWaWV3Q2hpbGQoXCJ0cmVlV3JhcHBlclwiKSByb290OiBFbGVtZW50UmVmO1xuXG5cdHByaXZhdGUgdHJlZVdhbGtlcjogVHJlZVdhbGtlcjtcblx0cHJpdmF0ZSBfdHJlZTogTm9kZVtdID0gW107XG5cdHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0QEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogRG9jdW1lbnQsXG5cdFx0cHJvdGVjdGVkIHRyZWVWaWV3U2VydmljZTogVHJlZVZpZXdTZXJ2aWNlLFxuXHRcdHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZlxuXHQpIHt9XG5cblx0LyoqXG5cdCAqIFN1YnNjcmliZSBmb3Igbm9kZSBzZWxlY3Rpb25cblx0ICovXG5cdG5nT25Jbml0KCk6IHZvaWQge1xuXHRcdHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy50cmVlVmlld1NlcnZpY2Uuc2VsZWN0aW9uT2JzZXJ2YWJsZS5zdWJzY3JpYmUoKG5vZGVzTWFwOiBNYXA8c3RyaW5nLCBOb2RlPikgPT4ge1xuXHRcdFx0Ly8gR2V0IGFsbCB2YWx1ZXMgZnJvbSB0aGUgbWFwIHRvIGVtaXRcblx0XHRcdGNvbnN0IG5vZGVzID0gWy4uLm5vZGVzTWFwLnZhbHVlcygpXTtcblxuXHRcdFx0Ly8gVXBkYXRlIGZvY3VzIHRvIHJlc2V0IGFycm93IGtleSB0cmF2ZXJzYWxcblx0XHRcdC8vIFNlbGVjdCB0aGUgY3VycmVudCBoaWdobGlnaHQgbm9kZSBhcyB0aGUgbGFzdCBub2RlLCBzaW5jZSB3ZSBwcmVzZXJ2ZSBvcmRlciBpbiBtYXBcblx0XHRcdHRoaXMudHJlZVdhbGtlci5jdXJyZW50Tm9kZSA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke0NTUy5lc2NhcGUobm9kZXNbbm9kZXMubGVuZ3RoIC0gMV0uaWQpfWApO1xuXHRcdFx0dGhpcy5zZWxlY3QuZW1pdCh0aGlzLnRyZWVWaWV3U2VydmljZS5pc011bHRpU2VsZWN0ID8gbm9kZXMgOiBub2Rlc1swXSk7XG5cdFx0fSk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpOiB2b2lkIHtcblx0XHR0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdHJlZSB3YWxrZXIgdG8gc3VwcG9ydCBrZXlib2FyZCBuYXZpZ2F0aW9uXG5cdCAqL1xuXHRuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cdFx0dGhpcy50cmVlV2Fsa2VyID0gdGhpcy5kb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHRoaXMucm9vdC5uYXRpdmVFbGVtZW50LCBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCwge1xuXHRcdFx0YWNjZXB0Tm9kZTogZnVuY3Rpb24gKG5vZGU6IEhUTUxFbGVtZW50KSB7XG5cdFx0XHRcdGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucyhgY2RzLS10cmVlLW5vZGUtLWRpc2FibGVkYCkpIHtcblx0XHRcdFx0XHRyZXR1cm4gTm9kZUZpbHRlci5GSUxURVJfUkVKRUNUO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChub2RlLm1hdGNoZXMoYGRpdi5jZHMtLXRyZWUtbm9kZWApKSB7XG5cdFx0XHRcdFx0cmV0dXJuIE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVDtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gTm9kZUZpbHRlci5GSUxURVJfU0tJUDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZSB0cmVlIHVzaW5nIHRyZWUgd2Fsa2VyXG5cdCAqIEBwYXJhbSBldmVudCAtIEtleWJvYXJkRXZlbnRcblx0ICovXG5cdG5hdmlnYXRlVHJlZShldmVudDogS2V5Ym9hcmRFdmVudCkge1xuXHRcdGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dVcFwiKSB7XG5cdFx0XHQodGhpcy50cmVlV2Fsa2VyLnByZXZpb3VzTm9kZSgpIGFzIEhUTUxFbGVtZW50KT8uZm9jdXMoKTtcblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkFycm93RG93blwiKSB7XG5cdFx0XHQodGhpcy50cmVlV2Fsa2VyLm5leHROb2RlKCkgYXMgSFRNTEVsZW1lbnQpPy5mb2N1cygpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBpc1Byb2plY3RlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy50cmVlVmlld1NlcnZpY2UuY29udGVudFByb2plY3RlZDtcblx0fVxufVxuIl19