Live Preview
Checkbox Component Generation Skill
Skill này hướng dẫn bạn (AI Agent) tạo component Checkbox — điều khiển cho phép chọn nhiều giá trị, hỗ trợ trạng thái indeterminate.
1. Mục tiêu (Objective)
Tạo component Checkbox hoàn chỉnh gồm Checkbox đơn lẻ và Checkbox Group, hỗ trợ indeterminate state cho "Select All", tích hợp 100% Design Tokens.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Checkbox?
- Chọn nhiều giá trị từ nhóm options (vd: chọn tính năng, chọn danh mục)
- Toggle đơn lẻ cho agree/consent (vd: "Tôi đồng ý điều khoản")
- Select All / Deselect All trong danh sách
Phân biệt với component khác
| Tình huống | Component đúng | Lý do |
|---|---|---|
| Chọn NHIỀU từ ≤ 5 options | Checkbox Group | Thấy hết, toggle nhanh |
| Chọn NHIỀU từ > 5 options | Select (multi) | Tiết kiệm không gian |
| Chọn MỘT từ ≤ 5 options | Radio Group | Mutually exclusive |
| Toggle on/off có hiệu lực TỨC THÌ | Switch | Instant effect, no save |
| Toggle on/off trong form (cần submit) | Checkbox | Deferred, submit cùng form |
Decision Tree cho AI
text
User cần toggle/chọn?
├─ Nhiều lựa chọn cùng lúc → Checkbox (Group)
├─ Một lựa chọn duy nhất trong nhóm → Radio
├─ On/Off tức thì (không cần save) → Switch
├─ On/Off trong form (cần save/submit) → Checkbox (đơn lẻ)
└─ Agree/consent/terms → Checkbox (đơn lẻ)
3. Ngữ nghĩa & Phân loại (Semantics)
3.1. Checkbox States
| State | Visual | Mô tả |
|---|---|---|
| Unchecked | ☐ | Chưa chọn, hiện border box trống |
| Checked | ☑ | Đã chọn, hiện check icon + background primary |
| Indeterminate | ☐─ | Một phần con đã chọn (dùng cho "Select All") |
| Disabled | ☐ (mờ) | Không tương tác, giảm opacity |
| Error | ☐ (đỏ) | Validation thất bại (vd: chưa agree terms) |
3.2. Checkbox Group
- Wrapper chứa nhiều Checkbox với label, mô tả, error chung.
- Hỗ trợ
orientation:vertical(mặc định) hoặchorizontal. - Có thể có "Select All" checkbox với indeterminate logic tự động.
3.5. Slot Map (Figma ↔ Code)
📎 Source:
slot-manifest.json→checkbox· Layer: item
| Figma Slot | data-slot |
CSS Class | Required | Accepts |
|---|---|---|---|---|
| Root | checkbox |
.checkbox |
✅ | — |
| Indicator | checkbox-indicator |
— | ✅ | checkmark |
| Label | checkbox-label |
— | ❌ | text |
| Description | checkbox-description |
— | ❌ | text |
4. Token Mapping
📦 Token values: Xem
ATOMIC-MAPPING.md— single source of truth cho tất cả actual token values.
| Token | Type | Value | Mô tả |
|---|---|---|---|
box-size |
number | {spacing.5} |
Checkbox box dimensions (20px) |
box-radius |
number | {comp-radius-small} |
Rounded square (8px web/mobile) |
gap |
number | {spacing.2} |
Gap between checkbox and label |
group-gap |
number | {spacing.3} |
Gap between checkbox items in group |
color.box-border |
color | {base.input-border} |
Unchecked border |
color.box-bg-unchecked |
color | transparent |
Unchecked background |
color.box-bg-checked |
color | {base.primary} |
Checked fill |
color.box-bg-indeterminate |
color | {base.primary} |
Indeterminate fill |
color.check-icon |
color | {base.primary-foreground} |
Tick mark color |
color.box-border-error |
color | {base.destructive} |
Error border |
color.label |
color | {base.foreground} |
Label text |
color.description |
color | {base.muted-foreground} |
Description text below label |
color.hover |
color | {state-layer.hover} |
Box hover background |
color.focus-ring |
color | {focus.ring-color} |
Focus ring color — ref shared/focus |
color.bg |
color | {base.background} |
Default background |
disabled-opacity |
number | {opacity.50} |
|
transition |
string | {duration.instant} {easing.standard} |
Check/uncheck animation |
padding |
number | {item.padding-default} |
Internal padding |
5. Props & API
typescript
interface CheckboxProps {
/** Checked state */
checked?: boolean;
/** Indeterminate state (overrides checked visual) */
indeterminate?: boolean;
/** Label text */
label?: string;
/** Description bên dưới label */
description?: string;
/** Disabled */
disabled?: boolean;
/** Error state */
isError?: boolean;
/** Size */
size?: 'sm' | 'md' | 'lg';
/** onChange callback */
onChange?: (checked: boolean) => void;
}
interface CheckboxGroupProps {
/** Label của group */
label?: string;
/** Options */
options: { value: string; label: string; description?: string; disabled?: boolean }[];
/** Values đã chọn */
value?: string[];
/** Orientation */
orientation?: 'vertical' | 'horizontal';
/** Error message */
errorMessage?: string;
/** Select All option */
showSelectAll?: boolean;
/** onChange callback */
onChange?: (values: string[]) => void;
}
6. Accessibility (a11y)
- Role: Dùng
<input type="checkbox">native (có thể ẩn visually). - Label: Mỗi checkbox phải có
<label>kết nối quahtmlFor. - Indeterminate: Set
checkbox.indeterminate = truequa JavaScript (không có HTML attribute). - Group: Wrap trong
<fieldset>+<legend>hoặcrole="group"+aria-labelledby. - Keyboard:
Spacetoggle checked,Tabdi chuyển focus giữa checkboxes. - Error:
aria-invalid="true"+aria-describedbytrỏ error message.
7. Best Practices & Rules
- Semantic HTML: Dùng native
<input type="checkbox">, có thể custom visual bằng CSS. - Touch target: Vùng bấm tối thiểu 44×44px (iOS) — bao gồm cả label area.
- Indeterminate logic: Khi "Select All" checked → tất cả con checked. Khi bỏ → tất cả unchecked. Khi một phần → indeterminate.
- Không Hardcode: Mọi giá trị từ Token.
- Icon: Check mark (
check), indeterminate dash (minus) CHỈ dùng Lucide icon từassets/icons/. CẤM dùng text emoji. Xemicon.mdmục 10.
8. Example Usage
jsx
{/* Single checkbox */}
<Checkbox label="Tôi đồng ý với Điều khoản sử dụng" />
{/* Checkbox group */}
<CheckboxGroup
label="Chọn tính năng"
showSelectAll
options={[
{ value: 'qr', label: 'QR Pay', description: 'Thanh toán bằng mã QR' },
{ value: 'nfc', label: 'NFC', description: 'Thanh toán chạm' },
{ value: 'card', label: 'Thẻ liên kết' },
]}
value={['qr', 'nfc']}
/>
{/* Error state */}
<Checkbox label="Tôi đồng ý" isError />