feat(theme): add theme switching functionality with ModeSwitcher and ThemeProvider
This commit is contained in:
parent
398c56b38b
commit
8808b4fb9b
@ -23,6 +23,7 @@
|
|||||||
"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",
|
||||||
|
"next-themes": "^0.4.4",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"tailwind-merge": "^2.5.5",
|
"tailwind-merge": "^2.5.5",
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
import { SessionProvider } from "next-auth/react";
|
import { SessionProvider } from "next-auth/react";
|
||||||
import { AppSidebar } from "@/components/app-sidebar";
|
import { AppSidebar } from "@/components/app-sidebar";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { ModeSwitcher } from "@/components/mode-switcher";
|
||||||
import ConfirmationDialog from "@/dialogs/ConfirmationDialog";
|
import ConfirmationDialog from "@/dialogs/ConfirmationDialog";
|
||||||
|
|
||||||
export default function DashboardLayout({
|
export default function DashboardLayout({
|
||||||
@ -27,6 +28,7 @@ export default function DashboardLayout({
|
|||||||
<header className="flex h-16 shrink-0 items-center gap-2">
|
<header className="flex h-16 shrink-0 items-center gap-2">
|
||||||
<div className="flex items-center gap-2 px-4">
|
<div className="flex items-center gap-2 px-4">
|
||||||
<SidebarTrigger className="-ml-1" />
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<ModeSwitcher />
|
||||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<BreadcrumbList>
|
<BreadcrumbList>
|
||||||
|
@ -2,6 +2,7 @@ import "@/app/globals.css";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });
|
const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });
|
||||||
|
|
||||||
@ -21,7 +22,14 @@ export default function RootLayout({
|
|||||||
<body
|
<body
|
||||||
className={cn("font-sans antialiased flex min-h-full", inter.variable)}
|
className={cn("font-sans antialiased flex min-h-full", inter.variable)}
|
||||||
>
|
>
|
||||||
<div className="w-full">{children}</div>
|
<ThemeProvider
|
||||||
|
attribute="class"
|
||||||
|
defaultTheme="system"
|
||||||
|
enableSystem
|
||||||
|
disableTransitionOnChange
|
||||||
|
>
|
||||||
|
<div className="w-full">{children}</div>
|
||||||
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
26
src/components/mode-switcher.tsx
Normal file
26
src/components/mode-switcher.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { Sun, Moon } from "lucide-react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
export function ModeSwitcher() {
|
||||||
|
const { setTheme, resolvedTheme } = useTheme();
|
||||||
|
|
||||||
|
const toggleTheme = React.useCallback(() => {
|
||||||
|
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
||||||
|
}, [resolvedTheme, setTheme]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="group/toggle h-8 w-8 px-0"
|
||||||
|
onClick={toggleTheme}
|
||||||
|
>
|
||||||
|
<Sun className="hidden [html.dark_&]:block" />
|
||||||
|
<Moon className="hidden [html.light_&]:block" />
|
||||||
|
<span className="sr-only">Toggle theme</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
11
src/components/theme-provider.tsx
Normal file
11
src/components/theme-provider.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
|
|
||||||
|
export function ThemeProvider({
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof NextThemesProvider>) {
|
||||||
|
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user