Interactive demo of combobox field
/**
* Combobox Field Demo - Interactive examples of combobox fields
*/
import { Form, FormBuilder } from '@saastro/forms';
import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';
const config = FormBuilder.create('combobox-demo')
.layout('manual')
.columns(12)
.addField('framework', (f) =>
f
.type('combobox')
.label('Framework')
.placeholder('Search frameworks...')
.helperText('Type to search and filter options')
.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' },
{ label: 'Preact', value: 'preact' },
{ label: 'Lit', value: 'lit' },
])
.required('Please select a framework')
.columns({ default: 12, md: 6 }),
)
.addField('language', (f) =>
f
.type('combobox')
.label('Programming Language')
.placeholder('Search languages...')
.options([
{ label: 'TypeScript', value: 'typescript' },
{ label: 'JavaScript', value: 'javascript' },
{ label: 'Python', value: 'python' },
{ label: 'Rust', value: 'rust' },
{ label: 'Go', value: 'go' },
{ label: 'Java', value: 'java' },
{ label: 'C#', value: 'csharp' },
{ label: 'Ruby', value: 'ruby' },
])
.required()
.columns({ default: 12, md: 6 }),
)
.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' },
{ label: 'China', value: 'cn' },
{ label: 'France', value: 'fr' },
{ label: 'Germany', value: 'de' },
{ label: 'India', value: 'in' },
{ label: 'Japan', value: 'jp' },
{ label: 'Mexico', value: 'mx' },
{ label: 'Spain', value: 'es' },
{ label: 'United Kingdom', value: 'uk' },
{ label: 'United States', value: 'us' },
])
.required()
.columns({ default: 12 }),
)
.addStep('main', ['framework', 'language', 'country'])
.build();
export default function ComboboxDemo() {
const handleSubmit = (data: Record<string, unknown>) => {
console.log('Form submitted:', data);
alert('Form submitted! Check console for data.');
};
return (
<TooltipProvider>
<FormProvider>
<Form config={config} onSubmit={handleSubmit} className="space-y-4" />
</FormProvider>
</TooltipProvider>
);
} 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
import { FormBuilder } from '@saastro/forms';
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
.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
{
"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
.addField('timezone', (f) =>
f.type('combobox')
.label('Timezone')
.options([...timezones])
.required('Please select a timezone')
)
Styling
Custom Classes
.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
.addField('timezone', (f) =>
f.type('combobox')
.label('Timezone')
.options([...])
.size('lg')
)
Responsive Layout
.addField('country', (f) =>
f.type('combobox')
.label('Country')
.options([...])
.columns({ default: 12, md: 6 })
)
JSON Styling
{
"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 - Simple dropdown without search
- Command - Command palette style
- Native Select - Browser native select
Accessibility
- Built on cmdk (Command Menu)
- Full keyboard navigation
- Type to filter
- Screen reader announcements
- Focus management