Prisma
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.jsonsearch · 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-expanded toggles with suggestion panel.
  • aria-activedescendant tracks highlighted suggestion.
  • Keyboard: Arrow Down opens/navigates suggestions, Escape closes, Enter submits.

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. Xem icon.md mụ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}
/>