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 List {
17 pub fn new() -> Self {
18 Self {
19 empty_message: "No items".into(),
20 header: None,
21 toggle: None,
22 children: SmallVec::new(),
23 }
24 }
25
26 pub fn empty_message(mut self, empty_message: impl Into<SharedString>) -> Self {
27 self.empty_message = empty_message.into();
28 self
29 }
30
31 pub fn header(mut self, header: impl Into<Option<ListHeader>>) -> Self {
32 self.header = header.into();
33 self
34 }
35
36 pub fn toggle(mut self, toggle: impl Into<Option<bool>>) -> Self {
37 self.toggle = toggle.into();
38 self
39 }
40}
41
42impl ParentElement for List {
43 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
44 self.children.extend(elements)
45 }
46}
47
48impl RenderOnce for List {
49 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
50 v_flex().w_full().py_1().children(self.header).map(|this| {
51 match (self.children.is_empty(), self.toggle) {
52 (false, _) => this.children(self.children),
53 (true, Some(false)) => this,
54 (true, _) => this.child(Label::new(self.empty_message.clone()).color(Color::Muted)),
55 }
56 })
57 }
58}