Skip to main content

Columns

Column definitions describe identity, value access, formatting, interaction, and presentation. The same definition model is used by the core and both framework bindings.

Loading interactive example…
React
const columns: ReactColDef[] = [
{ key: "orderNo", label: "Order", pinned: "left" },
{ key: "customer", label: "Customer", width: 180 },
{ key: "revenue", label: "Revenue", type: ColumnType.CURRENCY },
];

<Grid
rowData={rows}
columnDefs={columns}
columnPanel={{ trigger: "toolbar" }}
/>

Essential fields

FieldPurpose
keyReads a field from row data and provides a stable fallback identity
colIdExplicit public identity for state and API calls
labelVisible header label
typeSelects default comparison, formatting, filtering, and editing behavior
valueGetterComputes a value instead of reading key
valueFormatter / valueParserConverts values for display and committed edits

Users can resize and reorder enabled columns directly. Initial pinning and visibility use pinned and hidden; the API and column panel can change both at runtime. Capture the resulting layout with api.getColumnState() and restore it with api.applyColumnState(state).

Shared behavior

Put common capabilities such as sortable, resizable, and filter in defaultColDef. An explicit column value always wins.

Column types and formatting

import { ColumnType, type ColDef } from "@agility-workbench/grid";

const columnDefs: ColDef[] = [
{ key: "name", label: "Name", type: ColumnType.STRING },
{ key: "quantity", label: "Quantity", type: ColumnType.NUMBER },
{ key: "active", label: "Active", type: ColumnType.BOOLEAN },
{ key: "createdAt", label: "Created", type: ColumnType.DATE },
{ key: "revenue", label: "Revenue", type: ColumnType.CURRENCY },
];

Value getter, formatter, and parser

const column = {
colId: "total",
label: "Total",
valueGetter: (row) => row.quantity * row.unitPrice,
valueFormatter: ({ value }) => `$${Number(value).toFixed(2)}`,
editable: true,
valueParser: ({ value }) => Number(value),
} satisfies ColDef;

Pinning, visibility, and capabilities

const columnDefs: ColDef[] = [
{ key: "id", label: "ID", pinned: "left", movable: false },
{ key: "internal", label: "Internal", hidden: true },
{ key: "name", label: "Name", hideable: false },
{ key: "actions", label: "Actions", pinned: "right", resizable: false },
];

Users pin and hide columns through the column menu or the column panel.

Explicit width and automatic sizing

const options = {
minResizeWidth: 60,
maxColumnWidth: 360,
columnDefs: [
{ colId: "name", key: "name", label: "Name", minWidth: 120, maxWidth: 280 },
{ key: "notes", label: "Notes", width: 240 },
],
} satisfies GridOptions;

// Fit one column to its rendered content.
api.dispatch({ type: "columnAutosize", colId: "name" });

Set autosizeColumnsOnDataChange: true to recompute content widths after each data refresh. Enable a leading row-number column with rowNumbers: true.

Cell spanning

const columnDefs: ColDef[] = [
{
key: "title",
label: "Title",
colSpan: ({ data }) => data.kind === "section" ? 3 : 1,
},
{ key: "owner", label: "Owner" },
{ key: "status", label: "Status" },
];

A span stops at a pinned-section boundary.

Conditional cell styling

const column = {
key: "change",
label: "Change",
cellClass: ({ value }) => Number(value) < 0 ? "is-negative" : "is-positive",
cellStyle: ({ value }) => ({ fontWeight: Number(value) > 10 ? "700" : "400" }),
} satisfies ColDef;

Header content and whole-cell components

const labelOnly = ({ colDef }) => {
const strong = document.createElement("strong");
strong.textContent = colDef.label;
return strong;
};

const columnDefs: ColDef[] = [
{ key: "name", label: "Name", headerComponent: labelOnly },
{ key: "status", label: "Status", headerCellComponent: labelOnly },
];

headerComponent replaces header content while preserving grid controls. headerCellComponent replaces the whole header cell except its resize handle. The framework bindings accept React/Angular components in both slots.

Column state

const savedState = api.getColumnState();

// Later: restore widths, order, pinning, and visibility.
api.applyColumnState(savedState);

// Exact restore: hide columns absent from the saved state.
api.applyColumnState(savedState, { defaultState: { hidden: true } });

Add or replace definitions at runtime

api.setColumnDefs([...baseColumns, { key: "margin", label: "Margin" }]);

api.dispatch({
type: "addSparklineColumn",
targetColId: "revenue",
colIds: ["jan", "feb", "mar"],
sparklineType: "line",
});