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)
.list .child(
.read(cx)
.delegate()
.delegate
.get(*selected_index)
.map(|item| item.title().to_string())
.unwrap_or_default();
if let Some(prefix) = self.title_prefix.as_ref() {
title = format!("{}{}", prefix, title);
}
div().child(title.clone())
} else {
div().text_color(cx.theme().accent_foreground).child(
self.placeholder self.placeholder
.clone() .clone()
.unwrap_or_else(|| t!("Dropdown.placeholder").into()), .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;
}; };
title.when(self.disabled, |this| { let Some(title) = self
this.text_color(cx.theme().muted_foreground) .list
}) .read(cx)
.delegate()
.delegate
.get(*selected_index)
.map(|item| {
if let Some(el) = item.display_title() {
el
} else {
if let Some(prefix) = self.title_prefix.as_ref() {
format!("{}{}", prefix, item.title()).into_any_element()
} else {
item.title().into_any_element()
}
}
})
else {
return default_title;
};
div()
.when(self.disabled, |this| {
this.text_color(cx.theme().muted_foreground)
})
.child(title)
} }
} }