# Grid

> _Since v0.1.0_

Directive that automatically registers the Angular adapter with tbw-grid elements.

This directive eliminates the need to manually register the adapter in your component
constructor. Simply import this directive and it will handle adapter registration.

## Usage

```typescript
import { Component } from '@angular/core';
import { Grid } from '@toolbox-web/grid-angular';

@Component({
  selector: 'app-root',
  imports: [Grid],
  template: `
    <tbw-grid [rows]="rows" [gridConfig]="config" [customStyles]="myStyles">
      <!-- column templates -->
    </tbw-grid>
  `
})
export class AppComponent {
  rows = [...];
  config = {...};
  myStyles = `.my-class { color: red; }`;
}
```

The directive automatically:
- Creates a GridAdapter instance
- Registers it with the GridElement
- Injects custom styles into the grid
- Handles cleanup on destruction

## Multi-version coexistence

In single-version apps the directive matches the bare `<tbw-grid>` tag. When
two different grid versions share a page, the second-loaded bundle registers
under a version-suffixed tag (e.g. `<tbw-grid-v2-15-0>`). Because Angular
matches selectors at compile time, a runtime-only tag cannot be matched by
tag name. The directive therefore also matches the stable `[data-tbw-grid]`
attribute, so a suffixed grid can opt in by adding it literally:

```html
<tbw-grid-v2-15-0 data-tbw-grid [rows]="rows" [gridConfig]="config"></tbw-grid-v2-15-0>
```

Read the concrete tag from `DataGridElement.activeTag` of the bundle you
imported. See the multi-version coexistence guide.

## Properties

| Property | Type | Description |
| -------- | ---- | ----------- |
| `customStyles` | <code>InputSignal&lt;string &#124; undefined&gt;</code> | Custom CSS styles to inject into the grid. Use this to style custom cell renderers, editors, or detail panels. |
| `sortable` | <code>InputSignal&lt;boolean &#124; undefined&gt;</code> | Grid-wide sorting toggle. When false, disables sorting for all columns regardless of their individual `sortable` setting. When true (default), columns with `sortable: true` can be sorted. |
| `filterable` | <code>InputSignal&lt;boolean &#124; undefined&gt;</code> | Grid-wide filtering toggle. When false, disables filtering for all columns regardless of their individual `filterable` setting. When true (default), columns with `filterable: true` can be filtered. |
| `selectable` | <code>InputSignal&lt;boolean &#124; undefined&gt;</code> | Grid-wide selection toggle. When false, disables selection for all rows/cells. When true (default), selection is enabled based on plugin mode. |
| `loading` | <code>InputSignal&lt;boolean &#124; undefined&gt;</code> | Show a loading overlay on the grid. Use this during initial data fetch or refresh operations. |
| `rows` | <code>InputSignal&lt;any[] &#124; undefined&gt;</code> | The data rows to display in the grid. |
| `columns` | <code>InputSignal&lt;<a href="/grid/angular/api/types/columnshorthand/">ColumnShorthand</a>&lt;any&gt;[] &#124; undefined&gt;</code> | Column configuration array. |
| `columnDefaults` | <code>InputSignal&lt;Partial&lt;<a href="/grid/angular/api/types/columnconfig/">ColumnConfig</a>&lt;any&gt;&gt; &#124; undefined&gt;</code> | Default column properties applied to every column in `columns`. Individual column properties override these defaults. |
| `fitMode` | <code>InputSignal&lt;<a href="/grid/api/core/types/fitmode/">FitMode</a> &#124; undefined&gt;</code> | Column sizing strategy. |
| `columnInference` | <code>InputSignal&lt;<a href="/grid/api/core/types/columninferencemode/">ColumnInferenceMode</a> &#124; undefined&gt;</code> | How automatic column inference combines with explicitly provided columns. |
| `gridConfig` | <code>InputSignal&lt;<a href="/grid/angular/api/types/gridconfig/">GridConfig</a>&lt;any&gt; &#124; undefined&gt;</code> | Grid configuration object with optional Angular-specific extensions. |
| `selection` | <code>InputSignal&lt;row &#124; <a href="/grid/plugins/selection/interfaces/selectionconfig/">SelectionConfig</a>&lt;any&gt; &#124; cell &#124; range &#124; undefined&gt;</code> | Enable cell/row/range selection. |
| `editing` | <code>InputSignal&lt;boolean &#124; click &#124; dblclick &#124; manual &#124; <a href="/grid/plugins/editing/interfaces/editingconfig/">EditingConfig</a> &#124; undefined&gt;</code> | Enable inline cell editing. |
| `clipboard` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/clipboard/interfaces/clipboardconfig/">ClipboardConfig</a> &#124; undefined&gt;</code> | Enable clipboard copy/paste. Requires selection to be enabled. |
| `contextMenu` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/context-menu/interfaces/contextmenuconfig/">ContextMenuConfig</a> &#124; undefined&gt;</code> | Enable right-click context menu. |
| `multiSort` | <code>InputSignal&lt;boolean &#124; multi &#124; <a href="/grid/plugins/multi-sort/interfaces/multisortconfig/">MultiSortConfig</a> &#124; single &#124; undefined&gt;</code> | Enable multi-column sorting. |
| `filtering` | <code>InputSignal&lt;boolean &#124; <a href="/grid/angular/api/types/filterconfig/">FilterConfig</a>&lt;any&gt; &#124; undefined&gt;</code> | Enable column filtering. |
| `reorderColumns` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/reorder-columns/interfaces/reorderconfig/">ReorderConfig</a> &#124; undefined&gt;</code> | Enable column drag-to-reorder. |
| `visibility` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/visibility/interfaces/visibilityconfig/">VisibilityConfig</a> &#124; undefined&gt;</code> | Enable column visibility toggle panel. |
| `pinnedColumns` | <code>InputSignal&lt;boolean &#124; undefined&gt;</code> | Enable pinned/sticky columns. Columns are pinned via the `sticky` column property. |
| `groupingColumns` | <code>InputSignal&lt;boolean &#124; <a href="/grid/angular/api/types/groupingcolumnsconfig/">GroupingColumnsConfig</a> &#124; undefined&gt;</code> | Enable multi-level column headers (column groups). |
| `columnVirtualization` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/column-virtualization/interfaces/columnvirtualizationconfig/">ColumnVirtualizationConfig</a> &#124; undefined&gt;</code> | Enable horizontal column virtualization for wide grids. |
| `reorderRows` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/reorder-rows/types/rowreorderconfig/">RowReorderConfig</a> &#124; undefined&gt;</code> | Enable row drag-to-reorder. |
| `rowDragDrop` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/row-drag-drop/interfaces/rowdragdropconfig/">RowDragDropConfig</a>&lt;any&gt; &#124; undefined&gt;</code> | Enable row drag-and-drop within and across grids. |
| `groupingRows` | <code>InputSignal&lt;<a href="/grid/angular/api/types/groupingrowsconfig/">GroupingRowsConfig</a> &#124; undefined&gt;</code> | Enable row grouping by field values. |
| `pinnedRows` | <code>InputSignal&lt;boolean &#124; <a href="/grid/angular/api/types/pinnedrowsconfig/">PinnedRowsConfig</a> &#124; undefined&gt;</code> | Enable pinned rows (aggregation/status bar). |
| `tree` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/tree/interfaces/treeconfig/">TreeConfig</a> &#124; undefined&gt;</code> | Enable hierarchical tree view. |
| `masterDetail` | <code>InputSignal&lt;<a href="/grid/angular/api/types/masterdetailconfig/">MasterDetailConfig</a> &#124; undefined&gt;</code> | Enable master-detail expandable rows. |
| `responsive` | <code>InputSignal&lt;boolean &#124; <a href="/grid/angular/api/types/responsivepluginconfig/">ResponsivePluginConfig</a>&lt;unknown&gt; &#124; undefined&gt;</code> | Enable responsive card layout for narrow viewports. |
| `undoRedo` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/undo-redo/interfaces/undoredoconfig/">UndoRedoConfig</a> &#124; undefined&gt;</code> | Enable undo/redo for cell edits. Requires editing to be enabled. |
| `exportFeature` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/export/interfaces/exportconfig/">ExportConfig</a> &#124; undefined&gt;</code> | Enable CSV/JSON export functionality. |
| `print` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/print/interfaces/printconfig/">PrintConfig</a> &#124; undefined&gt;</code> | Enable print functionality. |
| `pivot` | <code>InputSignal&lt;<a href="/grid/plugins/pivot/interfaces/pivotconfig/">PivotConfig</a> &#124; undefined&gt;</code> | Enable pivot table functionality. |
| `serverSide` | <code>InputSignal&lt;<a href="/grid/plugins/server-side/interfaces/serversideconfig/">ServerSideConfig</a> &#124; undefined&gt;</code> | Enable server-side data operations. |
| `tooltip` | <code>InputSignal&lt;boolean &#124; <a href="/grid/plugins/tooltip/interfaces/tooltipconfig/">TooltipConfig</a> &#124; undefined&gt;</code> | Controls the tooltip behavior for the grid. |
| `cellClick` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/cellclickdetail/">CellClickDetail</a>&lt;any&gt;&gt;</code> | Emitted when a cell is clicked. |
| `rowClick` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/rowclickdetail/">RowClickDetail</a>&lt;any&gt;&gt;</code> | Emitted when a row is clicked. |
| `cellActivate` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/cellactivatedetail/">CellActivateDetail</a>&lt;any&gt;&gt;</code> | Emitted when a cell is activated (Enter key or double-click). |
| `cellChange` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/cellchangedetail/">CellChangeDetail</a>&lt;any&gt;&gt;</code> | Emitted when a cell value changes (before commit). |
| `cellCommit` | <code>OutputEmitterRef&lt;<a href="/grid/angular/api/types/cellcommitevent/">CellCommitEvent</a>&lt;unknown, unknown&gt;&gt;</code> | Emitted when a cell value is committed (inline editing). Provides the row, field, new value, and change tracking information. |
| `cellCancel` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/cellcanceldetail/">CellCancelDetail</a>&gt;</code> | Emitted when a cell edit is cancelled (Escape, click outside without commit, or `editor.cancel()`). |
| `editOpen` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/editopendetail/">EditOpenDetail</a>&lt;any&gt;&gt;</code> | Emitted when a cell editor opens. |
| `beforeEditClose` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/beforeeditclosedetail/">BeforeEditCloseDetail</a>&lt;any&gt;&gt;</code> | Emitted before an editor closes. Useful for last-chance validation. |
| `editClose` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/editclosedetail/">EditCloseDetail</a>&lt;any&gt;&gt;</code> | Emitted after an editor closes (whether committed or cancelled). |
| `dirtyChange` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/dirtychangedetail/">DirtyChangeDetail</a>&lt;any&gt;&gt;</code> | Emitted when the dirty / changed-rows state transitions. |
| `dataChange` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/datachangedetail/">DataChangeDetail</a>&gt;</code> | Emitted when row data is replaced (e.g. via the `rows` setter). |
| `rowCommit` | <code>OutputEmitterRef&lt;<a href="/grid/angular/api/types/rowcommitevent/">RowCommitEvent</a>&lt;unknown&gt;&gt;</code> | Emitted when a row's values are committed (bulk/row editing). Provides the row data and change tracking information. |
| `changedRowsReset` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/editing/interfaces/changedrowsresetdetail/">ChangedRowsResetDetail</a>&lt;unknown&gt;&gt;</code> | Emitted when the changed rows are reset. |
| `sortChange` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/sortchangedetail/">SortChangeDetail</a>&gt;</code> | Emitted when sort state changes. |
| `filterChange` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/filtering/interfaces/filterchangedetail/">FilterChangeDetail</a>&gt;</code> | Emitted when filter values change. |
| `columnResize` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/columnresizedetail/">ColumnResizeDetail</a>&gt;</code> | Emitted when a column is resized. |
| `columnResizeReset` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/columnresizeresetdetail/">ColumnResizeResetDetail</a>&gt;</code> | Emitted when a column's width is reset (double-click on the resize handle). |
| `columnMove` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/reorder-columns/interfaces/columnmovedetail/">ColumnMoveDetail</a>&gt;</code> | Emitted when a column is moved via drag-and-drop. |
| `columnVisibility` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/visibility/interfaces/columnvisibilitydetail/">ColumnVisibilityDetail</a>&gt;</code> | Emitted when a column is shown or hidden — either via the visibility sidebar, `grid.toggleColumnVisibility(field)`, `grid.setColumnVisible(field, visible)`, or `grid.showAllColumns()`. |
| `columnStateChange` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/gridcolumnstate/">GridColumnState</a>&gt;</code> | Emitted when column state changes (resize, reorder, visibility). |
| `selectionChange` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/selection/interfaces/selectionchangedetail/">SelectionChangeDetail</a>&gt;</code> | Emitted when selection changes. |
| `rowMove` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/row-drag-drop/interfaces/rowmovedetail/">RowMoveDetail</a>&lt;any&gt;&gt;</code> | Emitted when a row is moved via drag-and-drop. |
| `rowDragStart` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/row-drag-drop/interfaces/rowdragstartdetail/">RowDragStartDetail</a>&lt;any&gt;&gt;</code> | Emitted when a row drag starts. Cancelable via `event.preventDefault()`. |
| `rowDragEnd` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/row-drag-drop/interfaces/rowdragenddetail/">RowDragEndDetail</a>&lt;any&gt;&gt;</code> | Emitted when a row drag ends (after drop or cancel). |
| `rowDrop` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/row-drag-drop/interfaces/rowdropdetail/">RowDropDetail</a>&lt;any&gt;&gt;</code> | Emitted on the target grid when rows are dropped from another grid. Cancelable via `event.preventDefault()`. |
| `rowTransfer` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/row-drag-drop/interfaces/rowtransferdetail/">RowTransferDetail</a>&lt;any&gt;&gt;</code> | Emitted on BOTH source and target grids after a successful cross-grid row transfer. |
| `groupToggle` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/grouping-rows/interfaces/grouptoggledetail/">GroupToggleDetail</a>&gt;</code> | Emitted when a group is expanded or collapsed. |
| `groupExpand` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/grouping-rows/interfaces/groupexpanddetail/">GroupExpandDetail</a>&gt;</code> | Emitted when a group is expanded. |
| `groupCollapse` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/grouping-rows/interfaces/groupcollapsedetail/">GroupCollapseDetail</a>&gt;</code> | Emitted when a group is collapsed. |
| `treeExpand` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/tree/interfaces/treeexpanddetail/">TreeExpandDetail</a>&lt;any&gt;&gt;</code> | Emitted when a tree node is expanded. |
| `detailExpand` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/master-detail/interfaces/detailexpanddetail/">DetailExpandDetail</a>&gt;</code> | Emitted when a detail panel is expanded or collapsed. |
| `responsiveChange` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/responsive/interfaces/responsivechangedetail/">ResponsiveChangeDetail</a>&gt;</code> | Emitted when responsive mode changes (table ↔ card). |
| `contextMenuOpen` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/context-menu/interfaces/contextmenuopendetail/">ContextMenuOpenDetail</a>&gt;</code> | Emitted when the context menu opens. |
| `copy` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/clipboard/interfaces/copydetail/">CopyDetail</a>&gt;</code> | Emitted when cells are copied to clipboard. |
| `paste` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/clipboard/interfaces/pastedetail/">PasteDetail</a>&gt;</code> | Emitted when cells are pasted from clipboard. |
| `undo` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/undo-redo/interfaces/undoredodetail/">UndoRedoDetail</a>&gt;</code> | Emitted when an undo action is performed. |
| `redo` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/undo-redo/interfaces/undoredodetail/">UndoRedoDetail</a>&gt;</code> | Emitted when a redo action is performed. |
| `exportComplete` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/export/interfaces/exportcompletedetail/">ExportCompleteDetail</a>&gt;</code> | Emitted when export completes. |
| `printStart` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/print/interfaces/printstartdetail/">PrintStartDetail</a>&gt;</code> | Emitted when print starts. |
| `printComplete` | <code>OutputEmitterRef&lt;<a href="/grid/plugins/print/interfaces/printcompletedetail/">PrintCompleteDetail</a>&gt;</code> | Emitted when print completes. |
| `tbwScroll` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/tbwscrolldetail/">TbwScrollDetail</a>&gt;</code> | Emitted (rAF-batched) when the grid's viewport is scrolled vertically. |
| `render` | <code>OutputEmitterRef&lt;<a href="/grid/api/core/interfaces/renderdetail/">RenderDetail</a>&gt;</code> | Emitted once at the end of every render-scheduler flush, after all plugin `afterRender` hooks have run and `ready()` has resolved. |

### Property Details

#### customStyles

```typescript
// In your component
customStyles = `
  .my-detail-panel { padding: 16px; }
  .my-status-badge { border-radius: 4px; }
`;
```

```html
<tbw-grid [customStyles]="customStyles">...</tbw-grid>
```

---

#### sortable

Grid-wide sorting toggle.
When false, disables sorting for all columns regardless of their individual `sortable` setting.
When true (default), columns with `sortable: true` can be sorted.

This is a core grid config property, not a plugin feature.
For multi-column sorting, also add the `[multiSort]` feature.

**Default:** `true`

```html
<!-- Disable all sorting -->
<tbw-grid [sortable]="false" />

<!-- Enable sorting (default) - columns still need sortable: true -->
<tbw-grid [sortable]="true" />

<!-- Enable multi-column sorting -->
<tbw-grid [sortable]="true" [multiSort]="true" />
```

---

#### filterable

Grid-wide filtering toggle.
When false, disables filtering for all columns regardless of their individual `filterable` setting.
When true (default), columns with `filterable: true` can be filtered.

Requires the FilteringPlugin to be loaded.

**Default:** `true`

```html
<!-- Disable all filtering -->
<tbw-grid [filterable]="false" [filtering]="true" />

<!-- Enable filtering (default) -->
<tbw-grid [filterable]="true" [filtering]="true" />
```

---

#### selectable

Grid-wide selection toggle.
When false, disables selection for all rows/cells.
When true (default), selection is enabled based on plugin mode.

Requires the SelectionPlugin to be loaded.

**Default:** `true`

```html
<!-- Disable all selection -->
<tbw-grid [selectable]="false" [selection]="'range'" />

<!-- Enable selection (default) -->
<tbw-grid [selectable]="true" [selection]="'range'" />
```

---

#### loading

Show a loading overlay on the grid.
Use this during initial data fetch or refresh operations.

For row/cell loading states, access the grid element directly:
- `grid.setRowLoading(rowId, true/false)`
- `grid.setCellLoading(rowId, field, true/false)`

**Default:** `false`

```html
<!-- Show loading during data fetch -->
<tbw-grid [loading]="isLoading" [rows]="rows" />
```

```typescript
isLoading = true;

ngOnInit() {
  this.dataService.fetchData().subscribe(data => {
    this.rows = data;
    this.isLoading = false;
  });
}
```

---

#### rows

The data rows to display in the grid.

Accepts an array of data objects. Each object represents one row.
The grid reads property values for each column's `field` from these objects.

```html
<tbw-grid [rows]="employees()" [gridConfig]="config" />
```

---

#### columns

Column configuration array.

Accepts either full `ColumnConfig` objects or shorthand strings such as
`'name'` or `'salary:number'`. Shorthands auto-generate human-readable
headers from the field name.

Shorthand for setting columns without wrapping them in a full `gridConfig`.
If both `columns` and `gridConfig.columns` are set, `columns` takes precedence
(see configuration precedence system).

```html
<tbw-grid [rows]="data" [columns]="['id:number', 'name', { field: 'status', editable: true }]" />
```

---

#### columnDefaults

```html
<tbw-grid
  [columnDefaults]="{ sortable: true, resizable: true }"
  [columns]="[{ field: 'id', sortable: false }, { field: 'name' }]"
/>
```

---

#### fitMode

Column sizing strategy.

- `'stretch'` (default) — columns stretch to fill available width
- `'fixed'` — columns use their declared widths; enables horizontal scrolling
- `'auto-fit'` — columns auto-size to content, then stretch to fill

**Default:** `'stretch'`

```html
<tbw-grid [rows]="data" fitMode="fixed" />
<tbw-grid [rows]="data" [fitMode]="dynamicMode()" />
```

---

#### columnInference

How automatic column inference combines with explicitly provided columns.

- `'auto'` (default): infer only when no columns are provided.
- `'merge'`: always infer from data, then overlay provided columns by `field`.

```html
<tbw-grid [rows]="data" columnInference="merge" />
<tbw-grid [rows]="data" [columnInference]="mode()" />
```

---

#### gridConfig

Grid configuration object with optional Angular-specific extensions.

Accepts Angular-augmented `GridConfig` from `@toolbox-web/grid-angular`.
You can specify Angular component classes directly for renderers and editors.

Component classes must implement the appropriate interfaces:
- Renderers: `CellRenderer<TRow, TValue>` - requires `value()` and `row()` signal inputs
- Editors: `CellEditor<TRow, TValue>` - adds `commit` and `cancel` outputs

```typescript
// Simple config with plain renderers
config: GridConfig = {
  columns: [
    { field: 'name', header: 'Name' },
    { field: 'active', type: 'boolean' }
  ],
  typeDefaults: {
    boolean: { renderer: (ctx) => ctx.value ? '✓' : '✗' }
  }
};

// Config with component classes
config: GridConfig<Employee> = {
  columns: [
    { field: 'name', header: 'Name' },
    { field: 'bonus', header: 'Bonus', editable: true, editor: BonusEditorComponent }
  ]
};
```

```html
<tbw-grid [gridConfig]="config" [rows]="employees"></tbw-grid>
```

---

#### selection

Enable cell/row/range selection.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/selection';
```

```html
<!-- Shorthand - just the mode -->
<tbw-grid [selection]="'range'" />

<!-- Full config object -->
<tbw-grid [selection]="{ mode: 'range', checkbox: true }" />
```

---

#### editing

Enable inline cell editing.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/editing';
```

```html
<!-- Enable with default trigger (dblclick) -->
<tbw-grid [editing]="true" />

<!-- Specify trigger -->
<tbw-grid [editing]="'click'" />
<tbw-grid [editing]="'dblclick'" />
<tbw-grid [editing]="'manual'" />

<!-- Full config with callbacks -->
<tbw-grid [editing]="{ editOn: 'dblclick', onBeforeEditClose: myCallback }" />
```

---

#### clipboard

Enable clipboard copy/paste. Requires selection to be enabled.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/clipboard';
```

```html
<tbw-grid [selection]="'range'" [clipboard]="true" />
```

---

#### contextMenu

Enable right-click context menu.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/context-menu';
```

```html
<tbw-grid [contextMenu]="true" />
```

---

#### multiSort

Enable multi-column sorting.

Multi-sort allows users to sort by multiple columns simultaneously.
For basic single-column sorting, columns with `sortable: true` work without this plugin.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/multi-sort';
```

```html
<!-- Enable multi-column sorting -->
<tbw-grid [multiSort]="true" />

<!-- Limit to single column (uses plugin but restricts to 1 column) -->
<tbw-grid [multiSort]="'single'" />

<!-- Full config -->
<tbw-grid [multiSort]="{ maxSortColumns: 3 }" />
```

---

#### filtering

Enable column filtering.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/filtering';
```

```html
<tbw-grid [filtering]="true" />
<tbw-grid [filtering]="{ debounceMs: 200 }" />
```

---

#### reorderColumns

Enable column drag-to-reorder.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/reorder-columns';
```

```html
<tbw-grid [reorderColumns]="true" />
```

---

#### visibility

Enable column visibility toggle panel.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/visibility';
```

```html
<tbw-grid [visibility]="true" />
```

---

#### pinnedColumns

Enable pinned/sticky columns.
Columns are pinned via the `sticky` column property.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/pinned-columns';
```

```html
<tbw-grid [pinnedColumns]="true" [columns]="[
  { field: 'id', pinned: 'left' },
  { field: 'name' },
  { field: 'actions', pinned: 'right' }
]" />
```

---

#### groupingColumns

Enable multi-level column headers (column groups).

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/grouping-columns';
```

```html
<tbw-grid [groupingColumns]="true" />
```

---

#### columnVirtualization

Enable horizontal column virtualization for wide grids.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/column-virtualization';
```

```html
<tbw-grid [columnVirtualization]="true" />
```

---

#### rowDragDrop

Enable row drag-and-drop within and across grids.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/row-drag-drop';
```

```html
<tbw-grid [rowDragDrop]="{ dropZone: 'employees', operation: 'move' }" />
```

---

#### groupingRows

Enable row grouping by field values.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/grouping-rows';
```

```html
<tbw-grid [groupingRows]="{ groupBy: ['department'] }" />
```

---

#### pinnedRows

Enable pinned rows (aggregation/status bar).

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/pinned-rows';
```

```html
<tbw-grid [pinnedRows]="{ bottom: [{ type: 'aggregation' }] }" />
```

---

#### tree

Enable hierarchical tree view.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/tree';
```

```html
<tbw-grid [tree]="{ childrenField: 'children' }" />
```

---

#### masterDetail

Enable master-detail expandable rows.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/master-detail';
```

```html
<tbw-grid [masterDetail]="{ detailRenderer: detailFn }" />
```

---

#### responsive

Enable responsive card layout for narrow viewports.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/responsive';
```

```html
<tbw-grid [responsive]="{ breakpoint: 768 }" />
```

---

#### undoRedo

Enable undo/redo for cell edits. Requires editing to be enabled.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/undo-redo';
```

```html
<tbw-grid [editing]="'dblclick'" [undoRedo]="true" />
```

---

#### exportFeature

Enable CSV/JSON export functionality.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/export';
```

```html
<tbw-grid [export]="true" />
<tbw-grid [export]="{ filename: 'data.csv' }" />
```

---

#### print

Enable print functionality.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/print';
```

```html
<tbw-grid [print]="true" />
```

---

#### pivot

Enable pivot table functionality.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/pivot';
```

```html
<tbw-grid [pivot]="{ rowFields: ['category'], valueField: 'sales' }" />
```

---

#### serverSide

Enable server-side data operations.

**Requires feature import:**
```typescript
import '@toolbox-web/grid-angular/features/server-side';
```

```html
<tbw-grid [serverSide]="{ dataSource: fetchDataFn }" />
```

---

#### tooltip

```html
<tbw-grid [tooltip]="true" />
<tbw-grid [tooltip]="{ header: true, cell: false }" />
```

---

#### cellClick

```html
<tbw-grid (cellClick)="onCellClick($event)">...</tbw-grid>
```

---

#### rowClick

```html
<tbw-grid (rowClick)="onRowClick($event)">...</tbw-grid>
```

---

#### cellActivate

```html
<tbw-grid (cellActivate)="onCellActivate($event)">...</tbw-grid>
```

---

#### cellChange

```html
<tbw-grid (cellChange)="onCellChange($event)">...</tbw-grid>
```

---

#### cellCommit

```html
<tbw-grid (cellCommit)="onCellCommit($event)">...</tbw-grid>
```

```typescript
onCellCommit(event: CellCommitEvent) {
  console.log(`Changed ${event.field} to ${event.value} in row ${event.rowIndex}`);
}
```

---

#### cellCancel

```html
<tbw-grid (cellCancel)="onCellCancel($event)">...</tbw-grid>
```

---

#### editOpen

```html
<tbw-grid (editOpen)="onEditOpen($event)">...</tbw-grid>
```

---

#### beforeEditClose

```html
<tbw-grid (beforeEditClose)="onBeforeEditClose($event)">...</tbw-grid>
```

---

#### editClose

```html
<tbw-grid (editClose)="onEditClose($event)">...</tbw-grid>
```

---

#### dirtyChange

```html
<tbw-grid (dirtyChange)="onDirtyChange($event)">...</tbw-grid>
```

---

#### dataChange

```html
<tbw-grid (dataChange)="onDataChange($event)">...</tbw-grid>
```

---

#### rowCommit

```html
<tbw-grid (rowCommit)="onRowCommit($event)">...</tbw-grid>
```

---

#### changedRowsReset

```html
<tbw-grid (changedRowsReset)="onChangedRowsReset($event)">...</tbw-grid>
```

---

#### sortChange

```html
<tbw-grid (sortChange)="onSortChange($event)">...</tbw-grid>
```

---

#### filterChange

```html
<tbw-grid (filterChange)="onFilterChange($event)">...</tbw-grid>
```

---

#### columnResize

```html
<tbw-grid (columnResize)="onColumnResize($event)">...</tbw-grid>
```

---

#### columnResizeReset

```html
<tbw-grid (columnResizeReset)="onColumnResizeReset($event)">...</tbw-grid>
```

---

#### columnMove

```html
<tbw-grid (columnMove)="onColumnMove($event)">...</tbw-grid>
```

---

#### columnVisibility

```html
<tbw-grid (columnVisibility)="onColumnVisibility($event)">...</tbw-grid>
```

---

#### columnStateChange

```html
<tbw-grid (columnStateChange)="onColumnStateChange($event)">...</tbw-grid>
```

---

#### selectionChange

```html
<tbw-grid (selectionChange)="onSelectionChange($event)">...</tbw-grid>
```

---

#### rowMove

```html
<tbw-grid (rowMove)="onRowMove($event)">...</tbw-grid>
```

---

#### rowDragStart

```html
<tbw-grid (rowDragStart)="onRowDragStart($event)">...</tbw-grid>
```

---

#### groupToggle

```html
<tbw-grid (groupToggle)="onGroupToggle($event)">...</tbw-grid>
```

---

#### groupExpand

```html
<tbw-grid (groupExpand)="onGroupExpand($event)">...</tbw-grid>
```

---

#### groupCollapse

```html
<tbw-grid (groupCollapse)="onGroupCollapse($event)">...</tbw-grid>
```

---

#### treeExpand

```html
<tbw-grid (treeExpand)="onTreeExpand($event)">...</tbw-grid>
```

---

#### detailExpand

```html
<tbw-grid (detailExpand)="onDetailExpand($event)">...</tbw-grid>
```

---

#### responsiveChange

```html
<tbw-grid (responsiveChange)="onResponsiveChange($event)">...</tbw-grid>
```

---

#### contextMenuOpen

```html
<tbw-grid (contextMenuOpen)="onContextMenuOpen($event)">...</tbw-grid>
```

---

#### copy

```html
<tbw-grid (copy)="onCopy($event)">...</tbw-grid>
```

---

#### paste

```html
<tbw-grid (paste)="onPaste($event)">...</tbw-grid>
```

---

#### undo

```html
<tbw-grid (undo)="onUndo($event)">...</tbw-grid>
```

---

#### redo

```html
<tbw-grid (redo)="onRedo($event)">...</tbw-grid>
```

---

#### exportComplete

```html
<tbw-grid (exportComplete)="onExportComplete($event)">...</tbw-grid>
```

---

#### printStart

```html
<tbw-grid (printStart)="onPrintStart($event)">...</tbw-grid>
```

---

#### printComplete

```html
<tbw-grid (printComplete)="onPrintComplete($event)">...</tbw-grid>
```

---

#### tbwScroll

Emitted (rAF-batched) when the grid's viewport is scrolled vertically.

For server-side pagination of large datasets prefer `ServerSidePlugin`
— this event is the lower-level primitive for custom load-more triggers,
deferring heavy cell content, dismissing overlays, etc.

Named `tbwScroll` (not `scroll`) to avoid collision with the native DOM
scroll event that bubbles from focusable internals.

```html
<tbw-grid (tbwScroll)="onScroll($event)">...</tbw-grid>
```

---

#### render

Emitted once at the end of every render-scheduler flush, after all
plugin `afterRender` hooks have run and `ready()` has resolved.

Use this to act on the rendered DOM after a programmatic mutation
(e.g. focus the first input of a freshly added row in full-grid edit
mode) without `setTimeout` or double-`requestAnimationFrame` hacks.
The `render` event fires on every flush — including scroll-driven
virtual-window updates — so prefer subscribing once and unsubscribing
(or gating on `detail.phase >= RenderPhase.ROWS`) when you only care
about a specific mutation.

```html
<tbw-grid (render)="onRender($event)">...</tbw-grid>
```

---

## Methods

### ngOnInit()

A callback method that is invoked immediately after the
default change detector has checked the directive's
data-bound properties for the first time,
and before any of the view or content children have been checked.
It is invoked only once when the directive is instantiated.

```ts
ngOnInit(): void
```

***

### ngAfterContentInit()

A callback method that is invoked immediately after
Angular has completed initialization of all of the directive's
content.
It is invoked only once when the directive is instantiated.

```ts
ngAfterContentInit(): void
```

***

### ngOnDestroy()

A callback method that performs custom clean-up, invoked immediately
before a directive, pipe, or service instance is destroyed.

```ts
ngOnDestroy(): void
```

***
