Skip to main content

Column Groups

Group related columns under shared parent headers. OGrid supports arbitrarily nested column groups that render as multi-row <thead> headers.

Live Demo

Column headers are grouped into 'Personal Info' and 'Employment'
Live
Personal InfoEmployment
Name
Age
Email
Department
Salary
Status
Alice Johnson
25
alice@example.com
Engineering
$50,000
Active
Bob Smith
26
bob@example.com
Marketing
$53,500
Draft
Carol Lee
27
carol@example.com
Sales
$57,000
Archived
David Kim
28
david@example.com
Finance
$60,500
Active
Eve Torres
29
eve@example.com
Operations
$64,000
Draft
Frank Wu
30
frank@example.com
Engineering
$67,500
Archived
Grace Park
31
grace@example.com
Marketing
$71,000
Active
Henry Adams
32
henry@example.com
Sales
$74,500
Draft
Irene Costa
33
irene@example.com
Finance
$78,000
Archived
Jack Rivera
34
jack@example.com
Operations
$81,500
Active
Try it in your framework

The demo above uses Radix UI for styling. To see this feature with your framework's design system (Fluent UI, Material UI, Vuetify, PrimeNG, etc.), click "Open in online demo" below the demo.

Quick Example

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

interface Person {
id: number;
name: string;
age: number;
email: string;
department: string;
salary: number;
status: string;
}

const columns: (IColumnDef<Person> | IColumnGroupDef<Person>)[] = [
{
headerName: 'Personal Info',
children: [
{ columnId: 'name', name: 'Name' },
{ columnId: 'age', name: 'Age', type: 'numeric' },
{ columnId: 'email', name: 'Email' },
],
},
{
headerName: 'Employment',
children: [
{ columnId: 'department', name: 'Department' },
{
columnId: 'salary',
name: 'Salary',
type: 'numeric',
valueFormatter: (v) => `$${Number(v).toLocaleString()}`,
},
{ columnId: 'status', name: 'Status' },
],
},
];

function App() {
return (
<OGrid
columns={columns}
data={people}
getRowId={(p) => p.id}
defaultPageSize={10}
/>
);
}
Switching UI libraries

The OGrid component has the same props across all React UI packages. To switch, just change the import:

  • Radix (lightweight, default): from '@alaarab/ogrid-react-radix'
  • Fluent UI (Microsoft 365 / SPFx): from '@alaarab/ogrid-react-fluent' — wrap in <FluentProvider>
  • Material UI (MUI v7): from '@alaarab/ogrid-react-material' — wrap in <ThemeProvider>

This renders a two-row header: the first row shows "Personal Info" spanning three columns and "Employment" spanning three columns, with the individual column names in the second row.

How It Works

Column groups use the IColumnGroupDef<T> type. A group has a headerName (the text displayed in the group header cell) and a children array that can contain either IColumnDef items or nested IColumnGroupDef items.

// IColumnGroupDef<T>
{
headerName: string;
children: (IColumnGroupDef<T> | IColumnDef<T>)[];
}

When the columns prop contains groups, OGrid internally calls buildHeaderRows() to produce a multi-row header model. Each group header cell spans the correct number of leaf columns via colSpan.

Nested Groups

Groups can be nested to any depth. Each level adds another header row.

const columns: (IColumnDef<Row> | IColumnGroupDef<Row>)[] = [
{
headerName: 'Contact',
children: [
{
headerName: 'Name',
children: [
{ columnId: 'firstName', name: 'First' },
{ columnId: 'lastName', name: 'Last' },
],
},
{ columnId: 'email', name: 'Email' },
],
},
{ columnId: 'role', name: 'Role' },
];

This produces three header rows:

Contact (span 3)Role (span 1, rowSpan 3)
Name (span 2)Email (rowSpan 2)
FirstLast

Mixing Groups and Standalone Columns

Standalone IColumnDef items at the top level are valid alongside groups. They span all header rows vertically.

Group Header Behavior

Group headers are display-only:

  • Not sortable. Clicking a group header does nothing.
  • Not filterable. No filter icon or popover appears on group headers.
  • Not resizable. Group headers cannot be dragged to resize.
  • Centered text. Group header labels are centered over their children by default.

Sorting, filtering, and resizing remain available on the leaf column headers beneath the groups.

Props Reference

TypeFieldDescription
IColumnGroupDef<T>headerNameDisplay text for the group header
IColumnGroupDef<T>childrenArray of child columns or nested groups
IOGridProps<T>columnsAccepts (IColumnDef<T> | IColumnGroupDef<T>)[]