---
title: "Tree 컴포넌트 — zenit Zig UI"
description: "계층 데이터, 파일 트리, 펼칠 수 있는 구조.펼치기, 선택, 들여쓰기, 아이콘, 키보드 탐색이 안정적인 node id를 기준으로 동작합니다."
url: https://zenit.z.express/ko/components/tree
language: ko
alternate_en: https://zenit.z.express/components/tree.md
alternate_zh: https://zenit.z.express/zh/components/tree.md
alternate_es: https://zenit.z.express/es/components/tree.md
alternate_ja: https://zenit.z.express/ja/components/tree.md
alternate_fr: https://zenit.z.express/fr/components/tree.md
alternate_de: https://zenit.z.express/de/components/tree.md
project: zenit v0.1.0-alpha (Zig 0.15.2, macOS)
source: https://github.com/version-next/zenit
---

# Tree

`ui.widgets.Tree`

계층 데이터, 파일 트리, 펼칠 수 있는 구조.

[Video](https://zenit.z.express/media/stories/tree.mp4?v=8481e7ed45)

**BEHAVIOR CONTRACT**

펼치기, 선택, 들여쓰기, 아이콘, 키보드 탐색이 안정적인 node id를 기준으로 동작합니다.

**RECORDED INTERACTION**

harness가 src 노드를 클릭해 하위 트리를 접고 펼칩니다.

`examples/storybook/stories.zig:2420`

```zig
// ── Tree ──
pub fn buildTree(scope: *ui.Scope, cx: *ui.Cx) anyerror!*ui.Node {
    const leaves = [_]W.TreeNodeData{
        .{ .id = "main", .label_text = "main.zig" },
        .{ .id = "root", .label_text = "root.zig" },
    };
    const nodes = [_]W.TreeNodeData{
        .{ .id = "src", .label_text = "src", .children = &leaves },
        .{ .id = "readme", .label_text = "README.md" },
    };
    const t = try W.Tree(.{ .nodes = &nodes }).mount(scope, cx);
    return t.wrapper;
}
```

[GitHub에서 소스 보기examples/storybook/stories.zig:2420](https://github.com/version-next/zenit/blob/HEAD/examples/storybook/stories.zig#L2420)

Storybook에 있는 이 story의 원본 코드입니다(zenit 5f9add5+wip 2026-09-30). `W`는 `ui.widgets`이며, `col` / `row` / `label`은 Storybook 내부의 작은 레이아웃 헬퍼입니다.

### TreeProps

`ui.widgets.Tree`

[src/ui/components/tree/mod.zig:38](https://github.com/version-next/zenit/blob/HEAD/src/ui/components/tree/mod.zig#L38)

```zig
fn Tree(props: TreeProps) TreeBuilder
```

| 필드 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| `nodes` | `[]const TreeNodeData` | `&.{}` | — |
| `indent` | `f32` | `20` | — |
| `selectable` | `bool` | `true` | — |
| `on_select` | `?core.HandlerRef` | `null` | 选中回调。用 \`cx.strHandlerFrom(State, ptr, method)\` 构造即可在回调里 拿到\*\*被选中节点的 id\*\*（此前是无 payload 的 HandlerRef，而 FlatNode 是私有的，应用根本无从知道选中了谁）。注册成无参 handler 也仍会被调用。 |
| `on_expand` | `?core.HandlerRef` | `null` | — |
| `expand_icon_asset` | `?svg_assets.Asset` | `null` | — |
| `selection_mode` | `selection_mod.SelectionMode` | `.single` | 选择模式。默认 .single = 与加入多选之前的行为一致（非破坏性新增）。 .multi 下 Cmd/Ctrl 点选切换、Shift 点选连续区间（按 flat\_index）。 |

### TreeResult

`ui.widgets.Tree`

[src/ui/components/tree/mod.zig:269](https://github.com/version-next/zenit/blob/HEAD/src/ui/components/tree/mod.zig#L269)

| 필드 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| `wrapper` | `*Node` | — | — |
| `state` | `*TreeState` | — | — |
