feat(theme): add meta color management and integrate Jotai for theme switching

This commit is contained in:
ngc2207 2024-12-09 20:38:08 +08:00
parent ed547464c1
commit 93798b5a7e
6 changed files with 48 additions and 2 deletions

View File

@ -20,6 +20,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"gitea-js": "^1.22.0",
"jotai": "^2.10.3",
"lucide-react": "^0.468.0",
"next": "15.0.4",
"next-auth": "^5.0.0-beta.25",

View File

@ -27,6 +27,7 @@ export default function RootLayout({
defaultTheme="system"
enableSystem
disableTransitionOnChange
enableColorScheme
>
<div className="w-full">{children}</div>
</ThemeProvider>

View File

@ -7,13 +7,21 @@ import * as React from "react";
import { useTheme } from "next-themes";
import { Sun, Moon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { META_THEME_COLORS } from "@/config/site";
import { useMetaColor } from "@/hooks/use-meta-color";
export function ModeSwitcher() {
const { setMetaColor } = useMetaColor();
const { setTheme, resolvedTheme } = useTheme();
const toggleTheme = React.useCallback(() => {
setTheme(resolvedTheme === "dark" ? "light" : "dark");
}, [resolvedTheme, setTheme]);
setMetaColor(
resolvedTheme === "dark"
? META_THEME_COLORS.light
: META_THEME_COLORS.dark
);
}, [resolvedTheme, setTheme, setMetaColor]);
return (
<Button

View File

@ -4,11 +4,19 @@
"use client";
import * as React from "react";
import { Provider as JotaiProvider } from "jotai";
import { TooltipProvider } from "@/components/ui/tooltip";
import { ThemeProvider as NextThemesProvider } from "next-themes";
export function ThemeProvider({
children,
...props
}: React.ComponentProps<typeof NextThemesProvider>) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
return (
<JotaiProvider>
<NextThemesProvider {...props}>
<TooltipProvider delayDuration={0}>{children}</TooltipProvider>
</NextThemesProvider>
</JotaiProvider>
);
}

4
src/config/site.ts Normal file
View File

@ -0,0 +1,4 @@
export const META_THEME_COLORS = {
light: "#ffffff",
dark: "#09090b",
}

View File

@ -0,0 +1,24 @@
import * as React from "react";
import { useTheme } from "next-themes";
import { META_THEME_COLORS } from "@/config/site";
export function useMetaColor() {
const { resolvedTheme } = useTheme();
const metaColor = React.useMemo(() => {
return resolvedTheme !== "dark"
? META_THEME_COLORS.light
: META_THEME_COLORS.dark;
}, [resolvedTheme]);
const setMetaColor = React.useCallback((color: string) => {
document
.querySelector('meta[name="theme-color"]')
?.setAttribute("content", color);
}, []);
return {
metaColor,
setMetaColor,
};
}