Data grid / foldkit-data-grid

One grid's state

DataGrid.make({ id, columns }) joins focus, the viewport and the column state into the one Bundle an application places for a grid. Its update is the parts' own; what it adds is the seam between them: a key that moves focus off screen scrolls the container.

ts
import { Option } from 'effect'
import { DataGrid } from 'foldkit-data-grid'

const Grid = DataGrid.make({ id: 'products', columns })

Grid.Message.Moved({
  address: { row: 'p2', column: 'price' },
  reveal: Option.some({ top: 64, left: 0 }),
})
// update focuses the cell and returns GridViewport.scrollTo('products', ...)
  • Focused is a cell focused by the pointer or the browser; it scrolls nothing.
  • Moved is a key's move, with reveal from VirtualGrid.reveal, worked out by the view from the viewport it drew. When it is some, the update issues the Command that scrolls the container whose DOM id is id.
  • Measured and Revealed are the viewport's, from GridViewport.Measure and the scroll Command.
  • ColumnResized, ColumnHidden, ColumnShown and ColumnMoved change the column state (below).
  • ResizeStarted, ResizeMoved and ResizeEnded are a pointer drag on a resize handle. The grid records the width the drag began at, so each move is measured from there, not summed; a cancelled drag puts the width back. A column that does not resize starts no drag.

The Model is { focus, viewport, columns, resizing } and encodes to plain data. Grid.project(rows, model.columns) is the projection for that state, built once per rows model and state, so the view and the application share it. GridFocus and GridViewport stay available for a grid that composes its own state.