# Collection Components

> Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.

## Table

Data table with sorting, pagination, and row selection. Zero-config `<Table data columns />` renders bare; selection, sorting, pagination, and resize are opt-in via `tableConfig`.

**Props:**

- `data` - Array of row objects (must have `id` field)
- `columns` - Array of `ColumnDefinition` objects
- `columnOrder` - Optional column order (defaults to column definition order)
- `pagination` - `{ current, size, total, onChange }`
- `sorting` - `{ columns, direction, onChange }` (max 3 sort columns)
- `onSelect` - Callback with selected row IDs
- `onCellChange` - Write-back from `editable` cells: `({ rowId, columnId, slug, value }) => void` (data stays consumer-controlled)
- `loading` - Show loading skeleton
- `tableConfig` - Optional; `{ preset, rowSelection, sort, pagination, header, density, columnBorders, tableBorders, resize, autoHeight }`

`preset: "classic"` restores the legacy look in one key; `resize` gates column drag handles; the pagination footer is opt-in (`pagination: true`).

```tsx
<Table
  data={users}
  columns={columns}
  pagination={{ current: 1, size: 10, total: 100, onChange: setPagination }}
  sorting={{ columns: ["name"], direction: "asc", onChange: setSorting }}
  onSelect={setSelectedIds}
  tableConfig={{ rowSelection: true, resize: true }}
/>
```

## ColumnDefinition

Define table columns using the `defineColumn()` helper.

**Fields:**

- `slug` - Field key in data object
- `label` - Column header text
- `type` - Data type: `text`, `number`, `boolean`, `date`, `enum`, `user`
- `component` - Renderer (defaults from `type`): `text`, `number`, `boolean`, `date`, `select`, `multiselect`, `slider`, `rating`, `status`, `priority`, `assignee`, `sparkline`, `date-range`
- `hidden` - Hide column
- `editable` - Activate the interactive widget; columns render the read-only display variant by default
- `metadata` - Component-specific options (see table below)
- `display` - `{ width, sortable }` (width optional — columns are fluid when unset)
- `cell` - Custom render function `(row) => ReactNode`

For full control, pass your own `cell()` or import a renderer from `@nurix/components/block/table` (`StatusPill`, `SelectCell`, etc.) as an escape hatch.

### Metadata options by component

| Component | Options |
| --- | --- |
| Text/Number | `placeholder`, `prefix`, `suffix`, `prefixIcon` |
| Number/Slider | `min`, `max`, `step`, `stepButtons` [arrows \| plusminus \| none] |
| Enum/Select | `options: [{ value, label, color }]` |
| Date | `relativeFormat` |
| Date Range | `showPresets` |
| Rating | `allowHalf` |
| Sparkline | `sparklineType` [bar \| line \| pie \| stacked], `sparklineWidth`, `sparklineHeight`, `sparklineGap`, `sparklineStrokeWidth`, `sparklineColors` |

### Example

```tsx
import { defineColumn } from "@nurix/components/block/table";

const columns = [
  defineColumn({
    slug: "name",
    label: "Name",
    type: "text",
    editable: true,
  }),
  defineColumn({
    slug: "status",
    label: "Status",
    type: "enum",
    component: "status",
    metadata: {
      options: [{ value: "active", label: "Active", color: "#22c55e" }],
    },
  }),
  defineColumn({
    slug: "progress",
    label: "Progress",
    type: "number",
    component: "slider",
    metadata: { min: 0, max: 100 },
  }),
  defineColumn({
    slug: "createdAt",
    label: "Created",
    type: "date",
    metadata: { relativeFormat: true },
  }),
];
```

## PageHeader

Config-driven page masthead with an optional stat ledger — router-agnostic (the consumer owns navigation). Import from `@nurix/components/block/page-header`.

**Props:** `title`, `eyebrow` (breadcrumb segments — strings or linked `Crumb`s; last is the current page), `description`, `statusSlot`, `actions`, `stats` (`Stat[]` ledger), `back` (`BackLink`), `onBack`, `onNavigate` (fired with a crumb's/stat's `href`), `statsAlign` [left|right], `tall`

```tsx
<PageHeader
  title="Q3 Pipeline"
  eyebrow={["Sales", "Pipelines"]}
  actions={<Button size="sm">Export</Button>}
  stats={[{ label: "Open deals", value: "142" }, { label: "Won", value: "$1.2M" }]}
/>
```

## Conversation surfaces

Chat/AI message chrome; import each from its kebab-case subpath.

- `message` — docs-style message rows: `MessageGroup`, `Message`, `MessageAvatar`, `MessageHeader`, `MessageContent`, `MessageFooter`, `MessageStatus` (`status` [sending|sent|failed…] with icon + `data-status`)
- `message-scroller` — pinned-to-bottom scroll container for feeds: `MessageScrollerProvider`, `MessageScroller`, `MessageScrollerViewport`, `MessageScrollerContent`, `MessageScrollerItem`, `MessageScrollerButton` (jump-to-latest); hooks `useMessageScroller`, `useMessageScrollerScrollable`, `useMessageScrollerVisibility`
- `bubble` — chat-bubble rows: `BubbleGroup`, `Bubble`, `BubbleContent`, `BubbleReactions`
- `attachment` — file chips for composer/thread: `Attachment` (+ `AttachmentGroup`, `AttachmentMedia`, `AttachmentContent`, `AttachmentTitle`, `AttachmentDescription`, `AttachmentActions`, `AttachmentAction`, `AttachmentTrigger`); `size` [default|sm], dashed border in idle state, `data-[state=error]` styling
- `marker` — inline annotation row in a stream: `Marker`, `MarkerIcon`, `MarkerContent`; `variant` [default|separator|border]

## Other Collections

- `activity-timeline` — `GanttChart`: D3-based activity timeline (`Task`, `TaskStatus`, `ViewMode`, `GanttChartProps` types; `DEFAULT_STATUS_COLORS`, `getTaskDuration` helpers)
- `changes-list` — `ChangesList`: grouped change-history feed (`ChangeItem`, `EntityConfig`, `OperationConfig`, `GroupBy` types)
- `header` — `Header`: config-driven page header taking a single `config: HeaderConfig` (breadcrumbs, profile, status bar, grid, actions sections); sub-components `HeaderBreadcrumbs`, `HeaderActions`, `HeaderSection`, `HeaderCell`
- `list` — `List`: data list with `ListToolbar`, `ListPagination`, `ListItemErrorBoundary`
- `ui-table` — `UiTable`, `UiTableHeader`, `UiTableBody`, `UiTableFooter`, `UiTableHead`, `UiTableRow`, `UiTableCell`, `UiTableCaption`: bare HTML-table primitives; prefer `Table`
