feat(ui): Implement theme persistence and system preference support

Adds comprehensive theme management across the application, allowing users to save their preferred color scheme (light/dark) or automatically follow the operating system's settings. This required updating state management in App.svelte to handle theme loading and applying changes dynamically via CSS variables.

The styling layer was significantly updated with new CSS variables and rules for both dark and light modes, ensuring visual consistency across all components like dialogs, buttons, and sidebars.

- Added logic to detect system color scheme preference
- Implemented full support for persistent light/dark mode switching
- Overhauled global CSS variables for improved theme adaptability
This commit is contained in:
Christoph Brandau
2026-07-10 12:24:14 +02:00
parent 7ef1a2dac8
commit 25b98d7c4d
7 changed files with 680 additions and 35 deletions
+30 -8
View File
@@ -24,22 +24,44 @@
export let onToggleAutoRefresh: () => void = () => {};
export let onOpenSettings: () => void = () => {};
const win = getCurrentWindow();
let win: ReturnType<typeof getCurrentWindow> | null = null;
let isMaximized = false;
let unlisten: (() => void) | undefined;
let appVersion = "";
onMount(async () => {
isMaximized = await win.isMaximized();
unlisten = await win.onResized(async () => {
try {
win = getCurrentWindow();
isMaximized = await win.isMaximized();
});
appVersion = await getVersion();
unlisten = await win.onResized(async () => {
isMaximized = await win?.isMaximized() ?? false;
});
} catch {
win = null;
}
try {
appVersion = await getVersion();
} catch {
appVersion = "";
}
});
onDestroy(() => {
unlisten?.();
});
function minimizeWindow() {
void win?.minimize();
}
function toggleMaximizeWindow() {
void win?.toggleMaximize();
}
function closeWindow() {
void win?.close();
}
</script>
<header class="titlebar" data-tauri-drag-region>
@@ -200,12 +222,12 @@
<div class="titlebar-divider" aria-hidden="true"></div>
<div class="titlebar-controls">
<button class="tb-btn" onclick={() => win.minimize()} title="Minimize" aria-label="Minimize">
<button class="tb-btn" onclick={minimizeWindow} title="Minimize" aria-label="Minimize">
<Minus size={12} aria-hidden="true" />
</button>
<button
class="tb-btn"
onclick={() => win.toggleMaximize()}
onclick={toggleMaximizeWindow}
title={isMaximized ? "Restore" : "Maximize"}
aria-label={isMaximized ? "Restore" : "Maximize"}
>
@@ -220,7 +242,7 @@
</svg>
{/if}
</button>
<button class="tb-btn close" onclick={() => win.close()} title="Close" aria-label="Close">
<button class="tb-btn close" onclick={closeWindow} title="Close" aria-label="Close">
<X size={12} aria-hidden="true" />
</button>
</div>