Table
_id instead of id — you map it straight into JSX. Nothing has to be flattened or transformed first.Soft variant
A plain read-only table in the admin-dashboard look — a rounded panel on a hairline ring, a tinted header band, calm dividers and soft row hover. No search, filters or paging: just the rows.
- Set
variant"soft" - once on
Table; the heading, header band, cells and dividers read it from context. Every tint is mixed from the table colour. TablePerson- and
TableBadgedraw the avatar-and-email cell and the status pill, in any variant.
Table is the card. TableContent renders the scroll container and the <table> element. Everything else maps one-to-one onto the HTML table tags, so colSpan, scope and any other native attribute pass straight through.Composable table
- Map
rows - straight into JSX — nested values like customer.email need no transformation.
Installation
New project? Follow the installation guide to set up Tailwind CSS, shadcn, the cn helper and lucide-react, register the @algorize-ui registry once, then copy your styles from the Themes page.
Install Table
components/ is written into your project. Copy any snippet from a Usage tab above and it runs.
Install dependencies
Step 1 installs this for you. Run it yourself only if you are adding Table to an existing project by hand. The cn helper and lucide-react are not listed — the installation guide covers them once for every component.
toggle-group is a component, not a package — the shadcn CLI installs it as source files.
Examples
Minimal
- Set
variant"minimal" - to drop the card wrapper so the table sits directly on the page.
Sortable headers
- Set
sortable - on a TableHead to render the sort affordance.
sortDirection- and onSort keep it fully controlled — the table never reorders your data behind your back.
Expandable rows
- Pair
TableExpandToggle - with TableExpandedRow, both driven by your own open state.
Pagination
- Fill
TableFooter - with your own pager. For pagination that is wired for you, use the Data Table.
Row actions
- Wrap
TableRowActions - around your buttons to fade them in on row hover and on keyboard focus.
Comparison (soft)
The same soft table as a plan comparison: features down the side, plans across the top, ticks and limits centred under their headers.
align"center"- on both
TableHeadandTableCelllines the ticks and values up under each plan.
Density
Sizes
- Set
size"sm" | "md" | "lg" - on Table — every descendant reads it from context, so cells and headers stay in step.
Features
Any data shape
No column config and no required row shape. Nested objects, unusual key names and computed cells all work without a transformation step.
Real table markup
Each primitive renders its native element, so colSpan, scope and aria attributes pass straight through and screen readers get a genuine table.
Themed by context
Variant, size and colour are set once on Table and read by every descendant, so a cell dropped three levels deep still matches.
Stateless by default
Sorting and expansion are controlled props. The table never reorders or hides your data on its own, so server-side sorting and paging drop in unchanged.
Best Practices & Guidelines
Reach for the Data Table instead
These primitives are deliberately stateless. If you need search, pagination, row selection and batch actions wired up for you, use the Data Table — it composes the very same primitives and adds a state provider.
Keep colSpan honest
TableEmpty and TableExpandedRow both need a colSpan that matches your real column count. Derive it from a variable rather than hard-coding it, so conditional columns cannot drift out of sync.
Props Reference
Components
| Component | Renders | Purpose |
|---|---|---|
Table | div | The card wrapper. Provides variant, size and colour by context. |
TableHeading | div | Title bar above the table. Children align to the right as an action slot. |
TableContent | div > table | Horizontal scroll container plus the table element. |
TableHeader | thead | Plain pass-through. |
TableBody | tbody | Optional staggered entrance animation. |
TableRow | tr | Body row, or a header row with isHeader. |
TableHead | th | Header cell, optionally sortable. |
TableCell | td | Body cell. |
TableFooter | div | Footer bar below the table — pagers, totals, bulk controls. |
TableEmpty | tr > td | Full-width empty state row. |
TableExpandedRow | tr > td | Animated detail panel beneath a row. |
TableExpandToggle | button | Rotating chevron for the row above. |
TableRowActions | div | Reveals its buttons on row hover or keyboard focus (always visible in soft). |
TableRowAction | button | Round icon button for a row action; label is required, tone="danger" for deletes. |
TableAction | button | Toolbar button in the table's look — variant primary, secondary or ghost. |
TableBadge | span | Status pill with a dot (tone: neutral, success, warning, danger, info), or a tag with dot={false}. |
TablePerson | div | Avatar (photo or initials), a name and a muted second line. |
Table
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "minimal" | "glass" | "soft" | "default" | Bordered card, bare table, frosted glass panel, or the admin-dashboard look (see Data Table for the full soft example). |
size | "sm" | "md" | "lg" | "md" | Row density — cell padding and text size. |
color | "primary" | "indigo" | "rose" | "emerald" | "zinc" | (hex) | "primary" | Accent for selected rows and interactive affordances. Any #rrggbb works. |
TableHead
| Prop | Type | Default | Description |
|---|---|---|---|
align | "left" | "center" | "right" | "left" | Text alignment. |
sortable | boolean | false | Renders the header as a sort button. |
sortDirection | "asc" | "desc" | null | null | Controlled — drives the chevron and aria-sort. |
onSort | () => void | — | Fired on click. You reorder the data. |
TableRow, TableCell, TableBody
| Component | Prop | Type | Description |
|---|---|---|---|
TableRow | isHeader | boolean | Applies header styling instead of body row styling. |
TableRow | selected | boolean | Applies the selected background and sets data-selected. |
TableCell | align | "left" | "center" | "right" | Text alignment. |
TableBody | animate | boolean | Staggered entrance (Web Animations API) for direct child rows. Off by default. |
TableBody | animateKey | React.Key | Change it to replay the entrance — e.g. on sort or page change. |
TableExpandedRow, TableEmpty, TableRowActions
| Component | Prop | Type | Description |
|---|---|---|---|
TableExpandedRow | open | boolean | Grid-animates the panel open or closed. |
TableExpandedRow | colSpan | number | Required. Must match your column count. |
TableEmpty | colSpan | number | Required. Defaults its text to “No data available.” |
TableRowActions | align | "left" | "center" | "right" | Horizontal alignment inside the cell. Defaults to "right". |
TableRowActions | alwaysVisible | boolean | Skip the hover reveal and keep the buttons visible. Defaults to visible in the soft variant. |