A spreadsheet surface with lettered columns, numbered rows, an active cell, range selection, in-cell editing and copy and paste. Built on TanStack Table and the Table primitive.
Use Data Table for records: one row per item, with sorting, filters and pages. Use Data Grid when people work on cells: pick a cell, type, select a range, copy it into another app. The Sheets block is a full spreadsheet on it.
Move. Arrows, Tab and Shift Tab, Home and End, Page Up and Page Down. Ctrl or Cmd with an arrow jumps to the edge.
Select. Shift with an arrow or a click, or drag across cells. Click a letter or number to take the whole column or row, and the corner for everything. Ctrl A selects all.
Edit. Start typing to replace a cell, or press Enter, F2 or double click to edit what is there. Enter saves and moves down, Tab saves and moves right, Escape cancels.
Clipboard. Ctrl C, X and V copy, cut and paste ranges as tab separated text, so they round trip with Google Sheets and Excel. One copied value pasted over a range fills it. Delete clears the range.
Columns. Drag the edge of a column header to resize it, and double click the edge to reset it.
On touch, a tap selects a cell, a second tap edits it, and swipes scroll the grid.
Data.rowCount and columnCount. getCell(row, col) returns what a cell shows: content, align, wrap, className and style, or null for empty. getRawValue returns what it edits and copies, such as a formula. Keep both stable with useCallback, since rows only repaint when they change.
Changes.onCellsChange gets every edit, paste and clear as one batch of { row, col, value }.
Selection.selection and onSelectionChange, or defaultSelection. The anchor is the active cell and focus is the other corner. gridRange, rangeName and cellName turn them into "B3:D9" style names.
Layout.columnSizing and onColumnSizingChange by column letter, defaultColumnWidth, rowHeight, zoom, frozenRows, frozenColumns, merges for horizontal merges keyed "row:col", and gridlines.
Editing extras.onDraftChange reports the draft while a cell is open, so a formula bar can follow it. getSuggestions shows a list under the editor, picked with the arrows and Tab. transformPaste and onCopyRange let you rewrite pasted values, like shifting formula references.
Ref.focus(), edit(initial), select(selection), copy(cut) and paste(text).
The grid scrolls on both axes inside its own frame, with the header row and row numbers pinned and the edges fading where there is more to see.