Table
A semantic HTML table component with visual variants for displaying structured data.
Uses native <table> semantics; TableHeader renders <th scope="col"> by default; numeric cells use data-numeric for screen-reader context.
Preview
tsx
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@arshad-shah/cynosure-react';
const users = [
{ id: 1, name: 'Alice Martin', role: 'Engineer', status: 'Active' },
{ id: 2, name: 'Bob Chen', role: 'Designer', status: 'Active' },
{ id: 3, name: 'Carol Smith', role: 'Product', status: 'Away' },
{ id: 4, name: 'Dan Kumar', role: 'Engineer', status: 'Inactive' },
];
export default function Example() {
return (
<Table>
<TableHead>
<TableRow>
<TableHeader>ID</TableHeader>
<TableHeader>Name</TableHeader>
<TableHeader>Role</TableHeader>
<TableHeader>Status</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{users.map((user) => (
<TableRow key={user.id}>
<TableCell numeric>{user.id}</TableCell>
<TableCell>{user.name}</TableCell>
<TableCell>{user.role}</TableCell>
<TableCell>{user.status}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
Variants
Section titled “Variants”Striped
Section titled “Striped”Use variant="striped" to apply alternating row backgrounds for easier scanning.
Preview
tsx
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@arshad-shah/cynosure-react';
const transactions = [
{ id: 'TXN-001', merchant: 'Coffee Shop', amount: 4.5, date: '2024-01-15' },
{ id: 'TXN-002', merchant: 'Supermarket', amount: 62.3, date: '2024-01-16' },
{ id: 'TXN-003', merchant: 'Bookstore', amount: 18.99, date: '2024-01-17' },
{ id: 'TXN-004', merchant: 'Restaurant', amount: 34.0, date: '2024-01-18' },
{ id: 'TXN-005', merchant: 'Pharmacy', amount: 12.75, date: '2024-01-19' },
];
export default function Example() {
return (
<Table variant="striped">
<TableHead>
<TableRow>
<TableHeader>Transaction</TableHeader>
<TableHeader>Merchant</TableHeader>
<TableHeader align="end">Amount</TableHeader>
<TableHeader>Date</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{transactions.map((tx) => (
<TableRow key={tx.id}>
<TableCell>{tx.id}</TableCell>
<TableCell>{tx.merchant}</TableCell>
<TableCell align="end" numeric>
${tx.amount.toFixed(2)}
</TableCell>
<TableCell>{tx.date}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
Compact
Section titled “Compact”Use size="sm" for dense tables — useful in dashboards and log viewers.
Preview
tsx
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@arshad-shah/cynosure-react';
const logs = [
{ level: 'INFO', message: 'Server started', timestamp: '10:00:01' },
{ level: 'INFO', message: 'Database connected', timestamp: '10:00:02' },
{ level: 'WARN', message: 'High memory usage', timestamp: '10:05:14' },
{ level: 'ERROR', message: 'Request timeout', timestamp: '10:07:33' },
{ level: 'INFO', message: 'Cache cleared', timestamp: '10:10:00' },
];
export default function Example() {
return (
<Table size="sm">
<TableHead>
<TableRow>
<TableHeader>Level</TableHeader>
<TableHeader>Message</TableHeader>
<TableHeader>Timestamp</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{logs.map((log, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: stable static list
<TableRow key={i}>
<TableCell>{log.level}</TableCell>
<TableCell>{log.message}</TableCell>
<TableCell>{log.timestamp}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
PropTypeDefaultDescription
variant
"line"|"striped"|"grid"|"minimal"
line
Visual treatment: `line` shows row dividers, `striped` zebras alternating
rows, `grid` draws both row and column borders, `minimal` strips all
chrome.
size
"sm"|"md"|"lg"
md
Density preset for padding and font size.
stickyHeader
boolean
false
Pin the `<thead>` to the top of the scroll container while the body
scrolls vertically. Requires the table to live inside a scrollable
ancestor for it to take effect.
layout
"auto"|"fixed"
auto
CSS `table-layout` strategy. `auto` (default) sizes columns from content;
`fixed` distributes width based on the first row only and is faster for
wide tables.
Accessibility
Section titled “Accessibility”- The component renders a native
<table>element with proper semantic structure. TableHeaderdefaults toscope="col"so screen readers can associate headers with data cells.- Pass
numerictoTableCellto setdata-numeric="true"and right-align values; this does not alter the accessible label. - Use
TableCaptionto provide a visible or visually-hidden caption that describes the table purpose. stickyHeaderkeeps column headers visible while scrolling long tables.
Recipes
Section titled “Recipes”- Use
variant="grid"for a full-bordered spreadsheet appearance. - Use
variant="minimal"to strip all borders for an ultra-clean look. - Wrap the table in a scrollable container when the column count may overflow on narrow screens.
- Pair with
layout="fixed"when column widths should be driven by the header, not cell content. - Combine
variant="striped"+stickyHeaderfor long financial or data-heavy tables.