feat: complete header and footer components and dark/light mode switching function
This commit is contained in:
parent
51e76a3b99
commit
e5b8bd7ab0
16 changed files with 234 additions and 19 deletions
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
|
|
@ -1,4 +1,8 @@
|
|||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"recommendations": [
|
||||
"astro-build.astro-vscode",
|
||||
"esbenp.prettier-vscode",
|
||||
"dbaeumer.vscode-eslint"
|
||||
],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
|
|
|
|||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[astro]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "always"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"astro": "^5.0.0-beta.10",
|
||||
"lucide-react": "^0.461.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"tailwindcss": "^3.4.15",
|
||||
|
|
|
|||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
|
|
@ -26,6 +26,9 @@ importers:
|
|||
astro:
|
||||
specifier: ^5.0.0-beta.10
|
||||
version: 5.0.0-beta.10(jiti@1.21.6)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1)
|
||||
lucide-react:
|
||||
specifier: ^0.461.0
|
||||
version: 0.461.0(react@18.3.1)
|
||||
react:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
|
|
@ -1991,6 +1994,11 @@ packages:
|
|||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
lucide-react@0.461.0:
|
||||
resolution: {integrity: sha512-Scpw3D/dV1bgVRC5Kh774RCm99z0iZpPv75M6kg7QL1lLvkQ1rmI1Sjjic1aGp1ULBwd7FokV6ry0g+d6pMB+w==}
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc
|
||||
|
||||
magic-string@0.30.14:
|
||||
resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==}
|
||||
|
||||
|
|
@ -5297,6 +5305,10 @@ snapshots:
|
|||
dependencies:
|
||||
yallist: 3.1.1
|
||||
|
||||
lucide-react@0.461.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
magic-string@0.30.14:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
|
|
|||
22
src/components/astro/footer.astro
Normal file
22
src/components/astro/footer.astro
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<div class="my-10 flex flex-col md:flex-row">
|
||||
<p>
|
||||
© {new Date().getFullYear()}
|
||||
</p>
|
||||
<p class="mx-1 hidden md:block">|</p>
|
||||
<p class="mr-1">Designed By</p>
|
||||
<a href="https://sunguoqi.com" class="text-blue-500 hover:underline">
|
||||
Guoqi Sun
|
||||
</a>
|
||||
<p class="mx-1 hidden md:block">|</p>
|
||||
<p class="mr-1">Powered By</p>
|
||||
<a
|
||||
href="https://github.com/sun0225SUN/astro-air"
|
||||
class="text-blue-500 hover:underline"
|
||||
>
|
||||
Astro Air
|
||||
</a>
|
||||
</div>
|
||||
17
src/components/astro/header.astro
Normal file
17
src/components/astro/header.astro
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
import { Rss } from "lucide-react"
|
||||
import ThemeToggle from "~/components/astro/theme-toggle.astro"
|
||||
import { site } from "~/config"
|
||||
---
|
||||
|
||||
<header class="flex h-20 w-full items-center justify-between">
|
||||
<a href="/">
|
||||
<div class="text-xl font-semibold">{site.name}</div>
|
||||
</a>
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="/atom.xml" target="_blank">
|
||||
<Rss />
|
||||
</a>
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</header>
|
||||
57
src/components/astro/theme-toggle.astro
Normal file
57
src/components/astro/theme-toggle.astro
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
import { Moon, Sun } from "lucide-react"
|
||||
---
|
||||
|
||||
<button id="themeToggle">
|
||||
<Sun className="dark:hidden" />
|
||||
<Moon className="hidden dark:block" />
|
||||
</button>
|
||||
|
||||
<script>
|
||||
// check current theme
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
|
||||
return localStorage.getItem("theme")
|
||||
}
|
||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return "dark"
|
||||
}
|
||||
return "light"
|
||||
})()
|
||||
|
||||
// set theme
|
||||
if (theme === "light") {
|
||||
document.documentElement.classList.remove("dark")
|
||||
} else {
|
||||
document.documentElement.classList.add("dark")
|
||||
}
|
||||
|
||||
// save theme
|
||||
window.localStorage.setItem("theme", theme!)
|
||||
|
||||
// update theme
|
||||
const updateTheme = () => {
|
||||
const isDark = document.documentElement.classList.contains("dark")
|
||||
localStorage.setItem("theme", isDark ? "dark" : "light")
|
||||
}
|
||||
|
||||
// toggle theme
|
||||
const handleToggleClick = () => {
|
||||
const element = document.documentElement
|
||||
|
||||
if (!document.startViewTransition) {
|
||||
element.classList.toggle("dark")
|
||||
updateTheme()
|
||||
return
|
||||
}
|
||||
|
||||
document.startViewTransition(() => {
|
||||
element.classList.toggle("dark")
|
||||
updateTheme()
|
||||
})
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("themeToggle")!
|
||||
.addEventListener("click", handleToggleClick)
|
||||
</script>
|
||||
28
src/config.ts
Normal file
28
src/config.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
export const site = {
|
||||
name: "小孙同学",
|
||||
favicon: "/avatar.png",
|
||||
title: "小孙同学",
|
||||
url: "https://blog.sunguoqi.com",
|
||||
slogan: "一个浪漫的理性主义者",
|
||||
description:
|
||||
"🖥️ 前端小学生(React)|📸 摄影爱好者(Nikon Zfc)|🛸 旅行探索家(体验派)|🚴 骑行蹭风选手( Java 鱼雷 6-top )|🍎 科技产品发烧友(苹果&小米)<br/><br/> ✨ 路虽远行则将至,事虽难做则必成。热爱可抵岁月漫长。山高路远,独善其身,看世界,也找自己。希望能成为一个有趣的人~",
|
||||
}
|
||||
|
||||
export const tabs = [
|
||||
// {
|
||||
// label: "归档",
|
||||
// link: "./archive",
|
||||
// },
|
||||
// {
|
||||
// label: "标签",
|
||||
// link: "./tags",
|
||||
// },
|
||||
{
|
||||
label: "影集",
|
||||
link: "https://camlife.cn",
|
||||
},
|
||||
{
|
||||
label: "关于",
|
||||
link: "https://sunguoqi.com",
|
||||
},
|
||||
]
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>Astro Basics</title>
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
42
src/layouts/base.astro
Normal file
42
src/layouts/base.astro
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
import "~/styles/globals.css"
|
||||
import { site } from "~/config"
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href={site.favicon} />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{site.title} - {site.slogan}</title>
|
||||
<meta name="description" content={site.description} />
|
||||
<script is:inline>
|
||||
// set theme before page load
|
||||
const theme = (() => {
|
||||
if (
|
||||
typeof localStorage !== "undefined" &&
|
||||
localStorage.getItem("theme")
|
||||
) {
|
||||
return localStorage.getItem("theme")
|
||||
}
|
||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return "dark"
|
||||
}
|
||||
return "light"
|
||||
})()
|
||||
|
||||
if (theme === "dark") {
|
||||
document.documentElement.classList.add("dark")
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
class="flex min-h-screen w-full justify-center dark:bg-[#121212] dark:text-white"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
9
src/layouts/home.astro
Normal file
9
src/layouts/home.astro
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import BaseLayout from "./base.astro"
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<main class="max-auto w-full max-w-3xl">
|
||||
<slot />
|
||||
</main>
|
||||
</BaseLayout>
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
---
|
||||
import Layout from "../layouts/layout.astro"
|
||||
import { Test } from "../components/test"
|
||||
import Footer from "~/components/astro/footer.astro"
|
||||
import Header from "~/components/astro/header.astro"
|
||||
import { Test } from "../components/react/test"
|
||||
import HomeLayout from "../layouts/home.astro"
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<HomeLayout>
|
||||
<Header />
|
||||
<Test />
|
||||
</Layout>
|
||||
<Footer />
|
||||
</HomeLayout>
|
||||
|
|
|
|||
27
src/styles/globals.css
Normal file
27
src/styles/globals.css
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* Theme toggle effect */
|
||||
/* https://theme-toggle.rdsx.dev/ */
|
||||
/* https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API */
|
||||
::view-transition-group(root) {
|
||||
animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><filter id="blur"><feGaussianBlur stdDeviation="2"/></filter></defs><circle cx="0" cy="0" r="18" fill="white" filter="url(%23blur)"/></svg>')
|
||||
top left / 0 no-repeat;
|
||||
mask-origin: content-box;
|
||||
animation: scale 1s;
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
::view-transition-old(root),
|
||||
.dark::view-transition-old(root) {
|
||||
animation: scale 1s;
|
||||
transform-origin: top left;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@keyframes scale {
|
||||
to {
|
||||
mask-size: 350vmax;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||
darkMode: ["class"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react",
|
||||
|
||||
/* Path Aliases */
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue