Next로 다크모드 구현하기(next-themes)

ㅇㅖㅈㅣ·2024년 6월 6일
0

Today I Learned

목록 보기
92/93
post-thumbnail

Next.js와 Typescript로 간단한 로그인 기능을 연습하면서 다크모드 기능을 함께 구현해보았다.

찾아보니 shadcn/ui에서 제공하는 next-themes로 쉽게 구현이 가능하다는 것을 알게되었다.

Next-themes

개발환경

Next.js 의 app router + Typescript + tailwindCSS

설치

먼저 next-themes 를 설치해주어야 한다.

npm install next-themes
yarn add next-themes

참고
공식문서

이대로 보고 따라하면 큰 문제없이 구현할 수 있다.


코드작성

먼저 layout.tsx 파일이 csr이 아니기 때문에 따로 provider.tsx 파일을 만들어주었다.

// provider.tsx
"use client";

import React from "react";
import { ModeToggle } from "@/components/mode-toggle";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";

export const ThemeProvider = ({ children, ...props }: ThemeProviderProps) => {
  return (
    <NextThemesProvider {...props} attribute="class" defaultTheme="system">
      {children}
      // 모드선택 토글버튼
      <ModeToggle className={"absolute top-6 right-6"} />
    </NextThemesProvider>
  );
};

여기서 defaultTheme 은 처음 고정값을 어떻게 설정할지에 대한 것인데 처음에는 light로 설정했다가 그냥 시스템설정을 따르는 것으로 바꾸었다.

그리고 attribute 는 tailwndCSS의 클래스로 다크모드를 설정하기 위해 class로 설정해주었다.

// tailwind.config.ts
const config = {
  darkMode: ["class"],
// ...생략

그리고 다크모드, 라이트모드를 선택할 수 있는 토글버튼 파일을 만들어주었다.

// mode-toggle.tsx
import { Moon, Sun } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useTheme } from "next-themes";

export function ModeToggle({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) {
  const { setTheme } = useTheme();

  return (
    <div className={className} {...props}>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant="outline" size="icon">
            <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
            <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
            <span className="sr-only">Toggle theme</span>
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem onClick={() => setTheme("light")}>
            Light
          </DropdownMenuItem>
          <DropdownMenuItem onClick={() => setTheme("dark")}>
            Dark
          </DropdownMenuItem>
          <DropdownMenuItem onClick={() => setTheme("system")}>
            System
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  );
}

shadcn/ui 에서 제공해주는 dropdown-menubutton 도 다운받아 주어야 하는데 방법은 앞에 작성한 글을 참고해도 좋을 것 같다!
보러가기


마지막으로 최상위 파일인 layout.tsx 에 추가해주면 된다!

// ... 생략
return (
    <html lang="en">
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  );

결과

라이트모드

다크모드

아직 화면은 구현되지 않았지만 이렇게 모드변경이 가능하다!


공식문서 보는것이 어렵게 느껴지기도 하지만 정말 상세하게 잘 되어있다고 생각한다. 그렇기 때문에 조금만 꼼꼼히 살펴보고 사용해보면 다양한 기능을 구현할 수 있다는 것이 신기하고 재미있다.

더 살펴봐야겠다!

profile
웰씽킹_나는 경쟁력을 갖춘 FE개발자로 성장할 것이다.

0개의 댓글