Skip to content

fix(renderer): animate mermaid block height when the diagram renders - #2142

Draft
roxi3906 wants to merge 2 commits into
aipoch:mainfrom
roxi3906:fix/mermaid-height-jump
Draft

fix(renderer): animate mermaid block height when the diagram renders#2142
roxi3906 wants to merge 2 commits into
aipoch:mainfrom
roxi3906:fix/mermaid-height-jump

Conversation

@roxi3906

@roxi3906 roxi3906 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Streamdown reserves a fixed ~200px placeholder for each mermaid fence and only renders the diagram once the block scrolls near the viewport (IntersectionObserver + idle callback). The rendered SVG's height almost never matches the placeholder, so the moment the diagram appears, the surrounding transcript jumps abruptly.

Change

Adds an install-time DOM enhancement (installMermaidHeightAnimation, wired into installStreamdown) that smooths the swap:

  • A MutationObserver discovers [data-streamdown="mermaid-block"] elements inside .agent-markdown-root (covers both static and streaming render modes, since both go through the same DOM).
  • A ResizeObserver tracks each block's height. When it changes — placeholder → spinner → rendered SVG, streaming re-renders, window resize — the block's height is pinned to the previous value and transitioned to the new height (180ms, ease) instead of snapping. Inline styles are cleaned up when the transition ends so the block returns to height: auto.
  • The first measurement after observe never animates (no animation on initial mount).
  • Sub-2px deltas are ignored to avoid animating rounding noise.
  • prefers-reduced-motion: reduce skips the animation entirely.
  • A height change that lands mid-transition is re-measured when the transition finishes and chains into a follow-up animation instead of snapping.
  • Removed blocks are unobserved and any in-flight inline styles are restored; uninstalling mid-animation also restores auto height.

No upstream patch and no changes to streamdown's rendering or to the mermaid block chrome (actions/fullscreen/download all untouched).

Testing

  • New unit suite mermaid-height-animation.test.ts (9 tests): placeholder→render animation, initial-measurement skip, delta threshold, mid-transition chaining, observer frame filtering, reduced motion, blocks outside the markdown root, add/remove tracking, uninstall cleanup.
  • Full vitest run: 23,695 passed; the only 4 failures (network-enforcement.integration, literature-review kernel, kernel-executor Windows cancellation) reproduce identically on a clean main checkout — pre-existing environment issues (Python version, sandbox network policy), unrelated to this change.
  • npm run typecheck and ESLint clean.

Streamdown reserves a 200px placeholder for mermaid fences and swaps in
the real SVG once the block scrolls near the viewport. The placeholder
and rendered heights almost never match, so the transcript jumps.

Add an install-time DOM enhancement that observes each mermaid block
with a ResizeObserver and transitions the block's height (180ms) from
the placeholder height to the rendered height instead of snapping. The
first measurement never animates, sub-2px changes are ignored,
prefers-reduced-motion skips the animation, and a height change that
lands mid-transition chains into a follow-up animation rather than
snapping at the end.
@github-actions github-actions Bot added the bug Something isn't working label Sep 4, 2026
…jump

# Conflicts:
#	src/renderer/src/components/streamdown/install-streamdown.ts
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.

1 participant