use crate::{v_flex, ActiveTheme, Collapsible}; use gpui::{ div, prelude::FluentBuilder as _, App, Div, IntoElement, ParentElement, RenderOnce, SharedString, Styled as _, Window, }; /// A sidebar group #[derive(IntoElement)] pub struct SidebarGroup { base: Div, label: SharedString, collapsed: bool, children: Vec, } impl SidebarGroup { pub fn new(label: impl Into) -> Self { Self { base: div().gap_2().flex_col(), label: label.into(), collapsed: false, children: Vec::new(), } } pub fn child(mut self, child: E) -> Self { self.children.push(child); self } pub fn children(mut self, children: impl IntoIterator) -> Self { self.children.extend(children); self } } impl Collapsible for SidebarGroup { fn is_collapsed(&self) -> bool { self.collapsed } fn collapsed(mut self, collapsed: bool) -> Self { self.collapsed = collapsed; self } } impl RenderOnce for SidebarGroup { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { v_flex() .relative() .p_2() .when(!self.collapsed, |this| { this.child( div() .flex_shrink_0() .px_2() .rounded(cx.theme().radius) .text_xs() .text_color(cx.theme().sidebar_foreground.opacity(0.7)) .h_8() .child(self.label), ) }) .child( self.base.children( self.children .into_iter() .map(|child| child.collapsed(self.collapsed)), ), ) } }