Skip to main content
Table is a low-level component for building custom table layouts. For a full-featured data table with sorting, filtering, and pagination, use the DataTable component.

Import

import { 
  Table, 
  TableHeader, 
  TableBody, 
  TableRow, 
  TableHead, 
  TableCell,
  TableFooter,
  TableCaption
} from 'popui'

Basic Usage

<script lang="ts">
  import { 
    Table, 
    TableHeader, 
    TableBody, 
    TableRow, 
    TableHead, 
    TableCell 
  } from 'popui'
  
  const invoices = [
    { id: 'INV001', status: 'Paid', method: 'Credit Card', amount: '$250.00' },
    { id: 'INV002', status: 'Pending', method: 'PayPal', amount: '$150.00' },
    { id: 'INV003', status: 'Unpaid', method: 'Bank Transfer', amount: '$350.00' }
  ]
</script>

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Method</TableHead>
      <TableHead>Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {#each invoices as invoice}
      <TableRow>
        <TableCell>{invoice.id}</TableCell>
        <TableCell>{invoice.status}</TableCell>
        <TableCell>{invoice.method}</TableCell>
        <TableCell>{invoice.amount}</TableCell>
      </TableRow>
    {/each}
  </TableBody>
</Table>
<script lang="ts">
  import { 
    Table, 
    TableHeader, 
    TableBody,
    TableFooter,
    TableRow, 
    TableHead, 
    TableCell 
  } from 'popui'
</script>

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Item</TableHead>
      <TableHead>Quantity</TableHead>
      <TableHead>Price</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Product A</TableCell>
      <TableCell>5</TableCell>
      <TableCell>$50.00</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Product B</TableCell>
      <TableCell>3</TableCell>
      <TableCell>$30.00</TableCell>
    </TableRow>
  </TableBody>
  <TableFooter>
    <TableRow>
      <TableCell colspan="2">Total</TableCell>
      <TableCell>$80.00</TableCell>
    </TableRow>
  </TableFooter>
</Table>

With Caption

<script lang="ts">
  import { 
    Table, 
    TableCaption,
    TableHeader, 
    TableBody, 
    TableRow, 
    TableHead, 
    TableCell 
  } from 'popui'
</script>

<Table>
  <TableCaption>A list of your recent invoices.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>INV001</TableCell>
      <TableCell>Paid</TableCell>
      <TableCell>$250.00</TableCell>
    </TableRow>
  </TableBody>
</Table>

Clickable Rows

<script lang="ts">
  function handleRowClick(invoice) {
    console.log('Clicked:', invoice)
  }
</script>

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {#each invoices as invoice}
      <TableRow 
        onclick={() => handleRowClick(invoice)}
        class="cursor-pointer"
      >
        <TableCell>{invoice.id}</TableCell>
        <TableCell>{invoice.status}</TableCell>
      </TableRow>
    {/each}
  </TableBody>
</Table>

Row States

Table rows support different visual states through data attributes:
<TableBody>
  <TableRow data-state="selected">
    <TableCell>Selected row</TableCell>
  </TableRow>
  
  <TableRow data-state="error">
    <TableCell>Error state</TableCell>
  </TableRow>
  
  <TableRow data-state="warning">
    <TableCell>Warning state</TableCell>
  </TableRow>
  
  <TableRow data-state="success">
    <TableCell>Success state</TableCell>
  </TableRow>
</TableBody>

Custom Styling

<Table class="border border-border">
  <TableHeader class="bg-gray-50">
    <TableRow>
      <TableHead class="font-bold">Name</TableHead>
      <TableHead class="font-bold text-right">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell class="font-medium">John Doe</TableCell>
      <TableCell class="text-right font-mono">$250.00</TableCell>
    </TableRow>
  </TableBody>
</Table>
The TableHeader component is sticky by default and remains visible when scrolling:
<div class="h-96 overflow-auto">
  <Table>
    <TableHeader>
      <TableRow>
        <TableHead>Column 1</TableHead>
        <TableHead>Column 2</TableHead>
      </TableRow>
    </TableHeader>
    <TableBody>
      {#each Array(50) as _, i}
        <TableRow>
          <TableCell>Row {i + 1}</TableCell>
          <TableCell>Data {i + 1}</TableCell>
        </TableRow>
      {/each}
    </TableBody>
  </Table>
</div>

Responsive Table

<div class="overflow-x-auto">
  <Table>
    <TableHeader>
      <TableRow>
        <TableHead class="min-w-[100px]">ID</TableHead>
        <TableHead class="min-w-[200px]">Name</TableHead>
        <TableHead class="min-w-[150px]">Email</TableHead>
        <TableHead class="min-w-[100px]">Status</TableHead>
      </TableRow>
    </TableHeader>
    <TableBody>
      {#each data as item}
        <TableRow>
          <TableCell>{item.id}</TableCell>
          <TableCell>{item.name}</TableCell>
          <TableCell>{item.email}</TableCell>
          <TableCell>{item.status}</TableCell>
        </TableRow>
      {/each}
    </TableBody>
  </Table>
</div>

Components

Table

The root table container.
ref
HTMLTableElement
Reference to the underlying table element.
class
string
Additional CSS classes.
children
Snippet
Table content (Header, Body, Footer, Caption).

TableHeader

The table header section (sticky by default).
ref
HTMLTableSectionElement
Reference to the thead element.
class
string
Additional CSS classes.
children
Snippet
TableRow components with TableHead cells.

TableBody

The table body section.
ref
HTMLTableSectionElement
Reference to the tbody element.
class
string
Additional CSS classes.
children
Snippet
TableRow components.

TableFooter

The table footer section.
ref
HTMLTableSectionElement
Reference to the tfoot element.
class
string
Additional CSS classes.
children
Snippet
TableRow components.

TableRow

A table row.
ref
HTMLTableRowElement
Reference to the tr element.
class
string
Additional CSS classes.
onclick
(event: MouseEvent) => void
Click handler.
oncontextmenu
(event: MouseEvent) => void
Context menu handler.
onkeydown
(event: KeyboardEvent) => void
Keydown handler.
onmouseover
(event: MouseEvent) => void
Mouse over handler.
onfocus
(event: FocusEvent) => void
Focus handler.
data-state
'selected' | 'checked' | 'error' | 'warning' | 'success'
Row visual state.
data-focused
boolean
Whether the row is focused.
children
Snippet
TableCell or TableHead components.

TableHead

A header cell.
ref
HTMLTableCellElement
Reference to the th element.
class
string
Additional CSS classes.
colspan
number
Number of columns to span.
rowspan
number
Number of rows to span.
children
Snippet
Cell content.

TableCell

A data cell.
ref
HTMLTableCellElement
Reference to the td element.
class
string
Additional CSS classes.
colspan
number
Number of columns to span.
rowspan
number
Number of rows to span.
children
Snippet
Cell content.

TableCaption

A table caption.
ref
HTMLTableCaptionElement
Reference to the caption element.
class
string
Additional CSS classes.
children
Snippet
Caption content.

Build docs developers (and LLMs) love