Skip to content

History & Undo/Redo (HistoryPlugin)

createHistoryPlugin provides a complete operation history management system based on a pure snapshot stack. It supports Ctrl+Z / Ctrl+Y shortcuts and advanced time travel to jump directly to any historical step.

Quick Start

typescript
import { createHistoryPlugin } from '@yh-ui/flow'

onMounted(() => {
  // 1. Create and install plugin
  const plugin = createHistoryPlugin({
    maxHistory: 100, // Keep up to 100 steps
    enableKeyboard: true, // Bind Ctrl+Z / Ctrl+Y
    onHistoryChange: (canUndo, canRedo, length) => {
      // update UI states like disabled buttons
    }
  })
  flowRef.value?.usePlugin(plugin)

  // 2. Once installed, manually save snapshot on user actions
})

// 3. Call this on drag end, node connect, or delete
const handleDragEnd = () => flowRef.value?.saveSnapshot?.('Drag node')

// 4. Undo / Redo programmatically
const undo = () => flowRef.value?.undo?.()
const redo = () => flowRef.value?.redo?.()

IMPORTANT

saveSnapshot, undo, redo methods are dynamically mounted to flowRef.value only after usePlugin is called. Only call these methods within or after the onMounted hook.

Basic Usage Demo

Steps: 0
📦 Drag me!
⚙️ And me!
💡 Drag nodes → click "Snapshot" → then "Undo"
Save snaphots then Undo/Redo changes

API

HistoryPluginOptions

PropTypeDefaultDescription
enabledbooleantrueEnable plugin
maxHistorynumber100Maximum history steps
enableKeyboardbooleantrueEnable Ctrl+Z/Y global window shortcuts
onHistoryChange(canUndo, canRedo, length) => voidCallback on history change

FlowInstance Extended Methods

Automatically mounted onto flowRef.value after usePlugin is called

Method/PropTypeDescription
undo()() => voidUndo to previous step
redo()() => voidRedo to next step
saveSnapshot(desc?)(description?: string) => voidManually save current snapshot
clearHistory()() => voidClear all history
jumpToStep(index)(index: number) => voidJump to specific step (time travel)
getHistory()() => FlowHistorySnapshot[]Get full history stack
canUndoRef<boolean>Whether undo is available (reactive)
canRedoRef<boolean>Whether redo is available (reactive)
historyLengthRef<number>Total step count (reactive)

FlowHistorySnapshot

typescript
interface FlowHistorySnapshot {
  nodes: Node[]
  edges: Edge[]
  timestamp: number
  description?: string
}

Keyboard Shortcuts

ShortcutAction
Ctrl + Z / ⌘ + ZUndo
Ctrl + Y / ⌘ + YRedo
Ctrl + Shift + Z / ⌘ + ⇧ + ZRedo (macOS alternative)

Best Practices

TIP

Manual snapshot saving is recommended over auto-capturing every tiny change. Calling saveSnapshot at key moments ensures meaningful steps for your users:

typescript
// ✅ Recommended: Save on drag complete
flowRef.value?.on('node:dragend', () => flowRef.value?.saveSnapshot?.('Drag node'))

// e.g. Call after connection established
// e.g. Call before bulk delete

Next Steps

Released under the MIT License.