Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 08a78b8

Browse files
committed
Update README.md
1 parent d26c81f commit 08a78b8

File tree

1 file changed

+1
-341
lines changed

1 file changed

+1
-341
lines changed

README.md

Lines changed: 1 addition & 341 deletions
Original file line numberDiff line numberDiff line change
@@ -1,343 +1,3 @@
11
# Undo Manager
22

3-
Simple undo manager to provide undo and redo actions in JavaScript applications.
4-
5-
6-
- [Demos](#demos)
7-
- [Installation](#installation)
8-
- [Example](#example)
9-
- [Updating the UI](#updating-the-ui)
10-
- [Methods](#methods)
11-
- [add](#add)
12-
- [undo](#undo)
13-
- [redo](#redo)
14-
- [clear](#clear)
15-
- [setLimit](#setlimit)
16-
- [hasUndo](#hasundo)
17-
- [hasRedo](#hasredo)
18-
- [setCallback](#setcallback)
19-
- [getIndex](#getindex)
20-
- [getCommands](#getcommands)
21-
- [Use with CommonJS](#use-with-commonjs)
22-
- [Use with RequireJS](#use-with-requirejs)
23-
24-
25-
## Demos
26-
27-
* [CodeSandbox with RGB color slider](https://codesandbox.io/s/undo-manager-color-sliders-z4myoj)
28-
* [Undo Manager with canvas drawing](https://arthurclemens.github.io/JavaScript-Undo-Manager/)
29-
* [JSBin demo, also with canvas](http://jsbin.com/tidibi/edit?js,output)
30-
31-
32-
## Installation
33-
34-
```
35-
npm install undo-manager
36-
```
37-
38-
39-
## Example
40-
41-
Actions (typing a character, moving an object) are structured as command pairs: one command for destruction (undo) and one for creation (redo). Each pair is added to the undo stack:
42-
43-
```js
44-
const undoManager = new UndoManager();
45-
undoManager.add({
46-
undo: function() {
47-
// ...
48-
},
49-
redo: function() {
50-
// ...
51-
}
52-
});
53-
```
54-
55-
To make an action undoable, you'd add an undo/redo command pair to the undo manager:
56-
57-
```js
58-
const undoManager = new UndoManager();
59-
const people = {};
60-
61-
function addPerson(id, name) {
62-
people[id] = name;
63-
};
64-
65-
function removePerson(id) {
66-
delete people[id];
67-
};
68-
69-
function createPerson(id, name) {
70-
// first creation
71-
addPerson(id, name);
72-
73-
// make undoable
74-
undoManager.add({
75-
undo: () => removePerson(id),
76-
redo: () => addPerson(id, name)
77-
});
78-
}
79-
80-
createPerson(101, "John");
81-
createPerson(102, "Mary");
82-
83-
console.log(people); // logs: {101: "John", 102: "Mary"}
84-
85-
undoManager.undo();
86-
console.log(people); // logs: {101: "John"}
87-
88-
undoManager.undo();
89-
console.log(people); // logs: {}
90-
91-
undoManager.redo();
92-
console.log(people); // logs: {101: "John"}
93-
```
94-
95-
## Updating the UI
96-
97-
TL;DR UI that relies on undo manager state - for example `hasUndo` and `hasRedo` - needs to be updated using the callback function provided with `setCallback`. This ensures that all internal state has been resolved before the UI is repainted.
98-
99-
Let's say we have an update function that conditionally disables the undo and redo buttons:
100-
101-
```js
102-
function updateUI() {
103-
btn_undo.disabled = !undoManager.hasUndo();
104-
btn_redo.disabled = !undoManager.hasRedo();
105-
}
106-
```
107-
108-
You might be inclined to call the update in the undo/redo command pair:
109-
110-
```js
111-
// wrong approach, don't copy
112-
const undoManager = new UndoManager();
113-
const states = [];
114-
115-
function updateState(newState) {
116-
states.push(newState);
117-
updateUI();
118-
119-
undoManager.add({
120-
undo: function () {
121-
states.pop();
122-
updateUI(); // <= this will lead to inconsistent UI state
123-
},
124-
redo: function () {
125-
states.push(newState);
126-
updateUI(); // <= this will lead to inconsistent UI state
127-
}
128-
});
129-
}
130-
```
131-
132-
Instead, pass the update function to `setCallback`:
133-
134-
```js
135-
// recommended approach
136-
const undoManager = new UndoManager();
137-
undoManager.setCallback(updateUI);
138-
139-
const states = [];
140-
141-
function updateState(newState) {
142-
states.push(newState);
143-
updateUI();
144-
145-
undoManager.add({
146-
undo: function () {
147-
states.pop();
148-
},
149-
redo: function () {
150-
states.push(newState);
151-
}
152-
});
153-
}
154-
```
155-
156-
## Methods
157-
158-
### add
159-
160-
Adds an undo/redo command pair to the stack.
161-
162-
```js
163-
function createPerson(id, name) {
164-
// first creation
165-
addPerson(id, name);
166-
167-
// make undoable
168-
undoManager.add({
169-
undo: () => removePerson(id),
170-
redo: () => addPerson(id, name)
171-
});
172-
}
173-
```
174-
175-
Optionally add a `groupId` to identify related command pairs. Undo and redo actions will then be performed on all adjacent command pairs with that group id.
176-
177-
```js
178-
undoManager.add({
179-
groupId: 'auth',
180-
undo: () => removePerson(id),
181-
redo: () => addPerson(id, name)
182-
});
183-
```
184-
185-
186-
### undo
187-
188-
Performs the undo action.
189-
190-
```js
191-
undoManager.undo();
192-
```
193-
194-
If a `groupId` was set, the undo action will be performed on all adjacent command pairs with that group id.
195-
196-
### redo
197-
198-
Performs the redo action.
199-
200-
```js
201-
undoManager.redo();
202-
```
203-
204-
If a `groupId` was set, the redo action will be performed on all adjacent command pairs with that group id.
205-
206-
### clear
207-
208-
Clears all stored states.
209-
210-
```js
211-
undoManager.clear();
212-
```
213-
214-
### setLimit
215-
216-
Set the maximum number of undo steps. Default: 0 (unlimited).
217-
218-
```js
219-
undoManager.setLimit(limit);
220-
```
221-
222-
### hasUndo
223-
224-
Tests if any undo actions exist.
225-
226-
```js
227-
const hasUndo = undoManager.hasUndo();
228-
```
229-
230-
### hasRedo
231-
232-
Tests if any redo actions exist.
233-
234-
```js
235-
const hasRedo = undoManager.hasRedo();
236-
```
237-
238-
### setCallback
239-
240-
Get notified on changes. Pass a function to be called on undo and redo actions.
241-
242-
```js
243-
undoManager.setCallback(myCallback);
244-
```
245-
246-
### getIndex
247-
248-
Returns the index of the actions list.
249-
250-
```js
251-
const index = undoManager.getIndex();
252-
```
253-
254-
### getCommands
255-
256-
Returns the list of queued commands, optionally filtered by group id.
257-
258-
```js
259-
const commands = undoManager.getCommands();
260-
const commands = undoManager.getCommands(groupId);
261-
```
262-
263-
## Use with CommonJS
264-
265-
```bash
266-
npm install undo-manager
267-
```
268-
269-
```js
270-
const UndoManager = require('undo-manager')
271-
```
272-
273-
If you only need a single instance of UndoManager throughout your application, it may be wise to create a module that exports a singleton:
274-
275-
```js
276-
// undoManager.js
277-
const undoManager = require('undo-manager'); // require the lib from node_modules
278-
let singleton = undefined;
279-
280-
if (!singleton) {
281-
singleton = new undoManager();
282-
}
283-
284-
module.exports = singleton;
285-
```
286-
287-
Then in your app:
288-
289-
```js
290-
// app.js
291-
const undoManager = require('undoManager');
292-
293-
undoManager.add(...);
294-
undoManager.undo();
295-
```
296-
297-
298-
## Use with RequireJS
299-
300-
If you are using RequireJS, you need to use the `shim` config parameter.
301-
302-
Assuming `require.js` and `domReady.js` are located in `js/extern`, the `index.html` load call would be:
303-
304-
```html
305-
<script src="js/extern/require.js" data-main="js/demo"></script>
306-
```
307-
308-
And `demo.js` would look like this:
309-
310-
```js
311-
requirejs.config({
312-
baseUrl: "js",
313-
paths: {
314-
domReady: "extern/domReady",
315-
app: "../demo",
316-
undomanager: "../../js/undomanager",
317-
circledrawer: "circledrawer"
318-
},
319-
shim: {
320-
"undomanager": {
321-
exports: "UndoManager"
322-
},
323-
"circledrawer": {
324-
exports: "CircleDrawer"
325-
}
326-
}
327-
});
328-
329-
require(["domReady", "undomanager", "circledrawer"], function(domReady, UndoManager, CircleDrawer) {
330-
"use strict";
331-
332-
let undoManager,
333-
circleDrawer,
334-
btnUndo,
335-
btnRedo,
336-
btnClear;
337-
338-
undoManager = new UndoManager();
339-
circleDrawer = new CircleDrawer("view", undoManager);
340-
341-
// etcetera
342-
});
343-
```
3+
Migrated to https://codeberg.org/ArthurClemens/JavaScript-Undo-Manager

0 commit comments

Comments
 (0)