diff --git a/CHANGELOG.md b/CHANGELOG.md index 9267034c..ced89e9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed issue with the symbol hover popover clipping at the top of the page. [#326](https://github.com/sourcebot-dev/sourcebot/pull/326) + ## [4.1.0] - 2025-06-02 ### Added diff --git a/packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx b/packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx index 86c0d0f5..ff3a245a 100644 --- a/packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx +++ b/packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx @@ -7,6 +7,7 @@ import { Loader2 } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; import { SymbolDefinition, useHoveredOverSymbolInfo } from "./useHoveredOverSymbolInfo"; import { SymbolDefinitionPreview } from "./symbolDefinitionPreview"; +import { createPortal } from "react-dom"; interface SymbolHoverPopupProps { editorRef: ReactCodeMirrorRef; @@ -55,9 +56,11 @@ export const SymbolHoverPopup: React.FC = ({ crossAxis: false, fallbackPlacements: ['bottom'], boundary: editorRef.view?.dom, + padding: 20, }), shift({ padding: 5, + boundary: editorRef.view?.dom, }) ] }).then(({ x, y }) => { @@ -91,7 +94,14 @@ export const SymbolHoverPopup: React.FC = ({ } }, [symbolInfo, onGotoDefinition]); - return symbolInfo ? ( + if (!symbolInfo) { + return null; + } + + // We use a portal here to render the popup at the document body level. + // This avoids clipping issues that occur when the popup is rendered inside scrollable or overflow-hidden containers (like the editor or its parent). + // By rendering in a portal, the popup can be absolutely positioned anywhere in the viewport without being cut off by parent containers. + return createPortal(
= ({ Find references
- - ) : null; + , + document.body + ); };