Table
Display tabular data in a grid with selection and sorting.
- Documentation
- React Aria
- Pattern
- W3C ARIA
- Source
- GitHub
- Issues
- Report
Name | Type |
---|---|
Games | File folder |
Program Files | File folder |
bootmgr | System file |
Documents | File folder |
Downloads | File folder |
Table example
import {
Cell,
Column,
Row,
Table,
TableBody,
TableHeader,
} from "@/shim-ui/table";
export default () => (
<Table aria-label="Files">
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
</TableHeader>
<TableBody>
<Row>
<Cell>Games</Cell>
<Cell>File folder</Cell>
</Row>
<Row>
<Cell>Program Files</Cell>
<Cell>File folder</Cell>
</Row>
<Row>
<Cell>bootmgr</Cell>
<Cell>System file</Cell>
</Row>
<Row>
<Cell>Documents</Cell>
<Cell>File folder</Cell>
</Row>
<Row>
<Cell>Downloads</Cell>
<Cell>File folder</Cell>
</Row>
</TableBody>
</Table>
);
Install
Use the CLI or copy the source code manually.
Command
Source code
pnpm dlx @kkga/shim add table
Content
Provide columns via the columns
prop on <TableHeader>
and data with items
on <TableBody>
to render dynamic tables.
Creature | Can fly | Has horn | Magical | Scary |
---|---|---|---|---|
Unicorn | ||||
Dragon | ||||
Mermaid | ||||
Bigfoot | ||||
Chimera |
Content example
"use client";
import { CheckIcon, XIcon } from "@phosphor-icons/react";
import {
Cell,
Column,
Row,
Table,
TableBody,
TableHeader,
} from "@/shim-ui/table";
let columns = [
{ id: "creature", name: "Creature", isRowHeader: true },
{ id: "canFly", name: "Can fly" },
{ id: "hasHorn", name: "Has horn" },
{ id: "magical", name: "Magical" },
{ id: "scary", name: "Scary" },
];
let rows = [
{
id: 1,
creature: "Unicorn",
canFly: false,
hasHorn: true,
magical: true,
scary: false,
},
{
id: 2,
creature: "Dragon",
canFly: true,
hasHorn: false,
magical: true,
scary: true,
},
{
id: 3,
creature: "Mermaid",
canFly: false,
hasHorn: false,
magical: true,
scary: false,
},
{
id: 4,
creature: "Bigfoot",
canFly: false,
hasHorn: false,
magical: false,
scary: true,
},
{
id: 5,
creature: "Chimera",
canFly: false,
hasHorn: true,
magical: false,
scary: true,
},
];
const Check = () => (
<CheckIcon className="text-success-text" size={16} weight="bold" />
);
const X = () => <XIcon className="text-neutral-text-subtle" size={16} />;
export default () => (
<Table aria-label="Mythical Creatures">
<TableHeader columns={columns}>
{(column) => (
<Column isRowHeader={column.isRowHeader}>{column.name}</Column>
)}
</TableHeader>
<TableBody items={rows}>
{({ creature, canFly, hasHorn, magical, scary }) => (
<Row>
<Cell>{creature}</Cell>
<Cell>{canFly ? <Check /> : <X />}</Cell>
<Cell>{hasHorn ? <Check /> : <X />}</Cell>
<Cell>{magical ? <Check /> : <X />}</Cell>
<Cell>{scary ? <Check /> : <X />}</Cell>
</Row>
)}
</TableBody>
</Table>
);
Sorting
Enable column sorting by providing a sortDescriptor
with a column
key and direction
value.
Direction accepts "ascending"
or "descending"
and the column matches the column key.
Name | Major | GPA |
---|---|---|
Alice Johnson | Mathematics | 3.9 |
Bob Brown | Physics | 3.7 |
Charlie Davis | Chemistry | 3.6 |
Diana Evans | Biology | 3.8 |
Ethan Foster | Economics | 3.4 |
Fiona Green | Psychology | 3.7 |
Jane Smith | Mechanical Engineering | 3.8 |
John Doe | Computer Science | 3.5 |
Sorting example
"use client";
import { useMemo, useState } from "react";
import type { SortDescriptor } from "react-aria-components";
import {
Cell,
Column,
Row,
Table,
TableBody,
TableHeader,
} from "@/shim-ui/table";
interface RowData {
id: number;
name: string;
major: string;
gpa: number;
}
let rows: RowData[] = [
{ id: 1, name: "John Doe", major: "Computer Science", gpa: 3.5 },
{ id: 2, name: "Jane Smith", major: "Mechanical Engineering", gpa: 3.8 },
{ id: 3, name: "Alice Johnson", major: "Mathematics", gpa: 3.9 },
{ id: 4, name: "Bob Brown", major: "Physics", gpa: 3.7 },
{ id: 5, name: "Charlie Davis", major: "Chemistry", gpa: 3.6 },
{ id: 6, name: "Diana Evans", major: "Biology", gpa: 3.8 },
{ id: 7, name: "Ethan Foster", major: "Economics", gpa: 3.4 },
{ id: 8, name: "Fiona Green", major: "Psychology", gpa: 3.7 },
];
export default () => {
let [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
column: "name",
direction: "ascending",
});
let items = useMemo(() => {
let sorted = [...rows].sort((a, b) => {
let column = sortDescriptor.column as keyof RowData;
if (typeof a[column] === "number" && typeof b[column] === "number") {
return a[column] - b[column];
}
if (typeof a[column] === "string" && typeof b[column] === "string") {
return a[column].localeCompare(b[column]);
}
return 0;
});
if (sortDescriptor.direction === "descending") {
sorted.reverse();
}
return sorted;
}, [sortDescriptor]);
return (
<Table
aria-label="Students"
onSortChange={setSortDescriptor}
sortDescriptor={sortDescriptor}
>
<TableHeader>
<Column allowsSorting id="name" isRowHeader>
Name
</Column>
<Column allowsSorting id="major">
Major
</Column>
<Column allowsSorting id="gpa">
GPA
</Column>
</TableHeader>
<TableBody items={items}>
{({ name, major, gpa }) => (
<Row>
<Cell>{name}</Cell>
<Cell>{major}</Cell>
<Cell className="tabular-nums">{gpa}</Cell>
</Row>
)}
</TableBody>
</Table>
);
};