1#![allow(missing_docs)]
2
3use crate::prelude::*;
4use crate::{h_flex, Icon, IconName, IconSize, Label};
5
6#[derive(IntoElement)]
7pub struct ListSubHeader {
8 label: SharedString,
9 start_slot: Option<IconName>,
10 inset: bool,
11 selected: bool,
12}
13
14impl ListSubHeader {
15 pub fn new(label: impl Into<SharedString>) -> Self {
16 Self {
17 label: label.into(),
18 start_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 inset(mut self, inset: bool) -> Self {
30 self.inset = inset;
31 self
32 }
33}
34
35impl Toggleable for ListSubHeader {
36 fn toggle_state(mut self, selected: bool) -> Self {
37 self.selected = selected;
38 self
39 }
40}
41
42impl RenderOnce for ListSubHeader {
43 fn render(self, cx: &mut WindowContext) -> impl IntoElement {
44 h_flex()
45 .flex_1()
46 .w_full()
47 .relative()
48 .pb(DynamicSpacing::Base04.rems(cx))
49 .px(DynamicSpacing::Base02.rems(cx))
50 .child(
51 div()
52 .h_6()
53 .when(self.inset, |this| this.px_2())
54 .when(self.selected, |this| {
55 this.bg(cx.theme().colors().ghost_element_selected)
56 })
57 .flex()
58 .flex_1()
59 .w_full()
60 .gap_1()
61 .items_center()
62 .justify_between()
63 .child(
64 div()
65 .flex()
66 .gap_1()
67 .items_center()
68 .children(
69 self.start_slot.map(|i| {
70 Icon::new(i).color(Color::Muted).size(IconSize::Small)
71 }),
72 )
73 .child(Label::new(self.label.clone()).color(Color::Muted)),
74 ),
75 )
76 }
77}