Slint Kit Documentation

Choices and values

Searchable combobox for Slint

KitCombobox · Slint Kit 0.3.0

Slint combobox for searching options and selecting one value.

Slint combobox for searching options and selecting one value.
Native app built from the example below.

Try the component

Download the complete project, extract it and run cargo run --locked in its folder. Rust 1.92+; Slint Kit 0.3.0 from crates.io. You can also copy the four files below.

Open the list, type sha, then choose Shared. Rust retains the selected key; Escape closes the list without changing the choice.

ui/app.slint

export { KitFormValidation, HtmlInputKind, NumberInputFormat, KitInputConstraints, KitValidationResult, KitValidityState } from "@kit/kit.slint";
import { KitCombobox, KitThemes, OptionRow, SelectState, NavigationStep, CloseReason, SelectionAvailability, SearchPresentation } from "@kit/kit.slint";
export { OptionRow, SelectState, NavigationStep, CloseReason, SelectionAvailability }

export component App inherits Window {
    title: "Slint combobox";
    preferred-width: 480px;
    preferred-height: 480px;
    max-width: 100000px;
    max-height: 100000px;
    background: KitThemes.light.canvas;
    in property <[OptionRow]> rows;
    in property <SelectState> select-state;
    in property <string> selected-label: "Personal";
    in-out property <string> query;
    callback select-open();
    callback select-navigate(NavigationStep);
    callback select-activate(int, int);
    callback select-dismiss(CloseReason);
    callback select-query(string);
    callback select-typeahead(string);
    VerticalLayout {
        padding: 24px;
        spacing: 16px;
        alignment: start;
        workspace := KitCombobox {
            label: "Workspace";
            rows: root.rows;
            state: root.select-state;
            query <=> root.query;
            selected-label: root.selected-label;
            search-state: SearchPresentation.ready;
            open-requested => { root.select-open(); }
            navigate(step) => { root.select-navigate(step); }
            activate(token, generation) => { root.select-activate(token, generation); }
            dismiss(reason) => { root.select-dismiss(reason); }
            query-edited(text) => { root.select-query(text); }
            typeahead(text) => { root.select-typeahead(text); }
            tab-navigation(reverse) => { return reject; }
        }
        selected-label-view := Text { text: "Accepted workspace: " + root.selected-label; color: KitThemes.light.text-primary; }
    }
}

src/main.rs

use slint::ComponentHandle;
use slint_kit::{Ownership, SelectOption, SelectionIntent};

mod ui {
    slint::include_modules!();
}

#[derive(Clone, Copy, PartialEq, Eq, Hash)]
enum Workspace {
    Personal,
    Shared,
    Archive,
}

impl Workspace {
    fn label(self) -> &'static str {
        match self {
            Self::Personal => "Personal",
            Self::Shared => "Shared",
            Self::Archive => "Archive",
        }
    }
}

fn main() -> Result<(), slint::PlatformError> {
    let app = ui::App::new()?;
    slint_kit::init_form_validation!(ui, app);
    let selection = slint_kit::bind_select!(
        ui,
        app,
        vec![
            SelectOption::new(Workspace::Personal, "Personal"),
            SelectOption::new(Workspace::Shared, "Shared"),
            SelectOption::new(Workspace::Archive, "Archive"),
        ],
        Some(Workspace::Personal),
        Ownership::Local
    );
    let weak = app.as_weak();
    selection.on_intent(move |intent| {
        if let Some(app) = weak.upgrade() {
            let label = match intent {
                SelectionIntent::Commit(workspace) => workspace.label(),
                SelectionIntent::Clear => "Choose a workspace",
            };
            app.set_selected_label(label.into());
        }
    });
    app.run()
}

Cargo.toml and build.rs

Cargo.toml

[package]
name = "slint-kit-combobox-example"
version = "0.1.0"
edition = "2024"
rust-version = "1.92"
license = "GPL-3.0-or-later"
publish = false

[dependencies]
slint-kit = "=0.3.0"
slint = { version = "=1.18.1", default-features = false, features = ["std", "compat-1-18", "backend-winit", "renderer-skia", "accessibility"] }

[build-dependencies]
slint-kit-build = "=0.3.0"

[workspace]

build.rs

fn main() {
    slint_kit_build::compile("ui/app.slint").expect("compile component example");
}

Files: Cargo.toml · build.rs · ui/app.slint · src/main.rs

Supply rows and state from a SelectBinding projection. Forward query-edited to its query method and connect opening, navigation, activation and dismissal to the binding. Update selected-label when a selection is accepted.

The popup virtualizes the projected options; the Rust binding performs filtering and retains the selected key when the query changes. For asynchronous search, project search-state and status-text to show loading or failure.

Choose between built-in options and custom composition

Shared options

Visual composition

The file below produces the screenshot. For controller-driven components, it shows the displayed state without supplying the Rust wiring. Create a project.

Show the screenshot source
Slint combobox for searching options and selecting one value.
Native screenshot of the same example, rendered with Skia.
// SPDX-License-Identifier: GPL-3.0-or-later
import { KitCombobox, KitTheme, KitThemes, SelectionAvailability } from "@kit/kit.slint";

export component Example inherits Window {
    title: "KitCombobox example";
    preferred-width: 420px;
    preferred-height: 180px;
    max-width: 100000px;
    max-height: 100000px;
    background: root.theme.canvas;
    in-out property <KitTheme> theme: KitThemes.light;
    in-out property <string> status;
    VerticalLayout {
        padding: 24px; spacing: 16px; alignment: start;
        Text { text: "Combobox"; color: root.theme.text-primary; font-size: 20px * root.theme.text-scale; font-weight: 600; }
        KitCombobox { theme: root.theme; label: "Search projects"; rows: [{ token: 11, generation: 1, label: "Overview", description: "Project summary", disabled: false }, { token: 23, generation: 1, label: "Activity", description: "Recent changes", disabled: false }, { token: 38, generation: 1, label: "Settings", description: "Project preferences", disabled: false }]; state: { open: false, generation: 1, active-index: 0, active: { present: true, token: 11 }, selected: { present: true, token: 11 }, selection-availability: SelectionAvailability.available }; selected-label: "Overview"; query: ""; query-edited(value) => { root.status = "Search: " + value; } }
        if root.status != "": Text { text: root.status; color: root.theme.text-secondary; font-size: 12px * root.theme.text-scale; wrap: word-wrap; }
    }
}

Download this example

Public API

Inherits Rectangle.

Properties

Name Type Direction
required bool in
required-message string in
custom-validity string in-out
validity KitValidityState out
will-validate bool out
validation-message string out
theme KitTheme in
control-size ControlSize in
access FieldAccess in
rows [OptionRow] in
state SelectState in
search-state SearchPresentation in
status-text string in
label string in
selected-label string in
unavailable-label string in
query string in-out
has-focus bool out

Types and variants

Type Declaration
enum CloseReason escape, outside-press, system-back, trigger-toggle, programmatic, host-closed
enum ControlSize compact, medium, comfortable
enum FieldAccess editable, read-only, disabled
struct KitValidityState valid: bool, value-missing: bool, type-mismatch: bool, pattern-mismatch: bool, too-long: bool, too-short: bool, range-underflow: bool, range-overflow: bool, step-mismatch: bool, bad-input: bool, custom-error: bool,
enum NavigationStep next, previous, first, last, page-next, page-previous
struct OptionRow token: int, generation: int, label: string, description: string, disabled: bool
enum SearchPresentation idle, loading, ready, failed
enum SelectionAvailability absent, available, unavailable
struct SelectionRef present: bool, token: int
struct SelectState selection-availability: SelectionAvailability, selected: SelectionRef, active: SelectionRef, open: bool, active-index: int, generation: int

Callbacks

Functions

See also