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