For hundreds of files, pass virtual to the file uploader with the virtualizer hook as use (useVirtualizer from @tanstack/react-virtual): it renders only the rows in view inside a scroll area. VirtualFileUploader from slotsmith/virtual passes the hook for you. The queue, progress, retry and every slot work the same.

Drag and drop, or browsemax 500 files
  • scan-001.pdf39 KBUploaded
  • scan-002.pdf47 KBUploaded
  • scan-003.pdf55 KBUploaded
  • scan-004.pdf62 KBUploaded
  • scan-005.pdf70 KBUploaded
  • scan-006.pdf78 KBUploaded
  • scan-007.pdf85 KBUploaded
  • scan-008.pdf93 KBUploaded
  • scan-009.pdf101 KBUploaded
  • scan-010.pdf109 KBUploaded
  • scan-011.pdf116 KBUploaded

The list holds 300 stored scans and scrolls inside 320px; only about a dozen rows are in the page at a time. Add more files and they upload at the end of the list.

Install

The hook comes from TanStack Virtual, an optional peer dependency that slotsmith never imports itself. Install it next to slotsmith:

npm i @tanstack/react-virtual

The virtual option

The virtual prop takes the hook as use (VirtualFileUploader passes it for you), and three numbers:

  • estimateSize: the height of one row in pixels, 56 by default. The rows are not measured, so set it to your row height plus the gap between rows: a fallback row is 64.5px and the gap 8px, so the demo uses 72.5.
  • maxHeight: the height of the scroll area in pixels, 400 by default.
  • overscan: how many rows to render beyond the visible area, 6 by default.

Rows out of view are replaced by two spacer <li> elements, hidden from assistive technology, that keep the scrollbar true to the whole list. The spacers never shrink and allow for the list’s row gap, so the fallback flex list scrolls through every row, and so does a replacement List laid out as a grid or a block.

Your own layout

The list on its own is FileUploaderVirtualList, also from slotsmith/virtual. Use it in place of FileUploader.List inside the compound parts, with the same options as props.