use dioxus::prelude::*;
use freya_elements::elements as dioxus_elements;
use freya_elements::events::MouseEvent;
use freya_hooks::{use_get_theme, FontTheme, TableTheme};
#[allow(non_snake_case)]
#[component]
fn TableArrow(cx: Scope, order_direction: OrderDirection) -> Element {
let theme = use_get_theme(cx);
let TableTheme { arrow_fill, .. } = theme.table;
let rotate = match order_direction {
OrderDirection::Down => "0",
OrderDirection::Up => "180",
};
render!(svg {
height: "10",
width: "10",
rotate: "{rotate}deg",
svg_content: r#"
<svg viewBox="0 0 18 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.18177 9.58579L0 2.40401L1.81823 0.585785L9 7.76756L16.1818 0.585787L18 2.40402L10.8182 9.58579L10.8185 9.58601L9.00023 11.4042L9 11.404L8.99977 11.4042L7.18154 9.58602L7.18177 9.58579Z" fill="{arrow_fill}" stroke="{arrow_fill}" stroke-width="2"/>
</svg>
"#
})
}
#[derive(Props)]
pub struct TableHeadProps<'a> {
children: Element<'a>,
}
#[allow(non_snake_case)]
pub fn TableHead<'a>(cx: Scope<'a, TableHeadProps<'a>>) -> Element {
render!(
rect {
width: "100%",
&cx.props.children
}
)
}
#[derive(Props)]
pub struct TableBodyProps<'a> {
children: Element<'a>,
}
#[allow(non_snake_case)]
pub fn TableBody<'a>(cx: Scope<'a, TableBodyProps<'a>>) -> Element {
render!(
rect {
width: "100%",
&cx.props.children
}
)
}
#[derive(Props)]
pub struct TableRowProps<'a> {
children: Element<'a>,
#[props(default = false)]
alternate_colors: bool,
}
#[allow(non_snake_case)]
pub fn TableRow<'a>(cx: Scope<'a, TableRowProps<'a>>) -> Element {
let theme = use_get_theme(cx);
let TableTheme {
divider_fill,
alternate_row_background,
row_background,
..
} = theme.table;
let background = if cx.props.alternate_colors {
alternate_row_background
} else {
row_background
};
render!(
rect {
direction: "horizontal",
width: "100%",
background: "{background}",
&cx.props.children
}
rect {
height: "1",
width: "100%",
background: "{divider_fill}"
}
)
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum OrderDirection {
Up,
#[default]
Down,
}
#[derive(Props)]
pub struct TableCellProps<'a> {
children: Element<'a>,
onclick: Option<EventHandler<'a, MouseEvent>>,
#[props(into)]
order_direction: Option<Option<OrderDirection>>,
#[props(default = "5 25".to_string(), into)]
padding: String,
#[props(default = "35".to_string(), into)]
height: String,
}
#[allow(non_snake_case)]
pub fn TableCell<'a>(cx: Scope<'a, TableCellProps<'a>>) -> Element {
let config = cx.consume_context::<TableConfig>().unwrap();
let width = 100.0 / config.columns as f32;
let TableCellProps {
children,
order_direction,
padding,
height,
..
} = &cx.props;
render!(
rect {
overflow: "clip",
padding: "{padding}",
width: "{width}%",
main_align: "center",
cross_align: "center",
height: "{height}",
align: "right",
direction: "horizontal",
onclick: |e| {
if let Some(onclick) = &cx.props.onclick {
onclick.call(e);
}
},
if let Some(order_direction) = &order_direction {
rsx!(
rect {
margin: "10",
width: "10",
height: "10",
if let Some(order_direction) = &order_direction {
rsx!(
TableArrow {
order_direction: *order_direction
}
)
}
}
)
}
children
}
)
}
#[derive(Props)]
pub struct TableProps<'a> {
columns: usize,
children: Element<'a>,
#[props(default = "auto".to_string(), into)]
height: String,
#[props(default = "6".to_string(), into)]
corner_radius: String,
#[props(default = "0 2 15 5 rgb(35, 35, 35, 70)".to_string(), into)]
shadow: String,
}
#[allow(non_snake_case)]
pub fn Table<'a>(cx: Scope<'a, TableProps<'a>>) -> Element {
let theme = use_get_theme(cx);
let TableTheme {
background,
font_theme: FontTheme { color },
..
} = theme.table;
cx.provide_context(TableConfig {
columns: cx.props.columns,
});
let height = &cx.props.height;
let corner_radius = &cx.props.corner_radius;
let shadow = &cx.props.shadow;
render!(
rect {
overflow: "clip",
color: "{color}",
background: "{background}",
corner_radius: "{corner_radius}",
shadow: "{shadow}",
height: "{height}",
&cx.props.children
}
)
}
#[derive(Clone)]
pub struct TableConfig {
columns: usize,
}