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 '../styles/global.css';
import { Sprite } from 'astro-icon'; import { Sprite } from 'astro-icon';
import ThemeProvider from '../components/ThemeProvider.astro';
export interface Props { export interface Props {
title: string; title: string;
} }
@@ -10,10 +11,7 @@ const { title, frontmatter } = Astro.props;
--- ---
<!DOCTYPE html> <!DOCTYPE html>
<html <html lang="en" class="no-js box-border scroll-smooth">
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]"
>
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <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="manifest" href="/manifest.webmanifest" /> -->
<link <link
rel="preload"
href="/assets/fonts/secuela-regular-vf.woff2"
as="font" as="font"
type="font/woff2"
crossorigin crossorigin
href="/assets/fonts/secuela-regular-vf.woff2"
rel="preload"
type="font/woff2"
/> />
<link <link
rel="preload"
href="/assets/fonts/secuela-italic-vf.woff2"
as="font" as="font"
type="font/woff2"
crossorigin crossorigin
href="/assets/fonts/secuela-italic-vf.woff2"
rel="preload"
type="font/woff2"
/> />
<ThemeProvider />
</head> </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> <Sprite.Provider>
<header <header
class="page-header grid grid-cols-18 grid-rows-layout mbe-layout print:hidden" 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
</footer> </footer>
</Sprite.Provider> </Sprite.Provider>
<style>
:global([astro-icon]) {
width: 24px;
height: 24px;
}
</style>
</body> </body>
</html> </html>
<style>
[astro-icon] {
width: 24px;
height: 24px;
}
</style>

View File

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

View File

@@ -1,6 +1,7 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
darkMode: 'class',
theme: { theme: {
extend: { extend: {
screens: { screens: {
@@ -10,6 +11,7 @@ module.exports = {
'3xl': '1800px', // --wide '3xl': '1800px', // --wide
}, },
colors: { colors: {
accent: '#e60510',
shibui: { shibui: {
50: '#f3f3f1', 50: '#f3f3f1',
100: '#e6e6e3', // bg (light), fg (dark, 0.87 alpha) 100: '#e6e6e3', // bg (light), fg (dark, 0.87 alpha)
@@ -40,6 +42,36 @@ module.exports = {
gridTemplateRows: ({ theme }) => ({ gridTemplateRows: ({ theme }) => ({
layout: `clamp(3rem, ${theme('spacing.55')}, 9rem)`, layout: `clamp(3rem, ${theme('spacing.55')}, 9rem)`,
}), }),
columns: {
13: '13',
14: '14',
15: '15',
16: '16',
17: '17',
18: '18',
},
gridColumn: {
'span-13': 'span 13 / span 13',
'span-14': 'span 14 / span 14',
'span-15': 'span 15 / span 15',
'span-16': 'span 16 / span 16',
'span-17': 'span 17 / span 17',
'span-18': 'span 18 / span 18',
},
gridColumnStart: {
14: '14',
15: '15',
16: '16',
17: '17',
18: '18',
},
gridColumnEnd: {
14: '14',
15: '15',
16: '16',
17: '17',
18: '18',
},
borderRadius: { borderRadius: {
1: '2px', // --radius-1 1: '2px', // --radius-1
2: '5px', // --radius-2 2: '5px', // --radius-2