# Table

## Overview

Structured tabular data display. Provides semantic HTML table elements wrapped in accessible, styled components. Used in CRUD list pages, reports, and any data-heavy view where rows represent records and columns represent attributes.

---

## When to Use

- Displaying collections of records (users, products, orders)
- Comparison views with consistent attributes per row
- Reports with sortable or filterable columns

## When NOT to Use

- Key-value pairs (profile details) — use a `<Card>` with a definition list instead.
- Simple two-column data without rows — use a `<ScrollArea>` with a styled list.

---

## Anatomy

```
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Column Name</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Cell Value</TableCell>
    </TableRow>
  </TableBody>
  <TableFooter>  ← optional (totals, summaries)
    <TableRow>
      <TableCell>Total</TableCell>
    </TableRow>
  </TableFooter>
</Table>
```

---

## Sub-Components

| Component      | Description                                        |
| -------------- | -------------------------------------------------- |
| `Table`        | Wraps `<table>` with horizontal scroll on overflow |
| `TableHeader`  | Wraps `<thead>`                                    |
| `TableBody`    | Wraps `<tbody>`                                    |
| `TableFooter`  | Wraps `<tfoot>`                                    |
| `TableRow`     | Wraps `<tr>` with hover state                      |
| `TableHead`    | Wraps `<th>` with muted text                       |
| `TableCell`    | Wraps `<td>`                                       |
| `TableCaption` | Below-table caption text                           |

---

## Common Patterns

### Full CRUD Table

```tsx
import {
  Table,
  TableHeader,
  TableRow,
  TableHead,
  TableBody,
  TableCell,
  Badge,
  Button,
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
} from 'xertica-ui/ui';
import { MoreHorizontal } from 'lucide-react';

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Name</TableHead>
      <TableHead>Email</TableHead>
      <TableHead className="hidden md:table-cell">Role</TableHead>
      <TableHead>Status</TableHead>
      <TableHead className="text-right">Actions</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {records.map(record => (
      <TableRow key={record.id}>
        <TableCell className="font-medium">{record.name}</TableCell>
        <TableCell>{record.email}</TableCell>
        <TableCell className="hidden md:table-cell">{record.role}</TableCell>
        <TableCell>
          <Badge variant="outline">{record.status}</Badge>
        </TableCell>
        <TableCell className="text-right">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon" className="size-8">
                <MoreHorizontal className="size-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem>Edit</DropdownMenuItem>
              <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>;
```

---

## AI Rules

- Always wrap the `<Table>` and its filter row (search input, filter dropdowns) inside a single `<Card>` — not separate cards.
- Status values are always `<Badge>` — never plain text.
- The actions column is always the **last column** with `className="text-right"`.
- Actions inside cells always use `<DropdownMenu>` — never standalone inline buttons for more than one action.
- Use `className="hidden md:table-cell"` on less important columns for responsive hiding.
- The primary identifying column (name, title) uses `className="font-medium"`.

---

## Related Components

- [`Badge`](./badge.md) — For status cells
- [`DropdownMenu`](./dropdown-menu.md) — For row action menus
- [`Pagination`](./pagination.md) — For paginating large tables
- [`Card`](./card.md) — Wraps the filter row + table
