select: Impl SelectItem for &'static str. (#1451)

This commit is contained in:
Jason Lee 2025-10-28 21:37:00 +08:00 committed by GitHub
parent 34ef0ff6d0
commit 55db53a46d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 43 additions and 33 deletions

View file

@ -38,9 +38,9 @@ impl SelectItem for Country {
pub struct SelectStory {
disabled: bool,
country_select: Entity<SelectState<SearchableVec<SelectGroup<Country>>>>,
fruit_select: Entity<SelectState<SearchableVec<SharedString>>>,
simple_select1: Entity<SelectState<Vec<SharedString>>>,
simple_select2: Entity<SelectState<SearchableVec<SharedString>>>,
fruit_select: Entity<SelectState<SearchableVec<&'static str>>>,
simple_select1: Entity<SelectState<Vec<&'static str>>>,
simple_select2: Entity<SelectState<SearchableVec<&'static str>>>,
simple_select3: Entity<SelectState<Vec<SharedString>>>,
disabled_select: Entity<SelectState<Vec<SharedString>>>,
appearance_select: Entity<SelectState<Vec<SharedString>>>,
@ -103,13 +103,13 @@ impl SelectStory {
let input_state = cx.new(|cx| InputState::new(window, cx).placeholder("Your phone number"));
let fruits = SearchableVec::new(vec![
"Apple".into(),
"Orange".into(),
"Banana".into(),
"Grape".into(),
"Pineapple".into(),
"Watermelon & This is a long long long long long long long long long title".into(),
"Avocado".into(),
"Apple",
"Orange",
"Banana",
"Grape",
"Pineapple",
"Watermelon & This is a long long long long long long long long long title",
"Avocado",
]);
let fruit_select = cx.new(|cx| SelectState::new(fruits, None, window, cx));
@ -124,15 +124,8 @@ impl SelectStory {
simple_select1: cx.new(|cx| {
SelectState::new(
vec![
"GPUI".into(),
"Iced".into(),
"egui".into(),
"Makepad".into(),
"Slint".into(),
"QT".into(),
"ImGui".into(),
"Cocoa".into(),
"WinUI".into(),
"GPUI", "Iced", "egui", "Makepad", "Slint", "QT", "ImGui", "Cocoa",
"WinUI",
],
Some(IndexPath::default()),
window,
@ -143,12 +136,7 @@ impl SelectStory {
let mut select = SelectState::new(SearchableVec::new(vec![]), None, window, cx);
select.set_items(
SearchableVec::new(vec![
"Rust".into(),
"Go".into(),
"C++".into(),
"JavaScript".into(),
]),
SearchableVec::new(vec!["Rust", "Go", "C++", "JavaScript"]),
window,
cx,
);

View file

@ -72,6 +72,18 @@ impl SelectItem for SharedString {
}
}
impl SelectItem for &'static str {
type Value = Self;
fn title(&self) -> SharedString {
SharedString::from(self.to_string())
}
fn value(&self) -> &Self::Value {
self
}
}
pub trait SelectDelegate: Sized {
type Item: SelectItem;

View file

@ -28,10 +28,16 @@ use gpui_component::select::{
### Basic Select
You can create a basic select dropdown by initializing a `SelectState` with a list of items.
The first type parameter of `SelectState` is the items for the state, which must implement the [SelectItem] trait.
The built-in implementations of `SelectItem` include common types like `String`, `SharedString`, and `&'static str`.
```rust
let state = cx.new(|cx| {
SelectState::new(
vec!["Apple".into(), "Orange".into(), "Banana".into()],
vec!["Apple", "Orange", "Banana"],
Some(IndexPath::default()), // Select first item
window,
cx,
@ -46,7 +52,7 @@ Select::new(&state)
```rust
let state = cx.new(|cx| {
SelectState::new(
vec!["Rust".into(), "Go".into(), "JavaScript".into()],
vec!["Rust", "Go", "JavaScript"],
None, // No initial selection
window,
cx,
@ -61,11 +67,7 @@ Select::new(&state)
```rust
let fruits = SearchableVec::new(vec![
"Apple".into(),
"Orange".into(),
"Banana".into(),
"Grape".into(),
"Pineapple".into(),
"Apple", "Orange", "Banana", "Grape", "Pineapple",
]);
let state = cx.new(|cx| {
@ -76,7 +78,13 @@ Select::new(&state)
.icon(IconName::Search) // Shows search icon
```
### Custom Item
### Impl SelectItem
By default, we have implmemented `SelectItem` for common types like `String`, `SharedString` and `&'static str`. You can also create your own item types by implementing the `SelectItem` trait.
This is useful when you want to display complex data structures, and also want get that data type from `select_value` method.
You can also customize the search logic by overriding the `matches` method.
```rust
#[derive(Debug, Clone)]
@ -377,3 +385,5 @@ The dropdown respects the current theme and uses the following theme tokens:
- `accent_foreground` - Placeholder text color
- `border` - Menu border
- `radius` - Border radius
[SelectItem]: https://docs.rs/gpui-component/latest/gpui_component/select/trait.SelectItem.html