mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-17 03:56:19 +02:00
feat: add theme toggle for light/dark modes
This commit is contained in:
parent
d148649454
commit
d599b3e26d
9 changed files with 125 additions and 28 deletions
|
@ -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') && <link rel="icon" type="image/svg+xml" href={favicon} />}
|
||||
{favicon.toLowerCase().endsWith('.png') && <link rel="icon" type="image/png" href={favicon} />}
|
||||
|
||||
<title>{postTitle ? `${postTitle} - ${title}` : `${title} - ${subtitle}`}</title>
|
||||
<title>{postTitle ? `${postTitle} | ${title}` : `${title} - ${subtitle}`}</title>
|
||||
<meta name="description" content={postDescription || description} />
|
||||
<meta name="author" content={author} />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
|
|
62
src/components/ThemeToggle.astro
Normal file
62
src/components/ThemeToggle.astro
Normal file
|
@ -0,0 +1,62 @@
|
|||
<button
|
||||
aria-pressed="false"
|
||||
aria-label="Theme Toggle Button"
|
||||
class="fixed right-10 top-10 z-999 aspect-square w-8 text-secondary"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="moon-icon" fill="currentColor">
|
||||
<g>
|
||||
<path d="m11.64 12.36c-3.6-3.6-4.14-8.89-2.8-10.66-2.39 1.75-1.88 7.86 1.86 11.6s9.86 4.28 11.6 1.86c-1.77 1.34-7.06.8-10.66-2.8" />
|
||||
<path d="m5.22 4.01a10 10 0 0 1 3.54-2.28c-2.02.47-3.24 1.19-4.54 2.49-4.3 4.3-4.3 11.26 0 15.55 4.29 4.29 11.26 4.3 15.55 0 1.3-1.3 2.27-2.68 2.51-4.6a9.8 9.8 0 0 1 -2.3 3.6c-3.96 3.96-10.48 3.86-14.56-.21-4.08-4.08-4.18-10.6-.21-14.56z" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="sun-icon" fill="currentColor">
|
||||
<path d="m4.22 4.22c-4.3 4.3-4.3 11.26 0 15.56s11.26 4.3 15.56 0 4.3-11.26 0-15.56-11.26-4.3-15.56 0m15.17 15.17c-3.63 3.63-9.88 3.26-13.96-.82s-4.45-10.33-.82-13.96 9.88-3.26 13.96.82 4.45 10.33.82 13.96" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<script>
|
||||
declare global {
|
||||
interface Document {
|
||||
startViewTransition: (callback: () => void) => void
|
||||
}
|
||||
}
|
||||
|
||||
const TOGGLE = document.querySelector('button[aria-pressed]') as HTMLButtonElement
|
||||
if (!TOGGLE)
|
||||
throw new Error('Theme toggle button not found')
|
||||
|
||||
const defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const savedTheme = localStorage.getItem('theme')
|
||||
const initialTheme = savedTheme || (defaultDark ? 'dark' : 'light')
|
||||
|
||||
TOGGLE.setAttribute('aria-pressed', initialTheme === 'dark' ? 'true' : 'false')
|
||||
document.documentElement.classList.toggle('dark', initialTheme === 'dark')
|
||||
|
||||
function SWITCH() {
|
||||
const isDark = !TOGGLE.matches('[aria-pressed=true]')
|
||||
TOGGLE.setAttribute('aria-pressed', String(isDark))
|
||||
const newTheme = isDark ? 'dark' : 'light'
|
||||
document.documentElement.classList.toggle('dark', isDark)
|
||||
localStorage.setItem('theme', newTheme)
|
||||
}
|
||||
|
||||
function TOGGLE_THEME() {
|
||||
if (!document.startViewTransition) {
|
||||
SWITCH()
|
||||
return
|
||||
}
|
||||
document.startViewTransition(SWITCH)
|
||||
}
|
||||
|
||||
TOGGLE.addEventListener('click', TOGGLE_THEME)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
[aria-pressed='true'] .moon-icon,
|
||||
.sun-icon {
|
||||
display: none;
|
||||
}
|
||||
[aria-pressed='true'] .sun-icon {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue