sidebar: Add some design adjustments (#52832)
- Adjust thread item and gradient fade colors for themes that define transparent colors for the tokens we use on them - Make the entire project header clickable area activate the workspace instead of collapsing the group. The chevron is now an icon button that does that, which makes it consistent with the collab panel and settings UI. Release Notes: - N/A
This commit is contained in:
1 parent
833b8074e7
commit
9503795c6c
5 files changed
+64
-67
No files matched your search
@@ -1,7 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5Z" fill="#C6CAD0"/>
|
||||
<path d="M2.25 4.80555V3.52777C2.25 3.18889 2.38462 2.86388 2.62425 2.62425C2.86388 2.38462 3.18889 2.25 3.52777 2.25H4.80555" stroke="#C6CAD0" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.1945 2.25H12.4722C12.8111 2.25 13.1361 2.38462 13.3758 2.62425C13.6154 2.86388 13.75 3.18889 13.75 3.52777V4.80555" stroke="#C6CAD0" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.75 11.1945V12.4722C13.75 12.8111 13.6154 13.1361 13.3758 13.3758C13.1361 13.6154 12.8111 13.75 12.4722 13.75H11.1945" stroke="#C6CAD0" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4.80555 13.75H3.52777C3.18889 13.75 2.86388 13.6154 2.62425 13.3758C2.38462 13.1361 2.25 12.8111 2.25 12.4722V11.1945" stroke="#C6CAD0" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -131,7 +131,6 @@ pub enum IconName {
|
||||
FileTree,
|
||||
Filter,
|
||||
Flame,
|
||||
Focus,
|
||||
Folder,
|
||||
FolderOpen,
|
||||
FolderPlus,
|
||||
|
||||
@@ -1281,13 +1281,14 @@ impl Sidebar {
|
||||
) -> AnyElement {
|
||||
let id_prefix = if is_sticky { "sticky-" } else { "" };
|
||||
let id = SharedString::from(format!("{id_prefix}project-header-{ix}"));
|
||||
let disclosure_id = SharedString::from(format!("disclosure-{ix}"));
|
||||
let group_name = SharedString::from(format!("{id_prefix}header-group-{ix}"));
|
||||
|
||||
let is_collapsed = self.collapsed_groups.contains(path_list);
|
||||
let disclosure_icon = if is_collapsed {
|
||||
IconName::ChevronRight
|
||||
let (disclosure_icon, disclosure_tooltip) = if is_collapsed {
|
||||
(IconName::ChevronRight, "Expand Project")
|
||||
} else {
|
||||
IconName::ChevronDown
|
||||
(IconName::ChevronDown, "Collapse Project")
|
||||
};
|
||||
|
||||
let has_new_thread_entry = self
|
||||
@@ -1325,8 +1326,8 @@ impl Sidebar {
|
||||
.group(&group_name)
|
||||
.h(Tab::content_height(cx))
|
||||
.w_full()
|
||||
.pl_1p5()
|
||||
.pr_1()
|
||||
.pl(px(5.))
|
||||
.pr_1p5()
|
||||
.border_1()
|
||||
.map(|this| {
|
||||
if is_selected {
|
||||
@@ -1339,16 +1340,21 @@ impl Sidebar {
|
||||
.hover(|s| s.bg(hover_color))
|
||||
.child(
|
||||
h_flex()
|
||||
.when(!is_active, |this| this.cursor_pointer())
|
||||
.relative()
|
||||
.min_w_0()
|
||||
.w_full()
|
||||
.gap_1p5()
|
||||
.gap(px(5.))
|
||||
.child(
|
||||
h_flex().size_4().flex_none().justify_center().child(
|
||||
Icon::new(disclosure_icon)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Custom(cx.theme().colors().icon_muted.opacity(0.5))),
|
||||
),
|
||||
IconButton::new(disclosure_id, disclosure_icon)
|
||||
.shape(ui::IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(Color::Custom(cx.theme().colors().icon_muted.opacity(0.5)))
|
||||
.tooltip(Tooltip::text(disclosure_tooltip))
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
this.selection = None;
|
||||
this.toggle_collapse(&path_list_for_toggle, window, cx);
|
||||
})),
|
||||
)
|
||||
.child(label)
|
||||
.when_some(
|
||||
@@ -1425,39 +1431,6 @@ impl Sidebar {
|
||||
})),
|
||||
)
|
||||
})
|
||||
.when(!is_active, |this| {
|
||||
this.child(
|
||||
IconButton::new(
|
||||
SharedString::from(format!(
|
||||
"{id_prefix}project-header-open-workspace-{ix}",
|
||||
)),
|
||||
IconName::Focus,
|
||||
)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(Color::Muted)
|
||||
.tooltip(Tooltip::text("Activate Workspace"))
|
||||
.on_click(cx.listener({
|
||||
move |this, _, window, cx| {
|
||||
this.active_entry =
|
||||
Some(ActiveEntry::Draft(workspace_for_open.clone()));
|
||||
if let Some(multi_workspace) = this.multi_workspace.upgrade() {
|
||||
multi_workspace.update(cx, |multi_workspace, cx| {
|
||||
multi_workspace.activate(
|
||||
workspace_for_open.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
if AgentPanel::is_visible(&workspace_for_open, cx) {
|
||||
workspace_for_open.update(cx, |workspace, cx| {
|
||||
workspace.focus_panel::<AgentPanel>(window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
})),
|
||||
)
|
||||
})
|
||||
.when(show_new_thread_button, |this| {
|
||||
this.child(
|
||||
IconButton::new(
|
||||
@@ -1483,10 +1456,29 @@ impl Sidebar {
|
||||
)
|
||||
})
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
this.selection = None;
|
||||
this.toggle_collapse(&path_list_for_toggle, window, cx);
|
||||
}))
|
||||
.when(!is_active, |this| {
|
||||
this.tooltip(Tooltip::text("Activate Workspace"))
|
||||
.on_click(cx.listener({
|
||||
move |this, _, window, cx| {
|
||||
this.active_entry =
|
||||
Some(ActiveEntry::Draft(workspace_for_open.clone()));
|
||||
if let Some(multi_workspace) = this.multi_workspace.upgrade() {
|
||||
multi_workspace.update(cx, |multi_workspace, cx| {
|
||||
multi_workspace.activate(
|
||||
workspace_for_open.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
if AgentPanel::is_visible(&workspace_for_open, cx) {
|
||||
workspace_for_open.update(cx, |workspace, cx| {
|
||||
workspace.focus_panel::<AgentPanel>(window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
@@ -2779,6 +2771,11 @@ impl Sidebar {
|
||||
|
||||
let id = SharedString::from(format!("thread-entry-{}", ix));
|
||||
|
||||
let color = cx.theme().colors();
|
||||
let sidebar_bg = color
|
||||
.title_bar_background
|
||||
.blend(color.panel_background.opacity(0.32));
|
||||
|
||||
let timestamp = format_history_entry_timestamp(
|
||||
self.thread_last_message_sent_or_queued
|
||||
.get(&thread.metadata.session_id)
|
||||
@@ -2788,6 +2785,7 @@ impl Sidebar {
|
||||
);
|
||||
|
||||
ThreadItem::new(id, title)
|
||||
.base_bg(sidebar_bg)
|
||||
.icon(thread.icon)
|
||||
.status(thread.status)
|
||||
.when_some(thread.icon_from_external_svg.clone(), |this, svg| {
|
||||
|
||||
@@ -218,21 +218,23 @@ impl RenderOnce for ThreadItem {
|
||||
let color = cx.theme().colors();
|
||||
let sidebar_base_bg = color
|
||||
.title_bar_background
|
||||
.blend(color.panel_background.opacity(0.2));
|
||||
.blend(color.panel_background.opacity(0.32));
|
||||
|
||||
let base_bg = self.base_bg.unwrap_or(sidebar_base_bg);
|
||||
let raw_bg = self.base_bg.unwrap_or(sidebar_base_bg);
|
||||
let apparent_bg = color.background.blend(raw_bg);
|
||||
|
||||
let base_bg = if self.selected {
|
||||
color.element_active
|
||||
apparent_bg.blend(color.element_active)
|
||||
} else {
|
||||
base_bg
|
||||
apparent_bg
|
||||
};
|
||||
|
||||
let hover_color = color
|
||||
.element_active
|
||||
.blend(color.element_background.opacity(0.2));
|
||||
let hover_bg = apparent_bg.blend(hover_color);
|
||||
|
||||
let gradient_overlay = GradientFade::new(base_bg, hover_color, hover_color)
|
||||
let gradient_overlay = GradientFade::new(base_bg, hover_bg, hover_bg)
|
||||
.width(px(64.0))
|
||||
.right(px(-10.0))
|
||||
.gradient_stop(0.75)
|
||||
@@ -399,7 +401,7 @@ impl RenderOnce for ThreadItem {
|
||||
.child(gradient_overlay)
|
||||
.when(self.hovered, |this| {
|
||||
this.when_some(self.action_slot, |this, slot| {
|
||||
let overlay = GradientFade::new(base_bg, hover_color, hover_color)
|
||||
let overlay = GradientFade::new(base_bg, hover_bg, hover_bg)
|
||||
.width(px(64.0))
|
||||
.right(px(6.))
|
||||
.gradient_stop(0.75)
|
||||
@@ -432,6 +434,7 @@ impl RenderOnce for ThreadItem {
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
.into();
|
||||
|
||||
let worktree_tooltip_title = if self.worktrees.len() > 1 {
|
||||
"Thread Running in Local Git Worktrees"
|
||||
} else {
|
||||
|
||||
@@ -49,10 +49,14 @@ impl GradientFade {
|
||||
}
|
||||
|
||||
impl RenderOnce for GradientFade {
|
||||
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let stop = self.gradient_stop;
|
||||
let hover_bg = self.hover_bg;
|
||||
let active_bg = self.active_bg;
|
||||
|
||||
// Best-effort to flatten potentially-transparent colors to opaque ones.
|
||||
let app_bg = cx.theme().colors().background;
|
||||
let base_bg = app_bg.blend(self.base_bg);
|
||||
let hover_bg = app_bg.blend(self.hover_bg);
|
||||
let active_bg = app_bg.blend(self.active_bg);
|
||||
|
||||
div()
|
||||
.id("gradient_fade")
|
||||
@@ -63,8 +67,8 @@ impl RenderOnce for GradientFade {
|
||||
.h_full()
|
||||
.bg(linear_gradient(
|
||||
90.,
|
||||
linear_color_stop(self.base_bg, stop),
|
||||
linear_color_stop(self.base_bg.opacity(0.0), 0.),
|
||||
linear_color_stop(base_bg, stop),
|
||||
linear_color_stop(base_bg.opacity(0.0), 0.),
|
||||
))
|
||||
.when_some(self.group_name.clone(), |element, group_name| {
|
||||
element.group_hover(group_name, move |s| {
|
||||
|
||||
Reference in new issue
Block a user