# useTableTreeData

## 使用方法

给表格用的无渲染树插件。树列（默认是第一列）里会按层级缩进，并画出展开/收起的箭头；表体行上会带 `aria-level` 和 `aria-expanded`，把层级关系说出来。它和别的表格插件可以叠着用：约定顺序是树在前、选择在后，这样复选框列就落在缩进过的树列左边。配置可以直接用 `useTableTreeState` 帮你拼好的那份，也可以在服务端驱动或者数据已经拍平的场景自己拼。一行都不可展开时（比如拍平的普通数据），它的每个变换都是原样返回，表格看起来和没装这个插件一样。已知限制：树列里的内容会自动换行，所以 `textOverflow="truncate"` 的提示在树列里不生效。

```ts
import { useTableTreeData } from '@astryx-vue/core/Table'
```

## 示例

### useTableTreeData —— 树形表格

子行沿用同样的列，按层级缩进，树列里带展开/收起箭头。表头的开关可以一次展开所有分支。

```vue
<script setup lang="ts">
import type { TableColumn } from '@astryx-vue/core/Table'
import { proportional, Table, useTableTreeState } from '@astryx-vue/core/Table'

interface Node extends Record<string, unknown> {
  id: string
  name: string
  owner: string
  children?: Node[]
}

const nodes: Node[] = [
  {
    id: 'platform',
    name: 'Platform',
    owner: 'Ada',
    children: [
      { id: 'api', name: 'API', owner: 'Grace' },
      {
        id: 'web',
        name: 'Web',
        owner: 'Lin',
        children: [
          { id: 'docs', name: 'Docs', owner: 'Maya' },
        ],
      },
    ],
  },
  { id: 'design', name: 'Design', owner: 'Noah' },
]

const columns: TableColumn<Node>[] = [
  { key: 'name', header: 'Name', width: proportional(2) },
  { key: 'owner', header: 'Owner', width: proportional(1) },
]

const { visibleData, plugin: treePlugin } = useTableTreeState<Node>({
  data: nodes,
  idKey: 'id',
  defaultExpandedIds: ['platform'],
  hasExpandAllControl: true,
  hasRowClickExpansion: true,
})
</script>

<template>
  <Table
    :data="visibleData"
    :columns="columns"
    id-key="id"
    has-hover
    :plugins="{ tree: treePlugin }"
  />
</template>
```

## 属性

配置对象是 `MaybeRefOrGetter`：传一个 getter，行的层级信息、全展开状态和切换动作才能保持实时。

## 参数

| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `getRowMeta` | `(item: T) => TableTreeRowMeta \| undefined` | — | 某一可见行的结构信息：`{ id, level（从 0 开始）, hasChildren, isExpanded }`。不属于树的行返回 `undefined`。 |
| `onToggleItem` | `(item: T) => void` | — | 切换这一行的展开状态。 |
| `hasExpandableRows` | `boolean` | — | 数据里有没有可展开的行。为 false 时插件什么都不做：没有箭头，没有缩进，也没有树的 ARIA 属性。 |
| `hasExpandAllControl` | `boolean` | `false` | 在树列的表头放一个全部展开/全部收起的开关。要配合 `isAllExpanded` 和 `onExpandAll` / `onCollapseAll` 一起用。 |
| `isAllExpanded` | `boolean \| 'indeterminate'` | — | 所有可展开行的整体展开状态，驱动表头那个开关。全展开是 `true`，全收起是 `false`，只有一部分展开是 `'indeterminate'`。 |
| `onExpandAll` | `() => void` | — | 展开所有可展开的行。表头的开关会调它。 |
| `onCollapseAll` | `() => void` | — | 收起所有行。表头的开关会调它。 |
| `indent` | `'sm' \| 'md' \| 'lg'` | `'md'` | 每层的缩进档位，对应 spacing-3 / spacing-4 / spacing-6 三个 token。 |
| `treeColumnKey` | `string` | 插件之外的第一列 | 承载缩进和展开箭头的列。给的键找不到时，用第一个不是插件加进来的列。 |
| `hasRowClickExpansion` | `boolean` | `false` | 为 true 时，点可展开行的任意位置都能展开或收起，不只是点箭头。这是方便鼠标用户的额外操作：键盘和读屏用户仍然用箭头按钮。点到单元格里的交互内容（按钮、链接、表单控件）或者正在选中文字时不会切换。叶子行没有反应，数据本来就拍平时这个参数也没作用。 |

## 返回值

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `transformColumns` | `(columns: TableColumn[]) => TableColumn[]` | 把树列原来的单元格渲染包一层，画出层级缩进、箭头和内容。`hasExpandableRows` 为 false 或者找不到树列时，原样返回。 |
| `headerPatch` | `(column: TableColumn) => TableHeaderPatch \| null` | 把全部展开 / 全部收起的按钮放到树列表头文字前面。其它列、没开 `hasExpandAllControl`、或者三个全展开字段没给齐时，返回 `null`。 |
| `rowPatch` | `(row: T, index: number, columnCount: number) => TableRowPatch \| null` | 写出 `aria-level`（层级 + 1），有子行的还写 `aria-expanded`。开了 `hasRowClickExpansion` 时，还会给可展开行加上点击切换和 `astryx-table__clickable` 类。 |
