Dark mode toggle (#36)
* Add dark and light mode icons * Respect user's OS preferences, unless they toggle manually Co-authored-by: Brian Ginsburg <7957636+bgins@users.noreply.github.com>
This commit is contained in:
parent
f57beafa6c
commit
eec81aa1bf
|
|
@ -37,6 +37,6 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="svelte">%sveltekit.body%</div>
|
||||
<div id="svelte" class="h-screen">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation'
|
||||
import { sessionStore } from '../stores'
|
||||
import { sessionStore, theme } from '../stores'
|
||||
import { storeTheme, type Theme } from '$lib/theme/index'
|
||||
|
||||
import Shield from '$components/icons/Shield.svelte'
|
||||
import LightMode from '$components/icons/LightMode.svelte'
|
||||
import DarkMode from '$components/icons/DarkMode.svelte'
|
||||
|
||||
const setTheme = (newTheme: Theme) => {
|
||||
theme.set(newTheme)
|
||||
storeTheme(newTheme)
|
||||
}
|
||||
</script>
|
||||
|
||||
<header class="navbar bg-base-100 pt-0">
|
||||
|
|
@ -24,10 +32,22 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<span class="mr-2">
|
||||
{#if $theme === 'light'}
|
||||
<span on:click={() => setTheme('dark')}>
|
||||
<LightMode />
|
||||
</span>
|
||||
{:else}
|
||||
<span on:click={() => setTheme('light')}>
|
||||
<DarkMode />
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
{#if !$sessionStore.loading}
|
||||
{#if !$sessionStore.authed}
|
||||
<div class="flex-none">
|
||||
<a class="btn btn-sm btn-primary normal-case" href="/connect">
|
||||
<a class="btn btn-sm h-10 btn-primary normal-case" href="/connect">
|
||||
Connect
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<svg
|
||||
width="41"
|
||||
height="40"
|
||||
viewBox="0 0 41 40"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="stroke-slate-50 fill-slate-900 hover:stroke-slate-900 hover:fill-slate-50 hover:cursor-pointer transition-colors"
|
||||
>
|
||||
<rect x="1" y="0.5" width="39" height="39" rx="19.5" />
|
||||
<path
|
||||
d="M28.8542 23.3542C27.8176 23.7708 26.6856 24.0001 25.5 24.0001C20.5294 24.0001 16.5 19.9706 16.5 15.0001C16.5 13.8145 16.7292 12.6825 17.1458 11.6459C13.8365 12.9758 11.5 16.2151 11.5 20.0001C11.5 24.9706 15.5294 29.0001 20.5 29.0001C24.285 29.0001 27.5243 26.6636 28.8542 23.3542Z"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 673 B |
|
|
@ -0,0 +1,16 @@
|
|||
<svg
|
||||
width="41"
|
||||
height="40"
|
||||
viewBox="0 0 41 40"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="stroke-slate-900 fill-slate-50 hover:stroke-slate-50 hover:fill-slate-900 hover:cursor-pointer transition-colors"
|
||||
>
|
||||
<rect x="1" y="0.5" width="39" height="39" rx="19.5" />
|
||||
<path
|
||||
d="M20.5 11V12M20.5 28V29M29.5 20H28.5M12.5 20H11.5M26.864 26.364L26.1569 25.6569M14.8431 14.3431L14.136 13.636M26.864 13.6361L26.1569 14.3432M14.8432 25.6569L14.1361 26.364M24.5 20C24.5 22.2091 22.7091 24 20.5 24C18.2909 24 16.5 22.2091 16.5 20C16.5 17.7909 18.2909 16 20.5 16C22.7091 16 24.5 17.7909 24.5 20Z"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 700 B |
|
|
@ -4,7 +4,12 @@ export type Theme = 'light' | 'dark'
|
|||
|
||||
export const loadTheme = (): Theme => {
|
||||
if (browser) {
|
||||
return (localStorage.getItem('theme') as Theme) ?? 'light'
|
||||
const browserTheme = localStorage.getItem('theme') as Theme
|
||||
const osTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? 'dark'
|
||||
: 'light'
|
||||
|
||||
return browserTheme ?? (osTheme as Theme) ?? 'light'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,17 +5,12 @@
|
|||
import { appName } from '$lib/app-name'
|
||||
import { initialize } from '$lib/common/webnative'
|
||||
import { deviceStore, sessionStore, theme } from '../stores'
|
||||
import { storeTheme } from '$lib/theme'
|
||||
import { errorToMessage, type Session } from '$lib/session'
|
||||
import Toast from '$components/notifications/Toast.svelte'
|
||||
import Header from '$components/Header.svelte'
|
||||
|
||||
let session: Session = null
|
||||
|
||||
theme.subscribe(val => {
|
||||
storeTheme(val)
|
||||
})
|
||||
|
||||
sessionStore.subscribe(val => {
|
||||
session = val
|
||||
})
|
||||
|
|
@ -50,7 +45,7 @@
|
|||
|
||||
<svelte:window on:resize={setDevice} />
|
||||
|
||||
<div data-theme={$theme}>
|
||||
<div data-theme={$theme} class="h-screen">
|
||||
<Header />
|
||||
|
||||
{#if session.error}
|
||||
|
|
|
|||
Loading…
Reference in New Issue