mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-16 05:04:41 +08:00
first commit
This commit is contained in:
70
src/components/ThemeToggle.tsx
Normal file
70
src/components/ThemeToggle.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any,react-hooks/exhaustive-deps */
|
||||
|
||||
'use client';
|
||||
|
||||
import { Moon, Sun } from 'lucide-react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function ThemeToggle() {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const { setTheme, resolvedTheme } = useTheme();
|
||||
const pathname = usePathname();
|
||||
|
||||
const setThemeColor = (theme?: string) => {
|
||||
const meta = document.querySelector('meta[name="theme-color"]');
|
||||
if (!meta) {
|
||||
const meta = document.createElement('meta');
|
||||
meta.name = 'theme-color';
|
||||
meta.content = theme === 'dark' ? '#0c111c' : '#f9fbfe';
|
||||
document.head.appendChild(meta);
|
||||
} else {
|
||||
meta.setAttribute('content', theme === 'dark' ? '#0c111c' : '#f9fbfe');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
// 监听主题变化和路由变化,确保主题色始终同步
|
||||
useEffect(() => {
|
||||
if (mounted) {
|
||||
setThemeColor(resolvedTheme);
|
||||
}
|
||||
}, [mounted, resolvedTheme, pathname]);
|
||||
|
||||
if (!mounted) {
|
||||
// 渲染一个占位符以避免布局偏移
|
||||
return <div className='w-10 h-10' />;
|
||||
}
|
||||
|
||||
const toggleTheme = () => {
|
||||
// 检查浏览器是否支持 View Transitions API
|
||||
const targetTheme = resolvedTheme === 'dark' ? 'light' : 'dark';
|
||||
setThemeColor(targetTheme);
|
||||
if (!(document as any).startViewTransition) {
|
||||
setTheme(targetTheme);
|
||||
return;
|
||||
}
|
||||
|
||||
(document as any).startViewTransition(() => {
|
||||
setTheme(targetTheme);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className='w-10 h-10 p-2 rounded-full flex items-center justify-center text-gray-600 hover:bg-gray-200/50 dark:text-gray-300 dark:hover:bg-gray-700/50 transition-colors'
|
||||
aria-label='Toggle theme'
|
||||
>
|
||||
{resolvedTheme === 'dark' ? (
|
||||
<Sun className='w-full h-full' />
|
||||
) : (
|
||||
<Moon className='w-full h-full' />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user