From 1dd80ac28f436cec7f481dbdfcb90d1d9c1d8cea Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:47:04 -0300 Subject: [PATCH] agent_ui: Add more refinements for v2 flag (#50968) - Fixes message editor in empty state not consuming the whole height of the panel - Remove duped focused method in the `ListItem` - Remove duped "new thread" buttons when group is empty - Add some UI adjustments like removing labels and fading out truncated items Release Notes: - N/A --- crates/agent_ui/src/agent_panel.rs | 2 +- .../src/connection_view/thread_view.rs | 26 ++ crates/agent_ui/src/message_editor.rs | 6 +- crates/sidebar/src/sidebar.rs | 227 ++++++++++-------- crates/ui/src/components/ai/thread_item.rs | 66 +++-- crates/ui/src/components/list/list_item.rs | 14 -- 6 files changed, 202 insertions(+), 139 deletions(-) diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 917de98f7ebaab4c0a7f804b63ba54b2489258ee..4c05be77349aa7fecbe0855e3388e29ddbad2dcd 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -3685,7 +3685,7 @@ impl AgentPanel { h_flex() .gap_1() .child(agent_icon_element) - .child(Label::new(selected_agent_label).color(label_color)) + .child(Label::new(selected_agent_label).color(label_color).ml_0p5()) .child( Icon::new(chevron_icon) .color(icon_color) diff --git a/crates/agent_ui/src/connection_view/thread_view.rs b/crates/agent_ui/src/connection_view/thread_view.rs index 0154ec920c82ccb829ad7486b3de97d5fb33e3ef..0519362ab1194a6e21ff9b3f213112f94f4cce55 100644 --- a/crates/agent_ui/src/connection_view/thread_view.rs +++ b/crates/agent_ui/src/connection_view/thread_view.rs @@ -2715,6 +2715,31 @@ impl ThreadView { (IconName::Maximize, "Expand Message Editor") }; + if v2_empty_state { + self.message_editor.update(cx, |editor, cx| { + editor.set_mode( + EditorMode::Full { + scale_ui_elements_with_buffer_font_size: false, + show_active_line_background: false, + sizing_behavior: SizingBehavior::Default, + }, + cx, + ); + }); + } else { + self.message_editor.update(cx, |editor, cx| { + editor.set_mode( + EditorMode::AutoHeight { + min_lines: AgentSettings::get_global(cx).message_editor_min_lines, + max_lines: Some( + AgentSettings::get_global(cx).set_message_editor_max_lines(), + ), + }, + cx, + ); + }); + } + v_flex() .on_action(cx.listener(Self::expand_message_editor)) .p_2() @@ -2731,6 +2756,7 @@ impl ThreadView { v_flex() .relative() .size_full() + .when(v2_empty_state, |this| this.flex_1()) .pt_1() .pr_2p5() .child(self.message_editor.clone()) diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index cee6725cd15c15f4f39ad5e53be5578f5f5cc3d8..933e24e83c0450dcbdde27d49abebb7fda2fa119 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -1222,8 +1222,10 @@ impl MessageEditor { pub fn set_mode(&mut self, mode: EditorMode, cx: &mut Context) { self.editor.update(cx, |editor, cx| { - editor.set_mode(mode); - cx.notify() + if *editor.mode() != mode { + editor.set_mode(mode); + cx.notify() + } }); } diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index eec55f16af8cf7deefdb8adeddeac5b6b4fb4ea9..40ba738ba98ff4d77932eabeca9bdf0a7d0b8861 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -73,6 +73,7 @@ enum ListEntry { label: SharedString, workspace: Entity, highlight_positions: Vec, + has_threads: bool, }, Thread { session_info: acp_thread::AgentSessionInfo, @@ -322,10 +323,15 @@ impl Sidebar { window, |this, agent_panel, event: &AgentPanelEvent, _window, cx| match event { AgentPanelEvent::ActiveViewChanged => { - if let Some(thread) = agent_panel.read(cx).active_connection_view() - && let Some(session_id) = thread.read(cx).parent_id(cx) - { - this.focused_thread = Some(session_id); + match agent_panel.read(cx).active_connection_view() { + Some(thread) => { + if let Some(session_id) = thread.read(cx).parent_id(cx) { + this.focused_thread = Some(session_id); + } + } + None => { + this.focused_thread = None; + } } this.update_entries(cx); } @@ -334,7 +340,7 @@ impl Sidebar { .read(cx) .active_connection_view() .and_then(|thread| thread.read(cx).parent_id(cx)); - if new_focused != this.focused_thread { + if new_focused.is_some() && new_focused != this.focused_thread { this.focused_thread = new_focused; this.update_entries(cx); } @@ -522,6 +528,7 @@ impl Sidebar { } if !query.is_empty() { + let has_threads = !threads.is_empty(); let mut matched_threads = Vec::new(); for mut thread in threads { if let ListEntry::Thread { @@ -554,14 +561,17 @@ impl Sidebar { label, workspace: workspace.clone(), highlight_positions: workspace_highlight_positions, + has_threads, }); entries.extend(matched_threads); } else { + let has_threads = !threads.is_empty(); entries.push(ListEntry::ProjectHeader { path_list: path_list.clone(), label, workspace: workspace.clone(), highlight_positions: Vec::new(), + has_threads, }); if is_collapsed { @@ -677,12 +687,14 @@ impl Sidebar { label, workspace, highlight_positions, + has_threads, } => self.render_project_header( ix, path_list, label, workspace, highlight_positions, + *has_threads, is_selected, cx, ), @@ -736,12 +748,12 @@ impl Sidebar { label: &SharedString, workspace: &Entity, highlight_positions: &[usize], + has_threads: bool, is_selected: bool, cx: &mut Context, ) -> AnyElement { let id = SharedString::from(format!("project-header-{}", ix)); let ib_id = SharedString::from(format!("project-header-new-thread-{}", ix)); - let group = SharedString::from(format!("group-{}", ix)); let is_collapsed = self.collapsed_groups.contains(path_list); let disclosure_icon = if is_collapsed { @@ -774,20 +786,19 @@ impl Sidebar { .into_any_element() }; - // TODO: if is_selected, draw a blue border around the item. - ListItem::new(id) - .selection_outlined(is_selected) - .group_name(&group) .toggle_state(is_active_workspace) + .focused(is_selected) .child( - h_flex().px_1().py_1p5().gap_0p5().child(label).child( - div().visible_on_hover(group).child( + h_flex() + .p_1() + .gap_1p5() + .child( Icon::new(disclosure_icon) .size(IconSize::Small) - .color(Color::Muted), - ), - ), + .color(Color::Custom(cx.theme().colors().icon_muted.opacity(0.6))), + ) + .child(label), ) .end_hover_slot( h_flex() @@ -808,18 +819,21 @@ impl Sidebar { )), ) }) - .child( - IconButton::new(ib_id, IconName::NewThread) - .icon_size(IconSize::Small) - .icon_color(Color::Muted) - .tooltip(Tooltip::text("New Thread")) - .on_click(cx.listener(move |this, _, window, cx| { - this.selection = None; - this.create_new_thread(&workspace_for_new_thread, window, cx); - })), - ), + .when(has_threads, |this| { + this.child( + IconButton::new(ib_id, IconName::NewThread) + .icon_size(IconSize::Small) + .icon_color(Color::Muted) + .tooltip(Tooltip::text("New Thread")) + .on_click(cx.listener(move |this, _, window, cx| { + this.selection = None; + this.create_new_thread(&workspace_for_new_thread, window, cx); + })), + ) + }), ) .on_click(cx.listener(move |this, _, window, cx| { + this.selection = None; this.toggle_collapse(&path_list_for_toggle, window, cx); })) // TODO: Decide if we really want the header to be activating different workspaces @@ -887,12 +901,7 @@ impl Sidebar { self.update_entries(cx); } - fn focus_in(&mut self, _window: &mut Window, cx: &mut Context) { - if self.selection.is_none() && !self.contents.entries.is_empty() { - self.selection = Some(0); - cx.notify(); - } - } + fn focus_in(&mut self, _window: &mut Window, _cx: &mut Context) {} fn cancel(&mut self, _: &Cancel, window: &mut Window, cx: &mut Context) { if self.reset_filter_editor_text(window, cx) { @@ -1122,7 +1131,7 @@ impl Sidebar { .status(status) .notified(has_notification) .selected(self.focused_thread.as_ref() == Some(&session_info.session_id)) - .outlined(is_selected) + .focused(is_selected) .on_click(cx.listener(move |this, _, window, cx| { this.selection = None; this.activate_thread(session_info.clone(), &workspace, window, cx); @@ -1168,7 +1177,7 @@ impl Sidebar { let count = format!("({})", remaining_count); ListItem::new(id) - .selection_outlined(is_selected) + .focused(is_selected) .child( h_flex() .px_1() @@ -1319,52 +1328,45 @@ impl Render for Sidebar { .justify_between() .border_b_1() .border_color(cx.theme().colors().border) - .child( - h_flex() - .gap_1() - .child({ - let focus_handle_toggle = self.focus_handle.clone(); - let focus_handle_focus = self.focus_handle.clone(); - IconButton::new("close-sidebar", IconName::WorkspaceNavOpen) - .icon_size(IconSize::Small) - .tooltip(Tooltip::element(move |_, cx| { - v_flex() - .gap_1() - .child( - h_flex() - .gap_2() - .justify_between() - .child(Label::new("Close Sidebar")) - .child(KeyBinding::for_action_in( - &ToggleWorkspaceSidebar, - &focus_handle_toggle, - cx, - )), - ) - .child( - h_flex() - .pt_1() - .gap_2() - .border_t_1() - .border_color( - cx.theme().colors().border_variant, - ) - .justify_between() - .child(Label::new(focus_tooltip_label)) - .child(KeyBinding::for_action_in( - &FocusWorkspaceSidebar, - &focus_handle_focus, - cx, - )), - ) - .into_any_element() - })) - .on_click(cx.listener(|_this, _, _window, cx| { - cx.emit(SidebarEvent::Close); - })) - }) - .child(Label::new("Threads").size(LabelSize::Small)), - ) + .child({ + let focus_handle_toggle = self.focus_handle.clone(); + let focus_handle_focus = self.focus_handle.clone(); + IconButton::new("close-sidebar", IconName::WorkspaceNavOpen) + .icon_size(IconSize::Small) + .tooltip(Tooltip::element(move |_, cx| { + v_flex() + .gap_1() + .child( + h_flex() + .gap_2() + .justify_between() + .child(Label::new("Close Sidebar")) + .child(KeyBinding::for_action_in( + &ToggleWorkspaceSidebar, + &focus_handle_toggle, + cx, + )), + ) + .child( + h_flex() + .pt_1() + .gap_2() + .border_t_1() + .border_color(cx.theme().colors().border_variant) + .justify_between() + .child(Label::new(focus_tooltip_label)) + .child(KeyBinding::for_action_in( + &FocusWorkspaceSidebar, + &focus_handle_focus, + cx, + )), + ) + .into_any_element() + })) + .on_click(cx.listener(|_this, _, _window, cx| { + cx.emit(SidebarEvent::Close); + })) + }) .child( IconButton::new("open-project", IconName::OpenFolder) .icon_size(IconSize::Small) @@ -1852,6 +1854,7 @@ mod tests { label: "expanded-project".into(), workspace: workspace.clone(), highlight_positions: Vec::new(), + has_threads: true, }, // Thread with default (Completed) status, not active ListEntry::Thread { @@ -1954,6 +1957,7 @@ mod tests { label: "collapsed-project".into(), workspace: workspace.clone(), highlight_positions: Vec::new(), + has_threads: true, }, ]; // Select the Running thread (index 2) @@ -2014,11 +2018,16 @@ mod tests { cx.run_until_parked(); // Entries: [header, thread3, thread2, thread1] - // Focusing the sidebar triggers focus_in, which selects the first entry + // Focusing the sidebar does not set a selection; select_next/select_previous + // handle None gracefully by starting from the first or last entry. open_and_focus_sidebar(&sidebar, &multi_workspace, cx); + assert_eq!(sidebar.read_with(cx, |s, _| s.selection), None); + + // First SelectNext from None starts at index 0 + cx.dispatch_action(SelectNext); assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); - // Move down through all entries + // Move down through remaining entries cx.dispatch_action(SelectNext); assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(1)); @@ -2072,7 +2081,7 @@ mod tests { } #[gpui::test] - async fn test_keyboard_focus_in_selects_first(cx: &mut TestAppContext) { + async fn test_keyboard_focus_in_does_not_set_selection(cx: &mut TestAppContext) { let project = init_test_project("/my-project", cx).await; let (multi_workspace, cx) = cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx)); @@ -2081,11 +2090,16 @@ mod tests { // Initially no selection assert_eq!(sidebar.read_with(cx, |s, _| s.selection), None); - // Open the sidebar so it's rendered, then focus it to trigger focus_in + // Open the sidebar so it's rendered, then focus it to trigger focus_in. + // focus_in no longer sets a default selection. open_and_focus_sidebar(&sidebar, &multi_workspace, cx); - assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); + assert_eq!(sidebar.read_with(cx, |s, _| s.selection), None); + + // Manually set a selection, blur, then refocus — selection should be preserved + sidebar.update_in(cx, |sidebar, _window, _cx| { + sidebar.selection = Some(0); + }); - // Blur the sidebar, then refocus — existing selection should be preserved cx.update(|window, _cx| { window.blur(); }); @@ -2135,9 +2149,11 @@ mod tests { 1 ); - // Focus the sidebar — focus_in selects the header (index 0) + // Focus the sidebar and manually select the header (index 0) open_and_focus_sidebar(&sidebar, &multi_workspace, cx); - assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); + sidebar.update_in(cx, |sidebar, _window, _cx| { + sidebar.selection = Some(0); + }); // Press confirm on project header (workspace 0) to activate it. cx.dispatch_action(Confirm); @@ -2176,9 +2192,9 @@ mod tests { assert_eq!(entries.len(), 7); assert!(entries.iter().any(|e| e.contains("View More (3)"))); - // Focus sidebar (selects index 0), then navigate down to the "View More" entry (index 6) + // Focus sidebar (selection starts at None), then navigate down to the "View More" entry (index 6) open_and_focus_sidebar(&sidebar, &multi_workspace, cx); - for _ in 0..6 { + for _ in 0..7 { cx.dispatch_action(SelectNext); } assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(6)); @@ -2210,9 +2226,11 @@ mod tests { vec!["v [my-project]", " Thread 1"] ); - // Focus sidebar — focus_in selects the header (index 0). Press left to collapse. + // Focus sidebar and manually select the header (index 0). Press left to collapse. open_and_focus_sidebar(&sidebar, &multi_workspace, cx); - assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); + sidebar.update_in(cx, |sidebar, _window, _cx| { + sidebar.selection = Some(0); + }); cx.dispatch_action(CollapseSelectedEntry); cx.run_until_parked(); @@ -2248,9 +2266,10 @@ mod tests { multi_workspace.update_in(cx, |_, _window, cx| cx.notify()); cx.run_until_parked(); - // Focus sidebar (selects header at index 0), then navigate down to the thread (child) + // Focus sidebar (selection starts at None), then navigate down to the thread (child) open_and_focus_sidebar(&sidebar, &multi_workspace, cx); cx.dispatch_action(SelectNext); + cx.dispatch_action(SelectNext); assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(1)); assert_eq!( @@ -2282,8 +2301,12 @@ mod tests { vec!["v [empty-project]", " [+ New Thread]"] ); - // Focus sidebar — focus_in selects the first entry (header at 0) + // Focus sidebar — focus_in does not set a selection open_and_focus_sidebar(&sidebar, &multi_workspace, cx); + assert_eq!(sidebar.read_with(cx, |s, _| s.selection), None); + + // First SelectNext from None starts at index 0 (header) + cx.dispatch_action(SelectNext); assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); // SelectNext moves to the new thread button @@ -2311,9 +2334,10 @@ mod tests { multi_workspace.update_in(cx, |_, _window, cx| cx.notify()); cx.run_until_parked(); - // Focus sidebar (selects header at 0), navigate down to the thread (index 1) + // Focus sidebar (selection starts at None), navigate down to the thread (index 1) open_and_focus_sidebar(&sidebar, &multi_workspace, cx); cx.dispatch_action(SelectNext); + cx.dispatch_action(SelectNext); assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(1)); // Collapse the group, which removes the thread from the list @@ -2935,9 +2959,11 @@ mod tests { cx.run_until_parked(); // User focuses the sidebar and collapses the group using keyboard: - // select the header, then press CollapseSelectedEntry to collapse. + // manually select the header, then press CollapseSelectedEntry to collapse. open_and_focus_sidebar(&sidebar, &multi_workspace, cx); - assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(0)); + sidebar.update_in(cx, |sidebar, _window, _cx| { + sidebar.selection = Some(0); + }); cx.dispatch_action(CollapseSelectedEntry); cx.run_until_parked(); @@ -3151,15 +3177,12 @@ mod tests { }); assert_eq!(sidebar.read_with(cx, |sidebar, _| sidebar.selection), None); - // When the user tabs back into the sidebar, focus_in restores - // selection to the first entry for keyboard navigation. + // When the user tabs back into the sidebar, focus_in no longer + // restores selection — it stays None. sidebar.update_in(cx, |sidebar, window, cx| { sidebar.focus_in(window, cx); }); - assert_eq!( - sidebar.read_with(cx, |sidebar, _| sidebar.selection), - Some(0) - ); + assert_eq!(sidebar.read_with(cx, |sidebar, _| sidebar.selection), None); } #[gpui::test] diff --git a/crates/ui/src/components/ai/thread_item.rs b/crates/ui/src/components/ai/thread_item.rs index c8f5c8a41cdf74dae16a411b4fe3170b2be04bf3..171a6968290b3239e21faf9cd669559b88f9a964 100644 --- a/crates/ui/src/components/ai/thread_item.rs +++ b/crates/ui/src/components/ai/thread_item.rs @@ -3,7 +3,7 @@ use crate::{ prelude::*, }; -use gpui::{AnyView, ClickEvent, Hsla, SharedString}; +use gpui::{AnyView, ClickEvent, Hsla, SharedString, linear_color_stop, linear_gradient}; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub enum AgentThreadStatus { @@ -24,7 +24,7 @@ pub struct ThreadItem { notified: bool, status: AgentThreadStatus, selected: bool, - outlined: bool, + focused: bool, hovered: bool, added: Option, removed: Option, @@ -48,7 +48,7 @@ impl ThreadItem { notified: false, status: AgentThreadStatus::default(), selected: false, - outlined: false, + focused: false, hovered: false, added: None, removed: None, @@ -92,8 +92,8 @@ impl ThreadItem { self } - pub fn outlined(mut self, outlined: bool) -> Self { - self.outlined = outlined; + pub fn focused(mut self, focused: bool) -> Self { + self.focused = focused; self } @@ -153,7 +153,7 @@ impl ThreadItem { impl RenderOnce for ThreadItem { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { - let clr = cx.theme().colors(); + let color = cx.theme().colors(); // let dot_separator = || { // Label::new("•") // .size(LabelSize::Small) @@ -161,7 +161,7 @@ impl RenderOnce for ThreadItem { // .alpha(0.5) // }; - let icon_container = || h_flex().size_4().justify_center(); + let icon_container = || h_flex().size_4().flex_none().justify_center(); let agent_icon = if let Some(custom_svg) = self.custom_icon_from_external_svg { Icon::from_external_svg(custom_svg) .color(Color::Muted) @@ -189,7 +189,7 @@ impl RenderOnce for ThreadItem { } else if self.status == AgentThreadStatus::Error { Some(decoration(IconDecorationKind::X, cx.theme().status().error)) } else if self.notified { - Some(decoration(IconDecorationKind::Dot, clr.text_accent)) + Some(decoration(IconDecorationKind::Dot, color.text_accent)) } else { None }; @@ -209,15 +209,41 @@ impl RenderOnce for ThreadItem { let title = self.title; let highlight_positions = self.highlight_positions; let title_label = if highlight_positions.is_empty() { - Label::new(title).truncate().into_any_element() + Label::new(title).into_any_element() } else { - HighlightedLabel::new(title, highlight_positions) - .truncate() - .into_any_element() + HighlightedLabel::new(title, highlight_positions).into_any_element() }; + let base_bg = if self.selected { + color.element_active + } else { + color.panel_background + }; + + let gradient_overlay = div() + .absolute() + .top_0() + .right(px(-10.0)) + .w_12() + .h_full() + .bg(linear_gradient( + 90., + linear_color_stop(base_bg, 0.6), + linear_color_stop(base_bg.opacity(0.0), 0.), + )) + .group_hover("thread-item", |s| { + s.bg(linear_gradient( + 90., + linear_color_stop(color.element_hover, 0.6), + linear_color_stop(color.element_hover.opacity(0.0), 0.), + )) + }); + v_flex() .id(self.id.clone()) + .group("thread-item") + .relative() + .overflow_hidden() .cursor_pointer() .w_full() .map(|this| { @@ -227,11 +253,11 @@ impl RenderOnce for ThreadItem { this.px_2().py_1() } }) - .when(self.selected, |s| s.bg(clr.element_active)) + .when(self.selected, |s| s.bg(color.element_active)) .border_1() .border_color(gpui::transparent_black()) - .when(self.outlined, |s| s.border_color(clr.panel_focused_border)) - .hover(|s| s.bg(clr.element_hover)) + .when(self.focused, |s| s.border_color(color.panel_focused_border)) + .hover(|s| s.bg(color.element_hover)) .on_hover(self.on_hover) .child( h_flex() @@ -249,6 +275,7 @@ impl RenderOnce for ThreadItem { .child(title_label) .when_some(self.tooltip, |this, tooltip| this.tooltip(tooltip)), ) + .child(gradient_overlay) .when(running_or_action, |this| { this.child( h_flex() @@ -271,7 +298,6 @@ impl RenderOnce for ThreadItem { Label::new(worktree) .size(LabelSize::Small) .color(Color::Muted) - .truncate_start() .into_any_element() } else { HighlightedLabel::new(worktree, worktree_highlight_positions) @@ -420,25 +446,25 @@ impl Component for ThreadItem { .into_any_element(), ), single_example( - "Outlined Item (Keyboard Selection)", + "Focused Item (Keyboard Selection)", container() .child( ThreadItem::new("ti-7", "Implement keyboard navigation") .icon(IconName::AiClaude) .timestamp("4:00 PM") - .outlined(true), + .focused(true), ) .into_any_element(), ), single_example( - "Selected + Outlined", + "Selected + Focused", container() .child( ThreadItem::new("ti-8", "Active and keyboard-focused thread") .icon(IconName::AiGemini) .timestamp("5:00 PM") .selected(true) - .outlined(true), + .focused(true), ) .into_any_element(), ), diff --git a/crates/ui/src/components/list/list_item.rs b/crates/ui/src/components/list/list_item.rs index cc9c955fd35aa33355be84f9ee3f17f27995ffaf..d581fad9453d9812f17b7bc9e0297fb9927c8188 100644 --- a/crates/ui/src/components/list/list_item.rs +++ b/crates/ui/src/components/list/list_item.rs @@ -42,7 +42,6 @@ pub struct ListItem { selectable: bool, always_show_disclosure_icon: bool, outlined: bool, - selection_outlined: Option, rounded: bool, overflow_x: bool, focused: Option, @@ -72,7 +71,6 @@ impl ListItem { selectable: true, always_show_disclosure_icon: false, outlined: false, - selection_outlined: None, rounded: false, overflow_x: false, focused: None, @@ -173,11 +171,6 @@ impl ListItem { self } - pub fn selection_outlined(mut self, outlined: bool) -> Self { - self.selection_outlined = Some(outlined); - self - } - pub fn rounded(mut self) -> Self { self.rounded = true; self @@ -248,13 +241,6 @@ impl RenderOnce for ListItem { }) }) .when(self.rounded, |this| this.rounded_sm()) - .when_some(self.selection_outlined, |this, outlined| { - this.border_1() - .border_color(gpui::transparent_black()) - .when(outlined, |this| { - this.border_color(cx.theme().colors().panel_focused_border) - }) - }) .when_some(self.on_hover, |this, on_hover| this.on_hover(on_hover)) .child( h_flex()