refactor: 移除主题切换功能,统一使用明亮风格

- 从 Header 移除 ThemeToggle 组件
- 删除 theme-toggle.tsx 文件
- 简化 theme-context.tsx,只保留 light 主题~
This commit is contained in:
张翔
2026-02-23 08:04:50 +08:00
parent 5f0f642ab6
commit b32fcdbbdc
3 changed files with 14 additions and 112 deletions
+10 -16
View File
@@ -4,7 +4,6 @@ import { useState, useEffect, useCallback } from 'react';
import { Menu, X } from 'lucide-react'; import { Menu, X } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { ThemeToggle } from '@/components/ui/theme-toggle';
import { COMPANY_INFO, NAVIGATION } from '@/lib/constants'; import { COMPANY_INFO, NAVIGATION } from '@/lib/constants';
export function Header() { export function Header() {
@@ -64,7 +63,7 @@ export function Header() {
fixed top-0 left-0 right-0 z-50 fixed top-0 left-0 right-0 z-50
transition-all duration-300 ease-out transition-all duration-300 ease-out
${isScrolled ${isScrolled
? 'bg-[var(--color-bg-primary)]/80 backdrop-blur-xl border-b border-[var(--color-border-primary)] shadow-[0_4px_30px_rgba(0,217,255,0.1)]' ? 'bg-white/95 backdrop-blur-xl border-b border-[#E2E8F0] shadow-sm'
: 'bg-transparent' : 'bg-transparent'
} }
`} `}
@@ -93,8 +92,8 @@ export function Header() {
relative px-3 py-1.5 text-sm font-medium relative px-3 py-1.5 text-sm font-medium
transition-all duration-300 transition-all duration-300
${activeSection === item.id.replace('#', '') ${activeSection === item.id.replace('#', '')
? 'text-[var(--color-tech-blue)]' ? 'text-[#005EB8]'
: 'text-[var(--color-text-secondary)] hover:text-[var(--color-tech-blue)]' : 'text-[#4A5568] hover:text-[#005EB8]'
} }
`} `}
> >
@@ -102,7 +101,7 @@ export function Header() {
{activeSection === item.id.replace('#', '') && ( {activeSection === item.id.replace('#', '') && (
<motion.span <motion.span
layoutId="activeNav" layoutId="activeNav"
className="absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-gradient-to-r from-[var(--color-tech-blue)] to-[var(--color-tech-purple)] rounded-full" className="absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-[#005EB8] rounded-full"
transition={{ type: "spring", stiffness: 380, damping: 30 }} transition={{ type: "spring", stiffness: 380, damping: 30 }}
/> />
)} )}
@@ -111,7 +110,6 @@ export function Header() {
</nav> </nav>
<div className="hidden md:flex items-center gap-3"> <div className="hidden md:flex items-center gap-3">
<ThemeToggle />
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
@@ -138,7 +136,7 @@ export function Header() {
</div> </div>
<button <button
className="md:hidden p-2 -mr-2 text-[var(--color-text-secondary)] hover:text-[var(--color-tech-blue)] transition-colors" className="md:hidden p-2 -mr-2 text-[#4A5568] hover:text-[#005EB8] transition-colors"
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
> >
{isOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />} {isOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
@@ -156,7 +154,7 @@ export function Header() {
className="fixed inset-0 z-40 md:hidden" className="fixed inset-0 z-40 md:hidden"
> >
<div <div
className="absolute inset-0 bg-black/60 backdrop-blur-sm" className="absolute inset-0 bg-black/20 backdrop-blur-sm"
onClick={() => setIsOpen(false)} onClick={() => setIsOpen(false)}
/> />
<motion.div <motion.div
@@ -164,7 +162,7 @@ export function Header() {
animate={{ y: 0, opacity: 1 }} animate={{ y: 0, opacity: 1 }}
exit={{ y: -20, opacity: 0 }} exit={{ y: -20, opacity: 0 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }} transition={{ type: "spring", stiffness: 300, damping: 30 }}
className="absolute top-16 left-0 right-0 bg-[var(--color-bg-secondary)]/95 backdrop-blur-xl border-b border-[var(--color-border-primary)] shadow-[0_4px_30px_rgba(0,217,255,0.1)]" className="absolute top-16 left-0 right-0 bg-white/95 backdrop-blur-xl border-b border-[#E2E8F0] shadow-lg"
> >
<nav className="container-wide py-4"> <nav className="container-wide py-4">
{NAVIGATION.map((item, index) => ( {NAVIGATION.map((item, index) => (
@@ -180,19 +178,15 @@ export function Header() {
transition-all duration-300 transition-all duration-300
border-l-2 border-l-2
${activeSection === item.id.replace('#', '') ${activeSection === item.id.replace('#', '')
? 'text-[var(--color-tech-blue)] border-[var(--color-tech-blue)] bg-[rgba(0,217,255,0.1)]' ? 'text-[#005EB8] border-[#005EB8] bg-[#E8F4FD]'
: 'text-[var(--color-text-secondary)] border-transparent hover:text-[var(--color-tech-blue)] hover:bg-[rgba(255,255,255,0.05)]' : 'text-[#4A5568] border-transparent hover:text-[#005EB8] hover:bg-[#F5F7FA]'
} }
`} `}
> >
{item.label} {item.label}
</motion.a> </motion.a>
))} ))}
<div className="mt-4 px-4 pt-4 border-t border-[var(--color-border-primary)] space-y-3"> <div className="mt-4 px-4 pt-4 border-t border-[#E2E8F0] space-y-3">
<div className="flex items-center justify-between">
<span className="text-sm text-[var(--color-text-tertiary)]"></span>
<ThemeToggle />
</div>
<Button <Button
className="w-full" className="w-full"
onClick={() => { onClick={() => {
-44
View File
@@ -1,44 +0,0 @@
'use client';
import { useTheme } from '@/contexts/theme-context';
import { Moon, Sun, Monitor } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
export function ThemeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm" className="relative w-9 h-9 p-0">
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only"></span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
<Sun className="mr-2 h-4 w-4" />
<span></span>
{theme === 'light' && <span className="ml-auto text-[#C41E3A]"></span>}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
<Moon className="mr-2 h-4 w-4" />
<span></span>
{theme === 'dark' && <span className="ml-auto text-[#C41E3A]"></span>}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
<Monitor className="mr-2 h-4 w-4" />
<span></span>
{theme === 'system' && <span className="ml-auto text-[#C41E3A]"></span>}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
+4 -52
View File
@@ -1,65 +1,17 @@
'use client'; 'use client';
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'; import { createContext, useContext, type ReactNode } from 'react';
type Theme = 'light' | 'dark' | 'system';
interface ThemeContextType { interface ThemeContextType {
theme: Theme; theme: 'light';
setTheme: (theme: Theme) => void; resolvedTheme: 'light';
resolvedTheme: 'light' | 'dark';
} }
const ThemeContext = createContext<ThemeContextType | undefined>(undefined); const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
const THEME_STORAGE_KEY = 'ruixin-theme';
export function ThemeProvider({ children }: { children: ReactNode }) { export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setThemeState] = useState<Theme>('system');
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');
useEffect(() => {
const stored = localStorage.getItem(THEME_STORAGE_KEY) as Theme | null;
if (stored && ['light', 'dark', 'system'].includes(stored)) {
setThemeState(stored);
}
}, []);
useEffect(() => {
const root = document.documentElement;
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const updateTheme = () => {
let resolved: 'light' | 'dark';
if (theme === 'system') {
resolved = mediaQuery.matches ? 'dark' : 'light';
} else {
resolved = theme;
}
setResolvedTheme(resolved);
if (resolved === 'dark') {
root.classList.add('dark');
} else {
root.classList.remove('dark');
}
};
updateTheme();
mediaQuery.addEventListener('change', updateTheme);
return () => mediaQuery.removeEventListener('change', updateTheme);
}, [theme]);
const setTheme = (newTheme: Theme) => {
setThemeState(newTheme);
localStorage.setItem(THEME_STORAGE_KEY, newTheme);
};
return ( return (
<ThemeContext.Provider value={{ theme, setTheme, resolvedTheme }}> <ThemeContext.Provider value={{ theme: 'light', resolvedTheme: 'light' }}>
{children} {children}
</ThemeContext.Provider> </ThemeContext.Provider>
); );