Studio
2

Combobox

Installation

pnpm dlx @mielui/svelte add combobox

Usage

The theme setting chrome.borders chooses "single" or "double" framing. Double is the default. Single removes the extra frame while preserving content padding, composition, and inset variants.

Bind value to the selected option. Single selection is the default. Clicking an option or pressing Enter updates value and calls onValueChange. Keyboard navigation skips disabled options. Changing an item label updates the selected label without replacing an active search.

Set name on Trigger to submit the selected value. Search text and labels are not submitted. Trigger renders an input by default, or a button with searchPlacement="menu". Its bind:element matches that element type.

An item callback runs when that option changes the selection. Selecting the current option again in single mode closes the menu without reporting a value change. Call preventDefault() in Trigger's onclick to cancel click activation. Input appearance can still open on focus or typing. Trigger's disabled prop disables both editing and its clear action.

Settype="multiple" on Root and bind a string array to value to choose several options. Selecting an item toggles it, clears the search, and keeps the menu open. The trigger lists selected labels; Escape or an outside click closes the menu. With name on Trigger, each selected value submits under that name.

import * as Combobox from '$lib/mielui/components/combobox';

let selected = $state('next');

<Combobox.Root bind:value={selected}>
  <Combobox.Trigger placeholder="Framework" />
  <Combobox.Content>
    <Combobox.Results>
      <Combobox.Item value="next" label="Next.js" />
    </Combobox.Results>
  </Combobox.Content>
</Combobox.Root>

Examples

Basic usage

Multiple selection

Search for teams and toggle each selection without reopening the menu.

Scrollable

Long result lists stay in a height-capped menu and scroll inside it.

Glass surface

Set surface="glass" on Combobox.Content for a translucent background with blur. Omit surface to inherit --mielui-surface from your theme, or set surface="solid" to override it. The glass surface keeps an opaque fallback when backdrop filtering is unavailable and respects reduced-transparency preferences.

API reference

Combobox.Root

Provides combobox state.

Prop Type Default
children Snippet<[]> | undefined —
open Bindable boolean | undefined false
onOpenChange ((open: boolean) => void) | undefined —
placement Placement | undefined 'bottom'
state_key string | undefined

Stable identifier used to connect trigger and content ARIA attributes.

—
stateKey string | undefined —
hoverable boolean | undefined false
delay number | undefined 0
closeDelay number | undefined 150
inert boolean | undefined

Make document content outside an open non-hover popover inert. Defaults to `true`.

true
type "single" | undefined | "multiple" —
value Bindable string | undefined | string[] | undefined undefined
onValueChange ((value: string) => void) | undefined | ((value: string[]) => void) | undefined —

Combobox.Content

Contains combobox controls.

Prop Type Default
surface "solid" | "glass" | undefined —
children Required Snippet<[]> —
class (string & (ClassValue | null)) | undefined —
surfaceClass string | undefined

Classes for the inset surface (where children live) — padding, layout, background overrides. The `class` prop styles the outer Panel frame.

—
allowClickOutside boolean | undefined true
dismissLayer boolean | undefined

Render the full-viewport dismiss layer under the panel while open. Defaults to `true`. Set to `false` for triggers that must stay clickable while open (e.g. an input-style combobox trigger); outside pointer dismissal still applies via `allowClickOutside`.

true
portal boolean | undefined true
refElement VirtualElement | undefined —
role "none" | "alertdialog" | "dialog" | "listbox" | "menu" | undefined 'none'
tabindex number | undefined -1
focusTrap boolean | undefined

Trap Tab focus inside the panel while open. Defaults to `true`.

—
lockScroll boolean | undefined

Lock document scrolling while the panel is open. Defaults to `true`.

true

Combobox.Item

Defines a selectable item.

Prop Type Default
value Required string | string | (string & string[]) —
label Required string —
callback (() => void) | undefined —
disabled boolean | undefined false
variant ButtonVariant | undefined —
size "sm" | "md" | "lg" | "icon" | undefined —
children Snippet<[]> | undefined —
element Bindable HTMLButtonElement | HTMLAnchorElement | undefined

Bindable reference to the rendered DOM element. Type is the union of the two possible element types -- narrow at the use site:

—
unstyled boolean | undefined

Skip the variant/size base classes and render with `class` alone.

—
status ButtonStatus | undefined

Controlled visual state. Loading remains focusable and refuses activation.

—
loading boolean | undefined

Convenience alias for `status="loading"`.

—
loadingLabel string | undefined —
successLabel string | undefined —
errorLabel string | undefined —
onclick ((event: MouseEvent) => void) | undefined —
onkeydown ((event: KeyboardEvent) => void) | undefined —
href string | undefined —

Combobox.Label

Labels the combobox.

Prop Type Default
children Required Snippet<[]> —
class string | undefined —

Combobox.Results

Lists matching items.

Prop Type Default
children Snippet<[]> | undefined —

Combobox.Trigger

Opens the combobox.

Prop Type Default
class string | undefined —
style string | undefined —
onclick ((event: MouseEvent) => void) | undefined —
variant ButtonVariant | undefined 'outline'
size "sm" | "md" | "lg" | "icon" | undefined 'md'
unstyled boolean | undefined

Forwarded to Button: render with `class` alone, skipping variant/size.

—
icon boolean | undefined —
onopen (() => void) | undefined

Called immediately before this trigger opens its popover.

—
trailing Snippet<[]> | undefined —
placeholder string | undefined 'Select…'
searchPlacement "menu" | "trigger" | undefined 'trigger'
threshold number | undefined 0.28
appearance "button" | "input" | undefined 'button'
element Bindable HTMLButtonElement | HTMLInputElement | undefined —