gpui_component/form/
form.rs1use gpui::{
2 App, Axis, IntoElement, ParentElement, Pixels, Rems, RenderOnce, StyleRefinement, Styled,
3 Window, px,
4};
5
6use crate::{
7 Sizable, Size,
8 form::{Field, FieldProps},
9 v_flex,
10};
11
12#[derive(IntoElement)]
14pub struct Form {
15 style: StyleRefinement,
16 fields: Vec<Field>,
17 props: FieldProps,
18}
19
20impl Form {
21 fn new() -> Self {
22 Self {
23 style: StyleRefinement::default(),
24 props: FieldProps::default(),
25 fields: Vec::new(),
26 }
27 }
28
29 pub fn horizontal() -> Self {
31 Self::new().layout(Axis::Horizontal)
32 }
33
34 pub fn vertical() -> Self {
36 Self::new().layout(Axis::Vertical)
37 }
38
39 pub fn layout(mut self, layout: Axis) -> Self {
41 self.props.layout = layout;
42 self
43 }
44
45 pub fn label_width(mut self, width: Pixels) -> Self {
47 self.props.label_width = Some(width);
48 self
49 }
50
51 pub fn label_text_size(mut self, size: Rems) -> Self {
53 self.props.label_text_size = Some(size);
54 self
55 }
56
57 pub fn child(mut self, field: impl Into<Field>) -> Self {
59 self.fields.push(field.into());
60 self
61 }
62
63 pub fn children(mut self, fields: impl IntoIterator<Item = Field>) -> Self {
65 self.fields.extend(fields);
66 self
67 }
68
69 pub fn columns(mut self, columns: usize) -> Self {
73 self.props.columns = columns;
74 self
75 }
76}
77
78impl Styled for Form {
79 fn style(&mut self) -> &mut StyleRefinement {
80 &mut self.style
81 }
82}
83
84impl Sizable for Form {
85 fn with_size(mut self, size: impl Into<Size>) -> Self {
86 self.props.size = size.into();
87 self
88 }
89}
90
91impl RenderOnce for Form {
92 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
93 let props = self.props;
94
95 let gap = match props.size {
96 Size::XSmall | Size::Small => px(6.),
97 Size::Large => px(12.),
98 _ => px(8.),
99 };
100
101 v_flex()
102 .w_full()
103 .gap_x(gap * 3.)
104 .gap_y(gap)
105 .grid()
106 .grid_cols(props.columns as u16)
107 .children(
108 self.fields
109 .into_iter()
110 .enumerate()
111 .map(|(ix, field)| field.props(ix, props)),
112 )
113 }
114}