From 9d11418bd15c6fd465ef3fd8b674f1544e13039d Mon Sep 17 00:00:00 2001
From: obito <1255116997@qq.com>
Date: Tue, 18 Nov 2025 20:30:37 +0800
Subject: [PATCH] select: Add `render` prop to customize item title display.
(#1638)
Fixes #1410
## Problem
The `display_title` prop was overriding the default way dropdown option
titles are displayed, causing incorrect rendering of option titles.
**Expected behavior:**
**Actual behavior:**
## Solution
- Revert the `display_title` change that was causing the issue
- Add a `render` function to allow custom rendering of option titles
instead
This approach provides more flexibility for customizing option display
while preserving the default behavior.
cc @stippi
---
crates/ui/src/select.rs | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/crates/ui/src/select.rs b/crates/ui/src/select.rs
index 65ad518c..ff2ab084 100644
--- a/crates/ui/src/select.rs
+++ b/crates/ui/src/select.rs
@@ -41,6 +41,10 @@ pub trait SelectItem: Clone {
fn display_title(&self) -> Option {
None
}
+ /// Render the item for the select dropdown menu, default is to render the title.
+ fn render(&self, _: &mut Window, _: &mut App) -> impl IntoElement {
+ self.title().into_element()
+ }
/// Get the value of the item.
fn value(&self) -> &Self::Value;
/// Check if the item matches the query for search, default is to match the title.
@@ -184,7 +188,7 @@ where
);
}
- fn render_item(&self, ix: IndexPath, _: &mut Window, cx: &mut App) -> Option {
+ fn render_item(&self, ix: IndexPath, window: &mut Window, cx: &mut App) -> Option {
let selected = self
.selected_index
.map_or(false, |selected_index| selected_index == ix);
@@ -194,16 +198,10 @@ where
.map_or(Size::Medium, |state| state.read(cx).options.size);
if let Some(item) = self.delegate.item(ix) {
- let content = item.display_title().unwrap_or_else(|| {
- div()
- .whitespace_nowrap()
- .child(item.title().to_string())
- .into_any_element()
- });
let list_item = SelectListItem::new(ix.row)
.selected(selected)
.with_size(size)
- .child(content);
+ .child(div().whitespace_nowrap().child(item.render(window, cx)));
Some(list_item)
} else {
None