list.rs

 1mod list_header;
 2mod list_item;
 3mod list_separator;
 4mod list_sub_header;
 5
 6pub use list_header::*;
 7pub use list_item::*;
 8pub use list_separator::*;
 9pub use list_sub_header::*;
10
11use gpui::AnyElement;
12use smallvec::SmallVec;
13
14use crate::{prelude::*, v_flex, Label};
15
16pub use ListHeader;
17
18#[derive(IntoElement)]
19pub struct List {
20    /// Message to display when the list is empty
21    /// Defaults to "No items"
22    empty_message: SharedString,
23    header: Option<ListHeader>,
24    toggle: Option<bool>,
25    children: SmallVec<[AnyElement; 2]>,
26}
27
28impl Default for List {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl List {
35    pub fn new() -> Self {
36        Self {
37            empty_message: "No items".into(),
38            header: None,
39            toggle: None,
40            children: SmallVec::new(),
41        }
42    }
43
44    pub fn empty_message(mut self, empty_message: impl Into<SharedString>) -> Self {
45        self.empty_message = empty_message.into();
46        self
47    }
48
49    pub fn header(mut self, header: impl Into<Option<ListHeader>>) -> Self {
50        self.header = header.into();
51        self
52    }
53
54    pub fn toggle(mut self, toggle: impl Into<Option<bool>>) -> Self {
55        self.toggle = toggle.into();
56        self
57    }
58}
59
60impl ParentElement for List {
61    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
62        self.children.extend(elements)
63    }
64}
65
66impl RenderOnce for List {
67    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
68        v_flex().w_full().py_1().children(self.header).map(|this| {
69            match (self.children.is_empty(), self.toggle) {
70                (false, _) => this.children(self.children),
71                (true, Some(false)) => this,
72                (true, _) => this.child(Label::new(self.empty_message.clone()).color(Color::Muted)),
73            }
74        })
75    }
76}