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', ...)Focusedis a cell focused by the pointer or the browser; it scrolls nothing.Movedis a key's move, withrevealfromVirtualGrid.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 isid.MeasuredandRevealedare the viewport's, fromGridViewport.Measureand the scroll Command.ColumnResized,ColumnHidden,ColumnShownandColumnMovedchange the column state (below).ResizeStarted,ResizeMovedandResizeEndedare 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.