# PinnedColumnsPlugin

> _Since v0.1.1_

Pinned Columns Plugin for tbw-grid

Freezes columns to the left or right edge of the grid—essential for keeping key
identifiers or action buttons visible while scrolling through wide datasets. Just set
`pinned: 'left'` or `pinned: 'right'` on your column definitions.

## Installation

```ts
import { PinnedColumnsPlugin } from '@toolbox-web/grid/plugins/pinned-columns';
```

## Column Configuration

| Property | Type | Description |
|----------|------|-------------|
| `pinned` | `'left' \| 'right' \| 'start' \| 'end'` | Pin column to edge (logical or physical) |
| `lockPinning` | `boolean` | `false` | Prevent user from pin/unpin via context menu (legacy `meta.lockPinning` is honored) |

### RTL Support

Use logical values (`start`/`end`) for grids that work in both LTR and RTL layouts:
- `'start'` - Pins to left in LTR, right in RTL
- `'end'` - Pins to right in LTR, left in RTL

## CSS Custom Properties

| Property | Default | Description |
|----------|---------|-------------|
| `--tbw-pinned-shadow` | `4px 0 8px rgba(0,0,0,0.1)` | Shadow on pinned column edge |
| `--tbw-pinned-border` | `var(--tbw-color-border)` | Border between pinned and scrollable |

## Examples

### Pin ID Left and Actions Right

```ts
import { queryGrid } from '@toolbox-web/grid';
import { PinnedColumnsPlugin } from '@toolbox-web/grid/plugins/pinned-columns';

const grid = queryGrid('tbw-grid');
grid.gridConfig = {
  columns: [
    { field: 'id', header: 'ID', pinned: 'left', width: 80 },
    { field: 'name', header: 'Name' },
    { field: 'email', header: 'Email' },
    { field: 'department', header: 'Department' },
    { field: 'actions', header: 'Actions', pinned: 'right', width: 120 },
  ],
  plugins: [new PinnedColumnsPlugin()],
};
```

### RTL-Compatible Pinning

```ts
// Same config works in LTR and RTL
grid.gridConfig = {
  columns: [
    { field: 'id', header: 'ID', pinned: 'start' },  // Left in LTR, Right in RTL
    { field: 'name', header: 'Name' },
    { field: 'actions', header: 'Actions', pinned: 'end' },  // Right in LTR, Left in RTL
  ],
  plugins: [new PinnedColumnsPlugin()],
};
```

## See Also

- [`PinnedColumnsConfig`](/grid/plugins/pinned-columns/interfaces/pinnedcolumnsconfig.md) for configuration options

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

## Methods

### detect()

Auto-detect sticky columns from column configuration.

```ts
static detect(rows: readonly unknown[], config: object): boolean
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `rows` | <code>readonly unknown[]</code> |  |
| `config` | <code>object</code> |  |

***

### setPinPosition()

Set the pin position for a column.
Updates the column's `pinned` property and triggers a full re-render.

```ts
setPinPosition(field: string, position: PinnedPosition | undefined): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `field` | <code>string</code> | The field name of the column to pin/unpin |
| `position` | <code><a href="/grid/plugins/pinned-columns/types/pinnedposition/">PinnedPosition</a> &#124; undefined</code> | The pin position (`'left'`, `'right'`, `'start'`, `'end'`), or `undefined` to unpin |

***

### refreshStickyOffsets()

Re-apply sticky offsets (e.g., after column resize).

```ts
refreshStickyOffsets(): void
```

***

### getLeftPinnedColumns()

Get columns pinned to the left (after resolving logical positions for current direction).

```ts
getLeftPinnedColumns(): ColumnConfig<any>[]
```

***

### getRightPinnedColumns()

Get columns pinned to the right (after resolving logical positions for current direction).

```ts
getRightPinnedColumns(): ColumnConfig<any>[]
```

***

### clearStickyPositions()

Clear all sticky positioning.

```ts
clearStickyPositions(): void
```

***
