Table
Composable data table with head, body, row, header, and cell sub-components — supports striped rows and hoverable styling.
Preview
Basic table
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from '@/registry/ui-kit/tailwind-table/react'
function Example() {
return (
<Table>
<TableHead>
<TableRow>
<TableHeader>Name</TableHeader>
<TableHeader>Email</TableHeader>
<TableHeader>Role</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Alice Johnson</TableCell>
<TableCell>alice@example.com</TableCell>
<TableCell>Admin</TableCell>
</TableRow>
</TableBody>
</Table>
)
}Striped table
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from '@/registry/ui-kit/tailwind-table/react'
function Example() {
return (
<Table striped>
<TableHead>
<TableRow>
<TableHeader>Name</TableHeader>
<TableHeader>Email</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Alice</TableCell>
<TableCell>alice@example.com</TableCell>
</TableRow>
<TableRow>
<TableCell>Bob</TableCell>
<TableCell>bob@example.com</TableCell>
</TableRow>
</TableBody>
</Table>
)
}Component API
| Prop | Default | Description |
|---|---|---|
Table | — | Root wrapper with overflow-x-auto scroll container. |
striped | false | Adds alternating row background colors. |
hoverable | false | Adds hover highlight on rows. |
TableHead | — | The <thead> element. |
TableBody | — | The <tbody> with divide-y styling. |
TableRow | — | A <tr> row element. |
TableHeader | — | A <th> header cell with uppercase tracking. |
TableCell | — | A <td> data cell. |
Source Code
"use client";
import { createContext, forwardRef, useContext } from "react";
/* ── Context ── */
interface TableContextValue {
striped: boolean;
hoverable: boolean;
}
const TableContext = createContext<TableContextValue>({ striped: false, hoverable: false });
function useTableContext() {
return useContext(TableContext);
}
/* ── Table ── */
interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
striped?: boolean;
hoverable?: boolean;
}
const Table = forwardRef<HTMLTableElement, TableProps>(
({ striped = false, hoverable = false, className = "", children, ...props }, ref) => (
<TableContext.Provider value={{ striped, hoverable }}>
<div className="overflow-x-auto">
<table
ref={ref}
className={`min-w-full divide-y divide-zinc-200 dark:divide-zinc-800 ${className}`}
{...props}
>
{children}
</table>
</div>
</TableContext.Provider>
)
);
Table.displayName = "Table";
/* ── TableHead ── */
const TableHead = forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className = "", children, ...props }, ref) => (
<thead ref={ref} className={className} {...props}>
{children}
</thead>
)
);
TableHead.displayName = "TableHead";
/* ── TableBody ── */
const TableBody = forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className = "", children, ...props }, ref) => {
const { striped } = useTableContext();
const stripedStyles = striped
? "[&>tr:nth-child(even)]:bg-zinc-50 dark:[&>tr:nth-child(even)]:bg-zinc-800/50"
: "";
return (
<tbody
ref={ref}
className={`divide-y divide-zinc-100 dark:divide-zinc-800 ${stripedStyles} ${className}`}
{...props}
>
{children}
</tbody>
);
}
);
TableBody.displayName = "TableBody";
/* ── TableRow ── */
const TableRow = forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
({ className = "", children, ...props }, ref) => {
const { hoverable } = useTableContext();
const hoverStyles = hoverable ? "hover:bg-zinc-50 dark:hover:bg-zinc-800/50" : "";
return (
<tr ref={ref} className={`${hoverStyles} ${className}`} {...props}>
{children}
</tr>
);
}
);
TableRow.displayName = "TableRow";
/* ── TableHeader ── */
const TableHeader = forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
({ className = "", children, ...props }, ref) => (
<th
ref={ref}
className={`px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400 ${className}`}
{...props}
>
{children}
</th>
)
);
TableHeader.displayName = "TableHeader";
/* ── TableCell ── */
const TableCell = forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
({ className = "", children, ...props }, ref) => (
<td
ref={ref}
className={`whitespace-nowrap px-4 py-3 text-sm text-zinc-900 dark:text-zinc-100 ${className}`}
{...props}
>
{children}
</td>
)
);
TableCell.displayName = "TableCell";
export { Table, TableHead, TableBody, TableRow, TableHeader, TableCell };
export default Table;