dao_ui/components/table/
table.rs1use css_in_rust::Style;
2use yew::{
3 html, Component, ShouldRender, Html, ComponentLink, Properties, Classes, NodeRef,
4 html::{
5 ChildrenRenderer,
6 },
7 virtual_dom::{VComp, VChild},
8};
9use crate::theme::{Theme};
10use crate::components::table::table_body::table_body::{TableBody, Props as TableBodyProps};
11use crate::components::table::table_head::table_head::{TableHead, Props as TableHeadProps};
12
13#[derive(Clone, PartialEq)]
14pub enum Variants {
15 Head(<TableHead as Component>::Properties),
16 Body(<TableBody as Component>::Properties),
17}
18
19impl From<TableBodyProps> for Variants {
20 fn from(props: TableBodyProps) -> Self {
21 Variants::Body(props)
22 }
23}
24
25impl From<TableHeadProps> for Variants {
26 fn from(props: TableHeadProps) -> Self {
27 Variants::Head(props)
28 }
29}
30
31#[derive(PartialEq, Clone)]
32pub struct ChildVariant {
33 props: Variants,
34}
35
36#[derive(Clone, PartialEq, Debug)]
37#[allow(dead_code)]
38pub enum TableSize {
39 Small,
40 Medium,
41}
42
43pub struct Table {
44 style: Style,
45 props: Props,
46}
47
48#[derive(Properties, Clone, PartialEq, Debug)]
49pub struct Props {
50 #[prop_or_default]
51 pub class: String,
52 #[prop_or_default]
53 pub children: ChildrenRenderer<ChildVariant>,
54 #[prop_or(TableSize::Medium)]
55 pub size: TableSize,
56}
57
58impl<CHILD> From<VChild<CHILD>> for ChildVariant
59where
60 CHILD: Component,
61 CHILD::Properties: Into<Variants>,
62{
63 fn from(vchild: VChild<CHILD>) -> Self {
64 Self {
65 props: vchild.props.into(),
66 }
67 }
68}
69
70impl From<ChildVariant> for Html {
71 fn from(variant: ChildVariant) -> Html {
72 match variant.props {
73 Variants::Head(props) => VComp::new::<TableHead>(props, NodeRef::default(), None).into(),
74 Variants::Body(props) => VComp::new::<TableBody>(props, NodeRef::default(), None).into(),
75 }
76 }
77}
78
79impl Component for Table {
80 type Message = ();
81 type Properties = Props;
82
83 fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
84 let theme = Theme::default();
85 let style = Style::create(
86 String::from("table"),
87 include_str!("table.scss")
88 .replace("$font_family", &theme.typography.font_family),
89 )
90 .expect("An error occured while creating the style");
91
92 Self {
93 style,
94 props,
95 }
96 }
97
98 fn update(&mut self, _msg: Self::Message) -> ShouldRender {
99 false
100 }
101
102 fn change(&mut self, props: Self::Properties) -> ShouldRender {
103 if self.props != props {
104 self.props = props;
105
106 true
107 } else {
108 false
109 }
110 }
111
112 fn view(&self) -> Html {
113 html! {
114 <table
115 class=Classes::from(self.style.clone().to_string())
116 >
117 {
118 self.props.children.iter()
119 .filter(|c| matches!(c.props, Variants::Head(_)) || matches!(c.props, Variants::Body(_)))
120 .map(|mut c| {
121 if let Variants::Head(ref mut head_props) = c.props {
122 head_props.size = self.props.size.clone();
123 }
124 if let Variants::Body(ref mut body_props) = c.props {
125 body_props.size = self.props.size.clone();
126 }
127
128 c
129 })
130 .collect::<Html>()
131 }
132 </table>
133 }
134 }
135}