@anandarizki/use-undo-redo
Version:
A hook provides a simple and efficient way to manage undo and redo functionality in your React applications
64 lines • 2.41 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useUndoRedo = useUndoRedo;
const react_1 = require("react");
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
const lodash_last_1 = __importDefault(require("lodash.last"));
function useUndoRedo(primaryState, { capacity = 10, debounce = 0 } = {}) {
const [state, setState] = primaryState;
const [history, setHistory] = (0, react_1.useState)([]);
const [pointer, setPointer] = (0, react_1.useState)(0);
const allowUpdateHistory = (0, react_1.useRef)(true);
const updateHistory = (newState) => {
const updatedHistory = [
...history.slice(0, pointer + 1),
{ value: newState, timestamp: new Date() },
];
if (updatedHistory.length > capacity) {
updatedHistory.shift();
}
setHistory(updatedHistory);
setPointer(updatedHistory.length - 1);
};
const jumpTo = (index) => {
allowUpdateHistory.current = false;
setState(history[index].value);
setPointer(index);
};
const undo = () => {
if (canUndo)
jumpTo(pointer - 1);
};
const redo = () => {
if (canRedo)
jumpTo(pointer + 1);
};
const reset = () => {
setHistory([]);
setPointer(0);
};
const canUndo = pointer > 0;
const canRedo = pointer < history.length - 1;
(0, react_1.useEffect)(() => {
const addHistoryEntry = () => {
const lastEntry = (0, lodash_last_1.default)(history);
if (allowUpdateHistory.current && !(0, lodash_isequal_1.default)(state, lastEntry?.value)) {
updateHistory((0, lodash_clonedeep_1.default)(state));
}
allowUpdateHistory.current = true;
};
if (debounce === 0) {
addHistoryEntry();
}
else {
const timeoutId = setTimeout(addHistoryEntry, debounce);
return () => clearTimeout(timeoutId);
}
}, [state, debounce, history]);
return [undo, redo, { canUndo, canRedo, reset, history, jumpTo, pointer }];
}
//# sourceMappingURL=useUndoRedo.js.map