@vetc-miniapp/ui-react
v0.0.24
Published
MiniApp Platform UI React
Readme
@vetc-miniapp/ui-react
Bộ UI component React cho VETC MiniApp Platform, được xây dựng theo design system Tasco DLS Mini App từ Figma, sử dụng Ant Design v6 làm base và override hoàn toàn theo VETC design token.
Cài đặt
npm install antd @ant-design/icons
npm install @vetc-miniapp/ui-reactSử dụng cơ bản
// 1. Import CSS tokens ở app root (1 lần duy nhất)
import '@vetc-miniapp/ui-react/src/ui-react/styles/tokens.css';
// 2. Wrap app với VETCProvider
import { VETCProvider } from '@vetc-miniapp/ui-react';
function App() {
return (
<VETCProvider>
<YourApp />
</VETCProvider>
);
}Components
Button
import { Button } from '@vetc-miniapp/ui-react';
// Primary (default) — brand green
<Button variant="primary" size="lg">Xác nhận</Button>
// Secondary — outlined
<Button variant="secondary" size="lg">Hủy</Button>
// Tertiary — ghost/text
<Button variant="tertiary">Xem thêm</Button>
// Danger
<Button variant="danger">Xóa</Button>
// Pill shape
<Button variant="primary" shape="pill">Tìm kiếm</Button>
// Small size (32px)
<Button variant="primary" size="sm">OK</Button>
// Loading & disabled
<Button loading>Đang xử lý...</Button>
<Button disabled>Không khả dụng</Button>Props: variant (primary|secondary|tertiary|danger), size (lg|sm), shape (rounded|pill), block, disabled, loading, icon, iconRight
Typography
import { Display, Headline, Title, Label, Body, Typography } from '@vetc-miniapp/ui-react';
<Display level="2xl">Tiêu đề lớn</Display>
<Headline level="xl">Headline</Headline>
<Title size="base">Tiêu đề phần</Title>
<Label size="sm" color="secondary">Nhãn</Label>
<Body size="base" color="primary">Nội dung văn bản</Body>
// Màu sắc: primary | secondary | disabled | brand | error | warning | success | inherit
<Body color="error">Lỗi rồi!</Body>
// Clamp lines
<Body lines={2}>Nội dung dài sẽ bị cắt sau 2 dòng...</Body>Input / TextField
import { Input, PasswordInput } from '@vetc-miniapp/ui-react';
// Default
<Input label="Số điện thoại" placeholder="0901 234 567" />
// Required + error
<Input
label="Email"
required
error="Email không hợp lệ"
value={email}
onChange={setEmail}
/>
// With icons
<Input prefix={<PhoneIcon />} suffix={<ClearIcon />} allowClear />
// Password
<PasswordInput label="Mật khẩu" placeholder="Nhập mật khẩu" />Textarea
import { Textarea } from '@vetc-miniapp/ui-react';
<Textarea
label="Ghi chú"
placeholder="Nhập nội dung..."
rows={4}
maxLength={500}
showCount
/>Select
import { Select } from '@vetc-miniapp/ui-react';
<Select
label="Tỉnh/Thành phố"
placeholder="Chọn tỉnh thành"
options={[
{ label: 'Hà Nội', value: 'HN' },
{ label: 'TP.HCM', value: 'HCM' },
]}
onChange={(val) => console.log(val)}
/>Checkbox / Radio / Switch
import { Checkbox, CheckboxGroup, Radio, RadioGroup, Switch } from '@vetc-miniapp/ui-react';
// Checkbox
<Checkbox label="Đồng ý điều khoản" checked={agreed} onChange={setAgreed} />
// Checkbox Group
<CheckboxGroup
options={[
{ label: 'Tùy chọn A', value: 'a' },
{ label: 'Tùy chọn B', value: 'b' },
]}
value={selected}
onChange={setSelected}
direction="vertical"
/>
// Radio Group
<RadioGroup
options={[{ label: 'Nam', value: 'male' }, { label: 'Nữ', value: 'female' }]}
value={gender}
onChange={setGender}
/>
// Switch
<Switch label="Bật thông báo" checked={notif} onChange={setNotif} />Chip / Tag
import { Chip } from '@vetc-miniapp/ui-react';
// Types: default | brand | positive | negative | warning | info
// Variants: tinted | outlined | filled
<Chip type="positive" variant="tinted">Hoàn thành</Chip>
<Chip type="negative" variant="filled">Lỗi</Chip>
<Chip type="warning" variant="outlined" closable onClose={...}>Cảnh báo</Chip>
// Small
<Chip size="sm" type="info">Mới</Chip>Avatar
import { Avatar } from '@vetc-miniapp/ui-react';
// Image
<Avatar src="https://..." alt="User" size="md" />
// Initials
<Avatar initials="Nguyễn Văn A" size="lg" color="#25a45e" />
// Sizes: xl(56) | lg(48) | md(40) | sm(32) | xs(24)Card
import { Card } from '@vetc-miniapp/ui-react';
// Elevations: outlined | raised | flat
<Card elevation="outlined" title="Thông tin xe" extra={<Button size="sm">Sửa</Button>}>
Nội dung card...
</Card>List / ListItem
import { List, ListItem } from '@vetc-miniapp/ui-react';
<List
bordered
items={vehicles}
renderItem={(v) => (
<ListItem
leading={<CarIcon />}
title={v.plate}
description={v.type}
arrow
onClick={() => navigate(v.id)}
/>
)}
/>Loading
import { Spinner, SkeletonLoader } from '@vetc-miniapp/ui-react';
// Spinner inline
<Spinner size="md" />
// Full-screen overlay
<Spinner fullscreen spinning={isLoading} />
// Spinner wrapping content
<Spinner spinning={loading}>
<Content />
</Spinner>
// Skeleton
<SkeletonLoader loading={loading} rows={3} avatar>
<ActualContent />
</SkeletonLoader>Toast
import { toast, useToast } from '@vetc-miniapp/ui-react';
// Static (simple)
toast.success('Đăng ký thành công!');
toast.error('Có lỗi xảy ra', 'Vui lòng thử lại');
toast.warning('Cảnh báo');
toast.info('Thông tin');
// Hook-based (recommended)
function MyComponent() {
const { toast, contextHolder } = useToast();
return (
<>
{contextHolder}
<Button onClick={() => toast.success('OK!')}>Thông báo</Button>
</>
);
}Modal / Dialog
import { Modal, useConfirm } from '@vetc-miniapp/ui-react';
// Controlled modal
<Modal
open={isOpen}
title="Xác nhận thanh toán"
okText="Thanh toán"
cancelText="Hủy"
onOk={handlePay}
onCancel={() => setOpen(false)}
>
Bạn có chắc muốn thanh toán 50,000đ?
</Modal>
// Confirm dialog
function MyComp() {
const { confirm } = useConfirm();
return (
<Button onClick={() => confirm({
title: 'Xóa phương tiện?',
content: 'Hành động này không thể hoàn tác.',
okDanger: true,
onOk: handleDelete,
})}>
Xóa
</Button>
);
}Bottom Sheet
import { BottomSheet } from '@vetc-miniapp/ui-react';
<BottomSheet
open={isOpen}
title="Chọn phương thức"
onClose={() => setOpen(false)}
>
<ListItem title="Thẻ ngân hàng" arrow onClick={...} />
<ListItem title="Ví điện tử" arrow onClick={...} />
</BottomSheet>NavigationBar (Top Nav)
import { NavigationBar } from '@vetc-miniapp/ui-react';
<NavigationBar
title="Chi tiết giao dịch"
showBack
onBack={() => history.back()}
actions={[
{ icon: <ShareIcon />, label: 'Chia sẻ', onClick: handleShare },
{ icon: <MoreIcon />, label: 'Thêm', onClick: handleMore },
]}
/>TabBar (Bottom Nav)
import { TabBar } from '@vetc-miniapp/ui-react';
<TabBar
activeKey={activeTab}
onChange={setActiveTab}
items={[
{ key: 'home', label: 'Trang chủ', icon: <HomeIcon /> },
{ key: 'history', label: 'Lịch sử', icon: <HistoryIcon />, badge: 3 },
{ key: 'profile', label: 'Tài khoản', icon: <UserIcon /> },
]}
/>Design Tokens
import { colorAlias, colorGlobal, fontSize, spacing, borderRadius } from '@vetc-miniapp/ui-react';
// Colors
colorAlias.brand // #25a45e
colorAlias.negative // #da2c39
colorAlias.warning // #ff8c2f
// Typography
fontSize.base // '16px'
fontSize.sm // '13px'
// Spacing
spacing[16] // '16px'
// Border radius
borderRadius.md // '8px'
borderRadius.xl // '16px'
borderRadius.pill // '1000px'Theming
VETCProvider tự động inject Ant Design ConfigProvider với toàn bộ VETC token. Bạn có thể extend theme:
import { VETCProvider, vetcAntdTheme } from '@vetc-miniapp/ui-react';
import { ConfigProvider } from 'antd';
<ConfigProvider theme={{ ...vetcAntdTheme, token: { ...vetcAntdTheme.token, colorPrimary: '#custom' } }}>
<App />
</ConfigProvider>