# useTableSelection

## 使用方法

返回一个 `TablePlugin`，实现行选择：复选框列、全选，以及 `aria-selected`。复选框列由表格自己加，不用你在 `columns` 里写。选择状态是从你给的 getter 里现读的，这些 getter 读到哪个响应式状态，复选框就跟着哪个状态走，不需要再套一层 provider。

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

两个 getter 决定一行长什么样。`getIsItemSelectable` 让没什么可选的行连复选框都不显示；`getIsItemEnabled` 保留复选框但把它禁用，用在「这一行现在不能选」的场合。

```ts
const selection = useTableSelection({
  getIsItemSelected: item => selectedKeys.value.has(item.id),
  onSelectItem: ({ item, isSelected }) => { /* ... */ },
  onSelectAll: ({ isAllSelected }) => { /* ... */ },
  getIsAllSelected: () => /* ... */ false,
  getIsItemSelectable: item => item.role !== 'System',
  getIsItemEnabled: item => item.status !== 'Locked',
})
```

`hasRowHighlight` 只管选中行上那层浅色底。`aria-selected` 无论如何都写在选中的行上，所以就算周围界面已经用行底色表达别的意思，选中状态照样念得出来。

## 示例

### useTableSelection —— 行选择

带行选择复选框和表头全选复选框的表格。

```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>
```

## 属性

配置对象是 `MaybeRefOrGetter`：传一个 getter 或 ref，插件才会跟着最新值走。

## 参数

| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `getIsItemSelected` | `(item: T) => boolean` | — | 这一行现在是否被选中。 |
| `onSelectItem` | `(event: { item: T; isSelected: boolean }) => void` | — | 行的复选框被切换时调用。`isSelected` 是切换后的目标状态。 |
| `onSelectAll` | `(event: { isAllSelected: boolean }) => void` | — | 表头的全选复选框被切换时调用。 |
| `getIsAllSelected` | `() => boolean` | — | 所有可选行现在是否都被选中。 |
| `getIsIndeterminate` | `() => boolean` | `() => false` | 是否只选中了一部分（有选中的，也有没选的）。全选复选框会显示成半选状态。 |
| `getIsItemSelectable` | `(item: T) => boolean` | `() => true` | 这一行要不要显示复选框。返回 false 的行，选择那一格是空的。 |
| `getIsItemEnabled` | `(item: T) => boolean` | `() => true` | 这一行的复选框能不能点。返回 false 时复选框还在，但是禁用状态，选择列不会因此错位。 |
| `getRowLabel` | `(item: T) => string` | — | 给出一行的人话名字，复选框的隐藏标签会变成「选择 `getRowLabel(item)`」，读屏软件才知道这个复选框选的是哪一行。不传时用内置的「选择行」。 |
| `hasRowHighlight` | `boolean` | `true` | 给选中的行铺一层浅色底。如果周围的界面已经用行底色表达别的意思（比如这一行正在详情面板里打开），就设成 false。关掉的只是底色，`aria-selected` 照旧写在选中的行上，读屏仍然念得出这一行被选中了。 |

## 返回值

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `selection` | `TableSelectionContribution` | 表格读取的那部分贡献。把整个插件塞进 `plugins` 的任意一个键里，表格会自己挑出带 `selection` 的那一个。 |
| `selection.isAllSelected` | `() => boolean` | 转调 `getIsAllSelected`。 |
| `selection.isIndeterminate` | `() => boolean` | 转调 `getIsIndeterminate`；没传时返回 `false`。 |
| `selection.isSelected` | `(row: T) => boolean` | 转调 `getIsItemSelected`。 |
| `selection.isSelectable` | `(row: T) => boolean` | 转调 `getIsItemSelectable`；没传时返回 `true`。 |
| `selection.isEnabled` | `(row: T) => boolean` | 转调 `getIsItemEnabled`；没传时返回 `true`。 |
| `selection.selectAll` | `(selected: boolean) => void` | 用 `{ isAllSelected: selected }` 调 `onSelectAll`。 |
| `selection.selectRow` | `(row: T, selected: boolean) => void` | 用 `{ item: row, isSelected: selected }` 调 `onSelectItem`。 |
| `selection.rowLabel` | `(row: T) => string` | 转调 `getRowLabel`；没传时返回空字符串。 |
| `selection.hasRowHighlight` | `boolean \| undefined` | 配置里的原值。只要不是 `false`，底色就照旧铺。 |
