fix: theme select

This commit is contained in:
Torsten Dittmann
2023-09-28 00:03:48 +02:00
parent 6cbaee0e7b
commit 7adcfd02a8
4 changed files with 95 additions and 80 deletions

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/images/logos/logo.svg" /> <link rel="icon" type="image/svg+xml" href="/images/logos/logo.svg" />
@@ -8,27 +9,10 @@
<meta name="”twitter:site”" content="@appwrite" /> <meta name="”twitter:site”" content="@appwrite" />
%sveltekit.head% %sveltekit.head%
</head> </head>
<body class="theme-dark" data-sveltekit-preload-data="hover"> <body class="theme-dark" data-sveltekit-preload-data="hover">
<script
type="module"
src="https://unpkg.com/@splinetool/viewer@0.9.455/build/spline-viewer.js"
></script>
<script>
const isDocs = window.location.pathname.startsWith('/docs');
if (isDocs) {
const theme = localStorage.getItem('theme');
document.body.classList.remove('theme-dark', 'theme-light') || 'dark';
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
document.body.classList.add(`theme-${systemTheme}`);
} else {
document.body.classList.add(`theme-${theme}`);
}
localStorage.setItem('theme', theme);
}
</script>
<div id="top" style="display: contents">%sveltekit.body%</div> <div id="top" style="display: contents">%sveltekit.body%</div>
<script type="module" src="https://unpkg.com/@splinetool/viewer@0.9.455/build/spline-viewer.js" defer></script>
</body> </body>
</html> </html>

View File

@@ -1,21 +1,16 @@
<script lang="ts"> <script lang="ts">
import { capitalize } from '$lib/utils/capitalize.js'; import { capitalize } from '$lib/utils/capitalize.js';
import { currentTheme, setTheme, type Theme } from '$routes/+layout.svelte';
import { createSelect, melt } from '@melt-ui/svelte'; import { createSelect, melt } from '@melt-ui/svelte';
import { onMount } from 'svelte';
import { fly } from 'svelte/transition'; import { fly } from 'svelte/transition';
const iconMap = { const iconMap: Record<Theme, string> = {
dark: 'aw-icon-dark', dark: 'aw-icon-dark',
light: 'aw-icon-light', light: 'aw-icon-light',
system: 'icon-server' system: 'icon-server'
} as const; };
const themes = ['dark', 'light', 'system'] as const; const themes: Array<Theme> = ['dark', 'light', 'system'];
type Theme = (typeof themes)[number];
function isTheme(theme: unknown): theme is Theme {
return themes.includes(theme as Theme);
}
const { const {
elements: { trigger, menu, option }, elements: { trigger, menu, option },
@@ -23,8 +18,8 @@
} = createSelect<Theme>({ } = createSelect<Theme>({
preventScroll: false, preventScroll: false,
defaultSelected: { defaultSelected: {
value: 'dark', value: $currentTheme,
label: 'Dark' label: capitalize($currentTheme)
}, },
positioning: { positioning: {
sameWidth: true, sameWidth: true,
@@ -33,44 +28,13 @@
forceVisible: true, forceVisible: true,
onSelectedChange({ curr, next }) { onSelectedChange({ curr, next }) {
const t = next?.value; const t = next?.value;
if (isTheme(t) && t !== curr?.value) { if (t && t !== curr?.value) {
setTheme(t); setTheme(t);
} }
open.set(false); open.set(false);
return next; return next;
} }
}); });
function setSelected(theme: Theme) {
selected.set({
value: theme,
label: capitalize(theme)
});
}
function setTheme(theme: Theme) {
document.body.classList.remove('theme-dark', 'theme-light');
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
document.body.classList.add(`theme-${systemTheme}`);
} else {
document.body.classList.add(`theme-${theme}`);
}
localStorage.setItem('theme', theme);
}
onMount(() => {
const theme = localStorage.getItem('theme');
if (isTheme(theme)) {
setTheme(theme);
setSelected(theme);
} else {
setTheme('dark');
setSelected('dark');
}
});
</script> </script>
<button class="aw-select is-colored" use:melt={$trigger}> <button class="aw-select is-colored" use:melt={$trigger}>

View File

@@ -90,10 +90,6 @@
label: 'Blog', label: 'Blog',
href: '/blog' href: '/blog'
}, },
// {
// label: 'Changelog',
// href: '#'
// },
{ {
label: 'Pricing', label: 'Pricing',
href: '/pricing' href: '/pricing'

View File

@@ -1,3 +1,41 @@
<script lang="ts" context="module">
export type Theme = 'dark' | 'light' | 'system';
export const currentTheme = writable<Theme>(getPreferredTheme());
function isTheme(theme: unknown): theme is Theme {
return ['dark', 'light', 'system'].includes(theme as Theme);
}
function getSystemTheme(): Theme {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
function getPreferredTheme() {
if (!browser) {
return 'dark';
}
const theme = globalThis?.localStorage.getItem('theme');
if (!isTheme(theme)) {
return 'dark';
}
if (theme === 'system') {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
return theme;
}
export function setTheme(theme: string) {
if (!isTheme(theme)) {
return;
}
currentTheme.set(theme === 'system' ? getSystemTheme() : theme);
}
</script>
<script lang="ts"> <script lang="ts">
import '@fontsource/inter/100.css'; import '@fontsource/inter/100.css';
import '@fontsource/inter/200.css'; import '@fontsource/inter/200.css';
@@ -9,7 +47,40 @@
import '@fontsource/inter/800.css'; import '@fontsource/inter/800.css';
import '@fontsource/inter/900.css'; import '@fontsource/inter/900.css';
import '$scss/index.scss'; import '$scss/index.scss';
import { dev } from '$app/environment'; import { browser, dev } from '$app/environment';
import { writable } from 'svelte/store';
import { navigating, page } from '$app/stores';
import { onMount } from 'svelte';
function applyTheme(theme: Omit<Theme, 'system'>) {
const className = `theme-${theme}`;
document.body.classList.add(className);
document.body.classList.remove(`theme-${theme === 'dark' ? 'light' : 'dark'}`);
}
onMount(() => {
const initialTheme = $page.route.id?.startsWith('/docs') ? getPreferredTheme() : 'dark';
applyTheme(initialTheme);
currentTheme.subscribe((theme) => applyTheme(theme));
navigating.subscribe((n) => {
if (!n?.to) {
return;
}
const isDocs = n.to.route.id?.startsWith('/docs');
if (isDocs) {
console.log('isDocs');
if (!document.body.classList.contains(`theme-${$currentTheme}`)) {
console.log('set 123');
applyTheme($currentTheme);
}
} else {
applyTheme('dark');
}
});
});
</script> </script>
<svelte:head> <svelte:head>