1use crate::{ListItem, prelude::*};
2use component::{Component, ComponentScope, example_group_with_title, single_example};
3use gpui::{IntoElement, ParentElement, SharedString};
4
5#[derive(IntoElement, RegisterComponent)]
6pub struct ListBulletItem {
7 label: SharedString,
8}
9
10impl ListBulletItem {
11 pub fn new(label: impl Into<SharedString>) -> Self {
12 Self {
13 label: label.into(),
14 }
15 }
16}
17
18impl RenderOnce for ListBulletItem {
19 fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement {
20 let line_height = window.line_height() * 0.85;
21
22 ListItem::new("list-item")
23 .selectable(false)
24 .child(
25 h_flex()
26 .w_full()
27 .min_w_0()
28 .gap_1()
29 .items_start()
30 .child(
31 h_flex().h(line_height).justify_center().child(
32 Icon::new(IconName::Dash)
33 .size(IconSize::XSmall)
34 .color(Color::Hidden),
35 ),
36 )
37 .child(div().w_full().min_w_0().child(Label::new(self.label))),
38 )
39 .into_any_element()
40 }
41}
42
43impl Component for ListBulletItem {
44 fn scope() -> ComponentScope {
45 ComponentScope::DataDisplay
46 }
47
48 fn description() -> Option<&'static str> {
49 Some("A list item with a bullet point indicator for unordered lists.")
50 }
51
52 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
53 Some(
54 v_flex()
55 .gap_6()
56 .child(example_group_with_title(
57 "Bullet Items",
58 vec![
59 single_example(
60 "Simple",
61 ListBulletItem::new("First bullet item").into_any_element(),
62 ),
63 single_example(
64 "Multiple Lines",
65 v_flex()
66 .child(ListBulletItem::new("First item"))
67 .child(ListBulletItem::new("Second item"))
68 .child(ListBulletItem::new("Third item"))
69 .into_any_element(),
70 ),
71 single_example(
72 "Long Text",
73 ListBulletItem::new(
74 "A longer bullet item that demonstrates text wrapping behavior",
75 )
76 .into_any_element(),
77 ),
78 ],
79 ))
80 .into_any_element(),
81 )
82 }
83}