Slint Kit Documentation

Selection

Select for Slint

KitSelect · Slint Kit 0.3.0

Popup selector with search, keyboard navigation and virtualized options.

Popup selector with search, keyboard navigation and virtualized options.
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.

Choose Activity: Rust keeps Destination::Activity and updates the selected label.

ui/app.slint

export { KitFormValidation, HtmlInputKind, NumberInputFormat, KitInputConstraints, KitValidationResult, KitValidityState } from "@kit/kit.slint";
// SPDX-License-Identifier: GPL-3.0-or-later
import { KitSelect, OptionRow, SelectState, NavigationStep, CloseReason, SelectionAvailability, KitTheme, KitThemes } from "@kit/kit.slint";
export component App inherits Window {
    title: "KitSelect example";
    preferred-width: 520px;
    preferred-height: 420px;
    max-width: 100000px;
    max-height: 100000px;
    background: root.theme.canvas;
    in-out property <KitTheme> theme: KitThemes.light;
    in property <[OptionRow]> rows;
    in property <SelectState> select-state;
    in property <string> selected-label: "Overview";
    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;
        control := KitSelect {
            theme: root.theme; rows: root.rows; state: root.select-state;
            placeholder: root.selected-label;
            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); }
            typeahead(text) => { root.select-typeahead(text); }
            query-edited(text) => { root.select-query(text); }
            tab-navigation(reverse) => { return reject; }
        }
        result := Text { text: "Selected: " + root.selected-label; color: root.theme.text-primary; }
    }

}

src/main.rs

// SPDX-License-Identifier: GPL-3.0-or-later
use slint::ComponentHandle;
use slint_kit::{Ownership, SelectOption, SelectionIntent};
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
enum Destination { Overview, Activity, Settings }
impl Destination {
    fn label(self) -> &'static str {
        match self { Self::Overview => "Overview", Self::Activity => "Activity", Self::Settings => "Settings" }
    }
}

mod ui { slint::include_modules!(); }
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(Destination::Overview, "Overview"),
        SelectOption::new(Destination::Activity, "Activity"),
        SelectOption::new(Destination::Settings, "Settings"),
    ], Some(Destination::Overview), Ownership::Local);
    let weak = app.as_weak();
    selection.on_intent(move |intent| {
        if let Some(app) = weak.upgrade() {
            app.set_selected_label(match intent {
                SelectionIntent::Commit(key) => key.label(),
                SelectionIntent::Clear => "No selection",
            }.into());
        }
    });
    app.run()
}

Cargo.toml and build.rs

Cargo.toml

[package]
name = "slint-kit-select-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

Provide rows and state from SelectBinding or a selection controller, then forward navigation, opening and activation callbacks. Put the selected label in placeholder, which supplies the trigger text.

Activation carries token and generation; the controller acknowledges selection and handles disabled options. SelectionAvailability.unavailable signals an unavailable choice, and tab-navigation lets the host advance focus after closing.

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
Popup selector with search, keyboard navigation and virtualized options.
Native screenshot of the same example, rendered with Skia.
// SPDX-License-Identifier: GPL-3.0-or-later
import { KitSelect, KitTheme, KitThemes, SelectionAvailability } from "@kit/kit.slint";

export component Example inherits Window {
    title: "KitSelect 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: "Select"; color: root.theme.text-primary; font-size: 20px * root.theme.text-scale; font-weight: 600; }
        KitSelect { theme: root.theme; placeholder: "Overview"; 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 }; activate(token, generation) => { root.status = "Activated stable token " + token; } }
        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
rows [OptionRow] in
state SelectState in
placeholder string in
unavailable-label string in
disabled bool in
control-size ControlSize in
popup-height length in
row-height length in
popup-visible bool 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
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 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