mirror of
				https://github.com/ItzCrazyKns/Perplexica.git
				synced 2025-11-04 12:48:14 +00:00 
			
		
		
		
	feat: setup theme context config
This commit is contained in:
		@@ -4,6 +4,7 @@ import './globals.css';
 | 
			
		||||
import { cn } from '@/lib/utils';
 | 
			
		||||
import Sidebar from '@/components/Sidebar';
 | 
			
		||||
import { Toaster } from 'sonner';
 | 
			
		||||
import { ThemeProviderComponent } from '@/components/theme/Provider';
 | 
			
		||||
 | 
			
		||||
const montserrat = Montserrat({
 | 
			
		||||
  weight: ['300', '400', '500', '700'],
 | 
			
		||||
@@ -24,18 +25,20 @@ export default function RootLayout({
 | 
			
		||||
  children: React.ReactNode;
 | 
			
		||||
}>) {
 | 
			
		||||
  return (
 | 
			
		||||
    <html className="h-full" lang="en">
 | 
			
		||||
    <html className="h-full" lang="en" suppressHydrationWarning>
 | 
			
		||||
      <body className={cn('h-full', montserrat.className)}>
 | 
			
		||||
        <Sidebar>{children}</Sidebar>
 | 
			
		||||
        <Toaster
 | 
			
		||||
          toastOptions={{
 | 
			
		||||
            unstyled: true,
 | 
			
		||||
            classNames: {
 | 
			
		||||
              toast:
 | 
			
		||||
                'bg-[#111111] text-white rounded-lg p-4 flex flex-row items-center space-x-2',
 | 
			
		||||
            },
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
        <ThemeProviderComponent>
 | 
			
		||||
          <Sidebar>{children}</Sidebar>
 | 
			
		||||
          <Toaster
 | 
			
		||||
            toastOptions={{
 | 
			
		||||
              unstyled: true,
 | 
			
		||||
              classNames: {
 | 
			
		||||
                toast:
 | 
			
		||||
                  'dark:dark:bg-[#111111] text-white rounded-lg p-4 flex flex-row items-center space-x-2',
 | 
			
		||||
              },
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </ThemeProviderComponent>
 | 
			
		||||
      </body>
 | 
			
		||||
    </html>
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								ui/components/theme/Provider.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								ui/components/theme/Provider.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
'use client';
 | 
			
		||||
import { ThemeProvider } from 'next-themes';
 | 
			
		||||
 | 
			
		||||
export function ThemeProviderComponent({
 | 
			
		||||
  children,
 | 
			
		||||
}: {
 | 
			
		||||
  children: React.ReactNode;
 | 
			
		||||
}) {
 | 
			
		||||
  return (
 | 
			
		||||
    <ThemeProvider attribute="class" enableSystem={false} defaultTheme="dark">
 | 
			
		||||
      {children}
 | 
			
		||||
    </ThemeProvider>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								ui/components/theme/Switcher.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								ui/components/theme/Switcher.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
'use client';
 | 
			
		||||
import { useTheme } from 'next-themes';
 | 
			
		||||
import { SunIcon, MoonIcon, MonitorIcon } from 'lucide-react';
 | 
			
		||||
import { useCallback, useEffect, useState } from 'react';
 | 
			
		||||
 | 
			
		||||
type Theme = 'dark' | 'light' | 'system';
 | 
			
		||||
 | 
			
		||||
export function ThemeSwitcher() {
 | 
			
		||||
  const [mounted, setMounted] = useState(false);
 | 
			
		||||
 | 
			
		||||
  const { theme, setTheme } = useTheme();
 | 
			
		||||
 | 
			
		||||
  const isTheme = useCallback((t: Theme) => t === theme, [theme]);
 | 
			
		||||
 | 
			
		||||
  const handleThemeSwitch = (theme: Theme) => {
 | 
			
		||||
    setTheme(theme);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setMounted(true);
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (isTheme('system')) {
 | 
			
		||||
      const preferDarkScheme = window.matchMedia(
 | 
			
		||||
        '(prefers-color-scheme: dark)',
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      const detectThemeChange = (event: MediaQueryListEvent) => {
 | 
			
		||||
        const theme: Theme = event.matches ? 'dark' : 'light';
 | 
			
		||||
        setTheme(theme);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      preferDarkScheme.addEventListener('change', detectThemeChange);
 | 
			
		||||
 | 
			
		||||
      return () => {
 | 
			
		||||
        preferDarkScheme.removeEventListener('change', detectThemeChange);
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }, [isTheme, setTheme, theme]);
 | 
			
		||||
 | 
			
		||||
  // Avoid Hydration Mismatch
 | 
			
		||||
  if (!mounted) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return isTheme('dark') ? (
 | 
			
		||||
    <SunIcon
 | 
			
		||||
      className="cursor-pointer"
 | 
			
		||||
      onClick={() => handleThemeSwitch('light')}
 | 
			
		||||
    />
 | 
			
		||||
  ) : isTheme('light') ? (
 | 
			
		||||
    <MoonIcon
 | 
			
		||||
      className="cursor-pointer"
 | 
			
		||||
      onClick={() => handleThemeSwitch('dark')}
 | 
			
		||||
    />
 | 
			
		||||
  ) : (
 | 
			
		||||
    <MonitorIcon
 | 
			
		||||
      className="cursor-pointer"
 | 
			
		||||
      onClick={() => handleThemeSwitch('system')}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,7 @@ const config: Config = {
 | 
			
		||||
    './components/**/*.{js,ts,jsx,tsx,mdx}',
 | 
			
		||||
    './app/**/*.{js,ts,jsx,tsx,mdx}',
 | 
			
		||||
  ],
 | 
			
		||||
  darkMode: 'class',
 | 
			
		||||
  theme: {
 | 
			
		||||
    extend: {},
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user