Zaidan

Command Palette

Search for a command to run...

GitHub

Table

A responsive table component.

Installation

CLI

Manual

Copy and paste the following code into your project.

import { type ComponentProps, splitProps } from "solid-js";
import { cn } from "~/lib/utils";
type TableProps = ComponentProps<"table">;
const Table = (props: TableProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div data-slot="table-container" class="z-table-container">
<table data-slot="table" class={cn("z-table", local.class)} {...others} />
</div>
);
};
type TableHeaderProps = ComponentProps<"thead">;
const TableHeader = (props: TableHeaderProps) => {
const [local, others] = splitProps(props, ["class"]);
return <thead data-slot="table-header" class={cn("z-table-header", local.class)} {...others} />;
};
type TableBodyProps = ComponentProps<"tbody">;
const TableBody = (props: TableBodyProps) => {
const [local, others] = splitProps(props, ["class"]);
return <tbody data-slot="table-body" class={cn("z-table-body", local.class)} {...others} />;
};
type TableFooterProps = ComponentProps<"tfoot">;
const TableFooter = (props: TableFooterProps) => {
const [local, others] = splitProps(props, ["class"]);
return <tfoot data-slot="table-footer" class={cn("z-table-footer", local.class)} {...others} />;
};
type TableRowProps = ComponentProps<"tr">;
const TableRow = (props: TableRowProps) => {
const [local, others] = splitProps(props, ["class"]);
return <tr data-slot="table-row" class={cn("z-table-row", local.class)} {...others} />;
};
type TableHeadProps = ComponentProps<"th">;
const TableHead = (props: TableHeadProps) => {
const [local, others] = splitProps(props, ["class"]);
return <th data-slot="table-head" class={cn("z-table-head", local.class)} {...others} />;
};
type TableCellProps = ComponentProps<"td">;
const TableCell = (props: TableCellProps) => {
const [local, others] = splitProps(props, ["class"]);
return <td data-slot="table-cell" class={cn("z-table-cell", local.class)} {...others} />;
};
type TableCaptionProps = ComponentProps<"caption">;
const TableCaption = (props: TableCaptionProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<caption data-slot="table-caption" class={cn("z-table-caption", local.class)} {...others} />
);
};
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };

Data Table

You can use the <Table /> component to build more complex data tables. Combine it with @tanstack/solid-table to create tables with sorting, filtering and pagination.

Examples

Here are the source code of all the examples from the preview page:

Basic

import { For } from "solid-js";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableBasic() {
return (
<Example title="Basic">
<Table>
<TableCaption>A list of your recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead class="w-[100px]">Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead>Method</TableHead>
<TableHead class="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={invoices.slice(0, 3)}>
{(invoice) => (
<TableRow>
<TableCell class="font-medium">{invoice.invoice}</TableCell>
<TableCell>{invoice.paymentStatus}</TableCell>
<TableCell>{invoice.paymentMethod}</TableCell>
<TableCell class="text-right">{invoice.totalAmount}</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
</Example>
);
}
import { For } from "solid-js";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableWithFooter() {
return (
<Example title="With Footer">
<Table>
<TableCaption>A list of your recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead class="w-[100px]">Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead>Method</TableHead>
<TableHead class="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={invoices.slice(0, 3)}>
{(invoice) => (
<TableRow>
<TableCell class="font-medium">{invoice.invoice}</TableCell>
<TableCell>{invoice.paymentStatus}</TableCell>
<TableCell>{invoice.paymentMethod}</TableCell>
<TableCell class="text-right">{invoice.totalAmount}</TableCell>
</TableRow>
)}
</For>
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={3}>Total</TableCell>
<TableCell class="text-right">$2,500.00</TableCell>
</TableRow>
</TableFooter>
</Table>
</Example>
);
}

Simple

import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableSimple() {
return (
<Example title="Simple">
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead class="text-right">Role</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell class="font-medium">Sarah Chen</TableCell>
<TableCell>sarah.chen@acme.com</TableCell>
<TableCell class="text-right">Admin</TableCell>
</TableRow>
<TableRow>
<TableCell class="font-medium">Marc Rodriguez</TableCell>
<TableCell>marcus.rodriguez@acme.com</TableCell>
<TableCell class="text-right">User</TableCell>
</TableRow>
<TableRow>
<TableCell class="font-medium">Emily Watson</TableCell>
<TableCell>emily.watson@acme.com</TableCell>
<TableCell class="text-right">User</TableCell>
</TableRow>
</TableBody>
</Table>
</Example>
);
}

With Badges

import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableWithBadges() {
return (
<Example title="With Badges">
<Table>
<TableHeader>
<TableRow>
<TableHead>Task</TableHead>
<TableHead>Status</TableHead>
<TableHead class="text-right">Priority</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell class="font-medium">Design homepage</TableCell>
<TableCell>
<span class="inline-flex items-center rounded-full bg-green-500/10 px-2 py-1 font-medium text-green-700 text-xs dark:text-green-400">
Completed
</span>
</TableCell>
<TableCell class="text-right">
<span class="inline-flex items-center rounded-full bg-blue-500/10 px-2 py-1 font-medium text-blue-700 text-xs dark:text-blue-400">
High
</span>
</TableCell>
</TableRow>
<TableRow>
<TableCell class="font-medium">Implement API</TableCell>
<TableCell>
<span class="inline-flex items-center rounded-full bg-yellow-500/10 px-2 py-1 font-medium text-xs text-yellow-700 dark:text-yellow-400">
In Progress
</span>
</TableCell>
<TableCell class="text-right">
<span class="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 font-medium text-gray-700 text-xs dark:text-gray-400">
Medium
</span>
</TableCell>
</TableRow>
<TableRow>
<TableCell class="font-medium">Write tests</TableCell>
<TableCell>
<span class="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 font-medium text-gray-700 text-xs dark:text-gray-400">
Pending
</span>
</TableCell>
<TableCell class="text-right">
<span class="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 font-medium text-gray-700 text-xs dark:text-gray-400">
Low
</span>
</TableCell>
</TableRow>
</TableBody>
</Table>
</Example>
);
}

With Actions

import { MoreHorizontal } from "lucide-solid";
import { For } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableWithActions() {
const products = [
{ name: "Wireless Mouse", price: "$29.99" },
{ name: "Mechanical Keyboard", price: "$129.99" },
{ name: "USB-C Hub", price: "$49.99" },
];
return (
<Example title="With Actions">
<Table>
<TableHeader>
<TableRow>
<TableHead>Product</TableHead>
<TableHead>Price</TableHead>
<TableHead class="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={products}>
{(product) => (
<TableRow>
<TableCell class="font-medium">{product.name}</TableCell>
<TableCell>{product.price}</TableCell>
<TableCell class="text-right">
<DropdownMenu placement="bottom-end">
<DropdownMenuTrigger as={Button} variant="ghost" size="icon" class="size-8">
<MoreHorizontal />
<span class="sr-only">Open menu</span>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
</Example>
);
}

With Select

import { For } from "solid-js";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "~/components/ui/select";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableWithSelect() {
return (
<Example title="With Select">
<Table>
<TableHeader>
<TableRow>
<TableHead>Task</TableHead>
<TableHead>Assignee</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={tasks}>
{(item) => (
<TableRow>
<TableCell class="font-medium">{item.task}</TableCell>
<TableCell>
<Select
options={people}
optionValue="value"
optionTextValue="label"
defaultValue={people.find((person) => person.value === item.assignee)}
itemComponent={(props) => (
<SelectItem item={props.item}>{props.item.rawValue.label}</SelectItem>
)}
>
<SelectTrigger class="w-40" size="sm">
<SelectValue<(typeof people)[number]>>
{(state) => state.selectedOption()?.label}
</SelectValue>
</SelectTrigger>
<SelectContent />
</Select>
</TableCell>
<TableCell>{item.status}</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
</Example>
);
}

With Input

import { For } from "solid-js";
import { Input } from "~/components/ui/input";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "~/components/ui/table";
function TableWithInput() {
const products = [
{ name: "Wireless Mouse", price: "$29.99" },
{ name: "Mechanical Keyboard", price: "$129.99" },
{ name: "USB-C Hub", price: "$49.99" },
];
return (
<Example title="With Input">
<Table>
<TableHeader>
<TableRow>
<TableHead>Product</TableHead>
<TableHead>Quantity</TableHead>
<TableHead>Price</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={products}>
{(product, index) => (
<TableRow>
<TableCell class="font-medium">{product.name}</TableCell>
<TableCell>
<Input type="number" value={index() === 1 ? "2" : "1"} class="h-8 w-20" min="0" />
</TableCell>
<TableCell>{product.price}</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
</Example>
);
}