Alternative.images: array of urls, rendered as a Swiper card deck
Deploy / deploy (push) Successful in 1m0s
Deploy / deploy (push) Successful in 1m0s
image: Option<String> becomes images: Vec<String> (nothing in live content used the old field). One url renders as the plain banner it was; several become a swipeable cards-effect deck via Swiper Element 12.2.0, vendored into public/ (MIT) like prosekit-editor.js/yes.js rather than pulled from a CDN - the bundle only loads on pages where some alternative actually declares more than one image. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
40694a8f3f
commit
3233d9a3db
+34
-3
@@ -163,7 +163,13 @@ fn QuestionView(
|
||||
.into_any();
|
||||
}
|
||||
|
||||
// Swiper Element only registers its custom elements when its
|
||||
// (vendored, ~180KB) script runs - loaded once per page, and only
|
||||
// on pages where some alternative actually declares a deck.
|
||||
let needs_swiper = question.alternatives.iter().any(|a| a.images.len() > 1);
|
||||
|
||||
view! {
|
||||
{needs_swiper.then(|| view! { <leptos_meta::Script src="/swiper-element-bundle.min.js"/> })}
|
||||
<Hero
|
||||
title=question.name.clone()
|
||||
description=question.description.clone()
|
||||
@@ -370,6 +376,33 @@ fn Hero(title: String, description: String, show_yes: bool) -> impl IntoView {
|
||||
}
|
||||
}
|
||||
|
||||
/// An alternative's banner imagery: nothing, a plain image, or - for
|
||||
/// several urls - a Swiper Element card deck. The `swiper-container`/
|
||||
/// `swiper-slide` custom elements render inert server-side and upgrade
|
||||
/// once the vendored bundle registers them (loaded per-page by
|
||||
/// `QuestionView` only when some alternative actually needs it).
|
||||
#[component]
|
||||
fn AltImages(images: Vec<String>) -> impl IntoView {
|
||||
match images.len() {
|
||||
0 => ().into_any(),
|
||||
1 => view! { <img class="alt-image" src=images[0].clone() alt="" /> }.into_any(),
|
||||
_ => view! {
|
||||
<swiper-container class="alt-image-deck" effect="cards" grab-cursor="true">
|
||||
<For
|
||||
each=move || images.clone()
|
||||
key=|src| src.clone()
|
||||
children=|src: String| view! {
|
||||
<swiper-slide>
|
||||
<img class="alt-image" src=src alt="" />
|
||||
</swiper-slide>
|
||||
}.into_any()
|
||||
/>
|
||||
</swiper-container>
|
||||
}
|
||||
.into_any(),
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn AlternativeCard(
|
||||
question_id: String,
|
||||
@@ -593,9 +626,7 @@ fn AlternativeCard(
|
||||
|
||||
view! {
|
||||
<section class="alt-card">
|
||||
{alternative.image.clone().map(|src| view! {
|
||||
<img class="alt-image" src=src alt="" />
|
||||
})}
|
||||
<AltImages images=alternative.images.clone() />
|
||||
<h2>{alternative.name.clone()}</h2>
|
||||
<p class="alt-description">{alternative.description.clone()}</p>
|
||||
<div class="features">
|
||||
|
||||
Reference in New Issue
Block a user