Skip to content
Template Empire / components

Search components

10 results

Browse components

Expandable Rows

Free expandable table rows for React and Next.js, animated with pure CSS.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • CSS and React
  • 1 runtime package

Expandable Rows is a free React table component for Next.js that adds expandable detail rows to a real HTML table, styled with Tailwind and animated with zero JavaScript animation code. Each data row carries a trailing toggle button; activating it unfolds a full width detail panel beneath the row by interpolating a CSS grid wrapper's grid-template-rows from 0fr to 1fr while the chevron rotates ninety degrees in sync.

Semantics stay pure table throughout: detail panels are real tr and td elements with colSpan, never divs pretending to be rows, so screen readers and crawlers see an ordinary table. Any number of rows can be open at once, each one independent, and a required stable row id keeps expansion attached to the same record through inserts, removals, and reordering. Closing panels become inert immediately, then transition visibility to hidden after the fold completes; with reduced motion enabled every toggle is instant.

Recent orders with expandable fulfilment details
OrderCustomerTotalStatusDetails
TE-1042Aurora Studio$1,240.00Shipped
Items
3 x Studio Display Arm, 1 x Desk Mat
Carrier
DHL Express, 1 to 2 business days
TE-1041Northwind Labs$386.50Processing
Items
2 x Mechanical Keyboard, 65 percent
Warehouse
Rotterdam, picking since 08:15
Note
Gift wrap requested on both units
TE-1040Halbon Systems$2,980.00Delivered
Items
10 x Conference Speakerphone
Delivered
Signed by R. Okafor, dock 4
Invoice
Paid via ACH on net 30 terms
TE-1039Fieldline Co$149.00Refunded
Items
1 x Travel Router
Reason
Arrived with damaged packaging
Refund
Full amount returned to card
TE-1038Meridian Press$720.00Shipped
Items
4 x Archival Paper, A2 bundle
Carrier
UPS Ground, 3 to 5 business days
Note
Deliver to loading bay before noon

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/table-expand-rows

Usage

import { TableExpandRows } from "@/components/table-expand-rows";

const columns = [
  { key: "order", label: "Order" },
  { key: "customer", label: "Customer" },
  { key: "total", label: "Total" },
];

const rows = [
  {
    id: "TE-1042",
    cells: { order: "TE-1042", customer: "Aurora Studio", total: "$1,240.00" },
    detail: <p>3 x Studio Display Arm, shipped via DHL Express.</p>,
  },
  {
    id: "TE-1041",
    cells: { order: "TE-1041", customer: "Northwind Labs", total: "$386.50" },
    detail: <p>2 x Mechanical Keyboard, picking in Rotterdam.</p>,
  },
];

export default function Page() {
  return (
    <TableExpandRows caption="Recent orders" columns={columns} rows={rows} />
  );
}

Props

PropTypeDefaultDescription
columns{ key: string; label: string }[]requiredColumn definitions; each key indexes into every row's cells record and each label renders as a column header.
rows{ id: string; cells: Record<string, ReactNode>; detail: ReactNode }[]requiredRow data with a unique stable id plus the detail panel content. The id keeps expansion attached to its record when rows reorder.
captionstringundefinedRendered as a visible caption at the top of the table.
classNamestringundefinedAdditional classes merged onto the table.

Customisation

Expandable Rows declares no tokens of its own; it consumes the shared motion tokens for the unfold and the global semantic colour tokens through its Tailwind utilities, with the docs/03 values baked in as fallbacks for fresh installs. Slow the unfold or change its curve by overriding the motion tokens, and restyle the table through the className prop and your semantic tokens:

<TableExpandRows columns={columns} rows={rows} className="text-sm" />

/* slower, softer unfold everywhere the tokens are consumed */
:root {
  --dur-3: 800ms;
  --ease-out-quart: cubic-bezier(0.22, 1, 0.36, 1);
}

Frequently asked questions

Is Expandable Rows free for commercial use?
Yes. Expandable Rows is MIT licensed, so you can use it in personal and commercial projects without attribution.
Does Expandable Rows stay accessible while rows are collapsed?
Yes. Every toggle is a real button with aria-expanded and a name that references its row, and detail panels are real table rows with a single spanned cell, so table semantics are never faked. A closing panel becomes inert immediately, removing its content from focus and accessibility navigation while its visibility waits for the visual fold to finish. The animation interpolates grid-template-rows in pure CSS, and with reduced motion enabled both directions toggle instantly.
Can several rows be open at the same time?
Yes. Each row's required id owns its expanded state, so any number of detail panels can be open at once, reordering the rows keeps the right record open, and toggling one row never closes another. IDs must be unique and stable for the lifetime of each record. There is no accordion mode or controlled expansion API.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates