# refactor\(web\): the Mermaid code block lives in its own component file · PR \#22691 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/22691)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: refactor/chat-markdown-mermaid

Target branch: refactor/chat-markdown-code-blocks

Head commit: 0a9ade9156c9a9d199b97b3042b01213c23888cb

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/22691)

[Commits](https://git.cafe/pingdotgg/t3code/pull/22691/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/22691/diffs?format=markdown)

## Description

---

ChatMarkdown.tsx was a 3,560-line file that held every markdown renderer. This stack splits it into focused modules so each piece is readable on its own.

`MarkdownMermaidCodeBlock` moves next to `MermaidDiagram`. That includes its diagram/source toggle and its find reveal. The `./chat/MermaidDiagram` mock in ChatMarkdown.browser.test.tsx still applies, because it mocks by module path.

This is a pure move. Each renderer was already its own component, so no render boundary changes. Behavior is unchanged.

| | Before | After |
|---|---|---|
| `ChatMarkdown.tsx` lines | 3069 | 2992 |
| New files | | chat/MarkdownMermaidCodeBlock.tsx (84) |
| Renders | unchanged: no component, subscription or context boundary moved | unchanged |

Renders were not measured for this layer. It changes no render boundaries: the components, their props, and the two contexts stay exactly as they were.

Tests run:
- `vp test run --project browser src/components/ChatMarkdown.browser.test.tsx src/components/ChatMarkdown.permissions.browser.test.tsx` (11 passed)
- `vp test run --project unit src/reactCompilerCoverage.test.ts` for every touched file (0 bailouts)
- `tsc --noEmit` for apps/web, and `vp lint` on changed files

🤖 Generated with [Claude Code](https://claude.com/claude-code)
