dropdown: Add display_title to DropdownItem to support custom title to dropdown input. (#816)

Co-authored-by: Jason Lee <huacnlee@gmail.com>
This commit is contained in:
Ylin 2025-04-25 19:05:24 +08:00 committed by GitHub
parent 9085879795
commit f946560837
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 20 deletions

View file

@ -42,6 +42,10 @@ impl DropdownItem for Country {
self.name.clone() self.name.clone()
} }
fn display_title(&self) -> Option<gpui::AnyElement> {
Some(format!("{} ({})", self.name, self.code).into_any_element())
}
fn value(&self) -> &Self::Value { fn value(&self) -> &Self::Value {
&self.code &self.code
} }

View file

@ -43,6 +43,12 @@ pub fn init(cx: &mut App) {
pub trait DropdownItem { pub trait DropdownItem {
type Value: Clone; type Value: Clone;
fn title(&self) -> SharedString; fn title(&self) -> SharedString;
/// Customize the display title used to selected item in Dropdown Input.
///
/// If return None, the title will be used.
fn display_title(&self) -> Option<AnyElement> {
None
}
fn value(&self) -> &Self::Value; fn value(&self) -> &Self::Value;
} }
@ -550,33 +556,49 @@ where
cx.emit(DropdownEvent::Confirm(None)); cx.emit(DropdownEvent::Confirm(None));
} }
/// Returns the title element for the dropdown input.
fn display_title(&self, _: &Window, cx: &App) -> impl IntoElement { fn display_title(&self, _: &Window, cx: &App) -> impl IntoElement {
let title = if let Some(selected_index) = &self.selected_index(cx) { let default_title = div()
let mut title = self .text_color(cx.theme().accent_foreground)
.child(
self.placeholder
.clone()
.unwrap_or_else(|| t!("Dropdown.placeholder").into()),
)
.when(self.disabled, |this| {
this.text_color(cx.theme().muted_foreground)
});
let Some(selected_index) = &self.selected_index(cx) else {
return default_title;
};
let Some(title) = self
.list .list
.read(cx) .read(cx)
.delegate() .delegate()
.delegate .delegate
.get(*selected_index) .get(*selected_index)
.map(|item| item.title().to_string()) .map(|item| {
.unwrap_or_default(); if let Some(el) = item.display_title() {
el
if let Some(prefix) = self.title_prefix.as_ref() {
title = format!("{}{}", prefix, title);
}
div().child(title.clone())
} else { } else {
div().text_color(cx.theme().accent_foreground).child( if let Some(prefix) = self.title_prefix.as_ref() {
self.placeholder format!("{}{}", prefix, item.title()).into_any_element()
.clone() } else {
.unwrap_or_else(|| t!("Dropdown.placeholder").into()), item.title().into_any_element()
) }
}
})
else {
return default_title;
}; };
title.when(self.disabled, |this| { div()
.when(self.disabled, |this| {
this.text_color(cx.theme().muted_foreground) this.text_color(cx.theme().muted_foreground)
}) })
.child(title)
} }
} }