BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/tablecn/use-data-grid-undo-redo

Use Data Grid Undo Redo

tablecn/use-data-grid-undo-redo
FreeHook

An undo/redo hook for the data grid with keyboard shortcuts and history management

Install it

npx shadcn@latest add https://tablecn.com/r/use-data-grid-undo-redo.json

Source

src/hooks/use-data-grid-undo-redo.tstablecn.com/r/use-data-grid-undo-redo.json · first 6 KB
1import * as React from "react";
2import { toast } from "sonner";
3
4import { useAsRef } from "@/hooks/use-as-ref";
5import { useLazyRef } from "@/hooks/use-lazy-ref";
6import { getIsInPopover } from "@/lib/data-grid";
7
8const DEFAULT_MAX_HISTORY = 100;
9const BATCH_TIMEOUT = 300;
10
11interface HistoryEntry<TData> {
12 variant: "cells_update" | "rows_add" | "rows_delete";
13 count: number;
14 timestamp: number;
15 undo: (currentData: TData[]) => TData[];
16 redo: (currentData: TData[]) => TData[];
17}
18
19interface UndoRedoCellUpdate {
20 rowId: string;
21 columnId: string;
22 previousValue: unknown;
23 newValue: unknown;
24}
25
26interface StoreState<TData> {
27 undoStack: HistoryEntry<TData>[];
28 redoStack: HistoryEntry<TData>[];
29 hasPendingChanges: boolean;
30}
31
32interface Store<TData> {
33 subscribe: (callback: () => void) => () => void;
34 getState: () => StoreState<TData>;
35 push: (entry: HistoryEntry<TData>) => void;
36 undo: () => HistoryEntry<TData> | null;
37 redo: () => HistoryEntry<TData> | null;
38 clear: () => void;
39 setPendingChanges: (value: boolean) => void;
40 notify: () => void;
41}
42
43function useStore<T>(
44 store: Store<T>,
45 selector: (state: StoreState<T>) => boolean,
46): boolean {
47 const getSnapshot = React.useCallback(
48 () => selector(store.getState()),
49 [store, selector],
50 );
51
52 return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
53}
54
55function buildIndexById<TData>(
56 data: TData[],
57 getRowId: (row: TData) => string,
58): Map<string, number> {
59 const map = new Map<string, number>();
60 for (let i = 0; i < data.length; i++) {
61 const row = data[i];
62 if (row) {
63 map.set(getRowId(row), i);
64 }
65 }
66 return map;
67}
68
69function getPendingKey(rowId: string, columnId: string): string {
70 return `${rowId}\0${columnId}`;
71}
72
73interface UseDataGridUndoRedoProps<TData> {
74 data: TData[];
75 onDataChange: (data: TData[]) => void;
76 getRowId: (row: TData) => string;
77 maxHistory?: number;
78 enabled?: boolean;
79}
80
81interface UseDataGridUndoRedoReturn<TData> {
82 canUndo: boolean;
83 canRedo: boolean;
84 onUndo: () => void;
85 onRedo: () => void;
86 onClear: () => void;
87 trackCellsUpdate: (updates: UndoRedoCellUpdate[]) => void;
88 trackRowsAdd: (rows: TData[]) => void;
89 trackRowsDelete: (rows: TData[]) => void;
90}
91
92function useDataGridUndoRedo<TData>({
93 data,
94 onDataChange,
95 getRowId,
96 maxHistory = DEFAULT_MAX_HISTORY,
97 enabled = true,
98}: UseDataGridUndoRedoProps<TData>): UseDataGridUndoRedoReturn<TData> {
99 const propsRef = useAsRef({
100 data,
101// … truncated

What it pulls in

npm packages

  • sonner

Files it writes

  • src/hooks/use-data-grid-undo-redo.ts
  • src/hooks/use-as-ref.ts
  • src/hooks/use-lazy-ref.ts

Facts

Registry
tablecn
Type
registry:hook
Access
Free
Files written
3
Licence
MIT
First indexed
2026-08-01
Last confirmed
yesterday

Go to the source

tablecn.com sadmann7/tablecn on GitHub Raw registry item This item as JSON
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex