Flow Studio
Undo (Ctrl+Z)
Pressing Ctrl+Z pops the top entry from the undo stack, saves the current graph state to the redo stack, and restores the nodes and edges from the popped snapshot. If the undo stack is empty, the keypress is a no-op.
Undo Implementation
undo: () => {
const { undoStack, redoStack, nodes, edges } = get();
if (undoStack.length === 0) return; // Nothing to undo
// Pop the top snapshot from undo stack
const [previous, ...remainingUndo] = undoStack;
// Push current state to redo stack
const currentSnapshot: HistorySnapshot = {
nodes: JSON.parse(JSON.stringify(nodes)),
edges: JSON.parse(JSON.stringify(edges))
};
// Restore the graph to the snapshot state
set({
nodes : previous.nodes,
edges : previous.edges,
undoStack: remainingUndo,
redoStack: [currentSnapshot, ...redoStack]
});
}
Keyboard Binding
// useKeyboardShortcuts.ts
useEffect(() => {
function handleKeyDown(e: KeyboardEvent) {
const isMod = e.metaKey || e.ctrlKey;
if (isMod && e.key === 'z' && !e.shiftKey) {
e.preventDefault();
useWorkflowStore.getState().undo();
}
}
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
Undo Button in Toolbar
function UndoButton() {
const { undo, undoStack } = useWorkflowStore(
state => ({ undo: state.undo, undoStack: state.undoStack }),
shallow
);
return (
<button onClick={undo} disabled={undoStack.length === 0}>
<i className="fa-solid fa-rotate-left" />
Undo
</button>
);
}
After Undo
| Before Undo | After Undo |
|---|---|
| undoStack: [A, B, C] | undoStack: [B, C] |
| redoStack: [] | redoStack: [current] |
| Canvas shows: current state | Canvas shows: state A |