Overview
The Tree component displays hierarchical data in an expandable/collapsible tree structure. It supports single/multiple selection, checkbox selection, filtering, and drag-and-drop reordering.
Import
import { MagaryTree, MagaryTreeNode } from 'ng-magary';
Basic Usage
import { Component, signal } from '@angular/core';
import { MagaryTree, MagaryTreeNode } from 'ng-magary';
@Component({
selector: 'app-tree-demo',
standalone: true,
imports: [MagaryTree],
template: `
<magary-tree
[value]="nodes()"
(onNodeSelect)="onNodeSelect($event)"
(onNodeUnselect)="onNodeUnselect($event)">
</magary-tree>
`
})
export class TreeDemoComponent {
nodes = signal<MagaryTreeNode[]>([
{
label: 'Documents',
expanded: true,
children: [
{ label: 'Work', children: [
{ label: 'Report.pdf', icon: 'file-text' },
{ label: 'Budget.xlsx', icon: 'file-spreadsheet' }
]},
{ label: 'Personal', children: [
{ label: 'Resume.pdf', icon: 'file-text' }
]}
]
}
]);
onNodeSelect(event: any) {
console.log('Selected:', event.node.label);
}
onNodeUnselect(event: any) {
console.log('Unselected:', event.node.label);
}
}
With Selection
@Component({
template: `
<magary-tree
[value]="nodes"
selectionMode="single"
[(selection)]="selectedNode"
(onNodeSelect)="onNodeSelect($event)">
</magary-tree>
`
})
export class TreeSelectionComponent {
nodes: MagaryTreeNode[] = [...];
selectedNode: MagaryTreeNode | null = null;
onNodeSelect(event: any) {
console.log('Selected:', event.node);
}
}
With Checkbox Selection
@Component({
template: `
<magary-tree
[value]="nodes"
selectionMode="checkbox"
[(selection)]="selectedNodes"
(onNodeSelect)="onNodeSelect($event)">
</magary-tree>
`
})
export class TreeCheckboxComponent {
nodes: MagaryTreeNode[] = [...];
selectedNodes: Record<string, boolean> = {};
onNodeSelect(event: any) {
console.log('Selection changed:', this.selectedNodes);
}
}
With Filtering
<magary-tree
[value]="nodes"
[filter]="true"
filterPlaceholder="Search tree..."
filterMode="lenient"
(onNodeSelect)="onNodeSelect($event)">
</magary-tree>
With Drag and Drop
@Component({
template: `
<magary-tree
[value]="nodes"
[draggable]="true"
[droppable]="true"
[validateDrop]="true"
(onNodeDrop)="onNodeDrop($event)">
</magary-tree>
`
})
export class TreeDragDropComponent {
nodes: MagaryTreeNode[] = [...];
onNodeDrop(event: any) {
console.log('Dropped:', event.dragNode, 'to', event.parent);
// Update your data structure here
}
}
Properties
value
MagaryTreeNode[]
default:"[]"
Array of tree nodes to display.
selectionMode
'single' | 'multiple' | 'checkbox' | null
default:"null"
Selection mode for the tree. When null, selection is disabled.
selection
MagaryTreeSelectionValue
default:"null"
Currently selected node(s). Type depends on selectionMode.
When enabled, displays a search input to filter tree nodes.
filterPlaceholder
string
default:"'Search...'"
Placeholder text for the filter input.
filterAriaLabel
string
default:"'Filter tree nodes'"
ARIA label for the filter input.
filterMode
'lenient' | 'strict'
default:"'lenient'"
Filter matching mode. ‘lenient’ uses contains, ‘strict’ uses exact match.
Enables drag functionality for tree nodes.
Enables drop functionality for tree nodes.
When enabled, prevents dropping nodes onto their descendants.
treeAriaLabel
string
default:"'Tree data'"
ARIA label for the tree element.
Events
onNodeSelect
EventEmitter<MagaryTreeNodeSelectionEvent>
Emitted when a node is selected.
onNodeUnselect
EventEmitter<MagaryTreeNodeSelectionEvent>
Emitted when a node is unselected.
onNodeExpand
EventEmitter<MagaryTreeNode>
Emitted when a node is expanded.
onNodeCollapse
EventEmitter<MagaryTreeNode>
Emitted when a node is collapsed.
onNodeDrop
EventEmitter<MagaryTreeNodeDropEvent>
Emitted when a node is dropped (requires draggable and droppable).
Interfaces
MagaryTreeNode
interface MagaryTreeNode {
label?: string; // Node label text
data?: any; // Custom data
icon?: string; // Icon name
expandedIcon?: string; // Icon when expanded
collapsedIcon?: string; // Icon when collapsed
children?: MagaryTreeNode[]; // Child nodes
leaf?: boolean; // Is leaf node
expanded?: boolean; // Expansion state
type?: string; // Node type
parent?: MagaryTreeNode; // Parent node reference
partialSelected?: boolean; // Partial selection state
styleClass?: string; // Custom CSS class
draggable?: boolean; // Can be dragged
droppable?: boolean; // Can receive drops
selectable?: boolean; // Can be selected
key?: string; // Unique identifier
}
MagaryTreeSelectionValue
type MagaryTreeSelectionValue =
| MagaryTreeNode // Single selection
| MagaryTreeNode[] // Multiple selection
| Record<string, boolean> // Checkbox selection
| null;
MagaryTreeNodeSelectionEvent
interface MagaryTreeNodeSelectionEvent {
originalEvent: Event; // Original DOM event
node: MagaryTreeNode; // Selected/unselected node
}
MagaryTreeNodeDropEvent
interface MagaryTreeNodeDropEvent {
originalEvent: CdkDragDrop<MagaryTreeNode[]>;
parent: MagaryTreeNode | null; // New parent node
dragNode: MagaryTreeNode; // Dragged node
}
Filtering Behavior
When filtering is enabled:
- Lenient Mode: Shows nodes whose labels contain the filter text (case-insensitive)
- Strict Mode: Shows nodes whose labels exactly match the filter text
- Parent nodes are automatically expanded when children match
- The tree structure is preserved (parent nodes shown if children match)
Drag and Drop Behavior
When validateDrop is enabled:
- Nodes cannot be dropped onto themselves
- Nodes cannot be dropped onto their descendants
- Invalid drop targets are rejected
Handle the onNodeDrop event to update your data structure:
onNodeDrop(event: MagaryTreeNodeDropEvent) {
const dragNode = event.dragNode;
const newParent = event.parent;
// Update your data structure
// Remove dragNode from old parent
// Add dragNode to newParent.children
}
Accessibility
- Uses proper ARIA tree roles and attributes
- Keyboard navigation with arrow keys
- Expand/collapse with Enter/Space
- Focus management for keyboard users
- Screen reader announcements for selection changes
Styling
Key CSS classes:
magary-tree - Main tree container
magary-tree-node - Individual tree node
magary-tree-node-content - Node content wrapper
magary-tree-node-children - Children container
Source
View source: projects/ng-magary/src/lib/Data/tree/tree.ts:36