Skip to main content

Table

Renders tabular data as a real HTML table — headers, rows, footer.

import { Table } from "@/fragments/ui";Source

Preview

<Table aria-label="Team members">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Name</Table.HeaderCell>
      <Table.HeaderCell>Role</Table.HeaderCell>
      <Table.HeaderCell>Status</Table.HeaderCell>

Installation

npx @usefragments/cli add table

Writes src/fragments/ui/components/Table plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

Table is a compound: import the root and reach its parts through dot notation.

  • Table.Head
  • Table.Body
  • Table.Footer
  • Table.Row
  • Table.Cell
  • Table.HeaderCell
  • Table.Caption

Header row plus body rows, no extra styling.

<Table aria-label="Team members">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Name</Table.HeaderCell>
      <Table.HeaderCell>Role</Table.HeaderCell>
      <Table.HeaderCell>Status</Table.HeaderCell>
    </Table.Row>
  </Table.Head>
  <Table.Body>
    <Table.Row>
      <Table.Cell>Alice Johnson</Table.Cell>
      <Table.Cell>Engineer</Table.Cell>
      <Table.Cell>Active</Table.Cell>
    </Table.Row>
    <Table.Row>
      <Table.Cell>Bob Smith</Table.Cell>
      <Table.Cell>Designer</Table.Cell>
      <Table.Cell>Active</Table.Cell>

Examples

Empty

Keep the headers and fill one full-width cell so the layout holds.

<Table aria-label="Team members">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Name</Table.HeaderCell>
      <Table.HeaderCell>Role</Table.HeaderCell>
      <Table.HeaderCell>Status</Table.HeaderCell>

Striped

Row tint alternates so the eye tracks across wide rows.

<Table striped aria-label="Inventory">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Item</Table.HeaderCell>
      <Table.HeaderCell>Category</Table.HeaderCell>
      <Table.HeaderCell>Qty</Table.HeaderCell>

Bordered

A border wraps the data so it reads as one block on a busy page.

<Table bordered aria-label="Pricing">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Plan</Table.HeaderCell>
      <Table.HeaderCell>Price</Table.HeaderCell>
      <Table.HeaderCell>Features</Table.HeaderCell>

Compact

Tighter rows fit more data in the same height.

<Table density="compact" aria-label="Shortcuts">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Key</Table.HeaderCell>
      <Table.HeaderCell>Action</Table.HeaderCell>
    </Table.Row>

With Caption

A visible caption titles the data for every reader.

<Table aria-label="Q1 results">
  <Table.Caption>Quarterly Results (Q1 2026)</Table.Caption>
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Metric</Table.HeaderCell>
      <Table.HeaderCell>Value</Table.HeaderCell>

Screen Reader Caption

The caption reaches screen readers only; the layout stays tight.

<Table aria-label="API keys">
  <Table.Caption visuallyHidden>API keys and last-used timestamps</Table.Caption>
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Name</Table.HeaderCell>
      <Table.HeaderCell>Prefix</Table.HeaderCell>

Totals sit in a footer that stays separate from the data.

<Table bordered aria-label="Expenses">
  <Table.Head>
    <Table.Row>
      <Table.HeaderCell>Category</Table.HeaderCell>
      <Table.HeaderCell>Amount</Table.HeaderCell>
    </Table.Row>

API

Component props
Prop
Type
Default
Description
sizeenumsmmdcompactmdTable density
stripedbooleanfalseShow alternating row backgrounds
borderedbooleanfalseWrap table in a bordered container
wrapperClassNamestringNot setClass name for the outer scroll/wrapper container
wrapperPropsobjectNot setHTML attributes for the outer scroll/wrapper container
childrennodeNot set
densityenumcompactregularrelaxedNot setCanonical row density.

Accessibility

  • Semantic HTML table elements (thead, tbody, tfoot, th, td)
  • Column headers have scope="col" by default
  • Caption provides table description for screen readers
  • Supports visually-hidden caption for screen-reader-only labels

Guidance

Use when

  • The data is static — read it, do not interact with it
  • You need real thead/tbody/tfoot semantics
  • The table needs a caption or a totals footer

Avoid when

  • Rows need sorting, selection, or clicking (use DataTable)
  • Content is a single column of items (use List)
  • DataTablealternativeUse DataTable for sorting, selection, and TanStack features

Next steps