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:
Name | Status | Role |
---|---|---|
John Doe | Active | Developer |
Jane Smith | Inactive | Designer |
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:
Status | Role | |
---|---|---|
John Doe | Active | Developer |
Jane Smith | Inactive | Designer |
<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:
Name | Role | |
---|---|---|
John Doe | Developer | |
Jane Smith | Designer |
<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:
Name | Role | |
---|---|---|
John Doe | Developer |
<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
-
Data Display
- Keep rows scannable
- Align content properly
- Use appropriate cell padding
-
Responsive Design
- Handle mobile views
- Consider horizontal scrolling
- Provide alternative layouts
-
Accessibility
- Use proper table semantics
- Add sort indicators
- Include ARIA labels
-
Performance
- Virtualize large datasets
- Implement pagination
- Optimize sorting
-
User Experience
- Show loading states
- Handle empty states
- Provide clear actions
-
Styling
- Consistent borders
- Clear row separation
- Hover states