yew_datatable/components/
table_body.rs1use crate::hooks::use_table::UseTableHandle;
4use yew::prelude::*;
5use yew_datatable_core::prelude::DataTableRowId;
6
7#[derive(Properties, Clone)]
9pub struct TableBodyProps<T: Clone + PartialEq + 'static> {
10 pub table: UseTableHandle<T>,
12
13 #[prop_or_default]
15 pub class: Classes,
16
17 #[prop_or_default]
19 pub tr_class: Classes,
20
21 #[prop_or_default]
23 pub td_class: Classes,
24
25 #[prop_or_default]
27 pub selected_class: Classes,
28
29 #[prop_or(true)]
31 pub selectable: bool,
32
33 #[prop_or_default]
35 pub render_cell: Option<Callback<CellRenderContext<T>, Html>>,
36}
37
38impl<T: Clone + PartialEq + 'static> PartialEq for TableBodyProps<T> {
40 fn eq(&self, other: &Self) -> bool {
41 self.class == other.class
43 && self.tr_class == other.tr_class
44 && self.td_class == other.td_class
45 && self.selected_class == other.selected_class
46 && self.selectable == other.selectable
47 }
48}
49
50#[derive(Clone)]
52pub struct CellRenderContext<T> {
53 pub row: T,
55
56 pub row_id: DataTableRowId,
58
59 pub row_index: usize,
61
62 pub column_id: String,
64
65 pub column_index: usize,
67
68 pub value: String,
70}
71
72#[function_component(TableBody)]
74pub fn table_body<T: Clone + PartialEq + 'static>(props: &TableBodyProps<T>) -> Html {
75 let column_ids = props.table.visible_column_ids();
77
78 let rows = props.table.visible_rows();
80
81 html! {
82 <tbody class={props.class.clone()}>
83 {rows.into_iter().enumerate().map(|(row_idx, row)| {
84 let row_id = row.id.clone();
86 let is_selected = props.table.is_row_selected(&row_id);
87
88 let row_class = if is_selected {
90 classes!(props.tr_class.clone(), props.selected_class.clone())
91 } else {
92 props.tr_class.clone()
93 };
94
95 let onclick = if props.selectable {
97 let table = props.table.clone();
98 let row_id = row_id.clone();
99 Some(Callback::from(move |_: MouseEvent| {
100 table.toggle_row_selection(row_id.clone());
101 }))
102 } else {
103 None
104 };
105
106 html! {
107 <tr
108 key={row_id.as_str().to_string()}
109 class={row_class}
110 onclick={onclick}
111 >
112 {column_ids.iter().enumerate().map(|(col_idx, column_id)| {
113 let value = props.table.get_cell_value(&row.original, column_id)
115 .unwrap_or_default();
116
117 let cell_html = if let Some(render_cell) = &props.render_cell {
119 let ctx = CellRenderContext {
120 row: row.original.clone(),
121 row_id: row_id.clone(),
122 row_index: row_idx,
123 column_id: column_id.as_str().to_string(),
124 column_index: col_idx,
125 value: value.clone(),
126 };
127 render_cell.emit(ctx)
128 } else {
129 html! { {value} }
130 };
131
132 html! {
133 <td
134 key={column_id.as_str().to_string()}
135 class={props.td_class.clone()}
136 >
137 {cell_html}
138 </td>
139 }
140 }).collect::<Html>()}
141 </tr>
142 }
143 }).collect::<Html>()}
144 </tbody>
145 }
146}