feat(astro): add theme provider for dark mode

This commit is contained in:
Stefan Imhoff
2023-02-23 19:51:50 +01:00
parent e2ccaf991f
commit ba21116210
4 changed files with 79 additions and 19 deletions

View File

@@ -0,0 +1,26 @@
---
---
<script is:inline>
const getThemePreference = () => {
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
return localStorage.getItem('theme');
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
const isDark = getThemePreference() === 'dark';
document.documentElement.classList[isDark ? 'add' : 'remove']('dark');
if (typeof localStorage !== 'undefined') {
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class'],
});
}
</script>

View File

@@ -2,6 +2,7 @@
import '../styles/global.css';
import { Sprite } from 'astro-icon';
import ThemeProvider from '../components/ThemeProvider.astro';
export interface Props {
title: string;
}
@@ -10,10 +11,7 @@ const { title, frontmatter } = Astro.props;
---
<!DOCTYPE html>
<html
lang="en"
class="no-js box-border scroll-smooth bg-shibui-100 text-[125%] text-shibui-950 dark:bg-shibui-900 dark:text-shibui-200/[0.87]"
>
<html lang="en" class="no-js box-border scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -33,21 +31,24 @@ const { title, frontmatter } = Astro.props;
<!-- <link rel="manifest" href="/manifest.webmanifest" /> -->
<link
rel="preload"
href="/assets/fonts/secuela-regular-vf.woff2"
as="font"
type="font/woff2"
crossorigin
href="/assets/fonts/secuela-regular-vf.woff2"
rel="preload"
type="font/woff2"
/>
<link
rel="preload"
href="/assets/fonts/secuela-italic-vf.woff2"
as="font"
type="font/woff2"
crossorigin
href="/assets/fonts/secuela-italic-vf.woff2"
rel="preload"
type="font/woff2"
/>
<ThemeProvider />
</head>
<body class="flex h-screen flex-col font-sans font-normal leading-relaxed">
<body
class="flex h-screen flex-col bg-shibui-100 font-sans text-[125%] font-normal leading-relaxed text-shibui-950 dark:bg-shibui-900 dark:text-shibui-200/[0.87]"
>
<Sprite.Provider>
<header
class="page-header grid grid-cols-18 grid-rows-layout mbe-layout print:hidden"
@@ -80,12 +81,11 @@ const { title, frontmatter } = Astro.props;
Footer
</footer>
</Sprite.Provider>
<style>
:global([astro-icon]) {
width: 24px;
height: 24px;
}
</style>
</body>
</html>
<style>
[astro-icon] {
width: 24px;
height: 24px;
}
</style>

View File

@@ -2,4 +2,6 @@
import Layout from '../layouts/Layout.astro';
---
<Layout title="Homepage">Homepage</Layout>
<Layout title="Homepage">
<h1>Homepage</h1>
</Layout>