diff --git a/crates/agent/src/assistant_panel.rs b/crates/agent/src/assistant_panel.rs index 2f788d18f4..8a060d80bc 100644 --- a/crates/agent/src/assistant_panel.rs +++ b/crates/agent/src/assistant_panel.rs @@ -458,7 +458,8 @@ impl AssistantPanel { for entry in recently_opened.iter() { let summary = entry.summary(cx); - menu = menu.entry_with_end_slot( + + menu = menu.entry_with_end_slot_on_hover( summary, None, { diff --git a/crates/ui/src/components/context_menu.rs b/crates/ui/src/components/context_menu.rs index a076a08aef..4f6703c566 100644 --- a/crates/ui/src/components/context_menu.rs +++ b/crates/ui/src/components/context_menu.rs @@ -52,6 +52,7 @@ pub struct ContextMenuEntry { end_slot_icon: Option, end_slot_title: Option, end_slot_handler: Option, &mut Window, &mut App)>>, + show_end_slot_on_hover: bool, } impl ContextMenuEntry { @@ -70,6 +71,7 @@ impl ContextMenuEntry { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, } } @@ -365,6 +367,7 @@ impl ContextMenu { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, })); self } @@ -392,6 +395,35 @@ impl ContextMenu { end_slot_icon: Some(end_slot_icon), end_slot_title: Some(end_slot_title), end_slot_handler: Some(Rc::new(move |_, window, cx| end_slot_handler(window, cx))), + show_end_slot_on_hover: false, + })); + self + } + + pub fn entry_with_end_slot_on_hover( + mut self, + label: impl Into, + action: Option>, + handler: impl Fn(&mut Window, &mut App) + 'static, + end_slot_icon: IconName, + end_slot_title: SharedString, + end_slot_handler: impl Fn(&mut Window, &mut App) + 'static, + ) -> Self { + self.items.push(ContextMenuItem::Entry(ContextMenuEntry { + toggle: None, + label: label.into(), + handler: Rc::new(move |_, window, cx| handler(window, cx)), + icon: None, + icon_position: IconPosition::End, + icon_size: IconSize::Small, + icon_color: None, + action, + disabled: false, + documentation_aside: None, + end_slot_icon: Some(end_slot_icon), + end_slot_title: Some(end_slot_title), + end_slot_handler: Some(Rc::new(move |_, window, cx| end_slot_handler(window, cx))), + show_end_slot_on_hover: true, })); self } @@ -418,6 +450,7 @@ impl ContextMenu { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, })); self } @@ -472,6 +505,7 @@ impl ContextMenu { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, })); self } @@ -500,6 +534,7 @@ impl ContextMenu { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, })); self } @@ -519,6 +554,7 @@ impl ContextMenu { end_slot_icon: None, end_slot_title: None, end_slot_handler: None, + show_end_slot_on_hover: false, })); self } @@ -822,6 +858,7 @@ impl ContextMenu { end_slot_icon, end_slot_title, end_slot_handler, + show_end_slot_on_hover, } = entry; let this = cx.weak_entity(); @@ -884,6 +921,7 @@ impl ContextMenu { ) .child( ListItem::new(ix) + .group_name("label_container") .inset(true) .disabled(*disabled) .toggle_state(Some(ix) == self.selected_index) @@ -942,8 +980,8 @@ impl ContextMenu { .zip(end_slot_title.as_ref()) .zip(end_slot_handler.as_ref()), |el, (((icon, action), title), handler)| { - el.end_slot( - IconButton::new("end-slot-icon", *icon) + el.end_slot({ + let icon_button = IconButton::new("end-slot-icon", *icon) .shape(IconButtonShape::Square) .tooltip({ let action_context = self.action_context.clone(); @@ -981,8 +1019,17 @@ impl ContextMenu { }) .ok(); } - }), - ) + }); + + if *show_end_slot_on_hover { + div() + .visible_on_hover("label_container") + .child(icon_button) + .into_any_element() + } else { + icon_button.into_any_element() + } + }) }, ) .on_click({ diff --git a/crates/ui/src/components/list/list_item.rs b/crates/ui/src/components/list/list_item.rs index 8462e99eb8..9570301e2b 100644 --- a/crates/ui/src/components/list/list_item.rs +++ b/crates/ui/src/components/list/list_item.rs @@ -16,6 +16,7 @@ pub enum ListItemSpacing { #[derive(IntoElement)] pub struct ListItem { id: ElementId, + group_name: Option, disabled: bool, selected: bool, spacing: ListItemSpacing, @@ -48,6 +49,7 @@ impl ListItem { pub fn new(id: impl Into) -> Self { Self { id: id.into(), + group_name: None, disabled: false, selected: false, spacing: ListItemSpacing::Dense, @@ -72,6 +74,11 @@ impl ListItem { } } + pub fn group_name(mut self, group_name: impl Into) -> Self { + self.group_name = Some(group_name.into()); + self + } + pub fn spacing(mut self, spacing: ListItemSpacing) -> Self { self.spacing = spacing; self @@ -196,6 +203,7 @@ impl RenderOnce for ListItem { fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { h_flex() .id(self.id) + .when_some(self.group_name, |this, group| this.group(group)) .w_full() .relative() // When an item is inset draw the indent spacing outside of the item