
必須(ひっす)的(てき)なUIコンポーネントを提供(ていきょう)します。
デザイン分野(ぶんや)で1位(い)を記録(きろく)し、Tailwind CSSベースで制作(せいさく)されました。
필수적인 UI 컴포넌트를 제공합니다.
디자인 분야에서 1위를 기록했으며, Tailwind CSS 기반으로 제작되었습니다.
공식 사이트: ui.shadcn.com
まず、設定(せってい)ファイルにパスエイリアスを追加(ついか)します。
プロジェクトのsrc/フォルダーを@で参照(さんしょう)できるようにします。
먼저 설정 파일에 경로 별칭을 추가합니다.
프로젝트의 src/ 폴더를 @로 참조할 수 있게 합니다.
tsconfig.json
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
tsconfig.app.json
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});
세팅 완료: 이제 필요한 컴포넌트를 개별적으로 설치할 수 있습니다
ボタンコンポーネントをインストールします。
様々(さまざま)なバリアント(variant)で使(つか)い分(わ)けができます。
버튼 컴포넌트를 설치합니다.
다양한 variant로 구분해서 사용할 수 있습니다.
npx shadcn@latest add button
자동 생성되는 유틸리티 함수
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
cn 함수 활용 예시
<div
className={cn(
"w-10 text-sm",
isActive ? "text-green-500" : "text-red-500",
)}
>
isActive
</div>
cn 함수: 삼항 연산자를 사용해 조건부 스타일링을 쉽게 구현
Button Variants
<Button variant={"destructive"}>버튼</Button>
<Button variant={"ghost"}>버튼</Button>
<Button variant={"link"}>버튼</Button>
<Button variant={"outline"}>버튼</Button>
<Button variant={"secondary"}>버튼</Button>
| Variant | 説明(せつめい) |
|---|---|
destructive | 삭제, 위험한 작업용 (빨간색) |
ghost | 배경 없는 투명 버튼 |
link | 링크 스타일 버튼 |
outline | 테두리만 있는 버튼 |
secondary | 보조 버튼 (회색) |
テキスト入力(にゅうりょく)フィールドです。
プレースホルダーを設定(せってい)できます。
텍스트 입력 필드입니다.
플레이스홀더를 설정할 수 있습니다.
npx shadcn@latest add input
<Input placeholder="입력 ..." />
複数(ふくすう)行(ぎょう)のテキスト入力(にゅうりょく)です。
長(なが)い文章(ぶんしょう)の入力(にゅうりょく)に使(つか)います。
여러 줄의 텍스트 입력입니다.
긴 문장 입력에 사용합니다.
npx shadcn@latest add textarea
<Textarea />
画面(がめん)上部(じょうぶ)にメッセージを表示(ひょうじ)します。
一時的(いちじてき)な通知(つうち)に便利(べんり)です。
화면 상단에 메시지를 표시합니다.
일시적인 알림에 편리합니다.
npx shadcn@latest add sonner
import { Toaster } from "@/components/ui/sonner";
import { toast } from "sonner";
<Toaster />
<Button
onClick={() => {
toast("토스트 메시지", {
position: "top-center",
});
}}
>
버튼!
</Button>
Toaster 컴포넌트: 반드시 최상위에 추가해야 toast가 작동합니다
画像(がぞう)スライドに使(つか)われます。
複数(ふくすう)のアイテムを一度(いちど)に表示(ひょうじ)できます。
이미지 슬라이드에 사용됩니다.
여러 아이템을 한 번에 표시할 수 있습니다.
npx shadcn@latest add carousel
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
<Carousel className="mx-10">
<CarouselContent>
<CarouselItem className="basis-1/3">1</CarouselItem>
<CarouselItem className="basis-1/3">2</CarouselItem>
<CarouselItem className="basis-1/3">3</CarouselItem>
<CarouselItem className="basis-1/3">4</CarouselItem>
<CarouselItem className="basis-1/3">5</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
핵심:
mx-10으로 마진을 줘서 양옆 아이템이 보이게 하고,basis-1/3으로 한 번에 3개씩 표시
ボタンの下部(かぶ)に小(ちい)さなウィンドウが表示(ひょうじ)されます。
ユーザークリック、ログアウトなどに使(つか)います。
버튼 하단에 작은 창이 표시됩니다.
사용자 메뉴, 로그아웃 등에 사용합니다.
npx shadcn@latest add popover
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
<Popover>
<PopoverTrigger asChild>
<Button>Open</Button>
</PopoverTrigger>
<PopoverContent>Content!</PopoverContent>
</Popover>
중요:
@/components/ui에서 가져오는 것을 반드시 확인!
クリックするとモーダルウィンドウが表示(ひょうじ)されます。
重要(じゅうよう)な情報(じょうほう)を表示(ひょうじ)するときに使(つか)います。
클릭하면 모달 창이 표시됩니다.
중요한 정보를 표시할 때 사용합니다.
npx shadcn@latest add dialog
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
<Dialog>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent>
<DialogTitle>Title</DialogTitle>
<div>Body</div>
</DialogContent>
</Dialog>
ユーザーの確実(かくじつ)な反応(はんのう)を確認(かくにん)する必要(ひつよう)があるときに使(つか)います。
肯定(こうてい)ボタンと否定(ひてい)ボタンが追加(ついか)されます。
사용자의 확실한 반응을 확인해야 할 때 사용합니다.
긍정 버튼과 부정 버튼이 추가됩니다.
npx shadcn@latest add alert-dialog
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
<AlertDialog>
<AlertDialogTrigger>Open Alert Dialog</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogTitle>Title</AlertDialogTitle>
<AlertDialogDescription>Description</AlertDialogDescription>
<div>body</div>
<div>
<AlertDialogAction
onClick={() => {
console.log("Action!");
}}
>
Action
</AlertDialogAction>
<AlertDialogCancel onClick={() => console.log("Cancel")}>
Cancel
</AlertDialogCancel>
</div>
</AlertDialogContent>
</AlertDialog>
| コンポーネント | 用途(ようと) |
|---|---|
| Dialog | 일반적인 정보 표시 |
| Alert Dialog | 사용자 확인이 필요한 중요한 작업 |
권장: Alert Dialog 사용 시 Description 컴포넌트도 함께 사용하기
Lucide Reactからアイコンをインポートして使(つか)えます。
サイズや色(いろ)をTailwindで簡単(かんたん)に変更(へんこう)できます。
Lucide React에서 아이콘을 가져와 사용할 수 있습니다.
크기와 색상을 Tailwind로 쉽게 변경할 수 있습니다.
import { ChefHat } from "lucide-react";
<ChefHat className="h-10 w-10 fill-red-500" />
React Routerをインストールしてルーティングを設定(せってい)します。
ブラウザのアドレスをUIが感知(かんち)してレンダリングできるようにします。
React Router를 설치하고 라우팅을 설정합니다.
브라우저 주소를 UI가 감지해서 렌더링할 수 있게 합니다.
npm i react-router@7
npm run dev
main.tsx
import { BrowserRouter } from "react-router";
createRoot(document.getElementById("root")!).render(
<BrowserRouter>
<App />
</BrowserRouter>,
);
Routes、Route、Outletを使(つか)ってページを構成(こうせい)します。
パスに応(おう)じてコンポーネントがレンダリングされます。
Routes, Route, Outlet을 사용해서 페이지를 구성합니다.
경로에 따라 컴포넌트가 렌더링됩니다.
App.tsx
import { Outlet, Route, Routes } from "react-router";
import "./App.css";
import IndexPage from "@/pages/index-page";
import SignInPage from "@/pages/sign-in-page";
import SignUpPage from "@/pages/sign-up-page";
function AuthLayout() {
return (
<div>
<header>Auth!</header>
<Outlet />
</div>
);
}
function App() {
return (
<Routes>
<Route path="/" element={<IndexPage />} />
<Route element={<AuthLayout />}>
<Route path="/sign-in" element={<SignInPage />} />
<Route path="/sign-up" element={<SignUpPage />} />
</Route>
</Routes>
);
}
export default App;
pages/index-page.tsx
export default function IndexPage() {
return <div>Index</div>;
}
pages/sign-in-page.tsx
export default function SignInPage() {
return <div>SignInPage</div>;
}
pages/sign-up-page.tsx
export default function SignUpPage() {
return <div>SignUpPage</div>;
}
| パス | コンポーネント | 설명 |
|---|---|---|
/ | IndexPage | 홈 페이지 |
/sign-in | SignInPage | 로그인 페이지 |
/sign-up | SignUpPage | 회원가입 페이지 |
Outlet: 중첩된 라우트의 자식 컴포넌트가 렌더링될 위치를 지정
同(おな)じRoute内(ない)にネストされたページは同(おな)じレイアウトを共有(きょうゆう)します。
AuthLayoutでラップされた/sign-inと/sign-upは同(おな)じヘッダーを表示(ひょうじ)します。
같은 Route 내에 중첩된 페이지는 같은 레이아웃을 공유합니다.
AuthLayout으로 감싼 /sign-in과 /sign-up은 같은 헤더를 표시합니다.
/ → IndexPage만 표시
/sign-in → Auth! 헤더 + SignInPage
/sign-up → Auth! 헤더 + SignUpPage
Shadcn/uiで高品質(こうひんしつ)なUIコンポーネントを簡単(かんたん)に導入(どうにゅう)できます。
React Routerでページルーティングとレイアウト管理(かんり)が効率的(こうりつてき)になります。
Shadcn/ui로 고품질 UI 컴포넌트를 쉽게 도입할 수 있습니다.
React Router로 페이지 라우팅과 레이아웃 관리가 효율적으로 됩니다.
핵심: Shadcn/ui (디자인) + React Router (라우팅) = 완벽한 프론트엔드 구성