list.rs

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