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
132 lines
3.4 KiB
Markdown
132 lines
3.4 KiB
Markdown
# @warkypublic/zustandsyncstore v1.0.0
|
|
|
|
React library providing synchronized Zustand stores with prop-based state management and persistence support.
|
|
|
|
## Peer Dependencies
|
|
|
|
- `react` >= 19.0.0
|
|
- `zustand` >= 5.0.0
|
|
- `use-sync-external-store` >= 1.4.0
|
|
|
|
## Runtime Dependencies
|
|
|
|
- `@warkypublic/artemis-kit`
|
|
|
|
## API
|
|
|
|
Single export: `createSyncStore`
|
|
|
|
```typescript
|
|
import { createSyncStore } from '@warkypublic/zustandsyncstore';
|
|
```
|
|
|
|
### createSyncStore<TState, TProps>(createState?, useValue?)
|
|
|
|
**Parameters:**
|
|
- `createState` (optional): Zustand `StateCreator<TState>` function
|
|
- `useValue` (optional): Custom hook receiving `{ useStore, useStoreApi } & TProps`, returns additional state to merge
|
|
|
|
**Returns:** `SyncStoreReturn<TState, TProps>` containing:
|
|
- `Provider` — React context provider component
|
|
- `useStore` — 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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```tsx
|
|
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
|
|
|
|
```tsx
|
|
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
|
|
|
|
```tsx
|
|
<Provider initialCount={10} persist={{ name: 'my-store', storage: localStorage }}>
|
|
<Counter />
|
|
</Provider>
|
|
```
|
|
|
|
### Selective Prop Syncing
|
|
|
|
```tsx
|
|
<Provider initialCount={10} otherProp="value" firstSyncProps={['initialCount']}>
|
|
<Counter />
|
|
</Provider>
|
|
```
|
|
|
|
## Internal Types
|
|
|
|
```typescript
|
|
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;
|
|
};
|
|
};
|
|
```
|