use super::*;
#[component]
pub fn euv_table(node: VirtualNode<EuvTableProps>) -> VirtualNode {
let EuvTableProps {
columns,
rows,
caption,
zebra,
}: EuvTableProps = node.try_get_props().unwrap_or_default();
let head: VirtualNode = table_head(columns.as_slice());
let body: VirtualNode = table_body(columns.as_slice(), rows, zebra);
html! {
table {
class: c_euv_table()
if !caption.is_empty() {
caption {
class: c_euv_table_caption()
{
caption
}
}
}
head
body
}
}
}
fn table_head(columns: &[EuvTableColumn]) -> VirtualNode {
let header_cells: Vec<VirtualNode> = columns
.iter()
.map(|column: &EuvTableColumn| {
let align_class: &'static str = table_cell_align_class(column.align);
html! {
th {
key: column.key
class: c_euv_table_header_cell()
class: align_class
column.label
}
}
})
.collect();
html! {
thead {
class: c_euv_table_head()
tr {
header_cells
}
}
}
}
fn table_body(columns: &[EuvTableColumn], rows: Vec<EuvTableRow>, zebra: bool) -> VirtualNode {
let row_nodes: Vec<VirtualNode> = rows
.into_iter()
.enumerate()
.map(|(index, row): (usize, EuvTableRow)| table_row(columns, row, zebra && index % 2 == 0))
.collect();
html! {
tbody {
class: c_euv_table_body()
row_nodes
}
}
}
fn table_row(columns: &[EuvTableColumn], row: EuvTableRow, zebra: bool) -> VirtualNode {
let row_class: fn() -> &'static Css = if zebra {
c_euv_table_row_zebra
} else {
c_euv_table_row
};
let cells: Vec<VirtualNode> = columns
.iter()
.enumerate()
.map(|(index, column): (usize, &EuvTableColumn)| {
let align_class: &'static str = table_cell_align_class(column.align);
let text: &'static str = row.cells.get(index).copied().unwrap_or_default();
html! {
td {
class: c_euv_table_cell()
class: align_class
text
}
}
})
.collect();
html! {
tr {
key: row.key
class: row_class()
cells
}
}
}
fn table_cell_align_class(align: EuvTableAlign) -> &'static str {
match align {
EuvTableAlign::Left => "",
EuvTableAlign::Center => c_euv_table_cell_center().get_name(),
EuvTableAlign::Right => c_euv_table_cell_right().get_name(),
}
}