Combobox

A searchable dropdown component that combines the functionality of a select and input field with filtering capabilities.

Installation

Install the component:

npx natively-ui add combobox

Usage

ComboboxDemo.jsx
1import { Combobox } from '@/components/ui/combobox'; 2 3const items = [ 4 { value: "apple", label: "Apple" }, 5 { value: "banana", label: "Banana" }, 6 { value: "orange", label: "Orange" }, 7]; 8 9export default function MyComponent() { 10 return ( 11 <Combobox 12 items={items} 13 placeholder="Select a fruit..." 14 onValueChange={(value) => console.log('Selected:', value)} 15 /> 16 ); 17}

Props

PropTypeDefaultDescription
itemsComboboxItem[]-Array of items to display in the dropdown. Each item should have value and label properties.
defaultValuestring""Initial selected value for uncontrolled combobox.
valuestring-Controlled value for the combobox. When provided, combobox becomes controlled.
onValueChange(value: string) => void-Function called when the selected value changes.
placeholderstring"Select an option..."Text displayed when no item is selected.
searchPlaceholderstring"Search..."Placeholder text for the search input field.
emptyMessagestring"No results found."Message shown when no items match the search query.
disabledbooleanfalseWhether the combobox is disabled.
classNamestring""Additional CSS classes for the combobox container.
buttonClassNamestring""Additional CSS classes for the trigger button.
contentClassNamestring""Additional CSS classes for the dropdown content.
widthnumber300Width of the combobox and dropdown in pixels.
maxHeightnumber300Maximum height of the dropdown content in pixels.

Types

types.ts
1interface ComboboxItem { 2 value: string; 3 label: string; 4}

Features

  • Real-time search filtering with case-insensitive matching
  • Controlled and uncontrolled modes for flexible state management
  • Modal-based dropdown with backdrop dismissal
  • Built-in accessibility support with proper ARIA attributes
  • Keyboard navigation and focus management
  • Customizable sizing with width and maxHeight props
  • Visual selection indicators with checkmarks
  • Empty state handling with custom messages
  • Responsive design that adapts to screen height
  • Custom styling support with multiple className props

Examples

Basic Usage

ComboboxDemo.jsx
1const fruits = [ 2 { value: "apple", label: "Apple" }, 3 { value: "banana", label: "Banana" }, 4 { value: "orange", label: "Orange" }, 5 { value: "grape", label: "Grape" }, 6 { value: "strawberry", label: "Strawberry" }, 7]; 8 9<Combobox 10 items={fruits} 11 placeholder="Choose a fruit..." 12 onValueChange={(value) => console.log('Selected:', value)} 13/>

Controlled Combobox

ComboboxDemo.jsx
1const [selectedValue, setSelectedValue] = useState(""); 2 3const countries = [ 4 { value: "us", label: "United States" }, 5 { value: "ca", label: "Canada" }, 6 { value: "uk", label: "United Kingdom" }, 7 { value: "au", label: "Australia" }, 8]; 9 10<View style={{ gap: 16 }}> 11 <Combobox 12 items={countries} 13 value={selectedValue} 14 onValueChange={setSelectedValue} 15 placeholder="Select country..." 16 /> 17 18 <Text>Selected: {selectedValue || 'None'}</Text> 19</View>

Custom Sizing

ComboboxDemo.jsx
1const options = [ 2 { value: "option1", label: "Very long option name that might overflow" }, 3 { value: "option2", label: "Another lengthy option description" }, 4 { value: "option3", label: "Short option" }, 5]; 6 7<View style={{ gap: 16 }}> 8 <Combobox 9 items={options} 10 width={400} 11 maxHeight={200} 12 placeholder="Wide combobox..." 13 /> 14 15 <Combobox 16 items={options} 17 width={200} 18 maxHeight={150} 19 placeholder="Narrow combobox..." 20 /> 21</View>

Custom Messages

ComboboxDemo.jsx
1const products = [ 2 { value: "laptop", label: "Laptop" }, 3 { value: "phone", label: "Smartphone" }, 4 { value: "tablet", label: "Tablet" }, 5]; 6 7<Combobox 8 items={products} 9 placeholder="Find your device..." 10 searchPlaceholder="Type to search devices..." 11 emptyMessage="No devices match your search." 12 onValueChange={(value) => console.log('Product:', value)} 13/>

Large Dataset

ComboboxDemo.jsx
1// Generate a large list of options 2const generateOptions = () => { 3 const options = []; 4 for (let i = 1; i <= 1000; i++) { 5 options.push({ 6 value: `item-${i}`, 7 label: `Item ${i} - Sample data entry` 8 }); 9 } 10 return options; 11}; 12 13const largeDataset = generateOptions(); 14 15<Combobox 16 items={largeDataset} 17 placeholder="Search from 1000 items..." 18 searchPlaceholder="Type to filter..." 19 width={350} 20 maxHeight={250} 21 onValueChange={(value) => console.log('Selected item:', value)} 22/>

Custom Styling

ComboboxDemo.jsx
1const themes = [ 2 { value: "light", label: "Light Theme" }, 3 { value: "dark", label: "Dark Theme" }, 4 { value: "auto", label: "Auto Theme" }, 5]; 6 7<Combobox 8 items={themes} 9 placeholder="Select theme..." 10 buttonClassName="border-blue-500 bg-blue-50" 11 contentClassName="border-blue-300" 12 className="shadow-lg" 13 width={280} 14 onValueChange={(value) => console.log('Theme:', value)} 15/>

Disabled State

ComboboxDemo.jsx
1const options = [ 2 { value: "option1", label: "Option 1" }, 3 { value: "option2", label: "Option 2" }, 4]; 5 6<View style={{ gap: 16 }}> 7 <Combobox 8 items={options} 9 placeholder="Disabled combobox" 10 disabled 11 /> 12 13 <Combobox 14 items={options} 15 defaultValue="option1" 16 disabled 17 /> 18</View>