Table Component
Tables display information in a structured grid format, making it easy to scan, compare, and analyze data.
Basic Table
Name | Role | Status | |
---|---|---|---|
John Doe | john@example.com | Admin | Active |
Jane Smith | jane@example.com | Editor | Inactive |
Mike Johnson | mike@example.com | Viewer | Pending |
Sara Williams | sara@example.com | Editor | Active |
Robert Brown | robert@example.com | Admin | Active |
Code Example
<Table className="border rounded-lg overflow-hidden"> <TableHeader> <TableRow> <TableHead>Name</TableHead> <TableHead>Email</TableHead> <TableHead>Role</TableHead> <TableHead>Status</TableHead> </TableRow> </TableHeader> <TableBody> {data.map((row) => ( <TableRow key={row.id}> <TableCell>{row.name}</TableCell> <TableCell>{row.email}</TableCell> <TableCell>{row.role}</TableCell> <TableCell>{row.status}</TableCell> </TableRow> ))} </TableBody> </Table>
With Sortable Columns
Name | Email | Role | Status |
---|---|---|---|
John Doe | john@example.com | Admin | Active |
Jane Smith | jane@example.com | Editor | Inactive |
Mike Johnson | mike@example.com | Viewer | Pending |
Sara Williams | sara@example.com | Editor | Active |
Robert Brown | robert@example.com | Admin | Active |
Code Example
const [sortDirection, setSortDirection] = useState<'asc' | 'desc' | null>(null) const [sortColumn, setSortColumn] = useState<string | null>(null) const handleSort = (column: string) => { if (sortColumn === column) { if (sortDirection === 'asc') { setSortDirection('desc') } else if (sortDirection === 'desc') { setSortDirection(null) setSortColumn(null) } else { setSortDirection('asc') } } else { setSortColumn(column) setSortDirection('asc') } } <TableHead className="cursor-pointer" onClick={() => handleSort('name')} > <div className="flex items-center"> Name {sortColumn === 'name' && ( sortDirection === 'asc' ? <ChevronUp className="ml-1 h-4 w-4" /> : <ChevronDown className="ml-1 h-4 w-4" /> )} </div> </TableHead>
With Selection
Name | Role | Status | ||
---|---|---|---|---|
John Doe | john@example.com | Admin | Active | |
Jane Smith | jane@example.com | Editor | Inactive | |
Mike Johnson | mike@example.com | Viewer | Pending | |
Sara Williams | sara@example.com | Editor | Active | |
Robert Brown | robert@example.com | Admin | Active |
Code Example
const [selectedRows, setSelectedRows] = useState<Record<number, boolean>>({}) const toggleSelectAll = (checked: boolean) => { if (checked) { const newSelected: Record<number, boolean> = {} data.forEach((row, index) => { newSelected[index] = true }) setSelectedRows(newSelected) } else { setSelectedRows({}) } } const toggleSelectRow = (index: number) => { setSelectedRows(prev => ({ ...prev, [index]: !prev[index] })) } const areAllSelected = data.length > 0 && Object.keys(selectedRows).length === data.length && Object.values(selectedRows).every(Boolean) <TableHead className="w-[50px]"> <Checkbox checked={areAllSelected} onCheckedChange={toggleSelectAll} /> </TableHead> <TableCell> <Checkbox checked={selectedRows[index] || false} onCheckedChange={() => toggleSelectRow(index)} /> </TableCell>
With Actions and Status Badge
Name | Role | Status | Actions | |
---|---|---|---|---|
John Doe | john@example.com | Admin | Active | |
Jane Smith | jane@example.com | Editor | Inactive | |
Mike Johnson | mike@example.com | Viewer | Pending | |
Sara Williams | sara@example.com | Editor | Active | |
Robert Brown | robert@example.com | Admin | Active |
Code Example
<TableCell> <Badge variant={ row.status === 'Active' ? 'success' : row.status === 'Inactive' ? 'destructive' : 'warning' } > {row.status} </Badge> </TableCell> <TableCell className="text-right"> <div className="flex justify-end items-center gap-2"> <Button variant="ghost" size="icon" className="h-8 w-8"> <Edit className="h-4 w-4" /> </Button> <Button variant="ghost" size="icon" className="h-8 w-8 text-red-500"> <Trash className="h-4 w-4" /> </Button> <Button variant="ghost" size="icon" className="h-8 w-8"> <MoreHorizontal className="h-4 w-4" /> </Button> </div> </TableCell>
Usage Guidelines
Here are some best practices for using tables:
- Use tables when you need to present structured data with multiple attributes
- Keep tables simple by only including necessary columns
- Provide clear column headers to help users understand the data
- Use visual cues like badges or icons to highlight status or special conditions
- Include actions when users need to manipulate individual records
- Add sorting, filtering, or pagination for large datasets
- Use selection when users need to perform bulk actions on multiple rows
- Ensure tables are responsive and accessible on different screen sizes