# SelectionPlugin

> _Since v0.1.1_

Selection Plugin for tbw-grid

Adds cell, row, and range selection capabilities to the grid with full keyboard support.
Whether you need simple cell highlighting or complex multi-range selections, this plugin has you covered.

## Installation

```ts
import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
```

## Selection Modes

Configure the plugin with one of three modes via [`SelectionConfig`](/grid/plugins/selection/interfaces/selectionconfig.md):

- **`'cell'`** - Single cell selection (default). Click cells to select individually.
- **`'row'`** - Full row selection. Click anywhere in a row to select the entire row.
- **`'range'`** - Rectangular selection. Click and drag or Shift+Click to select ranges.

## Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Arrow Keys` | Move selection |
| `Shift + Arrow` | Extend selection (range mode) |
| `Ctrl/Cmd + Click` | Toggle selection (multi-select) |
| `Shift + Click` | Extend to clicked cell/row |
| `Ctrl/Cmd + A` | Select all (range mode) |
| `Escape` | Clear selection |

&gt; **Note:** When `multiSelect: false`, Ctrl/Shift modifiers are ignored —
&gt; clicks always select a single item.

## CSS Custom Properties

| Property | Description |
|----------|-------------|
| `--tbw-focus-background` | Focused row background |
| `--tbw-range-selection-bg` | Range selection fill |
| `--tbw-range-border-color` | Range selection border |

## [Configuration Options](/grid/plugins/selection/interfaces/selectionconfig.md)

| Option | Type | Description |
| ------ | ---- | ----------- |
| `mode` | <code><a href="/grid/plugins/selection/types/selectionmode/">SelectionMode</a> &#124; <a href="/grid/plugins/selection/types/selectionmode/">SelectionMode</a>[]</code> | Selection mode (default: `'cell'`). |
| `multiSelect?` | <code>boolean</code> | Allow multiple items to be selected simultaneously (default: true). |
| `enabled?` | <code>boolean</code> | Whether selection is enabled (default: true). |
| `triggerOn?` | <code><a href="/grid/plugins/selection/types/selectiontrigger/">SelectionTrigger</a></code> | Mouse event type that triggers selection (default: 'click'). |
| `checkbox?` | <code>boolean</code> | Show a checkbox column for row selection (row mode only). |
| `isSelectable?` | <code><a href="/grid/plugins/selection/types/selectablecallback/">SelectableCallback</a>&lt;T&gt;</code> | Callback that determines whether a specific row or cell can be selected. |

## Examples

### Basic row selection

```ts
grid.gridConfig = {
  columns: [...],
  plugins: [new SelectionPlugin({ mode: 'row' })],
};
```

### Range selection with event handling

```ts
grid.gridConfig = {
  plugins: [new SelectionPlugin({ mode: 'range' })],
};

grid.on('selection-change', ({ mode, ranges }) => {
  console.log(`Selected ${ranges.length} ranges in ${mode} mode`);
});
```

### Programmatic selection control

```ts
const plugin = grid.getPluginByName('selection');

// Get current selection
const selection = plugin.getSelection();
console.log(selection.ranges);

// Set selection programmatically
plugin.setRanges([{ from: { row: 0, col: 0 }, to: { row: 5, col: 3 } }]);

// Clear all selection
plugin.clearSelection();
```

## See Also

- [`SelectionMode`](/grid/plugins/selection/types/selectionmode.md) for detailed mode descriptions
- [`SelectionConfig`](/grid/plugins/selection/interfaces/selectionconfig.md) for configuration options
- [`SelectionResult`](/grid/plugins/selection/interfaces/selectionresult.md) for the selection result structure
- [`SelectionConfig`](/grid/plugins/selection/interfaces/selectionconfig.md) for interactive examples in the docs site

> **Extends** [BaseGridPlugin](/docs/grid-api-plugin-development-classes-basegridplugin--docs)
>
> Inherited methods like `attach()`, `detach()`, `afterRender()`, etc. are documented in the base class.

## Methods

### getSelection()

Get the current selection as a unified result.
Works for all selection modes and always returns ranges.

```ts
getSelection(): SelectionResult
```

#### Example

```ts
const selection = plugin.getSelection();
if (selection.ranges.length > 0) {
  const { from, to } = selection.ranges[0];
  // For cell mode: from === to (single cell)
  // For row mode: from.col = 0, to.col = lastCol (full row)
  // For range mode: rectangular selection
}
```

***

### getSelectedCells()

Get all selected cells across all ranges.

```ts
getSelectedCells(): object[]
```

***

### isCellSelected()

Check if a specific cell is in range selection.

```ts
isCellSelected(row: number, col: number): boolean
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `row` | <code>number</code> |  |
| `col` | <code>number</code> |  |

***

### selectAll()

Select all selectable rows (row mode) or all cells (range mode).

In row mode, selects every row where `isSelectable` returns true (or all rows if no callback).
In range mode, creates a single range spanning all rows and columns.
Has no effect in cell mode.

```ts
selectAll(): void
```

#### Example

```ts
const plugin = grid.getPluginByName('selection');
plugin.selectAll(); // Selects everything in current mode
```

***

### selectRows()

Select specific rows by index (row mode only).
Replaces the current selection with the provided row indices.
Indices that are out of bounds or fail the `isSelectable` check are ignored.

```ts
selectRows(indices: number[]): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `indices` | <code>number[]</code> | Array of row indices to select |

#### Example

```ts
const plugin = grid.getPluginByName('selection');
plugin.selectRows([0, 2, 4]); // Select rows 0, 2, and 4
```

***

### getSelectedRowIndices()

Get the indices of all selected rows (convenience for row mode).
Returns indices sorted in ascending order.

```ts
getSelectedRowIndices(): number[]
```

#### Example

```ts
const plugin = grid.getPluginByName('selection');
const rows = plugin.getSelectedRowIndices(); // [0, 2, 4]
```

***

### getSelectedRows()

Get the actual row objects for the current selection.

Works across all selection modes:
- **Row mode**: Returns the row objects for all selected rows.
- **Cell mode**: Returns the single row containing the selected cell, or `[]`.
- **Range mode**: Returns the unique row objects that intersect any selected range.

Row objects are resolved from the grid's processed (sorted/filtered) row array,
so they always reflect the current visual order.

```ts
getSelectedRows(): T[]
```

#### Example

```ts
const plugin = grid.getPluginByName('selection');
const selected = plugin.getSelectedRows(); // [{ id: 1, name: 'Alice' }, ...]
```

***

### selectColumn() <span class="since-badge" title="Introduced in v2.8.0">v2.8.0+</span>

Toggle, add, or replace a column in the column-axis selection.

Column selection is identified by **field name**, so it survives column
pinning, reordering, and virtualization recycling. The column must be
present in the grid's visible columns and must not be a utility column.

Only available when `mode` includes `'column'`. With `multiSelect: false`,
`range`/`toggle` options are ignored and the call always replaces the
current selection with the single column.

```ts
selectColumn(field: string, options: object): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `field` | <code>string</code> | The column field name to select. |
| `options` | <code>object</code> |  |

***

### deselectColumn() <span class="since-badge" title="Introduced in v2.8.0">v2.8.0+</span>

Remove a column from the column-axis selection. No-op if `field` isn't selected.

```ts
deselectColumn(field: string): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `field` | <code>string</code> |  |

***

### selectAllColumns() <span class="since-badge" title="Introduced in v2.8.0">v2.8.0+</span>

Select every selectable column. No-op when `multiSelect: false` or column
mode isn't enabled.

```ts
selectAllColumns(): void
```

***

### clearColumnSelection() <span class="since-badge" title="Introduced in v2.8.0">v2.8.0+</span>

Clear column-axis selection only. Leaves any row/cell/range selection intact.

```ts
clearColumnSelection(): void
```

***

### getSelectedColumns() <span class="since-badge" title="Introduced in v2.8.0">v2.8.0+</span>

Get the field names of all currently selected columns, in visible-column
order. Returns an empty array when the column axis is inactive or empty.

```ts
getSelectedColumns(): readonly string[]
```

***

### clearSelection()

Clear all selection (every axis).

```ts
clearSelection(): void
```

***

### setRanges()

Set selected ranges programmatically.

```ts
setRanges(ranges: CellRange[]): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `ranges` | <code><a href="/grid/plugins/selection/interfaces/cellrange/">CellRange</a>[]</code> |  |

***
