Hledám nějaké rozumné řešení prezentace komponent ve Storybooku, které jsou navržené pro práci s Zustandem (nebo jiným global state managementem). Vycházím z předpokladu, že v design-systemu by měly být komponenty v rámci svých možností co nejvíc agnostické.
Momentální řešení: Inicializuji separate store v rámci každé story, který obsahuje nezbytné minimum pro funkčnost komponenty.
Teď otázka zda řešit toto, jelikož momentálníé řešení nění úplně aligned s filozofií SB.
Store
instanceje pro celý modul**, a tu pak všechny stories sdílejí (riziko “prosakování” stavu mezi jednotlivými stories[Default, Second])
Existuje robustnějiši řešní (Decorator Mocking nebo Context Provider), které by overbleed stavu mělo vyřešit a vypadá to, že decorators jsou lepší cesta, abych nemusel přepisovat komponentu.
// FilterForm.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { FilterForm } from '@repo/design-system/components';
import { create } from 'zustand'; // Import create from zustand
const meta: Meta<typeof FilterForm> = {
title: 'Components/FilterForm',
component: FilterForm,
tags: ['autodocs'],
};
type FilterFormStory = StoryObj<typeof meta>;
const useStoryStore = create((set) => ({
items: [
{ value: 'one', label: 'One', checked: false },
{ value: 'two', label: 'Two', checked: false }, // Example initial state
{ value: 'three', label: 'Three', checked: false },
],
toggleItems: (value) =>
set((state) => ({
items: state.items.map((item) => (item.value === value ? { ...item, checked: !item.checked } : item)),
})),
toggleAllItems: () =>
set((state) => ({
items: state.items.map((item) => ({ ...item, checked: !item.checked })),
})),
}));
export const Default: FilterFormStory = {
render: () => {
const items = useStoryStore((state) => state.items);
const toggleItem = useStoryStore((state) => state.toggleItems);
const toggleAllItems = useStoryStore((state) => state.toggleAllItems);
console.log(items);
return (
<div>
<FilterForm items={items} toggleItem={(value) => toggleItem(value)} toggleAllItems={toggleAllItems} />
</div>
);
},
};
export default meta;
Co myslíte?