add select component built on menu
This commit is contained in:
+18
-11
@@ -7,7 +7,7 @@ use gpui::{
|
||||
Entity, InteractiveElement as _, IntoElement, KeyDownEvent, MouseButton, MouseDownEvent,
|
||||
ParentElement as _, Pixels, RenderOnce, Role, ScrollHandle, SharedString,
|
||||
StatefulInteractiveElement as _, Styled as _, Window, anchored, canvas, deferred, div,
|
||||
ease_out_quint, px, relative,
|
||||
ease_out_quint, px,
|
||||
};
|
||||
use gpui_native_icons::{IconRole, icon as icon_glyph};
|
||||
use gpui_native_theme::ActiveTheme as _;
|
||||
@@ -144,6 +144,7 @@ struct MenuChrome {
|
||||
pub struct Menu {
|
||||
id: ElementId,
|
||||
open: bool,
|
||||
initial_selection: Option<usize>,
|
||||
a11y_label: Option<SharedString>,
|
||||
on_change: Option<ChangeHandler>,
|
||||
trigger: Option<TriggerFn>,
|
||||
@@ -159,6 +160,7 @@ impl Menu {
|
||||
Self {
|
||||
id: id.into(),
|
||||
open: false,
|
||||
initial_selection: None,
|
||||
a11y_label: None,
|
||||
on_change: None,
|
||||
trigger: None,
|
||||
@@ -166,6 +168,12 @@ impl Menu {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the row keyboard-highlighted when the menu opens.
|
||||
pub fn initial_selection(mut self, index: usize) -> Self {
|
||||
self.initial_selection = Some(index);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the current open state.
|
||||
pub fn open(mut self, open: bool) -> Self {
|
||||
self.open = open;
|
||||
@@ -310,6 +318,8 @@ impl RenderOnce for Menu {
|
||||
|
||||
let selected = if *was_open.read(cx) {
|
||||
*selection.read(cx)
|
||||
} else if let Some(requested) = self.initial_selection {
|
||||
requested.min(items.len().saturating_sub(1))
|
||||
} else {
|
||||
let first = items.iter().position(|item| item.selectable()).unwrap_or(0);
|
||||
selection.update(cx, |selection, _| *selection = first);
|
||||
@@ -339,7 +349,6 @@ impl RenderOnce for Menu {
|
||||
.aria_label(label)
|
||||
.mt_1()
|
||||
.min_w_40()
|
||||
.max_h(relative(0.75))
|
||||
.p_1()
|
||||
.bg(chrome.surface)
|
||||
.text_color(chrome.foreground)
|
||||
@@ -490,15 +499,6 @@ fn render_item(
|
||||
}
|
||||
}
|
||||
})
|
||||
.when_some(checked, |row, checked| {
|
||||
row.child(div().flex_none().when(checked, |slot| {
|
||||
slot.child(
|
||||
icon_glyph(IconRole::Check)
|
||||
.size(chrome.icon_size * 0.75)
|
||||
.color(label_color),
|
||||
)
|
||||
}))
|
||||
})
|
||||
.when_some(icon_role, |row, role| {
|
||||
row.child(icon_glyph(role).size(chrome.icon_size).color(label_color))
|
||||
})
|
||||
@@ -519,6 +519,13 @@ fn render_item(
|
||||
.child(shortcut),
|
||||
)
|
||||
})
|
||||
.when(checked == Some(true), |row| {
|
||||
row.child(
|
||||
icon_glyph(IconRole::Check)
|
||||
.size(chrome.icon_size * 0.75)
|
||||
.color(label_color),
|
||||
)
|
||||
})
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user