feat: Dark mode
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 });
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user