Skip to main content

Column Definition

Complete reference for column definitions, column groups, cell editors, and related types.

IColumnMeta

Base metadata shared by all column definitions. These properties control how a column appears and behaves in the grid header.

interface IColumnMeta {
columnId: string;
name: string;
type?: 'numeric';
sortable?: boolean;
filterable?: IColumnFilterDef;
defaultVisible?: boolean;
required?: boolean;
minWidth?: number;
defaultWidth?: number;
idealWidth?: number;
pinned?: 'left' | 'right';
}
NameTypeDefaultDescription
columnIdstringRequiredUnique identifier for the column. Used as the key for sorting, filtering, visibility, and state persistence. Also used as the default field name for valueGetter if none is provided.
namestringRequiredDisplay name shown in the column header.
type'numeric'undefinedColumn data type. When set to 'numeric', cell content is right-aligned.
sortablebooleantrueWhether the column header is clickable for sorting.
filterableIColumnFilterDefundefinedFilter configuration. When provided, a filter icon appears in the column header. See IColumnFilterDef below.
defaultVisiblebooleantrueWhether the column is visible by default. Columns with defaultVisible: false can be shown via the column chooser.
requiredbooleanfalseWhen true, the column cannot be hidden via the column chooser.
minWidthnumberundefinedMinimum column width in pixels. The column cannot be resized below this value.
defaultWidthnumberundefinedDefault column width in pixels.
idealWidthnumberundefinedPreferred column width in pixels. Used by the grid's auto-sizing algorithm.
pinned'left' | 'right'undefinedPin the column to the left or right edge of the grid. Pinned columns remain visible when scrolling horizontally.

IColumnDef<T>

Extends IColumnMeta with rendering, editing, and data access properties.

interface IColumnDef<T> extends IColumnMeta {
renderCell?: (item: T) => ReactNode;
compare?: (a: T, b: T) => number;
valueGetter?: (item: T) => unknown;
valueFormatter?: (value: unknown, item: T) => string;
valueParser?: (params: IValueParserParams<T>) => unknown;
cellStyle?: CSSProperties | ((item: T) => CSSProperties);
editable?: boolean | ((item: T) => boolean);
cellEditor?: 'text' | 'select' | 'checkbox' | 'richSelect' | ComponentType<ICellEditorProps<T>>;
cellEditorPopup?: boolean;
cellEditorParams?: CellEditorParams;
}

Rendering

NameTypeDefaultDescription
renderCell(item: T) => ReactNodeundefinedCustom cell renderer. Receives the row data and returns JSX. When not provided, the grid displays the raw value from valueGetter or the field matching columnId.
cellStyleCSSProperties | ((item: T) => CSSProperties)undefinedCustom styles applied to the cell. Can be a static style object or a function that returns styles based on the row data.

Data Access

NameTypeDefaultDescription
valueGetter(item: T) => unknownundefinedExtracts the raw value from a row for sorting, filtering, editing, and display. When not provided, the grid reads item[columnId].
valueFormatter(value: unknown, item: T) => stringundefinedFormats the raw value for display and clipboard copy. Receives the value from valueGetter and the row data.
valueParser(params: IValueParserParams<T>) => unknownundefinedParses a user-entered string back into the data type expected by your model. Used during cell editing and paste operations.
compare(a: T, b: T) => numberundefinedCustom sort comparator. Returns a negative number if a comes before b, positive if after, or 0 if equal. When not provided, the grid uses a default comparison on the valueGetter result.

Editing

NameTypeDefaultDescription
editableboolean | ((item: T) => boolean)falseWhether cells in this column are editable. A function allows per-row control. The grid-level editable prop must also be true for editing to work.
cellEditor'text' | 'select' | 'checkbox' | 'richSelect' | ComponentType<ICellEditorProps<T>>'text'The editor to use when a cell enters edit mode. Built-in editors: 'text' (text input), 'select' (dropdown), 'checkbox' (toggle), 'richSelect' (searchable dropdown). You can also pass a custom React component.
cellEditorPopupbooleanfalseWhen true, the cell editor renders in a popup overlay instead of inline within the cell.
cellEditorParamsCellEditorParamsundefinedAdditional parameters passed to the cell editor. The shape depends on the editor type. See CellEditorParams below.

IColumnFilterDef

Configuration for column header filters.

interface IColumnFilterDef {
type: 'text' | 'multiSelect' | 'people';
filterField?: string;
optionsSource?: 'api' | 'static' | 'years';
options?: string[];
yearsCount?: number;
}
NameTypeDefaultDescription
type'text' | 'multiSelect' | 'people'RequiredFilter type. 'text' shows a text input. 'multiSelect' shows a list of checkboxes. 'people' shows a people picker with search.
filterFieldstringcolumnIdThe field name to use in the IFilters record. Defaults to the column's columnId. Useful when multiple columns filter on the same field.
optionsSource'api' | 'static' | 'years'undefinedWhere multiSelect options come from. 'static' uses the options array. 'api' calls dataSource.fetchFilterOptions(). 'years' auto-generates a list of years.
optionsstring[]undefinedStatic list of filter options for optionsSource: 'static'.
yearsCountnumberundefinedNumber of years to generate when optionsSource: 'years'.

Filter Type Examples

// Text filter
{ columnId: 'name', name: 'Name', filterable: { type: 'text' } }

// Multi-select with static options
{
columnId: 'status',
name: 'Status',
filterable: {
type: 'multiSelect',
optionsSource: 'static',
options: ['Active', 'Inactive', 'Pending'],
},
}

// Multi-select with server-side options
{
columnId: 'department',
name: 'Department',
filterable: { type: 'multiSelect', optionsSource: 'api' },
}

// People filter
{
columnId: 'assignee',
name: 'Assignee',
filterable: { type: 'people' },
}

// Year filter
{
columnId: 'year',
name: 'Year',
filterable: { type: 'multiSelect', optionsSource: 'years', yearsCount: 10 },
}

IColumnGroupDef<T>

Defines a group of columns rendered under a shared multi-row header.

interface IColumnGroupDef<T> {
headerName: string;
children: (IColumnGroupDef<T> | IColumnDef<T>)[];
}
NameTypeDefaultDescription
headerNamestringRequiredDisplay name for the column group header. Rendered centered above its child columns.
children(IColumnGroupDef<T> | IColumnDef<T>)[]RequiredChild columns or nested column groups. Groups can be nested to arbitrary depth, producing multi-row headers.

Column Group Example

const columns = [
{ columnId: 'name', name: 'Name' },
{
headerName: 'Contact Info',
children: [
{ columnId: 'email', name: 'Email' },
{ columnId: 'phone', name: 'Phone' },
],
},
{
headerName: 'Address',
children: [
{ columnId: 'city', name: 'City' },
{ columnId: 'state', name: 'State' },
{ columnId: 'zip', name: 'ZIP' },
],
},
];

This renders as:

NameContact InfoAddress
EmailPhoneCityStateZIP

ICellEditorProps<T>

Props received by custom cell editor components.

interface ICellEditorProps<T> {
value: unknown;
onValueChange: (value: unknown) => void;
onCommit: () => void;
onCancel: () => void;
item: T;
column: IColumnDef<T>;
cellEditorParams?: CellEditorParams;
}
NameTypeDescription
valueunknownThe current cell value.
onValueChange(value: unknown) => voidCall this to update the pending value as the user types or makes a selection.
onCommit() => voidCall this to commit the current value and exit edit mode. Typically bound to Enter or blur.
onCancel() => voidCall this to discard changes and exit edit mode. Typically bound to Escape.
itemTThe full row data object.
columnIColumnDef<T>The column definition for the cell being edited.
cellEditorParamsCellEditorParamsAdditional parameters from the column definition's cellEditorParams.

Custom Cell Editor Example

import { ICellEditorProps } from '@alaarab/ogrid-react-radix';

function DateEditor({ value, onValueChange, onCommit, onCancel }: ICellEditorProps<MyRow>) {
return (
<input
type="date"
value={value as string}
onChange={(e) => onValueChange(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') onCommit();
if (e.key === 'Escape') onCancel();
}}
onBlur={onCommit}
autoFocus
/>
);
}

const columns = [
{
columnId: 'dueDate',
name: 'Due Date',
editable: true,
cellEditor: DateEditor,
},
];

CellEditorParams

Parameters passed to built-in cell editors via the cellEditorParams property on a column definition. The shape varies by editor type.

Select Editor

{
cellEditor: 'select',
cellEditorParams: {
values: ['Option A', 'Option B', 'Option C'],
},
}
NameTypeDescription
valuesstring[]List of options for the select dropdown.

Rich Select Editor

{
cellEditor: 'richSelect',
cellEditorParams: {
values: ['Active', 'Inactive', 'Pending'],
formatValue: (value: string) => value.toUpperCase(),
},
}
NameTypeDescription
valuesstring[]List of options for the searchable dropdown.
formatValue(value: string) => stringOptional function to format how each option is displayed.

ICellValueChangedEvent<T>

Event object passed to onCellValueChanged after a cell edit is committed.

interface ICellValueChangedEvent<T> {
item: T;
columnId: string;
field: string;
oldValue: unknown;
newValue: unknown;
rowIndex: number;
}
NameTypeDescription
itemTThe row data object (before the change).
columnIdstringThe column ID of the edited cell.
fieldstringThe field name of the edited cell.
oldValueunknownThe value before editing.
newValueunknownThe value after editing.
rowIndexnumberThe row index of the edited cell.

Complete Column Definition Example

import { IColumnDef, IColumnGroupDef } from '@alaarab/ogrid-react-radix';

interface Employee {
id: number;
name: string;
department: string;
salary: number;
startDate: string;
manager: { displayName: string; email: string };
}

const columns: (IColumnDef<Employee> | IColumnGroupDef<Employee>)[] = [
{
columnId: 'name',
name: 'Employee Name',
sortable: true,
required: true,
pinned: 'left',
minWidth: 150,
filterable: { type: 'text' },
editable: true,
cellEditor: 'text',
},
{
headerName: 'Details',
children: [
{
columnId: 'department',
name: 'Department',
filterable: {
type: 'multiSelect',
optionsSource: 'static',
options: ['Engineering', 'Marketing', 'Sales', 'HR'],
},
editable: true,
cellEditor: 'richSelect',
cellEditorParams: { values: ['Engineering', 'Marketing', 'Sales', 'HR'] },
},
{
columnId: 'salary',
name: 'Salary',
type: 'numeric',
valueFormatter: (value) => `$${Number(value).toLocaleString()}`,
valueParser: ({ newValue }) => Number(String(newValue).replace(/[$,]/g, '')),
editable: true,
cellStyle: (item) => ({
color: item.salary > 100000 ? 'green' : undefined,
}),
},
],
},
{
columnId: 'startDate',
name: 'Start Date',
defaultVisible: false,
valueFormatter: (value) => new Date(value as string).toLocaleDateString(),
},
{
columnId: 'manager',
name: 'Manager',
filterable: { type: 'people' },
valueGetter: (item) => item.manager,
renderCell: (item) => <span>{item.manager.displayName}</span>,
valueFormatter: (value) => (value as Employee['manager']).displayName,
editable: false,
},
];