Add ThemeToggle component

This commit is contained in:
thiloho
2023-05-18 20:20:43 +02:00
parent 21437ae15d
commit 40411fd328
11 changed files with 139 additions and 9 deletions

View File

@@ -7,4 +7,4 @@ const articles = (await getCollection("blog")).sort(
);
---
<ArticleSearch client:load {articles} />
<ArticleSearch client:only="svelte" {articles} />

View File

@@ -1,7 +1,7 @@
<script lang="ts">
export let shortcut: string;
const possibleShortcuts = ["S", "T"];
const possibleShortcuts = ["S", "C", "T"];
let detailsElement: HTMLDetailsElement;
let summaryElement: HTMLElement;

View File

@@ -11,4 +11,8 @@ const { title, description } = Astro.props;
<title>{title}</title>
<meta name="author" content="Your Name" />
<meta name="description" content={description} />
<script is:inline>
const storedTheme = localStorage.getItem("theme");
document.documentElement.classList = storedTheme;
</script>
</head>

View File

@@ -1,5 +1,6 @@
---
import ArticleSearchWrapper from "../components/ArticleSearchWrapper.astro";
import ThemeToggle from "../components/ThemeToggle.svelte";
---
<nav>
@@ -9,6 +10,7 @@ import ArticleSearchWrapper from "../components/ArticleSearchWrapper.astro";
</a>
<slot />
<ArticleSearchWrapper />
<ThemeToggle client:only="svelte" />
</div>
</nav>

View File

@@ -4,19 +4,17 @@
export let headings: MarkdownHeading[] = [];
import Dropdown from "./Dropdown.svelte";
let dropdown;
</script>
<Dropdown shortcut="T" bind:this={dropdown}>
<Dropdown shortcut="C">
<svg slot="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<title>Table of contents (Shift + t)</title>
<title>Table of contents (Shift + c)</title>
<path fill-rule="evenodd" d="M2.625 6.75a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0zm4.875 0A.75.75 0 018.25 6h12a.75.75 0 010 1.5h-12a.75.75 0 01-.75-.75zM2.625 12a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0zM7.5 12a.75.75 0 01.75-.75h12a.75.75 0 010 1.5h-12A.75.75 0 017.5 12zm-4.875 5.25a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0zm4.875 0a.75.75 0 01.75-.75h12a.75.75 0 010 1.5h-12a.75.75 0 01-.75-.75z" clip-rule="evenodd" />
</svg>
<ul>
{#each headings.filter(({ depth }) => depth === 2) as { slug, text }}
<li>
<a href="#{slug}" on:click={dropdown.closeMenu}>{text}</a>
<a href="#{slug}">{text}</a>
</li>
{/each}
</ul>

View File

@@ -0,0 +1,47 @@
<script lang="ts">
import Dropdown from "./Dropdown.svelte";
let themeOptions = ["System", "Light", "Dark"];
let theme = "System";
function loadTheme() {
theme = localStorage.getItem("theme");
}
function saveTheme() {
localStorage.setItem("theme", theme);
}
loadTheme();
$: document.documentElement.classList = theme;
</script>
<Dropdown shortcut="T">
<svg slot="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<title>Toggle theme (Shift + t)</title>
<path fill-rule="evenodd" d="M2.25 5.25a3 3 0 013-3h13.5a3 3 0 013 3V15a3 3 0 01-3 3h-3v.257c0 .597.237 1.17.659 1.591l.621.622a.75.75 0 01-.53 1.28h-9a.75.75 0 01-.53-1.28l.621-.622a2.25 2.25 0 00.659-1.59V18h-3a3 3 0 01-3-3V5.25zm1.5 0v7.5a1.5 1.5 0 001.5 1.5h13.5a1.5 1.5 0 001.5-1.5v-7.5a1.5 1.5 0 00-1.5-1.5H5.25a1.5 1.5 0 00-1.5 1.5z" clip-rule="evenodd" />
</svg>
<div class="theme-toggle">
{#each themeOptions as option, index}
<div>
<input type="radio" id="theme-{option}" name="theme" value={option} bind:group={theme} on:change={saveTheme} />
<label for="theme-{option}">{option}</label>
</div>
{/each}
</div>
</Dropdown>
<style>
.theme-toggle {
position: absolute;
inset-inline-end: 0;
inset-block-start: var(--nav-height);
background-color: var(--background-color);
border: var(--standard-border);
padding: 1rem;
display: grid;
gap: 0.5rem;
}
</style>