# useTableSelectionState

## Usage

State management companion for `useTableSelection`. Returns `selectionConfig` for the behaviour plugin plus `selectionState` for selection-aware UI such as `TableSelectionToolbar`. The selection itself stays controlled: you own the `Set` of selected keys and pass a setter. Select-all only takes the rows that can be checked, so rows that are not selectable or are disabled keep whatever state they had. `idKey` takes a property name or a function that returns the key.

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

## Examples

### useTableSelectionState — Row Selection

Table with row selection checkboxes and a select-all header checkbox. The checked keys and the setter stay in the caller, and selectionState mirrors them for selection-aware UI such as a toolbar.

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

## Properties

`data` and `selectedKeys` are `MaybeRefOrGetter`, so a ref or a getter keeps the state live. The other fields are read from the config object you pass.

Select-all only touches rows that can actually be checked: rows where `getIsItemSelectable` or `getIsItemEnabled` is false keep whatever selection they already had, and a key that is not in `data` stays selected too.

## Parameters

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | `MaybeRefOrGetter<readonly T[]>` | — | The full data array rendered in the table. |
| `idKey` | `(keyof T & string) \| ((item: T) => string)` | — | Key extractor: either the property name that holds a unique string ID, or a function that returns it. |
| `selectedKeys` | `MaybeRefOrGetter<ReadonlySet<string>>` | — | Controlled set of selected item IDs. |
| `setSelectedKeys` | `(keys: Set<string>) => void` | — | Setter for the controlled selected keys. It is always handed a ready-made `Set`; assign it to your own ref. A dispatcher that also accepts updater functions, such as React's `setState`, fits the same signature. |
| `getIsItemSelectable` | `(item: T) => boolean` | `() => true` | Should this row show a checkbox? Non-selectable rows render nothing in the selection cell and are excluded from select-all. |
| `getIsItemEnabled` | `(item: T) => boolean` | `() => true` | Is this row checkbox interactive? Disabled rows keep their checkbox, rendered disabled, and are frozen: select-all preserves their state. |
| `getRowLabel` | `(item: T) => string` | — | Passed through to the selection plugin as the row checkbox label. |
| `hasRowHighlight` | `boolean` | `true` | Passed through to the selection plugin. `false` drops the accent wash on checked rows and keeps `aria-selected`. |

## Returns

| Field | Type | Description |
| --- | --- | --- |
| `selectionConfig` | `UseTableSelectionConfig & { readonly rows: readonly T[] }` | Everything `useTableSelection` needs. It also carries a `rows` getter with the current data, so a select-all handler that wants the rows can read them from the config. |
| `selectionState` | `TableSelectionState` | Read-only snapshot for selection-aware UI. Pass it to `TableSelectionToolbar` and the toolbar hides itself while nothing is selected. |
| `selectionState.selectedKeys` | `ReadonlySet<string>` | Every selected key, including rows that are not on the current page. |
| `selectionState.selectedCount` | `number` | How many keys are selected. |
| `selectionState.hasSelection` | `boolean` | True when at least one key is selected. |
| `selectionState.clearSelection` | `() => void` | Calls `setSelectedKeys` with an empty `Set`. |
