Select
Custom searchable dropdown with option groups, keyboard navigation, and clearing.
Rendering Select…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add selectUsage
import { Select } from "@/components/ui/select";
export default function Example() {
return (
<Select
label="Region"
placeholder="Choose a region"
defaultValue="eu"
options={[
{ value: "us", label: "United States" },
{ value: "eu", label: "Europe" },
{ value: "ap", label: "Asia Pacific" },
]}
/>
);
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">Examples
Searchable, in groups
Long lists get a search field; options can be grouped and disabled.
Rendering Searchable, in groups…
Several values
multiple collects values as chips; clearable empties them at once.
Rendering Several values…
In a form
name submits the value like a native select; id lets a label elsewhere in the form name it.
Rendering In a form…
HTML
Without React, write this markup and load @mlola-ui/behavior once. It runs the keyboard, focus and state for every element marked data-ml="select", including markup added later, and needs no build step.
<div class="ml-select-root" data-ml="select">
<span class="ml-select-label" id="fruit-label">Fruit</span>
<div class="ml-select-control">
<button class="ml-select" type="button" role="combobox" aria-expanded="false" aria-controls="fruit-list" aria-labelledby="fruit-label" data-state="closed">
<span class="ml-select-value" data-placeholder>Select…</span>
<span class="ml-select-chevron" aria-hidden="true"><svg class="mlola-glyph" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="m6 9 6 6 6-6"/></svg></span>
</button>
</div>
<div class="ml-select-popover" hidden>
<ul class="ml-select-list" id="fruit-list" role="listbox" aria-labelledby="fruit-label">
<li class="ml-select-option" id="opt-apple" role="option" aria-selected="false" data-state="unchecked">Apple</li>
<li class="ml-select-option" id="opt-pear" role="option" aria-selected="false" data-state="unchecked">Pear</li>
<li class="ml-select-option" id="opt-durian" role="option" aria-selected="false" aria-disabled="true" data-state="unchecked">Durian</li>
</ul>
</div>
</div><script type="module">
import { observe } from "@mlola-ui/behavior";
observe();
</script>Options
| Prop | Values | Default |
|---|---|---|
size | smmdlg | — |
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-select-root | data-invalid |
ml-select-control | — |
ml-select | data-size="lg | sm"data-state="open" |
ml-select-value | data-placeholder |
ml-select-chips | — |
ml-select-chip-overflow | — |
ml-select-chevron | — |
ml-select-clear | — |
ml-select-popover | data-side="top" |
ml-select-search-wrap | — |
ml-select-search | — |
ml-select-list | — |
ml-select-group | — |
ml-select-label | — |
ml-select-option | data-disableddata-highlighteddata-state="checked" |
ml-select-option-label | — |
ml-select-option-text | — |
ml-select-option-description | — |
ml-select-option-leading | — |
ml-select-option-trailing | — |
ml-select-check | — |
ml-select-empty | — |
ml-select-error | — |
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