primitives
DSTable
Product-grade list table with sticky header, sortable columns, optional pagination and row-selection state. The default choice for any /list page.
Flush-with-page chrome: no outer border, no row fills, no card wrap — hairline `border-b` separators only. Mono-caps column headers. Cells are flush with the page gutters by design (`first:pl-0 last:pr-0`), so the surrounding container should provide the side padding.
Install
Pull this component (and its dependencies) straight into your app via the shadcn CLI:
npx shadcn@latest add https://design.oapps.io/r/ds-table.jsonOr import from the workspace package:
import { DSTable, DSTableColumn, SortDir } from "@8maverik8/design";Examples
Three rows, two sortable columns
const columns: DSTableColumn<Row>[] = [
{ id: "name", header: "Name", sortKey: "name", cell: (r) => r.name },
{ id: "status", header: "Status", cell: (r) => r.status },
{ id: "resources", header: "Resources", sortKey: "resources",
cell: (r) => r.resources.toString(), cellClassName: "tabular-nums" },
];
<DSTable columns={columns} data={data} rowKey={(r) => r.id} />Anatomy
columnsColumn descriptors. `cell(row)` returns the JSX for that cell.rowKeyExtracts a stable id per row (used as React key).sortKey / sortDir / onSortWire up controlled sort. The header auto-renders the sort affordance.pagination props`totalCount / currentPage / totalPages / pageSize / onPageChange / onPageSizeChange` — pass all six to enable the footer pagination.isRowSelectedVisually highlight a row (e.g. when its detail panel is open).
Guidelines
- Make the lead-column cell the click target (e.g. wrap the name in a Link).Rows themselves are not clickable in this design — clicks live on the leading cell.
- Add row-level hover background.The table is borderless on the sides; a hover bar reads as a misaligned stripe.
- Provide a `description` per column when the header text isn't self-explanatory — it'll show as a tooltip on hover.