# Custom Header, Footer, Filter, and Group Cells

The KendoReact Grid lets you replace the cells in the header row, filter row, footer row, and group header and footer rows with custom cell components. Column header cells render as `<th>` elements and carry ARIA attributes for sorting and keyboard navigation. Filter, footer, and group cells render as `<td>` elements and use a separate set of attribute props.

You can replace any of these cell types by providing a custom cell component through the [`cells`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridprops#cells) prop on `Grid` or `GridColumn`. The available cell types are:

* [`headerCell`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings#headerCell)—the column title cell in the header row.
* [`filterCell`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings#filterCell)—the cell in the filter row below the header.
* [`footerCell`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings#footerCell)—the cell in the optional footer row at the bottom.
* [`groupHeader`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings#groupHeader)—the cell that labels each group row when grouping is enabled.
* [`groupFooter`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings#groupFooter)—the cell that appears at the bottom of each group when group footers are enabled.

<CtaPanelOverview></CtaPanelOverview>

The following example shows all cell types customized at once. Each type receives a different custom component that applies custom colors and renders the default `children` content so the Grid's built-in sort icon, column menu, and grouping labels are preserved.

[Demo Source](https://demos.telerik.com/kendo-react-ui/grid/grid-custom-cell/other/func/source.txt)

## Custom Header Cells

A custom header cell component receives [`GridCustomHeaderCellProps`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcustomheadercellprops). The most important props are:

* `thProps`—The full set of HTML and ARIA attributes the Grid would apply to the `<th>` element by default. This includes `aria-sort`, the column identity needed for keyboard navigation, and `colSpan` for spanned headers.
* `children`—The default cell content rendered by the Grid, including the column title, sort indicator, column menu trigger, and column resize handle.

When implementing a custom header cell, you must render the outer element as [`HeaderThElement`](https://www.telerik.com/kendo-react-ui/components/datatools/api/headerthelement) from `@progress/kendo-react-data-tools` and forward `thProps` to it. Rendering a plain `<th>` instead, or omitting `thProps`, will disconnect the column from the Grid's sort state, ARIA attributes, and keyboard focus management.

The following snippets show a custom header cell component and how to bind it to the Grid:

```tsx Component
import * as React from 'react';
import { HeaderThElement } from '@progress/kendo-react-data-tools';
import { GridCustomHeaderCellProps } from '@progress/kendo-react-grid';

// Forward thProps to keep sort state, ARIA attributes, and keyboard focus connected to the Grid.
const CustomHeaderCell = (props: GridCustomHeaderCellProps) => (
    <HeaderThElement columnId={props.thProps?.columnId || ''} {...props.thProps} style={{ color: '#533291' }}>
        {props.children}
    </HeaderThElement>
);
```

```tsx Grid Setup
{
    /* All columns */
}
<Grid data={data} cells={{ headerCell: CustomHeaderCell }}>
    <GridColumn field="ProductName" title="Product Name" />
    <GridColumn field="UnitPrice" title="Unit Price" />
</Grid>;

{
    /* Single column only */
}
<Grid data={data}>
    <GridColumn field="ProductName" title="Product Name" cells={{ headerCell: CustomHeaderCell }} />
    <GridColumn field="UnitPrice" title="Unit Price" />
</Grid>;
```

### Composing Header Cells With the Default Slots

Rendering `children` gives you the entire default header content as a single opaque node. That works well for styling changes and outer-element tweaks, but not when you want to keep the built-in sort icon, column menu, and resizer while extending or replacing just the title area.

For that case, `GridCustomHeaderCellProps` also exposes the default header content as individual slot nodes:

* `titleElement`—The default `<span class="k-column-title">` element with the column title text and the grouping-row class when applicable.
* `sortIcon`—The default sort direction icon and sort-order badge. `null` when the column is not sorted.
* `columnMenu`—The default column menu / filter button wrapper. `null` when the column has no column menu configured.
* `resizer`—The default column resize handle.

Compose these slots inside the standard `k-cell-inner` / `k-link` structure and attach `props.onClick` to the link element to preserve click-to-sort. The Grid keeps ownership of the sort icon rendering, filter popup, and resizing behavior — you only decide what appears around them.

[Demo Source](https://demos.telerik.com/kendo-react-ui/grid/grid-custom-cell/header-slots/func/source.txt)

## Custom Filter Cells

A custom filter cell component receives [`GridCustomFilterCellProps`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcustomfiltercellprops). Unlike header cells, filter row cells are rendered as `<td>` elements with a `role="gridcell"` by default. The Grid passes both `thProps` and `tdProps` to the custom filter cell and both point to the same navigation attributes object, including the column ID and keyboard navigation hooks.

You can use `HeaderThElement` with `thProps` as shown in the example below — the `role="gridcell"` attribute in `thProps` will override the native `<th>` role on the rendered element so accessibility semantics remain correct.

The `children` prop contains the default filter input the Grid would render. If you render `children`, the built-in filter input remains functional and you only affect the cell's outer element. If you omit `children` and render your own control, you take responsibility for calling `props.onChange` with the appropriate filter descriptor.

The following snippets show a minimal custom filter cell and how to bind it to the Grid:

```tsx Component
import * as React from 'react';
import { HeaderThElement } from '@progress/kendo-react-data-tools';
import { GridCustomFilterCellProps } from '@progress/kendo-react-grid';

const CustomFilterCell = (props: GridCustomFilterCellProps) => (
    <HeaderThElement columnId={props.thProps?.columnId || ''} {...props.thProps}>
        {props.children}
    </HeaderThElement>
);
```

```tsx Grid Setup
<Grid data={data} filterable={true} cells={{ filterCell: CustomFilterCell }}>
    <GridColumn field="ProductName" title="Product Name" />
    <GridColumn field="UnitPrice" title="Unit Price" />
</Grid>
```

## Custom Footer Cells

A custom footer cell component receives [`GridCustomFooterCellProps`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcustomfootercellprops). Footer cells render as `<td>` elements, so the relevant attribute prop here is `tdProps` rather than `thProps`. Forwarding `tdProps` is important when the Grid has locked (sticky) columns — it carries the positioning styles that keep locked cells aligned.

The `field` prop identifies which column the footer cell belongs to, making it straightforward to compute and display aggregates such as sum, average, minimum, or maximum values for that field.

The following snippets show a custom footer cell that renders aggregates and how to bind it to the Grid:

```tsx Component
import * as React from 'react';
import { GridCustomFooterCellProps } from '@progress/kendo-react-grid';

const CustomFooterCell = (props: GridCustomFooterCellProps) => {
    const field = props.field || '';
    const values = data.map((item) => item[field]);
    const min = Math.min(...values);
    const max = Math.max(...values);

    return (
        // Forward tdProps to keep locked (sticky) column positioning.
        <td {...props.tdProps}>
            min: {min}, max: {max}
        </td>
    );
};
```

```tsx Grid Setup
<Grid data={data} cells={{ footerCell: CustomFooterCell }}>
    <GridColumn field="ProductName" title="Product Name" />
    <GridColumn field="UnitPrice" title="Unit Price" />
</Grid>
```

## Custom Group Header and Group Footer Cells

Group header and group footer cells both receive [`GridCustomCellProps`](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcustomcellprops) and also render as `<td>` elements. The key props here are `dataItem`, which contains the group descriptor including the grouped `field` and its `value`, and `tdProps` for forwarding the cell's structural attributes.

`children` in group cells contains the default group label or footer content the Grid would render. Rendering `children` preserves the default label text, expand/collapse icon, and aggregate display.

```tsx Component
import * as React from 'react';
import { GridCustomCellProps } from '@progress/kendo-react-grid';

const CustomGroupHeaderCell = (props: GridCustomCellProps) => (
    <td {...props.tdProps} style={{ color: '#014830', backgroundColor: '#4a9d93' }}>
        {props.children}
    </td>
);
```

```tsx Grid Setup
<Grid
    data={data}
    groupable={{ footer: 'visible' }}
    defaultGroup={[{ field: 'Category' }]}
    cells={{
        groupHeader: CustomGroupHeaderCell,
        groupFooter: CustomGroupFooterCell
    }}
>
    <GridColumn field="ProductName" title="Product Name" />
    <GridColumn field="UnitPrice" title="Unit Price" />
</Grid>
```

### Customizing Cells in Group Columns

When the Grid uses the `singleColumn` or `multipleColumns` [grouping display modes](https://www.telerik.com/kendo-react-ui-develop/components/grid/grouping/grouping-modes), it generates dedicated group columns. You can customize the cells of those generated columns through the `cells` property of the `groupColumn` setting. Use `groupColumn.cells` to target the generated group column's own header cell, and the top-level `cells.groupFooter` to customize the footer cell of each data column.

The following example demonstrates a Grid in multiple-columns grouping mode with custom group header and footer cells that render aggregate values.

[Demo Source](https://demos.telerik.com/kendo-react-ui/grid/grouping/multi-columns-grouping-custom-header-footer/source.txt)

## Column-Level vs. Grid-Level Registration

The `cells` prop is available on both the `Grid` component and individual `GridColumn` components. When set on `Grid`, the custom cell applies to every column. When set on `GridColumn`, it applies only to that column and overrides the Grid-level setting for that column.

```tsx
{
    /* Applied to every column */
}
<Grid cells={{ headerCell: CustomHeaderCell }}>
    {/* Overrides only for this column */}
    <GridColumn field="UnitPrice" cells={{ footerCell: CustomUnitPriceFooterCell }} />
</Grid>;
```

## KendoReact Grid Custom Cells APIs

* [Grid Cells Prop](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridprops#cells)
* [GridColumn Cells Prop](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcolumnprops#cells)
* [API Reference of the GridCellsSettings](https://www.telerik.com/kendo-react-ui-develop/components/grid/api/gridcellssettings)

## Suggested Links

* [Grid Custom Cells Overview](https://www.telerik.com/kendo-react-ui-develop/components/grid/cells)
* [Grid Custom Edit Cells](https://www.telerik.com/kendo-react-ui-develop/components/grid/cells/edit-cells)
* [Grid Custom Hierarchy Cells](https://www.telerik.com/kendo-react-ui-develop/components/grid/cells/hierarchy-cells)
* [Grid Custom Group Cells](https://www.telerik.com/kendo-react-ui-develop/components/grid/cells/group-cells)
* [Grid Custom Selection Cells](https://www.telerik.com/kendo-react-ui-develop/components/grid/cells/selection-cells)
