Recipes · Product
Data tables
A workspace members table with sticky header, striped rows, inline status badges, and empty-friendly design.
Preview
The exact composition below is what ships in production apps built on Nova.
| Name | Team | Role | Status |
|---|---|---|---|
| Ada Lovelace | Engineering | Owner | Active |
| Grace Hopper | Design | Admin | Active |
| Radia Perlman | Engineering | Member | Invited |
| Katherine Johnson | Product | Admin | Active |
Source
tsx
export function MembersTable({ rows }) { return ( <table className="w-full text-sm"> <thead className="bg-subtle/60 text-left"> <tr> <th>Name</th><th>Team</th><th>Role</th><th>Status</th> </tr> </thead> <tbody> {rows.map((r) => ( <tr key={r.id} className="border-t"> <td className="px-3 py-2 font-medium">{r.name}</td> <td className="px-3 py-2 text-muted-foreground">{r.team}</td> <td className="px-3 py-2 text-muted-foreground">{r.role}</td> <td className="px-3 py-2"> <Badge variant="outline" size="sm">{r.status}</Badge> </td> </tr> ))} </tbody> </table> );}Anatomy
- Header uses uppercase mono at 11px for a data-heavy feel.
- Row separators via 1px borders — never full-width strong dividers.
- Status column always uses Badge for consistent semantics.
- Wrap the table in overflow-x-auto for narrow viewports.