Skip to content

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.

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

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:

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

PropertyTypeDescription
customStylesInputSignal<string | undefined>Custom CSS styles to inject into the grid. Use this to style custom cell renderers, editors, or detail panels.
sortableInputSignal<boolean | undefined>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.
filterableInputSignal<boolean | undefined>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.
selectableInputSignal<boolean | undefined>Grid-wide selection toggle. When false, disables selection for all rows/cells. When true (default), selection is enabled based on plugin mode.
loadingInputSignal<boolean | undefined>Show a loading overlay on the grid. Use this during initial data fetch or refresh operations.
rowsInputSignal<any[] | undefined>The data rows to display in the grid.
columnsInputSignal<ColumnShorthand<any>[] | undefined>Column configuration array.
columnDefaultsInputSignal<Partial<ColumnConfig<any, ColumnFieldKey<any>>> | undefined>Default column properties applied to every column in columns. Individual column properties override these defaults.
fitModeInputSignal<FitMode | undefined>Column sizing strategy.
columnInferenceInputSignal<ColumnInferenceMode | undefined>How automatic column inference combines with explicitly provided columns.
gridConfigInputSignal<GridConfig<any, ColumnFieldKey<any>> | undefined>Grid configuration object with optional Angular-specific extensions.
pluginsInputSignal<BaseGridPlugin<unknown>[] | undefined>Manually instantiated plugins (escape hatch for advanced configuration). When provided, per-feature directive inputs are ignored — only plugins from this list plus any declared in gridConfig.plugins are used. v2.5.0+
cellClickOutputEmitterRef<CellClickDetail<any>>Emitted when a cell is clicked.
rowClickOutputEmitterRef<RowClickDetail<any>>Emitted when a row is clicked.
cellActivateOutputEmitterRef<CellActivateDetail<any>>Emitted when a cell is activated (Enter key or double-click).
cellChangeOutputEmitterRef<CellChangeDetail<any>>Emitted when a cell value changes (before commit).
dataChangeOutputEmitterRef<DataChangeDetail>Emitted when row data is replaced (e.g. via the rows setter).
sortChangeOutputEmitterRef<SortChangeDetail>Emitted when sort state changes.
columnResizeOutputEmitterRef<ColumnResizeDetail>Emitted when a column is resized.
columnResizeResetOutputEmitterRef<ColumnResizeResetDetail>Emitted when a column’s width is reset (double-click on the resize handle).
columnStateChangeOutputEmitterRef<GridColumnState>Emitted when column state changes (resize, reorder, visibility).
tbwScrollOutputEmitterRef<TbwScrollDetail>Emitted (rAF-batched) when the grid’s viewport is scrolled vertically.
renderOutputEmitterRef<RenderDetail>Emitted once at the end of every render-scheduler flush, after all plugin afterRender hooks have run and ready() has resolved.
// In your component
customStyles = `
.my-detail-panel { padding: 16px; }
.my-status-badge { border-radius: 4px; }
`;
<tbw-grid [customStyles]="customStyles">...</tbw-grid>

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

<!-- 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" />

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

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

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

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

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

<!-- Show loading during data fetch -->
<tbw-grid [loading]="isLoading" [rows]="rows" />
isLoading = true;
ngOnInit() {
this.dataService.fetchData().subscribe(data => {
this.rows = data;
this.isLoading = false;
});
}

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.

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

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).

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

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

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'

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

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.
<tbw-grid [rows]="data" columnInference="merge" />
<tbw-grid [rows]="data" [columnInference]="mode()" />

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
// 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 }
]
};
<tbw-grid [gridConfig]="config" [rows]="employees"></tbw-grid>

import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
plugins = [new SelectionPlugin({ mode: 'range', checkbox: true })];
<tbw-grid [rows]="employees()" [plugins]="plugins"></tbw-grid>

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

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

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

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

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

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

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

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

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

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.

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

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.

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

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.

ngOnInit(): void

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.

ngAfterContentInit(): void

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

ngOnDestroy(): void