title: Grid Overview description: Two paths for using Pretable's grid engine — the drop-in Pretable component, or the usePretable / usePretableModel hooks for custom rendering.

Grid Overview

Pretable's React engine ships two consumer paths. Pick the one that matches what you're building.

The two paths

Path 1: <Pretable> drop-in

import { Pretable } from "@pretable/react";

<Pretable rows={rows} columns={columns} />;

A 3-prop component that renders a basic grid. Internally it wraps the engine with sensible defaults — label-above-value layout, 320px viewport. Use this when you want a working grid with one import and don't need sort UI, filter UI, selection state in your component tree, or custom cell rendering.

What <Pretable> does NOT support out of the box:

If you need any of the above, jump to Path 2.

Path 2: usePretable / usePretableModel hooks (custom rendering)

import { usePretableModel } from "@pretable/react";

function MyGrid({ rows, columns }) {
  const { grid, snapshot, renderSnapshot, telemetry } = usePretableModel({
    columns,
    rows,
    viewportHeight: 480,
  });

  // Render your own JSX, applying [data-pretable-*] attributes for styling
  return /* ... */;
}

The hooks return the grid model and the virtualized render snapshot. You write your own JSX, applying the data-attribute contract so @pretable/ui/grid.css styles your output. You wire interaction by calling grid.setSort, grid.replaceFilters, grid.selectRow, grid.setFocus — the engine maintains the state, you render the UI.

Use this when:

See Custom rendering for the recipe with a working example.

The data-attribute contract

Both paths emit the same [data-pretable-*] data attributes on grid elements. @pretable/ui/grid.css styles those attributes. The contract:

| Attribute | Element | Purpose | | --------------------------------- | ------------------------------------- | -------------------------------------------------------------------------- | | [data-pretable-scroll-viewport] | the scrollable container | Outer chrome, focus ring, fixed height | | [data-pretable-scroll-content] | the absolute-positioned content layer | Total scroll height for virtualization | | [data-pretable-header-row] | the sticky header row | Header background, bottom border | | [data-pretable-header-cell] | each header column button | Header text, sort indicator | | [data-pretable-row] | each body row | Row positioning (position: absolute + top) | | [data-pretable-cell] | each body cell | Cell background, padding, font, gridlines | | [data-pretable-wrap] | each body cell (modifier) | "true" on cells with column.wrap; coexists with [data-pretable-cell] | | [data-pinned]="left" | pinned cells (header + body) | Sticky left positioning, distinct background | | [data-selected]="true" | selected cells | Selection background and text color | | [data-focused]="true" | focused row + cell | Focus outline; mirrored on row and cell so CSS can target either |

Path 1 (<Pretable>) emits these automatically. Path 2 (custom rendering) requires you to apply them yourself — @pretable/ui/grid.css only styles elements that match these selectors. See Custom rendering for examples.

Engine reads two CSS variables in JS

For row virtualization, the engine needs rowHeight and headerHeight as numbers (to compute row top positions and the body viewport height). It reads --pretable-row-height and --pretable-header-height from <html>'s computed style via the useResolvedHeights hook. When you flip data-density="..." on <html>, the engine re-renders with new heights automatically.

The other 22 tokens in the theming contract are CSS-only — they style the data-attribute selectors but don't enter JavaScript.

See Density helpers for the hook API and SSR considerations.

What's not yet documented

The engine has more capabilities than this section covers:

These ship as part of @pretable/react today; full doc coverage lands in subsequent releases.

Where to go next