From fd8f0cdfd7113ff3a9147db2b0d7a7e33feb6ce5 Mon Sep 17 00:00:00 2001 From: Atharva Ajmera Date: Fri, 24 Jul 2026 06:09:01 +0530 Subject: [PATCH] Fix squashed Mermaid diagrams in markdown preview (#61260) ## Summary Wide Mermaid diagrams in Markdown Preview were forced through `max_w_full()`, so both width and height shrank to the pane and text became unreadable/blurry. There was no horizontal pan. Markdown Preview already sets `code_block_overflow_x_scroll: true` for fenced code blocks. Mermaid ignored that flag. This change gates layout on that style flag: - **Preview** (`code_block_overflow_x_scroll`): keep the raster at intrinsic size and enable `overflow_x_scroll` (with `restrict_scroll_to_axis`) so wide diagrams stay readable and can be panned horizontally. - **Compact UIs** (e.g. agent): keep previous `max_w_full()` fit-to-pane behavior. Fixes #61051 ## Test plan - [ ] Open a markdown file with a wide ` ```mermaid ` flowchart (e.g. multi-column TB graph) in Markdown Preview - [ ] Confirm diagram is not crushed to pane width; text remains legible at default scale - [ ] Confirm horizontal scroll/pan works on the diagram without stealing vertical page scroll - [ ] Confirm compact surfaces that leave `code_block_overflow_x_scroll` off still fit diagrams to width - [ ] Confirm mermaid scale fence info still works (` ```mermaid 150 `) - [ ] Confirm Preview/Code tabs and copy button still work --- Release Notes: - Fixed wide Mermaid diagrams in Markdown Preview being squashed and illegible --- crates/markdown/src/mermaid.rs | 52 +++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/crates/markdown/src/mermaid.rs b/crates/markdown/src/mermaid.rs index d6ab952496..ae42ad453d 100644 --- a/crates/markdown/src/mermaid.rs +++ b/crates/markdown/src/mermaid.rs @@ -322,6 +322,8 @@ pub(crate) fn render_mermaid_diagram( let cached = mermaid_state.cache.get(&parsed.contents); let render_result = cached.and_then(|cached| cached.render_image.get()); let show_interactive = copy_button_visibility != CopyButtonVisibility::Hidden; + // Preview keeps diagrams at natural size + scroll instead of crushing them via max_w_full (#61051). + let allow_overflow_x = style.code_block_overflow_x_scroll; let code = parsed.contents.contents.clone(); @@ -333,16 +335,7 @@ pub(crate) fn render_mermaid_diagram( let body = if showing_code { render_mermaid_code_view(&parsed.contents.contents) } else { - div() - .w_full() - .child( - img(ImageSource::Render(render_image.clone())) - .max_w_full() - .with_fallback(|| { - Label::new("Failed to Load Mermaid Diagram").into_any_element() - }), - ) - .into_any_element() + render_mermaid_image(render_image.clone(), allow_overflow_x, source_offset) }; container @@ -382,16 +375,11 @@ pub(crate) fn render_mermaid_diagram( container .child( div() - .w_full() - .child( - img(ImageSource::Render(fallback.clone())) - .max_w_full() - .with_fallback(|| { - div() - .child(Label::new("Failed to load mermaid diagram")) - .into_any_element() - }), - ) + .child(render_mermaid_image( + fallback.clone(), + allow_overflow_x, + source_offset, + )) .with_animation( "mermaid-fallback-pulse", Animation::new(Duration::from_secs(2)) @@ -439,6 +427,30 @@ pub(crate) fn render_mermaid_diagram( } } +/// Renders a mermaid diagram image, scrolling at intrinsic size in preview or fit-to-pane elsewhere. +fn render_mermaid_image( + render_image: Arc, + allow_overflow_x: bool, + source_offset: usize, +) -> AnyElement { + let image = img(ImageSource::Render(render_image)) + .with_fallback(|| Label::new("Failed to Load Mermaid Diagram").into_any_element()); + + if allow_overflow_x { + div() + .id(("mermaid-scroll", source_offset)) + .w_full() + .map(|mut container| { + container.style().restrict_scroll_to_axis = Some(true); + container.overflow_x_scroll() + }) + .child(image) + .into_any_element() + } else { + div().w_full().child(image.max_w_full()).into_any_element() + } +} + fn render_mermaid_tab_header( source_offset: usize, showing_code: bool,