Skip to content

Instantly share code, notes, and snippets.

@rawnly
Created January 31, 2022 18:15
Show Gist options
  • Save rawnly/48e25e9b4c4e4e24602882177f68e2e6 to your computer and use it in GitHub Desktop.
Save rawnly/48e25e9b4c4e4e24602882177f68e2e6 to your computer and use it in GitHub Desktop.
import createStore from 'zustand'
type HistoryStore<T> = {
present: T
past: T[]
future: T[]
undo: () => void
redo: () => void
reset: (present: T | ((data: T) => T)) => void
set: (present: T | ((data: T) => T)) => void
can: {
undo: boolean
redo: boolean
}
}
export const useHistoryStore = createStore<HistoryStore<number>>(set => ({
present: 0,
past: [],
future: [],
undo: () => set(state => produce(state, draft => {
if ( state.past.length === 0 ) return
const previous = draft.past[draft.past.length - 1]
const newPast = draft.past.slice(0, draft.past.length - 1)
draft.past = newPast
draft.present = previous
draft.future = [state.present, ...draft.future]
draft.can = {
undo: draft.past.length !== 0,
redo: draft.future.length !== 0
}
})),
redo: () => set(state => produce(state, draft => {
if ( state.future.length === 0 ) return
const next = draft.future[0]
const newFuture = draft.future.slice(1)
draft.past = [...draft.past, state.present]
draft.present = next
draft.future = newFuture
draft.can = {
undo: draft.past.length !== 0,
redo: draft.future.length !== 0
}
})),
set: (data) => set(state => produce(state, draft => {
const present = data instanceof Function
? data(state.present)
: data
draft.past = [...draft.past, state.present]
draft.present = present
draft.future = []
draft.can = {
undo: draft.past.length !== 0,
redo: draft.future.length !== 0
}
})),
reset: (value) => set(state => produce(state, draft => {
draft.past = []
draft.present = value instanceof Function ? value(state.present) : value
draft.future = []
draft.can = {
undo: false,
redo: false
}
})),
can: {
undo: false,
redo: false
}
}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment