React Inline-Editable Grid
The screen where ops fixes the data without leaving the page. Double-click a cell to edit; each column validates its own input, changed cells are flagged, and nothing is sent until Save — with Revert always one click away.
No changes
SKU
Name
Price ($)
Stock
Status
AES-256-P
AES-256 GCM Core
$214
1,240
active
SHA3-512
SHA-3 Hash Engine
$142
860
active
MLKEM-768
ML-KEM Accelerator
$580
0
backorder
TRNG-90B
True RNG
$87
3,100
active
HSM-PCIE
PCIe HSM Card
$4,200
12
eol
Double-click a cell to edit · Enter to commit · Esc to cancel
Installation
npx shadcn@latest add "https://kelvinui.com/registry/editable-grid.json"
Props
| Prop | Type | Description |
|---|---|---|
| rows | T[] | Initial data |
| columns | EditableColumn<T>[] | { key, header, type?, editable?, options?, validate?, format? } |
| rowKey | (row: T) => string | Stable identity per row |
| onSave | (changed: T[]) => void | Receives only the changed rows |
Dirty state, validation, and commit
Three behaviours make this trustworthy enough for real edits:
- Dirty tracking is by value, not by touch. A cell is dirty only if its current value differs from the original snapshot — type a new value and type the old one back, and the flag clears. Only genuinely changed rows go to
onSave. - Validation blocks the commit, not the keystroke. You can type freely; on Enter (or blur) the column's
validateruns, and a failure keeps the cell in edit mode with the error shown rather than discarding your input. Save is disabled while any error stands. - Revert restores the snapshot. No undo stack to reason about — one button returns every cell to where it started.
type is text, number, or select; editable: false marks a read-only column (the SKU in the demo). Enter commits, Escape cancels — the two keys people already expect from a spreadsheet.
New components every week
Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.