fix: add viewTransitions to avoid flickering when switching
This commit is contained in:
parent
f431180328
commit
388d2c2ba7
6 changed files with 50 additions and 43 deletions
|
|
@ -12,4 +12,5 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
integrations: [react(), tailwind(), mdx()],
|
integrations: [react(), tailwind(), mdx()],
|
||||||
|
viewTransitions: true,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
14
src/components/astro/head/root.astro
Normal file
14
src/components/astro/head/root.astro
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
import { en, zh } from "~/config"
|
||||||
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
|
|
||||||
|
const lang = getLangFromUrl(Astro.url)
|
||||||
|
const config = lang === "zh" ? zh.meta : en.meta
|
||||||
|
---
|
||||||
|
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href={config.favicon} />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<title>{config.title} - {config.slogan}</title>
|
||||||
|
<meta name="description" content={config.description} />
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
import { Rss } from "lucide-react"
|
import { Rss } from "lucide-react"
|
||||||
import ThemeToggle from "~/components/astro/theme-toggle.astro"
|
|
||||||
import { LanguageToggle } from "~/components/react/language-toggle"
|
import { LanguageToggle } from "~/components/react/language-toggle"
|
||||||
|
import { ThemeToggle } from "~/components/react/theme-toggle"
|
||||||
import { en, zh } from "~/config"
|
import { en, zh } from "~/config"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
|
|
||||||
|
|
@ -31,6 +31,6 @@ const config = lang === "zh" ? zh : en
|
||||||
}
|
}
|
||||||
|
|
||||||
<LanguageToggle client:load />
|
<LanguageToggle client:load />
|
||||||
<ThemeToggle />
|
<ThemeToggle client:load />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export function NoiseBg() {
|
export function NoiseBackground() {
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 -z-10 h-full w-full bg-[url('https://framerusercontent.com/images/rR6HYXBrMmX4cRpXfXUOvpvpB0.png')] bg-[length:128px_128px] bg-repeat opacity-[0.06]"></div>
|
<div className="fixed inset-0 -z-10 h-full w-full bg-[url('https://framerusercontent.com/images/rR6HYXBrMmX4cRpXfXUOvpvpB0.png')] bg-[length:128px_128px] bg-repeat opacity-[0.06]"></div>
|
||||||
)
|
)
|
||||||
|
|
@ -1,23 +1,15 @@
|
||||||
---
|
|
||||||
import { Moon, Sun } from "lucide-react"
|
import { Moon, Sun } from "lucide-react"
|
||||||
---
|
|
||||||
|
|
||||||
<button id="themeToggle">
|
export function ThemeToggle() {
|
||||||
<Sun className="dark:hidden" />
|
|
||||||
<Moon className="hidden dark:block" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// update theme
|
|
||||||
const updateTheme = () => {
|
const updateTheme = () => {
|
||||||
const isDark = document.documentElement.classList.contains("dark")
|
const isDark = document.documentElement.classList.contains("dark")
|
||||||
localStorage.setItem("theme", isDark ? "dark" : "light")
|
localStorage.setItem("theme", isDark ? "dark" : "light")
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle theme
|
|
||||||
const handleToggleClick = () => {
|
const handleToggleClick = () => {
|
||||||
const element = document.documentElement
|
const element = document.documentElement
|
||||||
|
|
||||||
|
// if not supported, just toggle the theme
|
||||||
if (!document.startViewTransition) {
|
if (!document.startViewTransition) {
|
||||||
element.classList.toggle("dark")
|
element.classList.toggle("dark")
|
||||||
updateTheme()
|
updateTheme()
|
||||||
|
|
@ -30,7 +22,10 @@ import { Moon, Sun } from "lucide-react"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
document
|
return (
|
||||||
.getElementById("themeToggle")!
|
<button onClick={handleToggleClick}>
|
||||||
.addEventListener("click", handleToggleClick)
|
<Sun className="dark:hidden" />
|
||||||
</script>
|
<Moon className="hidden dark:block" />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,47 +1,44 @@
|
||||||
---
|
---
|
||||||
import "~/styles/globals.css"
|
import "~/styles/globals.css"
|
||||||
import { NoiseBg } from "~/components/react/noise-bg"
|
import { NoiseBackground } from "~/components/react/noise-background"
|
||||||
import { en, zh } from "~/config"
|
import { ClientRouter } from "astro:transitions"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
|
import Head from "~/components/astro/head/root.astro"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const config = lang === "zh" ? zh.meta : en.meta
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang={lang}>
|
<html lang={lang}>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<Head />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<ClientRouter />
|
||||||
<link rel="icon" type="image/svg+xml" href={config.favicon} />
|
|
||||||
<meta name="generator" content={Astro.generator} />
|
|
||||||
<title>{config.title} - {config.slogan}</title>
|
|
||||||
<meta name="description" content={config.description} />
|
|
||||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// set theme before page load
|
const setTheme = () => {
|
||||||
const theme = (() => {
|
const theme =
|
||||||
if (
|
localStorage.getItem("theme") ??
|
||||||
typeof localStorage !== "undefined" &&
|
(window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
localStorage.getItem("theme")
|
? "dark"
|
||||||
) {
|
: "light")
|
||||||
return localStorage.getItem("theme")
|
|
||||||
}
|
|
||||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark"
|
|
||||||
}
|
|
||||||
return "light"
|
|
||||||
})()
|
|
||||||
|
|
||||||
if (theme === "dark") {
|
if (theme === "dark") {
|
||||||
document.documentElement.classList.add("dark")
|
document.documentElement.classList.add("dark")
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme()
|
||||||
|
|
||||||
|
document.addEventListener("astro:page-load", () => {
|
||||||
|
setTheme()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="dark:bg-[#121212] dark:text-white">
|
<body class="dark:bg-[#121212] dark:text-white">
|
||||||
<div class="flex min-h-screen w-full justify-center px-6 md:p-0">
|
<div class="flex min-h-screen w-full justify-center px-6 md:p-0">
|
||||||
<slot />
|
<slot />
|
||||||
<NoiseBg />
|
<NoiseBackground />
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue