From 1368888747765c12c2d753004abdb6a5b8815348 Mon Sep 17 00:00:00 2001 From: ChrAlpha <53332481+ChrAlpha@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:47:42 +0000 Subject: [PATCH 1/8] feat(web): add Shiki highlight theme preference 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. --- .../src/components/markdown-preview/index.vue | 5 ++ .../src/components/monaco-editor/index.vue | 13 +++- .../src/composables/useShikiHighlighter.ts | 57 +++++++++++++--- apps/web/src/i18n/locales/en.json | 7 ++ apps/web/src/i18n/locales/ja.json | 7 ++ apps/web/src/i18n/locales/zh.json | 7 ++ apps/web/src/pages/about/index.vue | 7 ++ apps/web/src/pages/appearance/index.vue | 68 ++++++++++++++++++- .../pages/home/components/message-item.vue | 11 +++ apps/web/src/store/settings/index.ts | 24 +++++++ .../src/store/settings/shiki-theme.test.ts | 54 +++++++++++++++ apps/web/src/store/settings/shiki-theme.ts | 36 ++++++++++ 12 files changed, 279 insertions(+), 17 deletions(-) create mode 100644 apps/web/src/store/settings/shiki-theme.test.ts create mode 100644 apps/web/src/store/settings/shiki-theme.ts diff --git a/apps/web/src/components/markdown-preview/index.vue b/apps/web/src/components/markdown-preview/index.vue index c679f3b1d..68c284fae 100644 --- a/apps/web/src/components/markdown-preview/index.vue +++ b/apps/web/src/components/markdown-preview/index.vue @@ -19,6 +19,10 @@ const codeBlockMonacoOptions = computed(() => ({ fontFamily: settings.codeFontStack, fontSize: settings.codeFontSizePx, })) +const codeBlockTheme = computed(() => ({ + light: settings.shikiThemeLight, + dark: settings.shikiThemeDark, +})) const codeFontRenderKey = computed(() => settings.codeFontStack) @@ -32,6 +36,7 @@ const codeFontRenderKey = computed(() => settings.codeFontStack) :typewriter="false" :fade="false" :code-block-monaco-options="codeBlockMonacoOptions" + :theme="codeBlockTheme" custom-id="file-preview-md" /> diff --git a/apps/web/src/components/monaco-editor/index.vue b/apps/web/src/components/monaco-editor/index.vue index 84ccd863b..4808993c4 100644 --- a/apps/web/src/components/monaco-editor/index.vue +++ b/apps/web/src/components/monaco-editor/index.vue @@ -114,8 +114,10 @@ function buildMarkdownHeadingSymbols(model: Monaco.editor.ITextModel, monaco: ty // The applied light/dark mode is driven by the `.dark` class on (set by the // color-mode store, which also honors "system"). Read it straight from the DOM so we // pick the right base theme even when the preference is "system". -function resolveThemeName(): 'vitesse-dark' | 'vitesse-light' { - return document.documentElement.classList.contains('dark') ? 'vitesse-dark' : 'vitesse-light' +function resolveThemeName(): string { + return document.documentElement.classList.contains('dark') + ? settings.shikiThemeDark + : settings.shikiThemeLight } const { @@ -128,7 +130,7 @@ const { getEditorView, } = useMonaco({ theme: resolveThemeName(), - themes: ['vitesse-dark', 'vitesse-light'], + themes: [settings.shikiThemeDark, settings.shikiThemeLight], readOnly: props.readonly, automaticLayout: true, autoScrollInitial: false, @@ -346,6 +348,11 @@ watch(editorFontFamily, (fontFamily) => { watch([() => props.language, () => props.filename], () => { setLanguage(resolveLanguage()) }) + +watch( + () => [settings.shikiThemeLight, settings.shikiThemeDark] as const, + () => { void syncEditorTheme() }, +)