Taiga UI 5.0 is out!

Tree KIT

Examples API GitHub

On this page

Component to display tree-like data structure

Manual

Fruits
Apples
Granny SmithRed Delicious
Oranges
Animals
CatsDogs
    
      
    
    
      <div
    role="tree"
    [tuiTreeController]="true"
>
    <tui-tree-item>
        Fruits
        <tui-tree-item>
            Apples
            <tui-tree-item>Granny Smith</tui-tree-item>
            <tui-tree-item>Red Delicious</tui-tree-item>
        </tui-tree-item>
        <tui-tree-item>Oranges</tui-tree-item>
    </tui-tree-item>
    <tui-tree-item>
        Animals
        <tui-tree-item>Cats</tui-tree-item>
        <tui-tree-item>Dogs</tui-tree-item>
    </tui-tree-item>
</div>

    

Array

Top level 1
Second level item
Third level 1 Third level 2 Third level 3
Top level 2 Top level 3
Second 1 Second 2
    
      
    
    
      <tui-tree [value]="data" />

    
    
      tui-tree {
    margin-inline-start: -3.5rem;
}

    

Template

Topmost
Top level 1
Another item
Next level 1
Next level 2
Next level 3
Top level 2
Top level 3
Test 1
Test 2
    
      
    
    
      <tui-tree
    [childrenHandler]="handler"
    [content]="content"
    [tuiTreeController]="true"
    [value]="data"
/>

<ng-template
    #content
    let-node="node"
    let-value
>
    <div
        class="wrapper"
        [style.opacity]="1 / node.level"
    >
        @if (value.icon) {
            <tui-icon
                class="t-icon"
                [icon]="value.icon"
            />
        }
        {{ value.text }}
    </div>
</ng-template>

    
    
      .wrapper {
    display: flex;
    align-items: center;
}

.t-icon::before {
    font-size: 1rem;
}

    

Programmatic control

Topmost
Top level 1
Another item
Next level 1 Next level 2 Next level 3
Top level 2 Top level 3
Test 1 Test 2

    
      
    
    
      <tui-tree
    [childrenHandler]="handler"
    [content]="content"
    [map]="map"
    [tuiTreeController]="false"
    [value]="data"
/>

<ng-template
    #content
    let-item
>
    {{ item.text }}
</ng-template>

<p>
    <button
        size="s"
        tuiButton
        type="button"
        class="programmatic tui-space_right-2"
        (click)="toggleTopmost()"
    >
        Toggle Topmost
    </button>
</p>
<p>
    <button
        size="s"
        tuiButton
        type="button"
        class="programmatic"
        (click)="toggleLevel(0)"
    >
        Toggle Top level 1
    </button>
</p>
<button
    size="s"
    tuiButton
    type="button"
    class="programmatic"
    (click)="toggleLevel(2)"
>
    Toggle Top level 3
</button>

    

Custom

Top level 1
Another item
Next level 1 Next level 2 Next level 3
Top level 2 Top level 3
Test 1 Test 2
    
      
    
    
      @for (item of data.children; track item) {
    <tui-tree
        [childrenHandler]="handler"
        [content]="content"
        [tuiTreeController]="true"
        [value]="item"
    />
}

<ng-template
    #content
    let-item
>
    {{ item.text }}
</ng-template>

    
    
      tui-tree {
    overflow: hidden;
}

    

Checkbox

    
      
    
    
      @for (item of data.children; track item) {
    <tui-tree
        [childrenHandler]="handler"
        [content]="content"
        [tuiTreeController]="true"
        [value]="item"
    />
}

<ng-template
    #content
    let-item
>
    <label
        tuiLabel
        class="tui-space_vertical-2 tui-space_left-1"
    >
        <input
            size="s"
            tuiCheckbox
            type="checkbox"
            [ngModel]="item | tuiMapper: getValue : map"
            (ngModelChange)="onChecked(item, $event)"
        />
        <small>{{ item.text }}</small>
    </label>
</ng-template>

    

Asynchronous

Topmost
    
      
    
    
      <tui-tree
    [childrenHandler]="childrenHandler"
    [content]="content"
    [map]="map"
    [tuiTreeController]="false"
    [value]="service.data$ | async"
    (toggled)="onToggled($event)"
/>

<ng-template
    #content
    let-item
>
    @if (item === loading) {
        <tui-loader class="loader" />
    } @else {
        {{ item.text }}
    }
</ng-template>

    
    
      .loader {
    inline-size: 2rem;
    margin: 1rem 0;
}

    

Drag and drop

Topmost
Top level 1
Another item
Next level 1
Next level 2
Next level 3
Top level 2
Top level 3
Test 1
Test 2
    
      
    
    
      <tui-tree
    class="tree"
    [childrenHandler]="handler"
    [class._dragged]="drag()"
    [content]="content"
    [tuiTreeController]="true"
    [value]="data"
>
    <ng-template
        #content
        let-value
    >
        @if (!value.children) {
            <div class="wrapper">
                <div
                    class="drop"
                    (pointerup)="onDrop(value)"
                ></div>
                <tui-tiles class="tiles">
                    <tui-tile>
                        <div
                            tuiTileHandle
                            class="content"
                            (pointerdown)="onDrag(value)"
                        >
                            {{ value.text }}
                        </div>
                    </tui-tile>
                </tui-tiles>
                <div
                    class="drop"
                    (pointerup)="onDrop(value, 1)"
                ></div>
            </div>
        } @else {
            {{ value.text }}
        }
    </ng-template>
</tui-tree>

    
    
      .tree._dragged {
    .drop {
        pointer-events: auto;

        &:hover {
            opacity: 1;
        }
    }
}

.wrapper {
    position: relative;
    inline-size: 100%;
}

.content {
    display: flex;
    inline-size: 100%;
    align-items: center;
}

.tiles {
    inline-size: 100%;
    grid-template-rows: 1.5rem;
}

.drop {
    position: absolute;
    z-index: 1;
    inline-size: 100%;
    block-size: 0.5rem;
    margin-block-start: -0.25rem;
    background: #87ceeb;
    border-radius: 1rem;
    opacity: 0;
    pointer-events: none;
}