Acrylic
Components

Table

A data table — shadcn's Table restyled to the Acrylic material: flat and transparent so it composes inside a Card, with hairline row separators, muted column labels, and a spring-wired hover tint.

The shadcn Table, recolored to the Acrylic palette. The anatomy and API are copied 1:1 from shadcn; only the material changes — the table is flat and transparent (no surface of its own), rows are divided by inset hairlines, column labels take the small muted subheadline style, and — like the rest of the kit's rows (menus, command, items) — the row highlight is the macOS inset-rounded pill rather than a full-bleed tint: a rounded fill that hovers neutral and goes solid accent with a white label when selected, riding the same spring substrate. Drop it inside a Card when you want a surface behind it (the surface's padding is what insets the highlight).

Installation

npx shadcn add https://acrylic-ui.vercel.app/r/table.json

Usage

Your Apple subscriptions this month.
ServiceDetailBillingAmount
iCloud+2 TB storageMonthly$9.99
Apple MusicIndividualMonthly$10.99
Apple TV+Family sharingMonthly$9.99
Apple Arcade200+ gamesMonthly$6.99
Total$37.96

Click a row in the preview to select it, and hover a resting row alongside it to compare the two fills — selection is shadcn's contract unchanged, data-state="selected" on the TableRow.

import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/acrylic/table"

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Service</TableHead>
      <TableHead className="text-right">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>iCloud+</TableCell>
      <TableCell className="text-right tabular-nums">$9.99</TableCell>
    </TableRow>
    <TableRow data-state="selected">
      <TableCell>Apple Music</TableCell>
      <TableCell className="text-right tabular-nums">$10.99</TableCell>
    </TableRow>
  </TableBody>
</Table>

<TableHeader sticky> turns the column labels into floating chrome the rows scroll under: the kit's surface material + blur, and the bar's outer top corners take the same 7px the row pill uses, so it doesn't read as a square block inside a rounded surface. Scroll the list below.

#TitleAlbumTime
1Ventura HighwayHomecoming3:31
2Tin ManHoliday3:28
3Sister Golden HairHearts3:19
4A Horse with No NameAmerica4:08
5I Need YouAmerica3:07
6Lonely PeopleHoliday2:29
7Daisy JaneHearts3:09
8Woman TonightHearts2:39
9Only in Your HeartHomecoming3:02
10Don't Cross the RiverHomecoming2:31

Sticky needs the right scroll container. Table normally wraps itself in a horizontally-scrollable div — and that div, not the page, is what a sticky <th> would stick to, which looks like sticky is simply broken. Render the table bare inside your own scroll box: <Table scrollable={false}>.

Anatomy

  • Table — wraps the <table> in a horizontally scrollable container with the macOS overlay scrollbar (scrollbar-mac). scrollable={false} drops that wrapper (an acrylic divergence from shadcn) for when an outer box already scrolls — required for a sticky header.
  • TableHeader / TableBody / TableFooter<thead> / <tbody> / <tfoot>. The header takes sticky (see above). The footer carries a faint chip fill and medium weight for totals.
  • TableRow — a row separated by an inset hairline. On hover it shows the macOS inset-rounded highlight (neutral --acr-hover); set data-state="selected" for the solid accent selection (bg-primary + text-primary-foreground on every cell). A highlighted row drops its own separator and the one above it; the last body row has none to begin with. The row also carries group/table-row, so a descendant can react to selection (see Notes).
  • TableHead — a column-label cell: muted, small subheadline size.
  • TableCell — a body cell.
  • TableCaption — a muted caption below the table.

Notes

  • It has no surface of its own. For a framed look, put it inside a Card (see the preview). On a bare page it renders flat.
  • Right-align numeric columns with className="text-right" on both the TableHead and the TableCell. SF's proportional figures are the Apple default; reach for tabular-nums only in dense numeric grids where strict digit alignment actually matters.
  • Colours are tokens — pass className for layout only, never to override the material. Light / dark / acrylic themes flip automatically.
  • Selected rows: set data-state="selected" on a TableRow. The fill is solid --primary and every cell's text is forced to text-primary-foreground — a text-muted-foreground column would be illegible on the accent, so the component overrides it rather than leaving it to the call site. Hover is suppressed on a selected row, so the neutral tint never fights the accent.
  • Dimming a secondary column while selected: the row carries group/table-row, so opt a cell back down with group-data-[state=selected]/table-row:text-primary-foreground/70! — the ! is required, since the component's own per-cell rule is more specific (this is what the preview's Detail and Billing columns do).
  • The highlight is inset by the container — because the rounded pill spans the table width, it reads as "inset" only when the table has a padded surface around it (a Card, or a wrapper with a little horizontal padding), the same way a menu item is inset by its panel's padding.

On this page