a tool for shared writing and social publishing
1import { UndoManager as RociUndoManager } from "@rocicorp/undo"; 2import { create } from "zustand"; 3 4export type UndoManager = ReturnType<typeof createUndoManager>; 5export const useUndoState = create(() => ({ canUndo: false, canRedo: false })); 6export const createUndoManager = () => { 7 let isGrouping = false; 8 let undoManager = new RociUndoManager({ 9 onChange: (state) => { 10 useUndoState.setState(state); 11 }, 12 }); 13 let um = { 14 add: (args: { 15 undo: () => Promise<void> | void; 16 redo: () => Promise<void> | void; 17 }) => { 18 undoManager.add(args); 19 }, 20 startGroup: (groupName?: string) => { 21 if (isGrouping) { 22 undoManager.endGroup(); 23 } 24 isGrouping = true; 25 undoManager.startGroup(); 26 }, 27 endGroup: () => { 28 isGrouping = false; 29 undoManager.endGroup(); 30 }, 31 undo: () => undoManager.undo(), 32 redo: () => undoManager.redo(), 33 withUndoGroup: <T>(cb: () => T) => { 34 if (!isGrouping) um.startGroup(); 35 const r = cb(); 36 if (!isGrouping) um.endGroup(); 37 return r; 38 }, 39 }; 40 return um; 41};