virtua-restoration
Version:
<img src="./virtua-restoration.png" alt="Virtua Restoration" style="max-width: 1000px; width: 100%; display: block; margin: 0 auto 20px auto;">
128 lines (105 loc) โข 5.17 kB
Markdown
<img src="./virtua-restoration.png" alt="Virtua Restoration" style="max-width: 1000px; width: 100%; display: block; margin: 0 auto 20px auto;">
[](https://www.npmjs.com/package/virtua-restoration)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
[](https://www.npmjs.com/package/virtua-restoration)
[](https://github.com/serter1/virtua-restoration/actions)
It is a wrapper component that facilitates virtual listing with the [`virtua`](https://github.com/inokawa/virtua) library by storing scroll position and cache information in React applications.
https://virtua-restoration.vercel.app
- Maintains scroll position when doing virtual listing.
- Provides cache management with `sessionStorage`, `localStorage` or custom (e.g. Zustand).
- Works with the [`virtua`](https://github.com/inokawa/virtua) library.
- Prevents scroll and cache loss on route transitions or page refreshes.
## ๐ฆ Installation
```bash
pnpm add virtua virtua-restoration
# or
npm install virtua virtua-restoration
# or
yarn add virtua virtua-restoration
```
## ๐ Peer Dependencies
| Package | Version |
| ---------------- | ------------------------------------------ |
| react | >=19.0.0 |
| react-dom | >=19.0.0 |
| virtua | >=0.41.5 |
```typescript
import { WindowVirtualizedList } from 'virtua-restoration'
export default function Example() {
return (
<WindowVirtualizedList cacheKey="feed">
{[...Array(200)].map((_, i) => (
<div key={i} style={{ height: 80, borderBottom: '1px solid #ddd' }}>
Row {i}
</div>
))}
</WindowVirtualizedList>
)
}
```
```typescript
import { WindowVirtualizedList } from 'virtua-restoration'
export default function Example() {
return (
<WindowVirtualizedList cacheKey="feed" cacheSource="localStorage">
{[...Array(200)].map((_, i) => (
<div key={i} style={{ height: 80, borderBottom: '1px solid #ddd' }}>
Row {i}
</div>
))}
</WindowVirtualizedList>
)
}
```
```typescript
// store/virtualListStore.ts
import { create } from 'zustand'
import { CacheSnapshot } from 'virtua'
interface VirtualListState {
cacheMap: Record<string, [number, CacheSnapshot]>
get: (key: string) => [number, CacheSnapshot] | undefined
set: (key: string, data: [number, CacheSnapshot]) => void
}
export const useVirtualListStore = create<VirtualListState>((set, get) => ({
cacheMap: {},
get: (key) => get().cacheMap[key],
set: (key, data) =>
set((state) => ({
cacheMap: {
...state.cacheMap,
[]: data,
},
})),
}))
```
```typescript
// pages/list.tsx
import { WindowVirtualizedList } from 'virtua-restoration'
import { useVirtualListStore } from './store/virtualListStore'
const cacheProvider = {
get: () => useVirtualListStore.getState().get('feed'),
set: (data) => useVirtualListStore.getState().set('feed', data),
}
<WindowVirtualizedList cacheKey="feed" cacheSource="custom" customProvider={cacheProvider}>
{/* children */}
</WindowVirtualizedList>
```
| Prop |Type | Description |
| ---------------- | ------------------------------------------ | -------------------------------------------------------------------- |
| cacheKey |string | Unique outline where scroll/cache data will be stored |
| children |React.ReactNode | List content (items to be rendered virtually) |
| cacheSource |`sessionStorage` `localStorage` `custom` | Where to store the cache (default: `sessionStorage`) |
| customProvider | CacheProvider | Get/set functions to use if `cacheSource` is `custom` |
## ๐ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## ๐ License
MIT License - see the [LICENSE](LICENSE) file for details.