feat(theme): add meta color management and integrate Jotai for theme switching
This commit is contained in:
parent
ed547464c1
commit
93798b5a7e
@ -20,6 +20,7 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"gitea-js": "^1.22.0",
|
"gitea-js": "^1.22.0",
|
||||||
|
"jotai": "^2.10.3",
|
||||||
"lucide-react": "^0.468.0",
|
"lucide-react": "^0.468.0",
|
||||||
"next": "15.0.4",
|
"next": "15.0.4",
|
||||||
"next-auth": "^5.0.0-beta.25",
|
"next-auth": "^5.0.0-beta.25",
|
||||||
|
@ -27,6 +27,7 @@ export default function RootLayout({
|
|||||||
defaultTheme="system"
|
defaultTheme="system"
|
||||||
enableSystem
|
enableSystem
|
||||||
disableTransitionOnChange
|
disableTransitionOnChange
|
||||||
|
enableColorScheme
|
||||||
>
|
>
|
||||||
<div className="w-full">{children}</div>
|
<div className="w-full">{children}</div>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
@ -7,13 +7,21 @@ import * as React from "react";
|
|||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
import { Sun, Moon } from "lucide-react";
|
import { Sun, Moon } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { META_THEME_COLORS } from "@/config/site";
|
||||||
|
import { useMetaColor } from "@/hooks/use-meta-color";
|
||||||
|
|
||||||
export function ModeSwitcher() {
|
export function ModeSwitcher() {
|
||||||
|
const { setMetaColor } = useMetaColor();
|
||||||
const { setTheme, resolvedTheme } = useTheme();
|
const { setTheme, resolvedTheme } = useTheme();
|
||||||
|
|
||||||
const toggleTheme = React.useCallback(() => {
|
const toggleTheme = React.useCallback(() => {
|
||||||
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
||||||
}, [resolvedTheme, setTheme]);
|
setMetaColor(
|
||||||
|
resolvedTheme === "dark"
|
||||||
|
? META_THEME_COLORS.light
|
||||||
|
: META_THEME_COLORS.dark
|
||||||
|
);
|
||||||
|
}, [resolvedTheme, setTheme, setMetaColor]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
@ -4,11 +4,19 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { Provider as JotaiProvider } from "jotai";
|
||||||
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
|
|
||||||
export function ThemeProvider({
|
export function ThemeProvider({
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: React.ComponentProps<typeof NextThemesProvider>) {
|
}: 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
4
src/config/site.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export const META_THEME_COLORS = {
|
||||||
|
light: "#ffffff",
|
||||||
|
dark: "#09090b",
|
||||||
|
}
|
24
src/hooks/use-meta-color.ts
Normal file
24
src/hooks/use-meta-color.ts
Normal 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,
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user