feat: add combobox filter

This commit is contained in:
2026-11-06 21:27:31 +07:00
parent 265d2d129b
commit 0ad5c3fe90
8 changed files with 256 additions and 65 deletions
+40
View File
@@ -1146,6 +1146,7 @@ fn combo_option(label: &'static str) -> ComboboxOption<SharedString> {
struct ComboboxDemo {
branch: Entity<ComboboxState<SharedString>>,
label: Entity<ComboboxState<SharedString>>,
fuzzy: Entity<ComboboxState<SharedString>>,
label_created: Option<SharedString>,
_subscriptions: Vec<gpui::Subscription>,
}
@@ -1199,15 +1200,43 @@ impl ComboboxDemo {
});
});
let label = cx.new(|cx| ComboboxState::new(label_builder, window, cx));
// A caller-owned matcher: characters in order, so "md" finds "markdown".
let fuzzy = cx.new(|cx| {
ComboboxState::new(
Combobox::new(
"combo-demo-fuzzy",
"Module",
vec![
combo_option("combobox"),
combo_option("dock"),
combo_option("editor"),
combo_option("markdown"),
],
)
.placeholder("Filter modules…")
.filter(|query, _value, label| {
let label = label.to_lowercase();
let mut letters = label.chars();
query
.to_lowercase()
.chars()
.all(|letter| letters.any(|found| found == letter))
}),
window,
cx,
)
});
// The panel is a cached view in the dock: the value readouts re-render
// only when the picker states it reads are notified.
let subscriptions = vec![
cx.observe(&branch, |_, _, cx| cx.notify()),
cx.observe(&label, |_, _, cx| cx.notify()),
cx.observe(&fuzzy, |_, _, cx| cx.notify()),
];
Self {
branch,
label,
fuzzy,
label_created: None,
_subscriptions: subscriptions,
}
@@ -1266,6 +1295,17 @@ impl Render for ComboboxDemo {
.child(format!("label: {label_value}")),
),
))
.child(demo_section(
"custom matcher",
colors,
v_flex().gap_2().child(
Field::new("combo-demo-fuzzy-field", "Module")
.description(
"The matcher is caller-owned: this one matches characters in order.",
)
.child(self.fuzzy.clone()),
),
))
}
}