import { Virtualizer, useVirtualizer } from "@tanstack/react-virtual"; import React, { useRef } from "react"; type VirtualListProps = { list: T[]; renderItem: (props: { item: T }) => JSX.Element; getItemHeight: (item: T) => number; onChange?: (instance: Virtualizer) => void; }; const VirtualList = ({ list, renderItem, getItemHeight }: VirtualListProps) => { const parentRef = useRef(null); const virtualizer = useVirtualizer({ debug: false, count: list.length, getScrollElement: () => parentRef.current, estimateSize: (index) => getItemHeight(list[index]), onChange: (instance) => { console.log("instance", instance); }, }); return (
{virtualizer.getVirtualItems().map((virtualItem) => (
{renderItem({ item: list[virtualItem.index] })}
))}
); }; export default VirtualList; const getItemHeight = useMemo( () => { // This function returns another function that calculates the item height return (item: any): number => { if (item.discriminant === ListItemDiscriminants.ITEM_CARD) { const aux = item as ItemCard; // Example height calculation, adjust based on your item structure and content return 144 + (aux.subfamilyName !== undefined && aux.rfidLocations?.includes("STORE") ? 20 : 0); } else { // Assuming headers have a fixed height return 34; } }; }, [ /* Dependencies that affect item heights, e.g., waveFilters */ ], ); const listState = useMemo(() => { const list = classifyBy === "units" ? generateItemList(itemsByLocation, waveFilters, checked, intl, true, parsedLocations) : generateItemList(itemsByOrder, waveFilters, checked, intl, true, undefined, itemsByOrderKeyList); if (!list) { return null; } return ; }, [classifyBy, unitsList, ordersList, locationHeaderSticky, subHeaderSticky, window.innerHeight]);