SearchableSelect
A searchable dropdown select component built on top of Combobox.
Import
import { SearchableSelect } from '@/components/ui';
Basic Usage
'use client';
import { useState } from 'react';
import { SearchableSelect } from '@/components/ui';
const options = [
{ id: '1', name: 'Option 1' },
{ id: '2', name: 'Option 2' },
{ id: '3', name: 'Option 3' },
];
export function Example() {
const [value, setValue] = useState('');
return (
<SearchableSelect
value={value}
onChange={setValue}
options={options}
placeholder="Select an option..."
/>
);
}
Props
| Prop |
Type |
Default |
Description |
value |
string |
required |
Selected option ID |
onChange |
(value: string) => void |
required |
Change handler |
options |
Array<{ id: string, name: string }> |
required |
Available options |
label |
string |
- |
Label text |
placeholder |
string |
- |
Placeholder text |
disabled |
boolean |
false |
Disable select |
className |
string |
- |
Additional CSS classes |
aria-label |
string |
- |
Accessibility label |
With Label
<SearchableSelect
label="Country"
value={country}
onChange={setCountry}
options={countries}
placeholder="Search countries..."
/>
Country Selector Example
'use client';
import { useState } from 'react';
import { SearchableSelect } from '@/components/ui';
const countries = [
{ id: 'us', name: 'United States' },
{ id: 'uk', name: 'United Kingdom' },
{ id: 'ca', name: 'Canada' },
{ id: 'au', name: 'Australia' },
{ id: 'de', name: 'Germany' },
{ id: 'fr', name: 'France' },
// ... more countries
];
export function CountrySelector() {
const [country, setCountry] = useState('');
return (
<SearchableSelect
label="Country"
value={country}
onChange={setCountry}
options={countries}
placeholder="Search for a country..."
/>
);
}
Role Selector Example
'use client';
import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { SearchableSelect, Spinner } from '@/components/ui';
export function RoleSelector({ value, onChange }) {
const { data: roles, isLoading } = useQuery({
queryKey: ['roles'],
queryFn: fetchRoles,
});
if (isLoading) return <Spinner />;
const options = roles.map((role) => ({
id: role.id,
name: role.name,
}));
return (
<SearchableSelect
label="Role"
value={value}
onChange={onChange}
options={options}
placeholder="Select a role..."
/>
);
}
Form Integration
'use client';
import { useState } from 'react';
import { SearchableSelect, Input, Button } from '@/components/ui';
export function UserForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
roleId: '',
organizationId: '',
});
const handleSubmit = (e) => {
e.preventDefault();
// Submit form
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<Input
label="Name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
<Input
label="Email"
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
/>
<SearchableSelect
label="Role"
value={formData.roleId}
onChange={(value) => setFormData({ ...formData, roleId: value })}
options={roles}
placeholder="Select a role..."
/>
<SearchableSelect
label="Organization"
value={formData.organizationId}
onChange={(value) => setFormData({ ...formData, organizationId: value })}
options={organizations}
placeholder="Select an organization..."
/>
<Button type="submit" color="blue">
Create User
</Button>
</form>
);
}
Features
- Search filtering - Type to filter options
- Keyboard navigation - Arrow keys, Enter to select
- Virtual scrolling - Handles large option lists
- Accessible - ARIA labels and roles
- Dark mode - Full dark mode support
When to Use
| Scenario |
Component |
| Few options (<10) |
Select |
| Many options (10+) |
SearchableSelect |
| Custom option rendering |
Combobox |
| Multi-select |
Custom implementation |
See Also
- Select - Native select dropdown
- Combobox - Advanced autocomplete component