Table
The Table component displays structured data in rows and columns. It provides components for defining the table, header, body, rows, and cells while supporting dense layouts, selected rows, and cell alignment.
A basic Table can be used to display tabular data with a header and multiple rows.
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const users = [
{
name: "Olivia Martin",
email: "olivia@example.com",
role: "Admin",
status: "Active",
joined: "Jan 12, 2025",
},
{
name: "Jackson Lee",
email: "jackson@example.com",
role: "Member",
status: "Active",
joined: "Feb 08, 2025",
},
{
name: "Sophia Brown",
email: "sophia@example.com",
role: "Member",
status: "Inactive",
joined: "Mar 21, 2025",
},
];
export default function Example() {
return (
<div class="w-full overflow-x-auto">
<Table class="min-w-200">
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Role</TableCell>
<TableCell>Status</TableCell>
<TableCell>Joined</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.map((user) => (
<TableRow>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.role}</TableCell>
<TableCell>{user.status}</TableCell>
<TableCell>{user.joined}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}Examples
Dense
Use the dense prop to reduce the spacing within table rows and cells
when displaying a larger amount of data.
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const users = [
{ name: "Olivia Martin", email: "olivia@example.com", role: "Admin" },
{ name: "Jackson Lee", email: "jackson@example.com", role: "Member" },
{ name: "Sophia Brown", email: "sophia@example.com", role: "Member" },
{ name: "Noah Wilson", email: "noah@example.com", role: "Member" },
];
export default function Example() {
return (
<Table dense>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Role</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.map((user) => (
<TableRow>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.role}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}Selected Row
Use the selected prop on TableRow to indicate the currently selected
row.
import { createSignal, For } from "solid-js";
import Checkbox from "rocksolidjs/Checkbox";
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const users = [
{ id: 1, name: "Olivia Martin", email: "olivia@example.com", role: "Admin" },
{ id: 2, name: "Jackson Lee", email: "jackson@example.com", role: "Member" },
{ id: 3, name: "Sophia Brown", email: "sophia@example.com", role: "Member" },
];
export default function Example() {
const [selected, setSelected] = createSignal<number[]>([]);
const toggleRow = (id: number) => {
setSelected((current) =>
current.includes(id)
? current.filter((selectedId) => selectedId !== id)
: [...current, id],
);
};
const handleSelectAll = (e: Event) => {
if ((e.currentTarget as HTMLInputElement).checked) {
setSelected(users.map(user => user.id));
} else {
setSelected([]);
}
};
return (
<Table>
<TableHead>
<TableRow>
<TableCell class="w-12">
<Checkbox
aria-label="Select all users"
checked={selected().length === users.length}
onChange={handleSelectAll}
/>
</TableCell>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Role</TableCell>
</TableRow>
</TableHead>
<TableBody>
<For each={users}>
{(user) => (
<TableRow selected={selected().includes(user.id)}>
<TableCell>
<Checkbox
checked={selected().includes(user.id)}
onChange={() => toggleRow(user.id)}
aria-label={`Select ${user.name}`}
/>
</TableCell>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.role}</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
);
}Cell Alignment
Use the align prop on TableCell to control the horizontal alignment
of cell content.
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const orders = [
{ product: "Wireless Headphones", quantity: 2, price: "$199.00" },
{ product: "Mechanical Keyboard", quantity: 1, price: "$149.00" },
{ product: "USB-C Hub", quantity: 3, price: "$89.00" },
];
export default function Example() {
return (
<Table>
<TableHead>
<TableRow>
<TableCell align="left">Product</TableCell>
<TableCell align="right">Quantity</TableCell>
<TableCell align="right">Price</TableCell>
</TableRow>
</TableHead>
<TableBody>
{orders.map((order) => (
<TableRow>
<TableCell align="left">{order.product}</TableCell>
<TableCell align="right">{order.quantity}</TableCell>
<TableCell align="right">{order.price}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}Footer
Use TableFooter to display summary information, totals, or other
content associated with the table data.
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableFooter from "rocksolidjs/TableFooter";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const orders = [
{ product: "Wireless Headphones", quantity: 2, total: "$398.00" },
{ product: "Mechanical Keyboard", quantity: 1, total: "$149.00" },
{ product: "USB-C Hub", quantity: 3, total: "$267.00" },
];
export default function Example() {
const total = orders.reduce(
(sum, order) => sum + Number(order.total.replace("$", "")),
0,
);
return (
<Table>
<TableHead>
<TableRow>
<TableCell>Product</TableCell>
<TableCell align="right">Quantity</TableCell>
<TableCell align="right">Total</TableCell>
</TableRow>
</TableHead>
<TableBody>
{orders.map((order) => (
<TableRow>
<TableCell>{order.product}</TableCell>
<TableCell align="right">{order.quantity}</TableCell>
<TableCell align="right">{order.total}</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter class="bg-neutral-100 dark:bg-neutral-900">
<TableRow>
<TableCell class="font-semibold">Total</TableCell>
<TableCell align="right" class="font-semibold">
{orders.reduce((sum, order) => sum + order.quantity, 0)}
</TableCell>
<TableCell align="right" class="font-semibold">
${total.toFixed(2)}
</TableCell>
</TableRow>
</TableFooter>
</Table>
);
}Custom Styling
Use the class prop on Table components to add custom CSS classes.
import Table from "rocksolidjs/Table";
import TableBody from "rocksolidjs/TableBody";
import TableCell from "rocksolidjs/TableCell";
import TableHead from "rocksolidjs/TableHead";
import TableRow from "rocksolidjs/TableRow";
const orders = [
{
id: "#1024",
customer: "Olivia Martin",
product: "Wireless Headphones",
status: "Completed",
total: "$398.00",
},
{
id: "#1025",
customer: "Jackson Lee",
product: "Mechanical Keyboard",
status: "Processing",
total: "$149.00",
},
{
id: "#1026",
customer: "Sophia Brown",
product: "USB-C Hub",
status: "Pending",
total: "$267.00",
},
];
export default function CustomStyling() {
return (
<Table class="rounded-lg shadow-sm">
<TableHead class="bg-muted/50">
<TableRow>
<TableCell class="font-semibold">Order</TableCell>
<TableCell class="font-semibold">Customer</TableCell>
<TableCell class="font-semibold">Product</TableCell>
<TableCell class="font-semibold">Status</TableCell>
<TableCell align="right" class="font-semibold">
Total
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{orders.map((order) => (
<TableRow class="hover:bg-neutral-100/80 dark:hover:bg-neutral-900">
<TableCell class="font-medium">{order.id}</TableCell>
<TableCell>{order.customer}</TableCell>
<TableCell>{order.product}</TableCell>
<TableCell>{order.status}</TableCell>
<TableCell align="right" class="font-medium">
{order.total}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}Accessibility
- Use
TableHeadfor column headings andTableBodyfor table data. - Keep column headings concise and descriptive.
- Use
TableCellfor both header and data cells. Header cells are automatically rendered asthelements when used insideTableHead. - Use
selectedto provide a visual indication of the selected row, but ensure the selection state is also understandable without relying on color alone. - Keep the table structure consistent so that assistive technologies can correctly understand the relationship between headers and cells.
API
Table
The Table component supports dense layouts and custom styling.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| class | string |
No | — | Adds custom CSS classes to the table. |
| dense | boolean |
No | false |
Reduces the spacing within the table for a more compact layout. |
TableHead
The TableHead component defines the header section of a table.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| class | string |
No | — | Adds custom CSS classes to the table header. |
TableBody
The TableBody component defines the body section of a table.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| class | string |
No | — | Adds custom CSS classes to the table body. |
TableRow
The TableRow component represents a row within the table and can indicate a selected state.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| class | string |
No | — | Adds custom CSS classes to the table row. |
| selected | boolean |
No | false |
Indicates whether the row is selected. |
TableCell
The TableCell component represents a header or data cell. When used
inside TableHead, it is automatically rendered as a th element.
Otherwise, it renders as a td element.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| as | "th" | "td" |
No | Automatic | Controls the HTML element used for the cell. Defaults to th inside TableHead and td otherwise. |
| class | string |
No | — | Adds custom CSS classes to the table cell. |
| align | "left" | "center" | "right" | "justify" |
No | "left" |
Controls the horizontal alignment of the cell content. |
TableFooter
The TableFooter component defines the footer section of a table. It can be used to display summary information, totals, or other content related to the table data.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| class | string |
No | — | Adds custom CSS classes to the table footer. |
Related Components
- Checkbox — Use for row selection or bulk selection within a table.