Autocomplete
Preview
Async Data
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
import { BadgeCheck } from "lucide-react";
async function fetchBook(query: string): Promise<Place[]> {
const url = `https://openlibrary.org/search.json?q=${query}`;
const resp = await fetch(url);
const data = await resp.json();
return data?.docs;
}
export default function Page() {
return (
<Autocomplete
fetchOptions={fetchBook}
idField="cover_i"
labelField="title"
onChange={(e) => {}}
startAdornment={<BadgeCheck size={18} />}
/>
);
}
Default Component
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: 1, name: "تهران"},
{ code: 2, name: "اصفهان"},
{ code: 3, name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
onChange={(e) => {}}
/>
</div>
);
}
Size
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: 1, name: "تهران"},
{ code: 2, name: "اصفهان"},
{ code: 3, name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
size="xs"
onChange={(e) => {}}
/>
</div>
);
}
Has Error
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: 1, name: "تهران"},
{ code: 2, name: "اصفهان"},
{ code: 3, name: "مشهد"}
]}
isDropDown={true}
hasError={true}
idField="code"
labelField="name"
onChange={(e) => {}}
/>
</div>
);
}
Default value
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ id: "1", label: "خراسان رضوی"},
{ id: "2", label: "تهران"},
{ id: "3", label: "خراسان شمالی"},
{ id: "4", label: "کردستان"},
{ id: "5", label: "خراسان جنوبی"},
{ id: "6", label: "کرمان"},
{ id: "7", label: "خوزستان"},
{ id: "8", label: "همدان"},
{ id: "9", label: "کرمانشاه"}
]}
defaultValue={[
{ id: "4", label: "کردستان"},
{ id: "5", label: "خراسان جنوبی"}
]}
isDropDown={true}
onChange={(e) => {}}
/>
</div>
);
}
ReadOnly
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: 1, name: "تهران"},
{ code: 2, name: "اصفهان"},
{ code: 3, name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
inputProps={{
readOnly : true,
placeholder:"جستجو کنید",
}}
onChange={(e) => {}}
/>
</div>
);
}
Disabled
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: 1, name: "تهران"},
{ code: 2, name: "اصفهان"},
{ code: 3, name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
inputProps={{
disabled : true,
placeholder:"جستجو کنید",
}}
onChange={(e) => {}}
/>
</div>
);
}
Mulitple Select
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: "1", name: "تهران"},
{ code: "2", name: "اصفهان"},
{ code: "3", name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
multiple={false}
onChange={(e) => {}}
/>
</div>
);
}
DropDown Icon
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ code: "1", name: "تهران"},
{ code: "2", name: "اصفهان"},
{ code: "3", name: "مشهد"}
]}
isDropDown={true}
idField="code"
labelField="name"
multiple={false}
onChange={(e) => {}}
/>
</div>
);
}
Variant
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function Page() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<Autocomplete
options={[
{ id: "1", label: "خراسان رضوی"},
{ id: "2", label: "تهران"},
{ id: "3", label: "خراسان شمالی"},
{ id: "4", label: "کردستان"},
{ id: "5", label: "خراسان جنوبی"},
{ id: "6", label: "کرمان"},
{ id: "7", label: "خوزستان"},
{ id: "8", label: "همدان"},
{ id: "9", label: "کرمانشاه" }
]}
isDropDown={true}
onChange={(e) => {}}
variant="secondary"
/>
</div>
);
}
RenderOption
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
interface User {
id: number;
name: string;
email: string;
role: string;
avatar?: string;
}
export default function UserAutocomplete() {
const users: User[] = [
{ id: 1, name: "علیرضا محمدی", email: "ali@example.com", role: "مدیر" },
{ id: 2, name: "فاطمه کریمی", email: "fatemeh@example.com", role: "کاربر" },
{ id: 3, name: "محمد حسینی", email: "mohammad@example.com", role: "نویسنده" },
];
const renderUserOption = (user: User, isSelected: boolean) => (
<div className="flex items-center gap-3 p-2">
<div className="flex-1">
<div className="font-medium text-gray-800">{user.name}</div>
<div className="text-sm text-gray-500">{user.email}</div>
</div>
<div className={`px-2 py-1 rounded-full text-xs ${
user.role === "مدیر" ? "bg-red-100 text-red-800" :
user.role === "نویسنده" ? "bg-blue-100 text-blue-800" :
"bg-gray-100 text-gray-800"
}`}>
{user.role}
</div>
{isSelected && (
<div className="text-green-500 text-lg">✓</div>
)}
</div>
);
return (
<Autocomplete
options={users}
renderOption={renderUserOption}
labelField="name"
idField="id"
onChange={(user) => console.log("Selected user:", user)}
/>
);
}
Ref
import { useRef, useState } from "react";
import Autocomplete from "@repo/ui/Autocomplete";
export default function MultipleSelection() {
const tagsRef = useRef<any>(null);
const handleFocus = () => {
tagsRef.current?.focus();
};
const handleClearAll = () => {
tagsRef.current?.clear();
};
const showSelectedValues = () => {
const values = tagsRef.current?.getSelectedValue();
console.log("Selected tags:", values);
alert(`تگهای انتخاب شده: ${JSON.stringify(values, null, 2)}`);
};
return (
<div className="w-full">
<Autocomplete
ref={tagsRef}
name="tags"
multiple
options={[
{ id: "react", label: "React" },
{ id: "vue", label: "Vue" },
{ id: "angular", label: "Angular" },
{ id: "svelte", label: "Svelte" },
{ id: "nextjs", label: "Next.js" },
{ id: "nuxt", label: "Nuxt" },
]}
onChange={(tags) => {
console.log("Tags changed:", tags);
}}
/>
<div className="flex gap-2 flex-wrap">
<Button variant="contained" color="brand" onClick={handleFocus}>
فوکوس
</Button>
<Button variant="contained" color="brand" onClick={handleClearAll}>
پاک کردن همه
</Button>
<Button variant="contained" color="brand" onClick={showSelectedValues}>
نمایش مقادیر
</Button>
</div>
</div>
);
}
Installation
npx the-dig@latest add Autocomplete,Menu,CircularProgress,Chip
Props
Autocomplete
| Prop | Type | Default |
|---|---|---|
options * | Array | - |
fetchOptions * | promise | - |
debounceDelay | number | 500 |
value | object | Array<object> | string | Array<string> | - |
defaultValue | object | Array<object> | string | Array<string> | - |
name | string | - |
onChange | function | - |
notFoundText | string | موردی یافت نشد |
isDropDown | boolean | true |
searchingText | string | در حال جستجو... |
className | string | - |
idField | string | id |
labelField | string | label |
minSearchChars | number | 3 |
hasError | boolean | false |
size | "xs" | "sm" | "md" | "lg"| "xl" | md |
width | string | 100% |
variant | "primary" | "secondary" | | primary |
maxDropdownHeight | number | 200 |
renderOption | ReactNode | - |
id | string | - |
inputProps | HTMLAttributes<HTMLInputElement> (placeholder, disabled, readOnly , etc.) | Document |