Skip to content

Fix code lens tooltip jitter - #10591

Merged
mscolnick merged 2 commits into
mainfrom
aka/fix-code-lens-jitter
Aug 20, 2026
Merged

Fix code lens tooltip jitter#10591
mscolnick merged 2 commits into
mainfrom
aka/fix-code-lens-jitter

Conversation

@akshayka

Copy link
Copy Markdown
Contributor

CodeMirror measured the popover before React rendered its content. In an unfocused editor, the empty measurement placed the popover over the icon. The completed render then moved it and triggered extra pointer events.

Render the popover content before CodeMirror measures it. This keeps the initial placement stable and prevents the hover loop.

CodeMirror measured the popover before React rendered its content. In an
unfocused editor, the empty measurement placed the popover over the icon. The
completed render then moved it and triggered extra pointer events.

Render the popover content before CodeMirror measures it. This keeps the
initial placement stable and prevents the hover loop.
Copilot AI lite review requested due to automatic review settings August 19, 2026 15:54
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview Aug 19, 2026 4:04pm

Request Review

@akshayka
akshayka requested a review from mscolnick August 19, 2026 15:54
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a UI hover-loop/jitter issue in the CodeLens popover by ensuring the popover content is rendered before CodeMirror performs its initial tooltip measurement, keeping the initial placement stable.

Changes:

  • Wrap initial root.render(...) in flushSync(...) so the tooltip is fully rendered before CodeMirror measures/positions it.
  • Add a unit test asserting the popover content is present immediately after mounting (to match CodeMirror’s measurement timing).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
frontend/src/core/codemirror/code-lens/popover.tsx Forces synchronous initial render of the popover to stabilize CodeMirror tooltip measurement/positioning.
frontend/src/core/codemirror/code-lens/tests/popover.test.ts Adds a regression test for synchronous initial popover content rendering.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +59 to +66
it("renders content synchronously for CodeMirror's initial measurement", () => {
const dom = document.createElement("div");

const dispose = mountLensPopover(dom, CACHE_SPEC);

expect(dom.textContent).toContain("my_cache");
dispose();
});
@akshayka akshayka added the bug Something isn't working label Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for ./frontend

Status Category Percentage Covered / Total
🔵 Lines 78.78% 82064 / 104166
🔵 Statements 78.78% 82064 / 104166
🔵 Functions 71.67% 706 / 985
🔵 Branches 79.49% 4971 / 6253
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
frontend/src/core/codemirror/code-lens/popover.tsx 79.26% 33.33% 100% 79.26% 61, 63, 65, 74, 181, 202-219, 222-238
Generated in workflow #20601 for commit 481f2e8 by the Vitest Coverage Report Action

`act()` flushes pending React renders. Wrapping the test mount in `act()`
would hide a regression that removes the required `flushSync`.

Keep the mount unwrapped and run only the deferred cleanup inside `act()`.
This prevents unmount warnings without weakening the assertion.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Architecture diagram
sequenceDiagram
    participant CM as CodeMirror Editor
    participant Lens as CodeLens Plugin
    participant Popover as mountLensPopover()
    participant React as React Root
    participant DOM as Tooltip DOM Element

    Note over CM,DOM: Code Lens Popover Positioning Flow

    CM->>Lens: User hovers over code lens icon
    Lens->>Popover: Create tooltip DOM element
    Popover->>React: createRoot(dom)
    Popover->>React: flushSync(render(<LensPopover />))
    Note over React: Synchronous render completes<br/>before function returns
    React->>DOM: Render popover content
    React-->>Popover: Render complete
    Popover-->>Lens: Return dispose function
    Lens->>CM: Provide tooltip position callback
    CM->>DOM: Measure popover dimensions
    CM->>CM: Calculate stable position
    CM->>DOM: Position tooltip at calculated location
    
    Note over CM,DOM: Key difference: Content is rendered<br/>before measurement, preventing<br/>empty container sizing
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread frontend/src/core/codemirror/code-lens/__tests__/popover.test.ts
@mscolnick
mscolnick merged commit 001c892 into main Aug 20, 2026
31 checks passed
@mscolnick
mscolnick deleted the aka/fix-code-lens-jitter branch August 20, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants