Docs Kickstarter

Table

The Table component is used to display structured data in rows and columns. It supports sorting, pagination, and responsive layouts.

Basic Usage

Here’s a simple example of the Table component:

NameStatusRole
John DoeActiveDeveloper
Jane SmithInactiveDesigner
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Name</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Role</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>John Doe</TableCell>
      <TableCell>Active</TableCell>
      <TableCell>Developer</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Jane Smith</TableCell>
      <TableCell>Inactive</TableCell>
      <TableCell>Designer</TableCell>
    </TableRow>
  </TableBody>
</Table>

Component Implementation

Here’s how to implement the Table components:

// components/ui/table.tsx
import * as React from "react"
import { cn } from "@/lib/utils"

const Table = React.forwardRef<
  HTMLTableElement,
  React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
  <div className="relative w-full overflow-auto">
    <table
      ref={ref}
      className={cn("w-full caption-bottom text-sm", className)}
      {...props}
    />
  </div>
))
Table.displayName = "Table"

const TableHeader = React.forwardRef<
  HTMLTableSectionElement,
  React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
  <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
))
TableHeader.displayName = "TableHeader"

const TableBody = React.forwardRef<
  HTMLTableSectionElement,
  React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
  <tbody
    ref={ref}
    className={cn("[&_tr:last-child]:border-0", className)}
    {...props}
  />
))
TableBody.displayName = "TableBody"

const TableRow = React.forwardRef<
  HTMLTableRowElement,
  React.HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
  <tr
    ref={ref}
    className={cn(
      "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
      className
    )}
    {...props}
  />
))
TableRow.displayName = "TableRow"

const TableHead = React.forwardRef<
  HTMLTableCellElement,
  React.ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
  <th
    ref={ref}
    className={cn(
      "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
      className
    )}
    {...props}
  />
))
TableHead.displayName = "TableHead"

const TableCell = React.forwardRef<
  HTMLTableCellElement,
  React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
  <td
    ref={ref}
    className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
    {...props}
  />
))
TableCell.displayName = "TableCell"

export {
  Table,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
}

With Sorting

Here’s an example of a sortable table:

StatusRole
John DoeActiveDeveloper
Jane SmithInactiveDesigner
<TableHead>
  <Button variant="ghost" className="h-8 p-0">
    Name
    <ArrowUpDown className="ml-2 h-4 w-4" />
  </Button>
</TableHead>

With Selection

Add row selection functionality:

NameRole
John DoeDeveloper
Jane SmithDesigner
<Table>
  <TableHeader>
    <TableRow>
      <TableHead className="w-[50px]">
        <Checkbox />
      </TableHead>
      <TableHead>Name</TableHead>
      <TableHead>Role</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>
        <Checkbox />
      </TableCell>
      <TableCell>John Doe</TableCell>
      <TableCell>Developer</TableCell>
    </TableRow>
  </TableBody>
</Table>

With Actions

Add row actions using a dropdown menu:

NameRole
John DoeDeveloper
<TableCell>
  <Button variant="ghost" size="icon">
    <MoreVertical className="h-4 w-4" />
  </Button>
</TableCell>

Responsive Tables

Handle tables on mobile devices:

<div className="rounded-md border">
  <div className="md:hidden">
    {/* Mobile view */}
    {data.map((item) => (
      <div key={item.id} className="p-4 border-b">
        <div className="font-medium">{item.name}</div>
        <div className="text-sm text-muted-foreground mt-1">
          {item.email}
        </div>
      </div>
    ))}
  </div>
  <div className="hidden md:block">
    {/* Desktop table */}
    <Table>{/* ... */}</Table>
  </div>
</div>

Best Practices

  1. Data Display

    • Keep rows scannable
    • Align content properly
    • Use appropriate cell padding
  2. Responsive Design

    • Handle mobile views
    • Consider horizontal scrolling
    • Provide alternative layouts
  3. Accessibility

    • Use proper table semantics
    • Add sort indicators
    • Include ARIA labels
  4. Performance

    • Virtualize large datasets
    • Implement pagination
    • Optimize sorting
  5. User Experience

    • Show loading states
    • Handle empty states
    • Provide clear actions
  6. Styling

    • Consistent borders
    • Clear row separation
    • Hover states