NOCTA UI

Combobox

Searchable combobox component with filtering, keyboard navigation, and accessibility for advanced option selection

Installation

Install the Combobox component using the nocta-ui CLI:

Terminal
npx nocta-ui add combobox

Then import the component:

Import
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:

Combobox Option Interface
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

Use defaultValue for uncontrolled behavior:

Uncontrolled Combobox
<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, and aria-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:

Dynamic Options Example
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:

Form Integration Example
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:

Custom Styling Example
<Combobox
  options={options}
  className="w-full max-w-xs"
  popoverClassName="w-96 max-h-48"
  placeholder="Custom styled combobox"
/>

Props

Combobox

PropTypeDefaultDescription
optionsComboboxOption[]Array of selectable options
valuestringControlled selected value
defaultValuestringDefault selected value
onValueChange(value: string) => voidCallback when selection changes
placeholderstring'Select option...'Placeholder text
searchPlaceholderstring'Search...'Search input placeholder
emptyMessagestring'No options found'Message when no options match
disabledbooleanfalseDisable the combobox
size'sm' | 'md' | 'lg''md'Size variant
variant'default' | 'error' | 'success''default'Visual variant
classNamestring''Additional CSS classes for trigger
popoverClassNamestring''Additional CSS classes for dropdown
searchablebooleantrueEnable search functionality
clearablebooleantrueShow clear button when value selected

ComboboxOption

PropTypeDefaultDescription
valuestringUnique option identifier
labelstringDisplay text for the option
disabledbooleanfalseDisable this option

The Combobox component also accepts all standard HTML button attributes for the trigger element.