پرتوپرتو

اتوکامپلیت

کامپوننت Autocomplete برای جستجو و پیشنهاد نتایج

معرفی

کامپوننت Autocomplete یک input هوشمند با قابلیت نمایش پیشنهادهای لحظه‌ای است که شامل:

  • جستجوی Debounced (تاخیر هوشمند)
  • نمایش لیست پیشنهادها با scroll
  • Keyboard Navigation (پیمایش با کیبورد)
  • Click Outside (بسته شدن با کلیک خارج)
  • Loading State (نمایش وضعیت بارگذاری)
  • RTL Support (پشتیبانی کامل از راست به چپ)
  • Custom Render (سفارشی‌سازی نمایش هر مورد)

چه زمانی استفاده کنیم:

  • وقتی کاربر باید از لیست بزرگی (بیش از ۱۵ گزینه) جستجو و انتخاب کند
  • وقتی گزینه‌ها از سرور یا API دریافت می‌شوند
  • وقتی نمایش سفارشی هر گزینه (آواتار، آیکون و ...) مورد نیاز است

چه زمانی استفاده نکنیم:

  • برای لیست‌های کوچک (زیر ۱۵ گزینه) — از Select استفاده کنید
  • برای انتخاب چند گزینه — از MultiSelect استفاده کنید
  • وقتی کاربر باید مقدار جدید تایپ کند (نه از لیست انتخاب) — از Input با TagInput استفاده کنید

استفاده

import { Autocomplete } from '@parto-system-design/ui'

استفاده پایه

مثال ساده

با آیکون

Async (غیرهمزمان)

برای جستجوی سرور و API calls:

نسخه LTR (چپ به راست)

Props

Autocomplete

Prop

Type

AutocompleteItem

interface AutocompleteItem {
  value: string // مقدار یکتا
  label: string // برچسب نمایشی
  [key: string]: unknown // فیلدهای اضافی دلخواه
}

حالت‌ها و انواع

حالت بارگذاری

هنگام دریافت داده از سرور، isLoading را فعال کنید تا Spinner نمایش داده شود.

حالت Controlled و Uncontrolled

  • Controlled: از value و onValueChange استفاده کنید
  • Uncontrolled: از defaultValue استفاده کنید

جهت نمایش

با dir می‌توانید جهت RTL یا LTR را تنظیم کنید.

پاک‌سازی پس از انتخاب

با clearOnSelect={true} پس از هر انتخاب، input پاک می‌شود.

راهنمای استفاده

بکنید

  • برای جستجوی API، حتماً از onSearch استفاده کنید و debounceDelay مناسب تنظیم کنید - از minChars استفاده کنید تا جستجو با تعداد کاراکتر کم شروع نشود - از renderItem برای سفارشی‌سازی نمایش هر گزینه بهره ببرید

نکنید

  • بدون debounceDelay مناسب، درخواست‌های زیادی به سرور ارسال نکنید - از Autocomplete برای لیست‌های کوچک (زیر ۱۵ گزینه) استفاده نکنید — Select مناسب‌تر است - مقدار maxHeight را بیش از حد بزرگ تنظیم نکنید تا تجربه کاربری مختل نشود

موارد استفاده

جستجوی کاربران با API

import { Autocomplete } from '@parto-system-design/ui'
import { useState } from 'react'

export function UserSearch() {
  const [value, setValue] = useState('')
  const [suggestions, setSuggestions] = useState([])
  const [isLoading, setIsLoading] = useState(false)

  const handleSearch = async (query: string) => {
    setIsLoading(true)
    try {
      const response = await fetch(`/api/users/search?q=${query}`)
      const data = await response.json()
      setSuggestions(data.users)
    } catch (error) {
      console.error(error)
    } finally {
      setIsLoading(false)
    }
  }

  return (
    <Autocomplete
      value={value}
      onValueChange={setValue}
      suggestions={suggestions}
      isLoading={isLoading}
      onSearch={handleSearch}
      placeholder="جستجوی کاربر..."
      minChars={2}
      dir="rtl"
      renderItem={(item) => (
        <div className="flex items-center gap-3">
          <img src={item.avatar} className="w-10 h-10 rounded-full" />
          <div>
            <div className="font-medium">{item.name}</div>
            <div className="text-sm text-muted-foreground">@{item.username}</div>
          </div>
        </div>
      )}
      onSelect={(user) => {
        console.log('Selected user:', user)
      }}
    />
  )
}

انتخاب کشور با آیکون

import { Autocomplete } from '@parto-system-design/ui'

const countries = [
  { value: 'ir', label: 'ایران', icon: '🇮🇷' },
  { value: 'us', label: 'آمریکا', icon: '🇺🇸' },
  { value: 'uk', label: 'انگلستان', icon: '🇬🇧' },
]

export function CountrySelect() {
  const [value, setValue] = useState('')
  const [suggestions, setSuggestions] = useState(countries)

  return (
    <Autocomplete
      value={value}
      onValueChange={setValue}
      suggestions={suggestions}
      onSearch={(query) => {
        setSuggestions(countries.filter((c) => c.label.includes(query)))
      }}
      placeholder="انتخاب کشور..."
      renderItem={(item) => (
        <div className="flex items-center gap-2">
          <span className="text-2xl">{item.icon}</span>
          <span>{item.label}</span>
        </div>
      )}
    />
  )
}

فرم با Autocomplete

import { Autocomplete, Button, Label } from '@parto-system-design/ui'
import { useState } from 'react'

export function UserForm() {
  const [selectedUser, setSelectedUser] = useState('')

  return (
    <form className="space-y-4" dir="rtl">
      <div className="space-y-2">
        <Label>انتخاب کاربر</Label>
        <Autocomplete
          value={selectedUser}
          onValueChange={setSelectedUser}
          // ... props
        />
      </div>
      <Button type="submit">ارسال</Button>
    </form>
  )
}

Clear On Select

برای موارد استفاده مثل ارسال ایمیل که بعد از هر انتخاب input پاک شود:

<Autocomplete
  clearOnSelect={true}
  onSelect={(item) => {
    // Add to recipients list
    addRecipient(item)
  }}
/>

Keyboard Shortcuts

کلیدعملکرد
↓ Arrow Downحرکت به پیشنهاد بعدی
↑ Arrow Upحرکت به پیشنهاد قبلی
Enterانتخاب پیشنهاد فعال
Escapeبستن منوی پیشنهادها

دسترسی‌پذیری

  • پیمایش بین پیشنهادها با کلیدهای و
  • انتخاب پیشنهاد فعال با Enter
  • بستن منوی پیشنهادها با Escape
  • بسته شدن خودکار با کلیک خارج از کامپوننت
  • پشتیبانی کامل از RTL و LTR
  • نقش listbox برای لیست پیشنهادها و option برای هر آیتم

کامپوننت‌های مرتبط

  • اگر لیست گزینه‌ها کوچک و ثابت است (زیر ۱۵ مورد) → Select
  • اگر نیاز به انتخاب چندین گزینه همزمان دارید → MultiSelect
  • اگر جستجوی شما مختص کاربران است و نیاز به نمایش آواتار و فالوور دارید → UserAutocomplete
  • اگر نیاز به پالت دستورات با کلید میانبر دارید → Command