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}