# Bộ chuyển đổi Giao diện Thành phần shadcn (shadcn Component Visual Adapter)
## 🎯 Mục tiêu
Tái cấu trúc (refactor) thành phần giao diện `` hiện có nằm tại đường dẫn `` để khớp với **thiết kế trực quan, cấu trúc và hành vi** của thành phần tham chiếu có tại:
>
← tùy chọn; để trống nếu không có trang tài liệu nào
KHÔNG thay thế logic nghiệp vụ, giao diện thuộc tính (props interface) hiện có, hoặc các mẫu truy xuất dữ liệu (data-fetching patterns). Hãy bảo toàn chúng.
Chỉ điều chỉnh **tầng hiển thị trực quan (visual layer)**: cấu trúc thẻ đánh dấu (markup), tên lớp CSS (class names), hiệu ứng chuyển động (animations) và các thuộc tính hỗ trợ tiếp cận (accessibility attributes).
---
## 📋 Bước 1 — Phân tích Thành phần Hiện có
Trước khi viết bất kỳ dòng mã nào:
1. Đọc toàn bộ mã nguồn của ``.
2. Lập sơ đồ chi tiết:
- Toàn bộ **các thuộc tính (props) và kiểu dữ liệu của chúng** (TypeScript interfaces hoặc PropTypes).
- Các **biến trạng thái (state variables)** nội bộ (`useState`, `useReducer`, Zustand slices, v.v.).
- **Các Context providers hoặc custom hooks** đang được sử dụng.
- **Các thành phần con (child components)** được kết xuất và vị trí lưu trữ của chúng.
- **Các hàm xử lý sự kiện (event handlers)** và hàm gọi lại (callbacks) được truyền ra cho thành phần cha.
3. Liệt kê mọi câu lệnh **import** — gắn cờ bất kỳ thư viện nào sẽ xung đột hoặc có thể được thay thế bằng thành phần nguyên thủy (primitive) của shadcn.
Xuất ra một bảng kiểm toán ngắn gọn trước khi chạm vào mã nguồn:
| Hạng mục | Giá trị hiện tại | Hành động |
|------|--------------|--------|
| Props | ... | giữ nguyên / đổi tên / xóa |
| State | ... | giữ nguyên / chuyển đổi |
| Context/Hooks | ... | giữ nguyên / thay thế |
| Sub-components | ... | giữ nguyên / thay thế |
| Dependencies | ... | giữ nguyên / cài đặt thêm / gỡ bỏ |
---
## 📦 Bước 2 — Giải quyết Thư viện Phụ thuộc (Dependency Resolution)
Chạy trực tiếp câu lệnh cài đặt sau:
Sau khi lệnh chạy xong, các tệp được tạo ra sẽ xuất hiện trong thư mục
/. Tiến hành sang Bước 3 bằng cách sử dụng các tệp đó.
---
## 🔬 Bước 3 — Rà soát Thành phần Tham chiếu
NẾU được cung cấp → truy xuất trang đó và trích xuất đặc tả giao diện như thông thường.
NẾU để trống → đọc các tệp vừa được tải về bởi lệnh CLI
ở Bước 2 và trích xuất trực tiếp các thông tin tương tự từ mã nguồn:
- lược đồ biến thể `cva` (cva variant schema)
- các thuộc tính `data-state` / `data-disabled`
- các lớp hiệu ứng động/chuyển cảnh (animation/transition classes)
- các vai trò và thuộc tính ARIA (ARIA roles and props)
- các mẫu sử dụng hàm `cn()`
---
## 🛠 Bước 4 — Tái cấu trúc Thành phần (Refactor)
Áp dụng cấu trúc giao diện từ Bước 3 vào thành phần hiện có từ Bước 1.
### Quy tắc:
- ✅ Giữ nguyên toàn bộ **tên và kiểu dữ liệu của các prop hiện có** trừ khi có prop tương đương trực tiếp trong shadcn.
- ✅ Giữ nguyên toàn bộ **logic truy xuất dữ liệu, logic nghiệp vụ và các hàm callback**.
- ✅ Bọc các thành phần nguyên thủy Radix bằng **`forwardRef`** và trải phẳng `...props` để giữ nguyên tính linh hoạt.
- ✅ Sử dụng hàm `cn()` cho mọi thao tác gộp `className` — tuyệt đối không nối chuỗi thủ công.
- ✅ Xuất (export) các thành phần con phức hợp có đặt tên nếu thành phần tham chiếu sử dụng chúng (ví dụ: `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`).
- ❌ KHÔNG import tệp shadcn vừa sinh ra rồi xuất lại (re-export) — hãy xây dựng thành phần nguyên thủy trực tiếp ngay bên trong tệp được tái cấu trúc để giữ logic nằm chung một chỗ.
- ❌ KHÔNG tự ý thêm các lớp Tailwind không có mặt trong thành phần tham chiếu nếu không có chỉ dẫn rõ ràng.
### Hành vi đáp ứng kích thước màn hình (``):
Áp dụng các lớp đáp ứng ưu tiên thiết bị di động (mobile-first). Xác nhận các điểm ngắt (breakpoints) hiện tại trong `tailwind.config.ts` khớp với quy ước của dự án. Nếu bản tham chiếu sử dụng truy vấn vùng chứa (container queries), hãy cài đặt gói `@tailwindcss/container-queries`.
---
## 🧩 Bước 5 — Context Providers và Hooks
Nếu thành phần tham chiếu yêu cầu một context provider (ví dụ: `ToastProvider`, `TooltipProvider`):
1. Kiểm tra xem nó đã được gắn (mount) trong `` hoặc `` hay chưa.
2. Nếu chưa, hãy thêm nó vào tệp bố cục (layout) phù hợp. Cung cấp bản so sánh khác biệt (diff) chính xác.
3. Nếu cần một custom hook (ví dụ: `useToast`, `useDialog`), hãy đặt nó vào thư mục `` và import từ đó.
---
## ❓ Bước 6 — Câu hỏi Làm rõ (hỏi trước khi sinh mã nếu chưa rõ)
Nếu bất kỳ thông tin nào dưới đây không thể xác định được từ mã nguồn hiện có, **hãy hỏi trước khi viết mã**:
1. **Dữ liệu/props**: Dữ liệu truyền vào sẽ có cấu trúc như thế nào? (Cung cấp một đối tượng mẫu nếu hữu ích.)
2. **Quản lý trạng thái**: Trạng thái của thành phần là cục bộ (local), hay được quản lý từ bên ngoài (Zustand, Redux, React Query)?
3. **Tài nguyên (Assets)**: Có cần hình ảnh, logo hoặc biểu tượng tùy chỉnh nào nằm ngoài thư viện `lucide-react` hay không?
4. **Đáp ứng màn hình (Responsive)**: Bố cục mong đợi tại các điểm ngắt `` là gì?
5. **Vị trí đặt**: Thành phần này sẽ nằm ở đâu trong cây định tuyến/bố cục (routing/layout tree) của ứng dụng? (Rất quan trọng để đặt context provider đúng chỗ.)
---
## 📐 Bước 7 — Định dạng Đầu ra
Cung cấp kết quả theo cấu trúc sau:
1. **``** — toàn bộ tệp thành phần đã được tái cấu trúc hoàn chỉnh.
2. **`/.tsx`** — thành phần nguyên thủy shadcn (chỉ khi thực sự cần thiết và chưa được công cụ CLI tạo ra).
3. **`lib/utils.ts`** — chỉ khi cần tạo mới hoặc cập nhật.
4. **Bản diff của Layout/provider** — chỉ khi cần bổ sung thêm một provider.
5. Một phần **ghi chú chuyển đổi (migration notes)** ngắn gọn liệt kê:
- Các thư viện phụ thuộc đã gỡ bỏ
- Các thuộc tính (props) đã đổi tên (nếu có)
- Bất kỳ bước thủ công nào cần thực hiện thêm (ví dụ: thêm biến CSS vào `globals.css`)
---
## 🎨 Các Biến Tailwind CSS (shadcn design tokens)
Xác nhận rằng tệp `globals.css` đã chứa đầy đủ các thuộc tính tùy chỉnh CSS bắt buộc. Nếu thành phần tham chiếu sử dụng các token như `--radius`, `--background`, `--foreground`, `--primary`, `--ring`, hãy nối thêm các biến còn thiếu vào. Sử dụng bộ token mặc định của shadcn cho chủ đề màu `` trừ khi dự án đã định nghĩa sẵn một chủ đề tùy chỉnh riêng.
---
## 🚫 Các Ràng buộc
- Framework: ****
- Định kiểu (Styling): Chỉ sử dụng **Tailwind CSS ** — không dùng inline styles, không dùng CSS modules, không dùng styled-components.
- TypeScript: **chế độ nghiêm ngặt (strict mode)**. Toàn bộ mã mới viết phải được định kiểu đầy đủ.
- Không nâng cấp hoặc hạ cấp bất kỳ phiên bản thư viện phụ thuộc hiện có nào trừ khi xảy ra xung đột phụ thuộc ngang hàng (peer conflict) trực tiếp.