Giter Site home page Giter Site logo

tristargod / zundo Goto Github PK

View Code? Open in Web Editor NEW

This project forked from charkour/zundo

0.0 1.0 0.0 2.56 MB

๐Ÿœ undo/redo middleware for zustand

Home Page: https://codesandbox.io/s/zundo-2dom9

License: MIT License

JavaScript 4.18% TypeScript 95.82%

zundo's Introduction

๐Ÿœ Zundo

enable time-travel in your apps. undo/redo middleware for zustand. built with zustand.

Build Size Version Downloads

zundo demo

See a demo

Install

npm i zustand zundo

First create a store with undo middleware

This returns the familiar store accessible by a hook! But now your store tracks past actions.

import create, { UndoState } from 'zundo';

// define the store (typescript)
interface StoreState extends UndoState {
  bears: number;
  increasePopulation: () => void;
  removeAllBears: () => void;
}

// creates a store with undo/redo capability
const useStoreWithUndo = create<StoreState>(set => ({
  bears: 0,
  increasePopulation: () => set(state => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}));

Then bind your components

Use your store anywhere, including undo, redo, and clear!

const App = () => {
  const {
    bears,
    increasePopulation,
    removeAllBears,
    undo,
    redo,
    clear,
  } = useStoreWithUndo();

  return (
    <>
      bears: {bears}
      <button onClick={increasePopulation}>increase</button>
      <button onClick={removeAllBears}>remove</button>
      <button onClick={undo}>undo</button>
      <button onClick={redo}>redo</button>
      <button onClick={clear}>clear</button>
    </>
  );
};

Alternatively, use the middleware

Instead of using create from zundo, use the zundo middleware and the zustand create.

import { undoMiddleware, UndoState } from 'zundo';
import create from 'zustand';

const useStoreWithUndo = create<StoreState>(
  undoMiddleware(set => ({
    bears: 0,
    increasePopulation: () => set(state => ({ bears: state.bears + 1 })),
    removeAllBears: () => set({ bears: 0 }),
  }))
);

Other features

Omit fields from being tracked in history

Some fields you may not want to track in history and they can be ignored by zundo middleware. The second options parameter for undoMiddleware contains an omit field which is an array of string of keys on StoreState to be omitted from being tracked in history.

const useStore = create<StoreState>(
  undoMiddleware(
    set => ({ ... }),
    { omit: ['field1', 'field2'] }
  )
);

API

undoMiddleware(config: StateCreator<TState>)

This is middleware for zustand which takes in a config for the store.

This works for multiple undoable stores in the same app.

create

Create from zundo will return a store hook that has undo/redo capabilities. In addition to what fields are in the provided in your StoreState, the functions undo, redo, clear, and getState are added as well.

This works for multiple undoable stores in the same app.

  • undo: call function to apply previous state (if there are previous states)
  • redo: call function to apply future state (if there are future states). Future states are "previous previous states."
  • clear: call function to remove all stored states from your undo store. Warning: clearing cannot be undone.

Dispatching a new state will clear all of the future states.

createUndoStore()

Will create a store that is used by the middleware to track the internal state of type UndoStoreState.

UndoState

A type to extend when creating a global store with undo/redo capabilities.

type UndoState = {
  // Will go back one state
  undo?: (() => void) | undefined;
  // Will go forward one state
  redo?: (() => void) | undefined;
  // Will clear
  clear?: (() => void) | undefined;
  getState?: (() => UndoStoreState) | undefined;
};

Usage

import create, { UndoState } from 'zundo';

interface StoreState extends UndoState {
  // fields
}

const useStoreWithUndo = create<StoreState>();
// (set, get, api)

UseStore

It is an interface from zustand where T is your StoreState. Very similar to the type definition shown below. It is the type of any useStore hook. Used when passing the useStore hook as a prop.

type UseStore<T extends object> = {
    (): T;
    <U>(selector: StateSelector<T, U>, equalityFn?: EqualityChecker<U> | undefined): U;
    setState: SetState<T>;
    getState: GetState<...>;
    subscribe: Subscribe<...>;
    destroy: Destroy;
}

UndoStoreState

An interface for the store that tracks states.

type UndoStoreState = {
  prevStates: any[];
  futureStates: any[];
  undo: () => void;
  redo: () => void;
  clear: () => void;
  setStore: Function;
  getStore: Function;
};

Road Map

  • possibly use better data structure for storing previous states. Maybe just a diff between states?

Contributing

Issues and PRs are welcome. I'd like to hear your comments and critiques. We can discuss ways to make this package better. Thanks :)

zundo's People

Contributors

charkour avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.