Blog>
Snippets

Creating a Custom Scrollbar for Virtualized Lists

Provide an example of how to create a custom scrollbar component for a virtualized list, enhancing the default scrolling experience with TanStack Virtual.
import { useVirtual } from '@tanstack/react-virtual';
Import the useVirtual hook from TanStack Virtual.
import React, { useRef } from 'react';
Import useRef hook from React for referencing the parent div of the list and the scrollbar.
const CustomScrollbarList = () => {
Define a new React component for the list with a custom scrollbar.
  const parentRef = useRef(null);
Create a ref for the parent container to measure its size.
  const scrollbarRef = useRef(null);
Create a ref for the custom scrollbar.
  const rowVirtualizer = useVirtual({
    size: 1000,
    parentRef,
    estimateSize: React.useCallback(() => 35, []),
    overscan: 5
  });
Initialize the row virtualizer with useVirtual, providing the size of the list, the parentRef, an estimateSize function for item height, and an overscan parameter.
  const onScroll = (e) => {
    const scrollOffset = e.target.scrollTop;
    const scrollPercent = scrollOffset / (e.target.scrollHeight - e.target.clientHeight);
    const scrollbarHeight = parentRef.current.clientHeight * scrollPercent;
    scrollbarRef.current.style.transform = `translateY(${scrollbarHeight}px)`;
  };
Define an onScroll event handler to move the custom scrollbar based on the current scroll position of the list.
  return (
    <div style={{ position: 'relative', height: '100%', overflow: 'auto' }} onScroll={onScroll} ref={parentRef}>
      <div style={{ height: `${rowVirtualizer.totalSize}px`, position: 'relative' }}>
        {rowVirtualizer.virtualItems.map(virtualRow => (
          <div
            key={virtualRow.index}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              transform: `translateY(${virtualRow.start}px)`
            }}
          >
            {`Item ${virtualRow.index}`}
          </div>
        ))}
      </div>
      <div ref={scrollbarRef} style={{ position: 'absolute', top: 0, right: 0, width: '10px', height: '100%', backgroundColor: 'rgba(0,0,0,0.5)' }} />
    </div>
  );
Render the parent div as a relative container with overflow auto to enable scrolling, and map through the virtual rows to render each item. Also, render a div for the custom scrollbar, positioning it absolutely to the right.
};
Close the React component definition.
export default CustomScrollbarList;
Export the CustomScrollbarList component for use in other parts of the application.