An editable, composable data grid for the shadcn/ui ecosystem: range selection, spreadsheet clipboard, fill handle, pinning, undo/redo, and streaming updates. Real DOM cells, shadcn styling.
Row operations from two surfaces: toolbar buttons (insert above/below, duplicate, delete on the current selection) and the right-click context menu, with a side panel showing the last onDataChange payload (source + id-keyed ops) and a read-only toggle.
Drag rows by the reorder grip or move the active row with reorderRows - both emit one id-keyed move op (a single undo step), and row selection remaps by row id.
The full remote contract: header-click sort, filter menu, quick search and pagination are all sent to the fake server in one useQuery per view state; edits write through and refetch.
Toolbar quick-search with match navigation, a per-column filter menu, and click-to-sort headers with multi-column sort.
Toolbar sort add-on for the gridcn data grid: a sort button + popover listing applied sorts as editable, aligned rows (column / direction / remove / drag handle), with add/clear-all and precedence reordering via @dnd-kit/react drag or ArrowUp/ArrowDown on the grip (array order in SortSpec[]). New user-facing strings live under labels.sort (see data-grid/labels.ts DataGridSortLabels). Zero core changes — purely additive.
Toolbar sort button + popover: add/remove sorts, toggle ascending/descending, and reorder precedence via drag handle or ArrowUp/ArrowDown keyboard.
Status-bar add-on for the gridcn data grid: <DataGridStatusBar /> shows count, sum, avg, min, and max of the selected cells under the grid (useDataGridSelectionStats is the headless hook). Numbers are detected by value (finite numbers), sums use Neumaier-compensated summation, a single-column selection formats through that column's toDisplayText, and above 200,000 cells the walk caps and flags the values with ≈. New user-facing strings live under labels.statusBar (see data-grid/labels.ts DataGridStatusBarLabels). Zero core changes — purely additive.
Select a range, a row, or a column — the status bar below the grid aggregates count, sum, avg, min, and max of the selection in real time.
A live ticker: `updateCells` streams values in place. An auto-sort switch toggles between defer (rows hold position, re-sort on demand) and immediate (correct order every tick).
A fully-styled brand column (per-column cellClassName/headerClassName), a fully-styled at-risk row (getRowClassName beyond a bg tint), and a live density/rowHeight toggle.
Toolbar add-on for the gridcn data grid: quick-search with match navigation, a per-column filter menu (aligned rows, join column, drag-to-reorder via @dnd-kit/react), and a column visibility/pin menu.
Syncs the gridcn data grid's sort/filter/search state with the URL via nuqs (router-agnostic — requires a NuqsAdapter above it). Mount <DataGridUrlState prefix?> inside the provider; the prefix option namespaces the URL keys for multiple grids on one page.
Sort/filter/search/pagination state synced to the URL via nuqs; wrapped in the Next.js app-router NuqsAdapter (swap for your framework's adapter).
Nine rejection paths in one grid: a sync function (Age), hand-rolled sync/async/coercing Standard Schemas (Email, SKU, Price), a soft onInvalid rule (Notes), and one column per major library that implements Standard Schema natively — Zod (Score), Joi (Code), Valibot (Tag). Pasting mixed valid/invalid values shows the bulk-rejection path.
Dependency-free file dropzone: drag and drop or click to choose, with accept, size, and count checks and a compact variant. Used by the data-grid-io import dialog.