Radiation-map 프로젝트를 진행하는 중 다크모드를 적용하기 위해 공부해보았다.
tailwind.config.js에 다음과 같은 문구를 추가한다.
darkMode: "class", // Tailwindcss 3.0 default is 'media', 'class'
module.exports = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx}",
"./src/components/**/*.{js,ts,jsx,tsx}",
],
darkMode: "class", // Tailwindcss 3.0 default is 'media', 'class'
theme: {
extend: {},
},
plugins: [],
};
이후 next-themes 라는 패키지를 설치한다.
yarn add next-themes
모든 페이지에 다크모드를 적용해야 하기 때문에 layout.tsx에 "ThemeProvider" 로 감싸주자. 또한, enableSystem={true}, attribute='class'를 추가해준다.
enableSystem이 true라면 사용자 시스템 설정에 따라 theme가 설정되는 것이다.
export default function layout({ children }: any) {
return (
<html lang="kr">
<body>
<ThemeProvider enableSystem={true} attribute="class">
{children}
</ThemeProvider>
</body>
</html>
);
}
이후 다크모드 버튼을 제작하는데
useTheme() hook를 사용하여 테마 정보를 가져오고, currentTheme를 따로 두어 분기처리하여 시스템 테마의 경우를 고려하자.
"use client";
import { useTheme } from "next-themes";
export default function DarkModeBtn() {
const { systemTheme, theme, setTheme } = useTheme();
const currentTheme = theme === "system" ? systemTheme : theme;
return (
<div>
<button
className="bg-pink-100 dark:bg-white flex items-center transition duration-300 focus:outline-none shadow"
onClick={() => {
setTheme(currentTheme === "dark" ? "light" : "dark");
}}
>
{currentTheme === "dark" ? (
<div>
<svg
className="w-5 h-5 bg-black"
fill="white"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
</svg>
</div>
) : (
<div>
<svg
className="w-5 h-5 bg-white"
fill="black"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"></path>
</svg>
</div>
)}
</button>
</div>
);
}
이후 최종적으로 다크모드를 적용하는 방법은 className 에 'dark: 내용'을 넣어주면 적용된다.