fix(chat): theme mermaid diagrams to the active palette and re-render on theme change#5587
Open
BrunooMoniz wants to merge 1 commit into
Open
fix(chat): theme mermaid diagrams to the active palette and re-render on theme change#5587BrunooMoniz wants to merge 1 commit into
BrunooMoniz wants to merge 1 commit into
Conversation
… on theme change initMermaid() initialised Mermaid once with a hard-coded theme: 'dark', so diagrams never followed the app palette (dark-on-light on light themes) and did not retheme on a theme switch. Build Mermaid's themeable 'base' theme from the app's existing CSS variables (--bg/--panel/--fg/--border/--accent|--red/ --font-family), re-initialise when the palette changes, and re-render on-screen diagrams when theme.js dispatches an odysseus-theme-changed event. Stays on the CDN-loaded Mermaid; no new colours, fonts, or components.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mermaid diagrams were always drawn with Mermaid's built-in
darktheme:initMermaid()instatic/js/markdown.jscalledmermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'loose' })exactly once (guarded bywindow.__odysseusMermaidReady). Because Mermaid bakes colours into the SVG at render time, a diagram never followed the app's CSS variables — on any light theme it was dark-filled with light text on a light page — and switching themes at runtime left already-rendered diagrams untouched. This PR drives Mermaid's themeablebasetheme from the app's existing theme tokens instead:initMermaid()now buildsthemeVariablesfrom the live CSS variables (--bg,--panel,--fg,--border,--accent/--red,--font-family) so node fills, borders, edges, text, and font all track the active palette, and it re-initialises whenever that palette changes.renderMermaid()records each diagram's source before Mermaid overwrites the<pre>with an SVG, andtheme.jsdispatches anodysseus-theme-changedevent fromapplyColors()that a small debounced listener uses to re-render every on-screen diagram with the new palette. It stays on the CDN-loaded Mermaid, keepssecurityLevel: 'loose', and introduces no new colours, fonts, or components — only the theming and the re-render-on-switch.Target branch
dev, notmain. All PRs land indev;mainis curated by the maintainer at each release. If your PR is onmainby accident, click "Edit" on this PR and change the base.Linked Issue
Fixes #5586
Type of Change
Checklist
devdocker compose uporuvicorn app:app) and verified the change works end-to-end. Type-checks and unit tests are not enough.How to Test
Steps a reviewer can reproduce (full app):
docker compose up -d --build, open the chat.dev: the diagram renders with Mermaid's dark theme no matter which app theme is active — on a light preset it is dark-on-light and clashes, and switching themes afterwards does not retheme it. With this branch: the diagram uses the active palette. Open the theme picker, switch between a dark preset and a light one (for example dark ↔ light / paper), and the on-screen diagram re-renders to match each time.What was verified for this change:
theme: 'base'+themeVariablesbuilt from the app's CSS variables) in Chromium (desktop, 1280px) and WebKit (mobile, iPhone 12, 390px), for the built-in dark and light presets — see the screenshots below.node --check static/js/markdown.jsandnode --check static/js/theme.js— pass.python -m pytest tests/test_mermaid_theming_js.py— 2 passed (palette →themeVariablesmapping for light vs dark; anodysseus-theme-changeddispatch re-initialises Mermaid with the new palette and re-renders the diagram from its saved source).python -m pytest tests/test_markdown_rendering_js.py— 13 passed (no regression in the renderer this touches).python -m pytest— 4618 passed, 5 skipped; the only 2 failures (tests/test_research_report_read.py) reproduce identically on unmodifieddevand are unrelated to this change.Files changed:
static/js/markdown.js—initMermaid()builds Mermaid'sbasetheme from the app's CSS variables (theme: 'base'+themeVariables) instead of a hard-codedtheme: 'dark', and re-initialises when the palette signature changes;renderMermaid()captures each diagram's source before Mermaid replaces it with an SVG; a debouncedodysseus-theme-changedlistener re-renders on-screen diagrams with the new palette. Adds a small exported_mermaidThemeVariables(palette)used by the tests.static/js/theme.js—applyColors()dispatches anodysseus-theme-changedCustomEvent so theme-reactive renderers (Mermaid) can follow a palette change. No colour or behaviour change to the theme system itself.tests/test_mermaid_theming_js.py— node-driven tests (palette →themeVariablesmapping for light and dark; a theme-change dispatch triggers re-initialise + re-render), following the existingtests/test_markdown_rendering_js.pyconvention.Visual / UI changes — REQUIRED if you touched anything that renders
Anything that changes what the UI looks like — buttons, icons, padding, colors, fonts, spacing, layout, CSS, HTML, SVG, or any
static/js/module that draws to the DOM — needs all of the following.theme: 'base'withthemeVariablesproduced by the module's own_mermaidThemeVariables()from the app's CSS variables — in Chromium (desktop, 1280px) and WebKit (mobile, iPhone 12, 390px), using the built-in dark and light theme presets.--red,--fg,--bg,--card,--border, etc.) — do not introduce new color values, font sizes, or spacing units. (This change reads the existing--bg/--panel/--fg/--border/--accent/--red/--font-familyvariables to theme the diagram; it adds none.)static/index.html) or plain text.Fira Code) for primary UI text. Don't override.Screenshots / clips
Desktop — dark theme
Desktop — light theme
Mobile — dark theme
Mobile — light theme