list.rs

 1use crate::theme::theme;
 2use crate::tokens::token;
 3use crate::{icon, label, prelude::*, IconAsset, LabelColor, ListItem, ListSectionHeader};
 4use gpui2::style::StyleHelpers;
 5use gpui2::{elements::div, IntoElement};
 6use gpui2::{Element, ParentElement, ViewContext};
 7
 8#[derive(Element)]
 9pub struct List {
10    header: Option<ListSectionHeader>,
11    items: Vec<ListItem>,
12    empty_message: &'static str,
13    toggle: Option<ToggleState>,
14    // footer: Option<ListSectionFooter>,
15}
16
17pub fn list(items: Vec<ListItem>) -> List {
18    List {
19        header: None,
20        items,
21        empty_message: "No items",
22        toggle: None,
23    }
24}
25
26impl List {
27    pub fn header(mut self, header: ListSectionHeader) -> Self {
28        self.header = Some(header);
29        self
30    }
31
32    pub fn empty_message(mut self, empty_message: &'static str) -> Self {
33        self.empty_message = empty_message;
34        self
35    }
36
37    pub fn set_toggle(mut self, toggle: ToggleState) -> Self {
38        self.toggle = Some(toggle);
39        self
40    }
41
42    fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
43        let theme = theme(cx);
44        let token = token();
45
46        let disclosure_control = match self.toggle {
47            Some(ToggleState::NotToggled) => Some(icon(IconAsset::ChevronRight)),
48            Some(ToggleState::Toggled) => Some(icon(IconAsset::ChevronDown)),
49            None => None,
50        };
51
52        div()
53            .py_1()
54            .flex()
55            .flex_col()
56            .children(self.header.map(|h| h))
57            .children(
58                self.items
59                    .is_empty()
60                    .then(|| label(self.empty_message).color(LabelColor::Muted)),
61            )
62            .children(self.items.iter().cloned())
63    }
64}