gp-grid-logo
Examples

Custom Renderers

Render custom React components inside grid cells and headers, including badges, charts, action menus, and any other interactive UI you need to embed today.

Customize how cells and headers are rendered with custom renderer functions.

Interactive Demo

This demo shows three custom renderers in action:

  • Status - Colored dot indicator (green/amber/gray)
  • Performance - Positive values in green, negative in red
  • Salary - Formatted as currency

Free-text filter conditions and copy-paste operate on the formatted value — the string users actually see — while the values (checkbox) filter and sorting work on raw values. A cellRenderer only changes how a cell is painted; it does not affect filtering at all. Pair every custom renderer with a matching valueFormatter so the text users type into a filter matches what they see:

{
  field: "salary",
  cellDataType: "number",
  width: 140,
  cellRenderer: SalaryRenderer,
  valueFormatter: (value) => `$${(value as number).toLocaleString()}`,
}

Without the formatter, users typing "$82,000" into the Salary column's text condition would match nothing because the comparison would run against the raw 82000. See the full valueFormatter reference for signature, caveats, and more examples.

Cell Renderers

Global Cell Renderer

Apply a renderer to all cells:

import { Grid, type CellRendererParams } from "@gp-grid/react";

const MyCellRenderer = (params: CellRendererParams) => {
  return (
    <div className="flex items-center h-full px-2">
      {params.value?.toString()}
    </div>
  );
};

<Grid
  columns={columns}
  rowData={data}
  rowHeight={36}
  cellRenderer={MyCellRenderer}
/>

Per-Column Renderers (Inline)

Pass a renderer function directly in the column definition:

const StatusRenderer = (params: CellRendererParams) => {
  const status = params.value as string;
  const color = status === "Active" ? "green" : "red";

  return (
    <div className="flex items-center h-full px-2">
      <span
        className="w-2 h-2 rounded-full mr-2"
        style={{ backgroundColor: color }}
      />
      {status}
    </div>
  );
};

const columns: ColumnDefinition[] = [
  { field: "name", cellDataType: "text", width: 150 },
  {
    field: "status",
    cellDataType: "text",
    width: 120,
    cellRenderer: StatusRenderer,
  },
];

<Grid columns={columns} rowData={data} rowHeight={36} />

Per-Column Renderers (Registry)

Alternatively, register renderers by key and reference them by name. This is useful when the same renderer is shared across multiple columns:

const columns: ColumnDefinition[] = [
  { field: "name", cellDataType: "text", width: 150 },
  {
    field: "status",
    cellDataType: "text",
    width: 120,
    cellRenderer: "status"
  },
];

<Grid
  columns={columns}
  rowData={data}
  rowHeight={36}
  cellRenderers={{ status: StatusRenderer }}
/>

Header Renderers

Customize column headers:

import { type HeaderRendererParams } from "@gp-grid/react";

const MyHeaderRenderer = (params: HeaderRendererParams) => {
  return (
    <div className="flex items-center justify-between w-full h-full px-2">
      <span className="font-bold">{params.column.headerName}</span>
      {params.sortDirection && (
        <span>{params.sortDirection === "asc" ? "▲" : "▼"}</span>
      )}
    </div>
  );
};

<Grid
  columns={columns}
  rowData={data}
  rowHeight={36}
  headerRenderer={MyHeaderRenderer}
/>

Renderer Parameters

CellRendererParams

PropertyTypeDescription
valueCellValueCurrent cell value
rowDataTDataFull row data object
columnColumnDefinitionColumn definition
rowIndexnumberRow index
colIndexnumberColumn index
isActivebooleanIs the active cell
isSelectedbooleanIs in selection range
isEditingbooleanIs being edited

HeaderRendererParams

PropertyTypeDescription
columnColumnDefinitionColumn definition
colIndexnumberColumn index
sortDirectionSortDirection | undefinedCurrent sort direction
sortIndexnumber | undefinedMulti-sort order
sortablebooleanIs column sortable
filterablebooleanIs column filterable
hasFilterbooleanHas active filter
onSortfunctionTrigger sort
onFilterClickfunctionOpen filter popup