管理 shadcn-svelte 元件與專案 — 新增、更新、修復、除錯、樣式設定與組合 UI。提供專案上下文、元件文件與使用範例。適用於使用 shadcn-svelte、CLI、設計系統預設或任何包含 components.json 檔案的專案。也會在「shadcn-svelte init」、「add component」或註冊表 URL 時觸發。
shadcn-svelte
一個用於 Svelte 建立 UI、元件與設計系統的框架。元件透過 CLI 以原始碼形式加入使用者專案。
重要: 所有 CLI 指令請使用專案的套件執行器:
npx shadcn-svelte@latest、pnpm dlx shadcn-svelte@latest或bunx --bun shadcn-svelte@latest— 根據專案的套件管理器選擇。以下範例使用npx shadcn-svelte@latest,但請替換為專案適用的執行器。
當前專案上下文
讀取專案根目錄的 components.json,當需要即時檔案結構時,列出 aliases.ui 路徑(解析規則與 CLI 相同)所指定的目錄。
匯入(Svelte)
每個元件位於自己的資料夾,並包含一個 index.ts 匯出檔案。請遵循安裝文件:
- 多部分元件(dialog、select、card、field、tabs 等):
import * as Dialog from "$lib/components/ui/dialog",然後使用Dialog.Content、Dialog.Title、Card.Root、Card.Header等 — 視匯出內容而定(短名稱和/或Root as …別名)。 - 單一元件匯出(資料夾中只有一個有意義的元件):使用具名匯入 —
import { Button } from "$lib/components/ui/button"並使用<Button>,而非import * as Button搭配Button.Root。{ Input }、{ Badge }、{ Spinner }、{ Checkbox }、{ Separator }、{ Skeleton }等也遵循相同模式。
import * as Dialog from "$lib/components/ui/dialog";
import { Button } from "$lib/components/ui/button";
import { Separator } from "$lib/components/ui/separator";
使用 components.json 中的實際別名(通常是 $lib/components/ui/...),而非硬編碼路徑。
原則
- 優先使用現有元件。 執行
npx shadcn-svelte@latest add不帶參數以瀏覽可用元件,或在撰寫自訂 UI 前查閱元件。 - 組合,不要重新發明。 設定頁面 = Tabs + Card + 表單控制項。儀表板 = Sidebar + Card + Chart + Table。
- 優先使用內建變體而非自訂樣式。 例如
variant="outline"、size="sm"等。 - 使用語意顏色。 例如
bg-primary、text-muted-foreground— 絕不使用原始值如bg-blue-500。
關鍵規則
這些規則始終強制執行。每個規則連結到一個包含錯誤/正確程式碼對照的檔案。
樣式與 Tailwind → styling.md
class用於佈局,而非樣式。 絕不覆寫元件的顏色或字體。- 不使用
space-x-*或space-y-*。 使用flex搭配gap-*。垂直堆疊使用flex flex-col gap-*。 - 當寬高相等時使用
size-*。 使用size-10而非w-10 h-10。 - 使用
truncate簡寫。 而非overflow-hidden text-ellipsis whitespace-nowrap。 - 不要手動覆寫
dark:顏色。 使用語意 token(bg-background、text-muted-foreground)。 - 使用
cn()處理條件 class。 不要手寫模板字串三元運算式。 - 不要在覆蓋層元件上手動設定
z-index。 Dialog、Sheet、Popover 等會自行處理堆疊。
表單與輸入 → forms.md
- 表單使用
Field.FieldGroup+Field.Field。 絕不使用原始div搭配space-y-*或grid gap-*進行表單佈局。 InputGroup使用InputGroup.Input/InputGroup.Textarea。 絕不在InputGroup.Root內使用原始Input/Textarea。- 輸入內部的按鈕使用
InputGroup.Root+InputGroup.Addon。 - 選項集合(2–7 個選項)使用
ToggleGroup。 不要用迴圈產生Button並手動管理啟用狀態。 - 使用
Field.FieldSet+Field.FieldLegend來分組相關的核取方塊/選項按鈕。 不要使用div搭配標題。 - 欄位驗證使用
data-invalid+aria-invalid。data-invalid放在Field上,aria-invalid放在控制項上。禁用狀態:data-disabled放在Field上,disabled放在控制項上。
元件結構 → composition.md
- 項目總是放在其 Group 內。
Select.Item→Select.Group。DropdownMenu.Item→DropdownMenu.Group。Command.Item→Command.Group。 - 自訂觸發器。 將控制項包在
Dialog.Trigger/AlertDialog.Trigger中,或使用bind:open在根元件上控制開啟狀態 — 請參閱元件文件。 - Dialog、Sheet 和 Drawer 總是需要標題。
Dialog.Title、Sheet.Title、Drawer.Title是無障礙必備。若需視覺隱藏,使用class="sr-only"。 - 使用完整的 Card 組合。
Card.Header/Card.Title/Card.Description/Card.Content/Card.Footer。不要把所有內容都塞進Card.Content。 - Button 沒有
isPending/isLoading。 在Button內部組合Spinner並加上disabled;在Spinner上使用data-icon="inline-start"/inline-end以獲得正確間距(import { Button }、import { Spinner })。 Tabs.Trigger必須放在Tabs.List內。 絕不要直接在Tabs中渲染觸發器。Avatar總是需要Avatar.Fallback。 用於圖片載入失敗時。
使用元件,而非自訂標記 → composition.md
- 優先使用現有元件而非自訂標記。 在撰寫樣式化的
div之前,先檢查是否有對應元件。 - 提示框使用
Alert。 不要建立自訂的樣式化 div。 - 空狀態使用
Empty。 不要建立自訂的空狀態標記。 - Toast 透過
svelte-sonner。 使用svelte-sonner的toast()函式,搭配 UI 資料夾中的 Sonner 元件。 - 使用
Separator而非<hr>或僅有邊框 class 的div。 - 使用
Skeleton作為載入佔位符。不要使用自訂的animate-pulsediv。 - 使用
Badge而非自訂的樣式化 span。
圖示 → icons.md
<Button>中的圖示使用data-icon。 在圖示上使用data-icon="inline-start"或data-icon="inline-end"。- 元件內部的圖示不要加上尺寸 class。 元件透過 CSS 處理圖示尺寸。不要使用
size-4或w-4 h-4。 - 將圖示作為元件傳入。 從設定的
iconLibrary(例如@lucide/svelte)匯入,而非字串鍵。
CLI
- 預設 — 從 shadcn-svelte.com 的設計系統建構器複製編碼字串,並傳遞給
npx shadcn-svelte@latest init --preset <code>。
關鍵模式
以下是區分正確 shadcn-svelte 程式碼的最常見模式。邊緣情況請參閱上方連結的規則檔案。
<script lang="ts">
import * as Field from "$lib/components/ui/field";
import { Input } from "$lib/components/ui/input";
import { Button } from "$lib/components/ui/button";
import SearchIcon from "@lucide/svelte/icons/search";
import { Badge } from "$lib/components/ui/badge";
import * as Avatar from "$lib/components/ui/avatar";
</script>
<!-- 表單佈局:Field.FieldGroup + Field.Field,而非 div + Label。 -->
<Field.FieldGroup>
<Field.Field>
<Field.FieldLabel for="email">Email</Field.FieldLabel>
<Input id="email" />
</Field.Field>
</Field.FieldGroup>
<!-- 驗證:data-invalid 在 Field 上,aria-invalid 在控制項上。 -->
<Field.Field data-invalid>
<Field.FieldLabel for="email">Email</Field.FieldLabel>
<Input id="email" aria-invalid />
<Field.FieldDescription>無效的 Email。</Field.FieldDescription>
</Field.Field>
<!-- 按鈕中的圖示:data-icon,無尺寸 class。 -->
<Button>
<SearchIcon data-icon="inline-start" />
搜尋
</Button>
<!-- 間距:gap-*,而非 space-y-*。 -->
<div class="flex flex-col gap-4"></div>
<!-- 等寬高:size-*,而非 w-* h-*。 -->
<Avatar.Root class="size-10">
<Avatar.Image src="/u.png" alt="使用者" />
<Avatar.Fallback>U</Avatar.Fallback>
</Avatar.Root>
<!-- 狀態顏色:Badge 變體或語意 token,而非原始顏色。 -->
<Badge variant="secondary">+20.1%</Badge>
元件選擇
| 需求 | 使用 |
|---|---|
| 按鈕/動作 | Button 搭配適當的變體(import { Button }) |
| 表單輸入 | Input、Select、Combobox、Switch、Checkbox、RadioGroup、Textarea、InputOTP、Slider |
| 切換 2–5 個選項 | ToggleGroup.Root + ToggleGroup.Item |
| 資料顯示 | Table、Card、Badge、Avatar |
| 導航 | Sidebar、NavigationMenu、Breadcrumb、Tabs、Pagination |
| 覆蓋層 | Dialog(模態框)、Sheet(側邊面板)、Drawer(底部面板)、AlertDialog(確認對話框) |
| 回饋 | svelte-sonner(toast)、Alert、Progress、Skeleton、Spinner |
| 指令面板 | Command 放在 Dialog 內 |
| 圖表 | Chart(LayerChart) |
| 佈局 | Card、Separator、Resizable、ScrollArea、Accordion、Collapsible |
| 空狀態 | Empty |
| 選單 | DropdownMenu、ContextMenu、Menubar |
| 工具提示/資訊 | Tooltip、HoverCard、Popover |
關鍵欄位
使用 components.json 和檔案系統 — 而非獨立的 info 指令:
aliases→ 使用設定中的實際別名前綴(例如$lib/),絕不硬編碼其他專案的路徑。tailwind.css→ 全域 CSS 檔案,主題變數存放於此。編輯此檔案進行主題調整;除非使用者已使用第二個全域檔案,否則不要新增。style→ 視覺處理(例如nova、vega等)以及註冊表樣式路徑。iconLibrary→ 決定圖示套件(@lucide/svelte、@tabler/icons-svelte等)。絕不預設為@lucide/svelte。registry→ CLI 取得元件的位置;預設官方註冊表為shadcn-svelte.com。resolvedPaths(概念性)→ CLI 將aliases解析為絕對路徑;列出磁碟上的aliases.ui以查看已安裝的元件。
請參閱 cli.md 了解指令與旗標。
元件文件、範例與使用方式
開啟 https://shadcn-svelte.com/docs/components/<name>.md 查看文件與範例。在建立、修復、除錯或使用元件時,請先閱讀官方頁面,以遵循文件化的 API。
工作流程
- 取得專案上下文 — 讀取
components.json,並在需要時列出 UI 元件目錄。 - 先檢查已安裝的元件 — 在執行
add之前,列出已解析ui路徑下的檔案。不要匯入尚未新增的元件,也不要重新新增已存在的元件(除非要更新)。 - 探索元件 —
npx shadcn-svelte@latest add不帶參數(互動式列表),或使用文件網站。 - 安裝或更新 —
npx shadcn-svelte@latest add <name>或註冊表 URL。若要從註冊表重新整理現有檔案,使用npx shadcn-svelte@latest update(參閱 cli.md)。 - 修復第三方/URL 新增項目的匯入 — 從自訂註冊表 URL 新增後,檢查是否有硬編碼路徑不符合專案的
aliases。將匯入改寫為使用components.json中的專案ui/lib別名。 - 檢視新增的元件 — 新增後,讀取新增的檔案並驗證組合(群組、標題、驗證屬性)。將圖示匯入對齊
iconLibrary。 - 遠端註冊表項目 — 透過 URL 新增是明確的;如果使用者想要來自未知來源的元件,請在執行
add前確認註冊表 URL 或項目。
更新元件
使用 update 指令從註冊表拉取已安裝元件的最新版本。在 update 後使用 git diff 檢視變更。
- 提交或暫存本地工作。
- 執行
npx shadcn-svelte@latest update [component]或--all。 - 如果曾自訂檔案,解決合併衝突。
- 未經使用者明確同意,絕不在
add上使用--overwrite,因為這會破壞有意的編輯。
快速參考
# 在專案中初始化 shadcn-svelte。
npx shadcn-svelte@latest init
# 使用文件網站建構器中的預設字串初始化。
npx shadcn-svelte@latest init --preset <code>
# 新增元件(不帶名稱時為互動模式)。
npx shadcn-svelte@latest add
npx shadcn-svelte@latest add button card dialog
npx shadcn-svelte@latest add --all
# 更新已安裝的元件。
npx shadcn-svelte@latest update button
npx shadcn-svelte@latest update --all --yes
# 建立自訂註冊表(註冊表作者)。
npx shadcn-svelte@latest registry build
註冊表: 預設為 https://shadcn-svelte.com/registry — 如有需要可在 components.json 中覆寫。
文件: shadcn-svelte.com
詳細參考
- rules/forms.md — Field.FieldGroup、Field.Field、InputGroup、ToggleGroup、Field.FieldSet、驗證狀態
- rules/composition.md — 群組、覆蓋層、Card、Tabs、Avatar、Alert、Empty、Toast、Separator、Skeleton、Badge、按鈕載入
- rules/icons.md — data-icon、圖示尺寸、傳入圖示元件
- rules/styling.md — 語意顏色、變體、class、間距、尺寸、truncate、深色模式、cn()、z-index
- cli.md — 指令、旗標、註冊表
- customization.md — 主題、CSS 變數、擴充元件






