Skip to content
Latestv1.0.63

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

You can enable history management in two ways:

You can set the history and max-history props directly on the <yh-flow> component. The component automatically registers and manages the history plugin internally, including keyboard shortcuts.

vue
<template>
  <yh-flow ref="flowRef" :history="true" :max-history="100" @history-change="handleHistoryChange" />
</template>

<script setup lang="ts">
const flowRef = ref()

const handleHistoryChange = ({ canUndo, canRedo }) => {
  console.log('Can Undo:', canUndo, 'Can Redo:', canRedo)
}

// Methods are still accessible on flowRef
const undo = () => flowRef.value?.undo?.()
const redo = () => flowRef.value?.redo?.()
const saveSnapshot = () => flowRef.value?.saveSnapshot?.('Manual snapshot')
</script>

Method 2: Manual Plugin Registration (Highly Customizable)

If you need advanced control or custom options, you can manually create and register the history plugin:

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

onMounted(() => {
  // 1. Create and install the history 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. Undo / Redo programmatically
const undo = () => flowRef.value?.undo?.()
const redo = () => flowRef.value?.redo?.()

IMPORTANT

Whichever method you choose, the extended methods saveSnapshot, undo, redo, etc., are dynamically mounted to flowRef.value only after the component/plugin is loaded and ready. Ensure you call them inside onMounted or event/action callbacks.

Basic Usage Demo

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.