Live Preview
--- description: Hướng dẫn Agent tạo Search Bar — ô tìm kiếm với gợi ý, lịch sử
Search Bar Component
Skill này hướng dẫn tạo component Search Bar — input tìm kiếm với suggestion dropdown, recent searches, và expandable behavior.
1. Mục tiêu (Objective)
Tạo Search Bar: expandable search input + suggestion dropdown + recent searches. Hỗ trợ debounce, autocomplete, category filtering.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Search Bar?
- Global search: Tìm kiếm toàn app (header search)
- List/table filtering: Lọc danh sách theo keyword
- autocomplete lookup: Tìm user, sản phẩm, địa chỉ
⚠️ Phân biệt Search vs Input vs Command Palette (QUAN TRỌNG)
| Tiêu chí | Search Bar | Text Input | Command Palette |
|---|---|---|---|
| Bản chất | Tìm kiếm + gợi ý | Nhập liệu tự do | Quick actions + search |
| Trigger | Always visible / expandable | Always visible | Ctrl+K shortcut |
| Suggestions | ✅ Results + history | ❌ No dropdown | ✅ Actions + results |
| Ví dụ | Header search, product search | Username field | Spotlight/Cmd Palette |
Decision Tree cho AI
text
User cần tìm kiếm?
├─ Tìm content/data trong app → Search Bar
│ ├─ Header/toolbar search → Search Bar (default, persistent)
│ ├─ Mobile header search → Search Bar (expandable, icon → input)
│ ├─ Inline trong table/list → Search Bar (compact, no suggestions)
│ └─ E-commerce product search → Search Bar + category filter
│
├─ Quick actions + navigation → Command Palette (Ctrl+K)
├─ Filter existing list → Input + Filter logic (no suggestions)
└─ Select from known options → Select / Combobox
3. Anatomy
text
┌──────────────────────────────────────────┐
│ 🔍 Search products... ✕ │ ← Input (--input bg, --input-border)
└──────────────────────────────────────────┘
│ focus + type
▼
┌──────────────────────────────────────────┐
│ Recent Searches │ ← Section header (--muted-foreground)
│ ├─ 🕐 blue sneakers │ ← Recent item (--state-layer-hover)
│ └─ 🕐 wireless earbuds │
├──────────────────────────────────────────┤ ← --border
│ Suggestions │
│ ├─ 🔍 blue **jacket** (men's) │ ← Match highlight (--primary)
│ └─ 🔍 blue **jeans** women │
└──────────────────────────────────────────┘ ← Panel: reuse select/dropdown panel
4. Platform Mapping
| Platform | Component | Key Difference |
|---|---|---|
| Web | Search input + dropdown | Custom autocomplete panel |
| iOS | UISearchBar / .searchable | System search with cancel button |
| Android (M3) | SearchBar / SearchView | Expanding from icon to full toolbar |
| Fluent | SearchBox | Filterable with clear button |
| Carbon | Search | Persistent or expandable |
Cross-platform: ALL platforms có search, nhưng UX varies significantly.
5. States
| State | Mô tả |
|---|---|
collapsed |
Icon only (expandable variant) |
default |
Full input visible, placeholder |
focused |
Input focused, suggestion panel may open |
with-suggestions |
Dropdown showing results/history |
5.4. Slot Map (Figma ↔ Code)
📎 Source:
slot-manifest.json→search· Layer: item
| Figma Slot | data-slot |
CSS Class | Required | Accepts |
|---|---|---|---|---|
| Root | search |
.search |
✅ | — |
| Input | search-input |
.search-input |
✅ | text-input |
| Icon | search-icon |
— | ✅ | search-icon |
| Clear | search-clear |
— | ❌ | clear-button |
| Results | search-results |
.search-results |
❌ | list, search-item-group |
6. Token Mapping
📦 Atomic Mapping: Xem
ATOMIC-MAPPING.md→ mục search — UI Layer: Card (in-flow), Density Tier: comp.Input dùng
--input/--input-border, focus ring dùng--primary/--primary-muted, icon dùng--muted-foreground. Component token JSON files đã deprecated.
7. Props & API
typescript
interface SearchBarProps {
value?: string;
placeholder?: string;
expandable?: boolean;
suggestions?: SearchSuggestion[];
recentSearches?: string[];
showClear?: boolean;
onChange: (value: string) => void;
onSubmit?: (value: string) => void;
onSuggestionSelect?: (suggestion: SearchSuggestion) => void;
}
8. Accessibility (a11y)
role="search"on container,role="combobox"on input.aria-expandedtoggles with suggestion panel.aria-activedescendanttracks highlighted suggestion.- Keyboard:
Arrow Downopens/navigates suggestions,Escapecloses,Entersubmits.
9. Best Practices & Rules
- Debounce: 300ms debounce before fetching suggestions.
- Min chars: Require 2+ characters before showing suggestions.
- Match highlight: Bold matching text in suggestions.
- Mobile: Full-width, auto-focus keyboard on tap.
- Icon: Search icon (
search), clear icon (x) CHỈ dùng Lucide icon từassets/icons/. CẤM dùng text emoji. Xemicon.mdmục 10.
10. Example Usage
jsx
{/* Header search with suggestions */}
<SearchBar
placeholder="Tìm sản phẩm..."
suggestions={searchResults}
recentSearches={recent}
showClear
onChange={handleSearch}
onSubmit={handleSubmit}
onSuggestionSelect={handleSelect}
/>
{/* Expandable mobile search */}
<SearchBar
expandable
placeholder="Tìm kiếm..."
onChange={handleFilter}
/>
{/* Table inline filter (no suggestions) */}
<SearchBar
placeholder="Lọc theo tên..."
showClear
onChange={setFilterText}
/>