Data grid / foldkit-data-grid

Virtualization

A grid draws only what its scroll container shows. The container's scroll offsets and size are the fact; GridViewport keeps them in the Model, and VirtualGrid.window turns them into the rows and columns to draw.

ts
import { VirtualGrid } from 'foldkit-data-grid'

const shown = VirtualGrid.window({
  projection: grid,
  rowHeight: 32,
  width: column => (column === 'sku' ? 120 : 80),
  viewport: { top: 0, left: 0, width: 600, height: 320 },
  overscan: { rows: 4, columns: 1 },
})
// shown.rows: { start: 0, end: 2, before: 0, after: 0 }: draw rows [start, end)
// shown.start, shown.centerColumns, shown.end: the columns to draw, in order
// shown.width, shown.height: the size of the scrollable content
  • VirtualGrid.window(options) is pure. Rows are one fixed height, so the row window is arithmetic on the scroll offset and never walks the rows; the center columns are found by binary search over their widths. Pinned columns are always drawn, outside the horizontal window. before and after are the space the undrawn rows and columns take, for spacers. headerHeight leaves header rows inside the container out of the body. It throws for a row height that is not a positive number.
  • Grid.window({ rows, state, rowHeight, headerHeight, overscan }) is that window for a placed grid, as foldkit-mixins-data-grid's view works it out from the same input: to say how many rows are drawn, read it here rather than estimating.
  • VirtualGrid.reveal(options) is the least scroll that shows a cell, as { top, left }, or none when it is already in view. A pinned column never scrolls, so only its row is brought in.
  • GridViewport.bundle holds { top, left, width, height }. GridViewport.Measure is a Mount for the scroll container: it reports the geometry when it mounts and on every scroll and resize. Readings that are not numbers are ignored, and an overscroll reads as the edge.
  • GridViewport.scrollTo(viewportId, offsets) is the Command that applies a reveal: it scrolls the container and reports Revealed, so the next window is drawn from the new offsets without waiting for the scroll event.

packages/data-grid/bench measures this at 100,000 rows; see the benchmarks.