# useTableSelectionState

## 使用方法

`useTableSelection` 的配套状态工具。它返回两个东西：`selectionConfig` 交给选择插件，`selectionState` 交给关心选择状态的界面，比如 `TableSelectionToolbar`。选中结果仍然是受控的：选中的键那个 `Set` 由你保存，再给一个写回的函数。全选只勾真正能勾的行，不能选和被禁用的行保留原来的状态。`idKey` 可以给属性名，也可以给一个从行里取键的函数。

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

## 示例

### useTableSelectionState —— 行选择

带行选择复选框和表头全选复选框的表格。选中的键和写回函数留在调用方，selectionState 把它们映射给工具栏这类关心选择状态的界面。

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

interface User extends Record<string, unknown> {
  id: string
  name: string
  email: string
  role: string
}

const users: User[] = [
  { id: '1', name: 'Alice', email: 'alice@example.com', role: 'Engineer' },
  { id: '2', name: 'Bob', email: 'bob@example.com', role: 'Designer' },
  { id: '3', name: 'Charlie', email: 'charlie@example.com', role: 'Manager' },
  { id: '4', name: 'Diana', email: 'diana@example.com', role: 'Engineer' },
  { id: '5', name: 'Eve', email: 'eve@example.com', role: 'Admin' },
]

const columns: TableColumn<User>[] = [
  { key: 'name', header: 'Name', width: proportional(1) },
  { key: 'email', header: 'Email', width: proportional(2) },
  { key: 'role', header: 'Role', width: proportional(1) },
]

const selectedKeys = ref(new Set<string>())
const { selectionConfig } = useTableSelectionState<User>({
  data: users,
  idKey: 'id',
  selectedKeys,
  setSelectedKeys(keys) {
    selectedKeys.value = keys
  },
})
const selectionPlugin = useTableSelection<User>(selectionConfig)
</script>

<template>
  <Table
    :data="users"
    :columns="columns"
    id-key="id"
    :plugins="{ selection: selectionPlugin }"
  />
</template>
```

## 属性

`data` 和 `selectedKeys` 是 `MaybeRefOrGetter`，传 ref 或 getter 才能保持实时。其它字段从你传入的配置对象上读。

全选只动真的能勾的行：`getIsItemSelectable` 或 `getIsItemEnabled` 返回 false 的行保留原来的状态，不在 `data` 里的键也照样留着。

## 参数

| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `data` | `MaybeRefOrGetter<readonly T[]>` | — | 表格里渲染的完整数据数组。 |
| `idKey` | `(keyof T & string) \| ((item: T) => string)` | — | 键提取：存放唯一字符串 ID 的属性名，或者从行里取出这个 ID 的函数。 |
| `selectedKeys` | `MaybeRefOrGetter<ReadonlySet<string>>` | — | 受控的选中 ID 集合。 |
| `setSelectedKeys` | `(keys: Set<string>) => void` | — | 选中集合的写回函数。它每次给的都是一个算好的 `Set`，你把它赋给自己的 ref 就行。原版那种同时接受 updater 的派发器（例如 React 的 `setState`）也符合这个签名，可以直接传。 |
| `getIsItemSelectable` | `(item: T) => boolean` | `() => true` | 这一行要不要显示复选框。返回 false 的行连复选框都没有，也不算进全选。 |
| `getIsItemEnabled` | `(item: T) => boolean` | `() => true` | 这一行的复选框能不能点。返回 false 时复选框还在但是禁用，而且被冻结：全选会保留它原来的状态。 |
| `getRowLabel` | `(item: T) => string` | — | 原样传给选择插件，做行复选框的标签。 |
| `hasRowHighlight` | `boolean` | `true` | 原样传给选择插件。设成 `false` 后，选中的行不再铺浅色底，`aria-selected` 仍然保留。 |

## 返回值

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `selectionConfig` | `UseTableSelectionConfig & { readonly rows: readonly T[] }` | `useTableSelection` 需要的全部内容。另外带一个 `rows` getter，能直接拿到当前数据，处理全选时不用另外传。 |
| `selectionState` | `TableSelectionState` | 给选择相关界面用的只读快照。传给 `TableSelectionToolbar` 后，一个都没选中时工具栏自动不渲染。 |
| `selectionState.selectedKeys` | `ReadonlySet<string>` | 选中的全部键，包含不在当前页上的行。 |
| `selectionState.selectedCount` | `number` | 选中了多少个键。 |
| `selectionState.hasSelection` | `boolean` | 至少选中一个键时为 true。 |
| `selectionState.clearSelection` | `() => void` | 用一个空 `Set` 调 `setSelectedKeys`。 |
