Bộ công cụ Giao diện Quản trị (Admin UI Kit)
1. Kiểm soát Tài liệu
| Thuộc tính | Giá trị |
|---|---|
| Gói | @nx-app/admin-ui-kit |
| Phiên bản | 0.0.0 |
| Loại | Thư viện Thành phần (Component Library) |
| Dựa trên | Shadcn/UI, Radix UI |
| Runtime | React 19 |
2. Phạm vi & Mục tiêu
2.1. Phạm vi
Gói này là nguồn chân lý duy nhất cho các thành phần giao diện người dùng (UI components) trong hệ sinh thái BANA. Nó xuất các thành phần phi trạng thái (stateless), dễ tiếp cận (accessible) và có kiểu dáng (styled) được sử dụng bởi Back Office Client và ứng dụng Back Office (BO).
2.2. Mục tiêu
- Nhất quán về Hình ảnh: Nhận diện thương hiệu giống hệt nhau (màu sắc, kiểu chữ, khoảng cách) trên các ứng dụng.
- Khả năng tiếp cận (a11y): Có thể điều hướng bằng bàn phím và thân thiện với trình đọc màn hình (WAI-ARIA thông qua Radix).
- Hiệu quả: Các khối xây dựng sẵn sàng sử dụng để phát triển nhanh chóng.
- Tree-Shaking: Xuất theo tên (Named exports) để tối ưu kích thước gói (bundle size).
3. Ngăn xếp Công nghệ (Technology Stack)
3.1. Các phụ thuộc Cốt lõi (Core Dependencies)
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| React | ^19.0.0 | UI Framework (peer) |
| Tailwind CSS | >=4.0.0 | Styling (peer) |
| TypeScript | ^5 | An toàn kiểu dữ liệu (Type Safety) |
3.2. Tiện ích Kiểu dáng (Styling Utilities)
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| class-variance-authority | ^0.7.1 | Biến thể thành phần (Component Variants) |
| clsx | ^2.1.1 | Kết hợp Class (Class Composition) |
| tailwind-merge | ^3.4.0 | Gộp Class (Class Merging) |
| tw-animate-css | ^1.4.0 | Các lớp Hoạt hình (Animation Classes) |
3.3. Radix UI Primitives
| Thành phần | Phiên bản | Mục đích |
|---|---|---|
| @radix-ui/react-accordion | ^1.2.12 | Phần mở rộng được (Expandable Sections) |
| @radix-ui/react-alert-dialog | ^1.1.15 | Hộp thoại xác nhận |
| @radix-ui/react-avatar | ^1.1.11 | Ảnh đại diện người dùng |
| @radix-ui/react-checkbox | ^1.3.3 | Ô đánh dấu (Checkboxes) |
| @radix-ui/react-collapsible | ^1.1.12 | Bảng có thể thu gọn |
| @radix-ui/react-context-menu | ^2.2.16 | Menu chuột phải |
| @radix-ui/react-dialog | ^1.1.15 | Hộp thoại Modal |
| @radix-ui/react-dropdown-menu | ^2.1.16 | Menu thả xuống |
| @radix-ui/react-label | ^2.1.8 | Nhãn biểu mẫu (Form Labels) |
| @radix-ui/react-popover | ^1.1.15 | Bảng nổi (Floating Panels) |
| @radix-ui/react-radio-group | ^1.3.8 | Nút radio |
| @radix-ui/react-scroll-area | ^1.2.10 | Thanh cuộn tùy chỉnh |
| @radix-ui/react-select | ^2.2.6 | Danh sách thả xuống (Dropdowns) |
| @radix-ui/react-separator | ^1.1.8 | Dải phân cách trực quan |
| @radix-ui/react-slot | ^1.2.4 | Khe thành phần (Component Slots) |
| @radix-ui/react-switch | ^1.2.6 | Nút chuyển đổi (Toggle Switches) |
| @radix-ui/react-tabs | ^1.1.13 | Điều hướng Tab |
| @radix-ui/react-tooltip | ^1.2.8 | Chú thích công cụ (Tooltips) |
3.4. Các thành phần Bổ sung
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| lucide-react | ^0.562.0 | Thư viện Biểu tượng (Icon Library) |
| vaul | ^1.1.2 | Thành phần Ngăn kéo (Drawer Component) |
| sonner | ^2.0.7 | Thông báo Toast |
| react-day-picker | ^9.11.1 | Lịch/Chọn ngày |
| cmdk | ^1.1.1 | Bảng lệnh (Command Palette) |
3.5. Công cụ Phát triển
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| shadcn | ^3.5.1 | CLI Thành phần |
| tsc-alias | ^1.8.16 | Phân giải Path Alias |
| @venizia/dev-configs | ^0.0.5-0 | Cấu hình ESLint/Prettier chung |
4. Cấu trúc Dự án
apps/admin-ui-kit/
├── src/
│ ├── components/ # Mã nguồn Thành phần
│ │ ├── core/ # Các thành phần Cốt lõi
│ │ │ ├── backdrop/ # Lớp phủ nền (backdrop)
│ │ │ └── common/ # Các thành phần chung
│ │ ├── icons/ # Biểu tượng Tùy chỉnh
│ │ └── shadcn/ # Các thành phần shadcn/ui (38 files)
│ │ ├── accordion.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── breadcrumb.tsx
│ │ ├── button-group.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── card.tsx
│ │ ├── checkbox.tsx
│ │ ├── collapsible.tsx
│ │ ├── command.tsx
│ │ ├── context-menu.tsx
│ │ ├── dialog.tsx
│ │ ├── drawer.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── empty.tsx
│ │ ├── field.tsx
│ │ ├── input-group.tsx
│ │ ├── input.tsx
│ │ ├── kbd.tsx
│ │ ├── label.tsx
│ │ ├── popover.tsx
│ │ ├── radio-group.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── sheet.tsx
│ │ ├── sidebar.tsx
│ │ ├── skeleton.tsx
│ │ ├── spinner.tsx
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── textarea.tsx
│ │ └── tooltip.tsx
│ ├── hooks/ # Custom Hooks
│ │ └── use-mobile.ts # Phát hiện thiết bị di động
│ ├── styles/ # CSS Exports
│ ├── utilities/ # Các hàm Tiện ích
│ │ └── tw.utility.ts # Tiện ích gộp Tailwind
│ ├── generate-index.ts # Script tạo file index
│ └── index.ts # Exports của gói
├── scripts/ # Các script build
├── dist/ # Đầu ra build
└── package.json5. Danh mục Thành phần
5.1. Atoms (Thành phần Cơ sở)
| Thành phần | Mô tả | Biến thể (Variants) |
|---|---|---|
| Button | Nút tương tác | default, destructive, outline, secondary, ghost, link |
| Input | Trường nhập văn bản | - |
| Label | Nhãn biểu mẫu | - |
| Badge | Chỉ báo trạng thái | Nhiều biến thể màu sắc |
| Checkbox | Lựa chọn Boolean | - |
| Switch | Điều khiển chuyển đổi | - |
| Separator | Phân cách trực quan | horizontal, vertical |
| Skeleton | Trình giữ chỗ khi đang tải | - |
| Spinner | Chỉ báo đang tải | - |
5.2. Molecules (Thành phần Tổng hợp)
| Thành phần | Mô tả | Tính năng |
|---|---|---|
| Card | Container nội dung | Header, content, footer slots |
| Alert Dialog | Modal xác nhận | Nút Action/Cancel |
| Dialog | Lớp phủ Modal | Tiêu đề, mô tả, đóng |
| Popover | Nội dung nổi | Định vị dựa trên trigger |
| Tooltip | Thông tin khi di chuột | Độ trễ, định vị |
| Dropdown Menu | Menu hành động | Items, separators, sub-menus |
| Select | Lựa chọn thả xuống | Tìm kiếm, nhóm, đa chọn |
| Tabs | Điều hướng Tab | Các bảng nội dung |
| Accordion | Các phần mở rộng được | Mở rộng đơn/đa |
5.3. Organisms (Thành phần Phức tạp)
| Thành phần | Mô tả | Tính năng |
|---|---|---|
| Calendar | Bộ chọn ngày | Chọn khoảng, điều hướng |
| Command | Bảng lệnh | Tìm kiếm, phím tắt |
| Sidebar | Thanh bên điều hướng | Có thể thu gọn, nhóm |
| Table | Bảng dữ liệu | Headers, rows, cells |
| Sheet | Bảng trượt ra | Định vị bên cạnh |
| Drawer | Ngăn kéo dưới cùng | Cử chỉ vuốt |
5.4. Thành phần Tùy chỉnh (Custom Components)
| Thành phần | Mô tả |
|---|---|
| Backdrop | Lớp phủ nền |
| ComingSoon | Thành phần giữ chỗ |
| ButtonGroup | Nhóm nút |
| InputGroup | Đầu vào kèm addons |
| Field | Bao bọc trường biểu mẫu |
| Empty | Hiển thị trạng thái trống |
| Kbd | Hiển thị phím tắt |
6. Mẫu Triển khai Thành phần
6.1. Hệ thống Biến thể (Variant System)
Các thành phần sử dụng class-variance-authority (CVA) để quản lý biến thể:
const buttonVariants = cva(
"inline-flex items-center justify-center ...",
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-white hover:bg-destructive/90',
outline: 'border bg-background shadow-xs hover:bg-accent',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2',
lg: 'h-10 rounded-md px-6',
sm: 'h-8 rounded-md gap-1.5 py-1.5 px-2.5',
xs: 'h-7 rounded-md gap-1.5 px-1.5 py-1',
icon: 'size-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
);6.2. Tiện ích Class
Tiện ích cn gộp các class Tailwind một cách thông minh:
import clsx, { ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export const cn = (...inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
};6.3. Cấu trúc Thành phần
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<'button'> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot : 'button';
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}7. Biến thể Nút (Button Variants)
7.1. Biến thể Hình ảnh
| Biến thể | Kiểu dáng | Trường hợp sử dụng |
|---|---|---|
default | Nền chính (Primary background) | Hành động chính |
destructive | Màu đỏ/nguy hiểm | Xóa, gỡ bỏ |
outline | Chỉ viền | Hành động phụ |
secondary | Nền mờ (Muted background) | Hành động thay thế |
ghost | Không nền | Hành động tinh tế |
link | Chỉ văn bản | Liên kết điều hướng |
default-active | Active primary | Trạng thái đã chọn |
7.2. Biến thể Kích thước
| Kích thước | Chiều cao | Trường hợp sử dụng |
|---|---|---|
default | 36px (h-9) | Nút tiêu chuẩn |
lg | 40px (h-10) | Nút nổi bật |
sm | 32px (h-8) | Nút nhỏ gọn |
xs | 28px (h-7) | Nút rất nhỏ gọn |
icon | 36x36px | Nút chỉ có icon |
icon-sm | 32x32px | Nút icon nhỏ |
icon-lg | 40x40px | Nút icon lớn |
icon-xs | 28x28px | Nút icon rất nhỏ |
icon-xxs | 20x20px | Nút icon tối thiểu |
8. Hooks
8.1. useMobile
Phát hiện khung nhìn di động cho hành vi phản hồi (responsive):
import { useMobile } from '@nx-app/admin-ui-kit';
const isMobile = useMobile();9. Sử dụng
9.1. Cài đặt
Gói được liên kết qua giao thức workspace của Bun:
{
"dependencies": {
"@nx-app/admin-ui-kit": "workspace:*"
}
}9.2. Mẫu Import
Các export được đặt tên hỗ trợ tree-shaking:
import {
Button,
Card,
CardContent,
CardHeader,
Dialog,
DialogContent,
DialogTrigger,
} from '@nx-app/admin-ui-kit';9.3. Tùy chỉnh
Các thành phần chấp nhận className để ghi đè Tailwind:
<Button className="bg-red-500 hover:bg-red-600">
Hành động Quan trọng
</Button>9.4. Kết hợp với Radix Slot
Sử dụng asChild để kết hợp thành phần:
<Button asChild>
<Link href="/dashboard">Đi đến Bảng điều khiển</Link>
</Button>10. Design Tokens
10.1. Hệ thống Màu sắc
| Token | Mục đích |
|---|---|
primary | Màu thương hiệu |
primary-foreground | Văn bản trên nền primary |
secondary | Hành động phụ |
secondary-foreground | Văn bản trên nền secondary |
destructive | Hành động nguy hiểm/xóa |
muted | Nền tinh tế |
muted-foreground | Văn bản tinh tế |
accent | Điểm nhấn |
accent-foreground | Văn bản trên nền accent |
background | Nền trang |
foreground | Văn bản chính |
card | Nền thẻ |
card-foreground | Văn bản thẻ |
popover | Nền popover |
popover-foreground | Văn bản popover |
border | Màu viền |
input | Viền đầu vào |
ring | Vòng focus |
10.2. Khoảng cách & Bán kính
| Token | Giá trị | Sử dụng |
|---|---|---|
radius | Có thể cấu hình | Bán kính viền (Border radius) |
11. Xuất (Exports)
11.1. Gói Exports
{
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./styles/*": "./src/styles/*"
}
}11.2. Tác dụng phụ (Side Effects)
Các tệp CSS được đánh dấu là có tác dụng phụ để đóng gói đúng cách:
{
"sideEffects": ["**/*.css"]
}12. Build & Scripts
12.1. Các Script có sẵn
| Script | Lệnh | Mục đích |
|---|---|---|
gen:index | bun ./src/generate-index.ts | Tự động tạo index.ts |
build | sh ./scripts/build.sh | Build sản xuất |
rebuild | bun run gen:index && sh ./scripts/rebuild.sh | Build lại toàn bộ |
clean | sh ./scripts/clean.sh | Dọn dẹp thư mục dist |
lint | bun run eslint && bun run prettier:cli | Chạy linters |
lint:fix | Fix lint issues | Tự động sửa lỗi lint |
12.2. Tạo Index
Các thành phần được tự động xuất thông qua generate-index.ts:
// 🚀 AUTO GENERATE - DON'T EDIT THIS FILE
// Exports from components
export * from "./components/shadcn/button";
export * from "./components/shadcn/card";
// ... more exports
// Exports from hooks
export * from "./hooks/use-mobile";
// Exports from utilities
export * from "./utilities/tw.utility";13. Người tiêu dùng (Consumers)
13.1. Các ứng dụng sử dụng Admin UI Kit
| Ứng dụng | Sử dụng |
|---|---|
| client (Back Office) | Thư viện thành phần đầy đủ |
| bo (Back Office Internal) | Thư viện thành phần đầy đủ |
13.2. Không được sử dụng trong
| Ứng dụng | Lý do |
|---|---|
| sale-renderer (POS UI) | Có các thành phần shadcn riêng |
14. Thống kê Mã nguồn
| Chỉ số | Số lượng |
|---|---|
| Tệp Thành phần | 40+ |
| Thành phần shadcn | 38 |
| Thành phần Tùy chỉnh | 4 |
| Icons | 2 |
| Hooks | 1 |
| Utilities | 1 |
| Radix Primitives | 18 |