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:
- Sort/filter UI (the engine handles state, but
<Pretable>doesn't render the controls) - Selection state controlled from your component
- Custom cell rendering
- Pinned columns (controlled rendering)
- Density-prop overrides (CSS-driven only via
[data-density]on<html>)
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:
- You need a real production grid with sort/filter/selection/focus
- You want custom cell rendering (different per-column React components)
- You're building a wrapper around the engine for your design system
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:
- Column autosize — the
autosizeoption onusePretableandusePretableModel; resizes columns to content. Not yet documented as a recipe. - Streaming and transactions —
grid.applyTransaction({add, update, remove})for live row updates. Streaming Overview lands in a subsequent docs PR. - Per-row measured heights — pass
measuredHeights: Record<string, number>tousePretableModelfor content-aware row sizing. The bench'spretable-adapter.tsxshows this pattern.
These ship as part of @pretable/react today; full doc coverage lands in subsequent releases.
Where to go next
- <Pretable> component — drop-in recipe with the 3-prop API.
- Custom rendering —
usePretableModelwalkthrough with code. - Density helpers —
useResolvedHeightsandgetDensityHeights. - API reference — model methods + types.
- Theming Overview — how the data-attribute contract gets styled.