Skip to main content

max / makenotwork

2.8 KB · 76 lines History Blame Raw
1 //! The Askama entry point for `quasi_basics::carousel`.
2 //!
3 //! The widget left for `quasi-basics` once three real pages had proved it, and
4 //! this is the part that stayed: glue between a template's own frame type and
5 //! the widget's. Called from `partials/carousel.html`, so all three call sites
6 //! keep the macro they already have.
7 //!
8 //! Why the island wraps the region rather than being it: a custom element is
9 //! what the browser re-upgrades after an htmx swap, which is the whole reason
10 //! islands are custom elements, and the description emits a plain `<div>`
11 //! because it has no idea this host prefixes its tags with `mnw-`. The template
12 //! puts one around the other and both halves stay honest.
13
14 use quasi_basics::Frame;
15 use quasi_router::Node;
16
17 /// The markup, for an Askama template to drop in.
18 #[must_use]
19 pub fn html(id: &str, items: &[crate::templates::CarouselFrame]) -> String {
20 use quasi_axum::Serves as _;
21
22 let node = Node::Region(quasi_basics::carousel(
23 id,
24 items.iter().map(|frame| {
25 let mut built = Frame::new(&frame.image, &frame.alt);
26 if let Some((w, h)) = frame.intrinsic {
27 built = built.intrinsic(w, h);
28 }
29 match &frame.caption {
30 Some(caption) => built.caption(caption),
31 None => built,
32 }
33 }),
34 ));
35
36 // No shell: this is a fragment landing inside a document Askama already
37 // built, which is exactly what `fragment` is for.
38 quasi_webview::Webview::new().fragment(&node)
39 }
40
41 #[cfg(test)]
42 mod tests {
43 use crate::templates::CarouselFrame;
44
45 /// What the widget guarantees is `quasi-basics`' to test, and it does.
46 /// What is MNW's is that this conversion loses nothing on the way through,
47 /// because it is the one place a template's frame becomes a widget's.
48 #[test]
49 fn a_template_frame_arrives_whole() {
50 let html = super::html(
51 "landing-shots",
52 &[
53 CarouselFrame {
54 image: "/a.png".into(),
55 alt: "The library, mid-import".into(),
56 caption: Some("Library".into()),
57 intrinsic: Some((5120, 3412)),
58 },
59 CarouselFrame {
60 image: "/b.png".into(),
61 alt: "A project page".into(),
62 caption: None,
63 intrinsic: None,
64 },
65 ],
66 );
67
68 assert!(html.contains(r#"data-widget="carousel""#), "{html}");
69 assert!(html.contains(r#"id="landing-shots""#), "{html}");
70 assert!(html.contains(r#"alt="The library, mid-import""#), "{html}");
71 assert!(html.contains("Library</figcaption>"), "{html}");
72 assert!(html.contains(r#"width="5120" height="3412""#), "{html}");
73 assert!(html.contains("/b.png"), "{html}");
74 }
75 }
76