list_bullet_item.rs

  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}