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?: {