# Table Component Usage
## Overview
The table component displays data in rows and columns with support for sorting, selection, and responsive layouts. Tables are essential for presenting structured data like lists, comparisons, and data grids.
## HTML Structure
### Basic Table
```html
<table class="table w-full">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
<td>Admin</td>
</tr>
<tr>
<td>Jane Smith</td>
<td>jane@example.com</td>
<td>User</td>
</tr>
</tbody>
</table>
```
### Table with Footer
```html
<table class="table w-full">
<thead>
<tr>
<th>Product</th>
<th class="text-right">Price</th>
<th class="text-right">Quantity</th>
<th class="text-right">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget A</td>
<td class="text-right">$10.00</td>
<td class="text-right">5</td>
<td class="text-right">$50.00</td>
</tr>
<tr>
<td>Widget B</td>
<td class="text-right">$25.00</td>
<td class="text-right">2</td>
<td class="text-right">$50.00</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="text-right font-medium">Total</td>
<td class="text-right font-medium">$100.00</td>
</tr>
</tfoot>
</table>
```
## Implementation Examples
### User Management Table
```html
<div class="border rounded-lg overflow-hidden">
<table class="table w-full">
<thead>
<tr>
<th class="w-12">
<input type="checkbox" class="input" aria-label="Select all">
</th>
<th>User</th>
<th>Status</th>
<th>Role</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" class="input" aria-label="Select John Doe">
</td>
<td>
<div class="flex items-center gap-3">
<img src="/avatars/john.png" alt="" class="size-8 rounded-full">
<div>
<p class="font-medium">John Doe</p>
<p class="text-sm text-muted-foreground">john@example.com</p>
</div>
</div>
</td>
<td>
<span class="badge">Active</span>
</td>
<td>Admin</td>
<td class="text-right">
<div class="dropdown-menu">
<button type="button" class="btn-icon-ghost" aria-haspopup="menu" aria-label="Actions">
<svg class="size-4"><!-- more-horizontal icon --></svg>
</button>
<nav role="menu" data-align="end">
<button type="button" role="menuitem">Edit</button>
<button type="button" role="menuitem">View</button>
<hr role="separator">
<button type="button" role="menuitem" class="text-destructive">Delete</button>
</nav>
</div>
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="input" aria-label="Select Jane Smith">
</td>
<td>
<div class="flex items-center gap-3">
<img src="/avatars/jane.png" alt="" class="size-8 rounded-full">
<div>
<p class="font-medium">Jane Smith</p>
<p class="text-sm text-muted-foreground">jane@example.com</p>
</div>
</div>
</td>
<td>
<span class="badge-secondary">Pending</span>
</td>
<td>Editor</td>
<td class="text-right">
<div class="dropdown-menu">
<button type="button" class="btn-icon-ghost" aria-haspopup="menu" aria-label="Actions">
<svg class="size-4"><!-- more-horizontal icon --></svg>
</button>
<nav role="menu" data-align="end">
<button type="button" role="menuitem">Edit</button>
<button type="button" role="menuitem">View</button>
<hr role="separator">
<button type="button" role="menuitem" class="text-destructive">Delete</button>
</nav>
</div>
</td>
</tr>
</tbody>
</table>
</div>
```
### Sortable Table Headers
```html
<table class="table w-full">
<thead>
<tr>
<th>
<button type="button" class="flex items-center gap-1 hover:text-foreground">
Name
<svg class="size-4"><!-- arrow-up-down icon --></svg>
</button>
</th>
<th>
<button type="button" class="flex items-center gap-1 hover:text-foreground">
Email
<svg class="size-4"><!-- arrow-up icon (sorted ascending) --></svg>
</button>
</th>
<th>
<button type="button" class="flex items-center gap-1 hover:text-foreground">
Date
<svg class="size-4"><!-- arrow-down icon (sorted descending) --></svg>
</button>
</th>
</tr>
</thead>
<tbody>
<!-- rows -->
</tbody>
</table>
```
### Invoice Table
```html
<div class="border rounded-lg overflow-hidden">
<table class="table w-full">
<thead>
<tr>
<th>Invoice</th>
<th>Date</th>
<th>Status</th>
<th>Customer</th>
<th class="text-right">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td class="font-medium">INV-001</td>
<td>Jan 15, 2024</td>
<td>
<span class="badge">Paid</span>
</td>
<td>Acme Inc.</td>
<td class="text-right">$1,200.00</td>
</tr>
<tr>
<td class="font-medium">INV-002</td>
<td>Jan 16, 2024</td>
<td>
<span class="badge-secondary">Pending</span>
</td>
<td>Globex Corp.</td>
<td class="text-right">$2,500.00</td>
</tr>
<tr>
<td class="font-medium">INV-003</td>
<td>Jan 17, 2024</td>
<td>
<span class="badge-destructive">Overdue</span>
</td>
<td>Initech</td>
<td class="text-right">$890.00</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4" class="text-right font-medium">Total Outstanding</td>
<td class="text-right font-medium">$3,390.00</td>
</tr>
</tfoot>
</table>
</div>
```
### Responsive Table
```html
<div class="overflow-x-auto">
<table class="table w-full min-w-[600px]">
<thead>
<tr>
<th>Product</th>
<th>Category</th>
<th>Stock</th>
<th>Price</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td class="font-medium">MacBook Pro</td>
<td>Electronics</td>
<td>15</td>
<td>$2,499.00</td>
<td><span class="badge">In Stock</span></td>
</tr>
<tr>
<td class="font-medium">iPhone 15</td>
<td>Electronics</td>
<td>0</td>
<td>$999.00</td>
<td><span class="badge-destructive">Out of Stock</span></td>
</tr>
</tbody>
</table>
</div>
```
### Striped Table
```html
<table class="table w-full">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Department</th>
</tr>
</thead>
<tbody class="[&>tr:nth-child(odd)]:bg-muted/50">
<tr>
<td>Alice Johnson</td>
<td>Developer</td>
<td>Engineering</td>
</tr>
<tr>
<td>Bob Williams</td>
<td>Designer</td>
<td>Design</td>
</tr>
<tr>
<td>Carol Brown</td>
<td>Manager</td>
<td>Operations</td>
</tr>
<tr>
<td>David Lee</td>
<td>Analyst</td>
<td>Finance</td>
</tr>
</tbody>
</table>
```
### Compact Table
```html
<table class="table w-full [&_th]:py-2 [&_td]:py-2">
<thead>
<tr>
<th>ID</th>
<th>Event</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
<tr>
<td class="font-mono text-sm">#1234</td>
<td>User logged in</td>
<td class="text-muted-foreground text-sm">2024-01-15 10:30:00</td>
</tr>
<tr>
<td class="font-mono text-sm">#1235</td>
<td>File uploaded</td>
<td class="text-muted-foreground text-sm">2024-01-15 10:35:00</td>
</tr>
<tr>
<td class="font-mono text-sm">#1236</td>
<td>Settings changed</td>
<td class="text-muted-foreground text-sm">2024-01-15 10:42:00</td>
</tr>
</tbody>
</table>
```
### Table with Row Actions
```html
<table class="table w-full group">
<thead>
<tr>
<th>File</th>
<th>Size</th>
<th>Modified</th>
<th class="w-20"></th>
</tr>
</thead>
<tbody>
<tr class="group/row">
<td class="font-medium">document.pdf</td>
<td class="text-muted-foreground">2.4 MB</td>
<td class="text-muted-foreground">Jan 15, 2024</td>
<td>
<div class="opacity-0 group-hover/row:opacity-100 transition-opacity flex gap-1">
<button class="btn-icon-ghost size-8" aria-label="Download">
<svg class="size-4"><!-- download icon --></svg>
</button>
<button class="btn-icon-ghost size-8" aria-label="Delete">
<svg class="size-4"><!-- trash icon --></svg>
</button>
</div>
</td>
</tr>
<tr class="group/row">
<td class="font-medium">image.png</td>
<td class="text-muted-foreground">1.1 MB</td>
<td class="text-muted-foreground">Jan 14, 2024</td>
<td>
<div class="opacity-0 group-hover/row:opacity-100 transition-opacity flex gap-1">
<button class="btn-icon-ghost size-8" aria-label="Download">
<svg class="size-4"><!-- download icon --></svg>
</button>
<button class="btn-icon-ghost size-8" aria-label="Delete">
<svg class="size-4"><!-- trash icon --></svg>
</button>
</div>
</td>
</tr>
</tbody>
</table>
```
## Empty State
### Table with No Data
```html
<div class="border rounded-lg overflow-hidden">
<table class="table w-full">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3">
<div class="flex flex-col items-center justify-center py-12 text-center">
<svg class="size-12 text-muted-foreground mb-4"><!-- inbox icon --></svg>
<h3 class="text-lg font-medium">No users found</h3>
<p class="text-muted-foreground mb-4">Get started by adding a new user.</p>
<button class="btn">Add User</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
```
## Pagination
### Table with Pagination
```html
<div class="space-y-4">
<div class="border rounded-lg overflow-hidden">
<table class="table w-full">
<!-- table content -->
</table>
</div>
<div class="flex items-center justify-between">
<p class="text-sm text-muted-foreground">Showing 1 to 10 of 97 results</p>
<nav class="flex items-center gap-1">
<button class="btn-icon-ghost" disabled aria-label="Previous page">
<svg class="size-4"><!-- chevron-left --></svg>
</button>
<button class="btn-icon-outline">1</button>
<button class="btn-icon-ghost">2</button>
<button class="btn-icon-ghost">3</button>
<span class="px-2">...</span>
<button class="btn-icon-ghost">10</button>
<button class="btn-icon-ghost" aria-label="Next page">
<svg class="size-4"><!-- chevron-right --></svg>
</button>
</nav>
</div>
</div>
```
## Accessibility Guidelines
### Required Attributes
```html
<table class="table" aria-label="User list">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
</tr>
</tbody>
</table>
```
### Sortable Column Accessibility
```html
<th scope="col" aria-sort="ascending">
<button type="button">
Name
<svg aria-hidden="true"><!-- sort icon --></svg>
</button>
</th>
```
### Selection Accessibility
```html
<th scope="col">
<input
type="checkbox"
aria-label="Select all rows"
aria-checked="false"
>
</th>
<td>
<input
type="checkbox"
aria-label="Select row for John Doe"
aria-checked="false"
>
</td>
```
## Best Practices
### When to Use Tables
- Displaying structured data
- Comparing multiple items
- Financial/numerical data
- Lists with multiple attributes
### When to Avoid Tables
- Layout purposes (use CSS Grid/Flexbox)
- Single-column lists (use list elements)
- Very few data points (use cards)
- Mobile-only views (consider cards)
### Responsive Strategies
1. **Horizontal scroll**: Wrap table in overflow container
2. **Stacked cards**: Transform rows to cards on mobile
3. **Hidden columns**: Show/hide columns based on screen size
4. **Priority columns**: Show most important columns first
### Performance Tips
- Use virtual scrolling for large datasets
- Implement pagination for many rows
- Lazy load images in table cells
- Debounce sorting/filtering operations