Skip to content

Commit

Permalink
feat:#99 next-themes 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
frombozztoang committed Feb 27, 2024
1 parent dc8d2b8 commit f959d20
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 55 deletions.
7 changes: 1 addition & 6 deletions src/app/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
// Provider.tsx
'use client';
import { ThemeProvider } from 'next-themes';

const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<ThemeProvider enableSystem={true} attribute='class'>
{children}
</ThemeProvider>
);
return <ThemeProvider attribute='class'>{children}</ThemeProvider>;
};

export default Providers;
16 changes: 7 additions & 9 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const GA_ID = process.env.NEXT_PUBLIC_MEASUREMENT_ID;

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html suppressHydrationWarning lang='ko'>
<html lang='ko'>
<Head>
<script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`} />
<script
Expand All @@ -60,21 +60,19 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</Head>
{/* h-full -> scroll to top */}
<body className='h-full bg-bg dark:bg-dark-bg'>
{' '}
<QueryProvider>
{' '}
<NextThemeProvider>
<NextThemeProvider>
<QueryProvider>
<Header />
<main className='mt-100 tablet:mt-110 desktop:mt-200 min-h-screen px-24 tablet:px-0 box-border'>
{children}
</main>
<Chatbot />
<footer className='relative w-full mt-200'>
<footer className='relative w-screen mt-200'>
<Footer />
</footer>
<Chatbot />{' '}
</NextThemeProvider>
</QueryProvider>{' '}
<Chatbot />
</QueryProvider>
</NextThemeProvider>
</body>
</html>
);
Expand Down
39 changes: 17 additions & 22 deletions src/components/atom/header/HeaderSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,38 @@ import { cls } from '@/utils/cls';
import Light from '@/public/icons/light.svg';
import Dark from '@/public/icons/dark.svg';
import { useTheme } from 'next-themes';

export type THeaderSwitchProps = {
theme: string | undefined;
setTheme: (arg: string) => void;
};
import useThemeCheck from '@/hooks/useThemeCheck';

const HeaderSwitch = ({ ...props }) => {
const { systemTheme, theme, setTheme } = useTheme();
const currentTheme = theme === 'system' ? systemTheme : theme;
const { isDarkMode, toggleTheme } = useThemeCheck();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);

if (!mounted) {
// 클라이언트에서 마운트되지 않은 경우 UI를 렌더링하지 않음
return (
<div className='inline-block relative w-67 h-31 rounded-15 transition-colors duration-300 cursor-pointer bg-border02'></div>
);
}

const toggleTheme = () => {
if (currentTheme === 'light') {
setTheme('dark');
} else {
setTheme('light');
}
};
return (
<div
onClick={toggleTheme}
{...props}
className={cls(
'inline-block relative w-67 h-31 rounded-15 transition-colors duration-300 cursor-pointer',
currentTheme === 'dark' ? 'bg-border02' : ' bg-main',
'inline-block relative w-67 h-31 rounded-15 transition-all duration-300 cursor-pointer',
isDarkMode ? 'bg-border02' : ' bg-main',
)}
>
<div
className={cls(
'absolute bottom-3 left-6 w-25 h-25 rounded-15 duration-300',
currentTheme === 'dark' ? 'bg-main translate-x-[30px]' : ' bg-secondary translate-x-0',
isDarkMode ? 'bg-main translate-x-[30px]' : ' bg-secondary translate-x-0',
)}
></div>
{currentTheme === 'dark' ? (
<Dark className='absolute left-6 bottom-3' />
) : (
<Light className='absolute right-6 bottom-3' />
)}
{isDarkMode ? <Dark className='absolute left-6 bottom-3' /> : <Light className='absolute right-6 bottom-3' />}
</div>
);
};
Expand Down
52 changes: 34 additions & 18 deletions src/hooks/useThemeCheck.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
'use client';
import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react';

const UseThemeCheck = () => {
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);
const { theme, setTheme } = useTheme();
const [isDarkMode, setIsDarkMode] = useState(theme === 'dark');

useEffect(() => {
setIsDarkMode(theme === 'dark');
}, [theme]);

const toggleTheme = () => {
const theme = localStorage.getItem('theme');
setTheme(isDarkMode ? 'light' : 'dark');
};

setIsDarkMode(!isDarkMode);
return {
isDarkMode,
toggleTheme,
};
// const [isDarkMode, setIsDarkMode] = useState<boolean>(false);

useEffect(() => {
const storedTheme = localStorage.getItem('theme');
// const toggleTheme = () => {
// const theme = localStorage.getItem('theme');

// setIsDarkMode(!isDarkMode);
// };

// useEffect(() => {
// const storedTheme = localStorage.getItem('theme');

if (storedTheme === 'dark' || (!storedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
setIsDarkMode(true);
} else {
setIsDarkMode(false);
}
// if (storedTheme === 'dark' || (!storedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
// setIsDarkMode(true);
// } else {
// setIsDarkMode(false);
// }

// 추가: 다크모드 토글 이벤트 리스너 등록
window.addEventListener('darkModeToggle', toggleTheme);
// // 추가: 다크모드 토글 이벤트 리스너 등록
// window.addEventListener('darkModeToggle', toggleTheme);

return () => {
// 클린업: 컴포넌트 언마운트 시 리스너 제거
window.removeEventListener('darkModeToggle', toggleTheme);
};
}, [isDarkMode]);
// return () => {
// // 클린업: 컴포넌트 언마운트 시 리스너 제거
// window.removeEventListener('darkModeToggle', toggleTheme);
// };
// }, [isDarkMode]);

return isDarkMode;
// return isDarkMode;
};

export default UseThemeCheck;

0 comments on commit f959d20

Please sign in to comment.