Files
2026-05-27 23:29:53 +01:00

3.8 KiB

OpenSpec Change: enterprise-react-virtual

  • Change ID: enterprise-react-virtual
  • Package: @suaveplan/react-virtual
  • Category: react
  • Target path: react/ui/react-virtual
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/react-virtual.md

Summary

Deliver @suaveplan/react-virtual on genesis from scratch at enterprise quality. A TypeScript-first virtualization engine for React with a headless core (virtual-engine, range-calculator), React hooks (useVirtualList, useVirtualGrid, useVirtualScroll), and batteries-included components (VirtualList, VirtualGrid) with generic item types, dynamic sizing via SizeCache, overscan, scroll-direction-aware range calculation, SharedResizeObserver pooling, and scroll utilities. Zero workspace runtime deps — pure React + DOM.


Current-state audit (genesis)

Package does not exist on genesis — fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) VirtualError for invalid config
@suaveplan/types (workspace:^) Shared option types
zod (catalog:forms) Engine config schemas

External: clsx catalog:ui, tailwind-merge catalog:ui, tslib catalog:build. React 18 peer.


Preserved public API surface

Components

VirtualList<T>, VirtualGrid<T> — with handle refs (VirtualListHandle, VirtualGridHandle) and render-prop APIs.

Hooks

useVirtualList, useVirtualGrid, useVirtualScroll

Engine

createVirtualEngine, calculateVirtualItems, buildVirtualItems, calculateVisibleRange, calculateScrollToOffset, createSizeCache, findIndexAtOffset, getItemOffset, getItemSize, setItemSize, getScrollDirection, getTotalSize

Range calculator

calculateGridRange, calculateGridDimensions, buildGridCells, findAxisIndex, getAxisOffset, getAxisTotalSize, resolveSize

Utilities

SharedResizeObserver, getSharedResizeObserver, measureElement, resetSharedResizeObserver, throttle, throttleWithRaf, getScrollOffset, clampScrollOffset, scrollTo, isNearEnd

Types

ScrollAlignment, ScrollDirection, ScrollToIndexParams, SizeCache, SizeMode, VirtualEngineConfig, VirtualEngineResult, VirtualItem, VisibleRange, ThrottleOptions, ResizeCallback


New additions for genesis

  1. @suaveplan/error-backed VirtualError with codes VIRTUAL_INVALID_CONFIG, VIRTUAL_SCROLL_FAILED.
  2. Zod VirtualEngineConfigSchema for runtime validation of engine options.
  3. Stories — VirtualList and VirtualGrid each with default, dynamic-sizes, large-dataset (100k items), playground, a11y stories.
  4. prefers-reduced-motion scroll behavior — scrollTo respects behavior: 'instant' when reduced motion is detected.
  5. OTel instrumentation — virtual.scroll span event with virtual.item_count attribute.

File layout

react/ui/react-virtual/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    core/
      virtual-engine/ (ts + types + md + test + index)
      range-calculator/ (ts + types + md + test + index)
    hooks/
      use-virtual-list/ (ts + types + md + test + index)
      use-virtual-grid/ (ts + types + md + test + index)
      use-virtual-scroll/ (ts + types + md + test + index)
    components/
      virtual-list/ (tsx + types + md + test + stories + index)
      virtual-grid/ (tsx + types + md + test + stories + index)
    utils/
      resize-observer/ (ts + md + test + index)
      scroll-utils/ (ts + md + test + index)
    styles/
      virtual.css
  tests/
    integration.test.tsx
  e2e/
    virtual.spec.ts

Impact

@suaveplan/react-data-table and @suaveplan/react-timeline depend on this package. Must be published before them.