프론트엔드 개발 시작.
디자인에서 몇 번이나 꺾여버렸는지 모르겠다만 드디어 개발에 들어간다.
Shadcn /ui ??
다양한 프레임워크와 해당 생태계의 UI 라이브러리가 있지만. 대부분의 경우 내부 구현을 커스터마이징 하거나, 특정 요구 사항에 맞춰 수정하려면 오히려 내가 만드는게 빠를듯
이라는 생각이 들 정도로 복잡할 때가 있다.
collection of reusable components 는 철학 하에,
shadcn/ui
는 해당 컴포넌트를 설치하는 것이 아니라 컴포넌트 코드를 복사해온다.
특징
npx shadcn@latest init
을 통해 가져온다. (npm install 과 같은 설치 방식이 아님!)npx shadcn@latest add button
와 같이 필요한 요소를 추가할 수 있다.
위에서 보았듯 npm install 이 아니기 때문에, node_modules
와 같은 곳에 갇혀있는 코드가 아닌, 프로젝트 내부에 생성된다.
Radix UI
에 기초한다.
- 커스텀 하기 용이함
- 고품질의 접근성 + 상호작용 로직 제공
- 기본적인 스타일이 거의 없음
즉 Shadcn/ui
컴포넌트는 TailwindCSS + Radix UI
를 통해 스타일과 기능을 제공한다.
장점
- 개발 생산성
- 복잡한 컴포넌트의 재사용성
- 커스터마이징 가능성
- 기본적으로 제공되는 접근성
- 필요한 컴포넌트만 추가됨
사용해보기
Next.js 환경에서 진행합니다.
- 테스트용 Next.js 생성
npx create-next-app@latest
# 위의 명령어를 실행하면 아래와 같은 질문이 나온다. 원하는 설정에 맞춰서 선택
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like your code inside a `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to use Turbopack for `next dev`? No / Yes
Would you like to customize the import alias (`@/*` by default)? No / Yes
What import alias would you like configured? @/*
- 생성된 Next.js 파일 이동 & shadcn 명령어 실행
cd my-app # 위에서 입력한 앱 이름으로 폴더를 이동
npx shadcn@latest init
# 색상 추가 선택 후 완료
별거없음.
- init이 완료된 후 필요한 컴포넌트 추가
npx shadcn@latest add button input
사용 가능한 컴포넌트는 공식 문서에 잘 정리되어 있다.
실제로 위의 명령어를 통해 추가된 파일은
src/components/ui/input.tsx
와 같은 이름으로 추가된 모습을 확인할 수 있다.
해당 파일을 이용해서 컴포넌트 확장을 진행해도 되고, 사용하는 시점에 tailwindCss 를 통해 커스텀을 진행해도 된다.
import * as React from "react";
import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
// 외부에서 전달하는 클래스를 조합
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className // 외부에서 전달받는 커스텀 클래스!
)}
{...props}
/>
);
}
export { Input };
마무리
재사용 가능한 컴포넌트들을 직접 통합하고 완벽하게 제어하여, 강력하고 유연한 디자인 시스템을 구축
요약
- 내 파일에 생성됨
- 내가 모든 코드를 소유하는 만큼 유지보수 책임도 개발자 (나) 본인에게 있음
- 커스텀 편함
- 필요한 것만 생성됨