목표
React.JS와 Next.JS, shadcn/ui로 구성된 프로젝트에 dark mode를 적용하는 법을 알아보자.
Next.JS 프로젝트 셋팅
아래와 같은 create-next-app 명령어로 Next.JS 14버전의 새로운 프로젝트를 생성한다.
$ npx create-next-app@latest next-dark
명령어를 실행하면 사용자에게 몇가지 질문을 하는데 아래와 같이 src 디렉토리만 No를 선택하고,
Tailwind CSS, App Router는 사용하도록 Yes를 선택한다.
Need to install the following packages:
✔ Would you like to use TypeScript? … No / Yes > Yes
✔ Would you like to use ESLint? … No / Yes > Yes
✔ Would you like to use Tailwind CSS? … No / Yes > Yes
✔ Would you like to use `src/` directory? … No / Yes > No
✔ Would you like to use App Router? (recommended) … No / Yes > Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes > Yes
Creating a new Next.js
shadcn/ui 설치
설치가 완료되면 프로젝트 폴더로 이동 후 shadcn/ui를 설치하기위해 아래의 명령어를 입력한다
$ cd next-dark
$ npx shadcn-ui@latest init
타입스크립트를 사용하기 때문에 tailwind.config.js만 tailwind.config.ts로 변경하고, 테마는 Neutral을 사용하였다. 그외 나머지는 디폴트 옵션을 선택하면된다.
✔ Would you like to use TypeScript (recommended)? … no / yes > yes
✔ Which style would you like to use? > Default
✔ Which color would you like to use as base color? > Neutral
✔ Where is your global CSS file? … app/globals.css
✔ Would you like to use CSS variables for colors? … no / yes > yes
✔ Where is your tailwind.config.js located? … tailwind.config.ts
✔ Configure the import alias for components: … @/components
✔ Configure the import alias for utils: … @/lib/utils
✔ Are you using React Server Components? … no / yes > yes
✔ Write configuration to components.json. Proceed? … yes > yes
shadcn/ui button 설치
다크 모드 설정을 on/off로 토글하기 위해서 shacn/ui의 button 컴포넌트를 설치한다.
$ npx shadcn-ui@latest add button
다크모드 설정
next-themes 설치
다크모드 테마 설정을 위해 next-themes를 설치한다.
$ npm install next-themes
theme provider 생성
components/theme-provider.tsx
파일을 추가하여 아래의 코드를 추가한다.
참고 : 루트의 components 폴더는 shadcn/ui의 컴포넌트가 설치되는 경로다.
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
root layout에 provider 적용
위에서 작성한 ThemeProvider를 app/layout.tsx
에 적용하여 모든 하위 라우트 파일에 적용 받도록 한다.
(주의 : next-themes의 ThemeProvider가 아닌, 위에서 작성한 components폴더의 ThemeProvider를 import 해야한다.)
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
다크모드를 변경하는 토글 버튼 만들기
app/_components/dark-mode-toggle.tsx
파일을 새로 만들어 아래의 내용을 입력한다.
클라이언트에서만 렌더링 되는 버튼으로, dark mode와 light mode를 번갈아가면서 설정한다.
"use client";
import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button";
export function DarkModeToggle() {
const { resolvedTheme, setTheme } = useTheme();
const toggleTheme = () => {
if (resolvedTheme === "dark") {
setTheme("light");
} else {
setTheme("dark");
}
};
return (
<Button variant="outline" size="icon" onClick={toggleTheme}>
<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" />
</Button>
);
}
메인 페이지에 다크 모드 토글 버튼 추가
app/page.tsx
파일의 기존 내용을 아래의 내용으로 변경하여 버튼과 글자를 화면에 보여준다.
import { DarkModeToggle } from "./_components/dark-mode-toggle";
export default function Home() {
return (
<main className="flex flex-col items-center p-24">
<DarkModeToggle />
<div className="text-lg">다크모드 테스트</div>
</main>
);
}
최종 실행
아래의 명령어를 실행 후 웹브라우저에서 localhost:3000 주소로 접근하면 테마 버튼과 다크모드 테스트라는 글자를 볼 수 있다. 버튼을 눌러서 다크 모드와 라이트 모드로 테마가 잘 변경되는지 확인한다.
$ npm run dev
> next-dark@0.1.0 dev
> next dev
▲ Next.js 14.0.4
- Local: http://localhost:3000
✓ Ready in 2.4s
'개발 > React.JS, Next.JS' 카테고리의 다른 글
expo sdk 52로 업그레이드 (react native 0.76 적용) (0) | 2024.11.23 |
---|---|
tailwind css의 autoprefixer (1) | 2024.10.03 |
댓글