feat: add dark/light theme toggle with system preference support (#18)
Add theme switching with three modes (system/light/dark) using Tailwind v4 class-based dark mode. Theme preference is persisted in localStorage and defaults to the system's prefers-color-scheme. All components updated with dark: variants for consistent dark mode rendering including SVG elements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
37
src/lib/components/ThemeToggle.svelte
Normal file
37
src/lib/components/ThemeToggle.svelte
Normal file
@@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import { themeStore } from '$lib/stores/theme.svelte';
|
||||
|
||||
const labels: Record<string, string> = {
|
||||
system: 'System',
|
||||
light: 'Light',
|
||||
dark: 'Dark'
|
||||
};
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => themeStore.cycle()}
|
||||
class="flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-sm text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-100"
|
||||
title="Theme: {labels[themeStore.mode]} (click to cycle)"
|
||||
>
|
||||
{#if themeStore.mode === 'light'}
|
||||
<!-- Sun icon -->
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
|
||||
</svg>
|
||||
{:else if themeStore.mode === 'dark'}
|
||||
<!-- Moon icon -->
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
||||
</svg>
|
||||
{:else}
|
||||
<!-- Monitor/system icon -->
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
|
||||
<line x1="8" y1="21" x2="16" y2="21" />
|
||||
<line x1="12" y1="17" x2="12" y2="21" />
|
||||
</svg>
|
||||
{/if}
|
||||
<span class="text-xs">{labels[themeStore.mode]}</span>
|
||||
</button>
|
||||
Reference in New Issue
Block a user