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()
}
fn display_title(&self) -> Option<gpui::AnyElement> {
Some(format!("{} ({})", self.name, self.code).into_any_element())
}
fn value(&self) -> &Self::Value {
&self.code
}

View file

@ -43,6 +43,12 @@ pub fn init(cx: &mut App) {
pub trait DropdownItem {
type Value: Clone;
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;
}
@ -550,33 +556,49 @@ where
cx.emit(DropdownEvent::Confirm(None));
}
/// Returns the title element for the dropdown input.
fn display_title(&self, _: &Window, cx: &App) -> impl IntoElement {
let title = if let Some(selected_index) = &self.selected_index(cx) {
let mut title = self
.list
.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(
let default_title = div()
.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;
};
title.when(self.disabled, |this| {
this.text_color(cx.theme().muted_foreground)
})
let Some(title) = self
.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)
}
}