feat: Dark mode

This commit is contained in:
Sidharth Vinod
2025-03-10 21:27:50 -07:00
parent e33aed9cc6
commit f608761fa2
6 changed files with 27 additions and 56 deletions
+1
View File
@@ -87,6 +87,7 @@
"js-base64": "3.7.7",
"lodash-es": "^4.17.21",
"mermaid": "^11.3.0",
"mode-watcher": "^0.5.1",
"monaco-editor": "0.52.2",
"pako": "2.1.0",
"plausible-tracker": "^0.3.8",
+4 -4
View File
@@ -13,8 +13,8 @@
import { sanitizeText } from '$lib/util/sanitize';
import { stateStore, updateCode, updateConfig } from '$lib/util/state';
import { logEvent } from '$lib/util/stats';
import { themeStore } from '$lib/util/theme';
import { errorDebug, syncDiagram } from '$lib/util/util';
import { mode } from 'mode-watcher';
import * as monaco from 'monaco-editor';
import monacoEditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import monacoJsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
@@ -61,8 +61,8 @@
monaco.editor.setModelMarkers(model, 'mermaid', errorMarkers);
});
themeStore.subscribe(({ isDark }) => {
editor && monaco.editor.setTheme(isDark ? 'mermaid-dark' : 'mermaid');
mode.subscribe((mode) => {
editor && monaco.editor.setTheme(mode === 'dark' ? 'mermaid-dark' : 'mermaid');
});
const handleUpdate = (text: string, mode: EditorMode) => {
@@ -110,7 +110,7 @@
});
}
});
monaco.editor.setTheme($themeStore.isDark ? 'mermaid-dark' : 'mermaid');
monaco.editor.setTheme($mode === 'dark' ? 'mermaid-dark' : 'mermaid');
const resizeObserver = new ResizeObserver((entries) => {
editor?.layout({
height: entries[0].contentRect.height,
+12 -1
View File
@@ -14,6 +14,7 @@
import { dismissPromotion, getActivePromotion } from '$lib/util/promos/promo';
import { stateStore } from '$lib/util/state';
import { MCBaseURL } from '$lib/util/util';
import { toggleMode } from 'mode-watcher';
import type { ComponentProps } from 'svelte';
import DropdownNavMenu from './DropdownNavMenu.svelte';
@@ -84,7 +85,7 @@
</div>
{/if}
<nav class="z-50 flex p-4">
<nav class="z-50 flex p-4 px-6">
<div class="flex flex-1 items-center gap-4">
<Button variant="link" size="icon" href="/">
<img class="size-6" src="./favicon.svg" alt="Mermaid Live Editor" />
@@ -171,6 +172,16 @@
<DropdownNavMenu icon="fab fa-github fa-lg" links={githubLinks} />
<Separator orientation="vertical" class="min-h-[50%]" />
<Button onclick={toggleMode} variant="outline" size="icon">
<i
class="fas fa-sun rotate-0 scale-100 transition-all duration-200 dark:-rotate-90 dark:scale-0"
></i>
<i
class="fas fa-moon absolute rotate-90 scale-0 transition-all duration-200 dark:rotate-0 dark:scale-100"
></i>
<span class="sr-only">Toggle theme</span>
</Button>
<Button variant="secondary" size="sm">Share</Button>
{#if isEnabledMermaidChartLinks}
<Button size="sm" target="_blank" href="https://mermaidchart.com"
-38
View File
@@ -1,38 +0,0 @@
import { writable } from 'svelte/store';
import type { Writable } from 'svelte/store';
import { persist, localStorage } from '$lib/util/persist';
import { logEvent } from './stats';
export interface ThemeConfig {
isDark: boolean;
theme?: string;
}
export const themeStore: Writable<ThemeConfig> = persist(
writable({
isDark: false
}),
localStorage(),
'themeStore'
);
const darkThemes = new Set([
'dark',
'synthwave',
'halloween',
'aqua',
'forest',
'luxury',
'black',
'dracula'
]);
export const setTheme = (theme: string): void => {
if (theme.includes(' ')) {
theme = theme.split(' ')[1].trim();
}
const isDark = darkThemes.has(theme);
console.log('Setting theme', theme);
themeStore.set({ theme, isDark });
logEvent('themeChange', { theme, isDark });
};
+5 -13
View File
@@ -2,8 +2,8 @@
import { base } from '$app/paths';
import { loadingStateStore } from '$lib/util/loading';
import { toggleDarkTheme } from '$lib/util/state';
import { setTheme, themeStore } from '$lib/util/theme';
import { initHandler } from '$lib/util/util';
import { mode, ModeWatcher } from 'mode-watcher';
import { onMount, type Snippet } from 'svelte';
import '../app.postcss';
@@ -32,22 +32,14 @@
});
}
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
if ($themeStore.theme === undefined) {
setTheme(isDarkMode ? 'dark' : 'light');
}
themeStore.subscribe(({ theme, isDark }) => {
if (theme) {
document.querySelectorAll('html')[0].dataset.theme = theme;
toggleDarkTheme(isDark);
}
mode.subscribe((mode) => {
toggleDarkTheme(mode === 'dark');
});
});
</script>
<main class="h-screen text-primary-content">
<ModeWatcher />
<main class="text-primary-content h-screen">
{@render children?.()}
</main>
+5
View File
@@ -4646,6 +4646,11 @@ mlly@^1.7.3, mlly@^1.7.4:
pkg-types "^1.3.0"
ufo "^1.5.4"
mode-watcher@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mode-watcher/-/mode-watcher-0.5.1.tgz#310e6ac144b3f0b3cfb486e1015d9e746e503377"
integrity sha512-adEC6T7TMX/kzQlaO/MtiQOSFekZfQu4MC+lXyoceQG+U5sKpJWZ4yKXqw846ExIuWJgedkOIPqAYYRk/xHm+w==
monaco-editor@0.52.2:
version "0.52.2"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.52.2.tgz#53c75a6fcc6802684e99fd1b2700299857002205"