https://github.com/pvvng/use-undo-manager
A React hook that enables undo/redo history management with debounced state commits.
https://github.com/pvvng/use-undo-manager
react react-hooks react-state-management undo-redo
Last synced: 5 months ago
JSON representation
A React hook that enables undo/redo history management with debounced state commits.
- Host: GitHub
- URL: https://github.com/pvvng/use-undo-manager
- Owner: pvvng
- License: mit
- Created: 2025-07-23T02:11:06.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-07-23T02:48:51.000Z (11 months ago)
- Last Synced: 2025-10-03T20:19:00.805Z (8 months ago)
- Topics: react, react-hooks, react-state-management, undo-redo
- Language: TypeScript
- Homepage:
- Size: 59.6 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# useUndoManager
A powerful React hook for managing undo/redo functionality with delayed commit and batch update support. Ideal for building complex, user-friendly state workflows such as form editors, drawing apps, and JSON builders.
[](https://www.npmjs.com/package/use-undo-manager)
[](https://www.npmjs.com/package/use-undo-manager)
[](LICENSE)
## Features
- Undo & Redo with history management
- Debounced (delayed) commits
- Batch updates in commit window
- View state vs Committed state separation
- Lightweight and framework-agnostic
- Manual merge for grouped commits
- Pause/resume commit queue
- Reset and flush utilities
## Installation
```bash
npm install use-undo-manager
```
## Simple Usage
```tsx
import { useUndoManager } from "use-undo-manager";
function TextEditor() {
const {
state,
committed,
set,
undo,
redo,
flush,
mergeLast,
reset,
pause,
resume,
canUndo,
canRedo,
} = useUndoManager("Hello", {
commitDelay: 500,
historyLimit: 100,
onChange: (committedValue) => {
console.log("Committed:", committedValue);
},
});
return (
set(e.target.value)}
placeholder="Type something..."
/>
Undo
Redo
Flush
Merge Last
Pause
Resume
reset("Hello")}>Reset
);
}
```
## ⚙️ API
### `const result = useUndoManager(initialState, options?)`
#### Parameters:
| Name | Type | Default | Description |
| -------------- | -------------------------- | ------- | ----------------------------------- |
| `initialState` | `T` | — | Initial value for the state |
| `options` | `UseUndoManagerOptions` | `{}` | Optional settings for customization |
#### Options:
```ts
interface UseUndoManagerOptions {
/** Delay in milliseconds to commit changes (debounce window) */
commitDelay?: number;
/** Maximum number of undo/redo history entries to keep */
historyLimit?: number;
/** Callback called when the committed state changes */
onChange?: (state: T) => void;
}
```
---
### Return values
| Name | Type | Description |
| ----------- | --------------------- | ------------------------------------------------------------- |
| `state` | `T` | Current view state that updates immediately |
| `committed` | `T` | Last committed state (used for undo/redo history) |
| `set` | `(value: T) => void` | Updates the state; commits after debounce delay |
| `undo` | `() => void` | Undo the last committed change |
| `redo` | `() => void` | Redo the last undone change |
| `flush` | `() => void` | Immediately commits any pending changes |
| `mergeLast` | `() => void` | Replaces last committed state with current view state (batch) |
| `pause` | `() => void` | Temporarily pauses committing changes |
| `resume` | `() => void` | Resumes committing after pause |
| `reset` | `(value?: T) => void` | Resets state and clears history |
| `canUndo` | `boolean` | Whether undo is currently possible |
| `canRedo` | `boolean` | Whether redo is currently possible |
## Concepts
- viewState: State immediately updated by set(). Used in UI.
- committedState: State committed after debounce delay. Used in undo/redo history.
- pendingStack: Queue of values waiting to be committed.
- undoStack / redoStack: History stacks for state changes.
## Advanced Use Cases
- Grouping complex state transitions using mergeLast()
- Temporarily disabling commits during programmatic changes via pause()/resume()
- Manually controlling timing of batch commits with flush()
## Contributing
Feel free to open issues or pull requests!
If you have ideas or edge cases you’d like supported, let’s discuss it on GitHub.