Skip to content

Commit 4917db1

Browse files
committed
move theme to rune store/hook
1 parent e6dc936 commit 4917db1

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

src/lib/components/ThemeToggle.svelte

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
11
<script lang="ts">
2-
import { onMount } from 'svelte';
2+
import { getContext } from 'svelte';
33
44
import { Sun, Moon } from '@lucide/svelte';
55
import * as Dialog from '@/lib/components/ui/dialog/index.js';
6-
import { Button, buttonVariants } from '@/lib/components/ui/button/index.js';
6+
import { buttonVariants } from '@/lib/components/ui/button/index.js';
77
import * as RadioGroup from '@/lib/components/ui/radio-group/index';
88
import { Label } from '@/lib/components/ui/label';
9-
import { themes, type ThemeOptions } from '@/lib/utils/themes';
9+
import { themes } from '@/lib/utils/themes';
10+
import type { ThemeContext } from '@/stores/ThemeStove.svelte';
1011
11-
let currentTheme = $state(themes[0]);
1212
let isOpen = $state(false);
1313
14-
onMount(() => {
15-
const storedTheme = localStorage.getItem('theme');
16-
if (storedTheme) return handleThemeChange(storedTheme);
17-
checkSystemColorPreference();
18-
});
14+
let { currentTheme, handleThemeChange } = $derived(getContext<ThemeContext>('theme'));
1915
20-
const handleThemeChange = (theme: ThemeOptions) => {
21-
currentTheme = theme;
22-
document.documentElement.className = '';
23-
document.documentElement.classList.add(theme);
24-
localStorage.setItem('theme', theme);
16+
const handleThemeSelection = (value: string) => {
17+
handleThemeChange(value);
2518
isOpen = false;
2619
};
27-
28-
const checkSystemColorPreference = () => {
29-
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
30-
currentTheme = prefersDarkScheme ? 'dark' : 'light';
31-
};
3220
</script>
3321

3422
<Dialog.Root bind:open={isOpen}>
@@ -47,7 +35,7 @@
4735
</div>
4836
</Dialog.Trigger>
4937
<Dialog.Content class="max-h-[75vh] overflow-y-scroll">
50-
<RadioGroup.Root value={currentTheme} onValueChange={handleThemeChange}>
38+
<RadioGroup.Root value={currentTheme} onValueChange={handleThemeSelection}>
5139
{#each themes as theme}
5240
<div class="flex items-center space-x-2">
5341
<RadioGroup.Item value={theme} id={theme} />

src/lib/components/showcase/ThemeCard.svelte

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
<script lang="ts">
22
import * as Card from '@/lib/components/ui/card/index';
33
import { ScrollArea } from '@/lib/components/ui/scroll-area/index';
4-
import { themes, type ThemeOptions } from '@/lib/utils/themes';
4+
import { themes } from '@/lib/utils/themes';
55
import { Sun, Moon } from '@lucide/svelte';
66
import * as RadioGroup from '@/lib/components/ui/radio-group/index';
77
import Label from '@/lib/components/ui/label/label.svelte';
8-
import { onMount } from 'svelte';
8+
import { getContext } from 'svelte';
9+
import type { ThemeContext } from '@/stores/ThemeStove.svelte';
910
10-
let currentTheme = $state(themes[0]);
11-
12-
onMount(() => {
13-
const storedTheme = localStorage.getItem('theme');
14-
if (storedTheme) return handleThemeChange(storedTheme);
15-
checkSystemColorPreference();
16-
});
17-
18-
const handleThemeChange = (theme: ThemeOptions) => {
19-
currentTheme = theme;
20-
document.documentElement.className = '';
21-
document.documentElement.classList.add(theme);
22-
localStorage.setItem('theme', theme);
23-
};
24-
25-
const checkSystemColorPreference = () => {
26-
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
27-
currentTheme = prefersDarkScheme ? 'dark' : 'light';
28-
};
11+
let { currentTheme, handleThemeChange } = $derived(getContext<ThemeContext>('theme'));
2912
</script>
3013

3114
<Card.Root>

src/routes/+layout.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<script lang="ts">
22
import '../app.css';
3-
import type { Snippet } from 'svelte';
3+
import { setContext, type Snippet } from 'svelte';
44
import { ClerkProvider } from 'svelte-clerk';
55
import Footer from '@/lib/components/Footer.svelte';
66
import { Toaster } from '@/lib/components/ui/sonner/index.js';
77
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public';
8+
import { useTheme } from '@/stores/ThemeStove.svelte';
9+
10+
setContext('theme', useTheme());
811
912
const { children }: { children: Snippet } = $props();
1013
</script>

src/stores/ThemeStove.svelte.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { themes, type ThemeOptions } from '@/lib/utils/themes';
2+
3+
export const useTheme = () => {
4+
let currentTheme = $state(themes[0]);
5+
6+
$effect(() => {
7+
const storedTheme = localStorage.getItem('theme');
8+
if (storedTheme) return handleThemeChange(storedTheme);
9+
checkSystemColorPreference();
10+
});
11+
12+
const handleThemeChange = (theme: ThemeOptions) => {
13+
currentTheme = theme;
14+
document.documentElement.className = '';
15+
document.documentElement.classList.add(theme);
16+
localStorage.setItem('theme', theme);
17+
};
18+
19+
const checkSystemColorPreference = () => {
20+
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
21+
currentTheme = prefersDarkScheme ? 'dark' : 'light';
22+
};
23+
24+
return {
25+
get currentTheme() {
26+
return currentTheme;
27+
},
28+
handleThemeChange
29+
};
30+
};
31+
32+
export type ThemeContext = {
33+
currentTheme: string;
34+
handleThemeChange: (theme: string) => void;
35+
};

0 commit comments

Comments
 (0)