Skip to content

Commit

Permalink
add clear controls for useUndoRedoState
Browse files Browse the repository at this point in the history
  • Loading branch information
imbhargav5 committed Apr 28, 2023
1 parent 0182278 commit 33af9d7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
48 changes: 48 additions & 0 deletions packages/rooks/src/__tests__/useUndoRedoState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,52 @@ describe("useUndoRedoState", () => {
});
expect(result.current[0]).toBe(2);
});
it("should clear the undo stack", () => {
expect.hasAssertions();
const { result } = renderHook(() => useUndoRedoState(0));
act(() => {
result.current[1](1);
result.current[1](2);
result.current[2].clearUndoStack();
result.current[2].undo();
});
expect(result.current[0]).toBe(2); // Should not undo as the undo stack is cleared
});

it("should clear the redo stack", () => {
expect.hasAssertions();
const { result } = renderHook(() => useUndoRedoState(0));
act(() => {
result.current[1](1);
});
act(() => {
result.current[1](2);
});
act(() => {
result.current[2].undo();
});
act(() => {
result.current[2].clearRedoStack();
});
act(() => {
result.current[2].redo();
});
expect(result.current[0]).toBe(1); // Should not redo as the redo stack is cleared
});

it("should clear both undo and redo stacks", () => {
expect.hasAssertions();
const { result } = renderHook(() => useUndoRedoState(0));
act(() => {
result.current[1](1);
result.current[1](2);
result.current[2].clearAll();
result.current[2].undo();
});
expect(result.current[0]).toBe(2); // Should not undo as both stacks are cleared
act(() => {
result.current[2].redo();
});
expect(result.current[0]).toBe(2); // Should not redo as both stacks are cleared
});
});
41 changes: 34 additions & 7 deletions packages/rooks/src/hooks/useUndoRedoState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
* @description Setstate but can also undo and redo
* @see {@link https://rooks.vercel.app/docs/useUndoRedoState}
*/
import { useState, useCallback, SetStateAction, Dispatch } from "react";
import {
useState,
useCallback,
SetStateAction,
Dispatch,
useMemo,
} from "react";

function isFunctionInitializer<T>(
functionToCheck: SetStateAction<T>
Expand All @@ -16,6 +22,9 @@ type UndoRedoControls = {
redo: () => void;
canUndo: () => boolean;
canRedo: () => boolean;
clearUndoStack: () => void;
clearRedoStack: () => void;
clearAll: () => void;
};

/**
Expand Down Expand Up @@ -90,12 +99,30 @@ function useUndoRedoState<T>(
[state, maxDepth]
);

const controls: UndoRedoControls = {
undo,
redo,
canUndo,
canRedo,
};
const clearUndoStack = useCallback(() => {
setPast([]);
}, []);

const clearRedoStack = useCallback(() => {
setFuture([]);
}, []);

const clearAll = useCallback(() => {
setPast([]);
setFuture([]);
}, []);

const controls: UndoRedoControls = useMemo(() => {
return {
undo,
redo,
canUndo,
canRedo,
clearUndoStack,
clearRedoStack,
clearAll,
};
}, [undo, redo, canUndo, canRedo, clearUndoStack, clearRedoStack, clearAll]);

return [state, setState, controls];
}
Expand Down

0 comments on commit 33af9d7

Please sign in to comment.