yew_bs/components/
table.rs1use yew::prelude::*;
2use crate::components::common::Variant;
3#[derive(Properties, PartialEq)]
4pub struct TableProps {
5 #[prop_or_default]
6 pub children: Children,
7 #[prop_or_default]
8 pub striped: bool,
9 #[prop_or_default]
10 pub bordered: bool,
11 #[prop_or_default]
12 pub borderless: bool,
13 #[prop_or_default]
14 pub hover: bool,
15 #[prop_or_default]
16 pub size: Option<TableSize>,
17 #[prop_or_default]
18 pub variant: Option<Variant>,
19 #[prop_or_default]
20 pub responsive: bool,
21 #[prop_or_default]
22 pub responsive_breakpoint: Option<ResponsiveBreakpoint>,
23 #[prop_or_default]
24 pub class: Option<AttrValue>,
25 #[prop_or_default]
26 pub node_ref: NodeRef,
27 #[prop_or_default]
28 pub caption: Option<AttrValue>,
29}
30#[derive(Clone, Copy, PartialEq, Debug)]
31pub enum TableSize {
32 Small,
33 Large,
34}
35#[derive(Clone, Copy, PartialEq, Debug)]
36pub enum ResponsiveBreakpoint {
37 Sm,
38 Md,
39 Lg,
40 Xl,
41 Xxl,
42}
43impl ResponsiveBreakpoint {
44 pub fn as_str(&self) -> &'static str {
45 match self {
46 ResponsiveBreakpoint::Sm => "sm",
47 ResponsiveBreakpoint::Md => "md",
48 ResponsiveBreakpoint::Lg => "lg",
49 ResponsiveBreakpoint::Xl => "xl",
50 ResponsiveBreakpoint::Xxl => "xxl",
51 }
52 }
53}
54#[function_component(Table)]
56pub fn table(props: &TableProps) -> Html {
57 let mut table_classes = Classes::new();
58 table_classes.push("table");
59 if props.striped {
60 table_classes.push("table-striped");
61 }
62 if props.bordered {
63 table_classes.push("table-bordered");
64 }
65 if props.borderless {
66 table_classes.push("table-borderless");
67 }
68 if props.hover {
69 table_classes.push("table-hover");
70 }
71 if let Some(size) = props.size {
72 match size {
73 TableSize::Small => table_classes.push("table-sm"),
74 TableSize::Large => table_classes.push("table-lg"),
75 }
76 }
77 if let Some(variant) = &props.variant {
78 table_classes.push(format!("table-{}", variant.as_str()));
79 }
80 if let Some(class) = &props.class {
81 table_classes.push(class.to_string());
82 }
83 let content = html! {
84 < table class = { table_classes } ref = { props.node_ref.clone() } > if let
85 Some(caption) = & props.caption { < caption > { caption } </ caption > } { for
86 props.children.iter() } </ table >
87 };
88 if props.responsive {
89 let mut wrapper_classes = Classes::new();
90 wrapper_classes.push("table-responsive");
91 if let Some(breakpoint) = props.responsive_breakpoint {
92 wrapper_classes.push(format!("table-responsive-{}", breakpoint.as_str()));
93 }
94 html! {
95 < div class = { wrapper_classes } > { content } </ div >
96 }
97 } else {
98 content
99 }
100}
101#[derive(Properties, PartialEq)]
103pub struct TableHeadProps {
104 #[prop_or_default]
106 pub children: Children,
107 #[prop_or_default]
109 pub dark: bool,
110 #[prop_or_default]
112 pub light: bool,
113 #[prop_or_default]
115 pub class: Option<AttrValue>,
116 #[prop_or_default]
118 pub node_ref: NodeRef,
119}
120#[function_component(TableHead)]
122pub fn table_head(props: &TableHeadProps) -> Html {
123 let mut classes = Classes::new();
124 if props.dark {
125 classes.push("table-dark");
126 }
127 if props.light {
128 classes.push("table-light");
129 }
130 if let Some(class) = &props.class {
131 classes.push(class.to_string());
132 }
133 html! {
134 < thead class = { classes } ref = { props.node_ref.clone() } > { for props
135 .children.iter() } </ thead >
136 }
137}
138#[derive(Properties, PartialEq)]
140pub struct TableBodyProps {
141 #[prop_or_default]
143 pub children: Children,
144 #[prop_or_default]
146 pub class: Option<AttrValue>,
147 #[prop_or_default]
149 pub node_ref: NodeRef,
150}
151#[function_component(TableBody)]
153pub fn table_body(props: &TableBodyProps) -> Html {
154 let mut classes = Classes::new();
155 if let Some(class) = &props.class {
156 classes.push(class.to_string());
157 }
158 html! {
159 < tbody class = { classes } ref = { props.node_ref.clone() } > { for props
160 .children.iter() } </ tbody >
161 }
162}
163#[derive(Properties, PartialEq)]
165pub struct TableRowProps {
166 #[prop_or_default]
168 pub children: Children,
169 #[prop_or_default]
171 pub active: bool,
172 #[prop_or_default]
174 pub variant: Option<Variant>,
175 #[prop_or_default]
177 pub class: Option<AttrValue>,
178 #[prop_or_default]
180 pub node_ref: NodeRef,
181}
182#[function_component(TableRow)]
184pub fn table_row(props: &TableRowProps) -> Html {
185 let mut classes = Classes::new();
186 if props.active {
187 classes.push("table-active");
188 }
189 if let Some(variant) = &props.variant {
190 classes.push(format!("table-{}", variant.as_str()));
191 }
192 if let Some(class) = &props.class {
193 classes.push(class.to_string());
194 }
195 html! {
196 < tr class = { classes } ref = { props.node_ref.clone() } > { for props.children
197 .iter() } </ tr >
198 }
199}
200#[derive(Properties, PartialEq)]
202pub struct TableCellProps {
203 #[prop_or_default]
205 pub children: Children,
206 #[prop_or_default]
208 pub header: bool,
209 #[prop_or_default]
211 pub active: bool,
212 #[prop_or_default]
214 pub variant: Option<Variant>,
215 #[prop_or_default]
217 pub colspan: Option<u8>,
218 #[prop_or_default]
220 pub rowspan: Option<u8>,
221 #[prop_or_default]
223 pub class: Option<AttrValue>,
224 #[prop_or_default]
226 pub node_ref: NodeRef,
227}
228#[function_component(TableCell)]
230pub fn table_cell(props: &TableCellProps) -> Html {
231 let mut classes = Classes::new();
232 if props.active {
233 classes.push("table-active");
234 }
235 if let Some(variant) = &props.variant {
236 classes.push(format!("table-{}", variant.as_str()));
237 }
238 if let Some(class) = &props.class {
239 classes.push(class.to_string());
240 }
241 let cell_type = if props.header { "th" } else { "td" };
242 html! {
243 <@ { cell_type } class = { classes } ref = { props.node_ref.clone() } colspan = {
244 props.colspan.map(| c | c.to_string()) } rowspan = { props.rowspan.map(| r | r
245 .to_string()) } > { for props.children.iter() } </@>
246 }
247}