Skip to content

Commit

Permalink
add useUndo and undo middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
charkour committed Apr 2, 2021
1 parent 916fe4c commit 9fc6bd7
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 21 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,8 @@
"path": "dist/zundo.esm.js",
"limit": "10 KB"
}
]
],
"dependencies": {
"zustand": "^3.3.3"
}
}
34 changes: 34 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import createVanilla from "zustand/vanilla";
import create from "zustand";

// original implementation
// https://stackblitz.com/edit/react-bcql2z

// use immer patches? https://immerjs.github.io/immer/patches/

// Stores previous actions
const undoStore = createVanilla((set, get) => ({
prevActions: [],
undo: () => {
get().handle(get().prevActions.pop());
},
handle: undefined
}));
const { getState, setState, subscribe, destroy } = undoStore;
export const useUndo = create(undoStore);

// custom middleware to get previous state
export const undo = config => (set, get, api) =>
config(
args => {
setState({
prevActions: [...getState().prevActions, { ...get() }],
handle: set
});
set(args);
console.log(" new state", get());
},
get,
api
);
15 changes: 0 additions & 15 deletions src/index.tsx

This file was deleted.

55 changes: 50 additions & 5 deletions stories/Thing.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import React, { useState } from 'react';
import { Meta, Story } from '@storybook/react';
import { Thing, Props } from '../src';
import { undo, useUndo } from '../src';
import create from 'zustand';

const meta: Meta = {
title: 'Welcome',
component: Thing,
title: 'Demo',
argTypes: {
children: {
control: {
Expand All @@ -19,7 +19,52 @@ const meta: Meta = {

export default meta;

const Template: Story<Props> = args => <Thing {...args} />;
// create a store with undo middleware
const useStoreWithUndo = create(
undo(set => ({
bees: 0,
text: "",
incrementBees: () => set(state => (state.bees += 1)),
decrementBees: () => set(state => (state.bees -= 1)),
submitText: text => set({ text })
}))
);

const App = () => {
const { prevActions, undo } = useUndo();
const {
bees,
incrementBees,
decrementBees,
submitText,
text
} = useStoreWithUndo();
const [inputText, setInputText] = useState("");

return (
<div>
<h1>🐻 ♻️ Zustand undo!</h1>
actions stack: {JSON.stringify(prevActions)}
<br />
<br />
bees: {bees}
<br />
<button onClick={incrementBees}>incremenet</button>
<button onClick={decrementBees}>decrement</button>
<br />
<br />
<input value={inputText} onChange={e => setInputText(e.target.value)} />
<br />
<button onClick={() => submitText(inputText)}>submit text</button>
<br />
text: {text}
<br />
<button onClick={undo as any}>undo</button>
</div>
);
}

const Template: Story<{}> = args => <App {...args} />;

// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13414,6 +13414,11 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

zustand@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.3.3.tgz#88b930a873d0f13e406f96958c1409645ea8b370"
integrity sha512-KTN/O76rVc9muDoprsCDe/LQjbuq+GHYt5JdYahuXaGZ+8Gyk44SepzTFeQTF5J+b8+/Q+o90BaSEQ3WImKPog==

zwitch@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
Expand Down

0 comments on commit 9fc6bd7

Please sign in to comment.