# useTableColumnSettings

## 使用方法

给 Table 做列的显示与排序，只管逻辑，不画控件。插件只留下 key 在 `activeColumnKeys` 里的列，顺序也按这个数组来，所以列选择器和表格读的是同一份列表。`useTableColumnSettingsState` 是配套的开关助手：它保存 key，被删掉的 `isAlwaysVisible` 列会被放回去，还知道「恢复默认」该恢复哪一组。

```ts
import { useTableColumnSettings, useTableColumnSettingsState } from '@astryx-vue/core/Table'
```

每次读配置都会重新取值，所以 key 存在 `ref` 里时要传 getter。直接传对象也能跑，但表格会用第一次读到的 key。

列选择器由你自己搭。`MultiSelector` 的选项是 `{ value, label, disabled }`，把每列映射成这个形状，`isAlwaysVisible` 的标成禁用即可；选项带上 `group` 就能把列分成若干组显示。

`defaultColumnKeys` 是「恢复默认」要恢复的那组列。不传就恢复成全部列。

```ts
const state = useTableColumnSettingsState({
  columns: columnOptions,
  activeColumnKeys: activeKeys,
  onChangeActiveColumnKeys(keys) {
    activeKeys.value = [...keys]
  },
  defaultColumnKeys: ['name', 'email'],
})
```

`resetToDefault()` 把 `defaultColumnKeys` 交给 `onChangeActiveColumnKeys`，`showAllColumns()` 交出去的是全部列。恢复按钮和选择器顶部的「全选」各自调它们。

`useTableColumnSettings()` 只负责藏起和重排。列本身还是全部交给表格，插件从中挑出要显示的那些。

## 示例

### Table — 列设置

工具栏里放一个列选择器的表格。可以开关列，Name 列始终保留。

```vue
<script setup lang="ts">
import type { ColumnSettingsOption, TableColumn } from '@astryx-vue/core/Table'
import { MultiSelector } from '@astryx-vue/core/MultiSelector'
import { Stack } from '@astryx-vue/core/Stack'
import { proportional, Table, useTableColumnSettings, useTableColumnSettingsState } from '@astryx-vue/core/Table'
import { Text } from '@astryx-vue/core/Text'
import { Toolbar } from '@astryx-vue/core/Toolbar'
import { ref } from 'vue'

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

const users: User[] = [
  { id: '1', name: 'Alice Johnson', email: 'alice@example.com', role: 'Engineer', department: 'Platform', status: 'Active' },
  { id: '2', name: 'Bob Smith', email: 'bob@example.com', role: 'Designer', department: 'Product', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Manager', department: 'Platform', status: 'Away' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Engineer', department: 'Infra', status: 'Active' },
  { id: '5', name: 'Eve Davis', email: 'eve@example.com', role: 'Admin', department: 'Operations', status: 'Inactive' },
]

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

const columnOptions: ColumnSettingsOption<string>[] = [
  { key: 'name', label: 'Name', isAlwaysVisible: true },
  { key: 'email', label: 'Email' },
  { key: 'role', label: 'Role' },
  { key: 'department', label: 'Department' },
  { key: 'status', label: 'Status' },
]

const activeKeys = ref(columnOptions.map(column => column.key))
const state = useTableColumnSettingsState<string>({
  columns: columnOptions,
  activeColumnKeys: activeKeys,
  onChangeActiveColumnKeys(keys) {
    activeKeys.value = [...keys]
  },
})
const plugin = useTableColumnSettings<User>(state.columnSettingsConfig)
const selectorOptions = columnOptions.map(column => ({
  value: column.key,
  label: column.label,
  disabled: column.isAlwaysVisible === true,
}))

function onColumnsChange(keys: (string | number)[]) {
  state.setActiveColumnKeys(keys.map(String))
}
</script>

<template>
  <Stack direction="vertical" :gap="3" width="100%">
    <Toolbar label="Table actions">
      <template #start>
        <Text type="label">
          Team
        </Text>
      </template>
      <template #end>
        <MultiSelector
          label="Columns"
          label-hidden
          :options="selectorOptions"
          :model-value="[...state.activeColumnKeys]"
          @update:model-value="onColumnsChange"
        />
      </template>
    </Toolbar>
    <Table
      :data="users"
      :columns="allColumns"
      id-key="id"
      has-hover
      :plugins="{ columnSettings: plugin }"
    />
  </Stack>
</template>
```

## 参数

`useTableColumnSettings()` 只接一个配置对象。key 存在 `ref` 里时用 getter 包一层，表格每次读都能拿到最新的值：`useTableColumnSettings(() => state.columnSettingsConfig)`。

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `columns` | `readonly ColumnSettingsOption[]` | — | 必填。全部可选的列，带设置界面要用的信息。每一项有 `key`、`label`，还可以有 `isAlwaysVisible` 和 `group`。 |
| `activeColumnKeys` | `readonly TColumnKey[]` | — | 必填。当前打开的列 key，按显示顺序。只有 key 在这个数组里的列会显示。 |
| `onChangeActiveColumnKeys` | `(keys: TColumnKey[]) => void` | — | 打开的列变了时调用。`useTableColumnSettings()` 自己不会调它；它属于 `useTableColumnSettingsState()` 交回来的那份配置。 |
| `defaultColumnKeys` | `readonly TColumnKey[]` | — | 「恢复默认」用的那组列。不传就恢复成全部列。 |

## 返回值

`useTableColumnSettings()` 返回一个 `TablePlugin&lt;T&gt;`，放进 `Table` 的 `plugins` 里。它填的是插件约定里的一个字段：

| 名称 | 类型 | 说明 |
| --- | --- | --- |
| `transformColumns` | `(columns: TableColumn[]) => TableColumn[]` | 丢掉 key 不在 `activeColumnKeys` 里的列，再把剩下的按这个数组的顺序排好。 |

## useTableColumnSettingsState

配套的组合式函数。它替你拿住这些 key，所有写入都走它，所以 `isAlwaysVisible` 的列不会被删掉。

```ts
const state = useTableColumnSettingsState({
  columns: columnOptions,
  activeColumnKeys: activeKeys,
  onChangeActiveColumnKeys(keys) {
    activeKeys.value = [...keys]
  },
})
const plugin = useTableColumnSettings(state.columnSettingsConfig)
```

参数和上面那份配置一样，另外多一个 `defaultColumnKeys`。

| 名称 | 类型 | 说明 |
| --- | --- | --- |
| `activeColumnKeys` | `readonly TColumnKey[]` | 你传进来的 key，每次读都重新取值。 |
| `toggleColumn` | `(key: TColumnKey) => void` | 开关一列。`isAlwaysVisible` 的 key 会被忽略。 |
| `isColumnActive` | `(key: TColumnKey) => boolean` | 这一列现在是打开的吗。用来勾选选择器里的选项。 |
| `isColumnToggleable` | `(key: TColumnKey) => boolean` | 这一列允许被关掉吗。`isAlwaysVisible` 的列是 `false`，选择器里把它标成禁用。 |
| `showAllColumns` | `() => void` | 把 `columns` 里的全部列报成打开。 |
| `resetToDefault` | `() => void` | 报出 `defaultColumnKeys`，没设就报出全部列。「恢复默认」按钮调它。 |
| `setActiveColumnKeys` | `(keys: readonly TColumnKey[]) => void` | 把给的 key 补上所有 `isAlwaysVisible` 的 key 再报出去，然后调 `onChangeActiveColumnKeys`。 |
| `columnSettingsConfig` | `UseTableColumnSettingsConfig` | 给 `useTableColumnSettings()` 用的配置，写入接到 `setActiveColumnKeys`，并带上 `defaultColumnKeys`。 |

### ColumnSettingsOption

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `key` | `TColumnKey` | — | 列的 key，必须和某个 `TableColumn.key` 一致。 |
| `label` | `string` | — | 设置界面里显示的名字。 |
| `isAlwaysVisible` | `boolean` | `false` | 这一列不能被隐藏。用在 Name、ID 这种必须留着的列上。 |
| `group` | `string` | — | 分组名。同组的列在设置列表里排在一起，可以带个小标题。 |
