Data Table
A fully-featured data table with client-side sorting, fuzzy search, and pagination. Built on the Table primitive with generic column definitions.
| Name | Role | Status | |
|---|---|---|---|
| Alice Martin | alice@example.com | Admin | Active |
| Bob Chen | bob@example.com | Developer | Active |
| Carol Kim | carol@example.com | Designer | Inactive |
Page 1 of 2
import { DataTable } from "@aetherstack/patterns"
Installation
terminal
npx aether-ui add data-tableImport
import.tsx
import { DataTable } from "@aetherstack/patterns"
import type { DataTableColumn } from "@aetherstack/patterns"Usage
data-table.tsx
import { DataTable } from "@aetherstack/patterns"
type User = { name: string; email: string; role: string }
const columns = [
{ key: "name" as const, header: "Name", sortable: true },
{ key: "email" as const, header: "Email", sortable: true },
{ key: "role" as const, header: "Role", sortable: true },
]
const data: User[] = [
{ name: "Alice Martin", email: "alice@example.com", role: "Admin" },
{ name: "Bob Chen", email: "bob@example.com", role: "Developer" },
]
<DataTable
columns={columns}
data={data}
searchable
searchKeys={["name", "email"]}
pageSize={10}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| columns* | DataTableColumn<T>[] | — | Column definitions including key, header, optional render function, and sortable flag. |
| data* | T[] | — | Row data. T must extend Record<string, unknown>. |
| pageSize | number | 10 | Number of rows per page. |
| searchable | boolean | false | Show a search input above the table. |
| searchKeys | (keyof T)[] | — | Which keys to include in search. Defaults to all column keys. |
| emptyMessage | string | "No results found." | Message shown when no rows match the current filter. |
| className | string | — | Additional classes on the wrapper. |
* Required
Accessibility
- →Sortable column headers use aria-sort ("ascending" | "descending" | "none").
- →The search input has aria-label="Search table" for screen readers.
- →Pagination buttons have aria-label ("Previous page", "Next page") and are disabled when at limits.
- →Empty state cell spans all columns so the table structure stays valid.