# Tree

树形控件，用于展示层级结构数据，支持展开/收起、单选和 checkbox 多选。

## 适用场景

- 展示层级结构数据，如文件目录、组织架构、分类菜单
- 需要 checkbox 多选且父子节点联动的树形选择
- 需要精确控制展开/收起状态的树形列表

## Props

### Tree Props

| 名称 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| className | `string` | `""` | 否 | 自定义 class |
| nodes | `TreeNodeItem[]` | `-` | 否 | 节点数据 |
| harmonizeSelections | `boolean` | `true` | 否 | 联动父子节点选择/反选。联动模式下全选范围不包括 disabled 节点 |
| expandedIds | `(string \| number)[]` | `-` | 否 | 展开节点 ids 控制值 |
| defaultExpandedIds | `(string \| number)[]` | `-` | 否 | 展开节点 ids 默认值 |
| onChangeExpandedIds | `(ids: (string \| number)[]) => void` | `-` | 否 | 展开/收起变化时的回调 |
| onExpand | `(expandedId: string \| number, expandedIds: (string \| number)[]) => void` | `-` | 否 | 节点展开时的回调 |
| onCollapse | `(expandedId: string \| number, expandedIds: (string \| number)[]) => void` | `-` | 否 | 节点收起时的回调 |
| selectedIds | `(string \| number)[]` | `-` | 否 | 选中节点 ids 控制值 |
| defaultSelectedIds | `(string \| number)[]` | `-` | 否 | 选中节点 ids 默认值 |
| onChangeSelectedIds | `(ids: (string \| number)[]) => void` | `-` | 否 | 选中节点 ids 变化时的回调 |
| onSelect | `(selectId: string \| number, selectIds: (string \| number)[]) => void` | `-` | 否 | 节点选中时的回调 |
| onDeselect | `(selectId: string \| number, selectIds: (string \| number)[]) => void` | `-` | 否 | 节点反选时的回调 |
| toggleIcon | `(treeNodeItem: TreeNodeItem) => SvgFC` | `-` | 否 | 展开/收起 icon svg 取值函数 |
| prefixIcon | `(treeNodeItem: TreeNodeItem) => SvgFC` | `-` | 否 | 是否选中 icon svg 取值函数 |
| selectableType | `"checkbox" \| "normal"` | `"normal"` | 否 | 可选中模式的类型 |
| size | `"md" \| "sm"` | `-` | 否 | 尺寸，默认使用 config context 的 `baseSize` |

### TreeNodeItem Props

| 名称 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| id | `string \| number` | `-` | 是 | 节点唯一标识 |
| content | `ReactNode` | `-` | 否 | 节点内容 |
| disabled | `boolean` | `-` | 否 | 是否禁用 |
| children | `TreeNodeItem[]` | `-` | 否 | 子节点列表 |
| className | `string` | `-` | 否 | 自定义 class |
| toggleIcon | `SvgFC` | `-` | 否 | 节点展开/收起 icon svg |
| prefixIcon | `SvgFC` | `-` | 否 | 节点前缀 icon svg |
| isLeaf | `boolean` | `-` | 否 | 异步模式下指定为叶子节点，不加载子节点 |

## 典型用法

### 基础用法

```tsx
import { useState } from 'react'
import { Tree, TreeNodeItem, TreeProps } from '@befe/brick'

const nodes: TreeNodeItem[] = [
    {
        id: '1',
        content: '一级_1',
        children: [
            { id: '1.1', content: '二级_1-1' },
            { id: '1.2', content: '二级_1-2' },
        ],
    },
    {
        id: '2',
        content: '一级_2',
        children: [
            { id: '2.1', content: '二级_2-1', disabled: true },
            { id: '2.2', content: '二级_2-2' },
        ],
    },
    { id: '3', content: '一级_3' },
]

const [expandedIds, setExpandedIds] = useState<TreeProps['expandedIds']>(['1', '2'])

<Tree
    nodes={nodes}
    expandedIds={expandedIds}
    onChangeExpandedIds={setExpandedIds}
    selectedIds={[]}
/>
```

### Checkbox 多选

```tsx
const [selectedIds, setSelectedIds] = useState(['1.1', '2.1'])

<Tree
    nodes={nodes}
    defaultExpandedIds={['1', '2']}
    selectedIds={selectedIds}
    onChangeSelectedIds={setSelectedIds}
    selectableType="checkbox"
/>
```

### 尺寸

```tsx
<Tree size="md" nodes={nodes} selectableType="checkbox" />
<Tree size="sm" nodes={nodes} selectableType="checkbox" />
```

## 注意事项

- 每个 `TreeNodeItem` 的 `id` 必填，且在整棵树中须唯一
- `harmonizeSelections` 为 `true`（默认）时，父子节点选择联动；联动时全选/反选的计算范围**不包括** disabled 节点
- `selectableType="checkbox"` 时显示 checkbox 样式，`"normal"` 时为点击高亮选中样式
- `expandedIds` 和 `selectedIds` 均支持受控与非受控两种用法，分别对应 `defaultExpandedIds`/`defaultSelectedIds`
