From 917ff9a6726fae8645a1f967247790419e708ba9 Mon Sep 17 00:00:00 2001 From: xintaofei Date: Mon, 13 Apr 2026 12:08:00 +0800 Subject: [PATCH] fix(frontend): fix find widget tooltip flicker, clipping, and close button alignment - Prevent hover tooltip flicker by adding pointer-events:none to the .context-view overlay that covers trigger buttons - Escape overflow:hidden clipping on ancestor elements by switching the tooltip overlay to position:fixed, with CSS custom properties (--cv-offset-x/y) set via ResizeObserver to translate container-relative coordinates to viewport-relative - Give the find widget its own border/radius styles (no top border, bottom-only border-radius) since it slides from the editor top - Adjust close button vertical position to align with action buttons Closes #73 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/globals.css | 30 ++++++++++++++++++- src/components/files/file-workspace-panel.tsx | 15 ++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/app/globals.css b/src/app/globals.css index 907d1c4..2f7efa8 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1114,7 +1114,7 @@ /* Monaco widgets: align popups/menus with shadcn surface style */ .context-view .monaco-menu, .monaco-editor .suggest-widget, -.monaco-editor .editor-widget, +.monaco-editor .editor-widget:not(.find-widget), .monaco-editor .peekview-widget, .monaco-hover.workbench-hover { border: 1px solid var(--border) !important; @@ -1122,6 +1122,34 @@ box-shadow: 0 18px 36px -24px rgb(0 0 0 / 55%) !important; } +/* Find widget slides from top: only bottom corners rounded, no top border */ +.monaco-editor .find-widget { + border-left: 1px solid var(--border) !important; + border-right: 1px solid var(--border) !important; + border-bottom: 1px solid var(--border) !important; + border-top: none !important; + border-radius: 0 0 var(--radius) var(--radius) !important; + box-shadow: 0 18px 36px -24px rgb(0 0 0 / 55%) !important; +} + +/* Align the close button with the action buttons (prev/next match) */ +.monaco-editor .find-widget > .button.codicon-widget-close { + top: 9px !important; +} + +/* Fix: Monaco hover tooltips are rendered in a .context-view overlay that + 1) covers the trigger button causing mouseleave→show flicker, and + 2) gets clipped by overflow:hidden on ancestor elements. + Using position:fixed escapes overflow clipping; translate corrects the + coordinates (inline top/left are container-relative, translate adds the + container's viewport offset). pointer-events:none prevents the overlay + from stealing mouse events from the button underneath. */ +.context-view:has(> .workbench-hover-container) { + position: fixed !important; + translate: var(--cv-offset-x, 0px) var(--cv-offset-y, 0px); + pointer-events: none; +} + .context-view .monaco-menu .monaco-action-bar.vertical .action-item .action-menu-item, .monaco-editor .suggest-widget .monaco-list-row, .monaco-editor .peekview-widget .monaco-list-row { diff --git a/src/components/files/file-workspace-panel.tsx b/src/components/files/file-workspace-panel.tsx index 85661df..54b4664 100644 --- a/src/components/files/file-workspace-panel.tsx +++ b/src/components/files/file-workspace-panel.tsx @@ -1014,6 +1014,21 @@ export function FileWorkspacePanel() { setCursorLine(editorInstance.getPosition()?.lineNumber ?? 1) applyHiddenAreas() applyGitChangeDecorations() + + // Set CSS custom properties so hover tooltips can use position:fixed + // to escape overflow:hidden clipping on ancestor elements. + const dom = editorInstance.getContainerDomNode() + if (dom) { + const syncOffset = () => { + const r = dom.getBoundingClientRect() + dom.style.setProperty("--cv-offset-x", `${r.left}px`) + dom.style.setProperty("--cv-offset-y", `${r.top}px`) + } + syncOffset() + const ro = new ResizeObserver(syncOffset) + ro.observe(dom) + editorInstance.onDidDispose(() => ro.disconnect()) + } }, [applyGitChangeDecorations, applyHiddenAreas] )