Skip to content

Commit b050924

Browse files
Jappie3sebastinez
authored andcommitted
add follow system theme button & functionality
1 parent 870f073 commit b050924

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/App/Settings.svelte

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
storeCodeFont,
66
storeTheme,
77
theme,
8+
followSystemTheme,
89
} from "@app/lib/appearance";
910
1011
import Button from "@app/components/Button.svelte";
@@ -43,18 +44,30 @@
4344
<Button
4445
ariaLabel="Light Mode"
4546
styleBorderRadius="0"
46-
variant={$theme === "light" ? "selected" : "not-selected"}
47+
variant={!$followSystemTheme && $theme === "light"
48+
? "selected"
49+
: "not-selected"}
4750
on:click={() => storeTheme("light")}>
4851
<Icon name="sun" />
4952
</Button>
5053
<div class="global-spacer" />
5154
<Button
5255
ariaLabel="Dark Mode"
5356
styleBorderRadius="0"
54-
variant={$theme === "dark" ? "selected" : "not-selected"}
57+
variant={!$followSystemTheme && $theme === "dark"
58+
? "selected"
59+
: "not-selected"}
5560
on:click={() => storeTheme("dark")}>
5661
<Icon name="moon" />
5762
</Button>
63+
<div class="global-spacer" />
64+
<Button
65+
ariaLabel="System Theme"
66+
styleBorderRadius="0"
67+
variant={$followSystemTheme ? "selected" : "not-selected"}
68+
on:click={() => storeTheme("system")}>
69+
<Icon name="device" />
70+
</Button>
5871
</Radio>
5972
</div>
6073
</div>

src/lib/appearance.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { writable } from "svelte/store";
22

33
export type Theme = "dark" | "light";
4+
export const followSystemTheme = writable<boolean>(shouldFollowSystemTheme());
45
export const theme = writable<Theme>(loadTheme());
56

67
export type CodeFont = "jetbrains" | "system";
@@ -29,26 +30,44 @@ function loadCodeFont(): CodeFont {
2930
}
3031
}
3132

33+
function shouldFollowSystemTheme(): boolean {
34+
const storedTheme = localStorage ? localStorage.getItem("theme") : null;
35+
if (storedTheme === null) {
36+
return true; // default to following the system theme
37+
} else {
38+
return storedTheme === "system";
39+
}
40+
}
41+
3242
function loadTheme(): Theme {
3343
const { matches } = window.matchMedia("(prefers-color-scheme: dark)");
3444
const storedTheme = localStorage ? localStorage.getItem("theme") : null;
3545

36-
if (storedTheme === null) {
46+
if (storedTheme === null || storedTheme === "system") {
3747
return matches ? "dark" : "light";
3848
} else {
3949
return storedTheme as Theme;
4050
}
4151
}
4252

43-
export function storeTheme(newTheme: Theme): void {
44-
theme.set(newTheme);
53+
export function storeTheme(newTheme: Theme | "system"): void {
54+
followSystemTheme.set(newTheme === "system" ? true : false);
4555
if (localStorage) {
4656
localStorage.setItem("theme", newTheme);
4757
} else {
4858
console.warn(
4959
"localStorage isn't available, not able to persist the selected theme without it.",
5060
);
5161
}
62+
if (newTheme !== "system") {
63+
// update the theme to newTheme
64+
theme.set(newTheme);
65+
} else {
66+
// update the theme to the current system theme
67+
theme.set(
68+
window.matchMedia("(prefers-color-scheme: dark)") ? "dark" : "light",
69+
);
70+
}
5271
}
5372

5473
export function storeCodeFont(newCodeFont: CodeFont): void {

0 commit comments

Comments
 (0)