| Subject | From | Date |
|---|---|---|
| Kumo v1.0.0 released | Visal In | 5 seconds ago |
| New Job Offer | Cloudflare | 10 minutes ago |
| Daily Email Digest | Cloudflare | 1 hour ago |
<Table>
<Table.Header>
<Table.Row>
<Table.Head>Subject</Table.Head>
<Table.Head>From</Table.Head>
<Table.Head>Date</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Kumo v1.0.0 released</Table.Cell>
<Table.Cell>Visal In</Table.Cell>
<Table.Cell>5 seconds ago</Table.Cell>
</Table.Row>
</Table.Body>
</Table> Installation
Barrel
import { Table } from "@cloudflare/kumo"; Granular
import { Table } from "@cloudflare/kumo/components/table"; Usage
import { Table, LayerCard } from "@cloudflare/kumo";
export default function Example() {
return (
<LayerCard>
<LayerCard.Primary className="p-0">
<Table>
<Table.Header>
<Table.Row>
<Table.Head>Name</Table.Head>
<Table.Head>Email</Table.Head>
<Table.Head>Role</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>John Doe</Table.Cell>
<Table.Cell>john@example.com</Table.Cell>
<Table.Cell>Admin</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</LayerCard.Primary>
</LayerCard>
);
} Examples
With Checkboxes
Add row selection with Table.CheckHead and Table.CheckCell.
| Subject | From | Date | |
|---|---|---|---|
| Kumo v1.0.0 released | Visal In | 5 seconds ago | |
| New Job Offer | Cloudflare | 10 minutes ago | |
| Daily Email Digest | Cloudflare | 1 hour ago |
<Table>
<Table.Header>
<Table.Row>
<Table.CheckHead />
<Table.Head>Subject</Table.Head>
<Table.Head>From</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.CheckCell />
<Table.Cell>Email subject</Table.Cell>
<Table.Cell>Sender name</Table.Cell>
</Table.Row>
</Table.Body>
</Table> Selected Row
Use variant="selected" on Table.Row to highlight selected rows.
| Subject | From | Date | |
|---|---|---|---|
| Kumo v1.0.0 released | Visal In | 5 seconds ago | |
| New Job Offer | Cloudflare | 10 minutes ago | |
| Daily Email Digest | Cloudflare | 1 hour ago |
<Table.Row variant="selected">
<Table.CheckCell checked />
<Table.Cell>Selected row</Table.Cell>
</Table.Row> Fixed Layout with Column Sizes
For precise control over column widths, set layout="fixed" and use colgroup with col elements.
| Subject | From | Date |
|---|---|---|
| Kumo v1.0.0 released | Visal In | 5 seconds ago |
| New Job Offer | Cloudflare | 10 minutes ago |
| Daily Email Digest | Cloudflare | 1 hour ago |
| GitLab - New Comment | Rob Knecht | 1 day ago |
| Out of Office | Johnnie Lappen | 3 days ago |
<Table layout="fixed">
<colgroup>
<col />
<col className="w-[150px]" />
<col className="w-[150px]" />
</colgroup>
<Table.Header>
<Table.Row>
<Table.Head>Subject</Table.Head>
<Table.Head>From</Table.Head>
<Table.Head>Date</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{data.map((row) => (
<Table.Row key={row.id}>
<Table.Cell>{row.subject}</Table.Cell>
<Table.Cell>{row.from}</Table.Cell>
<Table.Cell>{row.date}</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table> Full Example
Complete table with checkboxes, badges, action buttons, and fixed column widths.
| Subject | From | Date | ||
|---|---|---|---|---|
Kumo v1.0.0 released | Visal In | 5 seconds ago | ||
New Job Offer | Cloudflare | 10 minutes ago | ||
Daily Email Digest promotion | Cloudflare | 1 hour ago | ||
GitLab - New Comment | Rob Knecht | 1 day ago | ||
Out of Office | Johnnie Lappen | 3 days ago |
<Table layout="fixed">
<colgroup>
<col style={{ width: "40px" }} />
<col />
<col style={{ width: "150px" }} />
<col style={{ width: "120px" }} />
<col style={{ width: "50px" }} />
</colgroup>
<Table.Header>
<Table.Row>
<Table.CheckHead />
<Table.Head>Subject</Table.Head>
<Table.Head>From</Table.Head>
<Table.Head>Date</Table.Head>
<Table.Head></Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{data.map((row) => (
<Table.Row key={row.id} variant={row.selected ? "selected" : "default"}>
<Table.CheckCell checked={row.selected} />
<Table.Cell>
<div className="flex items-center gap-2">
<EnvelopeSimple size={16} />
{row.subject}
{row.tags?.map((tag) => <Badge key={tag}>{tag}</Badge>)}
</div>
</Table.Cell>
<Table.Cell>{row.from}</Table.Cell>
<Table.Cell>{row.date}</Table.Cell>
<Table.Cell className="text-right">
<Button variant="ghost" size="sm" shape="square">
<DotsThree weight="bold" size={16} />
</Button>
</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table> API Reference
Table
Root table component. Renders a semantic <table> element.
| Prop | Type | Default | Description |
|---|---|---|---|
| layout | "auto" | "fixed" | "auto" | - |
| variant | "default" | "selected" | "default" | - |
| className | string | - | Additional CSS classes |
| children | ReactNode | - | Child elements |
Table.Header
Table header section. Renders <thead>.
Table.Body
Table body section. Renders <tbody>.
Table.Row
Table row. Supports variant="selected" for highlighting.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
Table.Head
Header cell. Renders <th>.
Table.Cell
Body cell. Renders <td>.
Table.CheckHead
Header cell with checkbox for "select all" functionality.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
Table.CheckCell
Body cell with checkbox for row selection.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
Table.ResizeHandle
Draggable handle for column resizing. Use with TanStack Table or custom resize logic.
TanStack Table Integration
For advanced features like sorting, filtering, and resizable columns, integrate with TanStack Table. The Table component is designed to work seamlessly with TanStack's headless API.
import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { Table } from "@cloudflare/kumo";
function DataTable({ data, columns }) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
columnResizeMode: "onChange",
});
return (
<Table layout="fixed">
<colgroup>
{table.getAllColumns().map((column) => (
<col key={column.id} style={{ width: column.getSize() }} />
))}
</colgroup>
<Table.Header>
{table.getHeaderGroups().map((headerGroup) => (
<Table.Row key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<Table.Head key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
<Table.ResizeHandle
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
/>
</Table.Head>
))}
</Table.Row>
))}
</Table.Header>
<Table.Body>
{table.getRowModel().rows.map((row) => (
<Table.Row key={row.id}>
{row.getVisibleCells().map((cell) => (
<Table.Cell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</Table.Cell>
))}
</Table.Row>
))}
</Table.Body>
</Table>
);
} Accessibility
Semantic HTML
Table uses semantic <table>, <thead>, <tbody>, <th>, and <td> elements for proper screen reader navigation.
Checkbox Labels
Always provide aria-label for Table.CheckHead and Table.CheckCell to describe their purpose.
Keyboard Navigation
Tab moves focus through interactive elements. Checkboxes respond to Space.