---
name: shadcn-reinstall
description: >
  ใช้ skill นี้เมื่อผู้ใช้ต้องการลบ shadcn/ui ออกจากโปรเจกต์ทั้งหมดแล้วติดตั้งใหม่ตั้งแต่ต้น
  และอาจต้องการแยก cva() variants ออกจาก component หลังติดตั้งใหม่เสร็จ
  ใช้ skill นี้เมื่อผู้ใช้พูดถึง "ลบ shadcn แล้วติดตั้งใหม่", "reinstall shadcn",
  "รีเซ็ต shadcn", "ล้าง shadcn", "ติดตั้ง shadcn ใหม่ทั้งหมด",
  "เริ่ม shadcn ใหม่ตั้งแต่ต้น", หรือ "reset shadcn/ui"
  หรือคำอื่นที่สื่อถึงการลบและติดตั้ง shadcn/ui ใหม่ทั้งหมด
  แม้ผู้ใช้จะไม่ได้ระบุคำว่า "reinstall" โดยตรงก็ตาม
  อย่าใช้ skill นี้กับงานที่ต้องการแค่ refactor, แยก variants, extract cva,
  หรือย้าย variants ออกจาก component โดยไม่ได้ต้องการลบและติดตั้ง shadcn/ui ใหม่
  ใช้กับโปรเจกต์ที่ shadcn/ui CLI รองรับ โดยให้ยืนยัน framework จาก package.json,
  components.json และ CLI output จริงก่อนเลือกคำสั่ง
---

# Shadcn Reinstall

Skill สำหรับลบ shadcn/ui ออกจากโปรเจกต์ทั้งหมด ติดตั้งใหม่ด้วย CLI
และแยก `cva()` variants ออกจากแต่ละ component ไปไว้ในไฟล์แยกต่างหากเมื่อผู้ใช้ยืนยันว่าต้องการทำต่อหลัง reinstall

## ภาพรวมขั้นตอนการทำงาน

0. **ตรวจสถานะและยืนยันขอบเขต** — ตรวจ `git status`, บันทึก config/path สำคัญ และให้ผู้ใช้ยืนยันก่อนลบหรือเขียนทับ
1. **ตรวจสอบโปรเจกต์** — ระบุ framework, package manager และโครงสร้างที่ใช้
2. **ลบ shadcn/ui ออกอย่างปลอดภัย** — ลบเฉพาะไฟล์ component และ configuration ที่ยืนยันแล้วว่าเกี่ยวข้อง
3. **ติดตั้ง shadcn/ui ใหม่** — ใช้ CLI ติดตั้งตั้งแต่ต้นเมื่อ network/approval พร้อม
4. **Cleanup dependency เมื่อจำเป็น** — หลัง reinstall แล้วค่อยเสนอ uninstall dependency ที่เหลือและพิสูจน์แล้วว่าไม่มีส่วนอื่นใช้
5. **ตรวจ `"use client"` ที่อาจไม่จำเป็น** — audit component ที่ CLI สร้างใหม่ แล้วเสนอรายการให้ผู้ใช้ยืนยันก่อนลบ directive
6. **แยก variants เมื่อผู้ใช้ยืนยัน** — ดึง `cva()` ออกจากแต่ละ component ไปไว้ในไฟล์ `[component]-variants.ts`

ดำเนินการตามลำดับข้างต้นอย่างเคร่งครัด ห้ามรันคำสั่งลบ เขียนทับ หรือ uninstall ก่อนมีการยืนยัน path จากผู้ใช้

## ขั้นตอนที่ 0: ตรวจสถานะและยืนยันขอบเขต

ก่อนทำงานที่ลบหรือเขียนทับไฟล์ ให้ทำรายการตรวจสอบความปลอดภัยนี้ก่อนเสมอ:

1. ตรวจ `git status --short` และ `git diff --stat` เพื่อดูว่ามีงานค้างของผู้ใช้หรือไม่
2. บันทึก path ที่จะถูกลบหรือเขียนทับ ได้แก่ ui directory, `components.json`, utils file และ CSS หลัก
3. สรุปรายการที่จะลบ/เขียนทับให้ผู้ใช้ยืนยันก่อนดำเนินการ

หาก workspace ไม่ได้อยู่ใน git หรือมี uncommitted changes ที่ไม่เกี่ยวข้องกับงานนี้ ให้ถามผู้ใช้ก่อนทำ destructive operation ใด ๆ

## ขั้นตอนที่ 1: ตรวจสอบโปรเจกต์

ก่อนดำเนินการใดๆ ให้ตรวจสอบข้อมูลพื้นฐานของโปรเจกต์ก่อน

### 1.1 ระบุ package manager

ตรวจสอบ lock file ที่มีอยู่ในโปรเจกต์เพื่อระบุ package manager ที่ใช้

```bash
rg --files -g "package-lock.json" -g "yarn.lock" -g "pnpm-lock.yaml" -g "bun.lock" -g "bun.lockb"
```

หากไม่มี `rg` ให้ใช้คำสั่ง native ของ shell ปัจจุบัน เช่น `Get-ChildItem` บน PowerShell หรือ `ls` บน Unix shell

เลือก package manager จาก lock file: `pnpm-lock.yaml` → `pnpm dlx`, `yarn.lock` → `yarn dlx`,
`bun.lock` หรือ `bun.lockb` → `bunx`, `package-lock.json` → `npx`

หากพบ lock file มากกว่าหนึ่งชนิด ให้หยุดและถามผู้ใช้ก่อนเลือก package manager
เพราะการใช้ package manager ผิดตัวอาจทำให้ lockfile เปลี่ยนกว้างหรือ dependency graph ไม่ตรงกับโปรเจกต์จริง

### 1.2 ระบุ framework

```bash
rg -n '"next"|"vite"|"astro"|"react-router"|"@tanstack/start"|"laravel"' -g "package.json"
```

### 1.3 บันทึกรายชื่อ component ที่ติดตั้งอยู่

อ่าน `components.json` เพื่อหา path ของ ui directory และ path ของไฟล์ CSS
จากนั้นบันทึกรายชื่อ component ที่มีอยู่

```bash
# อ่าน components.json เพื่อหา ui path และ CSS path
# PowerShell: Get-Content components.json
# Unix shell: cat components.json
```

หากไม่มี `components.json` ให้หยุดและตรวจจากหลักฐานอื่นก่อน เช่น import path, โฟลเดอร์ที่มีไฟล์ shadcn component,
CSS variables ในไฟล์ style หลัก และ dependency ที่เกี่ยวข้อง จากนั้นสรุป assumption ให้ผู้ใช้ยืนยันก่อนลบหรือติดตั้งใหม่

บันทึกข้อมูลต่อไปนี้ไว้ใช้ในขั้นตอนถัดไปและใช้ยืนยันค่าหลัง reinstall:

- **path ของโฟลเดอร์ ui** (ค่า `aliases.ui`) — ใช้ลบไฟล์ component ในขั้นตอนที่ 2
- **glob สำหรับ exclude ui directory** (เช่น `!**/components/ui/**` หรือค่าที่เทียบเท่ากับ `<ui-path>`) — ใช้ค้นหา dependency/import นอก ui directory
- **path ของไฟล์ CSS** (ค่า `tailwind.css`) — ใช้รีเซ็ตไฟล์ CSS ในขั้นตอนที่ 2
- **ค่า config เดิมทั้งหมด** เช่น `style`, `baseColor`, `iconLibrary`, `aliases`, `rsc`, `tsx` — ใช้ยืนยันว่าจะ preserve หรือ reset
- **รายชื่อ component** — ใช้ติดตั้งกลับคืนในขั้นตอนที่ 3

ห้ามทิ้งค่า config เดิมโดยอัตโนมัติ ให้ถามผู้ใช้ว่าต้องการ preserve ค่าเดิมหรือ reset ใหม่ทั้งหมดก่อนรัน `shadcn init`

เสนอทางเลือก config แบบสั้น: preserve ค่าเดิมเพื่อลด breakage กับ alias, style, base color และ path
หรือ reset ใหม่ทั้งหมดเมื่อผู้ใช้ต้องการเริ่มใหม่จริง ๆ และยอมรับความเสี่ยงที่ import path, theme หรือ CSS จะเปลี่ยนมากขึ้น

### 1.4 ตรวจสอบการ import ของ component ทั่วทั้งโปรเจกต์

สร้าง import search pattern จาก `aliases.ui`, path จริงของ ui directory และ alias ที่โปรเจกต์ใช้
เช่น `@/components/ui`, `~/components/ui`, `@/shared/ui` หรือ relative path ที่พบจาก codebase
ตัวอย่างด้านล่างเป็น pattern ทั่วไปเท่านั้น ให้ปรับตามหลักฐานจากโปรเจกต์จริง

```bash
# ค้นหาไฟล์ทั้งหมดที่ import จาก ui directory
rg -n "from ['\"].*components/ui|from ['\"].*@/components/ui|from ['\"].*~/components/ui" -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx"
```

บันทึกรายชื่อไฟล์เหล่านี้ไว้เพื่อตรวจสอบ import path หลังติดตั้งใหม่

## ขั้นตอนที่ 2: ลบ shadcn/ui ออกอย่างปลอดภัย

ก่อนเริ่มขั้นตอนนี้ ผู้ใช้ต้องยืนยัน path ที่จะลบหรือเขียนทับแล้วเท่านั้น
ห้ามใช้คำสั่งลบแบบ recursive กับ path ที่คำนวณขึ้นมาโดยยังไม่ได้แสดงให้ผู้ใช้ตรวจ

### 2.1 ลบไฟล์ component ในโฟลเดอร์ ui

ลบเฉพาะไฟล์ใน ui directory ที่ยืนยันแล้วว่า shadcn/ui สร้างขึ้น ไม่ลบไฟล์ที่ผู้ใช้สร้างเอง
หากไม่แน่ใจว่าไฟล์ใดเป็น custom component ให้ย้ายไป backup ชั่วคราวหรือถามผู้ใช้ก่อนลบ

```bash
# ลบเฉพาะไฟล์ shadcn-generated ที่ยืนยันแล้วทีละไฟล์
# ใช้ native shell command ที่ปลอดภัยกับ path จริง เช่น Remove-Item -LiteralPath บน PowerShell
```

ใช้ recursive delete กับ `<ui-path>` ได้เฉพาะหลังผู้ใช้ยืนยันชัดเจนว่าโฟลเดอร์นั้นไม่มีไฟล์ custom
และได้เห็น absolute path ที่จะถูกลบแล้วเท่านั้น

**ข้อควรระวัง:** หากผู้ใช้มี component ที่สร้างเองอยู่ในโฟลเดอร์ ui ให้แจ้งเตือนก่อนลบ
ตรวจสอบว่ามีไฟล์ที่ไม่ใช่ shadcn/ui component มาตรฐานหรือไม่

### 2.2 ลบ components.json

```bash
# หลัง confirmation แล้วเท่านั้น:
# PowerShell: Remove-Item -LiteralPath "components.json"
# Unix shell: rm -f "components.json"
```

### 2.3 ลบ utility function ที่ shadcn/ui สร้างขึ้น

```bash
# ลบไฟล์ cn utility (ปรับ path ตาม aliases.utils ใน components.json)
# ลบทั้งไฟล์เฉพาะเมื่อมีแค่ cn utility และผู้ใช้ยืนยันแล้ว
```

**ข้อควรระวัง:** หากไฟล์ `utils.ts` มีฟังก์ชันอื่นที่ผู้ใช้เขียนเพิ่มเอง
ให้ลบเฉพาะฟังก์ชัน `cn()` (หรือ `Cn()`) และ import ที่เกี่ยวข้อง ไม่ลบทั้งไฟล์
หากไม่มี `components.json` ให้หา utils path จาก import จริง เช่น `from "@/lib/utils"`
หรือค้นหา declaration ของ `cn` ด้วย pattern เช่น `function cn`, `const cn` หรือ `export function cn`
แล้วให้ผู้ใช้ยืนยัน path ก่อนแก้ไข

### 2.4 Snapshot dependency ที่ shadcn/ui อาจเคยติดตั้ง

ในขั้นตอนลบก่อน reinstall ให้บันทึก dependency ที่เกี่ยวข้องไว้ก่อน แต่อย่า uninstall ทันที
เพราะ `shadcn add` จะติดตั้ง dependency ที่จำเป็นกลับมาเอง และการ uninstall ก่อนอาจทำให้ lockfile churn โดยไม่จำเป็น

```bash
# ตรวจสอบ dependency ที่เกี่ยวข้องกับ shadcn/ui
rg -n "radix-ui|class-variance-authority|clsx|tailwind-merge|lucide-react|cmdk|@radix-ui|embla-carousel|react-day-picker|react-resizable-panels|recharts|sonner|vaul|input-otp" -g "package.json"
```

dependency หลักที่มักเกี่ยวข้องคือ `radix-ui`, `@radix-ui/react-*`, `class-variance-authority`,
`clsx`, `tailwind-merge` และ `lucide-react` แต่ให้ยืนยันจาก import จริงก่อน cleanup

เก็บ snapshot นี้ไว้เปรียบเทียบในขั้นตอนที่ 4 หลัง reinstall และ build ผ่านแล้ว

### 2.5 ตรวจและรีเซ็ตไฟล์ CSS อย่างมีเงื่อนไข

ตรวจไฟล์ CSS หลัก (เช่น `globals.css`, `index.css` หรือไฟล์ที่ระบุใน `tailwind.css` ของ
`components.json`) เพื่อแยกส่วนที่ shadcn/ui สร้างจาก custom style, design token หรือ CSS ของผู้ใช้
จากนั้นสรุปทางเลือกให้ผู้ใช้ยืนยันก่อนแก้ไข

```bash
# ห้ามเขียนทับทันที ให้แก้ผ่าน editor หรือ apply patch หลังยืนยัน path และเนื้อหาที่จะ preserve/reset
```

**สำคัญ:** ปรับ path ของไฟล์ CSS ให้ตรงกับค่า `tailwind.css` ที่อ่านได้จากขั้นตอนที่ 1.3
เช่น `app/globals.css`, `src/styles/globals.css` หรือ `src/index.css`

เหตุผลที่ต้องตรวจไฟล์นี้ก่อน reinstall คือ `shadcn init` อาจเขียน CSS variables และ theme ใหม่ลงในไฟล์เดียวกัน
หากปล่อยค่าเก่าที่ขัดแย้งไว้ อาจเกิดตัวแปรซ้ำหรือ theme ที่ไม่ตรงกับ config ใหม่

เสนอทางเลือกตามหลักฐานจาก diff: preserve custom CSS แล้วล้างเฉพาะ shadcn block เก่า,
reset เฉพาะ CSS variables/theme ของ shadcn หรือ reset ทั้งไฟล์เมื่อผู้ใช้ยืนยันว่าไฟล์นี้เป็นของ shadcn ล้วน

## ขั้นตอนที่ 3: ติดตั้ง shadcn/ui ใหม่ผ่าน CLI

**กฎเหล็ก:** ทุกขั้นตอนในการติดตั้งต้องทำผ่าน CLI ของ shadcn เท่านั้น
ห้ามสร้างไฟล์ `components.json`, ไฟล์ component หรือไฟล์ utility ด้วยตนเอง
CLI จะจัดการสร้างไฟล์ทั้งหมด ติดตั้ง dependency และตั้งค่า CSS variables ให้โดยอัตโนมัติ

การรัน `npx`, `pnpm dlx`, `yarn dlx` หรือ `bunx` ต้องใช้ network และอาจแก้ไฟล์หลายจุดโดยอัตโนมัติ
ให้ตรวจข้อจำกัดของ environment และขอ approval ตามระบบก่อนรัน CLI หาก CLI fail เพราะ network หรือ permission
ห้ามสร้างไฟล์ shadcn เองโดยเดา output ให้หยุดและรายงานสาเหตุพร้อมทางเลือกให้ผู้ใช้ตัดสินใจ

### 3.1 เริ่มต้นด้วย CLI init

รัน `shadcn init` เพื่อตั้งค่าโปรเจกต์ใหม่ทั้งหมด CLI จะถามคำถามเกี่ยวกับ
framework, style, base color และ aliases ให้เลือกตามที่ต้องการ
แทน `<version-or-latest>` ด้วย `latest` เมื่อต้องการ output ล่าสุด หรือ version ที่ pin ไว้
เมื่อต้องการ migration ที่ repeatable

```bash
# npm
npx shadcn@<version-or-latest> init

# pnpm
pnpm dlx shadcn@<version-or-latest> init

# yarn
yarn dlx shadcn@<version-or-latest> init

# bun
bunx shadcn@<version-or-latest> init
```

### 3.2 ติดตั้ง component ผ่าน CLI add

ใช้รายชื่อที่บันทึกไว้จากขั้นตอนที่ 1.3 เพื่อติดตั้ง component ทั้งหมดกลับคืน
ห้ามคัดลอกโค้ด component มาวางเอง ให้ใช้คำสั่ง `shadcn add` เท่านั้น
เพราะ CLI จะติดตั้ง dependency ที่จำเป็นและจัดการ import path ให้ถูกต้องโดยอัตโนมัติ

แทน `<runner>` ด้วย command runner จาก package manager ที่ตรวจพบ เช่น `npx`, `pnpm dlx`, `yarn dlx` หรือ `bunx`
และแทน `<version-or-latest>` ด้วย `latest` หรือ version ที่ pin ไว้สำหรับ migration ที่ต้อง reproducible

```bash
# ติดตั้ง component ทีละตัว
<runner> shadcn@<version-or-latest> add button
<runner> shadcn@<version-or-latest> add card
<runner> shadcn@<version-or-latest> add dialog

# หรือติดตั้งหลายตัวพร้อมกัน
<runner> shadcn@<version-or-latest> add button card dialog dropdown-menu input label select textarea

# ใช้ overwrite เฉพาะเมื่อผู้ใช้ยืนยันว่าให้เขียนทับไฟล์เดิม
<runner> shadcn@<version-or-latest> add button --overwrite
```

## ขั้นตอนที่ 4: Cleanup dependency เมื่อจำเป็น

หลัง reinstall และ build ผ่านแล้ว ให้เปรียบเทียบ dependency ก่อน/หลังจากขั้นตอนที่ 2.4
หากพบ package ที่เหลืออยู่แต่ไม่ได้ถูก import หรือใช้งานแล้ว ให้เสนอ cleanup พร้อมหลักฐานให้ผู้ใช้ยืนยันก่อน uninstall
ข้ามขั้นตอนนี้หากไม่พบ dependency ส่วนเกิน หรือหากการลบจะทำให้ lockfile churn โดยไม่เกิดประโยชน์ชัดเจน

ก่อนลบ dependency ใดๆ ให้ตรวจสอบว่าไม่มีโค้ดส่วนอื่นของโปรเจกต์ใช้อยู่
โดยค้นหา import, dynamic import, re-export และ subpath usage ทั่วทั้ง repo
ยกเว้นไฟล์ใน ui directory ที่ CLI สร้างใหม่และยืนยันว่าไม่ได้ใช้ package นั้นแล้ว

```bash
# ตรวจสอบว่ามีการใช้ dependency นอกเหนือจาก ui directory หรือไม่
# ตัวอย่าง: ตรวจสอบ clsx
rg -n "from ['\"]clsx['\"]|from ['\"]clsx/|import\\(['\"]clsx['\"]\\)|export .* from ['\"]clsx['\"]" -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx" -g "<ui-exclude-glob>"
```

ลบเฉพาะ dependency ที่ยืนยันว่าไม่มีส่วนอื่นใช้ และผู้ใช้อนุมัติ cleanup แล้ว:

```bash
# ปรับคำสั่งตาม package manager ที่ใช้
# npm
npm uninstall <package-names>

# pnpm
pnpm remove <package-names>

# yarn
yarn remove <package-names>

# bun
bun remove <package-names>
```

## ขั้นตอนที่ 5: Audit `"use client"` ที่อาจไม่จำเป็น

หลังจากติดตั้ง component ผ่าน `shadcn add` แล้ว ให้ค้นหาไฟล์ใน ui directory ที่มี directive `"use client"`
และสรุปรายการไฟล์ที่อาจลบ directive ได้ให้ผู้ใช้ยืนยันก่อนแก้ไข

```bash
rg -n "^[\"']use client[\"'];?$" "<ui-path>" -g "*.ts" -g "*.tsx"
```

พิจารณาเสนอให้ลบ `"use client"` ได้เฉพาะเมื่อไฟล์นั้นไม่มีสิ่งต่อไปนี้:

- React hooks เช่น `useState`, `useEffect`, `useLayoutEffect`, `useReducer`, `useRef`, `useId`, `useMemo`, `useCallback`
- event handlers หรือ interactive props ที่ประกาศใน component เช่น `onClick`, `onChange`, `onOpenChange`, `onValueChange`
- browser-only API เช่น `window`, `document`, `localStorage`, `ResizeObserver`, `IntersectionObserver`
- Radix หรือ third-party primitive ที่ต้องทำงานฝั่ง client และยังไม่ได้ถูก wrap แยกไว้ใน client boundary อื่น

ห้ามลบ `"use client"` อัตโนมัติ หากไม่แน่ใจว่า component ต้องเป็น client component หรือไม่ ให้คง directive ไว้ก่อน
แล้วรายงานเหตุผลให้ผู้ใช้ตัดสินใจ
หลังลบ directive ให้รัน build เพื่อตรวจว่า Server/Client Component boundary ยังถูกต้อง

### 5.1 Optional: เปลี่ยน `cn` เป็น `Cn` เมื่อผู้ใช้ยืนยัน

CLI ของ shadcn สร้างฟังก์ชัน `cn` ในไฟล์ utility และ import ฟังก์ชันนี้ไว้ในทุก component
โดยค่าเริ่มต้นของ shadcn ecosystem คือ `cn` จึงควรคง `cn` ไว้เสมอ เว้นแต่โปรเจกต์มี naming convention
ที่ยืนยันแล้วว่าต้องใช้ `Cn`

ข้ามหัวข้อนี้ทั้งหมดหากผู้ใช้ไม่ได้ยืนยันว่าต้องใช้ `Cn`
หากผู้ใช้ยืนยันว่าต้องเปลี่ยนเป็น `Cn` ให้ทำหลังจากติดตั้ง component ทั้งหมดผ่าน CLI เสร็จแล้ว
และตรวจซ้ำหลัง `shadcn add` ทุกครั้ง เพราะ component ที่เพิ่มภายหลังอาจกลับมา import `cn`

**a) แก้ไขจุดประกาศในไฟล์ utility:**

```bash
# ปรับ path ตาม aliases.utils ใน components.json (เช่น src/lib/utils.ts)
# แก้ด้วย editor หรือ structured replacement ให้เปลี่ยนเฉพาะ declaration ของ cn เท่านั้น
```

หากไม่มี `components.json` ให้หา utils path จาก import จริง เช่น `from "@/lib/utils"`
หรือค้นหา declaration ของ `cn` ด้วย pattern เช่น `function cn`, `const cn` หรือ `export function cn`
แล้วให้ผู้ใช้ยืนยัน path ก่อนแก้ไข

**b) แก้ไข import และการเรียกใช้ในทุกไฟล์ component ของ shadcn/ui:**

```bash
# เปลี่ยน import { cn } เป็น import { Cn } ในทุกไฟล์ที่อยู่ในโฟลเดอร์ ui
rg -n "import \\{ cn \\}|\\bcn\\(" "<ui-path>" -g "*.ts" -g "*.tsx"

# แก้ด้วย structured replacement หรือแก้ทีละไฟล์เพื่อหลีกเลี่ยงการเปลี่ยน identifier อื่นผิดตัว
```

**c) แก้ไข import และการเรียกใช้ในไฟล์อื่นทั่วทั้งโปรเจกต์:**

```bash
# ค้นหาไฟล์ทั้งหมดที่ import cn จาก utils (นอกโฟลเดอร์ ui)
rg -n "import \\{ cn \\}|\\bcn\\(" -g "*.ts" -g "*.tsx" -g "<ui-exclude-glob>"

# แก้เฉพาะไฟล์ที่ import cn จาก utils เดียวกันจริง ๆ
```

**ข้อควรระวัง:** ห้ามใช้ regex replace แบบกว้างกับ `cn(` ทั้ง repo โดยไม่ตรวจ AST/import ก่อน
เพราะอาจเปลี่ยนฟังก์ชันอื่นที่ชื่อเหมือนกันแต่ไม่ได้มาจาก shadcn utility

### 5.2 ตรวจสอบ import path

ตรวจสอบว่า import path ในไฟล์ที่บันทึกไว้จากขั้นตอนที่ 1.4 ยังถูกต้องหลังติดตั้งใหม่

```bash
# ตรวจสอบว่าไฟล์ component ถูกสร้างในตำแหน่งที่ถูกต้อง
rg --files "<ui-path>"

# ทดสอบ build เพื่อให้แน่ใจว่าไม่มี import ที่เสีย (ปรับ package manager ตามที่ตรวจพบในขั้นตอนที่ 1.1)
<package-manager> run build
```

## ขั้นตอนที่ 6: แยก variants ออกจาก component เมื่อผู้ใช้ยืนยัน

ขั้นตอนนี้ดึง `cva()` variants ออกจากแต่ละ component ไปไว้ในไฟล์แยกต่างหาก
ทำให้สามารถนำ variants กลับมาใช้ซ้ำในที่อื่นได้โดยไม่ต้อง import ทั้ง component
ให้ทำขั้นตอนนี้เฉพาะเมื่อผู้ใช้ระบุไว้ตั้งแต่ต้น หรือยืนยันหลัง reinstall แล้วว่าต้องการแยก variants ต่อ

### 6.1 โครงสร้างไฟล์ variants

สร้างไฟล์ variants ไว้ในโฟลเดอร์เดียวกับ component โดยใช้ชื่อตามรูปแบบ `[component]-variants.ts`

```
<ui-path>/
├── button.tsx
├── button-variants.ts        ← ไฟล์ variants ที่แยกออกมา
├── badge.tsx
├── badge-variants.ts         ← ไฟล์ variants ที่แยกออกมา
├── alert.tsx
├── alert-variants.ts         ← ไฟล์ variants ที่แยกออกมา
└── ...
```

### 6.2 รูปแบบไฟล์ variants

ใช้ไฟล์ variants เป็น TypeScript จริง ไม่ใช้ placeholder ที่ copy แล้วรันไม่ได้

```typescript
import { cva, type VariantProps } from 'class-variance-authority';

const button_variants = cva('base classes', {
  variants: {
    variant: { default: '...', outline: '...' },
    size: { default: '...', sm: '...' }
  },
  defaultVariants: { variant: 'default', size: 'default' }
});

type ButtonVariantsProps = VariantProps<typeof button_variants>;

export { button_variants, type ButtonVariantsProps };
```

ตั้งชื่อไฟล์แบบ kebab-case เช่น `button-variants.ts`, ตัวแปร variants แบบ snake_case เช่น
`button_variants` และ type แบบ PascalCase เช่น `ButtonVariantsProps`

ในไฟล์ component เดิม ให้ import variants กลับมาใช้และ preserve public export เดิม:

```tsx
import { cn } from '@/lib/utils';
import { button_variants, type ButtonVariantsProps } from './button-variants';

type ButtonProps = React.ComponentProps<'button'> & ButtonVariantsProps;

function Button({ className, variant, size, ...props }: ButtonProps) {
  return (
    <button
      className={cn(button_variants({ variant, size, className }))}
      {...props}
    />
  );
}

export { Button, button_variants };
```

**สำคัญ:** component ยังคง re-export `button_variants` เพื่อให้เข้ากันได้กับโค้ดเดิมที่ import
variants จากไฟล์ component โดยตรง

> ตัวอย่างนี้ใช้ `cn` ตามค่าเริ่มต้นของ shadcn ecosystem หากโปรเจกต์ยืนยัน naming convention ว่าต้องใช้ `Cn` ให้ปรับ import และ call site หลังผู้ใช้ยืนยันแล้วเท่านั้น
> Import source เช่น `radix-ui`, `@radix-ui/react-slot` หรือ path อื่น ต้อง preserve ตามไฟล์ที่ CLI สร้างจริง ห้ามบังคับแก้ตามตัวอย่างหาก CLI output ต่างกัน

### 6.3 ขั้นตอนการแยก variants สำหรับแต่ละ component

สำหรับแต่ละ component ที่มี `cva()` ให้ทำตามขั้นตอนเหล่านี้:

1. **ค้นหา component ที่มี cva():**

```bash
rg -l "cva\\(" "<ui-path>" -g "*.ts" -g "*.tsx"
```

2. **สำหรับแต่ละไฟล์ที่พบ ให้ดำเนินการ:**

   a. สร้างไฟล์ `[component]-variants.ts` ในโฟลเดอร์เดียวกัน

   b. ย้ายส่วนที่เกี่ยวข้องไปยังไฟล์ variants:
   - คำสั่ง `import { cva, type VariantProps } from 'class-variance-authority'`
   - การประกาศตัวแปร `cva()` ทั้งหมด โดยรองรับหลาย `cva()` ในไฟล์เดียวและตั้งชื่อไม่ให้ชนกัน
   - สร้าง type จาก `VariantProps<typeof ...>` สำหรับแต่ละ variants ที่จำเป็น
   - export ตัวแปร variants และ type

   c. แก้ไขไฟล์ component เดิม:
   - ลบ import ของ `cva` และ `VariantProps`
   - เพิ่ม import จากไฟล์ variants ที่สร้างใหม่
   - เปลี่ยน type annotation ให้ใช้ type ที่ import มา
   - preserve public exports เดิมทั้งหมด ห้ามเพิ่ม export ใหม่ที่ไม่เคยมีหากไม่จำเป็น
   - หากไฟล์ component เดิมเคย export variants อยู่แล้ว ให้คง re-export ไว้เพื่อ compatibility
   - หากไฟล์ component เดิมไม่ได้ export variants มาก่อน ให้ import ใช้ภายใน component เท่านั้น เว้นแต่ผู้ใช้ยืนยันว่าต้องการ export เพิ่ม

3. **ตรวจสอบว่า build ผ่าน:**

```bash
# ปรับ package manager ตามที่ตรวจพบในขั้นตอนที่ 1.1
<package-manager> run build
```

### 6.4 component ที่มักมี cva() ให้แยก

component มาตรฐานของ shadcn/ui ที่มักใช้ `cva()`:

- `button.tsx` → `button-variants.ts`
- `badge.tsx` → `badge-variants.ts`
- `alert.tsx` → `alert-variants.ts`
- `toggle.tsx` → `toggle-variants.ts`
- `sidebar.tsx` → `sidebar-variants.ts` (ถ้ามี)

ไม่ใช่ทุก component จะมี `cva()` จึงควรตรวจสอบด้วย `rg` ก่อนดำเนินการ

### 6.5 ตรวจสอบการ import ของ variants ทั่วทั้งโปรเจกต์

หลังแยก variants แล้ว ค้นหาไฟล์ที่ import variants โดยตรงจากไฟล์ component เดิม
และตรวจสอบว่ายังทำงานได้ถูกต้อง (เพราะไฟล์ component ยังคง re-export variants อยู่)

```bash
# ค้นหาไฟล์ที่ import variants จากไฟล์ component
rg -n "button_variants|badge_variants|alert_variants|toggle_variants" -g "*.ts" -g "*.tsx" -g "<ui-exclude-glob>"
```

## ข้อควรระวังสำคัญ

- **ทดสอบ build หลังขั้นตอนที่ควร build ผ่าน:** หลังลบ shadcn/ui แต่ก่อน reinstall ให้ตรวจ `git diff`
  และ path ที่ลบแทน เพราะ build อาจ fail จาก import ที่ยังรอ reinstall; รัน build หลังติดตั้งใหม่
  และหลังแยก variants เพื่อตรวจจับปัญหาแต่เนิ่นๆ
- **ไม่ลบ component ที่ผู้ใช้สร้างเอง:** ตรวจสอบว่าไฟล์ในโฟลเดอร์ ui
  เป็น component มาตรฐานของ shadcn/ui จริงก่อนลบ
- **ทำ dependency cleanup หลัง reinstall:** dependency บางตัว เช่น `clsx` อาจถูกใช้
  ในส่วนอื่นของโปรเจกต์ที่ไม่เกี่ยวข้องกับ shadcn/ui จึงไม่ควร uninstall ก่อน CLI add และ build ผ่าน
- **เลือก CLI version ให้เหมาะกับเป้าหมาย:** แทน `<version-or-latest>` ด้วย `latest` เมื่อต้องการ output ล่าสุดของ shadcn/ui
  หรือ `<pinned-version>` เมื่อต้องการ migration ที่ repeatable และตรวจสอบซ้ำได้
- **Audit `"use client"` ก่อนลบ:** เสนอให้ลบเฉพาะ component ที่ไม่มี hooks, event handlers,
  browser-only API หรือ client-only primitive และลบจริงหลังผู้ใช้ยืนยันเท่านั้น
