import React, { useRef } from 'react' import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual' type VirtualProps = { /** This is the number of rows in the dataset */ count: number /** Children is a function that has access to the useVirtualizer hook value and the ref that needs to be wrapped around the virtualized content. */ children: ({ virtualizer, virtualizedParentRef, }: { virtualizer: ReturnType virtualizedParentRef: React.RefObject }) => React.JSX.Element /** Optionally pass in more react-virtual props for the useVirtualizer */ virtualizerProps?: Parameters[0] /** Optionally define the row height for the rows. Note: This is not on a row-by-row basis. It will apply to every row. The default is 40px. */ rowHeight?: number } const Virtual = ({ count, children, virtualizerProps, rowHeight = 40, }: VirtualProps): React.JSX.Element => { const virtualizedParentRef = useRef(null) const virtualizer = useVirtualizer({ count, getScrollElement: () => virtualizedParentRef.current, estimateSize: () => rowHeight, overscan: 5, ...virtualizerProps, }) return children({ virtualizer, virtualizedParentRef }) } type VirtualListProps = { virtualizer: ReturnType children: ({ index, measureElement, }: { index: number measureElement: Virtualizer['measureElement'] }) => React.JSX.Element } export const VirtualList = ({ virtualizer, children, }: VirtualListProps): React.JSX.Element => { return (
{virtualizer.getVirtualItems().map((virtualRow) => (
{children({ index: virtualRow.index, measureElement: virtualizer.measureElement, })}
))}
) } Virtual.List = VirtualList export { Virtual }