# DataTable

> Shows records in rows and columns that people can sort, select and page through.

- **Level**: organism · **Status**: stable · **Role**: content
- **Import**: `import { DataTable, DataTableEmpty, DataTableHeader, DataTableLoading, DataTablePagination, DataTableRow } from "@rrios-forge/ui/organisms/data-table";`
- **Source**: `packages/ui/src/organisms/data-table`

**Purpose.** The tabular surface organism. `DataTable` composes the molecule layer (`TableHeader`, `TableRow`, `TablePagination`, `EmptyState`, `LoadingState`) into a single coordinated component that owns row rendering, selection ergonomics, sort affordance and density propagation — but never the data itself.

**When to use.**
- A list of structured records that benefits from columns, sorting, and per-row actions.
- A surface where the user needs to *select* one or many rows for a follow-up operation (`selection="multiple"`).
- A list whose layout must stay stable across loading, empty and error states (the chrome remains; the row area swaps).

**When NOT to use.**
- A scrolling feed of heterogeneous items → use `Card` or `ListItem` compositions inside a list shell.
- A dashboard of metrics → use `MetricCard` / `Card` instead.
- A small fixed list (≤ 5 rows) where columns add ceremony without value → use a `dl` / property list.
- A tree, kanban or timeline view — these need their own organism, not a `DataTable` with hidden columns.

**Composes with.**
- `DataTableToolbar` (consumer-passed `toolbar` slot) — search, filter, bulk actions.
- `DataTablePagination` (consumer-passed `pagination` slot) or `TablePagination` molecule directly.
- `DataTableEmpty`, `DataTableLoading` — exposed for swap-in customisation.
- `Badge`, `Avatar`, `IconButton`, `DropdownMenu` inside cells via column `render`.
- `PageShell mainPadding="flush"` to host the table edge-to-edge inside a Card.

**Accessibility.**
- Renders `<section role="region" aria-label>` so the table is an announced region.
- Header cells expose `aria-sort` when `sortable`; the sort glyph is decorative.
- Selection checkboxes carry explicit `aria-label`. The header tri-state checkbox announces `mixed` via `aria-checked`.
- Loading renders skeleton rows inside `role="status"` + `aria-live="polite"` (shape-preserving, per Patterns/System States); empty exposes `role="status"`. Neither state ever overlays stale rows.

**Related patterns.**
- `Patterns/System States · StateChoice` — Empty / Loading / Error are first-class states the organism honours.
- `Patterns/Density & Growth · DensityLevels` — when to pick `compact` vs `comfortable`.
- `Patterns/Navigation · PaginationForDatasets` — pagination over infinite scroll.
- `Patterns/Decision Matrix · ComponentChoice` — DataTable vs ListItem vs Card.

## Use it for

- Table → `DataTable`, or `TableHeader` + `TableRow` + `TablePagination`
- A chart (trend, comparison, part to whole) → `Chart` with the `form` the data's job names (`dataviz.yaml`); a single number is a `MetricCard`, many classes a `DataTable`

## Axes

| Axis | Part | Values | Default | Meaning |
|---|---|---|---|---|
| `density` | — | `compact` `comfortable` | — | — |
| `selection` | — | `none` `multiple` | — | — |

## Stories

- [Playground](/?path=/story/components-organisms-datatable--playground) · frame: `/iframe.html?id=components-organisms-datatable--playground&viewMode=story`
- [Loading](/?path=/story/components-organisms-datatable--loading) · frame: `/iframe.html?id=components-organisms-datatable--loading&viewMode=story`
- [Empty](/?path=/story/components-organisms-datatable--empty) · frame: `/iframe.html?id=components-organisms-datatable--empty&viewMode=story`
- [With filters](/?path=/story/components-organisms-datatable--with-filters) · frame: `/iframe.html?id=components-organisms-datatable--with-filters&viewMode=story`
- [With pagination](/?path=/story/components-organisms-datatable--with-pagination) · frame: `/iframe.html?id=components-organisms-datatable--with-pagination&viewMode=story`
- [Selectable rows](/?path=/story/components-organisms-datatable--selectable-rows) · frame: `/iframe.html?id=components-organisms-datatable--selectable-rows&viewMode=story`
- [Dense](/?path=/story/components-organisms-datatable--dense) · frame: `/iframe.html?id=components-organisms-datatable--dense&viewMode=story`
- [Row actions](/?path=/story/components-organisms-datatable--row-actions) · frame: `/iframe.html?id=components-organisms-datatable--row-actions&viewMode=story`
- [Status column](/?path=/story/components-organisms-datatable--status-column) · frame: `/iframe.html?id=components-organisms-datatable--status-column&viewMode=story`
- [Full example](/?path=/story/components-organisms-datatable--full-example) · frame: `/iframe.html?id=components-organisms-datatable--full-example&viewMode=story`

## Patterns consulted

- Patterns/Density & Growth · DensityLevels
- Patterns/Density & Growth · ContentGrowth
- Patterns/Navigation · PaginationForDatasets
- Patterns/Feedback · LoadingFeedback
- Patterns/Information Architecture · MetadataAndActions
- Patterns/Visual Priority · QuietSecondaryActions
- Patterns/Decision Matrix · ComponentChoice
- Patterns/System States · StateChoice

## Decisions that name it

- ADR-003 — Storybook editorial convention and pattern↔component bidirectionality
- ADR-004 — Migrate boolean configuration props to semantic axes
- ADR-005 — Visual operational rules: surfaces, interaction, motion
- ADR-006 — Geometry and typography signature
- ADR-013 — PageShell: mobile-nav polymorphism
- ADR-034 — Accessible names come from a labels provider
- ADR-035 — Motion grammar: the gate before motion, slop by repetition, and what reduced motion keeps

## Always

- Tokens only (R04); variants are semantic axes, never appearance (R02).
- Typography and actions are Poesía atoms, never raw HTML with utilities.
- Vibrant panes need a ground and never nest (ADR-027).
