table_rs/yew/body.rs
1use crate::yew::types::TableBodyProps;
2use yew::prelude::*;
3
4/// A table body component that handles rendering of table rows, empty state, and loading state.
5///
6/// This component is part of the `table_rs` Yew integration and is responsible for rendering
7/// the `<tbody>` section of a table, based on the provided data and configuration.
8///
9/// # Arguments
10/// * `props` - The properties passed to the component.
11/// - `columns` - A list of column definitions (`Vec<Column>`) specifying which fields to render.
12/// - `rows` - A vector of row data (`Vec<HashMap<&'static str, String>>`) to display.
13/// - `loading` - A boolean flag indicating whether the table is in a loading state.
14/// - `classes` - A `TableClasses` object defining CSS class names for customization.
15/// - `texts` - A `TableTexts` object defining UI text like loading or empty messages.
16///
17/// # Returns
18/// (Html): A rendered `<tbody>` element, containing:
19/// - A loading row if `loading` is `true`.
20/// - An empty state row if `rows` is empty.
21/// - The list of rows otherwise.
22///
23/// # Examples
24/// ```rust
25/// use table_rs::yew::body::TableBody;
26/// use table_rs::yew::types::{TableBodyProps, Column, TableClasses, TableTexts};
27/// use yew::prelude::*;
28/// use maplit::hashmap;
29///
30/// #[function_component(App)]
31/// pub fn app() -> Html {
32/// let rows = vec![
33/// hashmap! { "name" => "Ferris".to_string(), "email" => "ferris@opensass.org".to_string() },
34/// hashmap! { "name" => "Crab".to_string(), "email" => "crab@opensass.org".to_string() },
35/// ];
36///
37/// let columns = vec![
38/// Column { id: "name", header: "Name", ..Default::default() },
39/// Column { id: "email", header: "Email", ..Default::default() },
40/// ];
41///
42/// let props = TableBodyProps {
43/// columns,
44/// rows,
45/// loading: false,
46/// classes: Default::default(),
47/// texts: Default::default(),
48/// };
49///
50/// html! {
51/// <TableBody ..props />
52/// }
53/// }
54/// ```
55///
56/// # See Also
57/// - [MDN tbody Element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/tbody)
58#[function_component(TableBody)]
59pub fn body(props: &TableBodyProps) -> Html {
60 let TableBodyProps {
61 columns,
62 rows,
63 loading,
64 classes,
65 texts,
66 } = props;
67
68 html! {
69 <tbody class={classes.tbody}>
70 { if *loading {
71 html! {
72 <tr class={classes.loading_row}><td colspan={columns.len().to_string()}>{ texts.loading }</td></tr>
73 }
74 } else if rows.is_empty() {
75 html! {
76 <tr class={classes.empty_row}><td colspan={columns.len().to_string()}>{ texts.empty }</td></tr>
77 }
78 } else {
79 html! {
80 for row in rows.iter() {
81 <tr class={classes.row} role="row">
82 for col in columns.iter() {
83 <td class={classes.body_cell} role="cell">{ row.get(col.id).unwrap_or(&"".to_string()) }</td>
84 }
85 </tr>
86 }
87 }
88 } }
89 </tbody>
90 }
91}