From d599b3e26df0fb5c02a11f317e3e43c3d1a6837b Mon Sep 17 00:00:00 2001
From: radishzzz
Date: Mon, 20 Jan 2025 10:36:14 +0000
Subject: [PATCH] feat: add theme toggle for light/dark modes
---
public/image/moon.svg | 1 +
public/image/sun.svg | 1 +
src/components/Head.astro | 4 +--
src/components/ThemeToggle.astro | 62 ++++++++++++++++++++++++++++++++
src/config/index.ts | 18 +++++-----
src/layouts/Layout.astro | 15 ++++++--
src/pages/posts/[slug].astro | 6 +++-
src/styles/global.css | 32 +++++++++++++----
src/types/index.d.ts | 14 ++++----
9 files changed, 125 insertions(+), 28 deletions(-)
create mode 100644 public/image/moon.svg
create mode 100644 public/image/sun.svg
create mode 100644 src/components/ThemeToggle.astro
diff --git a/public/image/moon.svg b/public/image/moon.svg
new file mode 100644
index 0000000..6cc6f30
--- /dev/null
+++ b/public/image/moon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/image/sun.svg b/public/image/sun.svg
new file mode 100644
index 0000000..eb8a262
--- /dev/null
+++ b/public/image/sun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/Head.astro b/src/components/Head.astro
index 8f885e8..58a7d80 100644
--- a/src/components/Head.astro
+++ b/src/components/Head.astro
@@ -9,7 +9,7 @@ interface Props {
const { postTitle, postDescription, postImage } = Astro.props
const { title, subtitle, description, author, url, favicon } = themeConfig.site
-const { light: { backgroundTop: lightMode }, dark: { backgroundTop: darkMode } } = themeConfig.color
+const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
const { locale, moreLocale } = themeConfig.global
const { verification = {}, twitterID = '', facebookID = '', facebookLink = '', googleAnalyticsID = '', umamiAnalyticsID = '', siteScreenshot = '' } = themeConfig.seo ?? {}
const { google = '', bing = '', yandex = '', baidu = '' } = verification
@@ -23,7 +23,7 @@ const { cdn, commentURL = '', imageHostURL = '', customGoogleAnalyticsURL = '',
{favicon.toLowerCase().endsWith('.svg') && }
{favicon.toLowerCase().endsWith('.png') && }
-{postTitle ? `${postTitle} - ${title}` : `${title} - ${subtitle}`}
+{postTitle ? `${postTitle} | ${title}` : `${title} - ${subtitle}`}
diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro
new file mode 100644
index 0000000..f4e73c6
--- /dev/null
+++ b/src/components/ThemeToggle.astro
@@ -0,0 +1,62 @@
+
+
+
+
+
diff --git a/src/config/index.ts b/src/config/index.ts
index abeaa24..bb2bb15 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -3,27 +3,27 @@ import type { ThemeConfig } from '@/types'
export const themeConfig: ThemeConfig = {
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
site: {
- title: 'retypeset',
+ title: 'Retypeset',
subtitle: '再现版式之美',
description: '一个优美的博客主题',
author: 'radishzz',
url: 'https://retypeset.netlify.app',
- favicon: '/image/logo.svg', // or https://image.example.com/logo.svg support only webp, svg, png
+ favicon: '/image/logo.svg', // or https://image.example.com/logo.svg, support only webp, svg, png
},
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
// COLOR SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
color: {
- mode: 'light',
+ mode: 'dark', // light, dark, DEFAULT to match system theme
light: {
- text: '#232323',
- backgroundTop: '#f8f8f8',
- backgroundEnd: '#FDE9EB',
+ primary: '#505050', // title text color in light mode
+ secondary: '#17191A', // posts text color in light mode
+ background: '#F7EEEC', // background color in light mode
},
dark: {
- text: '#000000',
- backgroundTop: '#ffffff',
- backgroundEnd: '#000000',
+ primary: '#A0A09F', // title text color in dark mode
+ secondary: '#BEBEBE', // posts text color in dark mode
+ background: '#161616', // background color in dark mode
},
},
// COLOR SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index 153c71a..6c7432e 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -1,16 +1,27 @@
---
import Head from '@/components/Head.astro'
+import ThemeToggle from '@/components/ThemeToggle.astro'
import themeConfig from '@/config'
import '@/styles/global.css'
+interface Props {
+ postTitle?: string
+ postDescription?: string
+ postImage?: string
+}
+
+const { postTitle, postDescription, postImage } = Astro.props
+
const fontStyle = `font-${themeConfig.global.font}`
+const colorMode = themeConfig.color.mode
---
-
+
-
+
+
diff --git a/src/pages/posts/[slug].astro b/src/pages/posts/[slug].astro
index 28928f3..7576075 100644
--- a/src/pages/posts/[slug].astro
+++ b/src/pages/posts/[slug].astro
@@ -14,7 +14,11 @@ const { post } = Astro.props
const { Content } = await post.render()
---
-
+
{post.data.title}
diff --git a/src/styles/global.css b/src/styles/global.css
index a34b413..764000b 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -1,13 +1,13 @@
:root {
- --uno-colors-text: theme('colors.text');
- --uno-colors-backgroundTop: theme('colors.backgroundTop');
- --uno-colors-backgroundEnd: theme('colors.backgroundEnd');
+ --uno-colors-primary: theme('colors.primary');
+ --uno-colors-secondary: theme('colors.secondary');
+ --uno-colors-background: theme('colors.background');
}
html {
--at-apply: 'antialiased scroll-smooth text-62.5%';
}
body {
- --at-apply: 'min-h-screen min-h-dvh bg-gradient-to-b from-backgroundTop to-backgroundEnd bg-fixed overscroll-none text-1.6rem c-text';
+ --at-apply: 'bg-background min-h-dvh c-primary text-1.6rem';
}
h1, h2, h3 {
text-rendering: optimizeLegibility;
@@ -30,6 +30,24 @@ h5 {
h6 {
--at-apply: 'text-[1.6rem]';
}
-/* :where(p) {
- --at-apply: 'text-text/85';
-} */
+/* Horizontal reveal animation on theme toggle */
+@keyframes reveal {
+ from {
+ clip-path: inset(var(--from));
+ }
+}
+html.dark {
+ --from: 0 0 100% 0;
+}
+html:not(.dark) {
+ --from: 100% 0 0 0;
+}
+::view-transition-new(root) {
+ animation: reveal 1s cubic-bezier(0.4, 0, 0.2, 1);
+ clip-path: inset(0 0 0 0);
+ z-index: 2;
+}
+::view-transition-old(root) {
+ z-index: -1;
+ animation: none;
+}
diff --git a/src/types/index.d.ts b/src/types/index.d.ts
index 0bffa34..e1a6353 100644
--- a/src/types/index.d.ts
+++ b/src/types/index.d.ts
@@ -14,21 +14,21 @@ export interface ThemeConfig {
color: {
mode: 'light' | 'dark'
light: {
- text: string
- backgroundTop: string
- backgroundEnd: string
+ primary: string
+ secondary: string
+ background: string
}
dark: {
- text: string
- backgroundTop: string
- backgroundEnd: string
+ primary: string
+ secondary: string
+ background: string
}
}
global: {
locale: typeof langPath[number]
moreLocale: typeof langPath[number][]
- font: string
+ font: 'sans' | 'serif' | 'italic'
}
comment?: {