Live Preview
February 2026
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Date Picker Component
Skill này hướng dẫn tạo component Date Picker — calendar popup cho chọn ngày, khoảng ngày, tháng, năm.
1. Mục tiêu (Objective)
Tạo Date Picker: calendar popup, date range selection, month/year navigation. Hỗ trợ locale, validation, manual input.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Date Picker?
- Chọn ngày cụ thể: Ngày sinh, ngày hẹn, deadline
- Chọn khoảng ngày: Check-in / check-out, report period
- Chọn tháng/năm: Period selector, billing cycle
⚠️ Phân biệt Date Picker vs Input vs Select (QUAN TRỌNG)
| Tiêu chí | Date Picker | Text Input | Select |
|---|---|---|---|
| Bản chất | Calendar popup | Free-text field | Dropdown list |
| Best for | Ngày gần (1–90 days) | Ngày biết chính xác | Predefined options |
| UX | Visual calendar grid | Fast typing DD/MM/YYYY | Scroll through list |
| Ví dụ | Book appointment | Enter birth date (known) | Select month |
Decision Tree cho AI
text
Cần chọn date/time?
├─ Chọn 1 ngày → Date Picker (single)
│ ├─ Ngày gần (hẹn lịch, deadline) → Calendar popup
│ └─ Ngày xa (ngày sinh) → Text input + calendar fallback
│
├─ Chọn khoảng ngày → Date Picker (range)
│ ├─ Check-in/out, leave request → Range mode
│ └─ Report period (tháng/quý) → Month picker
│
├─ Chỉ cần tháng → Date Picker (month mode)
├─ Chỉ cần năm → Date Picker (year mode)
├─ Cần date + time → Date Picker + Time Picker (composite)
└─ Predefined periods ("Last 7 days") → Select/Dropdown
3. Anatomy
text
┌───────────────────────────┐
│ 📅 Select a date... ▼ │ ← Trigger (Input + icon)
└───────────────────────────┘
│ click
▼
┌───────────────────────────┐
│ ◀ March 2026 ▶ │ ← Header nav (month/year)
├───────────────────────────┤
│ Mo Tu We Th Fr Sa Su │ ← Weekday labels
├───────────────────────────┤
│ 1 2 3 4 │ ← Day cells (--surface bg)
│ 5 6 7 8 [9] 10 11 │ ← Selected: --primary bg
│ 12 13 14 15 16 17 18 │ ← Today: --primary border
│ 19 20 21 22 23 24 25 │ ← Hover: --state-layer-hover
│ 26 27 28 29 30 31 │
│ │
│ [ Today ] │ ← Quick action (optional)
└───────────────────────────┘ ← Panel: --surface, level-2
4. Platform Mapping
| Platform | Component | Key Difference |
|---|---|---|
| Web | Calendar popup dropdown | Month grid, click to select |
| iOS | UIDatePicker | Wheel picker (compact), inline calendar |
| Android (M3) | DatePicker / DateRangePicker | Modal calendar, text input option |
| Carbon | DatePicker | Text input + calendar flyout |
Cross-platform note: UX rất khác! Web dùng dropdown calendar, iOS dùng wheel, Android dùng modal. Token file covers the calendar grid pattern.
5. Modes
| Mode | Mô tả |
|---|---|
single |
Chọn 1 ngày |
range |
Chọn khoảng ngày (from → to) |
month |
Chọn tháng |
year |
Chọn năm |
5.4. Slot Map (Figma ↔ Code)
📎 Source:
slot-manifest.json→date-picker· Layer: surface
| Figma Slot | data-slot |
CSS Class | Required | Accepts |
|---|---|---|---|---|
| Root | date-picker |
.date-picker |
✅ | — |
| Trigger | date-picker-trigger |
— | ✅ | input-with-calendar-icon |
| Content | date-picker-content |
— | ✅ | calendar-grid |
| Header | date-picker-header |
— | ✅ | month/year nav |
| Grid | date-picker-grid |
— | ✅ | day cells |
| Footer | date-picker-footer |
— | ❌ | action buttons |
6. Token Mapping
📦 Atomic Mapping: Xem
ATOMIC-MAPPING.md→ mục date-picker — UI Layer: Surface (dropdown panel), Density Tier: section (panel) + comp (cells).Panel dùng
--surface, selected cell dùng--primary/--primary-foreground, today indicator dùng--primaryborder. Component token JSON files đã deprecated.
7. Props & API
typescript
interface DatePickerProps {
value?: Date | [Date, Date];
mode?: 'single' | 'range' | 'month' | 'year';
minDate?: Date;
maxDate?: Date;
disabledDates?: Date[] | ((date: Date) => boolean);
locale?: string;
firstDayOfWeek?: 0 | 1; // 0=Sunday, 1=Monday
placeholder?: string;
onChange: (date: Date | [Date, Date]) => void;
}
8. Accessibility (a11y)
- Trigger:
role="combobox",aria-haspopup="dialog". - Calendar:
role="grid", days =role="gridcell". - Selected:
aria-selected="true", today:aria-current="date". - Keyboard:
Arrow keysnavigate grid,Enterselects,Escapecloses. - Page Up/Down: Previous/next month.
9. Best Practices & Rules
- Locale-aware: Respect
firstDayOfWeek, month/weekday names. - Manual input: Allow typing date (DD/MM/YYYY) with validation.
- Today button: Quick action to jump to today.
- Outside days: Show dimmed days from adjacent months.
- Icon: Calendar icon (
calendar) CHỈ dùng Lucide icon từassets/icons/. CẤM dùng text emoji. Xemicon.mdmục 10.
10. Example Usage
jsx
{/* Single date selection */}
<DatePicker
mode="single"
value={selectedDate}
placeholder="Chọn ngày..."
minDate={new Date()}
onChange={setSelectedDate}
/>
{/* Date range for booking */}
<DatePicker
mode="range"
value={[checkIn, checkOut]}
placeholder="Check-in → Check-out"
minDate={new Date()}
disabledDates={bookedDates}
onChange={([from, to]) => { setCheckIn(from); setCheckOut(to); }}
/>
{/* Month picker for reports */}
<DatePicker
mode="month"
value={reportMonth}
placeholder="Chọn tháng báo cáo"
onChange={setReportMonth}
/>