An editable, virtualized grid your users will mistake for a native app.
Ops screens always end up wanting one: arrow keys that move like the spreadsheet your users came from, paste that accepts a whole block of cells, rows that drag into a new order, and virtualisation so ten thousand rows scroll like ten. Nobody should rent that as a SaaS widget. This one is source-shipped: install it, read the keyboard grid, and when your product needs a cell type nobody planned for, open the file and add it.
| Name | Reference | Stock |
|---|---|---|
Install
bun add @voila.dev/ui @tanstack/react-virtual@import "@voila.dev/ui/styles/sources.css";Or copy the source — it's the same files. Peers: react@19, react-dom@19,
tailwindcss@4.
The 3-minute win
A three-column stock grid. Your inputs go inside the cells, your state stays yours.
import { Spreadsheet } from "@voila.dev/ui/spreadsheet";
<Spreadsheet.Root>
<Spreadsheet.Columns>
<Spreadsheet.Column />
<Spreadsheet.Column width={130} />
<Spreadsheet.Column width={100} />
</Spreadsheet.Columns>
<Spreadsheet.Header>
<tr>
<Spreadsheet.Head>Name</Spreadsheet.Head>
<Spreadsheet.Head>Reference</Spreadsheet.Head>
<Spreadsheet.Head>Stock</Spreadsheet.Head>
</tr>
</Spreadsheet.Header>
<Spreadsheet.Body>
{rows.map((row) => (
<Spreadsheet.Row key={row.id}>
<Spreadsheet.Cell>
<Input value={row.name} onChange={…} />
</Spreadsheet.Cell>
<Spreadsheet.Cell>
<Input value={row.reference} onChange={…} />
</Spreadsheet.Cell>
<Spreadsheet.Cell>
<Input type="number" value={row.stock} onChange={…} />
</Spreadsheet.Cell>
</Spreadsheet.Row>
))}
</Spreadsheet.Body>
</Spreadsheet.Root>;Mental model
Spreadsheet.Root owns the state and the keyboard grid; every other part
draws into it. Cells hold your own inputs, so validation and formatting live
in your code, not in a cell renderer API. The grid never sorts or mutates your
rows: it reports intent (a paste, a reorder) and you update the array, so the
data stays the single source of truth. For rows that are read and exported
rather than edited, the answer is the other package; see
Which one do I need?
Page map
- Spreadsheet: the grid, its keyboard model, paste and reorder.
- Spreadsheet.NestedInput: a compact grid folded into a form field.
- Which one do I need?: read-heavy table or editable grid.