use dioxus::prelude::*;
use freya_elements::{
self as dioxus_elements,
events::MouseEvent,
};
use freya_hooks::{
use_applied_theme,
use_get_theme,
FontTheme,
TableTheme,
TableThemeWith,
};
use crate::icons::ArrowIcon;
#[allow(non_snake_case)]
#[component]
fn TableArrow(order_direction: OrderDirection) -> Element {
let theme = use_get_theme();
let TableTheme { arrow_fill, .. } = theme.table;
let rotate = match order_direction {
OrderDirection::Down => "0",
OrderDirection::Up => "180",
};
rsx!(ArrowIcon {
rotate: "{rotate}",
fill: "{arrow_fill}"
})
}
#[derive(Props, Clone, PartialEq)]
pub struct TableHeadProps {
pub children: Element,
}
#[allow(non_snake_case)]
pub fn TableHead(TableHeadProps { children }: TableHeadProps) -> Element {
rsx!(
rect { width: "100%", {children} }
)
}
#[derive(Props, Clone, PartialEq)]
pub struct TableBodyProps {
pub children: Element,
}
#[allow(non_snake_case)]
pub fn TableBody(TableBodyProps { children }: TableBodyProps) -> Element {
rsx!(
rect { width: "100%", {children} }
)
}
#[derive(Props, Clone, PartialEq)]
pub struct TableRowProps {
pub theme: Option<TableThemeWith>,
children: Element,
#[props(default = false)]
alternate_colors: bool,
}
#[allow(non_snake_case)]
pub fn TableRow(
TableRowProps {
theme,
children,
alternate_colors,
}: TableRowProps,
) -> Element {
let theme = use_applied_theme!(&theme, table);
let TableTheme {
divider_fill,
alternate_row_background,
row_background,
..
} = theme;
let background = if alternate_colors {
alternate_row_background
} else {
row_background
};
rsx!(
rect {
direction: "horizontal",
width: "100%",
background: "{background}",
{children}
}
rect {
height: "1",
width: "100%",
background: "{divider_fill}"
}
)
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum OrderDirection {
Up,
#[default]
Down,
}
#[derive(Props, Clone, PartialEq)]
pub struct TableCellProps {
pub children: Element,
pub onclick: Option<EventHandler<MouseEvent>>,
#[props(into)]
pub order_direction: Option<Option<OrderDirection>>,
#[props(default = "5 25".to_string(), into)]
pub padding: String,
#[props(default = "35".to_string(), into)]
pub height: String,
}
#[allow(non_snake_case)]
pub fn TableCell(props: TableCellProps) -> Element {
let config = consume_context::<TableConfig>();
let width = 100.0 / config.columns as f32;
let TableCellProps {
children,
order_direction,
padding,
height,
..
} = &props;
rsx!(
rect {
overflow: "clip",
padding: "{padding}",
width: "{width}%",
main_align: "end",
cross_align: "center",
height: "{height}",
direction: "horizontal",
onclick: move |e| {
if let Some(onclick) = &props.onclick {
onclick.call(e);
}
},
if let Some(order_direction) = &order_direction {
rect {
margin: "10",
width: "10",
height: "10",
if let Some(order_direction) = &order_direction {
TableArrow {
order_direction: *order_direction
}
}
}
}
{children}
}
)
}
#[derive(Props, Clone, PartialEq)]
pub struct TableProps {
pub theme: Option<TableThemeWith>,
pub columns: usize,
pub children: Element,
}
#[allow(non_snake_case)]
pub fn Table(
TableProps {
theme,
columns,
children,
}: TableProps,
) -> Element {
let TableTheme {
background,
height,
corner_radius,
shadow,
font_theme: FontTheme { color },
..
} = use_applied_theme!(&theme, table);
provide_context(TableConfig { columns });
rsx!(rect {
overflow: "clip",
color: "{color}",
background: "{background}",
corner_radius: "{corner_radius}",
shadow: "{shadow}",
height: "{height}",
{children}
})
}
#[doc(hidden)]
#[derive(Clone)]
pub struct TableConfig {
columns: usize,
}