UNPKG

rooks

Version:

Essential React custom hooks ⚓ to super charge your components!

66 lines (65 loc) 2.68 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { useCallback, useMemo, useState } from "react"; var defaultOptions = { maxSize: 100 }; /** * useUndoState hook * Drop in replacement for useState hook but with undo functionality. * * @typedef UndoStateOptions * @type {object} * @property {number} maxSize - Maximum number of states to keep in the undo stack. * @param {any} defaultValue - Default value to use for the state. This will be the first value in the undo stack. * @param {UseUndoStateOptions} options - Options for the undo state. Currently takes the maxSize option. * @returns {UseUndoStateReturnValue} * @see https://react-hooks.org/docs/useUndoState */ var useUndoState = function (defaultValue, options) { var maxSize = useMemo(function () { return __assign(__assign({}, defaultOptions), options); }, [options]).maxSize; var _a = useState([defaultValue]), value = _a[0], setValue = _a[1]; var push = useCallback(function (argument) { return setValue(function (current) { var restValues = current.length >= maxSize ? current.slice(0, maxSize) : current; if (typeof argument === "function") { // I dislike this type assertion, but it's the only way to get the type to match // as the type guard doesn't seem to be working here. // eslint-disable-next-line @typescript-eslint/ban-types return __spreadArray([argument(current[0])], restValues, true); } else { return __spreadArray([argument], restValues, true); } }); }, [maxSize]); var undo = useCallback(function () { setValue(function (current) { if (current.length === 1) { return current; } var values = current.slice(1); return values; }); }, []); return [value[0], push, undo]; }; export { useUndoState };