Table
Structured tabular data.
Preview
| Component | Category | Status |
|---|---|---|
| Button | Actions | Stable |
| Dialog | Overlay | Stable |
Code
import {
Table, TableBody, TableCaption, TableCell,
TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
export function Example() {
return (
<Table>
<TableCaption>System components</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Component</TableHead>
<TableHead>Category</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Button</TableCell>
<TableCell>Actions</TableCell>
<TableCell>Stable</TableCell>
</TableRow>
</TableBody>
</Table>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Additional Tailwind classes, merged with the component's defaults via cn(). |
Sub-components
TableHeader— `<thead>` wrapper.TableBody— `<tbody>` wrapper.TableFooter— `<tfoot>` wrapper.TableRow— Row with hover styling.TableHead— Header cell.TableCell— Body cell.TableCaption— Accessible caption.Plain HTML table primitives with PRIZM styling. No sorting / virtualization — bring your own.
All components also accept standard HTML attributes for their root element (e.g. `id`, `aria-*`, `data-*`, event handlers) and forward `ref` where applicable.
Source
The full implementation of components/ui/table.tsx is below — copy it into your project and own it. Some components import the cn helper from lib/utils or other primitives; copy those too.
import { cn } from "@/lib/utils";
import {
type HTMLAttributes,
type TdHTMLAttributes,
type ThHTMLAttributes,
forwardRef,
} from "react";
export const Table = forwardRef<HTMLTableElement, HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => (
<div className="w-full overflow-x-auto">
<table ref={ref} className={cn("w-full caption-bottom text-sm", className)} {...props} />
</div>
),
);
Table.displayName = "Table";
export const TableHeader = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn("[&_tr]:border-b [&_tr]:border-border", className)} {...props} />
));
TableHeader.displayName = "TableHeader";
export const TableBody = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
));
TableBody.displayName = "TableBody";
export const TableFooter = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn("border-t border-border bg-bg-muted/50 font-medium", className)}
{...props}
/>
));
TableFooter.displayName = "TableFooter";
export const TableRow = forwardRef<HTMLTableRowElement, HTMLAttributes<HTMLTableRowElement>>(
({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn(
"border-b border-border transition-colors hover:bg-bg-muted/50 data-[state=selected]:bg-bg-muted",
className,
)}
{...props}
/>
),
);
TableRow.displayName = "TableRow";
export const TableHead = forwardRef<HTMLTableCellElement, ThHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
"h-10 px-3 text-left align-middle text-xs font-semibold text-fg-muted",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
className,
)}
{...props}
/>
),
);
TableHead.displayName = "TableHead";
export const TableCell = forwardRef<HTMLTableCellElement, TdHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<td
ref={ref}
className={cn(
"px-3 py-2.5 align-middle text-sm text-fg",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
className,
)}
{...props}
/>
),
);
TableCell.displayName = "TableCell";
export const TableCaption = forwardRef<
HTMLTableCaptionElement,
HTMLAttributes<HTMLTableCaptionElement>
>(({ className, ...props }, ref) => (
<caption ref={ref} className={cn("mt-4 text-sm text-fg-muted", className)} {...props} />
));
TableCaption.displayName = "TableCaption";JavaFX
Ships in the PRIZM JavaFX library for thick-client C3 apps as PrizmTable<T> (extends TableView<T>). Run the gallery to see it natively.
import design.prizm.fx.controls.PrizmTable<T>;
PrizmTable()
PrizmTable(ObservableList<T> items)| Prop | Type | Default | Description |
|---|---|---|---|
| items | ObservableList<T> | — | Row data — set via setItems / getItems().addAll(...). |
| columns | ObservableList<TableColumn<T, ?>> | — | Add TableColumns with cell-value factories via getColumns(). |
Thin subclass of TableView; header / row separators / hover / selection styled by the .prizm-table rules. PARADIGM NOTE: the web Table is compositional (hand-written rows/cells); JavaFX is data-driven (items + TableColumns) — the API differs by design, only the visual styling is in parity. Mirrors components/ui/table.tsx.