Add theme toggle
This commit is contained in:
@@ -1,9 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import '../app.css';
|
||||
import Sidebar from '$lib/components/Sidebar.svelte';
|
||||
import SearchBar from '$lib/components/SearchBar.svelte';
|
||||
|
||||
let sidebarOpen = false;
|
||||
let theme: 'light' | 'dark' = 'dark';
|
||||
|
||||
const applyTheme = (value: 'light' | 'dark') => {
|
||||
theme = value;
|
||||
if (!browser) return;
|
||||
document.documentElement.dataset.theme = value;
|
||||
window.localStorage.setItem('theme', value);
|
||||
};
|
||||
|
||||
const toggleTheme = () => {
|
||||
applyTheme(theme === 'dark' ? 'light' : 'dark');
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
if (!browser) return;
|
||||
|
||||
const savedTheme = window.localStorage.getItem('theme') as 'light' | 'dark' | null;
|
||||
const initialTheme = savedTheme ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||
applyTheme(initialTheme);
|
||||
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const handlePreferenceChange = (event: MediaQueryListEvent) => {
|
||||
if (window.localStorage.getItem('theme')) return;
|
||||
applyTheme(event.matches ? 'dark' : 'light');
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
if ('removeEventListener' in mediaQuery) {
|
||||
mediaQuery.removeEventListener('change', handlePreferenceChange);
|
||||
} else {
|
||||
mediaQuery.removeListener(handlePreferenceChange);
|
||||
}
|
||||
};
|
||||
|
||||
if ('addEventListener' in mediaQuery) {
|
||||
mediaQuery.addEventListener('change', handlePreferenceChange);
|
||||
} else {
|
||||
mediaQuery.addListener(handlePreferenceChange);
|
||||
}
|
||||
|
||||
return cleanup;
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -22,6 +67,15 @@
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<SearchBar />
|
||||
<button
|
||||
type="button"
|
||||
class="theme-toggle"
|
||||
on:click={toggleTheme}
|
||||
aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}
|
||||
>
|
||||
<span aria-hidden="true">{theme === 'dark' ? '☀️' : '🌙'}</span>
|
||||
<span class="theme-toggle__label">{theme === 'dark' ? 'Light' : 'Dark'} mode</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user