Table
Table is a neobrutalist React component from Cruise UI. A fully bordered table with a --primary header row and zebra rows. Install it with npx shadcn@latest add @cruiseui/table.
Install
Terminal
npx shadcn@latest add @cruiseui/tableFirst time? Installation shows the one-off components.json setup (the @cruiseui registry) and how to turn the theme on.
Example
Corners
| Route | Fare | Status |
|---|---|---|
| Oshodi – CMS | ₦800 | Paid |
| Ikeja – Yaba | ₦600 | Pending |
| Ojota – Obalende | ₦1,000 | Overdue |
import type { ReactNode } from "react";
import { CruiseBadge } from "@/components/cruise/badge";
import { CruiseTable, type CruiseColumn } from "@/components/cruise/table";
type Row = { route: string; fare: string; status: ReactNode };
const columns: CruiseColumn<Row>[] = [
{ key: "route", header: "Route" },
{ key: "fare", header: "Fare", numeric: true },
{ key: "status", header: "Status" },
];
const rows: Row[] = [
{ route: "Oshodi – CMS", fare: "₦800", status: <CruiseBadge tone="success">Paid</CruiseBadge> },
{ route: "Ikeja – Yaba", fare: "₦600", status: <CruiseBadge tone="muted">Pending</CruiseBadge> },
{ route: "Ojota – Obalende", fare: "₦1,000", status: <CruiseBadge tone="danger">Overdue</CruiseBadge> },
];
export default function TableExample() {
return <CruiseTable columns={columns} rows={rows} rowKey={(row) => row.route} />;
}
<div class="brutal" style="overflow-x: auto">
<table style="width: 100%; border-collapse: collapse">
<thead class="on-primary"><tr><th style="border: 2px solid var(--ink); padding: 8px 12px; text-align: left">Route</th><th style="border: 2px solid var(--ink); padding: 8px 12px; text-align: right">Fare</th></tr></thead>
<tbody><tr><td style="border: 2px solid var(--ink); padding: 8px 12px">Oshodi – CMS</td><td style="border: 2px solid var(--ink); padding: 8px 12px; text-align: right">₦800</td></tr></tbody>
</table>
</div>Needs theme.css. Interactive parts (menus, tabs, drawers) also need the script in the spec for that component.
When to use it
When to use
Comparing rows of the same kind of data: orders, routes, invoices.
When not to
Layout. A single record (use a Card).
Props
CruiseTable
| Prop | Type | Default | Description |
|---|---|---|---|
columns | CruiseColumn<Row>[] | — | — |
rows | Row[] | — | — |
rowKey | (row: Row) => string | — | Stable React key per row. |
caption? | ReactNode | — | — |
className? | string | — | — |
Accessibility
- A real <table> with <th> headers; numbers are right-aligned.
- Scrolls sideways inside its box on small screens.