From 2c2494d6f9f00b65646e0161e0760351e299db52 Mon Sep 17 00:00:00 2001 From: Mike Neverov <3989091+mneveroff@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:43:46 +0000 Subject: [PATCH] Added slices pattern example (#194) * added slices pattern example * uninstall devtools * revert pnpm lock change --- README.md | 1 + examples/web/next-env.d.ts | 2 +- examples/web/pages/slices.tsx | 147 ++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 examples/web/pages/slices.tsx diff --git a/README.md b/README.md index 3f20534..bac982a 100644 --- a/README.md +++ b/README.md @@ -566,6 +566,7 @@ PRs are welcome! [pnpm](https://pnpm.io/) is used as a package manager. Run `pnp - [canUndo, canRedo, undoDepth, redoDepth](https://codesandbox.io/s/zundo-canundo-and-undodepth-l6jclx?file=/src/App.tsx:572-731) - [with deep equal](https://codesandbox.io/p/sandbox/zundo-deep-equal-qg69lj) - [with input](https://stackblitz.com/edit/vitejs-vite-jqngm9?file=src%2FApp.tsx) +- [with slices pattern](https://codesandbox.io/p/sandbox/pttx6c) ## Migrate from v1 to v2 diff --git a/examples/web/next-env.d.ts b/examples/web/next-env.d.ts index 4f11a03..a4a7b3f 100644 --- a/examples/web/next-env.d.ts +++ b/examples/web/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/examples/web/pages/slices.tsx b/examples/web/pages/slices.tsx new file mode 100644 index 0000000..8909a6f --- /dev/null +++ b/examples/web/pages/slices.tsx @@ -0,0 +1,147 @@ +import type { StateCreator } from 'zustand'; +import type { TemporalState } from 'zundo'; +import { temporal } from 'zundo'; +import { create } from 'zustand'; +import { useShallow } from 'zustand/shallow'; +import { useStoreWithEqualityFn } from 'zustand/traditional'; + +interface BearSlice { + bears: number + addBear: () => void + eatFish: () => void +} + +interface FishSlice { + fishes: number + addFish: () => void +} + +const createBearSlice: StateCreator< + BearSlice & FishSlice, + [], + [], + BearSlice +> = (set) => ({ + bears: 0, + addBear: () => set((state) => ({ bears: state.bears + 1 })), + removeBear: () => set((state) => ({ bears: state.bears - 1 })), + eatFish: () => set((state) => ({ fishes: state.fishes - 1 })), +}) + +const createFishSlice: StateCreator< + BearSlice & FishSlice, + [], + [], + FishSlice +> = (set) => ({ + fishes: 0, + addFish: () => set((state) => ({ fishes: state.fishes + 1 })), +}) + +const useSharedStore = create()( + temporal( + (...a) => ({ + ...createBearSlice(...a), + ...createFishSlice(...a), + }), + { + limit: 10 + } + ) +) + +function useTemporalStore(): TemporalState; +function useTemporalStore( + selector: (state: TemporalState) => T +): T; +function useTemporalStore( + selector: (state: TemporalState) => T, + equality: (a: T, b: T) => boolean +): T; +function useTemporalStore( + selector?: (state: TemporalState) => T, + equality?: (a: T, b: T) => boolean +) { + return useStoreWithEqualityFn(useSharedStore.temporal, selector!, equality); +} + +const UndoBar = () => { + const { undo, redo, pastStates, futureStates } = useTemporalStore( + (state) => ({ + undo: state.undo, + redo: state.redo, + pastStates: state.pastStates, + futureStates: state.futureStates, + }) + ); + + return ( +
+ past states: {JSON.stringify(pastStates)} +
+ future states: {JSON.stringify(futureStates)} +
+ + +
+ ); +}; + +const BearState = () => { + const { bears, addBear, eatFish } = useSharedStore(useShallow((state) => ({ + bears: state.bears, + addBear: state.addBear, + eatFish: state.eatFish, + }))); + + return ( +
+ bears: {bears} +
+ + +
+ ); +}; + +const FishState = () => { + const { fishes, addFish } = useSharedStore(useShallow((state) => ({ + fishes: state.fishes, + addFish: state.addFish, + }))); + + return ( +
+ fishes: {fishes} +
+ +
+ ); +}; + +const App = () => { + return ( +
+

+ {' '} + + 🐻 + {' '} + + ♻️ + {' '} + Zundo! +

+ + +
+ +
+ ); +}; + +export default App;