# Grid API reference

Type signatures for the public exports of @pretable/react.


Type signatures for the public API of `@pretable/react`. Hand-authored from the source at `packages/core/src/types.ts` and `packages/react-surface/src/use-pretable.ts`. Pre-1.0 — names may rename or remove in patch releases.

## `PretableColumn<TRow>`

A column definition. Generic over your row type.

| Field          | Type                                                    | Required | Description                                                                                                            |
| -------------- | ------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`           | `string`                                                | yes      | Unique column identifier. Used as React key, sort target, filter target, focus target.                                 |
| `header`       | `string`                                                | no       | Column header label. Defaults to the column `id` if omitted.                                                           |
| `wrap`         | `boolean`                                               | no       | If `true`, cells in this column wrap content vertically (sets `[data-pretable-wrap="true"]`).                          |
| `widthPx`      | `number`                                                | no       | Fixed pixel width. Defaults to 220 for wrapping columns, 140 for non-wrapping.                                         |
| `pinned`       | `"left"`                                                | no       | Pinned positioning. Currently only `"left"` is supported. Sets `[data-pinned="left"]` on the cell.                     |
| `sortable`     | `boolean`                                               | no       | Whether the column can be sorted. Defaults to `true` if a `value` is provided.                                         |
| `filterable`   | `boolean`                                               | no       | Whether the column can be filtered. Defaults to `true` if a `value` is provided.                                       |
| `value`        | `(row: TRow) => unknown`                                | no       | Extract the cell value from the row. If omitted, the column has no sortable/filterable value.                          |
| `format`       | `(input: PretableFormatInput<TRow>) => string`          | no       | Per-cell string formatter. Drives display and copy. See [Cell renderers](/docs/grid/cell-renderers).                   |
| `render`       | `(input: PretableCellRenderInput<TRow>) => ReactNode`   | no       | Per-cell ReactNode renderer. Receives `formattedValue` from `format`. See [Cell renderers](/docs/grid/cell-renderers). |
| `renderHeader` | `(input: PretableHeaderRenderInput<TRow>) => ReactNode` | no       | Per-column header renderer. See [Cell renderers](/docs/grid/cell-renderers).                                           |
| `minWidthPx`   | `number`                                                | no       | Per-column minimum width clamp. Applied during resize and autosize. Engine default min is 40.                          |
| `maxWidthPx`   | `number`                                                | no       | Per-column maximum width clamp. Applied during resize and autosize. Engine default max is 800.                         |
| `resizable`    | `boolean`                                               | no       | If `false`, the column has no resize handle and `setColumnWidth` is a no-op for it. Defaults true.                     |
| `reorderable`  | `boolean`                                               | no       | If `false`, header drag does not trigger reorder for this column. Defaults true.                                       |

## `PretableRow`

```ts
type PretableRow = Record<string, unknown>;
```

Your row type extends this. The engine treats rows as opaque records; only `getRowId` and `value` access fields.

## Selection types

The cell-range selection model. See [Selection](/docs/grid/selection) for the conceptual overview.

```ts
interface PretableCellAddress {
  rowId: string;
  columnId: string;
}

interface PretableCellRange {
  startRowId: string;
  endRowId: string;
  startColumnId: string;
  endColumnId: string;
}

interface PretableSelectionState {
  ranges: PretableCellRange[];
  anchor: PretableCellAddress | null;
}

interface PretableFocusState {
  rowId: string | null;
  columnId: string | null;
}

type PretableFocusDirection = "up" | "down" | "left" | "right";

interface PretableMoveFocusOptions {
  extend?: boolean; // shift+arrow
  jumpToEdge?: boolean; // cmd/ctrl+arrow
  byPage?: boolean; // page up/down
}

type RowSelectionTriState = "selected" | "indeterminate";
```

## Cell renderer types

Inputs passed to per-column `format`, `render`, and `renderHeader`.

```ts
interface PretableFormatInput<TRow extends PretableRow = PretableRow> {
  value: unknown;
  row: TRow;
  column: PretableColumn<TRow>;
}

interface PretableCellRenderInput<
  TRow extends PretableRow = PretableRow,
> extends PretableFormatInput<TRow> {
  formattedValue: string;
  rowId: string;
  rowIndex: number;
  isFocused: boolean;
  isSelected: boolean;
}

interface PretableHeaderRenderInput<TRow extends PretableRow = PretableRow> {
  column: PretableColumn<TRow>;
  label: string;
  sortDirection: "asc" | "desc" | null;
  isSorted: boolean;
}
```

`PretableCoreColumn<TRow>` is the engine-level (React-free) column type re-exported from `@pretable/core`. `PretableColumn<TRow>` extends it with the React-only `render` and `renderHeader` fields. Most consumers import `PretableColumn` from `@pretable/react`.

- `PretableCellAddress` — a single cell, identified by stable row + column id.
- `PretableCellRange` — a rectangular range over ids; survives sort/filter/reorder.
- `PretableSelectionState` — the engine's full selection slice (ranges plus the anchor for shift-extends).
- `PretableFocusState` — the focused cell address; nullable on each axis when focus has not landed yet.
- `PretableFocusDirection` — direction argument for `grid.moveFocus`.
- `PretableMoveFocusOptions` — modifier flags that turn `moveFocus` into shift-extend, edge-jump, or page-step.
- `RowSelectionTriState` — derived per-row state for the checkbox column header (full = `"selected"`, mixed = `"indeterminate"`; absent means unchecked).

## Surface configuration types

```ts
interface PretableSurfaceState {
  sort?: PretableSortState;
  filters?: Record<string, string>;
  selection?: PretableSelectionState;
  focus?: PretableFocusState;
  columnWidths?: Record<string, number>;
  columnOrder?: readonly string[];
  columnPinned?: Record<string, "left" | null>;
}

interface RowSelectionColumnConfig {
  enabled: true;
  position?: "left"; // v1: left only
  pinned?: boolean; // default true
  headerCheckbox?: boolean; // default true
  width?: number; // default 36
}

interface PretableSurfaceMessages {
  selectAllAnnouncement?: (args: {
    rowCount: number;
    columnCount: number;
    isAll: boolean;
  }) => string;
  copyAnnouncement?: (args: {
    rowCount: number;
    columnCount: number;
  }) => string;
  copyFailedAnnouncement?: () => string;
}
```

- `PretableSurfaceState` — the slice-based controlled-state shape passed via the surface's `state` prop. Each slice is independently controlled.
- `RowSelectionColumnConfig` — opts for the built-in checkbox column. Pass to `<PretableSurface>`'s `rowSelectionColumn` prop.
- `PretableSurfaceMessages` — overrides for the polite `aria-live` announcements (select-all and copy success/failure).

## Copy types

```ts
interface CopyPayload {
  text: string;
  html?: string;
}

interface SerializeRangesArgs<TRow> {
  ranges: readonly PretableCellRange[];
  visibleRows: readonly PretableVisibleRow<TRow>[];
  columns: readonly PretableColumn<TRow>[];
  copyWithHeaders?: boolean;
}
```

- `CopyPayload` — the return shape from `onCopy`. When `html` is present, the surface writes both `text/plain` and `text/html` to the clipboard.
- `SerializeRangesArgs<TRow>` — argument shape for `serializeRangesAsTsv` and any custom serializer.

## `PretableGrid<TRow>` — model methods

The `grid` returned by `usePretable`.

| Method                                                                        | Description                                                                                     |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `getSnapshot(): PretableGridSnapshot<TRow>`                                   | Read the current state.                                                                         |
| `subscribe(listener: () => void): () => void`                                 | Subscribe to state changes. Returns an unsubscribe fn.                                          |
| `setSort(columnId: string \| null, direction: "asc" \| "desc" \| null): void` | Set the sort state. Pass `null` to clear.                                                       |
| `setFilter(columnId: string, value: string): void`                            | Set a filter value for one column.                                                              |
| `clearFilters(): void`                                                        | Remove all filters.                                                                             |
| `replaceFilters(map: Record<string, string>): void`                           | Replace all filters with a new map.                                                             |
| `setSelection(state): void`                                                   | Replace the full selection state ({ ranges, anchor }).                                          |
| `selectAll(): void`                                                           | Select every visible cell as a single full-grid range.                                          |
| `clearSelection(): void`                                                      | Collapse selection to the focused cell (or empty if no focus).                                  |
| `addRange(range): void`                                                       | Append a discontiguous cell range; updates the anchor to the range start.                       |
| `extendRangeFromAnchor(addr): void`                                           | Replace the active range with one spanning anchor → addr.                                       |
| `toggleRowSelection(rowId: string): void`                                     | Add or remove a full-row range for the given row.                                               |
| `setSelectAllVisible(checked: boolean): void`                                 | Toggle full-row ranges across all currently visible rows.                                       |
| `setFocus(addr: { rowId, columnId } \| null): void`                           | Set the focused cell.                                                                           |
| `moveFocus(direction, options?): void`                                        | Move focus in `"up" \| "down" \| "left" \| "right"`; options: `extend`, `jumpToEdge`, `byPage`. |
| `setViewport({scrollTop, scrollLeft, height, width}): void`                   | Update viewport metrics. Wire to your scroll container's `onScroll`.                            |
| `applyTransaction({add?, update?, remove?}): void`                            | Live-update rows. `add` appends, `update` patches by `id`, `remove` deletes by `id`.            |
| `autosizeColumns(opts?): void`                                                | Resize columns to content. Optional `AutosizeOptions` controls the algorithm.                   |

### Column layout actions

| Method                                                              | Description                                                                                     |
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `setColumnWidth(columnId: string, width: number): void`             | Set a column's width. Clamps to per-column `minWidthPx` / `maxWidthPx` and engine-wide bounds.  |
| `moveColumn(columnId: string, toIndex: number): void`               | Reposition a column. Cross-boundary lands auto-pin/unpin to match the destination region.       |
| `setColumnPinned(columnId: string, pinned: "left" \| null): void`   | Explicit pin/unpin. Repositions the column to the pin-region boundary.                          |
| `autosizeColumn(columnId: string, options?: AutosizeOptions): void` | Autosize a single column to its measured content width.                                         |
| `resetColumnLayout(): void`                                         | Restore order, widths, and pinned state to the original `columns` prop snapshot taken at mount. |
| `mergeColumnsFromProps(nextColumns: PretableColumn<TRow>[]): void`  | Internal: called by `usePretable` when the columns prop's id list changes structurally.         |

## `PretableGridSnapshot<TRow>`

```ts
interface PretableGridSnapshot<TRow> {
  viewport: {
    scrollTop: number;
    scrollLeft: number;
    height: number;
    width: number;
  };
  sort: { columnId: string | null; direction: "asc" | "desc" | null };
  filters: Record<string, string>;
  selection: {
    ranges: Array<{
      startRowId: string;
      endRowId: string;
      startColumnId: string;
      endColumnId: string;
    }>;
    anchor: { rowId: string; columnId: string } | null;
  };
  focus: { rowId: string | null; columnId: string | null };
  totalRowCount: number;
  visibleRows: { id: string; row: TRow; sourceIndex: number }[];
  visibleRange: { start: number; end: number };
}
```

Read via `grid.getSnapshot()` or directly from the `usePretable` return value.

## `UsePretableOptions<TRow>` — `usePretable` arguments

```ts
interface UsePretableOptions<TRow> {
  columns: PretableColumn<TRow>[];
  rows: TRow[];
  getRowId?: (row: TRow, index: number) => string;
  autosize?: boolean | AutosizeOptions;
}
```

`usePretable` returns just the `grid` model. Use it when you only need interaction state, not virtualization.

## `UsePretableOptions<TRow>` — `usePretable` arguments

```ts
interface UsePretableOptions<TRow> extends UsePretableOptions<TRow> {
  viewportHeight: number;
  viewportWidth?: number;
  overscan?: number; // default 6
  state?: PretableSurfaceState | null;
  measuredHeights?: Record<string, number>;
  onSelectionChange?: (next: PretableSelectionState) => void;
  onFocusChange?: (next: PretableFocusState) => void;
}

interface PretableSurfaceState {
  sort?: PretableSortState;
  filters?: Record<string, string>;
  selection?: PretableSelectionState;
  focus?: PretableFocusState;
  columnWidths?: Record<string, number>;
  columnOrder?: readonly string[];
  columnPinned?: Record<string, "left" | null>;
}
```

`usePretable` returns `{grid, snapshot, renderSnapshot, telemetry}`. Use it when you need virtualization metadata for custom rendering.

## `PretableModel<TRow>` — `usePretable` return

```ts
interface PretableModel<TRow> {
  grid: PretableGrid<TRow>;
  snapshot: PretableGridSnapshot<TRow>;
  renderSnapshot: PretableRenderSnapshot<TRow>;
  telemetry: PretableTelemetry;
}
```

## `PretableRenderSnapshot<TRow>`

Tells you which rows to render and where to position them.

```ts
interface PretableRenderSnapshot<TRow> {
  columns: PlannedColumn[];
  rows: PretableRenderRow<TRow>[];
  nodeCount: number;
  totalHeight: number;
  totalWidth: number;
}

interface PretableRenderRow<TRow> {
  id: string;
  row: TRow;
  rowIndex: number;
  top: number;
  height: number;
}

interface PlannedColumn {
  id: string;
  index: number;
  left: number;
  width: number;
  pinned?: "left";
}
```

`renderSnapshot.rows` is the slice of rows currently visible in the viewport (plus overscan). Each has `top` (the absolute Y position) and `height` (the row's height — measured if you provided `measuredHeights`, otherwise estimated). Use these to position your row JSX with `position: absolute; top: ${row.top}px; height: ${row.height}px`.

`renderSnapshot.columns` is the column layout — left offset and width per column, accounting for pinned positioning.

## `PretableTelemetry`

```ts
interface PretableTelemetry {
  focusedRowId: string | null;
  rowModelRowCount: number;
  renderedRowCount: number;
  selectedRowId: string | null;
  totalRowCount: number;
  totalHeight: number;
  visibleRowCount: number;
  visibleRowRange: { start: number; end: number };
}
```

Useful for instrumentation (frame budget tracking, visible-row counts, focus survival across filters).

## Hook signatures

```ts
function usePretable<TRow>(opts: UsePretableOptions<TRow>): PretableGrid<TRow>;

function usePretable<TRow>(opts: UsePretableOptions<TRow>): PretableModel<TRow>;

function useResolvedHeights(
  rowHeightProp?: number,
  headerHeightProp?: number,
): { rowHeight: number; headerHeight: number };

function measureRenderedRowHeight(node: HTMLElement): number;
```

## Where to go next

- [Custom rendering](/docs/grid/custom-rendering) — uses every type listed above in a runnable example.
- [Density helpers](/docs/grid/density-helpers) — `useResolvedHeights` and `getDensityHeights` deeper dive.
- [Theming Overview](/docs/theming) — the `[data-pretable-*]` attribute contract that pairs with this engine.
