Skip to content

Commit ac397b4

Browse files
fix
1 parent 81a9ea1 commit ac397b4

1 file changed

Lines changed: 98 additions & 45 deletions

File tree

packages/web/src/ee/features/codeNav/components/exploreMenu/referenceList.tsx

Lines changed: 98 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
import { useBrowseNavigation } from "@/app/[domain]/browse/hooks/useBrowseNavigation";
44
import { FileHeader } from "@/app/[domain]/components/fileHeader";
55
import { LightweightCodeHighlighter } from "@/app/[domain]/components/lightweightCodeHighlighter";
6-
import { ScrollArea } from "@/components/ui/scroll-area";
76
import { FindRelatedSymbolsResponse } from "@/features/codeNav/types";
87
import { RepositoryInfo, SourceRange } from "@/features/search/types";
98
import { base64Decode } from "@/lib/utils";
10-
import { useMemo } from "react";
9+
import { useMemo, useRef } from "react";
1110
import useCaptureEvent from "@/hooks/useCaptureEvent";
11+
import { useVirtualizer } from "@tanstack/react-virtual";
1212

1313
interface ReferenceListProps {
1414
data: FindRelatedSymbolsResponse;
1515
revisionName: string;
1616
}
1717

18+
const ESTIMATED_LINE_HEIGHT_PX = 30;
19+
const ESTIMATED_MATCH_CONTAINER_HEIGHT_PX = 30;
20+
1821
export const ReferenceList = ({
1922
data,
2023
revisionName,
@@ -29,52 +32,102 @@ export const ReferenceList = ({
2932
const { navigateToPath } = useBrowseNavigation();
3033
const captureEvent = useCaptureEvent();
3134

32-
return (
33-
<ScrollArea className="h-full">
34-
{data.files.map((file, index) => {
35-
const repoInfo = repoInfoMap[file.repositoryId];
35+
// Virtualization setup
36+
const parentRef = useRef<HTMLDivElement>(null);
37+
const virtualizer = useVirtualizer({
38+
count: data.files.length,
39+
getScrollElement: () => parentRef.current,
40+
estimateSize: (index) => {
41+
const file = data.files[index];
42+
43+
const estimatedSize =
44+
file.matches.length * ESTIMATED_LINE_HEIGHT_PX +
45+
ESTIMATED_MATCH_CONTAINER_HEIGHT_PX;
46+
47+
return estimatedSize;
48+
},
49+
overscan: 5,
50+
enabled: true,
51+
});
3652

37-
return (
38-
<div key={index}>
39-
<div className="bg-accent py-1 px-2 flex flex-row sticky top-0">
40-
<FileHeader
41-
repo={{
42-
name: repoInfo.name,
43-
displayName: repoInfo.displayName,
44-
codeHostType: repoInfo.codeHostType,
45-
webUrl: repoInfo.webUrl,
53+
return (
54+
<div
55+
ref={parentRef}
56+
style={{
57+
width: "100%",
58+
height: "100%",
59+
overflowY: "auto",
60+
contain: "strict",
61+
}}
62+
>
63+
<div
64+
style={{
65+
height: virtualizer.getTotalSize(),
66+
width: "100%",
67+
position: "relative",
68+
}}
69+
>
70+
{virtualizer.getVirtualItems().map((virtualRow) => {
71+
const file = data.files[virtualRow.index];
72+
const repoInfo = repoInfoMap[file.repositoryId];
73+
return (
74+
<div
75+
key={virtualRow.key}
76+
data-index={virtualRow.index}
77+
ref={virtualizer.measureElement}
78+
style={{
79+
position: "absolute",
80+
transform: `translateY(${virtualRow.start}px)`,
81+
top: 0,
82+
left: 0,
83+
width: "100%",
84+
}}
85+
>
86+
<div
87+
className="bg-accent py-1 px-2 flex flex-row sticky top-0 z-10"
88+
style={{
89+
top: `-${virtualRow.start}px`,
4690
}}
47-
fileName={file.fileName}
48-
branchDisplayName={revisionName === "HEAD" ? undefined : revisionName}
49-
/>
50-
</div>
51-
<div className="divide-y">
52-
{file.matches
53-
.sort((a, b) => a.range.start.lineNumber - b.range.start.lineNumber)
54-
.map((match, index) => (
55-
<ReferenceListItem
56-
key={index}
57-
lineContent={match.lineContent}
58-
range={match.range}
59-
language={file.language}
60-
onClick={() => {
61-
captureEvent('wa_explore_menu_reference_clicked', {});
62-
navigateToPath({
63-
repoName: file.repository,
64-
revisionName,
65-
path: file.fileName,
66-
pathType: 'blob',
67-
highlightRange: match.range,
68-
})
69-
}}
70-
/>
71-
))}
91+
>
92+
<FileHeader
93+
repo={{
94+
name: repoInfo.name,
95+
displayName: repoInfo.displayName,
96+
codeHostType: repoInfo.codeHostType,
97+
webUrl: repoInfo.webUrl,
98+
}}
99+
fileName={file.fileName}
100+
branchDisplayName={revisionName === "HEAD" ? undefined : revisionName}
101+
/>
102+
</div>
103+
<div className="divide-y">
104+
{file.matches
105+
.sort((a, b) => a.range.start.lineNumber - b.range.start.lineNumber)
106+
.map((match, index) => (
107+
<ReferenceListItem
108+
key={index}
109+
lineContent={match.lineContent}
110+
range={match.range}
111+
language={file.language}
112+
onClick={() => {
113+
captureEvent('wa_explore_menu_reference_clicked', {});
114+
navigateToPath({
115+
repoName: file.repository,
116+
revisionName,
117+
path: file.fileName,
118+
pathType: 'blob',
119+
highlightRange: match.range,
120+
})
121+
}}
122+
/>
123+
))}
124+
</div>
72125
</div>
73-
</div>
74-
)
75-
})}
76-
</ScrollArea>
77-
)
126+
);
127+
})}
128+
</div>
129+
</div>
130+
);
78131
}
79132

80133

0 commit comments

Comments
 (0)