Skip to content
Glint UI

Combobox

An autocomplete input and popup picker supporting single selection, multi-tag picking with chips, and rich item rows.

Usage

import { Button } from "@glint/components/button.slint";
import { Combobox, ComboboxItem } from "@glint/components/combobox.slint";
export component AppWindow inherits Window {
in-out property <int> active-index: -1;
VerticalLayout {
alignment: center;
combo := Combobox {
selected-index <=> root.active-index;
items: [
{ value: "rust", label: "Rust" },
{ value: "ts", label: "TypeScript" },
{ value: "slint", label: "Slint" },
];
Button {
text: "Select Language";
haspopup: true;
clicked => { combo.show(); }
}
}
}
}

Combobox wraps a custom trigger in its @children slot. Calling show() opens a popup containing a search input over a scrollable suggestions list. Typing in the search input updates the two-way query property and dynamically drives typeahead navigation.

When multiple: true is set, Combobox operates as a multi-selection tag picker where items can be toggled without closing the dropdown.

Examples

Multi-selection tag picker with chips

Set multiple: true and bind selected (an array of booleans matching items length). Use ComboboxChips within or beside the trigger to display removable badges for selected items.

Rich item rows with icons, descriptions, and badges

ComboboxItem supports rich metadata including leading icons (icon) or avatars (avatar), secondary subtext (description), and trailing status badges (badge).

Grouped suggestions

Following the grouped rows model, use separator-before and heading-before on items to organize large option sets into titled categories without shifting item indices.

API Reference

Properties

PropertyTypeDefaultDescription
itemsin [ComboboxItem]no defaultOptions shown in the popup; value is yours to use, Glint only reads label.
selected-indexin-out int-1Two-way; index of the chosen item in items, or -1 for no selection. Single-selection mode only — see multiple.
multiplein boolfalseSeveral rows chosen at once rather than one: the tag picker. Rows announce themselves checkable, choosing one leaves the popup open so the next can be chosen without reopening, and the chosen values are drawn by a ComboboxChips the consumer puts inside its own trigger.
selectedin-out [bool][]Two-way; which rows are chosen in multiple mode, one flag per row of items in the same order. Size it to items: Slint cannot grow an array, so a flag past the end of this list is a choice with nowhere to land. A consumer who filters items by the query derives this beside it — which is also why the chips read their own list of labels rather than this one, and go on reading it while a query hides the rows.
queryin-out stringno defaultTwo-way; current text in the search field. Reset to "" to clear the filter.
highlighted-indexin-out int0Row highlighted by Enter; consumers rarely set this directly.
placeholderin string@tr("Search…")Hint shown in the search field when empty.
empty-textin string@tr("No results found.")Shown in place of the list when items is empty — the state a filtered popup lands in most often. Set it to "" to show nothing at all.
clear-labelin string@tr("Clear search")Name of the control that empties the query, for assistive technology.
content-widthin length320pxPixel width of the popup panel.
disabledin boolfalseWhen true, the popup stays shut and the control announces itself unavailable. The trigger is @children and its own look belongs to it (ADR-0006) — bind the same flag there to dim it.
is-openout boolno defaultTrue while the popup is on screen. The trigger is @children, so rotating its chevron is yours to do — bind the rotation to this.

Callbacks

CallbackDescription
changed(int)Fired with the chosen item's index when selected.

Functions

FunctionDescription
show()Opens the popup with the highlight back at the top. Mirrors PopupWindow.show() — wire it to a consumer-owned trigger so the popup opens from the keyboard as well as from a click. The disabled guard lives here rather than on each caller, because a consumer cannot suppress a popup from outside once it is up: every way in — the pointer, this function, both accessible actions — has to be refused at the same door.
close()Closes the popup. Mirrors PopupWindow.close().

ComboboxChips

A horizontal strip rendering selected values as individual tags with accessible remove buttons.

Properties

PropertyTypeDefaultDescription
labelsin [string]no defaultWhat is chosen, in the order the chips read.
remove-labelin string@tr("Remove")How the control that drops a chip is named. It is joined with the chip's own label, so each control says which value it drops rather than leaving a row of identical "Remove" buttons — Slint has no way to place the value inside an overridable sentence, so the join is a space.

Callbacks

CallbackDescription
removed(int)Fired with the index into labels of the chip that was dropped.

Accessibility

  • Combobox semantics. The trigger node exposes the combobox role, announcing expanded/collapsed states and current value.
  • Multi-select state. In multiple mode, list items announce themselves as checkable with their checked boolean state.
  • Rich content announcement. Item descriptions and badges ride as accessible-description on the list item rather than creating noisy secondary nodes.
  • Chip controls. Each chip in ComboboxChips includes a remove button with an accessible label explicitly naming the item to be removed (e.g. Remove Bug).
  • Keyboard navigation. / navigate items, Home/End jump to list ends, and typing in the search input runs query-driven prefix navigation.