Skip to content

Commit b5c693a

Browse files
🤖 fix: use Radix HoverCard for git status tooltip viewport handling (#1162)
## Problem The git status "Divergence" popup (showing line changes & commits) would exceed the window bounds when triggered from the topmost workspace in the sidebar. The popup used `translateY(-50%)` for centering but had no boundary clamping, causing half the content to render above the visible viewport. ## Solution Replace the manual `createPortal` + coordinate positioning with Radix `HoverCard` primitive, which handles viewport collision detection automatically via Floating UI under the hood. ### Why Radix HoverCard? 1. **Built-in viewport collision handling** — `collisionPadding={8}` ensures the popup stays within bounds 2. **Native hover behavior** — handles open/close delays, cursor-to-content transitions without manual timeout logic 3. **Consistent with existing patterns** — the codebase already uses Radix primitives (Popover, Tooltip, etc.) 4. **Less code to maintain** — removes ~90 lines of manual positioning, timeout refs, and coordinate calculations ### Changes - Add `hover-card.tsx` shadcn component wrapping `@radix-ui/react-hover-card` - Refactor `GitStatusIndicatorView` to use `<HoverCard>` instead of `createPortal` - Simplify `GitStatusIndicator` by removing manual hover state management - Use `openDelay={0}` (instant open) and `closeDelay={150}` (snappy close) ### Net impact - **-47 lines** in production code (117 added, 164 removed) - Viewport overflow bug fixed - Hover timing slightly snappier (150ms vs 300ms close delay) --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
1 parent d180c80 commit b5c693a

File tree

6 files changed

+119
-165
lines changed

6 files changed

+119
-165
lines changed

‎bun.lock‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"lockfileVersion": 1,
3+
"configVersion": 0,
34
"workspaces": {
45
"": {
56
"name": "mux",
@@ -22,6 +23,7 @@
2223
"@radix-ui/react-checkbox": "^1.3.3",
2324
"@radix-ui/react-context-menu": "^2.2.16",
2425
"@radix-ui/react-dialog": "^1.1.15",
26+
"@radix-ui/react-hover-card": "^1.1.15",
2527
"@radix-ui/react-label": "^2.1.8",
2628
"@radix-ui/react-popover": "^1.1.15",
2729
"@radix-ui/react-scroll-area": "^1.2.10",
@@ -872,6 +874,8 @@
872874

873875
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
874876

877+
"@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="],
878+
875879
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
876880

877881
"@radix-ui/react-label": ["@radix-ui/react-label@2.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A=="],
@@ -3766,6 +3770,8 @@
37663770

37673771
"@radix-ui/react-focus-scope/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
37683772

3773+
"@radix-ui/react-hover-card/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
3774+
37693775
"@radix-ui/react-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
37703776

37713777
"@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
@@ -4240,6 +4246,8 @@
42404246

42414247
"@radix-ui/react-focus-scope/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
42424248

4249+
"@radix-ui/react-hover-card/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
4250+
42434251
"@radix-ui/react-popper/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
42444252

42454253
"@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@radix-ui/react-checkbox": "^1.3.3",
6464
"@radix-ui/react-context-menu": "^2.2.16",
6565
"@radix-ui/react-dialog": "^1.1.15",
66+
"@radix-ui/react-hover-card": "^1.1.15",
6667
"@radix-ui/react-label": "^2.1.8",
6768
"@radix-ui/react-popover": "^1.1.15",
6869
"@radix-ui/react-scroll-area": "^1.2.10",

‎src/browser/components/GitStatusIndicator.tsx‎

Lines changed: 7 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useRef, useEffect, useCallback } from "react";
1+
import React, { useState, useCallback } from "react";
22
import type { GitStatus } from "@/common/types/workspace";
33
import { GIT_STATUS_INDICATOR_MODE_KEY } from "@/common/constants/storage";
44
import { usePersistedState } from "@/browser/hooks/usePersistedState";
@@ -15,7 +15,7 @@ interface GitStatusIndicatorProps {
1515

1616
/**
1717
* Container component for git status indicator.
18-
* Manages tooltip visibility, positioning, and data fetching.
18+
* Manages hover card visibility and data fetching.
1919
* Delegates rendering to GitStatusIndicatorView.
2020
*/
2121
export const GitStatusIndicator: React.FC<GitStatusIndicatorProps> = ({
@@ -24,13 +24,7 @@ export const GitStatusIndicator: React.FC<GitStatusIndicatorProps> = ({
2424
tooltipPosition = "right",
2525
isWorking = false,
2626
}) => {
27-
const [showTooltip, setShowTooltip] = useState(false);
28-
const [tooltipCoords, setTooltipCoords] = useState<{ top: number; left: number }>({
29-
top: 0,
30-
left: 0,
31-
});
32-
const hideTimeoutRef = useRef<NodeJS.Timeout | null>(null);
33-
const containerRef = useRef<HTMLSpanElement | null>(null);
27+
const [isOpen, setIsOpen] = useState(false);
3428
const trimmedWorkspaceId = workspaceId.trim();
3529

3630
const [mode, setMode] = usePersistedState<GitStatusIndicatorMode>(
@@ -51,75 +45,13 @@ export const GitStatusIndicator: React.FC<GitStatusIndicatorProps> = ({
5145
"GitStatusIndicator requires workspaceId to be a non-empty string."
5246
);
5347

54-
// Fetch branch details only when tooltip should be shown
48+
// Fetch branch details only when hover card is open
5549
const { branchHeaders, commits, dirtyFiles, isLoading, errorMessage } = useGitBranchDetails(
5650
trimmedWorkspaceId,
5751
gitStatus,
58-
showTooltip
52+
isOpen
5953
);
6054

61-
const handleMouseEnter = () => {
62-
// Cancel any pending hide timeout
63-
if (hideTimeoutRef.current) {
64-
clearTimeout(hideTimeoutRef.current);
65-
hideTimeoutRef.current = null;
66-
}
67-
68-
setShowTooltip(true);
69-
70-
// Calculate tooltip position based on indicator position
71-
if (containerRef.current) {
72-
const rect = containerRef.current.getBoundingClientRect();
73-
74-
if (tooltipPosition === "right") {
75-
// Position to the right of the indicator
76-
setTooltipCoords({
77-
top: rect.top + rect.height / 2,
78-
left: rect.right + 8,
79-
});
80-
} else {
81-
// Position below the indicator
82-
setTooltipCoords({
83-
top: rect.bottom + 8,
84-
left: rect.left,
85-
});
86-
}
87-
}
88-
};
89-
90-
const handleMouseLeave = () => {
91-
// Delay hiding to give user time to move cursor to tooltip
92-
hideTimeoutRef.current = setTimeout(() => {
93-
setShowTooltip(false);
94-
}, 300);
95-
};
96-
97-
const handleTooltipMouseEnter = () => {
98-
// Cancel hide timeout when hovering tooltip
99-
if (hideTimeoutRef.current) {
100-
clearTimeout(hideTimeoutRef.current);
101-
hideTimeoutRef.current = null;
102-
}
103-
};
104-
105-
const handleTooltipMouseLeave = () => {
106-
// Hide immediately when leaving tooltip
107-
setShowTooltip(false);
108-
};
109-
110-
const handleContainerRef = (el: HTMLSpanElement | null) => {
111-
containerRef.current = el;
112-
};
113-
114-
// Cleanup timeout on unmount
115-
useEffect(() => {
116-
return () => {
117-
if (hideTimeoutRef.current) {
118-
clearTimeout(hideTimeoutRef.current);
119-
}
120-
};
121-
}, []);
122-
12355
return (
12456
<GitStatusIndicatorView
12557
mode={mode}
@@ -130,14 +62,9 @@ export const GitStatusIndicator: React.FC<GitStatusIndicatorProps> = ({
13062
dirtyFiles={dirtyFiles}
13163
isLoading={isLoading}
13264
errorMessage={errorMessage}
133-
showTooltip={showTooltip}
134-
tooltipCoords={tooltipCoords}
135-
onMouseEnter={handleMouseEnter}
136-
onMouseLeave={handleMouseLeave}
137-
onTooltipMouseEnter={handleTooltipMouseEnter}
65+
isOpen={isOpen}
66+
onOpenChange={setIsOpen}
13867
onModeChange={handleModeChange}
139-
onTooltipMouseLeave={handleTooltipMouseLeave}
140-
onContainerRef={handleContainerRef}
14168
isWorking={isWorking}
14269
/>
14370
);

‎src/browser/components/GitStatusIndicatorView.tsx‎

Lines changed: 74 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from "react";
2-
import { createPortal } from "react-dom";
32
import type { GitStatus } from "@/common/types/workspace";
43
import type { GitCommit, GitBranchHeader } from "@/common/utils/git/parseGitLog";
54
import { cn } from "@/common/lib/utils";
65
import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group";
6+
import { HoverCard, HoverCardContent, HoverCardTrigger } from "./ui/hover-card";
77

88
// Helper for indicator colors
99
const getIndicatorColor = (branch: number): string => {
@@ -50,14 +50,9 @@ export interface GitStatusIndicatorViewProps {
5050
isLoading: boolean;
5151
errorMessage: string | null;
5252
// Interaction
53-
showTooltip: boolean;
54-
tooltipCoords: { top: number; left: number };
55-
onMouseEnter: () => void;
56-
onMouseLeave: () => void;
57-
onTooltipMouseEnter: () => void;
58-
onTooltipMouseLeave: () => void;
53+
isOpen: boolean;
54+
onOpenChange: (open: boolean) => void;
5955
onModeChange: (nextMode: GitStatusIndicatorMode) => void;
60-
onContainerRef: (el: HTMLSpanElement | null) => void;
6156
/** When true, shows blue pulsing styling to indicate agent is working */
6257
isWorking?: boolean;
6358
}
@@ -76,14 +71,9 @@ export const GitStatusIndicatorView: React.FC<GitStatusIndicatorViewProps> = ({
7671
dirtyFiles,
7772
isLoading,
7873
errorMessage,
79-
showTooltip,
80-
tooltipCoords,
81-
onMouseEnter,
82-
onMouseLeave,
83-
onTooltipMouseEnter,
84-
onTooltipMouseLeave,
74+
isOpen,
75+
onOpenChange,
8576
onModeChange,
86-
onContainerRef,
8777
isWorking = false,
8878
}) => {
8979
// Handle null gitStatus (loading state)
@@ -229,21 +219,9 @@ export const GitStatusIndicatorView: React.FC<GitStatusIndicatorViewProps> = ({
229219
const additionsColor = isWorking ? "text-success-light" : "text-muted";
230220
const deletionsColor = isWorking ? "text-warning-light" : "text-muted";
231221

232-
// Render tooltip via portal to bypass overflow constraints
233-
const tooltipElement = (
234-
<div
235-
className={cn(
236-
"fixed z-[10000] bg-modal-bg text-foreground border border-separator-light rounded px-3 py-2 text-[11px] font-mono whitespace-pre max-w-96 max-h-[400px] overflow-auto shadow-[0_4px_12px_rgba(0,0,0,0.5)] pointer-events-auto transition-opacity duration-200",
237-
showTooltip ? "opacity-100 visible" : "opacity-0 invisible"
238-
)}
239-
style={{
240-
top: `${tooltipCoords.top}px`,
241-
left: `${tooltipCoords.left}px`,
242-
transform: tooltipPosition === "right" ? "translateY(-50%)" : "none",
243-
}}
244-
onMouseEnter={onTooltipMouseEnter}
245-
onMouseLeave={onTooltipMouseLeave}
246-
>
222+
// Popover content with git divergence details
223+
const popoverContent = (
224+
<>
247225
<div className="border-separator-light mb-2 flex flex-col gap-1 border-b pb-2">
248226
<div className="flex items-center gap-2">
249227
<span className="text-muted-light">Divergence:</span>
@@ -296,65 +274,77 @@ export const GitStatusIndicatorView: React.FC<GitStatusIndicatorViewProps> = ({
296274
</div>
297275

298276
{renderTooltipContent()}
299-
</div>
277+
</>
300278
);
301279

302-
return (
280+
const triggerContent = (
303281
<>
304-
<span
305-
ref={onContainerRef}
306-
onMouseEnter={onMouseEnter}
307-
onMouseLeave={onMouseLeave}
308-
className={cn(
309-
"relative flex items-center gap-1 font-mono text-[11px] transition-colors",
310-
statusColor
311-
)}
312-
>
313-
{mode === "divergence" ? (
314-
<>
315-
{gitStatus.ahead > 0 && (
316-
<span className="flex items-center font-normal">
317-
↑{formatCountAbbrev(gitStatus.ahead)}
318-
</span>
319-
)}
320-
{gitStatus.behind > 0 && (
321-
<span className="flex items-center font-normal">
282+
{mode === "divergence" ? (
283+
<>
284+
{gitStatus.ahead > 0 && (
285+
<span className="flex items-center font-normal">
286+
↑{formatCountAbbrev(gitStatus.ahead)}
287+
</span>
288+
)}
289+
{gitStatus.behind > 0 && (
290+
<span className="flex items-center font-normal">
291+
↓{formatCountAbbrev(gitStatus.behind)}
292+
</span>
293+
)}
294+
</>
295+
) : (
296+
<>
297+
{outgoingHasDelta ? (
298+
<span className="flex items-center gap-2">
299+
{gitStatus.outgoingAdditions > 0 && (
300+
<span className={cn("font-normal", additionsColor)}>
301+
+{formatCountAbbrev(gitStatus.outgoingAdditions)}
302+
</span>
303+
)}
304+
{gitStatus.outgoingDeletions > 0 && (
305+
<span className={cn("font-normal", deletionsColor)}>
306+
-{formatCountAbbrev(gitStatus.outgoingDeletions)}
307+
</span>
308+
)}
309+
</span>
310+
) : (
311+
// No outgoing lines but behind remote - show muted behind indicator
312+
// so users know they can hover to toggle to divergence view
313+
gitStatus.behind > 0 && (
314+
<span className="text-muted flex items-center font-normal">
322315
↓{formatCountAbbrev(gitStatus.behind)}
323316
</span>
324-
)}
325-
</>
326-
) : (
327-
<>
328-
{outgoingHasDelta ? (
329-
<span className="flex items-center gap-2">
330-
{gitStatus.outgoingAdditions > 0 && (
331-
<span className={cn("font-normal", additionsColor)}>
332-
+{formatCountAbbrev(gitStatus.outgoingAdditions)}
333-
</span>
334-
)}
335-
{gitStatus.outgoingDeletions > 0 && (
336-
<span className={cn("font-normal", deletionsColor)}>
337-
-{formatCountAbbrev(gitStatus.outgoingDeletions)}
338-
</span>
339-
)}
340-
</span>
341-
) : (
342-
// No outgoing lines but behind remote - show muted behind indicator
343-
// so users know they can hover to toggle to divergence view
344-
gitStatus.behind > 0 && (
345-
<span className="text-muted flex items-center font-normal">
346-
↓{formatCountAbbrev(gitStatus.behind)}
347-
</span>
348-
)
349-
)}
350-
</>
351-
)}
352-
{gitStatus.dirty && (
353-
<span className={cn("flex items-center leading-none font-normal", dirtyColor)}>*</span>
354-
)}
355-
</span>
356-
357-
{createPortal(tooltipElement, document.body)}
317+
)
318+
)}
319+
</>
320+
)}
321+
{gitStatus.dirty && (
322+
<span className={cn("flex items-center leading-none font-normal", dirtyColor)}>*</span>
323+
)}
358324
</>
359325
);
326+
327+
return (
328+
<HoverCard open={isOpen} onOpenChange={onOpenChange} openDelay={0} closeDelay={150}>
329+
<HoverCardTrigger asChild>
330+
<span
331+
className={cn(
332+
"relative flex items-center gap-1 font-mono text-[11px] transition-colors",
333+
statusColor
334+
)}
335+
>
336+
{triggerContent}
337+
</span>
338+
</HoverCardTrigger>
339+
<HoverCardContent
340+
side={tooltipPosition === "right" ? "right" : "bottom"}
341+
align="center"
342+
sideOffset={8}
343+
collisionPadding={8}
344+
className="bg-modal-bg text-foreground border-separator-light z-[10000] max-h-[400px] w-auto max-w-96 min-w-0 overflow-auto px-3 py-2 font-mono text-[11px] whitespace-pre shadow-[0_4px_12px_rgba(0,0,0,0.5)]"
345+
>
346+
{popoverContent}
347+
</HoverCardContent>
348+
</HoverCard>
349+
);
360350
};

0 commit comments

Comments
 (0)