list.rs

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