1use gpui::prelude::*;
6use gpui::{div, px, AnyElement, App, IntoElement, SharedString, Window};
7
8use crate::devtools::Probed;
9use crate::theme::{theme, ColorName, Size};
10
11#[derive(IntoElement)]
13pub struct Field {
14 label: Option<SharedString>,
15 description: Option<SharedString>,
16 error: Option<SharedString>,
17 child: Option<AnyElement>,
18}
19
20impl Field {
21 pub fn new() -> Self {
22 Field {
23 label: None,
24 description: None,
25 error: None,
26 child: None,
27 }
28 }
29
30 pub fn label(mut self, label: impl Into<SharedString>) -> Self {
31 self.label = Some(label.into());
32 self
33 }
34
35 pub fn description(mut self, description: impl Into<SharedString>) -> Self {
36 self.description = Some(description.into());
37 self
38 }
39
40 pub fn error(mut self, error: impl Into<SharedString>) -> Self {
41 self.error = Some(error.into());
42 self
43 }
44
45 pub fn child(mut self, child: impl IntoElement) -> Self {
47 self.child = Some(child.into_any_element());
48 self
49 }
50}
51
52impl Default for Field {
53 fn default() -> Self {
54 Field::new()
55 }
56}
57
58impl RenderOnce for Field {
59 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
60 let t = theme(cx);
61 let text = t.text().hsla();
62 let dimmed = t.dimmed().hsla();
63 let error_color = t
64 .color(ColorName::Red, if t.scheme.is_dark() { 5 } else { 7 })
65 .hsla();
66 let font_sm = t.font_size(Size::Sm);
67 let font_xs = t.font_size(Size::Xs);
68
69 let mut column = div().flex().flex_col().min_w(px(0.0)).gap(px(4.0));
70 if let Some(label) = self.label {
71 column = column.child(
72 div()
73 .min_w(px(0.0))
74 .text_size(px(font_sm))
75 .text_color(text)
76 .child(label),
77 );
78 }
79 if let Some(child) = self.child {
80 column = column.child(child);
81 }
82 if let Some(error) = self.error {
83 column = column.child(
84 div()
85 .min_w(px(0.0))
86 .text_size(px(font_xs))
87 .text_color(error_color)
88 .child(error),
89 );
90 } else if let Some(description) = self.description {
91 column = column.child(
92 div()
93 .min_w(px(0.0))
94 .text_size(px(font_xs))
95 .text_color(dimmed)
96 .child(description),
97 );
98 }
99 column.probe("Field")
100 }
101}