createTimeline
Bounded undo/redo history built on createRegistry with a configurable size limit.
Usage
The createTimeline composable extends createRegistry to provide undo/redo functionality with a bounded history. When the timeline reaches its size limit, older items are moved to an overflow buffer, allowing you to undo back to them while maintaining a fixed active timeline size.
import { createTimeline } from '@vuetify/v0'
const timeline = createTimeline({ size: 10 })
// Register actions
timeline.register({ id: 'action-1', value: 'Created document' })
timeline.register({ id: 'action-2', value: 'Added title' })
timeline.register({ id: 'action-3', value: 'Added paragraph' })
console.log(timeline.size) // 3
// Undo the last action
timeline.undo()
console.log(timeline.size) // 2
// Redo the undone action
timeline.redo()
console.log(timeline.size) // 3Context / DI
Use createTimelineContext to share a timeline instance across a component tree:
import { createTimelineContext } from '@vuetify/v0'
export const [useHistory, provideHistory, history] =
createTimelineContext({ namespace: 'my:history', size: 50 })
// In parent component
provideHistory()
// In child component
const timeline = useHistory()
timeline.register({ id: 'action-1', value: 'Created item' })
timeline.undo()Options
| Option | Type | Default | Notes |
|---|---|---|---|
size | number | 10 | Maximum number of entries in the active timeline. When exceeded, the oldest entry moves to an internal overflow buffer — it remains accessible via undo() but no longer counts against the limit |
Architecture
createTimeline extends createRegistry with bounded history and overflow management:
Reactivity
createTimeline uses minimal reactivity like its parent createRegistry. History state is managed internally without reactive primitives.
Need reactive history? Wrap with useProxyRegistry(timeline) for full template reactivity on the active timeline.
Examples
Drawing Canvas
A freehand drawing canvas split into four files demonstrating timeline-powered undo/redo:
| File | Role |
|---|---|
context.ts | Defines Point, Stroke, CanvasContext types and the DI pair |
CanvasProvider.vue | Creates the timeline, tracks redo state, exposes add/undo/redo/clear |
CanvasConsumer.vue | Owns the <canvas> element, mouse/touch handlers, and render loop |
canvas.vue | Entry point — wraps Provider around Consumer |
Key patterns:
Provider owns
createTimeline+useProxyRegistry— consumer never touches the timeline directlystrokescomputed mapsproxy.valuesto rawStroke[]— consumer only sees domain dataredoStackSizetracked manually viashallowRefsince redo stack is internal to the timelinewatchEffectin consumer readsstrokes.valuefor reactive canvas re-renderingHistory bar visualizes the 20-slot bounded timeline capacity
Draw on the canvas, then use Undo/Redo to time-travel through your strokes.
Functions
createTimelineContext
(_options?: TimelineContextOptions) => ContextTrinity<E>Creates a new timeline context.
Options
Properties
Methods
move
(id: ID, toIndex: number) => E | undefinedSeek for a ticket based on direction and optional predicate
seek
(direction?: "first" | "last", from?: number, predicate?: (ticket) => boolean) => E | undefinedon
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidListen for registry events
off
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidStop listening for registry events
emit
<K extends Extensible<RegistryEventName>>(event: K, data: EventPayload<E, K>) => voidEmit an event with data
batch
<R>(fn: () => R) => RExecute operations in a batch, deferring cache invalidation and event emission until complete