Skip to content

fix(web): keep long mermaid labels inside their nodes - #2578

Open
djfch wants to merge 2 commits into
MoonshotAI:mainfrom
djfch:fix/web-mermaid-label-overlap
Open

fix(web): keep long mermaid labels inside their nodes#2578
djfch wants to merge 2 commits into
MoonshotAI:mainfrom
djfch:fix/web-mermaid-label-overlap

Conversation

@djfch

@djfch djfch commented Aug 3, 2026

Copy link
Copy Markdown

Related Issue

Resolve #2577

Problem

See linked issue.

What changed

Long mermaid labels overflowed their node boxes in the web UI: mermaid wraps long labels with CSS soft wrap inside <foreignObject> and sizes the node rect from the wrapped measurement, but the SVG sanitizer (stream-markdown-parser, pulled in by markstream-vue) flattens every <foreignObject> into a single-line <text>, keeping only literal <br> breaks. The full-width single-line label then renders centered on a rect sized for the wrapped width, overflowing both sides and overlapping neighbors.

This PR preprocesses chat markdown before rendering: every ```mermaid fence gets an injected %%{init: {"htmlLabels": false}}%% directive (behind a leading %% comment line so markstream still prepends its theme directive, which it only does when the code does not already start with a directive). With htmlLabels off, mermaid lays out native SVG text with real width-based line breaking (tspans), so the sanitizer has no <foreignObject> left to flatten and measurement and rendering agree.

Notes:

  • The directive must use the global htmlLabels key — flowchart.htmlLabels is deprecated and silently shadowed by the global default in mermaid 11.15 (verified empirically; the scoped key changes nothing).
  • The injector is a pure function with unit tests covering indented/CRLF/~~~ fences, streaming partial input, diagrams carrying their own init directive, and the invariant that injected code never starts with %%{ (which would disable markstream's theme prepend).
  • Verified in a real browser with the app's exact dependency versions (mermaid 11.15.0 + stream-markdown-parser 1.1.7): previously a 35-char CJK label rendered 576px of text in a 260px node; after the fix every label wraps into tspans and stays inside its rect, with dark/light theming intact.
  • No upstream code is patched, so future markstream/mermaid upgrades cannot silently conflict; once the upstream sanitizer handles soft-wrapped labels, deleting the single injection call site reverts this.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 74e0715

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0deecb0ffb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/kimi-web/src/lib/mermaidDirectives.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web: Long mermaid labels overflow their node boxes and overlap

1 participant