Skip to content

Commit a9554ee

Browse files
use a react portal to catch additional clipping issues
1 parent c131387 commit a9554ee

1 file changed

Lines changed: 51 additions & 43 deletions

File tree

  • packages/web/src/ee/features/codeNav/components/symbolHoverPopup

packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -94,48 +94,56 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
9494
}
9595
}, [symbolInfo, onGotoDefinition]);
9696

97-
return symbolInfo ? (
98-
<div
99-
ref={ref}
100-
className="absolute z-10 flex flex-col gap-2 bg-background border border-gray-300 dark:border-gray-700 rounded-md shadow-lg p-2 max-w-3xl"
101-
onMouseOver={() => setIsSticky(true)}
102-
onMouseOut={() => setIsSticky(false)}
103-
>
104-
{symbolInfo.isSymbolDefinitionsLoading ? (
105-
<div className="flex flex-row items-center gap-2 text-sm">
106-
<Loader2 className="w-4 h-4 animate-spin" />
107-
Loading...
108-
</div>
109-
) : symbolInfo.symbolDefinitions && symbolInfo.symbolDefinitions.length > 0 ? (
110-
<SymbolDefinitionPreview
111-
symbolDefinition={symbolInfo.symbolDefinitions[0]}
112-
/>
113-
) : (
114-
<p className="text-sm font-medium text-muted-foreground">No hover info found</p>
115-
)}
116-
<Separator />
117-
<div className="flex flex-row gap-2 mt-2">
118-
<LoadingButton
119-
loading={symbolInfo.isSymbolDefinitionsLoading}
120-
disabled={!symbolInfo.symbolDefinitions || symbolInfo.symbolDefinitions.length === 0}
121-
variant="outline"
122-
size="sm"
123-
onClick={onGotoDefinition}
124-
>
125-
{
126-
!symbolInfo.isSymbolDefinitionsLoading && (!symbolInfo.symbolDefinitions || symbolInfo.symbolDefinitions.length === 0) ?
127-
"No definition found" :
128-
`Go to ${symbolInfo.symbolDefinitions && symbolInfo.symbolDefinitions.length > 1 ? "definitions" : "definition"}`
129-
}
130-
</LoadingButton>
131-
<Button
132-
variant="outline"
133-
size="sm"
134-
onClick={() => onFindReferences(symbolInfo.symbolName)}
135-
>
136-
Find references
137-
</Button>
97+
if (!symbolInfo) {
98+
return null;
99+
}
100+
101+
// We use a portal here to render the popup at the document body level.
102+
// This avoids clipping issues that occur when the popup is rendered inside scrollable or overflow-hidden containers (like the editor or its parent).
103+
// By rendering in a portal, the popup can be absolutely positioned anywhere in the viewport without being cut off by parent containers.
104+
return createPortal(
105+
<div
106+
ref={ref}
107+
className="absolute z-10 flex flex-col gap-2 bg-background border border-gray-300 dark:border-gray-700 rounded-md shadow-lg p-2 max-w-3xl"
108+
onMouseOver={() => setIsSticky(true)}
109+
onMouseOut={() => setIsSticky(false)}
110+
>
111+
{symbolInfo.isSymbolDefinitionsLoading ? (
112+
<div className="flex flex-row items-center gap-2 text-sm">
113+
<Loader2 className="w-4 h-4 animate-spin" />
114+
Loading...
138115
</div>
139-
</div>
140-
) : null;
116+
) : symbolInfo.symbolDefinitions && symbolInfo.symbolDefinitions.length > 0 ? (
117+
<SymbolDefinitionPreview
118+
symbolDefinition={symbolInfo.symbolDefinitions[0]}
119+
/>
120+
) : (
121+
<p className="text-sm font-medium text-muted-foreground">No hover info found</p>
122+
)}
123+
<Separator />
124+
<div className="flex flex-row gap-2 mt-2">
125+
<LoadingButton
126+
loading={symbolInfo.isSymbolDefinitionsLoading}
127+
disabled={!symbolInfo.symbolDefinitions || symbolInfo.symbolDefinitions.length === 0}
128+
variant="outline"
129+
size="sm"
130+
onClick={onGotoDefinition}
131+
>
132+
{
133+
!symbolInfo.isSymbolDefinitionsLoading && (!symbolInfo.symbolDefinitions || symbolInfo.symbolDefinitions.length === 0) ?
134+
"No definition found" :
135+
`Go to ${symbolInfo.symbolDefinitions && symbolInfo.symbolDefinitions.length > 1 ? "definitions" : "definition"}`
136+
}
137+
</LoadingButton>
138+
<Button
139+
variant="outline"
140+
size="sm"
141+
onClick={() => onFindReferences(symbolInfo.symbolName)}
142+
>
143+
Find references
144+
</Button>
145+
</div>
146+
</div>,
147+
document.body
148+
);
141149
};

0 commit comments

Comments
 (0)