This commit is contained in:
73
src/lib/components/ThemeToggle.svelte
Normal file
73
src/lib/components/ThemeToggle.svelte
Normal file
@@ -0,0 +1,73 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
type Theme = 'light' | 'dark';
|
||||
let theme = $state<Theme>('light');
|
||||
|
||||
onMount(() => {
|
||||
theme = (document.documentElement.dataset.theme as Theme) === 'dark' ? 'dark' : 'light';
|
||||
});
|
||||
|
||||
function toggle() {
|
||||
theme = theme === 'dark' ? 'light' : 'dark';
|
||||
document.documentElement.dataset.theme = theme;
|
||||
try {
|
||||
localStorage.setItem('theme', theme);
|
||||
} catch {
|
||||
// storage may be unavailable (private mode); toggle still works for the session
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="theme-toggle"
|
||||
type="button"
|
||||
onclick={toggle}
|
||||
aria-label={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
>
|
||||
{#if theme === 'dark'}
|
||||
<!-- Sun: shown in dark mode to switch to light -->
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4.2" fill="currentColor" />
|
||||
<g stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
|
||||
<line x1="12" y1="2" x2="12" y2="4.6" />
|
||||
<line x1="12" y1="19.4" x2="12" y2="22" />
|
||||
<line x1="2" y1="12" x2="4.6" y2="12" />
|
||||
<line x1="19.4" y1="12" x2="22" y2="12" />
|
||||
<line x1="4.9" y1="4.9" x2="6.7" y2="6.7" />
|
||||
<line x1="17.3" y1="17.3" x2="19.1" y2="19.1" />
|
||||
<line x1="4.9" y1="19.1" x2="6.7" y2="17.3" />
|
||||
<line x1="17.3" y1="6.7" x2="19.1" y2="4.9" />
|
||||
</g>
|
||||
</svg>
|
||||
{:else}
|
||||
<!-- Moon: shown in light mode to switch to dark -->
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
||||
<path
|
||||
d="M20.5 14.2A8.2 8.2 0 0 1 9.8 3.5a8.2 8.2 0 1 0 10.7 10.7Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.theme-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
border: 1px solid #6f6f6f;
|
||||
padding: 0;
|
||||
}
|
||||
.theme-toggle:hover {
|
||||
background: #353535;
|
||||
}
|
||||
.theme-toggle svg {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user