Skip to content

feat(web): add Shiki/Mermaid theme preference#653

Open
ChrAlpha wants to merge 8 commits into
memohai:mainfrom
ChrAlpha:feat/shiki-mermaid-theme
Open

feat(web): add Shiki/Mermaid theme preference#653
ChrAlpha wants to merge 8 commits into
memohai:mainfrom
ChrAlpha:feat/shiki-mermaid-theme

Conversation

@ChrAlpha

@ChrAlpha ChrAlpha commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

在 appearance settings:

  • 添加 Shiki theme (light + dark) 配置项
  • 添加 Mermaid theme 配置项
image

ChrAlpha added 4 commits June 16, 2026 11:57
Two new appearance settings (light + dark) drive Shiki theme selection
across the highlighter composable, Monaco file viewer, and markstream-vue
markdown renderers, defaulting to github-light / github-dark. The
appearance code preview no longer hard-codes its theme.
New Appearance > Diagrams row picks one of mermaid's bundled themes (auto /
default / dark / forest / neutral) and persists to mermaid-theme. A themed
wrapper around MarkdownRender's mermaid slot injects an inline init directive
(skipped when the source already opens with %%{) so the choice carries through
both worker parsing and rendering. Auto keeps following the interface isDark.
Appearance reorganization:
- Mermaid Theme row now embeds a small flowchart preview so the chosen
  theme is visible immediately. A reactive key remounts the SVG when the
  theme (or interface dark) changes.
- Shiki Light/Dark theme pickers move into Typography next to the code
  font controls, and the syntax-highlighting code preview drops to the
  bottom of the section so all code-styling rows precede their preview.
The diagram already renders with its own outline; the surrounding card
chrome (border + bg-surface-editor) was redundant and made the row read
like a mocked tile rather than a live preview.

@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: 9a3fa0d53a

ℹ️ 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 on lines +47 to +50
const activeThemes = () => ({
light: settings.shikiThemeLight as BundledTheme,
dark: settings.shikiThemeDark as BundledTheme,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Re-highlight mounted code blocks after theme changes

These settings are only read when highlight()/highlightLang() is called, but existing consumers such as pages/home/components/code-block.vue watch only the code, language, and filename. If a user changes Settings → Appearance while a chat code fence or tool diff is already mounted, the HTML keeps the old Shiki colors until the message remounts or the code changes, so the new theme preference is not applied to the main code-block surfaces.

Useful? React with 👍 / 👎.

Comment on lines +303 to +307
auto: 'Auto',
default: 'Default',
dark: 'Dark',
forest: 'Forest',
neutral: 'Neutral',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use i18n for Mermaid theme labels

These labels are rendered directly in the Mermaid Theme dropdown, so zh/ja users see the new setting values in English despite locale files being updated for the rest of this section. apps/web/AGENTS.md requires all user-facing strings to use i18n keys, so move these labels into the locale files before exposing the setting.

Useful? React with 👍 / 👎.

Comment on lines +19 to +22
const content = props.node?.content ?? ''
const next = applyMermaidThemeToSource(content, settings.mermaidTheme)
if (next === content) return props.node
return { ...props.node, content: next }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Write the Mermaid theme into node.code

The Mermaid renderer receives the same CodeBlockNode shape as other fenced blocks, whose source is carried on node.code/node.raw (the existing chat code block reads those fields), but this wrapper reads and writes only a new content field. When a user selects forest or neutral, the injected init directive is ignored by MermaidBlockNode, so the new Mermaid theme preference does not actually change those diagrams.

Useful? React with 👍 / 👎.

:typewriter="false"
:fade="false"
:code-block-monaco-options="codeBlockMonacoOptions"
:theme="codeBlockTheme"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Forward Shiki themes through code-block props

For MarkdownRender's built-in code block renderer, the unified theme option is forwarded through code-block-props; passing it as a top-level theme prop here is ignored. In file previews and release notes that use the default Markstream code block, selecting a custom Shiki theme therefore leaves code blocks on the library default theme, so wrap this as :code-block-props="{ theme: codeBlockTheme }" or use the dedicated code-block theme props.

Useful? React with 👍 / 👎.

ChrAlpha added 4 commits June 16, 2026 12:28
Hide every toolbar control on the preview's mermaid block (header,
mode toggle, copy/export/fullscreen/collapse, zoom, interactions) and
flatten the container chrome via scoped overrides on .mermaid-block-container
and .mermaid-preview-area so only the bare diagram remains.
Two adjustments to the appearance page:
- Move the Diagrams (mermaid) section below Typography, since it's a
  child concern of code styling.
- Replace the stacked Light/Dark Shiki theme rows + single shared preview
  with a two-column grid: each picker sits directly above a preview
  rendered in its own theme. Each preview keeps the theme's background and
  reads line numbers from the inline pre color (currentColor / 0.45) so
  they stay legible on any theme, independent of the interface mode. The
  isDark watcher on the code preview is dropped — both previews are now
  bound to their own picked theme, not the interface mode.
The 2-column preview block previously used the UI's --color-border for
the wrapper outline, so flipping the interface theme nudged both preview
chrome even though the picked Shiki themes hadn't changed. Replace the
mode-aware wrapper border with an inset box-shadow on the <pre> derived
from currentColor (mix at 18%) so the outline rides on the theme's own
text color and stays identical across light/dark interface flips.

Also surface a small "Code highlight" heading + description above the
grid so the block aligns with how the other settings rows announce
their purpose.
packages/ui ships a layered \`.dark .shiki, .dark .shiki span { color:
var(--shiki-dark) !important }\` rule. With single-theme rendering the
override blasted past every inline token color in dark interface mode,
making the previews unreadable.

Render each preview in dual-theme mode with BOTH halves set to the same
picked theme. Shiki then writes \`--shiki-dark\` equal to the picked
colors, so the !important rule resolves back to the inline values and the
override is a visual no-op. Each preview now stays true to its picked
theme regardless of interface mode.

Also drop the chatty interface-mode caveat from the Code-highlight
description — it's our boundary to handle, not something to push onto
the user.
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.

1 participant