Skip to main content

dao_ui/components/table/
table.rs

1use 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}