gpui_component/sidebar/
header.rs1use gpui::{
2 prelude::FluentBuilder as _, Div, InteractiveElement, IntoElement, ParentElement, RenderOnce,
3 Styled,
4};
5
6use crate::{h_flex, popup_menu::PopupMenuExt, ActiveTheme as _, Collapsible, Selectable};
7
8#[derive(IntoElement)]
9pub struct SidebarHeader {
10 base: Div,
11 selected: bool,
12 collapsed: bool,
13}
14
15impl SidebarHeader {
16 pub fn new() -> Self {
17 Self {
18 base: h_flex().gap_2().w_full(),
19 selected: false,
20 collapsed: false,
21 }
22 }
23}
24impl Selectable for SidebarHeader {
25 fn selected(mut self, selected: bool) -> Self {
26 self.selected = selected;
27 self
28 }
29
30 fn is_selected(&self) -> bool {
31 self.selected
32 }
33}
34
35impl Collapsible for SidebarHeader {
36 fn is_collapsed(&self) -> bool {
37 self.collapsed
38 }
39
40 fn collapsed(mut self, collapsed: bool) -> Self {
41 self.collapsed = collapsed;
42 self
43 }
44}
45impl ParentElement for SidebarHeader {
46 fn extend(&mut self, elements: impl IntoIterator<Item = gpui::AnyElement>) {
47 self.base.extend(elements);
48 }
49}
50impl Styled for SidebarHeader {
51 fn style(&mut self) -> &mut gpui::StyleRefinement {
52 self.base.style()
53 }
54}
55
56impl InteractiveElement for SidebarHeader {
57 fn interactivity(&mut self) -> &mut gpui::Interactivity {
58 self.base.interactivity()
59 }
60}
61
62impl PopupMenuExt for SidebarHeader {}
63impl RenderOnce for SidebarHeader {
64 fn render(self, _: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
65 h_flex()
66 .id("sidebar-header")
67 .gap_2()
68 .p_2()
69 .w_full()
70 .justify_between()
71 .rounded(cx.theme().radius)
72 .hover(|this| {
73 this.bg(cx.theme().sidebar_accent)
74 .text_color(cx.theme().sidebar_accent_foreground)
75 })
76 .when(self.selected, |this| {
77 this.bg(cx.theme().sidebar_accent)
78 .text_color(cx.theme().sidebar_accent_foreground)
79 })
80 .child(self.base)
81 }
82}