File size: 3,036 Bytes
04ec17f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<script lang="ts">
	import { onMount } from "svelte";
	import ModeWatcherLite from "./mode-watcher-lite.svelte";
	import ModeWatcherFull from "./mode-watcher-full.svelte";
	import { modeStorageKey, themeStorageKey } from "../storage-keys.svelte.js";
	import {
		darkClassNames,
		disableTransitions,
		lightClassNames,
		mode,
		synchronousModeChanges,
		theme,
		themeColors,
	} from "../states.svelte.js";
	import type { ModeWatcherProps } from "../types.js";
	import { isValidMode } from "../modes.js";
	import { defineConfig, setMode, setTheme } from "../mode.js";
	import { systemPrefersMode } from "../mode-states.svelte.js";

	let {
		track = true,
		defaultMode = "system",
		themeColors: themeColorsProp,
		disableTransitions: disableTransitionsProp = true,
		darkClassNames: darkClassNamesProp = ["dark"],
		lightClassNames: lightClassNamesProp = [],
		defaultTheme = "",
		nonce = "",
		themeStorageKey: themeStorageKeyProp = "mode-watcher-theme",
		modeStorageKey: modeStorageKeyProp = "mode-watcher-mode",
		disableHeadScriptInjection = false,
		synchronousModeChanges: synchronousModeChangesProp = false,
	}: ModeWatcherProps = $props();

	modeStorageKey.current = modeStorageKeyProp;
	themeStorageKey.current = themeStorageKeyProp;
	darkClassNames.current = darkClassNamesProp;
	lightClassNames.current = lightClassNamesProp;
	disableTransitions.current = disableTransitionsProp;
	themeColors.current = themeColorsProp;
	synchronousModeChanges.current = synchronousModeChangesProp;

	$effect.pre(() => {
		synchronousModeChanges.current = synchronousModeChangesProp;
	});

	$effect.pre(() => {
		disableTransitions.current = disableTransitionsProp;
	});

	$effect.pre(() => {
		themeColors.current = themeColorsProp;
	});

	$effect.pre(() => {
		darkClassNames.current = darkClassNamesProp;
	});

	$effect.pre(() => {
		lightClassNames.current = lightClassNamesProp;
	});

	$effect.pre(() => {
		modeStorageKey.current = modeStorageKeyProp;
	});

	$effect.pre(() => {
		themeStorageKey.current = themeStorageKeyProp;
	});

	$effect.pre(() => {
		mode.current;
		modeStorageKey.current;
		themeStorageKey.current;
		theme.current;
	});

	onMount(() => {
		systemPrefersMode.tracking(track);
		systemPrefersMode.query();
		const localStorageMode = localStorage.getItem(modeStorageKey.current);
		setMode(isValidMode(localStorageMode) ? localStorageMode : defaultMode);
		const localStorageTheme = localStorage.getItem(themeStorageKey.current);
		setTheme(localStorageTheme || defaultTheme);
	});

	const initConfig = defineConfig({
		defaultMode,
		themeColors: themeColorsProp,
		darkClassNames: darkClassNamesProp,
		lightClassNames: lightClassNamesProp,
		defaultTheme,
		modeStorageKey: modeStorageKeyProp,
		themeStorageKey: themeStorageKeyProp,
	});

	const trueNonce = $derived(typeof window === "undefined" ? nonce : "");
</script>

{#if disableHeadScriptInjection}
	<ModeWatcherLite themeColors={themeColors.current} />
{:else}
	<ModeWatcherFull {trueNonce} {initConfig} themeColors={themeColors.current} />
{/if}