Chuyển tới nội dung chính

UI Components (@vppos/core/ui/react)

Tất cả shared UI components nằm trong @vppos/core/ui/react.

import { Button, Input, Select, Modal, Table, Toggle } from "@vppos/core/ui/react";
Storybook

Xem demo trực quan tất cả components trên Storybook.

pnpm --filter @vppos/core storybook   # http://localhost:6006

Nếu docs site không host Storybook cùng domain, tránh dùng link tương đối như /storybook/ để không bị broken link khi build docs.

Danh sách components

Form Controls

ComponentMô tảStorybook
Button7 variants (primary, secondary, warning, error, ghost, outline, dash), 3 sizes, loading, icons
InputInput text với label, error, helper, icons, password toggle, clear
SearchInputInput tìm kiếm (preset của Input)
SelectDropdown select (single & multi), floating-ui, clear
ToggleSwitch on/off, 4 sizes (sm, md, lg, xl)
CheckboxCheckbox với 3 sizes, indeterminate support
NumberInputInput số với prefix/suffix, format VND tự động
TagInputInput tags, thêm/xóa tag, Enter để thêm
ColorPickerChọn màu với Chrome picker, hex display
FileUploadUpload file, kéo thả, progress bar, preview
DatePickerDate picker với Calendar, min/max, footer
TimePickerTime picker cuộn giờ/phút, step tuỳ chỉnh
RichTextEditorWYSIWYG editor (react-quill), toolbar tuỳ chỉnh
FilterBarThanh bộ lọc nhanh với nhiều loại filter (select, range, date...)
FilterDrawerPanel bộ lọc nâng cao tích hợp trong Drawer, hỗ trợ cấu hình filter linh hoạt

Data Display

ComponentMô tảStorybook
TableBảng dữ liệu responsive, tự động chuyển sang card trên mobile; hỗ trợ renderMobileCard để tùy biến UI
TableMobileCardComponent nội bộ hiển thị card mobile (Mặc định: danh sách Label-Value; Tùy biến: Level 3 API)
PaginationPhân trang có ellipsis, items-per-page
StatusBadgeBadge trạng thái (active, inactive, pending, draft, deleted)
AvatarAvatar user, 7 sizes, circle/square, loading skeleton
ImageDisplayHiển thị ảnh với fallback icon, nhiều size/shape
SkeletonLoading placeholder (shimmer animation)
EmptyStateTrạng thái trống (no data, no search results)
StatCardsGrid các thẻ thống kê (doanh thu, đơn hàng...)
OverviewStatCardThẻ tổng quan với trend badge, info badge

Table — Mobile mode

Table mặc định sẽ tự động chuyển sang dạng card (Label: Value) khi màn hình nhỏ. Để tùy biến hoàn toàn, dùng prop renderMobileCard:

// 1. Mặc định (Auto Columns) - không cần làm gì thêm
<Table columns={columns} data={data} />

// 2. Tùy biến (Custom Render) - dùng JSX riêng
<Table
columns={columns}
data={orders}
renderMobileCard={(order) => (
<div className="rounded-xl border border-gray-100 bg-white p-4 shadow-sm">
<div className="flex items-start justify-between gap-3">
<h3 className="text-lg font-medium">{order.customerName}</h3>
<Badge>{order.status}</Badge>
</div>
<p className="mt-2 text-sm text-gray-500">25/10/2025</p>
<div className="mt-4 flex items-center justify-between">
<span className="text-xl font-medium">{formatCurrency(order.total)}</span>
<div className="flex gap-2">
<Button onClick={() => handleEdit(order)}>Sửa</Button>
<Button variant="outline" onClick={() => handleDelete(order)}>Xóa</Button>
</div>
</div>
</div>
)}
/>

Feedback

ComponentMô tảStorybook
ModalDialog modal, 6 sizes, 7 icon types
ConfirmDeleteModalModal xác nhận xóa (preset)
ConfirmLockModalModal xác nhận khoá (preset)
ConfirmUnlockModalModal xác nhận mở khoá (preset)
DrawerPanel trượt từ cạnh (left/right), nhiều sizes
TooltipTooltip dark/light, 4 positions, rich content
DropdownMenu dropdown (click trigger, floating-ui)
GlobalLoadingLoading overlay toàn màn hình, spinner + logo
UnderDevelopmentTrang "đang phát triển" với ảnh + action

Layout

ComponentMô tảStorybook
StepperStep-by-step wizard, interactive, home button
TabPanelTabs điều hướng, responsive, dropdown overflow🔜
ColumnVisibilityModalẨn/hiện cột table🔜

Quy tắc

  • Luôn dùng component từ core — không tự tạo lại
  • Nếu cần component mới → đề xuất trước → thêm vào core → export
  • Không copy code vào từng app