File

src/treeview/treeview.component.ts

Description

Get started with importing the module:

import { TreeviewModule } from 'carbon-components-angular';

See demo

Implements

AfterViewInit OnInit OnDestroy

Metadata

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(document: Document, treeViewService: TreeViewService, elementRef: ElementRef)
Parameters :
Name Type Optional
document Document No
treeViewService TreeViewService No
elementRef ElementRef No

Inputs

id
Type : string
Default value : `tree-view-${TreeViewComponent.treeViewCount++}`
isMultiSelect
Type : boolean

Experimental - Enable to select multiple nodes

label
Type : string | TemplateRef<any>

Tree view label

size
Type : "xs" | "sm"
Default value : "sm"

Specify the size of the list items in the tree

tree
Type : Node[]

Pass Node[] array to have tree view render the nodes Passing value will disregard projected content

Outputs

select
Type : EventEmitter

Methods

Public isProjected
isProjected()
Returns : any
navigateTree
navigateTree(event: KeyboardEvent)

Navigate tree using tree walker

Parameters :
Name Type Optional Description
event KeyboardEvent No
  • KeyboardEvent
Returns : void
ngAfterViewInit
ngAfterViewInit()

Initialize tree walker to support keyboard navigation

Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()

Subscribe for node selection

Returns : void

Properties

Private _tree
Type : Node[]
Default value : []
root
Type : ElementRef
Decorators :
@ViewChild('treeWrapper')
Private subscription
Type : Subscription
Static treeViewCount
Type : number
Default value : 0
Private treeWalker
Type : TreeWalker

Accessors

tree
gettree()
settree(treeNodes: Node[])

Pass Node[] array to have tree view render the nodes Passing value will disregard projected content

Parameters :
Name Type Optional
treeNodes Node[] No
Returns : void
isMultiSelect
setisMultiSelect(isMulti: boolean)

Experimental - Enable to select multiple nodes

Parameters :
Name Type Optional
isMulti boolean No
Returns : void
import { DOCUMENT } from "@angular/common";
import {
	Component,
	Input,
	Output,
	TemplateRef,
	EventEmitter,
	AfterViewInit,
	Inject,
	ViewChild,
	ElementRef,
	OnInit,
	OnDestroy
} from "@angular/core";
import { Subscription } from "rxjs";
import { Node } from "./tree-node.types";
import { TreeViewService } from "./treeview.service";

/**
 * Get started with importing the module:
 *
 * ```typescript
 * import { TreeviewModule } from 'carbon-components-angular';
 * ```
 *
 * [See demo](../../?path=/story/components-tree-view--basic)
 */
@Component({
	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]
})
export class TreeViewComponent implements AfterViewInit, OnInit, OnDestroy {
	/**
	 * Pass `Node[]` array to have tree view render the nodes
	 * Passing value will disregard projected content
	 */
	@Input() set tree(treeNodes: Node[]) {
		this._tree = treeNodes.map((node) => Object.assign({}, node));
		this.treeViewService.contentProjected = false;
	}

	get tree() {
		return this._tree;
	}

	static treeViewCount = 0;

	@Input() id = `tree-view-${TreeViewComponent.treeViewCount++}`;
	/**
	 * Tree view label
	 */
	@Input() label: string | TemplateRef<any>;
	/**
	 * Specify the size of the list items in the tree
	 */
	@Input() size: "xs" | "sm" = "sm";
	/**
	 * **Experimental** - Enable to select multiple nodes
	 */
	@Input() set isMultiSelect(isMulti: boolean) {
		this.treeViewService.isMultiSelect = isMulti;
	}

	@Output() select = new EventEmitter<Node | Node[]>();
	@ViewChild("treeWrapper") root: ElementRef;

	private treeWalker: TreeWalker;
	private _tree: Node[] = [];
	private subscription: Subscription;

	constructor(
		@Inject(DOCUMENT) private document: Document,
		protected treeViewService: TreeViewService,
		private elementRef: ElementRef
	) {}

	/**
	 * Subscribe for node selection
	 */
	ngOnInit(): void {
		this.subscription = this.treeViewService.selectionObservable.subscribe((nodesMap: Map<string, Node>) => {
			// 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(): void {
		this.subscription.unsubscribe();
	}

	/**
	 * Initialize tree walker to support keyboard navigation
	 */
	ngAfterViewInit(): void {
		this.treeWalker = this.document.createTreeWalker(this.root.nativeElement, NodeFilter.SHOW_ELEMENT, {
			acceptNode: function (node: HTMLElement) {
				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: KeyboardEvent) {
		if (event.key === "ArrowUp") {
			(this.treeWalker.previousNode() as HTMLElement)?.focus();
		}

		if (event.key === "ArrowDown") {
			(this.treeWalker.nextNode() as HTMLElement)?.focus();
		}
	}

	public isProjected() {
		return this.treeViewService.contentProjected;
	}
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""