Warper

repository·main·Indexed 43 days ago

https://github.com/warper-org/warper

An ultra-fast React virtualization library powered by Rust and WebAssembly, designed to handle massive datasets of 10M+ items at 120+ FPS. It provides the `useVirtualizer` hook for fine-grained control and the `WarperComponent` for declarative implementation. Supports multiple layout modes including List, Grid, Masonry, and Infinite Scroll, with built-in accessibility (A11y) and keyboard navigation.

Tokens
6.6K
Snippets
21
Records
26
Agent score
44%

What's inside Warper

  1. Supported Layout Modes in Warper

    main

    Warper supports several layout modes that share the same high-performance core engine. You can switch between these by adjusting the configuration:

    • List: Standard vertical scrolling list.
    • Grid: Items arranged in rows and columns.
    • Masonry: Items arranged in a masonry/waterfall layout.
    • Horizontal: Horizontal scrolling layouts.
    • Infinite Scroll: Automatically loads more data as the user reaches the end.
    • Combo Layouts: Combinations of the above.
  2. Advanced Features and Built-in Support

    main

    Warper includes several advanced features out-of-the-box to improve developer experience and user accessibility:

    Async and Infinite Scroll

    • onEndReached: Callback triggered when the user scrolls to the end of the list, ideal for infinite scrolling.
    • restoreScrollPosition: Automatically restores the scroll position on re-renders.
    • Async Placeholders: Support for rendering skeletons or placeholder rows while data is loading.
    • Multi-select: Built-in support for Shift+Click and Ctrl+Click selection.
    • Keyboard Navigation: Full support for arrow keys, Home, and End keys.

    Accessibility (A11y)

    • Automatically applies appropriate ARIA roles such as list, listitem, and gridcell.
    • Optimized for screen readers by ensuring only visible nodes are exposed to the accessibility tree.
  3. Quick Start: Using the WarperComponent

    main

    The WarperComponent provides a higher-level, declarative way to implement virtualization. You pass the total item count and an estimation function as props, and provide a render function as children that receives the current item index.

    Required props:

    • itemCount: Total number of items.
    • estimateSize: A function returning the estimated height of an item.
    • overscan: (Optional) Number of items to render outside the visible area.

    Children:

    • A function that receives the index and returns the component to render for that index.
    import { WarperComponent } from '@itsmeadarsh/warper';
    
    function App() {
      return (
        <WarperComponent
          itemCount={1_000_000}
          estimateSize={() => 44}
          overscan={5}
        >
          {(index) => <Row data={items[index]} />}
        </WarperComponent>
      );
    }
  4. Quick Start: Using the useVirtualizer hook

    main

    The useVirtualizer hook is the recommended way to implement virtualization when you need fine-grained control over the rendering logic and container structure.

    It returns:

    • scrollElementRef: A ref to be attached to the scrollable container.
    • range: An object containing items (the indices of visible items), offsets (the Y positions for each item), and sizes (the height of each item).
    • totalHeight: The calculated total height of the entire list to ensure correct scrollbar behavior.

    Required options:

    • itemCount: Total number of items in the list.
    • estimateSize: A function that returns the estimated height of an item.
    • overscan: (Optional) Number of items to render outside the visible area to reduce flickering during scrolling.
    import { useVirtualizer } from '@itsmeadarsh/warper';
    
    function MyList() {
      const { scrollElementRef, range, totalHeight } = useVirtualizer({
        itemCount: 1_000_000,
        estimateSize: () => 50,
        overscan: 5,
      });
    
      return (
        <div ref={scrollElementRef} style={{ height: 500, overflow: 'auto' }}>
          <div style={{ height: totalHeight, position: 'relative' }}>
            {range.items.map((index, i) => (
              <div
                key={index}
                style={{
                  position: 'absolute',
                  top: 0,
                  transform: `translateY(${range.offsets[i]}px)`,
                  height: range.sizes[i],
                  width: '100%',
                }}
              >
                Row {index}
              </div
            ))}
          </div
        </div>
      );
    }
  5. Install @itsmeadarsh/warper via package managers

    main

    Install the Warper React virtualization library using your preferred package manager.

    # Using npm
    npm install @itsmeadarsh/warper
    
    # Using yarn
    yarn add @itsmeadarsh/warper
    
    # Using pnpm
    pnpm add @itsmeadarsh/warper
    
    # Using bun
    bun add @itsmeadarsh/warper
  6. Install @itsmeadarsh/warper

    main

    Install the Warper package using your preferred package manager to use ultra-fast React virtualization powered by Rust and WebAssembly.

    npm install @itsmeadarsh/warper
    # or
    yarn add @itsmeadarsh/warper
    # or
    pnpm add @itsmeadarsh/warper
    # or
    bun add @itsmeadarsh/warper
  7. Initialize the Warper WASM module

    main

    To use the WASM-powered features of Warper, you must first initialize the module. You can use either the asynchronous default export or the synchronous initSync function.

    • Asynchronous (Default Export): Use this to fetch and instantiate the WASM module from a URL or a Response object. If no argument is provided, it defaults to fetching warper_wasm_bg.wasm relative to the current module.
    • Synchronous (initSync): Use this if you already have a WebAssembly.Module instance ready.

    Note: The module must be initialized before calling any other exported functions or classes.

    import init, { initSync } from './warper_wasm.js';
    
    // Asynchronous initialization (recommended)
    await init();
    
    // Or synchronous initialization if you have the module
    // initSync(wasmModule);
  8. Use the WarperComponent for quick implementation

    main

    If you prefer a declarative component-based approach instead of using the hook directly, use <WarperComponent />. This component handles the rendering logic internally.

    Props:

    • data: The array of items to virtualize.
    • estimateSize: A function providing the estimated size of items.
    • overscan: Number of items to render outside the visible viewport.
    • renderItem: A function that returns the React element for a single item.
    <WarperComponent
      data={bigList}
      estimateSize={() => 44}
      overscan={2}
      renderItem={(item) => <Row item={item} />}
    />
  9. Use the useVirtualizer hook

    main

    The useVirtualizer hook is the recommended way to implement virtualization. It provides a scrollElementRef to attach to your container, a range object containing visible item data, and utility methods for scrolling.

    Hook Options

    • itemCount (required): Total number of items.
    • estimateSize (required): Function returning item height: (index: number) => number.
    • overscan (default: 5): Extra items to render above/below the visible area.
    • horizontal (default: false): Enables horizontal scroll mode.
    • height (default: '100%'): Container height.

    Return Values

    • scrollElementRef: Ref to attach to the scroll container.
    • range: An object of type VirtualRange containing current visible data.
    • totalHeight: Total scrollable height.
    • isLoading: Boolean indicating WASM loading state.
    • error: Error object if initialization failed.
    • scrollToIndex: Function to scroll to a specific index: (index, behavior?) => void.
    • scrollToOffset: Function to scroll to a pixel offset: (offset, behavior?) => void.
    import { useVirtualizer } from '@itsmeadarsh/warper';
    
    function MyList() {
      const { scrollElementRef, range, totalHeight } = useVirtualizer({
        itemCount: 1_000_000,
        estimateSize: () => 50,
        overscan: 5,
      });
    
      return (
        <div ref={scrollElementRef} style={{ height: 500, overflow: 'auto' }}>
          <div style={{ height: totalHeight, position: 'relative' }}>
            {range.items.map((index, i) => (
              <div
                key={index}
                style={{
                  position: 'absolute',
                  top: 0,
                  transform: `translateY(${range.offsets[i]}px)`,
                  height: range.sizes[i],
                  width: '100%',
                }}
              >
                Row {index}
              </div>
            ))}
          </div>
        </div>
      );
    }
  10. Use the WarperComponent

    main

    The WarperComponent is a ready-to-use component that abstracts the virtualization logic. It accepts a render function as children.

    Props

    • itemCount (required): Total number of items.
    • estimateSize (required): Function returning item height.
    • children (required): A function (index: number) => React.ReactNode to render each item.
    • overscan (optional): Extra items to render.
    • height (optional): Container height.
    • horizontal (optional): Enables horizontal mode.
    • className (optional): CSS class name.
    • style (optional): Inline styles.
    • onRendered (optional): Callback when items are rendered.
    • loadingPlaceholder (optional): Component to show while loading.
    • errorPlaceholder (optional): Function (error: Error) => React.ReactNode to handle errors.
    import { WarperComponent } from '@itsmeadarsh/warper';
    
    function MyList() {
      return (
        <WarperComponent
          itemCount={1_000_000}
          estimateSize={() => 50}
          height={500}
          overscan={5}
        >
          {(index) => (
            <div style={{ padding: 16 }}>
              Row {index}
            </div>
          )}
        </WarperComponent>
      );
    }