clear-virtualizer 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -232,11 +232,14 @@ If the row is far away and its neighbors were never measured, the hook first jum
232
232
 
233
233
  `estimateSize` is only a starting guess until real measurements arrive. The closer it is to reality, the less rows visually shift on fast scroll through unmeasured regions: underestimated rows overlap until measured, overestimated ones leave temporary gaps. Pass a value near your average row height.
234
234
 
235
+ ## SSR
236
+
237
+ Server-side rendering is supported: on the server the hook renders an empty container (`virtualItems: []`, `scrollHeight: 0`) without touching browser APIs. Rows appear after hydration once the scroll container is attached and `ResizeObserver` reports real heights.
238
+
235
239
  ## Limitations
236
240
 
237
241
  - Vertical scrolling only — no horizontal virtualization, no sticky columns.
238
242
  - The internal offset tree keeps one `float64` per row (~8 MB per million rows).
239
- - Server-side rendering is not covered by tests.
240
243
 
241
244
  ## License
242
245
 
package/lib/index.cjs CHANGED
@@ -204,6 +204,8 @@ function useVirtualizer({ count, estimateSize, overscan = DEFAULT_OVERSCAN }) {
204
204
  existing.observer.disconnect();
205
205
  observersRef.current.delete(index);
206
206
  }
207
+ if (typeof ResizeObserver === "undefined")
208
+ return;
207
209
  const observer = new ResizeObserver(([entry]) => {
208
210
  const height = entry?.borderBoxSize[0]?.blockSize;
209
211
  if (height == null || !fenwickRef.current)
@@ -371,6 +373,21 @@ function useVirtualizer({ count, estimateSize, overscan = DEFAULT_OVERSCAN }) {
371
373
  },
372
374
  [handleScroll]
373
375
  );
376
+ react.useEffect(
377
+ () => () => {
378
+ if (rafRef.current !== null)
379
+ cancelAnimationFrame(rafRef.current);
380
+ if (tickRafRef.current !== null)
381
+ cancelAnimationFrame(tickRafRef.current);
382
+ observersRef.current.forEach((entry) => entry.observer.disconnect());
383
+ observersRef.current.clear();
384
+ containerObserverRef.current?.disconnect();
385
+ containerObserverRef.current = null;
386
+ scrollElementRef.current?.removeEventListener("scroll", handleScroll);
387
+ refCacheRef.current.clear();
388
+ },
389
+ [handleScroll]
390
+ );
374
391
  const { virtualItems, scrollHeight } = react.useMemo(
375
392
  () => computeItems(scrollOffset.value),
376
393
  [computeItems, scrollOffset]
package/lib/index.js CHANGED
@@ -202,6 +202,8 @@ function useVirtualizer({ count, estimateSize, overscan = DEFAULT_OVERSCAN }) {
202
202
  existing.observer.disconnect();
203
203
  observersRef.current.delete(index);
204
204
  }
205
+ if (typeof ResizeObserver === "undefined")
206
+ return;
205
207
  const observer = new ResizeObserver(([entry]) => {
206
208
  const height = entry?.borderBoxSize[0]?.blockSize;
207
209
  if (height == null || !fenwickRef.current)
@@ -369,6 +371,21 @@ function useVirtualizer({ count, estimateSize, overscan = DEFAULT_OVERSCAN }) {
369
371
  },
370
372
  [handleScroll]
371
373
  );
374
+ useEffect(
375
+ () => () => {
376
+ if (rafRef.current !== null)
377
+ cancelAnimationFrame(rafRef.current);
378
+ if (tickRafRef.current !== null)
379
+ cancelAnimationFrame(tickRafRef.current);
380
+ observersRef.current.forEach((entry) => entry.observer.disconnect());
381
+ observersRef.current.clear();
382
+ containerObserverRef.current?.disconnect();
383
+ containerObserverRef.current = null;
384
+ scrollElementRef.current?.removeEventListener("scroll", handleScroll);
385
+ refCacheRef.current.clear();
386
+ },
387
+ [handleScroll]
388
+ );
372
389
  const { virtualItems, scrollHeight } = useMemo(
373
390
  () => computeItems(scrollOffset.value),
374
391
  [computeItems, scrollOffset]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-virtualizer",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A lightweight React hook for virtualized lists and tables with dynamic row heights, measured automatically",
5
5
  "type": "module",
6
6
  "main": "./lib/index.cjs",