bx

Table

A responsive table component.

StatusEmailAmount
Successken99@example.com$316.00
Successabe45@example.com$242.00
Processingmonserrat44@example.com$837.00
Failedcarmella@example.com$721.00
tsx
<div className="w-full max-w-2xl">
  <Table
    head={["Status", "Email", "Amount"]}
    rows={[
      ["Success", "ken99@example.com", "$316.00"],
      ["Success", "abe45@example.com", "$242.00"],
      ["Processing", "monserrat44@example.com", "$837.00"],
      ["Failed", "carmella@example.com", "$721.00"],
    ]}
  />
</div>

Table is a native HTML <table> with shadcn styling. It is composed of Table + TableHeader + TableBody + TableRow + TableHead (th) + TableCell (td) + optionally TableCaption. There is no TableFooter in this port: write a plain <tfoot> if you need one.

Shorthand: head, rows and caption build the whole table from arrays. The last column is right-aligned.

For server-side filtering / pagination / sorting, use DataTable, which extends Table with a toolbar.

Installation

Terminal
$ bext ui add table

Usage

tsx
import { Table } from "@bext-stack/ui/primitives"

// Shorthand
<Table
  head={["Status", "Email", "Amount"]}
  rows={[
    ["Success", "a@ex.com", "$316"],
    ["Failed", "b@ex.com", "$242"],
  ]}
/>

Anatomy

<Table>
  ├── <TableCaption>...</TableCaption>          // optional
  ├── <TableHeader>
  │   └── <TableRow>
  │       └── <TableHead>Column</TableHead>
  └── <TableBody>
      └── <TableRow>
          └── <TableCell>value</TableCell>

API Reference

Table

Prop Type Default Description
head string[] — Shorthand: generates TableHeader from an array of labels.
rows ReactNode[][] — Shorthand: generates TableBody from a matrix of cells.
caption string — Shorthand: adds a TableCaption. Used only together with head or rows.
children ReactNode — Composed form: TableCaption, TableHeader and TableBody.
className string — Extra classes on the scroll wrapper around the <table> (relative w-full overflow-auto).

TableHeader / TableBody

Prop Type Default Description
children ReactNode — The TableRows. Rendered as <thead> and <tbody>.

TableRow

Prop Type Default Description
className string — Extra classes on the <tr> (border-b, hover:bg-muted/50 by default).

TableHead

Prop Type Default Description
scope "col" | "row" | "colgroup" | "rowgroup" "col" scope attribute of the <th>. Use "row" for a header cell at the start of a body row.
children ReactNode — <th> styled with h-10 px-2 text-left align-middle font-medium.

TableCell

Prop Type Default Description
children ReactNode — <td> p-2 align-middle.

TableCaption

Prop Type Default Description
children ReactNode — <caption> shown below the table, text-sm muted.

Accessibility

The components render the native <table>, <thead>, <tbody>, <th> and <td> elements, so the table semantics come for free. Use TableCaption (or the caption shorthand) to name the table for assistive technologies.

TableHead renders <th scope="col">. For a header cell at the start of a body row pass scope="row"; for grouped headers, "colgroup" or "rowgroup". It forwards no other attribute (no colspan, no headers): write those cells by hand.

Try it live Open in play

Edit this example live in the bext playground. It compiles and runs entirely in your browser.

src/app/page.tsx 1 file · react · runs in your browser
The React idiom: same UI, for comparison.