ftml/render/html/element/
collapsible.rs1use super::prelude::*;
22use crate::tree::{AttributeMap, Element};
23
24#[derive(Debug, Copy, Clone)]
25pub struct Collapsible<'a> {
26 elements: &'a [Element<'a>],
27 attributes: &'a AttributeMap<'a>,
28 start_open: bool,
29 show_text: Option<&'a str>,
30 hide_text: Option<&'a str>,
31 show_top: bool,
32 show_bottom: bool,
33}
34
35impl<'a> Collapsible<'a> {
36 #[inline]
37 pub fn new(
38 elements: &'a [Element<'a>],
39 attributes: &'a AttributeMap<'a>,
40 start_open: bool,
41 show_text: Option<&'a str>,
42 hide_text: Option<&'a str>,
43 show_top: bool,
44 show_bottom: bool,
45 ) -> Self {
46 Collapsible {
47 elements,
48 attributes,
49 start_open,
50 show_text,
51 hide_text,
52 show_top,
53 show_bottom,
54 }
55 }
56}
57
58pub fn render_collapsible(ctx: &mut HtmlContext, collapsible: Collapsible) {
59 let Collapsible {
60 elements,
61 attributes,
62 start_open,
63 show_text,
64 hide_text,
65 show_top,
66 show_bottom,
67 } = collapsible;
68
69 debug!(
70 "Rendering collapsible (elements length {}, start-open {}, show-text {}, hide-text {}, show-top {}, show-bottom {})",
71 elements.len(),
72 start_open,
73 show_text.unwrap_or("<default>"),
74 hide_text.unwrap_or("<default>"),
75 show_top,
76 show_bottom,
77 );
78
79 let show_text = show_text
80 .unwrap_or_else(|| ctx.handle().get_message(ctx.language(), "collapsible-open"));
81
82 let hide_text = hide_text
83 .unwrap_or_else(|| ctx.handle().get_message(ctx.language(), "collapsible-hide"));
84
85 ctx.html()
86 .details()
87 .attr(attr!(
88 "class" => "wj-collapsible",
89 "open"; if start_open,
90 "data-show-top"; if show_top,
91 "data-show-bottom"; if show_bottom;;
92 attributes,
93 ))
94 .inner(|ctx| {
95 ctx.html()
97 .summary()
98 .attr(attr!(
99 "class" => "wj-collapsible-button wj-collapsible-button-top",
100 ))
101 .inner(|ctx| {
102 ctx.html()
104 .span()
105 .attr(attr!("class" => "wj-collapsible-show-text"))
106 .contents(show_text);
107
108 ctx.html()
110 .span()
111 .attr(attr!("class" => "wj-collapsible-hide-text"))
112 .contents(hide_text);
113 });
114
115 ctx.html()
117 .div()
118 .attr(attr!("class" => "wj-collapsible-content"))
119 .contents(elements);
120
121 if show_bottom {
123 ctx.html()
124 .element("wj-collapsible-button-bottom")
125 .attr(attr!(
126 "class" => "wj-collapsible-button wj-collapsible-button-bottom",
127 ))
128 .inner(|ctx| {
129 ctx.html()
131 .span()
132 .attr(attr!("class" => "wj-collapsible-hide-text"))
133 .contents(hide_text);
134 });
135 }
136 });
137}