1use crate::prelude::*;
2use crate::{Icon, IconName, IconSize, Label, h_flex};
3
4#[derive(IntoElement)]
5pub struct ListSubHeader {
6 label: SharedString,
7 start_slot: Option<IconName>,
8 end_slot: Option<AnyElement>,
9 inset: bool,
10 selected: bool,
11}
12
13impl ListSubHeader {
14 pub fn new(label: impl Into<SharedString>) -> Self {
15 Self {
16 label: label.into(),
17 start_slot: None,
18 end_slot: None,
19 inset: false,
20 selected: false,
21 }
22 }
23
24 pub fn left_icon(mut self, left_icon: Option<IconName>) -> Self {
25 self.start_slot = left_icon;
26 self
27 }
28
29 pub fn end_slot(mut self, end_slot: AnyElement) -> Self {
30 self.end_slot = Some(end_slot);
31 self
32 }
33
34 pub fn inset(mut self, inset: bool) -> Self {
35 self.inset = inset;
36 self
37 }
38}
39
40impl Toggleable for ListSubHeader {
41 fn toggle_state(mut self, selected: bool) -> Self {
42 self.selected = selected;
43 self
44 }
45}
46
47impl RenderOnce for ListSubHeader {
48 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
49 h_flex()
50 .flex_1()
51 .w_full()
52 .relative()
53 .pb(DynamicSpacing::Base04.rems(cx))
54 .px(DynamicSpacing::Base02.rems(cx))
55 .child(
56 div()
57 .h_5()
58 .when(self.inset, |this| this.px_2())
59 .when(self.selected, |this| {
60 this.bg(cx.theme().colors().ghost_element_selected)
61 })
62 .flex()
63 .flex_1()
64 .w_full()
65 .gap_1()
66 .items_center()
67 .justify_between()
68 .child(
69 div()
70 .flex()
71 .gap_1()
72 .items_center()
73 .children(
74 self.start_slot.map(|i| {
75 Icon::new(i).color(Color::Muted).size(IconSize::Small)
76 }),
77 )
78 .child(
79 Label::new(self.label.clone())
80 .color(Color::Muted)
81 .size(LabelSize::Small),
82 ),
83 )
84 .children(self.end_slot),
85 )
86 }
87}