at-react-autocomplete-1
Version:
An auto complete dropdown component for React with TypeScript support.
144 lines (117 loc) • 5.85 kB
Markdown
[](https://www.npmjs.com/package/at-react-autocomplete-1)
[](https://opensource.org/licenses/MIT)
A highly customizable, keyboard-accessible autocomplete dropdown component for **React + TypeScript**.
---
## ✨ Features
- ⌨️ **Full keyboard navigation** (↑/↓ arrows, Enter, Escape)
- ⏳ **Built-in debouncing** for API calls
- 🔄 **Loading state** support
- 🎨 **Customizable item rendering** with `renderItem`
- 📏 **Minimum search length** requirement
- 🖱️ **Mouse + keyboard** interaction support
- 🛠 **TypeScript-first** design
- 🎛 Supports **controlled** or **uncontrolled** input
- 🎨 Accepts `className` for easy styling
---
## 📦 Installation
```bash
npm install at-react-autocomplete-1
# or
yarn add at-react-autocomplete-1
```
## Props
| Prop | Type | Description |
| ------------------ | ------------------------------ | -------------------------------------------------------------------- |
| `suggestions` | `T[]` | Array of suggestions to display |
| `onInputChange` | `(value: string) => void` | Called when input changes (debounced) |
| `onSelect` | `(item: T) => void` | Called when item is selected |
| `renderItem` | `(item: T) => React.ReactNode` | Renders each dropdown item (default: text) |
| `getDisplayValue?` | `(item: T) => string` | Value to display in input when selected (default: `item.toString()`) |
| `onEnter?` | `(inputValue: string) => void` | Called when the ENTER button is pressed |
| `isLoading?` | `boolean` | Shows loading indicator |
| `placeholder?` | `string` | Input placeholder text |
| `className?` | `string` | Custom class names for container |
| `inputClassName` | `string` | Custom class names for the input element |
| `inputValue?` | `string` | Controlled input value |
| `setInputValue?` | `(value: string) => void` | Updates controlled input value |
| `minSearchLength?` | `number` | Minimum chars before searching (default: `2`) |
| `debounceDelay?` | `number` | Debounce delay in ms (default: `300`) |
## Example
```tsx
import React, { useState } from "react";
import AutocompleteDropdown from "at-react-autocomplete-1";
interface Country {
id: number;
name: string;
flag: string;
}
export default function Page() {
const [suggestions, setSuggestions] = useState<Country[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [selectedCountry, setSelectedCountry] = useState<Country | null>(null);
// Mock API fetch function
const fetchCountries = async (query: string) => {
if (query.length < 2) {
setSuggestions([]);
return;
}
setIsLoading(true);
try {
// In a real app, you would fetch from an actual API
// const response = await fetch(`/api/countries?q=${query}`);
// const data = await response.json();
// Mock data
const mockCountries: Country[] = [
{ id: 1, name: "United States", flag: "🇺🇸" },
{ id: 2, name: "United Kingdom", flag: "🇬🇧" },
{ id: 3, name: "Canada", flag: "🇨🇦" },
{ id: 4, name: "Australia", flag: "🇦🇺" },
{ id: 5, name: "Germany", flag: "🇩🇪" },
{ id: 6, name: "France", flag: "🇫🇷" },
{ id: 7, name: "Japan", flag: "🇯🇵" },
];
// Filter mock data based on query
const filtered = mockCountries.filter((country) =>
country.name.toLowerCase().includes(query.toLowerCase())
);
// Simulate network delay
await new Promise((resolve) => setTimeout(resolve, 500));
setSuggestions(filtered);
} catch (error) {
console.error("Error fetching countries:", error);
setSuggestions([]);
} finally {
setIsLoading(false);
}
};
const handleInputChange = (value: string) => {
fetchCountries(value);
};
const handleSelect = (country: Country) => {
setSelectedCountry(country);
alert("Selected country: " + country.name);
};
const renderCountryItem = (country: Country) => (
<div className="flex items-center gap-2 hover:bg-accent p-2">
<span className="text-xl">{country.flag}</span>
<span>{country.name}</span>
</div>
);
return (
<AutocompleteDropdown<Country>
suggestions={suggestions}
onInputChange={handleInputChange}
onSelect={handleSelect}
renderItem={renderCountryItem}
getDisplayValue={(country) => country.name}
onEnter={(inputValue) => console.log("Value", inputValue)}
isLoading={isLoading}
placeholder="Search countries..."
className=" border rounded-md "
inputClassName="p-2"
/>
);
}
```
Do you also want me to add **badges for CI status, bundle size (bundlephobia), and TypeScript support** so it looks like a polished open-source package?