# Field: Combobox (category: selection)

URL: https://docs.forms.saastro.io/docs/combobox

<FieldPreview name="combobox" description="Interactive demo of combobox field" />

## Overview

The combobox field combines a text input with a dropdown list, allowing users to search and filter options. It's ideal for long lists where users need to find options quickly.

## Usage

### Basic Combobox

```tsx

const config = FormBuilder.create('form')
  .addField('framework', (f) =>
    f
      .type('combobox')
      .label('Framework')
      .placeholder('Search frameworks...')
      .options([
        { label: 'React', value: 'react' },
        { label: 'Vue', value: 'vue' },
        { label: 'Angular', value: 'angular' },
        { label: 'Svelte', value: 'svelte' },
        { label: 'Solid', value: 'solid' },
        { label: 'Qwik', value: 'qwik' },
      ])
      .required('Please select a framework'),
  )
  .addStep('main', ['framework'])
  .build();
```

### With Many Options

```tsx
.addField('country', (f) =>
  f.type('combobox')
    .label('Country')
    .placeholder('Search countries...')
    .options([
      { label: 'Argentina', value: 'ar' },
      { label: 'Australia', value: 'au' },
      { label: 'Brazil', value: 'br' },
      { label: 'Canada', value: 'ca' },
      // ... many more
    ])
    .required()
)
```

### JSON Configuration

```json
{
  "type": "combobox",
  "label": "Framework",
  "placeholder": "Search frameworks...",
  "options": [
    { "label": "React", "value": "react" },
    { "label": "Vue", "value": "vue" },
    { "label": "Angular", "value": "angular" }
  ],
  "schema": { "required": true }
}
```

## Props

| Prop          | Type                                                  | Default | Description                 |
| ------------- | ----------------------------------------------------- | ------- | --------------------------- |
| `type`        | `'combobox'`                                          | -       | Field type (required)       |
| `label`       | `string`                                              | -       | Label text                  |
| `placeholder` | `string`                                              | -       | Search input placeholder    |
| `helperText`  | `string`                                              | -       | Help text below field       |
| `options`     | `Option[]`                                            | -       | Array of searchable options |
| `value`       | `string`                                              | -       | Default selected value      |
| `size`        | `'sm' \| 'md' \| 'lg'`                                | `'md'`  | Input size variant          |
| `columns`     | `Partial<Record<Breakpoint, number>>`                 | -       | Grid columns by breakpoint  |
| `disabled`    | `boolean \| function \| ConditionGroup`               | `false` | Disable the field           |
| `hidden`      | `boolean \| function \| ConditionGroup \| Responsive` | `false` | Hide the field              |

## Combobox vs Select

| Use Combobox                 | Use Select           |
| ---------------------------- | -------------------- |
| 10+ options                  | Fewer options        |
| Users know what they want    | Users browse options |
| Long lists (countries, etc.) | Short curated lists  |
| Typing is faster             | Scrolling is fine    |

## Validation

### Required Selection

```tsx
.addField('timezone', (f) =>
  f.type('combobox')
    .label('Timezone')
    .options([...timezones])
    .required('Please select a timezone')
)
```

## Styling

### Custom Classes

```tsx
.addField('country', (f) =>
  f.type('combobox')
    .label('Country')
    .options([...])
    .required()
    .classNames({
      wrapper: 'bg-muted/30 p-4 rounded-lg',
      input: 'border-2 border-primary/20',
      label: 'text-lg font-semibold',
      error: 'text-destructive text-sm',
    })
)
```

### Size Variants

```tsx
.addField('timezone', (f) =>
  f.type('combobox')
    .label('Timezone')
    .options([...])
    .size('lg')
)
```

### Responsive Layout

```tsx
.addField('country', (f) =>
  f.type('combobox')
    .label('Country')
    .options([...])
    .columns({ default: 12, md: 6 })
)
```

### JSON Styling

```json
{
  "type": "combobox",
  "label": "Country",
  "placeholder": "Search countries...",
  "wrapper_className": "bg-muted/30 p-4 rounded-lg",
  "input_className": "border-2 border-primary/20",
  "label_className": "text-lg font-semibold",
  "size": "lg",
  "columns": { "default": 12, "md": 6 }
}
```

## Related Fields

- [Select](/docs/select) - Simple dropdown without search
- [Command](/docs/command) - Command palette style
- [Native Select](/docs/native-select) - Browser native select

## Accessibility

- Built on cmdk (Command Menu)
- Full keyboard navigation
- Type to filter
- Screen reader announcements
- Focus management
