Components

Combobox

Autocomplete input and command palette with a list of suggestions.

Overview

输入过滤 + 点击/Enter 选中;选中后 label 回填并可继续输入重新搜索。

GPUI · Live previewGPUI WASM

Installation

Combobox 是单个 Rust 文件(src/combobox.rs)—— 文本编辑复用 gpui-base 的 InputState,弹出层语义(role/ARIA/焦点移交)来自 gpui-base::Combobox 原语,勾选与 chevron 用 PathBuilder 手绘。

Cargo.toml
[dependencies]gpui-kit = "0.6.6"# combobox.rs builds on gpui-base primitives:# InputState (editing) + Combobox root (role/ARIA# + popup semantics) — no extra deps.

Download runnable example

Terminal
# Download the runnable example crate, then:cargo run --locked -- --combobox# Other demos:cargo run --locked -- --combobox multiplecargo run --locked -- --combobox groupscargo run --locked -- --combobox disabled

Usage

Combobox 是实体:输入框是一个真实的 InputState(先 new 出来再传进构造器),实体自持过滤列表、active 行和选中值。输入即过滤(label/value/group 子串匹配),Enter 提交高亮行,选项回填 label 后再次输入即可重新搜索。

Example.rs
use justdo_command::combobox::{Combobox, ComboboxItem, ComboboxChangeEvent};use gpui_kit::base::input::InputState;// The input entity is created with a Window, then the// combobox entity wraps it and owns selection + filtering.let input = cx.new(|cx| {    InputState::new(window, cx).placeholder("Select framework…")});let combobox = cx.new(|cx| {    Combobox::new(input, cx)        .items(vec![            ComboboxItem::new("Next.js"),            ComboboxItem::new("SvelteKit"),            ComboboxItem::new("Astro").disabled(true),        ])        .empty_text("No framework found.")});cx.subscribe(&combobox, |view, _, ev: &ComboboxChangeEvent, cx| {    view.selection = ev.selected.clone();    cx.notify();});div().child(combobox)

网页预览与桌面端运行同一份 Rust / GPUI 组件。

Composition

结构对应 Combobox → Input + Listbox:field 行承载 chips/清空/开合,popup 列表渲染分组、勾选与禁用态。

Structure
Combobox                  entity — input + popup + selection├── input                 Entity<InputState> — real text editing (gpui-base)├── field                 InputBase — chips / ✕ clear / chevron trigger row├── popup                 filtered rows — active highlight, ✓ on selected│   ├── group headers     ComboboxItem::group(..)│   ├── hint              ComboboxItem::hint(..) — trailing quiet text│   └── empty             .empty_text(..) — ComboboxEmpty├── single                .default_value(..) — label refills the input├── multiple              .multiple(true) — chips + Backspace pops last└── emits                 ComboboxChangeEvent { value, selected }
Controlled.rs
// Controlled selection — read it or drive it.combobox.update(cx, |c, cx| c.set_selected(&["Next.js"], cx));combobox.update_in(cx, |c, window, cx| {    c.set_value(Some("Astro"), window, cx);   // single select    c.set_open(true, cx);});let current: Option<SharedString> = combobox.read(cx).selected_value();

Keyboard

单行输入框不注册上下方向 handler —— 方向键以 input::MoveDown/MoveUp action 冒泡出来,组件在外层接住并驱动高亮行;Enter 走 input::Enter,Escape 走 input::Escape。多选下「空查询按 Backspace 删最后一个 chip」发生在绑定派发之前,由 keystroke interceptor 完成。

Key handling.rs
// Keyboard semantics ride GPUI's action system, not raw// key capture. A focused single-line input registers no// up/down handlers, so input::MoveUp / input::MoveDown// bubble out — the combobox listens for them and drives// the active row. Enter propagates as input::Enter,// Escape as input::Escape; both commit/close at the root.// One exception needs to run *before* bindings: Backspace// on an empty multi-select input is consumed by the editor,// so a keystroke interceptor pops the newest chip.

Accessibility

Semantics

根元素带 role=combobox + aria-expanded;禁用项与禁用组件不响应指针与键盘;invalid 用红边 + 焦点环双重标识,不只靠颜色。

Keyboard

输入保持焦点:↓/↑ 移动高亮、Enter 提交、Escape 还原并关闭、Backspace 空查询时删 chip;列表超长时可滚动且高亮行自动滚入视野。

API Reference

实体暴露的 builder 方法、受控方法与事件。

APISignatureNotes
Combobox::new(..)Entity<InputState>Wraps a caller-created input entity.
.items(..)Vec<ComboboxItem>The collection; filtered as you type.
ComboboxItem::new(..)&str label.value(..) .group(..) .hint(..) .disabled(..)
.multiple(..)boolChip selection; Enter/click toggles.
.default_value(..)&strInitial single selection.
.selected_values(..)&[&str]Initial multi selection.
.clearable(..)bool✕ button when a value is present.
.empty_text(..)&strShown when the query matches nothing.
.invalid(..)boolRed border + focus ring.
.disabled(..)boolDimmed and inert.
.set_value(..)Option<&str>, Window, cxControlled single selection.
.set_selected(..)&[&str], cxControlled multi selection.
.set_open(..)bool, cxControlled popup open state.
.selected_value()-> Option<SharedString>Current single selection.
.selected_values_vec()-> Vec<SharedString>Current multi selection.
ComboboxChangeEvent{ value, selected }Emitted on every commit/toggle/clear.

Source & inspiration

结构与交互参考 shadcn/ui Combobox (React Aria) 。本页交互由 Rust / GPUI 绘制,基础原语来自 gpui-kit 。