Data Grid

Pro

A spreadsheet in your app: select a cell or a range, type over it, paste a block from Excel or Sheets and undo it in one step. Calm rows at rest; the column rules arrive when the grid has focus.

SKU
Product
Supplier
Category
Stock
Unit price
Value
Updated
Active
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
€1,041.60
Nov 4, 2026
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
€1,247.00
Nov 2, 2026
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
€648.00
Oct 29, 2026
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
Oct 29, 2026
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
€1,344.00
Nov 6, 2026
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
€1,116.00
Nov 1, 2026
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
€523.60
Oct 27, 2026
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
€81.00
Nov 5, 2026
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
€1,067.50
Nov 3, 2026
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
€125.00
Oct 30, 2026
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
€154.00
Nov 7, 2026
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40
€258.40
Nov 4, 2026

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add data-grid

Usage#

Pass columns and rows, and take the next rows back in onRowsChange. DataGridViewport is the scrolling grid and needs a height; DataGridStatusBar is optional. For a table people read rather than edit, use Data Table.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import { DataGrid, DataGridViewport, DataGridStatusBar } from "@/components/ui/data-grid"<DataGrid columns={columns} rows={rows} onRowsChange={setRows}>  <DataGridViewport />  <DataGridStatusBar /></DataGrid>

Column types#

The type picks the editor and how a value reads, sorts, copies and pastes. Select a cell and press Enter to edit it.

SKU
Product
Supplier
Category
Stock
Unit price
Value
Updated
Active
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
€1,041.60
Nov 4, 2026
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
€1,247.00
Nov 2, 2026
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
€648.00
Oct 29, 2026
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
Oct 29, 2026
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
€1,344.00
Nov 6, 2026
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
€1,116.00
Nov 1, 2026
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
€523.60
Oct 27, 2026
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
€81.00
Nov 5, 2026
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
€1,067.50
Nov 3, 2026
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
€125.00
Oct 30, 2026
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
€154.00
Nov 7, 2026
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40
€258.40
Nov 4, 2026
  • text: an input in the cell.
  • number and currency: right-aligned in tabular figures; pasted text like €1,240.50 reads as 1240.5.
  • select: a badge; Enter opens the options, typing filters them.
  • date: Enter opens the calendar; typing a date also works. Stored as YYYY-MM-DD.
  • checkbox: Space or a click toggles it in place.
  • A column with value is computed and read-only, like Value here.

Keyboard#

Spreadsheet keys, with Ctrl on Windows and Cmd on a Mac.

ArrowsMove one cell. With Shift, grow the range.
Ctrl/Cmd + ArrowsJump to the edge of the data. With Shift, grow the range to it.
Home, EndStart or end of the row. With Ctrl/Cmd, the first or last cell.
Page Up, Page DownOne screen of rows.
Tab, Shift + TabNext or previous cell; at the row's end, focus leaves the grid.
Enter, F2, double-clickEdit in place: the arrows move the caret.
Type a characterReplace the cell: the arrows commit and move.
Enter, Shift + EnterWhile editing: commit and move down or up.
Ctrl/Cmd + EnterWhile editing: write the value into every selected cell.
EscapeCancel the edit, or collapse the range and clear the copy marker.
Delete, BackspaceClear the selected cells.
SpaceToggle a checkbox cell.
Shift + Space, Ctrl + SpaceSelect the row or the column.
Ctrl/Cmd + ASelect every cell.
Ctrl/Cmd + C, X, VCopy, cut and paste as TSV and HTML.
Ctrl/Cmd + Z, Shift + Z or YUndo, redo.
Arrow Up on the first rowMove into the header: Enter sorts, Alt + Arrows resize.

Row numbers and gridlines#

rowNumbers adds a frozen number column; click a number to select the row. gridlines="all" keeps the column rules on at rest, for finance sheets.

SKU
Product
Supplier
Category
Stock
Unit price
1
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
2
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
3
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
4
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
5
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
6
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
7
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
8
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
9
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
10
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
11
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
12
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40

Validation#

Return a message from validate to reject a value: the editor stays open, shakes once and shows the message under the cell. A value already in the data that fails shows a corner mark. Try a letter or a negative number in Stock.

SKU
Product
Supplier
Category
Stock
Unit price
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40

Saving changes#

onRowsChange fires once per action with patches, so a paste of 200 cells is one call and one undo step. Send the patches to your server instead of diffing the rows.

SKU
Product
Supplier
Category
Stock
Unit price
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40
  • Edit, paste or press Delete to see the patches.

Adding rows and columns#

onAddRow shows a New row row at the end and moves to it; onAddColumn shows a + at the end of the header. The grid never invents data: you append it.

SKU
Product
Supplier
Category
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
KP-2211
Washer M8, steel
Calder & Co
Hardware
KP-3007
A4 paper, 80 g
Brightline
Office
KP-3008
Toner cartridge, black
Brightline
Office
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
KP-3015
Sticky notes, yellow
Brightline
Office
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning

Large data#

Only the rows in view are mounted, so ten thousand rows scroll and select like twelve. Ctrl+End jumps to the last cell; Ctrl+Shift+End selects to it and the status bar sums the lot.

SKU
Product
Supplier
Category
Stock
Unit price
Value
Updated
Active
KP-10000
Box 1
Nordhaven Supply
Packaging
0
€0.10
€0.00
Jan 1, 2026
KP-10001
Film 1
Calder & Co
Hardware
37
€0.23
€8.51
Feb 2, 2026
KP-10002
Bolt 1
Brightline
Office
74
€0.36
€26.64
Mar 3, 2026
KP-10003
Washer 1
Oakmere
Cleaning
111
€0.49
€54.39
Apr 4, 2026
KP-10004
Paper 1
Nordhaven Supply
Packaging
148
€0.62
€91.76
May 5, 2026
KP-10005
Toner 1
Calder & Co
Hardware
185
€0.75
€138.75
Jun 6, 2026
KP-10006
Cleaner 1
Brightline
Office
222
€0.88
€195.36
Jul 7, 2026
KP-10007
Gloves 1
Oakmere
Cleaning
259
€1.01
€261.59
Aug 8, 2026
KP-10008
Tape 1
Nordhaven Supply
Packaging
296
€1.14
€337.44
Sep 9, 2026
KP-10009
Ties 1
Calder & Co
Hardware
333
€1.27
€422.91
Oct 10, 2026
KP-10010
Notes 1
Brightline
Office
370
€1.40
€518.00
Nov 11, 2026
KP-10011
Towels 1
Oakmere
Cleaning
407
€1.53
€622.71
Jan 12, 2026
KP-10012
Box 2
Nordhaven Supply
Packaging
444
€1.66
€737.04
Feb 13, 2026
KP-10013
Film 2
Calder & Co
Hardware
481
€1.79
€860.99
Mar 14, 2026
KP-10014
Bolt 2
Brightline
Office
518
€1.92
€994.56
Apr 15, 2026
KP-10015
Washer 2
Oakmere
Cleaning
555
€2.05
€1,137.75
May 16, 2026
KP-10016
Paper 2
Nordhaven Supply
Packaging
592
€2.18
€1,290.56
Jun 17, 2026
KP-10017
Toner 2
Calder & Co
Hardware
629
€2.31
€1,452.99
Jul 18, 2026
KP-10018
Cleaner 2
Brightline
Office
666
€2.44
€1,625.04
Aug 19, 2026
KP-10019
Gloves 2
Oakmere
Cleaning
703
€2.57
€1,806.71
Sep 20, 2026
KP-10020
Tape 2
Nordhaven Supply
Packaging
740
€2.70
€1,998.00
Oct 21, 2026
KP-10021
Ties 2
Calder & Co
Hardware
777
€2.83
€2,198.91
Nov 22, 2026
KP-10022
Notes 2
Brightline
Office
814
€2.96
€2,409.44
Jan 23, 2026
KP-10023
Towels 2
Oakmere
Cleaning
851
€3.09
€2,629.59
Feb 24, 2026
KP-10024
Box 3
Nordhaven Supply
Packaging
888
€3.22
€2,859.36
Mar 25, 2026
KP-10025
Film 3
Calder & Co
Hardware
925
€3.35
€3,098.75
Apr 26, 2026
KP-10026
Bolt 3
Brightline
Office
962
€3.48
€3,347.76
May 27, 2026

Read-only#

readOnly keeps selection, copy and the status bar, and writes nothing. Pair it with gridlines="rows" and the comfortable density for a report.

SKU
Product
Supplier
Category
Stock
Unit price
Value
KP-1042
Corrugated box, 40 x 30
Nordhaven Supply
Packaging
1,240
€0.84
€1,041.60
KP-1043
Stretch film, 500 mm
Nordhaven Supply
Packaging
86
€14.50
€1,247.00
KP-2210
Hex bolt M8, zinc
Calder & Co
Hardware
5,400
€0.12
€648.00
KP-2211
Washer M8, steel
Calder & Co
Hardware
n/a
€0.03
KP-3007
A4 paper, 80 g
Brightline
Office
320
€4.20
€1,344.00
KP-3008
Toner cartridge, black
Brightline
Office
18
€62.00
€1,116.00
KP-4101
Floor cleaner, 5 L
Oakmere
Cleaning
44
€11.90
€523.60
KP-4102
Nitrile gloves, M
Oakmere
Cleaning
900
€0.09
€81.00
KP-1050
Packing tape, clear
Nordhaven Supply
Packaging
610
€1.75
€1,067.50
KP-2230
Cable ties, 300 mm
Calder & Co
Hardware
2,500
€0.05
€125.00
KP-3015
Sticky notes, yellow
Brightline
Office
140
€1.10
€154.00
KP-4120
Paper towels, 2-ply
Oakmere
Cleaning
76
€3.40
€258.40

API reference#

DataGrid

The root: owns the rows, the columns, the selection, the undo history and the sort, and shares them with the parts through Context. With no children it renders a DataGridViewport. Forwards native <div> props; every part accepts className, merged last.

PropTypeDefaultDescription
columns*DataGridColumn<TRow>[]-The column definitions; see the Column table below.
rowsTRow[]-Controlled rows. Pair with onRowsChange.
defaultRowsTRow[]-Uncontrolled rows.
onRowsChange(rows, { changes, source }) => void-Fires once per action with the next rows and the cell patches behind them: { rowId, columnId, previous, value }. source is edit, paste, cut, clear, fill, undo or redo.
getRowId(row, index) => string-A stable id per row, used in the patches. Defaults to the row's index.
readOnlyboolean-Select and copy only.
rowNumbersbooleanfalseA pinned row-number column; click a number to select the row.
gridlines"focus" | "rows" | "all""focus"focus draws the column rules while the grid has focus; rows never; all always.
density"comfortable" | "compact"-Rows of 40px or 32px. Defaults to the surrounding DensityProvider.
sort, defaultSort, onSortChange{ columnId, direction: "asc" | "desc" } | null-The column sort, controlled or not.
onColumnWidthsChange(widths: Record<string, number>) => void-Fires when a resize or an auto-fit ends, to persist the widths.
onAddRow() => void-Shows a trailing New row row. Append the row here; the grid moves to it.
onAddColumn() => void-Shows a + cell at the end of the header. Append the column here.
labelsPartial<DataGridLabels>-Every string the grid shows or announces, for translation.
aria-labelstring-Names the grid for screen readers.

DataGridViewport

The scroll box, role="grid": the sticky header, the rows in view, the selection overlay and the editor. Give it a height. Copy, cut and paste are handled here. Forwards native <div> props.

Data attributeDescription
data-scrolled-xWhile scrolled sideways; shows the shadow on the frozen columns' edge.
CSS variableDescription
--dg-w{n}The width of column n, written on resize.
--dg-vThe column rule colour; transparent at rest with gridlines="focus".
--dg-fillThe range fill: 5% ink, 9% on dark themes.
--surfaceRead for the ground under sticky headers and frozen columns; falls back to --background.

DataGridStatusBar

Count, sum and average of the selection, live and in tabular figures. Currency columns sum in their currency. Forwards native <div> props.

DataGridColumn

The column definition passed in columns.

PropTypeDefaultDescription
id*string-Unique id; also the row field read when there is no accessorKey or value.
header*string-The header label; also names the column for screen readers.
accessorKeykeyof TRow-The row field this column reads and writes. Defaults to id.
value(row: TRow) => unknown-Derives the value instead of reading a field; the column is read-only.
type"text" | "number" | "currency" | "date" | "select" | "checkbox""text"Sets the editor, the alignment, the display format and how pasted text is read.
widthnumber150Starting width in px. Users can drag the header edge or double-click it to fit.
minWidth, maxWidthnumber56, 640Bounds for resizing.
pin"left"-Freezes the column at the left edge; pinned columns render first.
readOnlyboolean-Selectable and copyable, never written.
sortablebooleantrueShows the sort control in the header.
options{ value: string; label: string }[]-select columns: the choices, shown as badges in the cell.
currencystring"USD"currency columns: an ISO 4217 code.
align"start" | "center" | "end"-Defaults to end for numbers, center for checkboxes, start otherwise.
format(value, row) => string-Display text, and what a copy writes.
parse(text, row) => unknown-Turns typed or pasted text into a value.
validate(value, row) => string | null-Return a message to reject a value: the editor stays open, shakes and shows it under the cell. Rejected cells are skipped on paste.
cell({ value, row, rowIndex }) => ReactNode-Custom cell content.

FAQ#

Data Table is for reading: rows you scan, sort, filter and open. Data Grid is for working in cells: selecting ranges, typing, pasting from a spreadsheet. If nobody edits a cell, use Data Table.