UNPKG

at-react-autocomplete-1

Version:

An auto complete dropdown component for React with TypeScript support.

144 lines (117 loc) 5.85 kB
[![npm version](https://badge.fury.io/js/at-react-autocomplete-1 .svg)](https://www.npmjs.com/package/at-react-autocomplete-1) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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?