Skip to content

Commit d52a221

Browse files
feat: src/useUndo.ts (#13)
1 parent 098a9e5 commit d52a221

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

src/useUndo.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useState, useCallback, useRef } from "react";
2+
3+
export function useUndo<T>(initial: T) {
4+
const [state, setState] = useState<T>(initial);
5+
const history = useRef<T[]>([initial]);
6+
const idx = useRef(0);
7+
8+
const set = useCallback((val: T | ((p: T) => T)) => {
9+
setState(prev => {
10+
const next = typeof val === "function" ? (val as (p: T) => T)(prev) : val;
11+
history.current = history.current.slice(0, idx.current + 1);
12+
history.current.push(next);
13+
if (history.current.length > 50) history.current.shift();
14+
else idx.current++;
15+
return next;
16+
});
17+
}, []);
18+
19+
const undo = useCallback(() => {
20+
if (idx.current > 0) { idx.current--; setState(history.current[idx.current]); }
21+
}, []);
22+
23+
const redo = useCallback(() => {
24+
if (idx.current < history.current.length - 1) { idx.current++; setState(history.current[idx.current]); }
25+
}, []);
26+
27+
return { state, set, undo, redo, canUndo: idx.current > 0, canRedo: idx.current < history.current.length - 1 };
28+
}

0 commit comments

Comments
 (0)