vertigo_forms/resource_table/row_from_data_section.rs
1use vertigo::{DomNode, css, dom};
2
3use crate::{
4 form::{DataSection, Field},
5 resource_table::{base_row_css, normal_col_css},
6};
7
8/// Renders a single row in a `ResourceTable` using a `DataSection`.
9///
10/// This function simplifies building editable table rows by leveraging `vertigo_forms::form::DataSection`
11/// to automatically render form fields based on the section's definition.
12///
13/// # Arguments
14///
15/// * `section` - A reference to the `DataSection` containing the row's form fields.
16/// * `buttons` - A `DomNode` containing the action buttons (e.g., Save, Cancel) to render in the last column.
17/// * `grid_template_columns` - A string specifying the CSS `grid-template-columns` property to align the
18/// row's cells with the table header (e.g., `"50px 1fr 100px 150px"`).
19///
20/// # Example
21///
22/// ```rust,ignore
23/// render_row_form: |form: &Rc<DataSection>, buttons| {
24/// row_from_data_section(form, buttons, "50px 1fr 100px 150px")
25/// }
26/// ```
27pub fn row_from_data_section(
28 section: &DataSection,
29 buttons: DomNode,
30 grid_template_columns: &str,
31) -> DomNode {
32 let fields: Vec<DomNode> = section
33 .fields
34 .iter()
35 .map(|field| {
36 dom! { <Field {field} /> }
37 })
38 .collect();
39
40 let error_node = section.error.as_ref().map(|err| {
41 dom! { <span css={css! {"color: red; font-size: 0.8rem;"}}>{err}</span> }
42 });
43
44 dom! {
45 <div css={base_row_css() + css! {"grid-template-columns: {grid_template_columns};"}}>
46 <div css={normal_col_css()}>{section.label.clone()}</div>
47 {..fields}
48 {..error_node}
49 <div>{buttons}</div>
50 </div>
51 }
52}