1use crate::{ButtonLink, ListItem, prelude::*};
2use component::{Component, ComponentScope, example_group, single_example};
3use gpui::{IntoElement, ParentElement, SharedString};
4
5#[derive(IntoElement, RegisterComponent)]
6pub struct ListBulletItem {
7 label: SharedString,
8 label_color: Option<Color>,
9 children: Vec<AnyElement>,
10}
11
12impl ListBulletItem {
13 pub fn new(label: impl Into<SharedString>) -> Self {
14 Self {
15 label: label.into(),
16 label_color: None,
17 children: Vec::new(),
18 }
19 }
20
21 pub fn label_color(mut self, color: Color) -> Self {
22 self.label_color = Some(color);
23 self
24 }
25}
26
27impl ParentElement for ListBulletItem {
28 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
29 self.children.extend(elements)
30 }
31}
32
33impl RenderOnce for ListBulletItem {
34 fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement {
35 let line_height = window.line_height() * 0.85;
36
37 ListItem::new("list-item")
38 .selectable(false)
39 .child(
40 h_flex()
41 .w_full()
42 .min_w_0()
43 .gap_1()
44 .items_start()
45 .child(
46 h_flex().h(line_height).justify_center().child(
47 Icon::new(IconName::Dash)
48 .size(IconSize::XSmall)
49 .color(Color::Hidden),
50 ),
51 )
52 .map(|this| {
53 if !self.children.is_empty() {
54 this.child(h_flex().gap_0p5().flex_wrap().children(self.children))
55 } else {
56 this.child(
57 div().w_full().min_w_0().child(
58 Label::new(self.label)
59 .color(self.label_color.unwrap_or(Color::Default)),
60 ),
61 )
62 }
63 }),
64 )
65 .into_any_element()
66 }
67}
68
69impl Component for ListBulletItem {
70 fn scope() -> ComponentScope {
71 ComponentScope::DataDisplay
72 }
73
74 fn description() -> Option<&'static str> {
75 Some("A list item with a dash indicator for unordered lists.")
76 }
77
78 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
79 let basic_examples = vec![
80 single_example(
81 "Simple",
82 ListBulletItem::new("First bullet item").into_any_element(),
83 ),
84 single_example(
85 "Multiple Lines",
86 v_flex()
87 .child(ListBulletItem::new("First item"))
88 .child(ListBulletItem::new("Second item"))
89 .child(ListBulletItem::new("Third item"))
90 .into_any_element(),
91 ),
92 single_example(
93 "Long Text",
94 ListBulletItem::new(
95 "A longer bullet item that demonstrates text wrapping behavior",
96 )
97 .into_any_element(),
98 ),
99 single_example(
100 "With Link",
101 ListBulletItem::new("")
102 .child(Label::new("Create a Zed account by"))
103 .child(ButtonLink::new("visiting the website", "https://zed.dev"))
104 .into_any_element(),
105 ),
106 ];
107
108 Some(
109 v_flex()
110 .gap_6()
111 .child(example_group(basic_examples).vertical())
112 .into_any_element(),
113 )
114 }
115}