UNPKG

@modern-kit/react

Version:
89 lines (86 loc) 2.5 kB
import { isFunction, at } from '@modern-kit/utils'; import { useState, useMemo, useCallback } from 'react'; function useHistoryState(initialValue, capacity = 10) { const initialValueToUse = isFunction(initialValue) ? initialValue() : initialValue; const [state, innerSetState] = useState({ history: [initialValueToUse], current: initialValueToUse, pointer: 0 }); const canForward = useMemo( () => state.pointer < state.history.length - 1, [state.pointer, state.history.length] ); const canBack = useMemo(() => state.pointer > 0, [state.pointer]); const setState = useCallback( (newState) => { innerSetState((prev) => { const history = [...prev.history]; const newStateToUse = isFunction(newState) ? newState(history[prev.pointer]) : newState; if (history.length === capacity) { history.shift(); } history.push(newStateToUse); const pointer = history.length - 1; return { history, current: newStateToUse, pointer }; }); }, [capacity] ); const replaceState = useCallback((newState) => { innerSetState((prev) => { const history = [...prev.history]; const newStateToUse = isFunction(newState) ? newState(history[prev.pointer]) : newState; history[prev.pointer] = newStateToUse; return { ...prev, history, current: newStateToUse }; }); }, []); const back = useCallback(() => { innerSetState((prev) => { if (prev.pointer < 1) { return prev; } const pointer = prev.pointer - 1; return { ...prev, current: prev.history[pointer], pointer }; }); }, []); const forward = useCallback(() => { innerSetState((prev) => { if (prev.pointer >= prev.history.length - 1) { return prev; } const pointer = prev.pointer + 1; return { ...prev, current: prev.history[pointer], pointer }; }); }, []); const go = useCallback((index) => { innerSetState((prev) => { const element = at(prev.history, index); if (element == null) { return prev; } const pointer = index < 0 ? prev.history.length + index : index; return { ...prev, current: element, pointer }; }); }, []); return { state: state.current, canForward, canBack, setState, replaceState, forward, back, go }; } export { useHistoryState }; //# sourceMappingURL=index.mjs.map