ui/components/
description_list.rs1use gpui::AnyElement;
2
3use crate::prelude::*;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum DescriptionListMode {
8 #[default]
10 Stacked,
11 Horizontal,
13}
14
15#[derive(IntoElement, RegisterComponent)]
17pub struct DescriptionList {
18 mode: DescriptionListMode,
19 items: Vec<(SharedString, AnyElement)>,
20}
21
22impl DescriptionList {
23 pub fn new() -> Self {
24 Self {
25 mode: DescriptionListMode::default(),
26 items: Vec::new(),
27 }
28 }
29
30 pub fn mode(mut self, mode: DescriptionListMode) -> Self {
31 self.mode = mode;
32 self
33 }
34
35 pub fn item(mut self, label: impl Into<SharedString>, value: impl IntoElement) -> Self {
36 self.items.push((label.into(), value.into_any_element()));
37 self
38 }
39}
40
41impl Default for DescriptionList {
42 fn default() -> Self {
43 Self::new()
44 }
45}
46
47impl RenderOnce for DescriptionList {
48 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
49 let mode = self.mode;
50
51 v_flex()
52 .w_full()
53 .children(
54 self.items
55 .into_iter()
56 .enumerate()
57 .map(move |(index, (label, value))| {
58 let label = Label::new(label).size(LabelSize::Small).color(Color::Muted);
59
60 let row = match mode {
61 DescriptionListMode::Stacked => v_flex()
62 .gap_1()
63 .child(label)
64 .child(value)
65 .into_any_element(),
66 DescriptionListMode::Horizontal => h_flex()
67 .justify_between()
68 .gap_4()
69 .child(label)
70 .child(div().child(value))
71 .into_any_element(),
72 };
73
74 div()
75 .w_full()
76 .py_4()
77 .when(index > 0, |this| {
78 this.border_t_1().border_color(semantic::border_muted(cx))
79 })
80 .child(row)
81 }),
82 )
83 }
84}
85
86impl Component for DescriptionList {
87 fn scope() -> ComponentScope {
88 ComponentScope::DataDisplay
89 }
90
91 fn description() -> Option<&'static str> {
92 Some("A key-value list for displaying structured details, in stacked or horizontal mode.")
93 }
94
95 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
96 Some(
97 v_flex()
98 .gap_6()
99 .children(vec![
100 example_group_with_title(
101 "Stacked",
102 vec![single_example(
103 "Stacked mode",
104 DescriptionList::new()
105 .item("Full name", Label::new("Margot Foster"))
106 .item("Application for", Label::new("Backend Developer"))
107 .item("Email address", Label::new("margotfoster@example.com"))
108 .into_any_element(),
109 )],
110 ),
111 example_group_with_title(
112 "Horizontal",
113 vec![single_example(
114 "Horizontal mode",
115 DescriptionList::new()
116 .mode(DescriptionListMode::Horizontal)
117 .item("Full name", Label::new("Margot Foster"))
118 .item("Application for", Label::new("Backend Developer"))
119 .item("Email address", Label::new("margotfoster@example.com"))
120 .into_any_element(),
121 )],
122 ),
123 ])
124 .into_any_element(),
125 )
126 }
127}