In this blog, we are going to build a searchable select component. A searchable select component has a search field, which users can use to search and filter the options before selecting.
1. Create a React Project
First, create a React project.
npm create vite@latest react-searchable-select -- --template react
cd react-searchable-select
npm install
npm run dev
2. Create the Options List
Next, create a list of options for the selection.
const options = [
{ label: "India", value: "india" },
{ label: "United States", value: "usa" },
{ label: "United Kingdom", value: "uk" },
{ label: "Canada", value: "canada" },
{ label: "Australia", value: "australia" },
{ label: "Germany", value: "germany" },
{ label: "France", value: "france" },
];
3. Create the Searchable Select Component
Now, create a new file named SearchableSelect.jsx and add this code.
import { useState } from "react";
export default function SearchableSelect() {
const [isOpen, setIsOpen] = useState(false);
const [search, setSearch] = useState("");
const [selected, setSelected] = useState(null);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{selected ? selected.label : "Select a country"}
</button>
</div>
);
}4. Add a Search Input
Next, we can add the input field for the search function.
{isOpen && (
<div>
<input
type="text"
placeholder="Search countries..."
value={search}
onChange={(event) => setSearch(event.target.value)}
/>
</div>
)}5. Filter the Options
Update the component and add this function to filter.
const filteredOptions = options.filter((option) =>
option.label.toLowerCase().includes(search.toLowerCase())
);
Next, connect the filtered data to the dropdown list. Add this code.
{filteredOptions.length > 0 ? (
filteredOptions.map((option) => (
<button
key={option.value}
onClick={() => {
setSelected(option);
setIsOpen(false);
setSearch("");
}}
>
{option.label}
</button>
))
) : (
<p>No options found</p>
)}6. Add Basic Styling
We are using tailwind css classes to add styles to the select component.
<div className="relative w-64">
<button
onClick={() => setIsOpen(!isOpen)}
className="w-full rounded-md border bg-white px-4 py-2 text-left"
>
{selected ? selected.label : "Select a country"}
</button>
{isOpen && (
<div className="absolute z-10 mt-1 w-full rounded-md border bg-white p-2 shadow-lg">
<input
type="text"
placeholder="Search countries..."
value={search}
onChange={(event) => setSearch(event.target.value)}
className="mb-2 w-full rounded border px-3 py-2"
/>
{/* Filtered options go here */}
</div>
)}
</div>
7. Complete Searchable Select Component
import { useState } from "react";
const options = [
{ label: "India", value: "india" },
{ label: "United States", value: "usa" },
{ label: "United Kingdom", value: "uk" },
{ label: "Canada", value: "canada" },
{ label: "Australia", value: "australia" },
{ label: "Germany", value: "germany" },
{ label: "France", value: "france" },
];
export default function SearchableSelect() {
const [isOpen, setIsOpen] = useState(false);
const [search, setSearch] = useState("");
const [selected, setSelected] = useState(null);
const filteredOptions = options.filter((option) =>
option.label.toLowerCase().includes(search.toLowerCase())
);
const handleSelect = (option) => {
setSelected(option);
setIsOpen(false);
setSearch("");
};
return (
<div className="relative w-64">
<button
type="button"
onClick={() => setIsOpen(!isOpen)}
className="w-full rounded-md border bg-white px-4 py-2 text-left"
>
{selected ? selected.label : "Select a country"}
</button>
{isOpen && (
<div className="absolute z-10 mt-1 w-full rounded-md border bg-white p-2 shadow-lg">
<input
type="text"
placeholder="Search countries..."
value={search}
onChange={(event) => setSearch(event.target.value)}
className="mb-2 w-full rounded border px-3 py-2"
/>
<div className="max-h-48 overflow-y-auto">
{filteredOptions.length > 0 ? (
filteredOptions.map((option) => (
<button
key={option.value}
type="button"
onClick={() => handleSelect(option)}
className="block w-full rounded px-3 py-2 text-left hover:bg-gray-100"
>
{option.label}
</button>
))
) : (
<p className="px-3 py-2 text-sm text-gray-500">
No options found
</p>
)}
</div>
</div>
)}
</div>
);
}Now, import our component into App.jsx to view it.
import SearchableSelect from "./SearchableSelect";
function App() {
return (
<div className="p-6">
<SearchableSelect />
</div>
);
}
export default App;
In this blog, we have checked how to create a searchable select component. We can use this component to filter a large list of options. You can also extend this component with features like keyboard support, api search, multiple select, etc.
To read more about How to Build an Undo/Redo Feature in React, refer to our blog How to Build an Undo/Redo Feature in React.