refactor(types): reorganize SearchCondition and AdvancedSearchState interfaces refactor(filterPresets): streamline useFilterPresets hook and localStorage handling refactor(filtering): clean up ColumnFilterButton and ColumnFilterPopover components refactor(loading): separate GriddyLoadingOverlay from GriddyLoadingSkeleton refactor(searchHistory): enhance useSearchHistory hook with persistence refactor(index): update exports for adapters and core components refactor(rendering): improve EditableCell and TableCell components for clarity refactor(rendering): enhance TableHeader and VirtualBody components for better readability
3.4 KiB
3.4 KiB
@warkypublic/zustandsyncstore v1.0.0
React library providing synchronized Zustand stores with prop-based state management and persistence support.
Peer Dependencies
react>= 19.0.0zustand>= 5.0.0use-sync-external-store>= 1.4.0
Runtime Dependencies
@warkypublic/artemis-kit
API
Single export: createSyncStore
import { createSyncStore } from '@warkypublic/zustandsyncstore';
createSyncStore<TState, TProps>(createState?, useValue?)
Parameters:
createState(optional): ZustandStateCreator<TState>functionuseValue(optional): Custom hook receiving{ useStore, useStoreApi } & TProps, returns additional state to merge
Returns: SyncStoreReturn<TState, TProps> containing:
Provider— React context provider componentuseStore— Hook to access the store
Provider Props
| Prop | Type | Description |
|---|---|---|
children |
ReactNode |
Required |
firstSyncProps |
string[] |
Props to sync only on first render |
persist |
PersistOptions<Partial<TProps & TState>> |
Zustand persist config |
waitForSync |
boolean |
Wait for sync before rendering children |
fallback |
ReactNode |
Shown while waiting for sync |
...TProps |
TProps |
Custom props synced to store state |
useStore Hook
const state = useStore(); // entire state (TState & TProps)
const count = useStore(state => state.count); // with selector
const count = useStore(state => state.count, (a, b) => a === b); // with equality fn
Usage
Basic
interface MyState { count: number; increment: () => void; }
interface MyProps { initialCount: number; }
const { Provider, useStore } = createSyncStore<MyState, MyProps>(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
})
);
function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>Count: {count}</button>;
}
function App() {
return (
<Provider initialCount={10}>
<Counter />
</Provider>
);
}
With Custom Hook Logic
const { Provider, useStore } = createSyncStore<MyState, MyProps>(
(set) => ({ count: 0, increment: () => set((s) => ({ count: s.count + 1 })) }),
({ useStore, useStoreApi, initialCount }) => {
const currentCount = useStore(state => state.count);
return { computedValue: initialCount * 2 };
}
);
With Persistence
<Provider initialCount={10} persist={{ name: 'my-store', storage: localStorage }}>
<Counter />
</Provider>
Selective Prop Syncing
<Provider initialCount={10} otherProp="value" firstSyncProps={['initialCount']}>
<Counter />
</Provider>
Internal Types
type LocalUseStore<TState, TProps> = TState & TProps;
// Store state includes a $sync method for internal prop syncing
type InternalStoreState<TState, TProps> = TState & TProps & {
$sync: (props: TProps) => void;
};
type SyncStoreReturn<TState, TProps> = {
Provider: (props: { children: ReactNode } & {
firstSyncProps?: string[];
persist?: PersistOptions<Partial<TProps & TState>>;
waitForSync?: boolean;
fallback?: ReactNode;
} & TProps) => React.ReactNode;
useStore: {
(): LocalUseStore<TState, TProps>;
<U>(selector: (state: LocalUseStore<TState, TProps>) => U, equalityFn?: (a: U, b: U) => boolean): U;
};
};