Columns
Columns are the foundation of a GridStorm grid. Every column is described by a ColumnDef object that controls what data is displayed, how it is formatted, and what interactions are available.
Basic Column Definition
At minimum, a column needs a field that maps to a property on your row data:
const columns = [
{ field: 'name' },
{ field: 'age' },
{ field: 'email' },
];
When headerName is omitted, GridStorm uses the field value as the header text. For a cleaner display, provide an explicit header:
const columns = [
{ field: 'firstName', headerName: 'First Name' },
{ field: 'lastName', headerName: 'Last Name' },
{ field: 'email', headerName: 'Email Address' },
];
Column IDs
Each column has a unique colId. If you do not provide one, it is auto-generated from the field value. For columns without a field (e.g., action columns), always set colId explicitly:
{
colId: 'actions',
headerName: 'Actions',
cellRenderer: (params) => {
const btn = document.createElement('button');
btn.textContent = 'Edit';
return btn;
},
}
Sizing
Width
Set column width in pixels:
{ field: 'name', width: 200 }
Min and Max Width
Constrain the column's resizable range:
{ field: 'name', width: 200, minWidth: 100, maxWidth: 400 }
Flex
Use flex to distribute remaining space proportionally:
const columns = [
{ field: 'name', flex: 1 }, // 1/3 of remaining space
{ field: 'email', flex: 2 }, // 2/3 of remaining space
{ field: 'status', width: 100 }, // fixed 100px
];
Flex columns fill available space after fixed-width columns are laid out.
Feature Flags
Column definitions include boolean flags to enable plugin features per column:
| Property | Type | Default | Description |
|---|---|---|---|
sortable |
boolean |
false |
Allow sorting by clicking the header |
filterable |
boolean |
false |
Allow filtering this column |
editable |
boolean | function |
false |
Allow inline cell editing |
resizable |
boolean |
false |
Allow drag-to-resize from the header border |
{
field: 'name',
sortable: true,
filterable: true,
editable: true,
resizable: true,
}
:::tip
Use defaultColDef on the grid config to set defaults for all columns, then override per column:
const config = {
columns: [...],
rowData: [...],
defaultColDef: {
sortable: true,
resizable: true,
filterable: true,
},
};
:::
Conditional Editability
The editable property accepts a function for row-level control:
{
field: 'price',
editable: (params) => params.data?.status !== 'locked',
}
Pinning
Pin columns to the left or right edge so they remain visible during horizontal scrolling:
{ field: 'name', pinned: 'left' }
{ field: 'actions', pinned: 'right' }
Set lockPinned: true to prevent the user from unpinning a column via the context menu.
Visibility
Hide a column from the grid while keeping it available in the data model:
{ field: 'internalId', hide: true }
Toggle visibility programmatically via the API:
api.setColumnVisible('internalId', true);
Value Pipeline
GridStorm processes cell values through a pipeline of optional functions:
Raw Data --> valueGetter --> value --> valueFormatter --> display string
(editing uses valueParser)
Value Getter
Extract or compute values that do not map directly to a single field:
{
colId: 'fullName',
headerName: 'Full Name',
valueGetter: (params) => {
return `${params.data?.firstName} ${params.data?.lastName}`;
},
}
Value Formatter
Format a value for display without changing the underlying data:
{
field: 'salary',
valueFormatter: (params) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(params.value);
},
}
Value Setter
Control how edited values are written back to the row data:
{
field: 'price',
valueSetter: (params) => {
const parsed = parseFloat(params.newValue);
if (isNaN(parsed)) return false; // reject
params.data.price = parsed;
return true; // accept
},
}
Value Parser
Parse user input during editing before it reaches the value setter:
{
field: 'age',
valueParser: (params) => parseInt(params.newValue, 10),
}
Custom Cell Renderers
Return a string or an HTMLElement from the cellRenderer function to customize cell content:
{
field: 'status',
cellRenderer: (params) => {
const span = document.createElement('span');
span.className = `badge badge-${params.value}`;
span.textContent = params.value;
return span;
},
}
In the React adapter, you can pass React components as cell renderers. See the React guide for details.
Custom Header Renderers
Customize the header cell rendering:
{
field: 'name',
headerRenderer: (params) => {
const el = document.createElement('div');
el.innerHTML = `<strong>${params.displayName}</strong>`;
return el;
},
}
Cell Styling
Apply dynamic CSS classes or inline styles:
{
field: 'score',
cellClass: (params) => params.value >= 90 ? 'cell-high' : 'cell-low',
}
{
field: 'balance',
cellStyle: (params) => ({
color: params.value < 0 ? 'red' : 'green',
fontWeight: '600',
}),
}
Tooltips
Show a tooltip on hover:
{ field: 'description', tooltipField: 'description' }
Or compute the tooltip dynamically:
{
field: 'name',
tooltipValueGetter: (params) => `Employee ID: ${params.node.id}`,
}
Column Spanning
Span a cell across multiple columns:
{
field: 'title',
colSpan: (params) => params.data?.isHeader ? 3 : 1,
}
Row Grouping and Aggregation
Columns can participate in grouping and aggregation:
{ field: 'department', rowGroup: true, rowGroupIndex: 0 }
{ field: 'salary', aggFunc: 'sum' }
See the Grouping and Aggregation plugin pages for details.
Next Steps
- Row Data -- Setting and updating row data.
- Column Definitions API -- Complete ColumnDef property reference.
- Editing Plugin -- Cell editors and editing lifecycle.