Table recipe
Custom cells
Compose grouped headers, progress, status, alignment, and a pinned identity column.
RenderingGroupsPinning
Interactive, production component
tsx
import { DataTable } from "../../Datatable";
import type { ColumnSetting } from "../../Datatable";
import { products, type ProductRow } from "./exampleData";
import type { ExampleProps } from "./types";
function FlagThumb({ code }: { code: string }) {
const c = code.toLowerCase();
return (
<span className="example-flag">
<img
src={`https://flagcdn.com/w40/${c}.png`}
alt=""
width={24}
height={16}
loading="lazy"
decoding="async"
/>
<span>{c.toUpperCase()}</span>
</span>
);
}
const columns: ColumnSetting<ProductRow>[] = [
{
id: "thumb",
title: "",
width: 56,
align: "center",
headerAlign: "center",
enableSorting: false,
cell: ({ row }) => (
<img
className="example-thumb"
src={row.thumb}
alt=""
width={32}
height={32}
loading="lazy"
/>
),
},
{ id: "product", title: "Product", groupTitle: "Catalog", width: 200, pinned: "left" },
{ id: "brand", title: "Brand", groupTitle: "Catalog", width: 100 },
{ id: "category", title: "Category", groupTitle: "Catalog", width: 120 },
{ id: "subcategory", title: "Line", groupTitle: "Catalog", width: 100 },
{
id: "countryCode",
title: "Market",
groupTitle: "Logistics",
width: 120,
cell: ({ value }) => <FlagThumb code={String(value)} />,
},
{ id: "warehouse", title: "Warehouse", groupTitle: "Logistics", width: 110 },
{ id: "region", title: "Region", groupTitle: "Logistics", width: 90 },
{
id: "stock",
title: "Inventory",
groupTitle: "Health",
width: 160,
filterType: "number",
cell: ({ value }) => {
const stock = Number(value);
return (
<div className="example-stock">
<span>
<i style={{ width: `${Math.min(stock, 100)}%` }} />
</span>
<strong>{stock}</strong>
</div>
);
},
},
{ id: "reserved", title: "Reserved", groupTitle: "Health", width: 100, align: "right", filterType: "number" },
{
id: "status",
title: "Status",
groupTitle: "Health",
width: 110,
align: "center",
headerAlign: "center",
cell: ({ value }) => (
<span className={`example-status is-${String(value).toLowerCase()}`}>
{String(value)}
</span>
),
},
{
id: "price",
title: "Unit price",
groupTitle: "Commerce",
width: 110,
align: "right",
cell: ({ value }) => (
<strong className="example-price">${Number(value).toFixed(2)}</strong>
),
},
{
id: "margin",
title: "Margin %",
groupTitle: "Commerce",
width: 100,
align: "right",
cell: ({ value }) => `${Number(value).toFixed(1)}%`,
},
{ id: "rating", title: "Rating", groupTitle: "Commerce", width: 90, align: "right" },
{ id: "reviews", title: "Reviews", groupTitle: "Commerce", width: 100, align: "right" },
{ id: "owner", title: "Owner", groupTitle: "Team", width: 130 },
{ id: "updatedAt", title: "Updated", groupTitle: "Team", width: 110 },
{ id: "sku", title: "SKU", groupTitle: "Catalog", width: 110 },
{ id: "cost", title: "Cost", groupTitle: "Commerce", width: 100, align: "right" },
{ id: "reorderAt", title: "Reorder at", groupTitle: "Health", width: 110, align: "right" },
];
export default function CustomCellsExample({ theme }: ExampleProps) {
return (
<DataTable
theme={theme}
title="Inventory overview"
dataSource={products}
columnSettings={columns}
maxHeight={480}
enablePagination
enableColumnResizing
enableRowIndex
enableRowSelection
enableMultiRowSelection
/>
);
}
Related API