Combobox
Searchable combobox component with filtering, keyboard navigation, and accessibility for advanced option selection
Installation
Install the Combobox component using the nocta-ui CLI:
npx nocta-ui add combobox
Then import the component:
import { Combobox, ComboboxOption } from '@/components/ui/combobox';
Basic Usage
The Combobox component provides a searchable dropdown interface for selecting from a list of options.
Data Structure
The Combobox component expects an array of options with the following structure:
interface ComboboxOption {
value: string; // Unique identifier
label: string; // Display text
disabled?: boolean; // Optional disabled state
}
Variants
The Combobox component supports three visual variants: default
, error
, and success
.
This field is required
Selection confirmed
Sizes
Three size options are available: sm
, md
, and lg
. The default size is md
.
Searchable Options
Control whether users can search through options by typing.
Type to filter options
Dropdown only, no search
Clearable Selection
Control whether users can clear their selection with an X button.
X button appears when value is selected
No clear button shown
Disabled Options
Individual options can be disabled by setting the disabled
property.
Some options are disabled (e.g., PHP)
Disabled State
The entire combobox can be disabled.
Entire combobox is disabled
Custom Messages
Customize the empty state message when no options match the search.
Type something that doesn't match to see custom message
Controlled vs Uncontrolled
Uncontrolled (Recommended)
Use defaultValue
for uncontrolled behavior:
<Combobox
options={options}
defaultValue="react"
onValueChange={(value) => console.log('Selected:', value)}
/>
Controlled
Use value
and onValueChange
for controlled behavior:
Current value: react
Keyboard Navigation
The Combobox component includes comprehensive keyboard support:
- Arrow Down: Open dropdown or move to next option
- Arrow Up: Open dropdown or move to previous option
- Enter: Select the highlighted option or open dropdown
- Escape: Close dropdown and clear search
- Tab: Close dropdown and move to next element
- Type to search: Filter options when searchable is enabled
Accessibility Features
The Combobox component is built with accessibility in mind:
- ARIA Attributes: Proper
role
,aria-expanded
,aria-controls
, andaria-haspopup
attributes - Keyboard Navigation: Full keyboard support with arrow keys and shortcuts
- Focus Management: Proper focus handling and visual focus indicators
- Screen Reader Support: Announces option selection and state changes
- Semantic HTML: Uses proper button and listbox elements
- Option Highlighting: Visual indication of focused options
Advanced Usage
Dynamic Options
Create options dynamically from API data:
const [options, setOptions] = useState<ComboboxOption[]>([]);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(users => {
const userOptions = users.map(user => ({
value: user.id,
label: `${user.name} (${user.email})`,
disabled: !user.active
}));
setOptions(userOptions);
});
}, []);
<Combobox
options={options}
placeholder="Select a user..."
emptyMessage="No users found"
/>
Form Integration
Use with form libraries like React Hook Form:
import { useForm, Controller } from 'react-hook-form';
const { control, handleSubmit } = useForm();
<Controller
name="framework"
control={control}
rules={{ required: 'Please select a framework' }}
render={({ field, fieldState }) => (
<Combobox
options={frameworks}
value={field.value}
onValueChange={field.onChange}
variant={fieldState.error ? 'error' : 'default'}
placeholder="Select framework..."
/>
)}
/>
Custom Styling
Customize the appearance with className props:
<Combobox
options={options}
className="w-full max-w-xs"
popoverClassName="w-96 max-h-48"
placeholder="Custom styled combobox"
/>
Props
Combobox
Prop | Type | Default | Description |
---|---|---|---|
options | ComboboxOption[] | — | Array of selectable options |
value | string | — | Controlled selected value |
defaultValue | string | — | Default selected value |
onValueChange | (value: string) => void | — | Callback when selection changes |
placeholder | string | 'Select option...' | Placeholder text |
searchPlaceholder | string | 'Search...' | Search input placeholder |
emptyMessage | string | 'No options found' | Message when no options match |
disabled | boolean | false | Disable the combobox |
size | 'sm' | 'md' | 'lg' | 'md' | Size variant |
variant | 'default' | 'error' | 'success' | 'default' | Visual variant |
className | string | '' | Additional CSS classes for trigger |
popoverClassName | string | '' | Additional CSS classes for dropdown |
searchable | boolean | true | Enable search functionality |
clearable | boolean | true | Show clear button when value selected |
ComboboxOption
Prop | Type | Default | Description |
---|---|---|---|
value | string | — | Unique option identifier |
label | string | — | Display text for the option |
disabled | boolean | false | Disable this option |
The Combobox component also accepts all standard HTML button attributes for the trigger element.