Data grid / foldkit-data-grid

The clipboard

Copy and paste speak the tab-separated text spreadsheets do. Clipboard is pure: it writes and reads that text and lays a paste onto the grid; the view wires it to the browser's copy, cut and paste events.

ts
Clipboard.toTsv([['SKU', 'Price'], ['A-1', '9']]) // 'SKU\tPrice\nA-1\t9'
Clipboard.parseTsv('a\t"b\tc"\r\n') // [['a', 'b\tc']]
  • Clipboard.copy(projection, box, textOf) is a box's cells as TSV, rows in the projection's order and columns in display order.
  • Clipboard.pasteAt(projection, anchor, matrix, { editable, from }) is where pasted text lands: laid from the anchor, dropping cells past the edges, on columns that do not edit, or on rows not loaded. Each cell keeps from(address), the text it showed, as an edit would begin from.
  • Fill carries a range on, as a spreadsheet's fill does, and is pure. Fill.plan(projection, { source, to }) is the source's box and the box beyond it toward to, along one axis (toward: down, up, right or left; rows win a diagonal). Fill.cells(projection, plan, { editable, from }) is the cells it writes, each lane of the source carried on by Fill.series(texts, count, backward): two or more numbers a constant step apart continue their step, keeping the finest decimals, and anything else repeats in order. Like a paste, it drops columns that do not edit and rows not loaded, and keeps each cell's from.
  • Pasted({ cells }) hands those cells to the grid, which drops each one its text leaves unchanged (as an edit judges it), checks the rest against their columns' schema, and reports one Out.Pasted({ accepted, refused }): one change for the application to apply, and say what it refused. A paste or cut that changes no cell reports nothing. A paste while a cell is edited is the field's.
  • UndoRequested and RedoRequested (Ctrl or Meta with Z, with Shift or Ctrl+Y to redo) report Out.UndoRequested and Out.RedoRequested. They carry nothing: the grid keeps no history, since what an edit meant and how to take it back are the application's, read from its Model when the request arrives. While a cell is edited they are the field's.
  • A fill comes from Ctrl or Meta with D (down) or R (right) over a range, FillRequested, or from dragging the range's fill handle (FillStarted, FillDragged, FillEnded, the drag held in the Model's filling), and reports Out.Filled({ source, to }): the range, and the cell it was carried to. The grid holds no rows, so the application works out what it writes when it arrives, Grid.fill(rows, model.grid, request), with the rows it draws: { accepted, refused }, judged as a paste's cells are (Fill.plan and Fill.cells, above). A fill from a lone cell, or by key from a range one row tall, carries on the cell above (or before) it.