# SelectionModel

> Selection state for list-shaped widgets: a set of selected keys plus the toggle, contiguous-range, and select-all semantics behind row selection.

```ts
import { SelectionModel } from "@sdxc/ui/behaviors";
```

State model for list, grid, tree, and table row selection. Every mutating
method dispatches a plain `"change"` event exactly once, and only when the
selected-key set really changes, so a subscriber can re-render blindly.

## Signature

```ts
new SelectionModel(options?: SelectionModel.Options)
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `options?` | `SelectionModel.Options` | Initial mode, known key order, disabled keys, and pre-selected keys. All are optional and default to an empty, `"multiple"`-mode model with no known keys. |

## Properties

| Property | Type | Description |
| --- | --- | --- |
| `mode` | `SelectionModel.Mode` | Current selection cardinality. |
| `keys` | `readonly SelectionModel.Key[]` | Known selectable keys, in the order last provided to the constructor or setKeys. |
| `selectedKeys` | `ReadonlySet<SelectionModel.Key>` | Currently selected keys. |
| `disabledKeys` | `ReadonlySet<SelectionModel.Key>` | Keys excluded from selection. |
| `anchorKey` | `SelectionModel.Key \| null` | Key that anchors the next selectRange call, or `null` before any point interaction. |
| `size` | `number` | Number of currently selected keys. |
| `isEmpty` | `boolean` | `true` when no key is selected. |
| `isAll` | `boolean` | `true` when every non-disabled key in keys is selected. Always `false` when keys is empty, since there is nothing to select. |

## Methods

| Method | Description |
| --- | --- |
| `setMode(mode: SelectionModel.Mode): void` | Replaces the selection mode. The current selection clamps to it (`"none"` empties it, `"single"` keeps at most the first selected key), dispatching `"change"` when that clamp shrinks the selected-key set. |
| `setKeys(keys: Iterable<SelectionModel.Key>): void` | Replaces the known universe of selectable keys, in order. Selected and anchor keys no longer present in `keys` are dropped, so removing a rendered row also removes it from the selection. |
| `setDisabledKeys(keys: Iterable<SelectionModel.Key>): void` | Replaces the set of keys excluded from selection. Any of those keys currently selected are dropped from the selection. |
| `isSelected(key: SelectionModel.Key): boolean` | Reports whether `key` is currently selected. |
| `isDisabled(key: SelectionModel.Key): boolean` | Reports whether `key` is excluded from selection. |
| `select(key: SelectionModel.Key): void` | Selects `key`, replacing the selection in `"single"` mode or adding to it in `"multiple"` mode. No-op for a disabled key or in `"none"` mode. Sets anchorKey to `key` on success. |
| `deselect(key: SelectionModel.Key): void` | Removes `key` from the selection, regardless of mode. Sets anchorKey to `key` when it was selected; no-op otherwise. |
| `toggle(key: SelectionModel.Key): void` | Flips whether `key` is selected, replacing the selection in `"single"` mode and staying a no-op for a disabled key or in `"none"` mode. Sets anchorKey on success; a plain click maps to this operation. |
| `selectRange(key: SelectionModel.Key): void` | Selects the contiguous span between anchorKey and `key` in keys order, skipping disabled keys; the anchor stays put so repeated shift-clicks re-span. Anchorless calls run toggle. |
| `selectAll(): void` | Selects every non-disabled key in keys. No-op outside `"multiple"` mode or when keys is empty. |
| `clear(): void` | Deselects every key, regardless of mode. |

## Used with it

The events, constants and types its module publishes, each imported from `@sdxc/ui/behaviors` too.

### SelectionModel.Options

Constructor options for SelectionModel.

#### Members

| Member | Type | Description |
| --- | --- | --- |
| `mode?` | `Mode` | Selection cardinality; defaults to `"multiple"`. |
| `keys?` | `Iterable<Key>` | Ordered universe of selectable keys, backing SelectionModel.selectRange spans and the full set for SelectionModel.selectAll. Point selection works without it. |
| `disabledKeys?` | `Iterable<Key>` | Keys excluded from selection; any of them present in `selectedKeys` are dropped. |
| `selectedKeys?` | `Iterable<Key>` | Keys selected on construction, clamped to `mode` and `disabledKeys`. |

### SelectionModel.Key

Identifier for a selectable item. Row/item identity is left to the
consumer — a string slug and a numeric row id are both valid keys.

#### Signature

```ts
type SelectionModel.Key = string | number
```

### SelectionModel.Mode

Selection cardinality a model enforces: `"none"` accepts no selection
at all, `"single"` keeps at most one selected key, and `"multiple"`
allows any subset of the known keys.

#### Signature

```ts
type SelectionModel.Mode = "none" | "single" | "multiple"
```

One of `"none"`, `"single"`, `"multiple"`.
