ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto
1import React, { useRef } from "react";
2import { useVirtualizer } from "@tanstack/react-virtual";
3import SearchResultCard from "./SearchResultCard";
4import type { SearchResult } from "../types";
5import type { AtprotoAppId } from "../types/settings";
6
7interface VirtualizedResultsListProps {
8 results: SearchResult[];
9 expandedResults: Set<number>;
10 onToggleExpand: (index: number) => void;
11 onToggleMatchSelection: (resultIndex: number, did: string) => void;
12 sourcePlatform: string;
13 destinationAppId: AtprotoAppId;
14}
15
16const VirtualizedResultsList: React.FC<VirtualizedResultsListProps> = ({
17 results,
18 expandedResults,
19 onToggleExpand,
20 onToggleMatchSelection,
21 sourcePlatform,
22 destinationAppId,
23}) => {
24 const parentRef = useRef<HTMLDivElement>(null);
25
26 const virtualizer = useVirtualizer({
27 count: results.length,
28 getScrollElement: () => parentRef.current,
29 estimateSize: () => 200, // Initial estimate, will be measured dynamically
30 overscan: 3,
31 // Enable dynamic measurement - virtualizer will measure actual rendered heights
32 // and adjust positioning automatically
33 measureElement:
34 typeof window !== "undefined" && navigator.userAgent.indexOf("Firefox") === -1
35 ? (element) => element.getBoundingClientRect().height
36 : undefined,
37 });
38
39 return (
40 <div ref={parentRef} className="h-full overflow-auto">
41 <div
42 style={{
43 height: `${virtualizer.getTotalSize()}px`,
44 width: "100%",
45 position: "relative",
46 }}
47 >
48 {virtualizer.getVirtualItems().map((virtualItem) => {
49 const result = results[virtualItem.index];
50
51 return (
52 <div
53 key={virtualItem.key}
54 data-index={virtualItem.index}
55 ref={virtualizer.measureElement}
56 style={{
57 position: "absolute",
58 top: 0,
59 left: 0,
60 width: "100%",
61 transform: `translateY(${virtualItem.start}px)`,
62 }}
63 >
64 <div className="pb-4">
65 <SearchResultCard
66 result={result}
67 resultIndex={virtualItem.index}
68 isExpanded={expandedResults.has(virtualItem.index)}
69 onToggleExpand={() => onToggleExpand(virtualItem.index)}
70 onToggleMatchSelection={(did) =>
71 onToggleMatchSelection(virtualItem.index, did)
72 }
73 sourcePlatform={sourcePlatform}
74 destinationAppId={destinationAppId}
75 />
76 </div>
77 </div>
78 );
79 })}
80 </div>
81 </div>
82 );
83};
84
85export default VirtualizedResultsList;