use sycamore::prelude::*; #[derive(Debug, Clone)] pub struct TableContent where G: GenericNode, { pub headers_view: Vec>, pub data_view: Vec>>, } #[derive(Prop)] pub struct TableContentRx<'a, G> where G: GenericNode, { pub headers_view: &'a Signal>>, pub data_view: &'a Signal>>>, pub table_class: &'a String, } #[derive(Debug, Clone)] struct PEqView(usize, T); impl PartialEq> for PEqView { fn eq(&self, other: &PEqView) -> bool { self.0 == other.0 } } impl Eq for PEqView {} #[component] pub fn BaseTable<'a, G>(cx: Scope<'a>, props: TableContentRx<'a, G>) -> View where G: Html, { let headers = create_memo(cx, || { (*props.headers_view.get()) .clone() .into_iter() .enumerate() .map(|(idx, v)| PEqView(idx, v)) .collect::>>>() }); let data = create_signal(cx, vec![]); create_effect(cx, move || { data.set(vec![]); let v_table = props.data_view.get(); for (idx, row) in v_table.iter().enumerate() { let views = PEqView(idx, View::new_fragment( row.iter().map(|cell| { view!{cx, th (class="m-2 p-2 border-slate-500 border-x border-dashed") { (cell) } } } ).collect() )); let mut d = (*data.get()).clone(); d.push(views); data.set(d.to_vec()); } }); view! { cx, table (class=format!("{} table-auto bg-slate-200 text-left dark:bg-slate-800 rounded-lg mx-auto my-2", props.table_class)) { thead { tr (class="border-b-2 border-slate-500 text-center") { Keyed( iterable=headers, view=|cx, v| { view! {cx, th (class="m-2 p-2") { (v.1) } } }, key=|v| v.0, ) } } tbody { Keyed( iterable=data, view=|cx, t| { view! {cx, tr (class="m-2 p-2 border-slate-500 border") { (t.1) } } }, key=|x| x.0, ) } } } }