gpui_component/sidebar/
group.rs

1use crate::{v_flex, ActiveTheme, Collapsible};
2use gpui::{
3    div, prelude::FluentBuilder as _, App, Div, IntoElement, ParentElement, RenderOnce,
4    SharedString, Styled as _, Window,
5};
6
7/// A sidebar group
8#[derive(IntoElement)]
9pub struct SidebarGroup<E: Collapsible + IntoElement + 'static> {
10    base: Div,
11    label: SharedString,
12    collapsed: bool,
13    children: Vec<E>,
14}
15
16impl<E: Collapsible + IntoElement> SidebarGroup<E> {
17    pub fn new(label: impl Into<SharedString>) -> Self {
18        Self {
19            base: div().gap_2().flex_col(),
20            label: label.into(),
21            collapsed: false,
22            children: Vec::new(),
23        }
24    }
25
26    pub fn child(mut self, child: E) -> Self {
27        self.children.push(child);
28        self
29    }
30
31    pub fn children(mut self, children: impl IntoIterator<Item = E>) -> Self {
32        self.children.extend(children);
33        self
34    }
35}
36impl<E: Collapsible + IntoElement> Collapsible for SidebarGroup<E> {
37    fn is_collapsed(&self) -> bool {
38        self.collapsed
39    }
40
41    fn collapsed(mut self, collapsed: bool) -> Self {
42        self.collapsed = collapsed;
43        self
44    }
45}
46impl<E: Collapsible + IntoElement> RenderOnce for SidebarGroup<E> {
47    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
48        v_flex()
49            .relative()
50            .p_2()
51            .when(!self.collapsed, |this| {
52                this.child(
53                    div()
54                        .flex_shrink_0()
55                        .px_2()
56                        .rounded(cx.theme().radius)
57                        .text_xs()
58                        .text_color(cx.theme().sidebar_foreground.opacity(0.7))
59                        .h_8()
60                        .child(self.label),
61                )
62            })
63            .child(
64                self.base.children(
65                    self.children
66                        .into_iter()
67                        .map(|child| child.collapsed(self.collapsed)),
68                ),
69            )
70    }
71}