yew_and_bulma/elements/table.rs
1use yew::{function_component, html};
2use yew::{html::ChildrenRenderer, virtual_dom::VChild, AttrValue, Children, Html, Properties};
3use yew_and_bulma_macros::base_component_properties;
4
5use crate::utils::class::ClassBuilder;
6use crate::utils::constants::IS_NARROW;
7
8/// Defines the properties of the [Bulma table element][bd].
9///
10/// Defines the properties of the table element, based on the specification
11/// found in the [Bulma table element documentation][bd].
12///
13/// # Examples
14///
15/// ```rust
16/// use yew::prelude::*;
17/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
18///
19/// #[function_component(App)]
20/// fn app() -> Html {
21/// html! {
22/// <Table>
23/// <TableHeader>{"One"}</TableHeader>
24/// <TableHeader>{"Two"}</TableHeader>
25///
26/// <TableRow>
27/// <TableData>{ "Three" }</TableData>
28/// <TableData>{ "Four" }</TableData>
29/// </TableRow>
30/// <TableRow>
31/// <TableData>{ "Five" }</TableData>
32/// <TableData>{ "Six" }</TableData>
33/// </TableRow>
34/// <TableRow>
35/// <TableData>{ "Seven" }</TableData>
36/// <TableData>{ "Eight" }</TableData>
37/// </TableRow>
38/// </Table>
39/// }
40/// }
41/// ```
42///
43/// [bd]: https://bulma.io/documentation/elements/table/
44#[base_component_properties]
45#[derive(Properties, PartialEq)]
46pub struct TableProperties {
47 /// Whether or not the [Bulma table element][bd] should be scrollable.
48 ///
49 /// Whether or not the [Bulma table element][bd], which will receive these
50 /// properties, will be scrollable.
51 ///
52 /// # Examples
53 ///
54 /// ```rust
55 /// use yew::prelude::*;
56 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
57 ///
58 /// #[function_component(App)]
59 /// fn app() -> Html {
60 /// html! {
61 /// <Table scrollable=true>
62 /// <TableHeader>{"One"}</TableHeader>
63 /// <TableHeader>{"Two"}</TableHeader>
64 ///
65 /// <TableRow>
66 /// <TableData>{ "Three" }</TableData>
67 /// <TableData>{ "Four" }</TableData>
68 /// </TableRow>
69 /// <TableRow>
70 /// <TableData>{ "Five" }</TableData>
71 /// <TableData>{ "Six" }</TableData>
72 /// </TableRow>
73 /// <TableRow>
74 /// <TableData>{ "Seven" }</TableData>
75 /// <TableData>{ "Eight" }</TableData>
76 /// </TableRow>
77 /// </Table>
78 /// }
79 /// }
80 /// ```
81 ///
82 /// [bd]: https://bulma.io/documentation/elements/table/#table-container
83 #[prop_or_default]
84 pub scrollable: bool,
85 /// Whether or not the [Bulma table element][bd] should be bordered.
86 ///
87 /// Whether or not the [Bulma table element][bd], which will receive these
88 /// properties, will be bordered.
89 ///
90 /// # Examples
91 ///
92 /// ```rust
93 /// use yew::prelude::*;
94 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
95 ///
96 /// #[function_component(App)]
97 /// fn app() -> Html {
98 /// html! {
99 /// <Table bordered=true>
100 /// <TableHeader>{"One"}</TableHeader>
101 /// <TableHeader>{"Two"}</TableHeader>
102 ///
103 /// <TableRow>
104 /// <TableData>{ "Three" }</TableData>
105 /// <TableData>{ "Four" }</TableData>
106 /// </TableRow>
107 /// <TableRow>
108 /// <TableData>{ "Five" }</TableData>
109 /// <TableData>{ "Six" }</TableData>
110 /// </TableRow>
111 /// <TableRow>
112 /// <TableData>{ "Seven" }</TableData>
113 /// <TableData>{ "Eight" }</TableData>
114 /// </TableRow>
115 /// </Table>
116 /// }
117 /// }
118 /// ```
119 ///
120 /// [bd]: https://bulma.io/documentation/elements/table/#modifiers
121 #[prop_or_default]
122 pub bordered: bool,
123 /// Whether or not the [Bulma table element][bd] should be striped.
124 ///
125 /// Whether or not the [Bulma table element][bd], which will receive these
126 /// properties, will be striped.
127 ///
128 /// # Examples
129 ///
130 /// ```rust
131 /// use yew::prelude::*;
132 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
133 ///
134 /// #[function_component(App)]
135 /// fn app() -> Html {
136 /// html! {
137 /// <Table striped=true>
138 /// <TableHeader>{"One"}</TableHeader>
139 /// <TableHeader>{"Two"}</TableHeader>
140 ///
141 /// <TableRow>
142 /// <TableData>{ "Three" }</TableData>
143 /// <TableData>{ "Four" }</TableData>
144 /// </TableRow>
145 /// <TableRow>
146 /// <TableData>{ "Five" }</TableData>
147 /// <TableData>{ "Six" }</TableData>
148 /// </TableRow>
149 /// <TableRow>
150 /// <TableData>{ "Seven" }</TableData>
151 /// <TableData>{ "Eight" }</TableData>
152 /// </TableRow>
153 /// </Table>
154 /// }
155 /// }
156 /// ```
157 ///
158 /// [bd]: https://bulma.io/documentation/elements/table/#modifiers
159 #[prop_or_default]
160 pub striped: bool,
161 /// Whether or not the [Bulma table element][bd] should be narrow.
162 ///
163 /// Whether or not the [Bulma table element][bd], which will receive these
164 /// properties, will be narrow.
165 ///
166 /// # Examples
167 ///
168 /// ```rust
169 /// use yew::prelude::*;
170 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
171 ///
172 /// #[function_component(App)]
173 /// fn app() -> Html {
174 /// html! {
175 /// <Table narrow=true>
176 /// <TableHeader>{"One"}</TableHeader>
177 /// <TableHeader>{"Two"}</TableHeader>
178 ///
179 /// <TableRow>
180 /// <TableData>{ "Three" }</TableData>
181 /// <TableData>{ "Four" }</TableData>
182 /// </TableRow>
183 /// <TableRow>
184 /// <TableData>{ "Five" }</TableData>
185 /// <TableData>{ "Six" }</TableData>
186 /// </TableRow>
187 /// <TableRow>
188 /// <TableData>{ "Seven" }</TableData>
189 /// <TableData>{ "Eight" }</TableData>
190 /// </TableRow>
191 /// </Table>
192 /// }
193 /// }
194 /// ```
195 ///
196 /// [bd]: https://bulma.io/documentation/elements/table/#modifiers
197 #[prop_or_default]
198 pub narrow: bool,
199 /// Whether or not the [Bulma table element][bd] should be hoverable.
200 ///
201 /// Whether or not the [Bulma table element][bd], which will receive these
202 /// properties, will be hoverable.
203 ///
204 /// # Examples
205 ///
206 /// ```rust
207 /// use yew::prelude::*;
208 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
209 ///
210 /// #[function_component(App)]
211 /// fn app() -> Html {
212 /// html! {
213 /// <Table hoverable=true>
214 /// <TableHeader>{"One"}</TableHeader>
215 /// <TableHeader>{"Two"}</TableHeader>
216 ///
217 /// <TableRow>
218 /// <TableData>{ "Three" }</TableData>
219 /// <TableData>{ "Four" }</TableData>
220 /// </TableRow>
221 /// <TableRow>
222 /// <TableData>{ "Five" }</TableData>
223 /// <TableData>{ "Six" }</TableData>
224 /// </TableRow>
225 /// <TableRow>
226 /// <TableData>{ "Seven" }</TableData>
227 /// <TableData>{ "Eight" }</TableData>
228 /// </TableRow>
229 /// </Table>
230 /// }
231 /// }
232 /// ```
233 ///
234 /// [bd]: https://bulma.io/documentation/elements/table/#modifiers
235 #[prop_or_default]
236 pub hoverable: bool,
237 /// Whether or not the [Bulma table element][bd] should be full width.
238 ///
239 /// Whether or not the [Bulma table element][bd], which will receive these
240 /// properties, will be full width.
241 ///
242 /// # Examples
243 ///
244 /// ```rust
245 /// use yew::prelude::*;
246 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
247 ///
248 /// #[function_component(App)]
249 /// fn app() -> Html {
250 /// html! {
251 /// <Table full_width=true>
252 /// <TableHeader>{"One"}</TableHeader>
253 /// <TableHeader>{"Two"}</TableHeader>
254 ///
255 /// <TableRow>
256 /// <TableData>{ "Three" }</TableData>
257 /// <TableData>{ "Four" }</TableData>
258 /// </TableRow>
259 /// <TableRow>
260 /// <TableData>{ "Five" }</TableData>
261 /// <TableData>{ "Six" }</TableData>
262 /// </TableRow>
263 /// <TableRow>
264 /// <TableData>{ "Seven" }</TableData>
265 /// <TableData>{ "Eight" }</TableData>
266 /// </TableRow>
267 /// </Table>
268 /// }
269 /// }
270 /// ```
271 ///
272 /// [bd]: https://bulma.io/documentation/elements/table/#modifiers
273 #[prop_or_default]
274 pub full_width: bool,
275 /// The list of elements found inside the [table element][bd].
276 ///
277 /// Defines the elements that will be found inside the
278 /// [Bulma table element][bd] which will receive these properties.
279 ///
280 /// [bd]: https://bulma.io/documentation/elements/table/
281 pub children: ChildrenRenderer<TableItem>,
282}
283
284impl From<&TableProperties> for String {
285 fn from(value: &TableProperties) -> Self {
286 let mut modifier_classes = String::with_capacity(80);
287
288 modifier_classes.push_str("table");
289 if value.bordered {
290 modifier_classes.push_str(" is-bordered");
291 }
292 if value.striped {
293 modifier_classes.push_str(" is-striped");
294 }
295 if value.narrow {
296 modifier_classes.push_str(IS_NARROW);
297 }
298 if value.hoverable {
299 modifier_classes.push_str(" is-hoverable");
300 }
301 if value.full_width {
302 modifier_classes.push_str(" is-fullwidth");
303 }
304
305 modifier_classes
306 }
307}
308
309/// Defines the possible types of children from a [Bulma table element][bd].
310///
311/// Defines the possible types of children found inside a
312/// [Bulma table element][bd].
313///
314/// # Examples
315///
316/// ```rust
317/// use yew::prelude::*;
318/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
319///
320/// #[function_component(App)]
321/// fn app() -> Html {
322/// html! {
323/// <Table>
324/// <TableHeader>{"One"}</TableHeader>
325/// <TableHeader>{"Two"}</TableHeader>
326///
327/// <TableRow>
328/// <TableData>{ "Three" }</TableData>
329/// <TableData>{ "Four" }</TableData>
330/// </TableRow>
331/// <TableRow>
332/// <TableData>{ "Five" }</TableData>
333/// <TableData>{ "Six" }</TableData>
334/// </TableRow>
335/// <TableRow>
336/// <TableData>{ "Seven" }</TableData>
337/// <TableData>{ "Eight" }</TableData>
338/// </TableRow>
339/// </Table>
340/// }
341/// }
342/// ```
343///
344/// [bd]: https://bulma.io/documentation/elements/table/
345#[derive(Clone, PartialEq)]
346pub enum TableItem {
347 TableHeader(VChild<TableHeader>),
348 TableFooter(VChild<TableFooter>),
349 TableRow(VChild<TableRow>),
350 TableData(VChild<TableData>),
351}
352
353impl TableItem {
354 /// Determines if the table item is a [`crate::elements::table::TableHeader`].
355 pub fn is_header(&self) -> bool {
356 matches!(self, TableItem::TableHeader(_))
357 }
358
359 /// Determines if the table item is a [`crate::elements::table::TableFooter`].
360 pub fn is_footer(&self) -> bool {
361 matches!(self, TableItem::TableFooter(_))
362 }
363
364 /// Determines if the table item is a [`crate::elements::table::TableRow`].
365 pub fn is_row(&self) -> bool {
366 matches!(self, TableItem::TableRow(_))
367 }
368
369 /// Determines if the table item is a [`crate::elements::table::TableData`].
370 pub fn is_data(&self) -> bool {
371 matches!(self, TableItem::TableData(_))
372 }
373}
374
375impl From<VChild<TableHeader>> for TableItem {
376 fn from(value: VChild<TableHeader>) -> Self {
377 TableItem::TableHeader(value)
378 }
379}
380
381impl From<VChild<TableFooter>> for TableItem {
382 fn from(value: VChild<TableFooter>) -> Self {
383 TableItem::TableFooter(value)
384 }
385}
386
387impl From<VChild<TableRow>> for TableItem {
388 fn from(value: VChild<TableRow>) -> Self {
389 TableItem::TableRow(value)
390 }
391}
392
393impl From<VChild<TableData>> for TableItem {
394 fn from(value: VChild<TableData>) -> Self {
395 TableItem::TableData(value)
396 }
397}
398
399#[allow(clippy::from_over_into)]
400impl Into<Html> for TableItem {
401 fn into(self) -> Html {
402 match self {
403 TableItem::TableHeader(th) => th.into(),
404 TableItem::TableFooter(tf) => tf.into(),
405 TableItem::TableRow(tr) => tr.into(),
406 TableItem::TableData(td) => td.into(),
407 }
408 }
409}
410
411/// Yew implementation of the [Bulma table element][bd].
412///
413/// Yew implementation of the table element, based on the specification found
414/// in the [Bulma table element documentation][bd].
415///
416/// # Examples
417///
418/// ```rust
419/// use yew::prelude::*;
420/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
421///
422/// #[function_component(App)]
423/// fn app() -> Html {
424/// html! {
425/// <Table>
426/// <TableHeader>{"One"}</TableHeader>
427/// <TableHeader>{"Two"}</TableHeader>
428///
429/// <TableRow>
430/// <TableData>{ "Three" }</TableData>
431/// <TableData>{ "Four" }</TableData>
432/// </TableRow>
433/// <TableRow>
434/// <TableData>{ "Five" }</TableData>
435/// <TableData>{ "Six" }</TableData>
436/// </TableRow>
437/// <TableRow>
438/// <TableData>{ "Seven" }</TableData>
439/// <TableData>{ "Eight" }</TableData>
440/// </TableRow>
441/// </Table>
442/// }
443/// }
444/// ```
445///
446/// [bd]: https://bulma.io/documentation/elements/table/
447#[function_component(Table)]
448pub fn table(props: &TableProperties) -> Html {
449 let class = ClassBuilder::default()
450 .with_custom_class(&String::from(props))
451 .with_custom_class(
452 &props
453 .class
454 .as_ref()
455 .map(|c| c.to_string())
456 .unwrap_or("".to_owned()),
457 )
458 .build();
459 let headers: Vec<_> = props.children.iter().filter(|ti| ti.is_header()).collect();
460 let footers: Vec<_> = props.children.iter().filter(|ti| ti.is_footer()).collect();
461 let data: Vec<_> = props
462 .children
463 .iter()
464 .filter(|ti| ti.is_row() || ti.is_data())
465 .collect();
466
467 let table_html = html! {
468 <table id={props.id.clone()} {class}
469 onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
470 onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
471 ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
472 oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
473 onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
474 onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
475 onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
476 ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
477 onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
478 onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
479 onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
480 ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
481 if !headers.is_empty() {
482 <thead>
483 { for headers }
484 </thead>
485 }
486
487 if !footers.is_empty() {
488 <tfoot>
489 { for footers }
490 </tfoot>
491 }
492
493 <tbody>
494 { for data }
495 </tbody>
496 </table>
497 };
498
499 if props.scrollable {
500 html! {
501 <div class="table-container">
502 {table_html}
503 </div>
504 }
505 } else {
506 table_html
507 }
508}
509
510/// Defines the properties of the [Bulma table header element][bd].
511///
512/// Defines the properties of the table header element, based on the
513/// specification found in the [Bulma table element documentation][bd].
514///
515/// # Examples
516///
517/// ```rust
518/// use yew::prelude::*;
519/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
520///
521/// #[function_component(App)]
522/// fn app() -> Html {
523/// html! {
524/// <Table>
525/// <TableHeader>{"One"}</TableHeader>
526/// <TableHeader>{"Two"}</TableHeader>
527///
528/// <TableRow>
529/// <TableData>{ "Three" }</TableData>
530/// <TableData>{ "Four" }</TableData>
531/// </TableRow>
532/// <TableRow>
533/// <TableData>{ "Five" }</TableData>
534/// <TableData>{ "Six" }</TableData>
535/// </TableRow>
536/// <TableRow>
537/// <TableData>{ "Seven" }</TableData>
538/// <TableData>{ "Eight" }</TableData>
539/// </TableRow>
540/// </Table>
541/// }
542/// }
543/// ```
544///
545/// [bd]: https://bulma.io/documentation/elements/table/
546#[base_component_properties]
547#[derive(Properties, PartialEq)]
548pub struct TableHeaderProperties {
549 /// Sets the abbreviation of [Bulma table header element][bd].
550 ///
551 /// Sets the abbreviation of the [Bulma table header element][bd] which will
552 /// receive these properties.
553 ///
554 /// # Examples
555 ///
556 /// ```rust
557 /// use yew::prelude::*;
558 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
559 ///
560 /// #[function_component(App)]
561 /// fn app() -> Html {
562 /// html! {
563 /// <Table>
564 /// <TableHeader abbreviation={"1"}>{"One"}</TableHeader>
565 /// <TableHeader abbreviation={"1"}>{"Two"}</TableHeader>
566 ///
567 /// <TableRow>
568 /// <TableData>{ "Three" }</TableData>
569 /// <TableData>{ "Four" }</TableData>
570 /// </TableRow>
571 /// <TableRow>
572 /// <TableData>{ "Five" }</TableData>
573 /// <TableData>{ "Six" }</TableData>
574 /// </TableRow>
575 /// <TableRow>
576 /// <TableData>{ "Seven" }</TableData>
577 /// <TableData>{ "Eight" }</TableData>
578 /// </TableRow>
579 /// </Table>
580 /// }
581 /// }
582 /// ```
583 ///
584 /// [bd]: https://bulma.io/documentation/elements/table/
585 #[prop_or_default]
586 pub abbreviation: Option<AttrValue>,
587 /// The list of elements found inside the [table header element][bd].
588 ///
589 /// Defines the elements that will be found inside the
590 /// [Bulma table header element][bd] which will receive these properties.
591 ///
592 /// [bd]: https://bulma.io/documentation/elements/table/
593 pub children: Children,
594}
595
596/// Yew implementation of the [Bulma table header element][bd].
597///
598/// Yew implementation of the table header element, based on the specification
599/// found in the [Bulma table element documentation][bd].
600///
601/// # Examples
602///
603/// ```rust
604/// use yew::prelude::*;
605/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
606///
607/// #[function_component(App)]
608/// fn app() -> Html {
609/// html! {
610/// <Table>
611/// <TableHeader>{"One"}</TableHeader>
612/// <TableHeader>{"Two"}</TableHeader>
613///
614/// <TableRow>
615/// <TableData>{ "Three" }</TableData>
616/// <TableData>{ "Four" }</TableData>
617/// </TableRow>
618/// <TableRow>
619/// <TableData>{ "Five" }</TableData>
620/// <TableData>{ "Six" }</TableData>
621/// </TableRow>
622/// <TableRow>
623/// <TableData>{ "Seven" }</TableData>
624/// <TableData>{ "Eight" }</TableData>
625/// </TableRow>
626/// </Table>
627/// }
628/// }
629/// ```
630///
631/// [bd]: https://bulma.io/documentation/elements/table/
632#[function_component(TableHeader)]
633pub fn table_header(props: &TableHeaderProperties) -> Html {
634 let class = ClassBuilder::default()
635 .with_custom_class(
636 &props
637 .class
638 .as_ref()
639 .map(|c| c.to_string())
640 .unwrap_or("".to_owned()),
641 )
642 .build();
643 let abbr = &props.abbreviation;
644
645 html! {
646 <th id={props.id.clone()} {class}
647 onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
648 onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
649 ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
650 oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
651 onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
652 onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
653 onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
654 ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
655 onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
656 onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
657 onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
658 ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
659 if let Some(abbr) = &abbr {
660 <abbr {abbr}>{ for props.children.iter() }</abbr>
661 } else {
662 { for props.children.iter() }
663 }
664 </th>
665 }
666}
667
668/// Yew implementation of the [Bulma table footer element][bd].
669///
670/// Yew implementation of the table footer element, based on the specification
671/// found in the [Bulma table element documentation][bd]. Has the same
672/// properties as [`crate::elements::table::TableHeader`].
673///
674/// # Examples
675///
676/// ```rust
677/// use yew::prelude::*;
678/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
679///
680/// #[function_component(App)]
681/// fn app() -> Html {
682/// html! {
683/// <Table>
684/// <TableHeader>{"One"}</TableHeader>
685/// <TableHeader>{"Two"}</TableHeader>
686///
687/// <TableRow>
688/// <TableData>{ "Three" }</TableData>
689/// <TableData>{ "Four" }</TableData>
690/// </TableRow>
691/// <TableRow>
692/// <TableData>{ "Five" }</TableData>
693/// <TableData>{ "Six" }</TableData>
694/// </TableRow>
695/// <TableRow>
696/// <TableData>{ "Seven" }</TableData>
697/// <TableData>{ "Eight" }</TableData>
698/// </TableRow>
699/// </Table>
700/// }
701/// }
702/// ```
703///
704/// [bd]: https://bulma.io/documentation/elements/table/
705#[function_component(TableFooter)]
706pub fn table_footer(props: &TableHeaderProperties) -> Html {
707 let class = ClassBuilder::default()
708 .with_custom_class(
709 &props
710 .class
711 .as_ref()
712 .map(|c| c.to_string())
713 .unwrap_or("".to_owned()),
714 )
715 .build();
716 let abbr = &props.abbreviation;
717
718 html! {
719 <th id={props.id.clone()} {class}
720 onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
721 onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
722 ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
723 oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
724 onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
725 onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
726 onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
727 ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
728 onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
729 onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
730 onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
731 ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
732 if let Some(abbr) = &abbr {
733 <abbr {abbr}>{ for props.children.iter() }</abbr>
734 } else {
735 { for props.children.iter() }
736 }
737 </th>
738 }
739}
740
741/// Defines the properties of the [Bulma table row element][bd].
742///
743/// Defines the properties of the table row element, based on the
744/// specification found in the [Bulma table element documentation][bd].
745///
746/// # Examples
747///
748/// ```rust
749/// use yew::prelude::*;
750/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
751///
752/// #[function_component(App)]
753/// fn app() -> Html {
754/// html! {
755/// <Table>
756/// <TableHeader>{"One"}</TableHeader>
757/// <TableHeader>{"Two"}</TableHeader>
758///
759/// <TableRow>
760/// <TableData>{ "Three" }</TableData>
761/// <TableData>{ "Four" }</TableData>
762/// </TableRow>
763/// <TableRow>
764/// <TableData>{ "Five" }</TableData>
765/// <TableData>{ "Six" }</TableData>
766/// </TableRow>
767/// <TableRow>
768/// <TableData>{ "Seven" }</TableData>
769/// <TableData>{ "Eight" }</TableData>
770/// </TableRow>
771/// </Table>
772/// }
773/// }
774/// ```
775///
776/// [bd]: https://bulma.io/documentation/elements/table/
777#[base_component_properties]
778#[derive(Properties, PartialEq)]
779pub struct TableRowProperties {
780 /// Whether or not the [Bulma table row element][bd] should be selected.
781 ///
782 /// Whether or not the [Bulma table row element][bd], which will receive these
783 /// properties, will be selected.
784 ///
785 /// # Examples
786 ///
787 /// ```rust
788 /// use yew::prelude::*;
789 /// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
790 ///
791 /// #[function_component(App)]
792 /// fn app() -> Html {
793 /// html! {
794 /// <Table>
795 /// <TableHeader>{"One"}</TableHeader>
796 /// <TableHeader>{"Two"}</TableHeader>
797 ///
798 /// <TableRow>
799 /// <TableData>{ "Three" }</TableData>
800 /// <TableData>{ "Four" }</TableData>
801 /// </TableRow>
802 /// <TableRow selected=true>
803 /// <TableData>{ "Five" }</TableData>
804 /// <TableData>{ "Six" }</TableData>
805 /// </TableRow>
806 /// <TableRow>
807 /// <TableData>{ "Seven" }</TableData>
808 /// <TableData>{ "Eight" }</TableData>
809 /// </TableRow>
810 /// </Table>
811 /// }
812 /// }
813 /// ```
814 ///
815 /// [bd]: https://bulma.io/documentation/elements/table/
816 #[prop_or_default]
817 pub selected: bool,
818 /// The list of elements found inside the [table row element][bd].
819 ///
820 /// Defines the elements that will be found inside the
821 /// [Bulma table row element][bd] which will receive these properties.
822 ///
823 /// [bd]: https://bulma.io/documentation/elements/table/
824 pub children: Children,
825}
826
827impl From<&TableRowProperties> for String {
828 fn from(value: &TableRowProperties) -> Self {
829 if value.selected {
830 "is-selected".to_owned()
831 } else {
832 String::new()
833 }
834 }
835}
836
837/// Yew implementation of the [Bulma table row element][bd].
838///
839/// Yew implementation of the table row element, based on the specification
840/// found in the [Bulma table element documentation][bd].
841///
842/// # Examples
843///
844/// ```rust
845/// use yew::prelude::*;
846/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
847///
848/// #[function_component(App)]
849/// fn app() -> Html {
850/// html! {
851/// <Table>
852/// <TableHeader>{"One"}</TableHeader>
853/// <TableHeader>{"Two"}</TableHeader>
854///
855/// <TableRow>
856/// <TableData>{ "Three" }</TableData>
857/// <TableData>{ "Four" }</TableData>
858/// </TableRow>
859/// <TableRow>
860/// <TableData>{ "Five" }</TableData>
861/// <TableData>{ "Six" }</TableData>
862/// </TableRow>
863/// <TableRow>
864/// <TableData>{ "Seven" }</TableData>
865/// <TableData>{ "Eight" }</TableData>
866/// </TableRow>
867/// </Table>
868/// }
869/// }
870/// ```
871///
872/// [bd]: https://bulma.io/documentation/elements/table/
873#[function_component(TableRow)]
874pub fn table_row(props: &TableRowProperties) -> Html {
875 let class = ClassBuilder::default()
876 .with_custom_class(&String::from(props))
877 .with_custom_class(
878 &props
879 .class
880 .as_ref()
881 .map(|c| c.to_string())
882 .unwrap_or("".to_owned()),
883 )
884 .build();
885
886 html! {
887 <tr id={props.id.clone()} {class}
888 onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
889 onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
890 ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
891 oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
892 onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
893 onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
894 onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
895 ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
896 onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
897 onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
898 onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
899 ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
900 { for props.children.iter() }
901 </tr>
902 }
903}
904
905/// Defines the properties of the [Bulma table data element][bd].
906///
907/// Defines the properties of the table data element, based on the
908/// specification found in the [Bulma table element documentation][bd].
909///
910/// # Examples
911///
912/// ```rust
913/// use yew::prelude::*;
914/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
915///
916/// #[function_component(App)]
917/// fn app() -> Html {
918/// html! {
919/// <Table>
920/// <TableHeader>{"One"}</TableHeader>
921/// <TableHeader>{"Two"}</TableHeader>
922///
923/// <TableRow>
924/// <TableData>{ "Three" }</TableData>
925/// <TableData>{ "Four" }</TableData>
926/// </TableRow>
927/// <TableRow>
928/// <TableData>{ "Five" }</TableData>
929/// <TableData>{ "Six" }</TableData>
930/// </TableRow>
931/// <TableRow>
932/// <TableData>{ "Seven" }</TableData>
933/// <TableData>{ "Eight" }</TableData>
934/// </TableRow>
935/// </Table>
936/// }
937/// }
938/// ```
939///
940/// [bd]: https://bulma.io/documentation/elements/table/
941#[base_component_properties]
942#[derive(Properties, PartialEq)]
943pub struct TableDataProperties {
944 /// The list of elements found inside the [table data element][bd].
945 ///
946 /// Defines the elements that will be found inside the
947 /// [Bulma table data element][bd] which will receive these properties.
948 ///
949 /// [bd]: https://bulma.io/documentation/elements/table/
950 pub children: Children,
951}
952
953/// Yew implementation of the [Bulma table data element][bd].
954///
955/// Yew implementation of the table data element, based on the specification
956/// found in the [Bulma table element documentation][bd].
957///
958/// # Examples
959///
960/// ```rust
961/// use yew::prelude::*;
962/// use yew_and_bulma::elements::table::{Table, TableHeader, TableRow, TableData};
963///
964/// #[function_component(App)]
965/// fn app() -> Html {
966/// html! {
967/// <Table>
968/// <TableHeader>{"One"}</TableHeader>
969/// <TableHeader>{"Two"}</TableHeader>
970///
971/// <TableRow>
972/// <TableData>{ "Three" }</TableData>
973/// <TableData>{ "Four" }</TableData>
974/// </TableRow>
975/// <TableRow>
976/// <TableData>{ "Five" }</TableData>
977/// <TableData>{ "Six" }</TableData>
978/// </TableRow>
979/// <TableRow>
980/// <TableData>{ "Seven" }</TableData>
981/// <TableData>{ "Eight" }</TableData>
982/// </TableRow>
983/// </Table>
984/// }
985/// }
986/// ```
987///
988/// [bd]: https://bulma.io/documentation/elements/table/
989#[function_component(TableData)]
990pub fn table_data(props: &TableDataProperties) -> Html {
991 let class = ClassBuilder::default()
992 .with_custom_class(
993 &props
994 .class
995 .as_ref()
996 .map(|c| c.to_string())
997 .unwrap_or("".to_owned()),
998 )
999 .build();
1000
1001 html! {
1002 <td id={props.id.clone()} {class}
1003 onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
1004 onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
1005 ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
1006 oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
1007 onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
1008 onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
1009 onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
1010 ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
1011 onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
1012 onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
1013 onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
1014 ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
1015 { for props.children.iter() }
1016 </td>
1017 }
1018}