Combobox — <mv-combobox>
Search field with an accent-insensitive filtered list, groups, single or multiple selection as chips, option creation and a free-text (autocomplete) mode; form-associated.
Category Forms Type Web Component (<mv-combobox>) Status stable Keywords combobox, autocomplete, select, multiselect, tags, chips, typeahead, search, form-associated
When to use
A choice must be made from a long list that users would rather type to filter than scroll Several values such as tags, recipients or skills are picked and shown as removable chips Users may add a value that is not in the list yet, or type free text with suggestions Options come from a remote source loaded as the user types
Avoid when
There are only a handful of options and no filtering is needed → use Select instead The field is a storefront search with product thumbnails, prices and recent searches → use Search Autocomplete instead The list holds app actions and navigation triggered by a keyboard shortcut → use Command instead
Get Combobox. Included in every plan: the Pro pack ships all 226 components with the CLI and the MCP server used below.
See plans
Install
node scripts/add.mjs combobox --out ./src/marvelous
AI agent with the Marvelous UI MCP server: install_components({ slugs: ["combobox"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, core/dismiss.js, core/dom.js, core/element.js, core/position.js, components/combobox/combobox.js, components/combobox/combobox.css.
Usage
Canonical markup — start from it and customize with attributes, data-* and CSS variables:
<div style="display:grid;gap:1.25rem;width:min(100%,20rem)">
<div style="display:grid;gap:.4rem">
<label for="combobox-demo-city" style="font-size:.875rem;font-weight:500">Departure city</label>
<mv-combobox id="combobox-demo-city" name="city" placeholder="Search for a city…" clearable style="--mv-combobox-width:100%">
<svg data-start viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
<optgroup label="Europe">
<option value="london" data-hint="LHR">London</option>
<option value="zurich" data-hint="ZRH">Zürich</option>
<option value="berlin" data-hint="BER">Berlin</option>
</optgroup>
<optgroup label="Americas">
<option value="new-york" data-hint="JFK">New York</option>
<option value="sao-paulo" data-hint="GRU">São Paulo</option>
<option value="montreal" data-hint="YUL">Montréal</option>
</optgroup>
<optgroup label="Asia-Pacific">
<option value="tokyo" data-hint="HND">Tokyo</option>
<option value="singapore" data-hint="SIN">Singapore</option>
<option value="sydney" data-hint="SYD">Sydney</option>
<option value="seoul" data-hint="ICN" disabled>Seoul (full)</option>
</optgroup>
</mv-combobox>
</div>
<div style="display:grid;gap:.4rem">
<label for="combobox-demo-skills" style="font-size:.875rem;font-weight:500">Skills</label>
<mv-combobox id="combobox-demo-skills" name="skills" multiple creatable placeholder="Add a skill…" style="--mv-combobox-width:100%">
<option selected>Accessibility</option>
<option selected>CSS</option>
<option>JavaScript</option>
<option>TypeScript</option>
<option>Design systems</option>
<option>Animation</option>
<option>End-to-end testing</option>
<option>SEO</option>
</mv-combobox>
<small style="font-size:.75rem;color:var(--mv-fg-muted)">Type a term that isn’t in the list to create it.</small>
</div>
<div style="display:grid;gap:.4rem">
<label for="combobox-demo-lang" style="font-size:.875rem;font-weight:500">Language <span style="color:var(--mv-fg-subtle);font-weight:400">(free text)</span></label>
<mv-combobox id="combobox-demo-lang" name="language" free placeholder="English, Español…" style="--mv-combobox-width:100%">
<option>English</option><option>Français</option><option>Español</option><option>Deutsch</option><option>Italiano</option><option>Português</option><option>Nederlands</option>
</mv-combobox>
</div>
</div>
API
Attributes
Name Type Default Description namestring Form field name; in multiple mode, one entry per value. valuestring Initial value (comma-separated values in multiple mode). placeholderstring Field placeholder text. multipleboolean Multiple selection shown as removable chips (Backspace removes the last one). creatableboolean Offers an “Add ‘x’” option when the input matches no option. freeboolean Autocomplete mode: the value is the typed text, options are only suggestions. clearableboolean Clear button once a value is chosen. requiredboolean Native validation (valueMissing). disabledboolean Disables the field. invalidboolean Error style + aria-invalid. loadingboolean Shows “Loading…” with a spinner in the list (async sources). empty-textstring No resultsMessage when nothing matches. create-textstring Add “{query}”Label of the create option. placementbottom-start | top-start… bottom-startList placement (flipped when there is no room). labelstring Accessible name without a <label for>. data-sizesm | lg Field height.
Properties
Name Type Description valuestring Value (or text in free mode); in multiple mode, values joined by commas. valuesstring[] Selected values. optionsArray<string | { value, label, group?, hint?, keywords?, disabled? }> Option source (added to the child <option>s read on mount). selectedOptionsobject[] Selected options (read-only). isOpenboolean Whether the list is open (read-only).
Methods
Name Description open() / close()Opens or closes the list. clear()Clears the selection. addOption(option)Adds an option. focus()Focuses the field. checkValidity() / reportValidity()Native validation.
Events
Name Description mv-changedetail: { value, values, option }. mv-querydetail: { query } on every keystroke (to load remote options). mv-createCancelable; detail: { value, label } before an option is created. mv-open / mv-closeList opened and closed.
Content structure
Name Description <option> / <optgroup>Declarative options (value, label, disabled, selected, data-hint, data-keywords). [data-start]Icon placed at the start of the field.
CSS classes
Name Description mv-combobox-field / -input / -chip / -popup / -option / -emptyGenerated parts.
CSS variables
Name Default Description --mv-combobox-width18remField width. --mv-combobox-max-height16remMax list height. --mv-combobox-radiusvar(--mv-radius-md)Field radius.
Accessibility
APG “Combobox with listbox popup” pattern: input role=combobox, aria-expanded, aria-controls, aria-autocomplete=list and aria-activedescendant (focus stays in the field). ↓/↑ open and navigate, Alt+↓ opens, Page Up/Down jump by 10, Enter selects, Escape closes then clears, Backspace removes the last chip. List role=listbox (aria-multiselectable in multiple mode), labeled role=group groups, options with aria-selected / aria-disabled. Result count and additions are announced through a polite live region.