Add this component

npx zentauri-ui add table

Accessibility notes

Structure-first markup keeps dense data navigable. Preserve row, heading, and item labels when adapting examples.

Dependency notes

Static imports do not pull framer-motion. Use the animated entry only when you want motion and have framer-motion installed.

Data

Tables for dense data views

Tables align columns for scannable datasets—admin consoles, billing histories, and analytics exports. Compose them in React pages and Next.js server-rendered listings with stable column widths.

Recent deploys
ServiceRegionLatency
APIiad42ms
Workersfra28ms

Examples

Bordered appearance with sticky headers and composable sorting for data views.


Click a sortable header to cycle ascending, descending, and none. The active state stays outside the Table primitive.

InvoiceCustomerStatusAmount
INV-1048Acme LabsPaid$1,840
INV-1049Northstar Co.Pending$960
INV-1050Orbit WorksOverdue$2,260
INV-1051Pixel ForgePaid$1,280

IdName
1Alpha
2Beta
3Gamma

Table variants playground

Pick an appearance, size, text alignment, and sticky header option to preview the table live. Toggle Show output / Show code and the snippet updates to match the selected variant.


Appearance: default | Size: md | Sticky Header: false

NameRoleEmailAge
User 1Adminuser1a@example.com20
User 2Useruser2a@example.com25
User 3Useruser3a@example.com30
User 4Useruser4a@example.com30

All appearances

Every shipped appearance token at a glance. Click any swatch to load it into the playground above.

Table API

Generated from the package prop types and variant definitions.

Table

TableProps

Variants

PropTypeDefault
appearance
amberaquablueborderedcrimsoncyandefaultelectricemeraldforestghostgray+25
default
size
lgmdsm
md
stickyHeader
falsetrue
none

Behavior

PropTypeDefault
scrollAreaAriaLabelLabel for the overflow scroll wrapper (keyboard-focusable region).string | undefinednone
textAlign'center' | 'left' | 'right' | undefinednone

Content

PropTypeDefault
childrenReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLTableElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

TableCell

TableCellProps

Variants

PropTypeDefault
textAlign
centerleftright
none

Behavior

PropTypeDefault
scopeRow/column header scope; when set, the cell renders as `<th>` (required for valid `scope` usage).string | undefinednone
Inherited HTML props
PropTypeDefault
childrenReactNodenone
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLTableCellElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

TableHeadCell

TableHeadCellProps

Behavior

PropTypeDefault
onSortChangeTableSortChangeHandler<string> | undefinednone
sortDirectionTableSortDirection | undefinednone
sortKeystring | undefinednone
Inherited HTML props
PropTypeDefault
childrenReactNodenone
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLTableCellElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

TableAnimated

TableAnimatedProps

animated

Behavior

PropTypeDefault
appearance'default' | 'ghost' | 'blue' | 'cyan' | 'green' | 'lime' | 'mint' | 'ocean' | 'sapphire' | 'lavender' | 'ruby' | 'red' | 'slate' | 'zinc' | 'stone' | 'royal' | 'electric' | 'forest' | 'sunset' | 'magenta' | 'crimson' | 'aqua' | 'plum' | 'sky' | 'rose' | 'purple' | 'pink' | 'orange' | 'yellow' | 'teal' | 'indigo' | 'emerald' | 'gray' | 'violet' | 'amber' | 'striped' | 'bordered' | null | undefinednone
rowAnimationTableAnimation | undefinednone
scrollAreaAriaLabelLabel for the overflow scroll wrapper (keyboard-focusable region).string | undefinednone
size'md' | 'sm' | 'lg' | null | undefinednone
stickyHeaderboolean | null | undefinednone
textAlign'center' | 'left' | 'right' | undefinednone

Content

PropTypeDefault
childrenReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLTableElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone
CSS variable overrides

Table CSS variables

Override these table variables on :root, a theme selector, or a component wrapper.

352 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-table-fg: oklch(37.2% 0.044 257.287);
  --zui-table-bordered-border: #0000001a;
  --zui-table-sky-border: oklch(44.3% 0.11 240.79);
  --zui-table-rose-border: oklch(45.5% 0.188 13.697);
  --zui-table-purple-border: oklch(43.8% 0.218 303.724);
  --zui-table-pink-border: oklch(45.9% 0.187 3.815);
  --zui-table-orange-border: oklch(47% 0.157 37.304);
  --zui-table-yellow-border: oklch(47.6% 0.114 61.907);
  --zui-table-teal-border: oklch(43.7% 0.078 188.216);
  --zui-table-indigo-border: oklch(39.8% 0.195 277.366);
  --zui-table-emerald-border: oklch(43.2% 0.095 166.913);
  --zui-table-gray-border: oklch(27.8% 0.033 256.848);
  --zui-table-amber-border: oklch(47.3% 0.137 46.201);
  --zui-table-violet-border: oklch(43.2% 0.232 292.759);
  --zui-table-blue-border: #2563eb;
  --zui-table-cyan-border: #0891b2;
  --zui-table-green-border: #16a34a;
  --zui-table-lime-border: #65a30d;
  --zui-table-mint-border: #10b981;
  --zui-table-ocean-border: #0284c7;
  --zui-table-sapphire-border: #1d4ed8;
  --zui-table-lavender-border: #8b5cf6;
  --zui-table-ruby-border: #be123c;
  --zui-table-red-border: #dc2626;
  --zui-table-slate-border: #475569;
  --zui-table-zinc-border: #52525b;
  --zui-table-stone-border: #57534e;
  --zui-table-royal-border: #4338ca;
  --zui-table-electric-border: #0ea5e9;
  --zui-table-forest-border: #166534;
  --zui-table-sunset-border: #ea580c;
  --zui-table-magenta-border: #c026d3;
  --zui-table-crimson-border: #b91c1c;
  --zui-table-aqua-border: #0f766e;
  --zui-table-plum-border: #7e22ce;
  --zui-table-row-border: #0000000d;
  --zui-table-row-bg-selected: #0000000f;
  --zui-table-row-striped-bg: #00000008;
  --zui-table-row-ghost-border: transparent;
  --zui-table-row-ghost-bg-hover: #00000008;
  --zui-table-row-sky-border: oklch(44.3% 0.11 240.79);
  --zui-table-row-sky-bg-hover: oklch(44.3% 0.11 240.79);
  --zui-table-row-sky-fg-hover: oklch(95.1% 0.026 236.824);
  --zui-table-row-rose-border: oklch(45.5% 0.188 13.697);
  --zui-table-row-rose-bg-hover: oklch(64.5% 0.246 16.439);
  --zui-table-row-rose-fg-hover: oklch(94.1% 0.03 12.58);
  --zui-table-row-purple-border: oklch(43.8% 0.218 303.724);
  --zui-table-row-purple-bg-hover: oklch(62.7% 0.265 303.9);
  --zui-table-row-purple-fg-hover: oklch(94.6% 0.033 307.174);
  --zui-table-row-pink-border: oklch(45.9% 0.187 3.815);
  --zui-table-row-pink-bg-hover: oklch(65.6% 0.241 354.308);
  --zui-table-row-pink-fg-hover: oklch(94.8% 0.028 342.258);
  --zui-table-row-orange-border: oklch(47% 0.157 37.304);
  --zui-table-row-orange-bg-hover: oklch(70.5% 0.213 47.604);
  --zui-table-row-orange-fg-hover: oklch(95.4% 0.038 75.164);
  --zui-table-row-yellow-border: oklch(47.6% 0.114 61.907);
  --zui-table-row-yellow-bg-hover: oklch(79.5% 0.184 86.047);
  --zui-table-row-yellow-fg-hover: oklch(97.3% 0.071 103.193);
  --zui-table-row-teal-border: oklch(43.7% 0.078 188.216);
  --zui-table-row-teal-bg-hover: oklch(70.4% 0.14 182.503);
  --zui-table-row-teal-fg-hover: oklch(95.3% 0.051 180.801);
  --zui-table-row-indigo-border: oklch(39.8% 0.195 277.366);
  --zui-table-row-indigo-bg-hover: oklch(58.5% 0.233 277.117);
  --zui-table-row-indigo-fg-hover: oklch(93% 0.034 272.788);
  --zui-table-row-emerald-border: oklch(43.2% 0.095 166.913);
  --zui-table-row-emerald-bg-hover: oklch(69.6% 0.17 162.48);
  --zui-table-row-emerald-fg-hover: oklch(95% 0.052 163.051);
  --zui-table-row-gray-border: oklch(27.8% 0.033 256.848);
  --zui-table-row-gray-bg-hover: oklch(55.1% 0.027 264.364);
  --zui-table-row-gray-fg-hover: oklch(96.7% 0.003 264.542);
  --zui-table-row-amber-border: oklch(47.3% 0.137 46.201);
  --zui-table-row-amber-bg-hover: oklch(76.9% 0.188 70.08);
  --zui-table-row-amber-fg-hover: oklch(96.2% 0.059 95.617);
  --zui-table-row-violet-border: oklch(43.2% 0.232 292.759);
  --zui-table-row-violet-bg-hover: oklch(60.6% 0.25 292.717);
  --zui-table-row-violet-fg-hover: oklch(94.3% 0.029 294.588);
  --zui-table-row-blue-border: #2563eb;
  --zui-table-row-blue-bg-hover: #2563eb;
  --zui-table-row-blue-fg-hover: #ffffff;
  --zui-table-row-cyan-border: #0891b2;
  --zui-table-row-cyan-bg-hover: #0891b2;
  --zui-table-row-cyan-fg-hover: #083344;
  --zui-table-row-green-border: #16a34a;
  --zui-table-row-green-bg-hover: #16a34a;
  --zui-table-row-green-fg-hover: #ffffff;
  --zui-table-row-lime-border: #65a30d;
  --zui-table-row-lime-bg-hover: #65a30d;
  --zui-table-row-lime-fg-hover: #1a2e05;
  --zui-table-row-mint-border: #10b981;
  --zui-table-row-mint-bg-hover: #10b981;
  --zui-table-row-mint-fg-hover: #064e3b;
  --zui-table-row-ocean-border: #0284c7;
  --zui-table-row-ocean-bg-hover: #0284c7;
  --zui-table-row-ocean-fg-hover: #082f49;
  --zui-table-row-sapphire-border: #1d4ed8;
  --zui-table-row-sapphire-bg-hover: #1d4ed8;
  --zui-table-row-sapphire-fg-hover: #ffffff;
  --zui-table-row-lavender-border: #8b5cf6;
  --zui-table-row-lavender-bg-hover: #8b5cf6;
  --zui-table-row-lavender-fg-hover: #ffffff;
  --zui-table-row-ruby-border: #be123c;
  --zui-table-row-ruby-bg-hover: #be123c;
  --zui-table-row-ruby-fg-hover: #ffffff;
  --zui-table-row-red-border: #dc2626;
  --zui-table-row-red-bg-hover: #dc2626;
  --zui-table-row-red-fg-hover: #ffffff;
  --zui-table-row-slate-border: #475569;
  --zui-table-row-slate-bg-hover: #475569;
  --zui-table-row-slate-fg-hover: #ffffff;
  --zui-table-row-zinc-border: #52525b;
  --zui-table-row-zinc-bg-hover: #52525b;
  --zui-table-row-zinc-fg-hover: #ffffff;
  --zui-table-row-stone-border: #57534e;
  --zui-table-row-stone-bg-hover: #57534e;
  --zui-table-row-stone-fg-hover: #ffffff;
  --zui-table-row-royal-border: #4338ca;
  --zui-table-row-royal-bg-hover: #4338ca;
  --zui-table-row-royal-fg-hover: #ffffff;
  --zui-table-row-electric-border: #0ea5e9;
  --zui-table-row-electric-bg-hover: #0ea5e9;
  --zui-table-row-electric-fg-hover: #ffffff;
  --zui-table-row-forest-border: #166534;
  --zui-table-row-forest-bg-hover: #166534;
  --zui-table-row-forest-fg-hover: #ffffff;
  --zui-table-row-sunset-border: #ea580c;
  --zui-table-row-sunset-bg-hover: #ea580c;
  --zui-table-row-sunset-fg-hover: #ffffff;
  --zui-table-row-magenta-border: #c026d3;
  --zui-table-row-magenta-bg-hover: #c026d3;
  --zui-table-row-magenta-fg-hover: #ffffff;
  --zui-table-row-crimson-border: #b91c1c;
  --zui-table-row-crimson-bg-hover: #b91c1c;
  --zui-table-row-crimson-fg-hover: #ffffff;
  --zui-table-row-aqua-border: #0f766e;
  --zui-table-row-aqua-bg-hover: #0f766e;
  --zui-table-row-aqua-fg-hover: #ffffff;
  --zui-table-row-plum-border: #7e22ce;
  --zui-table-row-plum-bg-hover: #7e22ce;
  --zui-table-row-plum-fg-hover: #ffffff;
  --zui-table-cell-default-border: #0000001a;
  --zui-table-cell-striped-border: #0000001a;
  --zui-table-cell-bordered-border: #0000001a;
  --zui-table-cell-ghost-border: #0000001a;
  --zui-table-cell-sky-border: oklch(44.3% 0.11 240.79);
  --zui-table-cell-rose-border: oklch(45.5% 0.188 13.697);
  --zui-table-cell-purple-border: oklch(43.8% 0.218 303.724);
  --zui-table-cell-pink-border: oklch(45.9% 0.187 3.815);
  --zui-table-cell-orange-border: oklch(47% 0.157 37.304);
  --zui-table-cell-yellow-border: oklch(47.6% 0.114 61.907);
  --zui-table-cell-teal-border: oklch(43.7% 0.078 188.216);
  --zui-table-cell-indigo-border: oklch(39.8% 0.195 277.366);
  --zui-table-cell-emerald-border: oklch(43.2% 0.095 166.913);
  --zui-table-cell-gray-border: oklch(27.8% 0.033 256.848);
  --zui-table-cell-amber-border: oklch(47.3% 0.137 46.201);
  --zui-table-cell-violet-border: oklch(43.2% 0.232 292.759);
  --zui-table-cell-blue-border: #2563eb;
  --zui-table-cell-cyan-border: #0891b2;
  --zui-table-cell-green-border: #16a34a;
  --zui-table-cell-lime-border: #65a30d;
  --zui-table-cell-mint-border: #10b981;
  --zui-table-cell-ocean-border: #0284c7;
  --zui-table-cell-sapphire-border: #1d4ed8;
  --zui-table-cell-lavender-border: #8b5cf6;
  --zui-table-cell-ruby-border: #be123c;
  --zui-table-cell-red-border: #dc2626;
  --zui-table-cell-slate-border: #475569;
  --zui-table-cell-zinc-border: #52525b;
  --zui-table-cell-stone-border: #57534e;
  --zui-table-cell-royal-border: #4338ca;
  --zui-table-cell-electric-border: #0ea5e9;
  --zui-table-cell-forest-border: #166534;
  --zui-table-cell-sunset-border: #ea580c;
  --zui-table-cell-magenta-border: #c026d3;
  --zui-table-cell-crimson-border: #b91c1c;
  --zui-table-cell-aqua-border: #0f766e;
  --zui-table-cell-plum-border: #7e22ce;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-table-fg-dark: oklch(92.9% 0.013 255.508);
  --zui-table-bordered-border-dark: #ffffff1a;
}

What it does

Use semantic table elements for accessibility by default.

Sticky headers help long scroll regions remain navigable.

Composition and API

Prefer compound subcomponents instead of one oversized prop bag. Export a small, documented API for your design system.

Provide captions or aria-labels when the table’s purpose is not obvious from surrounding headings.

Common use cases

  • Operational dashboards with sortable columns.
  • Audit logs with monospace numerics.
  • Pricing matrices with tier comparisons.
  • Inventory views with row-level actions.

Accessibility

Keyboard order, focus rings, and ARIA attributes should match production usage. Test with your supported browsers and assistive technologies when semantics are non-trivial.

This preview page exposes a single h1 in the hero for a clean outline.

Next.js integration notes

Colocate examples under the App Router, keep server and client boundaries explicit, and avoid pulling interactive overlays into unexpected server layouts.

Set NEXT_PUBLIC_SITE_URL so canonical and Open Graph URLs resolve on deploy.

FAQ

Does the Table component work with Next.js App Router?

Yes. Import it like any other React component; keep interactive subtrees in client components when you need hooks or browser APIs, and leave static structure in server components where possible.

Can I customize table with Tailwind CSS?

Zentauri UI exposes class-friendly variants and slots so you can extend styles with Tailwind utilities without fighting inline styles.

Is this Table implementation accessible by default?

Primitives follow sensible defaults, but accessibility depends on how you label controls, manage focus, and wire keyboard handlers in your app. Validate critical flows with keyboard-only use and screen readers.