Table
Composable data table with semantic sections and glass variant support.
pnpm dlx @glinui/cli@latest add table| Client | Status | Amount | Actions | |
|---|---|---|---|---|
INV-2041Due Oct 02 | NSNorthwind Studio | Paid | $1,240.00 | |
INV-2040Due Oct 14 | FLFabrikam Labs | Pending | $3,890.00 | |
INV-2039Due Sep 21 | CHContoso Health | Overdue | $620.50 | |
INV-2038Due Sep 18 | TTTailspin Toys | Paid | $2,115.00 |
Installation
pnpm dlx @glinui/cli@latest add tablePrefer the package?
Usage
Variants
Every vocabulary variant on the default tone. Omit variant to follow the ambient design style.
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
| Name | Status |
|---|---|
| Glin UI | Active |
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@glinui/ui"
export function TableVariantsDemo() { return ( <div className="grid gap-4 md:grid-cols-2"> <Table variant="glinr" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="solid" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="plain" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="soft" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="outline" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="ghost" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> <Table variant="gradient" containerClassName="w-full"><TableHeader><TableRow><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>Glin UI</TableCell><TableCell>Active</TableCell></TableRow></TableBody></Table> </div> )}In a layout
A striped compact table inside a card with an export action and pagination.
Projects
Traffic over the last 30 days.
| Project | Owner | Status | Visits |
|---|---|---|---|
| Glin UI | Maya Kovacs | Live | 48,210 |
| Docs | Jonas Okafor | Live | 21,904 |
| Registry | Priya Nair | Building | 9,318 |
| Playground | Diego Alvarez | Paused | 2,044 |
import { CaretLeft, CaretRight, Download } from "@phosphor-icons/react"import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@glinui/ui"
export function Demo() { const rows = [ { name: "Glin UI", owner: "Maya Kovacs", visits: "48,210", status: "Live" }, { name: "Docs", owner: "Jonas Okafor", visits: "21,904", status: "Live" }, { name: "Registry", owner: "Priya Nair", visits: "9,318", status: "Building" }, { name: "Playground", owner: "Diego Alvarez", visits: "2,044", status: "Paused" } ] const tone = { Live: "success", Building: "warning", Paused: "neutral" } as const return ( <Card className="w-full max-w-3xl"> <CardHeader> <div className="flex flex-wrap items-center justify-between gap-3"> <div> <CardTitle>Projects</CardTitle> <CardDescription>Traffic over the last 30 days.</CardDescription> </div> <Button size="sm" variant="outline"> <Download aria-hidden className="size-4" /> Export </Button> </div> </CardHeader> <CardContent className="flex flex-col gap-4"> <Table striped size="sm"> <TableHeader> <TableRow> <TableHead>Project</TableHead> <TableHead>Owner</TableHead> <TableHead>Status</TableHead> <TableHead align="right">Visits</TableHead> </TableRow> </TableHeader> <TableBody> {rows.map((row) => ( <TableRow key={row.name}> <TableCell className="font-medium">{row.name}</TableCell> <TableCell>{row.owner}</TableCell> <TableCell><Badge variant="soft" tone={tone[row.status as keyof typeof tone]}>{row.status}</Badge></TableCell> <TableCell align="right" className="tabular-nums">{row.visits}</TableCell> </TableRow> ))} </TableBody> </Table> <div className="flex items-center justify-between gap-3 text-sm text-[var(--color-muted)]"> <span>Showing 1 to 4 of 12</span> <div className="flex items-center gap-2"> <Button size="sm" variant="outline" disabled aria-label="Previous page"><CaretLeft aria-hidden className="size-4" /></Button> <Button size="sm" variant="outline" aria-label="Next page"><CaretRight aria-hidden className="size-4" /></Button> </div> </div> </CardContent> </Card> )}When to choose Table vs DataTable
- Use `Table` for invoices, comparison matrices, read-only reports, and layouts where you control every row and cell. - Use `DataTable` for operational data views where users need filtering, sorting, pagination, and row selection with minimal setup.
Glass Variant
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell, TableCaption } from "@glinui/ui"
export function TableGlassDemo() {
return (
<Table variant="glass" grid>
<TableCaption>Quarterly metrics</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Metric</TableHead>
<TableHead align="right">Value</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Conversion</TableCell>
<TableCell align="right">7.3%</TableCell>
</TableRow>
</TableBody>
</Table>
)
}Lift table with YesNo cells
variant lift turns the overflow wrapper into a lift surface. wide sets a minimum width so it scrolls on small screens.
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, YesNo } from "@glinui/ui"
export function Demo() {
return (
<Table variant="lift" wide interactive={false}>
<TableHeader>
<TableRow>
<TableHead>Feature</TableHead>
<TableHead align="center">Us</TableHead>
<TableHead align="center">Them</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Self-host</TableCell>
<TableCell align="center"><YesNo value /></TableCell>
<TableCell align="center"><YesNo value={false} /></TableCell>
</TableRow>
</TableBody>
</Table>
)
}Accessibility
- Native `<table>` semantics with proper `<thead>`/`<tbody>` structure.
- Use `<th>` for column headers.
- Sticky headers preserve semantics because structure remains native.
- Uses semantic table elements (`table`, `thead`, `tbody`, `th`, `td`, `caption`).
- Keep column headers descriptive for screen reader table navigation.
- Use `TableCaption` to provide context when needed.
ARIA Attributes
- Native table semantics with `<th scope>`
Reduced Motion
Row hover color transitions use motion-safe classes with reduced-motion fallback.
Row hover transitions respect reduced-motion preferences.
Affected properties
background-colorAPI Reference
Table
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient" | "glass" | "liquid" | "matte" | "lift" | - | ambient (glinr) | Surface variant. Omit to follow the ambient design style (glinr by default, plain for minimal, glass for glass). |
size | "sm" | "md" | "lg" | - | md | Text and spacing scale. |
stickyHeader | boolean | - | false | Makes `<TableHeader />` stick to the top while scrolling. |
stickyFirstColumn | boolean | - | false | Pins the first column while horizontally scrolling. |
striped | boolean | - | false | Applies alternating row background treatment. |
interactive | boolean | - | true | Enables row hover treatment. |
grid | boolean | - | false | Adds vertical grid separators between cells. |
layout | "auto" | "fixed" | - | auto | Sets table layout algorithm. |
noWrap | boolean | - | false | Forces single-line cell and header content. |
rowDividers | boolean | - | true | Toggles horizontal row borders. |
containerClassName | string | - | - | Class names for the scroll container wrapper. |
align | "left" | "center" | "right" | No | "left" | Auto-generated from TypeScript source. |
sticky | boolean | No | false | Auto-generated from TypeScript source. |
truncate | boolean | No | false | Auto-generated from TypeScript source. |
TableHeader
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
className | string | - | - | Additional class names. |
align | "left" | "center" | "right" | No | "left" | Auto-generated from TypeScript source. |
sticky | boolean | No | false | Auto-generated from TypeScript source. |
truncate | boolean | No | false | Auto-generated from TypeScript source. |
TableRow
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
tone | "default" | "info" | "success" | "warning" | "danger" | - | default | Applies semantic row emphasis. |
className | string | - | - | Additional class names. |
align | "left" | "center" | "right" | No | "left" | Auto-generated from TypeScript source. |
sticky | boolean | No | false | Auto-generated from TypeScript source. |
truncate | boolean | No | false | Auto-generated from TypeScript source. |
TableHead
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
align | "left" | "center" | "right" | No | left | Text alignment for header cells. |
sticky | boolean | No | false | Pins a specific header cell to the left. |
className | string | - | - | Additional class names. |
truncate | boolean | No | false | Auto-generated from TypeScript source. |
TableBody
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
className | string | - | - | Additional class names. |
align | "left" | "center" | "right" | No | "left" | Auto-generated from TypeScript source. |
sticky | boolean | No | false | Auto-generated from TypeScript source. |
truncate | boolean | No | false | Auto-generated from TypeScript source. |
TableCell
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
align | "left" | "center" | "right" | No | left | Text alignment for body cells. |
truncate | boolean | No | false | Applies single-line truncation with ellipsis. |
sticky | boolean | No | false | Pins a specific body cell to the left. |
className | string | - | - | Additional class names. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { Table } from "@glinui/ui"Source Files
Dependencies
@glinui/uiGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/table.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
TableProps
TableCellProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
align | "left" | "center" | "right" | No | "left" | - |
sticky | boolean | No | false | - |
truncate | boolean | No | false | - |
TableHeadProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
align | "left" | "center" | "right" | No | "left" | - |
sticky | boolean | No | false | - |
TableProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
containerClassName | string | No | - | - |
grid | boolean | No | false | - |
interactive | boolean | No | true | - |
layout | "auto" | "fixed" | No | "auto" | - |
noWrap | boolean | No | false | - |
rowDividers | boolean | No | true | - |
size | "sm" | "md" | "lg" | No | - | - |
stickyFirstColumn | boolean | No | false | - |
stickyHeader | boolean | No | false | - |
striped | boolean | No | false | - |
variant | SurfaceVariant | "liquid" | "matte" | "lift" | "default" | "raised" | "frosted" | No | - | Visual variant. Omit for the ambient design style (glinr: lift wrapper with a raised header strip; plain: shadcn table). Vocabulary: glinr, solid, plain, soft, outline, ghost, gradient, glass. liquid, matte and the legacy `lift` alias stay supported. |
wide | boolean | string | No | false | Force a minimum table width so the wrapper scrolls horizontally on narrow screens. |
TableRowProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
tone | TableRowTone | No | "default" | - |
YesNoProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
noLabel | string | No | "No" | Screen reader text for the no state. |
value | boolean | Yes | - | True renders a check, false renders a minus. |
yesLabel | string | No | "Yes" | Screen reader text for the yes state. |