Skip to content

Commit

Permalink
convert to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
charkour committed Apr 2, 2021
1 parent e0d000b commit ef764f0
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 46 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Undo middleware for your favorite, comfy, bearbones state-management solution: [zustand](https://github.com/pmndrs/zustand).

## TODO: add demo

## Install

```sh
Expand Down Expand Up @@ -47,8 +49,7 @@ const App = () => {

## Road Map

- add redo
- typescript support
- add redo. probably with index to traverse through prevStates
- clean up api? return `undo` with the store hook?

## Contributing
Expand Down
34 changes: 0 additions & 34 deletions src/index.js

This file was deleted.

46 changes: 46 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import createVanilla, {
GetState,
SetState,
State,
StateCreator,
StoreApi,
} from 'zustand/vanilla';
import create from 'zustand';

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

interface UndoStoreState extends State {
prevStates: any[];
undo: () => void;
handle: Function;
}

// Stores previous actions
const undoStore = createVanilla<UndoStoreState>((_, get) => ({
prevStates: [],
undo: () => {
get().handle(get().prevStates.pop());
},
handle: () => {},
}));
const { getState, setState } = undoStore;
export const useUndo = create(undoStore);

// custom middleware to get previous state
export const undo = <TState extends State>(config: StateCreator<TState>) => (
set: SetState<TState>,
get: GetState<TState>,
api: StoreApi<TState>
) =>
config(
args => {
setState({
prevStates: [...getState().prevStates, { ...get() }],
handle: set,
});
set(args);
console.log(' new state', get());
},
get,
api
);
16 changes: 11 additions & 5 deletions stories/bears.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { undo, useUndo } from '../src';
import create from 'zustand';
import create, { State } from 'zustand';

const meta: Meta = {
title: 'bears',
Expand All @@ -19,8 +19,14 @@ const meta: Meta = {

export default meta;

interface StoreState extends State {
bears: number;
increasePopulation: () => void;
removeAllBears: () => void;
}

// create a store with undo middleware
const useStore = create(
const useStore = create<StoreState>(
undo(set => ({
bears: 0,
increasePopulation: () => set(state => ({ bears: state.bears + 1 })),
Expand All @@ -29,21 +35,21 @@ const useStore = create(
);

const App = () => {
const { prevActions, undo } = useUndo();
const { prevStates, undo } = useUndo();
const { bears, increasePopulation, removeAllBears } = useStore();

return (
<div>
<h1>🐻 ♻️ Zundo!</h1>
previous actions: {JSON.stringify(prevActions)}
previous actions: {JSON.stringify(prevStates)}
<br />
<br />
bears: {bears}
<br />
<button onClick={increasePopulation}>increase</button>
<button onClick={removeAllBears}>remove</button>
<br />
<button onClick={undo as any}>undo</button>
<button onClick={undo}>undo</button>
</div>
);
};
Expand Down
18 changes: 13 additions & 5 deletions stories/bees.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { Meta, Story } from '@storybook/react';
import { undo, useUndo } from '../src';
import create from 'zustand';
import create, { State } from 'zustand';

const meta: Meta = {
title: 'bees',
Expand All @@ -19,8 +19,16 @@ const meta: Meta = {

export default meta;

interface StoreStateWithUndo extends State {
bees: number;
text: string;
incrementBees: () => void;
decrementBees: () => void;
submitText: (text: string) => void;
}

// create a store with undo middleware
const useStoreWithUndo = create(
const useStoreWithUndo = create<StoreStateWithUndo>(
undo(set => ({
bees: 0,
text: "",
Expand All @@ -31,7 +39,7 @@ const useStoreWithUndo = create(
);

const App = () => {
const { prevActions, undo } = useUndo();
const { prevStates, undo } = useUndo();
const {
bees,
incrementBees,
Expand All @@ -44,7 +52,7 @@ const App = () => {
return (
<div>
<h1>🐻 ♻️ Zustand undo!</h1>
actions stack: {JSON.stringify(prevActions)}
actions stack: {JSON.stringify(prevStates)}
<br />
<br />
bees: {bees}
Expand All @@ -59,7 +67,7 @@ const App = () => {
<br />
text: {text}
<br />
<button onClick={undo as any}>undo</button>
<button onClick={undo}>undo</button>
</div>
);
}
Expand Down

0 comments on commit ef764f0

Please sign in to comment.