Combobox
A text field that filters a long list as you type, with grouping, descriptions and creating what is missing.
Rendering Combobox…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add comboboxUsage
import { Combobox } from "@/components/ui/combobox";
export default function Example() {
return (
<Combobox
label="Framework"
placeholder="Search frameworks"
clearable
options={[
{ value: "next", label: "Next.js" },
{ value: "remix", label: "Remix" },
{ value: "astro", label: "Astro" },
]}
/>
);
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">Examples
Create what is missing
When the search finds nothing, the typed text can become a new option.
Rendering Create what is missing…
HTML
The markup the example above renders, at rest. The interaction lives in the React component; from another framework, set the attributes below as the state changes.
<div class="ml-input-field ml-combobox">
<label class="ml-input-label" id="combobox-1-label" for="combobox-1">Framework</label>
<div class="ml-combobox-control">
<input class="ml-input ml-combobox-input" id="combobox-1" role="combobox" aria-expanded="false" aria-controls="combobox-1-list" aria-autocomplete="list" placeholder="Search frameworks" autoComplete="off" spellCheck="false" value=""/>
<svg class="mlola-glyph ml-combobox-chevron" width="1.1em" height="1.1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><polyline points="6 9 12 15 18 9" pathLength="1"></polyline></svg>
</div>
</div>Options
| Prop | Values | Default |
|---|---|---|
side | topbottom | — |
Every prop with a fixed set of values, read from the exported TypeScript types with its doc comment. Open the Code tab above for the rest of the API.
Classes and attributes
A class names each element; data-* and aria-* attributes carry its variant and state. The values listed are the ones the stylesheet draws; the default needs no attribute.
| Class | Attributes |
|---|---|
ml-combobox | — |
ml-combobox-control | data-open |
ml-combobox-input | data-clearabledata-leading |
ml-combobox-value-leading | — |
ml-combobox-chevron | — |
ml-combobox-clear | — |
ml-combobox-popover | data-side="top" |
ml-combobox-list | — |
ml-combobox-group | — |
ml-combobox-option | aria-disabled="true"aria-selected="true"data-createdata-highlighted |
ml-combobox-leading | — |
ml-combobox-text | — |
ml-combobox-label | — |
ml-combobox-description | — |
ml-combobox-check | — |
ml-combobox-empty | — |
Accessibility and theming
- Semantic elements, accessible names and state relationships are part of the contract.
- Keyboard, pointer and touch paths are operable; focus stays visible in every theme.
- Light and dark modes pass WCAG AA contrast in all 5 canonical themes.
- Reduced motion and forced colors keep meaning and operation.
Dependencies
Installed alongside this component. No third-party UI runtime is ever added.
- input
@mlola-ui/behavior@mlola-ui/icons