Data Grid
A spreadsheet for your application. Edit cells, select ranges, filter records, and work through thousands of rows with a frozen first column and live summaries.
Renewals
Installation
Add the free Data Grid with our CLI. It includes the BoardUI controls and private data helpers it uses:
Dark mode ready - this component follows BoardUI semantic tokens automatically. Set up theme switching.
The CLI copies the component source (with its internal dependencies) into your project and installs any required npm packages.
npx boardui@latest add data-gridUsing a shared UI package or custom import aliases? Configure your installation paths before running the CLI. Copy-paste examples use the default imports.
Columns and editing
Pass typed columns, your data, and a unique, stable getRowId. Provide onDataChange to enable editing. Text, number, and select editors reuse BoardUI inputs and selects. Set bounds with min and max, or reject values with validate.
Use format for cell display and formatSummary for sum, average, or count footers. Set editable= on individual columns. Formatting changes presentation; editing, copying, and exporting use the underlying values.
const columns: DataGridColumn<Account>[] = [ { key: "account", header: "Account", width: 220, validate: (value) => String(value).trim() ? undefined : "Account cannot be empty." }, { key: "stage", header: "Stage", type: "select", options: ["Discovery", "Proposal", "Closed won"] }, { key: "seats", header: "Seats", type: "number", min: 0, summary: "sum" }, { key: "arr", header: "ARR", type: "number", min: 0, editable: false, summary: "sum", formatSummary: (value) => `$${value.toLocaleString("en-US")}` },];
// Omit onDataChange to make every cell read-only.<DataGrid aria-label="Accounts" data={data} columns={columns} getRowId={getRowId} />Search, filter, and export
Search across all columns, click a heading to cycle through ascending, descending, and original order, or filter by exact values. Select columns automatically appear in the Filter menu; add filterable to other columns. Hide columns, resize their dividers, and switch between comfortable and compact rows.
The first visible column stays frozen beside the row numbers. On narrow screens it scrolls with the other columns so every cell remains reachable. Row checkboxes select records independently of cell ranges; the header checkbox toggles all filtered rows. Selecting rows shows the count and Delete, Copy, and Export actions in the toolbar. Copy uses tab-separated values; export downloads a CSV, both using visible columns and selected visible records. Delete requires onDataChange and can be undone. Clear the selection to return to the search and view controls. Summaries always reflect the filtered records.
Keyboard and clipboard
Tab into the grid and use arrow keys to move between cells. Hold Shift to extend a range, or drag across cells with the mouse. Home and End move across a row; add ⌘ or Ctrl to jump to the first or last record. Page Up and Page Down move by a viewport. ⌘/Ctrl+A selects all cells.
Select a cell with options to reveal its dropdown, then click the chevron to choose a value. Double-click, Enter, or F2 opens the cell editor. Enter saves and moves down; Shift+Enter moves up. Tab saves and moves to the next cell. Escape cancels. Copy a range and paste tab-separated spreadsheet data with the usual keyboard shortcuts. Invalid values reject the entire paste. Undo and redo apply to cell edits, pastes, and row deletions, with up to 100 transactions kept for the mounted grid.
Give each grid an aria-label. Wrap right-to-left regions in DirectionProvider; frozen columns, menus, and horizontal arrow keys follow the reading direction.
10,000 rows, a small viewport
The preview above contains 10,000 actual records. Fixed-height virtualization mounts only the rows in and around the viewport. The header and summary remain outside the scrolling body; a progressive blur softens the top edge as you scroll. Set height to change the viewport height.
Search, sorting, filtering, and summaries run in the browser over the provided data. Cell selection and edits follow stable row IDs as records move. Persist changes in your onDataChange handler. Remount the grid with a new React key when switching to a different dataset to reset view state and edit history.
Right-to-left and read-only
Use DirectionProvider to set the reading direction. This read-only example freezes the first column on the right and mirrors horizontal keyboard navigation. Your column labels and record values can use any language.