1import { useState, useCallback } from "react";
2
3export function useHistoryState<T>(initialValue: T) {
4 const [state, setState] = useState(initialValue);
5 const [history, setHistory] = useState<T[]>([initialValue]);
6 const [pointer, setPointer] = useState(0);
7
8 const set = useCallback((value: T) => {
9 const nextHistory = [...history.slice(0, pointer + 1), value];
10 setHistory(nextHistory);
11 setPointer(nextHistory.length - 1);
12 setState(value);
13 }, [history, pointer]);
14
15 const undo = useCallback(() => {
16 if (pointer > 0) {
17 setPointer((p) => p - 1);
18 setState(history[pointer - 1]);
19 }
20 }, [history, pointer]);
21
22 const redo = useCallback(() => {
23 if (pointer < history.length - 1) {
24 setPointer((p) => p + 1);
25 setState(history[pointer + 1]);
26 }
27 }, [history, pointer]);
28
29 return { state, set, undo, redo, canUndo: pointer > 0, canRedo: pointer < history.length - 1 };
30}