為 React 專案安裝與設定 shadcn/ui 元件。提供元件選擇、安裝順序、套件相依性管理、語意化 Token 自訂,以及常見 UI 組合範例(表單、資料表格、導覽列、彈窗 Modal)的完整指引。請在 tailwind-theme-builder 設定好主題基礎架構後使用,適用於新增元件、建立表單、製作資料表格或建置導覽選單等情境。
shadcn/ui 元件
將 shadcn/ui 元件新增至已套用主題的 React 專案中。本 Skill 需在 tailwind-theme-builder 設定完成 CSS 變數、ThemeProvider 與深色模式(dark mode)之後執行,負責處理元件安裝、風格自訂以及將元件組合為可運作的實用範例。
前置條件:必須先建立主題基礎架構(CSS 變數、components.json、cn() 工具函式)。若尚未設定,請先使用 tailwind-theme-builder。
安裝順序
請依照相依性順序安裝元件。先安裝基礎元件,再安裝功能性元件:
基礎元件(優先安裝)
pnpm dlx shadcn@latest add button
pnpm dlx shadcn@latest add input label
pnpm dlx shadcn@latest add card
功能性元件(依需求安裝)
# 表單類
pnpm dlx shadcn@latest add form # 需要:react-hook-form, zod, @hookform/resolvers
pnpm dlx shadcn@latest add textarea select checkbox switch
# 回饋提示類
pnpm dlx shadcn@latest add toast # 需要:sonner
pnpm dlx shadcn@latest add alert badge
# 浮層/彈窗類
pnpm dlx shadcn@latest add dialog sheet popover dropdown-menu
# 資料展示類
pnpm dlx shadcn@latest add table # 資料表格使用,另需:@tanstack/react-table
pnpm dlx shadcn@latest add tabs separator avatar
# 導覽類
pnpm dlx shadcn@latest add navigation-menu command
外部套件相依性
| 元件 | 需安裝套件 |
|---|---|
| Form | react-hook-form, zod, @hookform/resolvers |
| Toast | sonner |
| Data Table | @tanstack/react-table |
| Command | cmdk |
| Date Picker | date-fns(選填) |
請單獨安裝外部相依套件:pnpm add react-hook-form zod @hookform/resolvers
常見陷阱與注意事項(Known Gotchas)
以下為已知問題的修正經驗,可避免常見 Bug:
Radix Select — 禁止傳入空字串
// 請勿使用空字串作為 value
<SelectItem value="">All</SelectItem> // 錯誤做法(會引發異常)
// 請改用哨兵值(sentinel value)
<SelectItem value="__any__">All</SelectItem> // 正確做法
const actual = value === "__any__" ? "" : value
React Hook Form — Null 值的處理
// 請勿直接解構 {...field} — 這會傳入 null,而 Input 元件不接受 null
<Input
value={field.value ?? ''}
onChange={field.onChange}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
Lucide Icons — Tree-Shaking 議題
// 請勿使用動態匯入 — 圖示在正式環境(production)會被 Tree-shaking 移除
import * as LucideIcons from 'lucide-react'
const Icon = LucideIcons[iconName] // 正式環境會故障
// 請使用明確的對照表(Explicit map)
import { Home, Users, Settings, type LucideIcon } from 'lucide-react'
const ICON_MAP: Record<string, LucideIcon> = { Home, Users, Settings }
const Icon = ICON_MAP[iconName]
Dialog 寬度覆蓋
// 預設的 sm:max-w-lg 無法直接被 max-w-6xl 覆蓋
<DialogContent className="max-w-6xl"> // 無效
// 需使用相同的斷點前綴(breakpoint prefix)
<DialogContent className="sm:max-w-6xl"> // 生效
自訂元件風格
shadcn 元件採用主題定義的語意化 CSS Token。若要進行自訂:
擴充 Variant 變體
可透過修改 src/components/ui/ 中的元件檔案來新增自訂 variant:
// button.tsx — 新增 "brand" 變體
const buttonVariants = cva("...", {
variants: {
variant: {
default: "bg-primary text-primary-foreground",
brand: "bg-brand text-brand-foreground hover:bg-brand/90",
// ... 現有變體
},
},
})
覆蓋顏色
請務必使用主題提供的語意化 Token,切勿直接寫死 Tailwind 原生顏色:
// 請勿寫死顏色值
<Button className="bg-blue-500"> // 錯誤做法
// 請使用語意化 Token
<Button className="bg-primary"> // 正確做法
<Card className="bg-card text-card-foreground"> // 正確做法
工作流程
步驟 1:評估需求
確認專案所需的 UI 設計模式:
| 需求場景 | 所需元件 |
|---|---|
| 帶有驗證機制的表單 | Form, Input, Label, Select, Textarea, Button, Toast |
| 支援排序的資料展示 | Table, Badge, Pagination |
| 後台管理 CRUD 介面 | Dialog, Form, Table, Button, Toast |
| 行銷/一頁式 Landing Page | Card, Button, Badge, Separator |
| 設定/偏好設定頁面 | Tabs, Form, Switch, Select, Toast |
| 導覽選單 | NavigationMenu (電腦版), Sheet (行動版), ModeToggle |
步驟 2:安裝元件
先安裝基礎元件,再依據評估出的需求安裝功能性元件。請使用前述命令列指令。
步驟 3:建立 UI 組合範例(Recipes)
將元件組合為可運作的完整模式。完整範例程式碼請參考 references/recipes.md:
- 聯絡表單(Contact Form) — Form + Input + Textarea + Button + Toast
- 資料表格(Data Table) — Table + 欄位排序 + 分頁 + 搜尋
- 彈窗 CRUD(Modal CRUD) — Dialog + Form + Button
- 導覽列(Navigation) — Sheet + NavigationMenu + ModeToggle
- 設定頁面(Settings Page) — Tabs + Form + Switch + Select + Toast
步驟 4:自訂樣式
使用主題中的語意化 Token,套用專案專屬的顏色與 Variant 變體。
參考文件
| 使用時機 | 閱讀文件 |
|---|---|
| 選擇元件、查詢安裝指令與 Props 屬性 | references/component-catalogue.md |
| 建置完整的 UI 設計模式 | references/recipes.md |




