Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 19x 19x | import { CSSProperties, ReactElement, useCallback } from "react"; import { AutoSizer, IndexRange, InfiniteLoader, List, WindowScroller, } from "react-virtualized"; interface ItemRendererProps<T> { key: string; style: CSSProperties; index: number; item: T | undefined; additionalProps?: Record<string, any>; } interface VirtualizedListProps<T> { items: T[] | null; totalItems: number; itemHeight: number; loadMoreItems?: (range: IndexRange) => Promise<void>; renderItem: (props: ItemRendererProps<T>) => ReactElement; isItemLoaded?: (index: number) => boolean; scrollElementSelector?: string; overscanRowCount?: number; additionalProps?: Record<string, any>; } export default function VirtualizedList<T>({ items, totalItems, itemHeight, loadMoreItems, renderItem, isItemLoaded, scrollElementSelector = "#right .simplebar-content-wrapper", overscanRowCount = 2, }: Readonly<VirtualizedListProps<T>>): ReactElement | null { const scrollElement = typeof window !== "undefined" ? (document.querySelector(scrollElementSelector) as HTMLElement) : undefined; const defaultIsItemLoaded = useCallback( (index: number) => !!items?.[index], [items] ); const handleLoadMoreRows = useCallback( async (range: IndexRange) => { Iif (loadMoreItems) { await loadMoreItems(range); } }, [loadMoreItems] ); function rowRenderer({ key, style, index, }: { key: string; style: CSSProperties; index: number; }) { return renderItem({ key, style: style, index, item: items?.[index], }); } Iif (!scrollElement) return null; return ( <WindowScroller scrollElement={scrollElement}> {({ height, isScrolling, onChildScroll, scrollTop }) => ( <AutoSizer disableHeight> {({ width }) => ( <InfiniteLoader isRowLoaded={({ index }) => (isItemLoaded ?? defaultIsItemLoaded)(index) } loadMoreRows={handleLoadMoreRows} rowCount={totalItems} minimumBatchSize={50} threshold={100} > {({ onRowsRendered, registerChild }) => ( <List autoHeight height={height ?? 0} isScrolling={isScrolling} onRowsRendered={onRowsRendered} ref={registerChild} onScroll={onChildScroll} overscanRowCount={overscanRowCount} rowCount={totalItems} rowHeight={itemHeight} scrollTop={scrollTop} width={width} rowRenderer={rowRenderer} tabIndex={-1} /> )} </InfiniteLoader> )} </AutoSizer> )} </WindowScroller> ); } |