Table
A composable data table with sortable columns, striped rows, and multiple density variants. Built from semantic HTML table elements with accessible sort indicators.
Basic with sorting
Add sortable and sortDir to TableHeader for an accessible
sort button with directional icons. Click the Name column header below to toggle sort direction.
| Role | Status | ||
|---|---|---|---|
| Alice Johnson | Admin | alice@example.com | Active |
| Bob Smith | Editor | bob@example.com | Active |
| Carol White | Viewer | carol@example.com | Inactive |
| Dave Brown | Editor | dave@example.com | Active |
import {
Table, TableHead, TableBody, TableRow,
TableHeader, TableCell, TableCaption
} from "@usevyre/react";
const [sortDir, setSortDir] = useState<"asc" | "desc" | null>(null);
<Table hoverable>
<TableHead>
<TableRow>
<TableHeader sortable sortDir={sortDir} onSort={toggleSort}>Name</TableHeader>
<TableHeader>Role</TableHeader>
<TableHeader>Email</TableHeader>
<TableHeader align="center">Status</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
<TableCell>{row.name}</TableCell>
<TableCell>{row.role}</TableCell>
<TableCell>{row.email}</TableCell>
<TableCell align="center">{row.status}</TableCell>
</TableRow>
))}
</TableBody>
<TableCaption>Team members</TableCaption>
</Table> <script setup>
import {
Table, TableHead, TableBody, TableRow,
TableHeader, TableCell, TableCaption
} from "@usevyre/vue";
const sortDir = ref(null);
const toggleSort = () => {
sortDir.value = sortDir.value === "asc" ? "desc" : sortDir.value === "desc" ? null : "asc";
};
</script>
<template>
<Table :hoverable="true">
<TableHead>
<TableRow>
<TableHeader :sortable="true" :sort-dir="sortDir" @sort="toggleSort">Name</TableHeader>
<TableHeader>Role</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow v-for="row in rows" :key="row.id">
<TableCell>{{ row.name }}</TableCell>
<TableCell>{{ row.role }}</TableCell>
</TableRow>
</TableBody>
<TableCaption>Team members</TableCaption>
</Table>
</template> Variants
Mix striped, bordered, and compact props freely.
Striped
| Name | Role | Status |
|---|---|---|
| Alice Johnson | Admin | Active |
| Bob Smith | Editor | Active |
| Carol White | Viewer | Inactive |
Bordered + Compact
| Name | Role | Status |
|---|---|---|
| Alice Johnson | Admin | Active |
| Bob Smith | Editor | Active |
| Carol White | Viewer | Inactive |
{/* Striped rows */}
<Table striped>...</Table>
{/* Bordered cells */}
<Table bordered>...</Table>
{/* Compact padding */}
<Table compact>...</Table>
{/* Combined */}
<Table bordered compact>...</Table> <Table :striped="true">...</Table>
<Table :bordered="true" :compact="true">...</Table> Props — Table
Props
| Prop | Type | Default | Description |
|---|---|---|---|
striped | boolean | false | Alternating row background colors. |
bordered | boolean | false | Borders on all cells. |
compact | boolean | false | Reduced cell padding. |
hoverable | boolean | true | Highlight row on hover. |
class / className | string | — | Additional CSS class. |
Props — TableHeader
Props
| Prop | Type | Default | Description |
|---|---|---|---|
sortable | boolean | false | Renders a sort button inside the header cell. |
sortDir | "asc" | "desc" | null | null | Current sort direction. Controls icon opacity. |
onSort / @sort | () => void | — | Called when the sort button is clicked. |
align | "left" | "center" | "right" | "left" | Text alignment. |
class / className | string | — | Additional CSS class. |
Props — TableCell
Props
| Prop | Type | Default | Description |
|---|---|---|---|
align | "left" | "center" | "right" | "left" | Text alignment of the cell. |
class / className | string | — | Additional CSS class. |
Props — TableRow
Props
| Prop | Type | Default | Description |
|---|---|---|---|
selected | boolean | false | Highlights the row and sets aria-selected. |
class / className | string | — | Additional CSS class. |
Quick examples
Basic data table
<Table>
<TableHead>
<TableRow>
<TableHeader>Name</TableHeader>
<TableHeader>Status</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Alice</TableCell>
<TableCell><Badge variant="success">Active</Badge></TableCell>
</TableRow>
</TableBody>
</Table>