| 1 |
{# Composable click-through carousel. |
| 2 |
|
| 3 |
One widget, used everywhere. A carousel is just an ordered list of frames; |
| 4 |
every surface (app product pages, landing) calls this same macro with a |
| 5 |
different frame list. Do not fork it for bespoke layouts, if a surface |
| 6 |
needs more, extend the macro. |
| 7 |
|
| 8 |
Click-through, not animated: the viewer advances frames with the prev/next |
| 9 |
controls or the arrow keys. No autoplay, no auto-advance, no slide animation, |
| 10 |
frames swap instantly. |
| 11 |
|
| 12 |
The dots are gone as of 2026-08-14. A dot strip has no terminal form and no |
| 13 |
good webview form past a handful of frames, and only the landing gallery is a |
| 14 |
fixed three -- the project and item galleries are creator uploads of any |
| 15 |
length. The arrows came off the picture in the same pass; nothing overlays a |
| 16 |
frame now. |
| 17 |
|
| 18 |
Each frame is a `CarouselFrame { image, alt, caption: Option<_> }` |
| 19 |
(see `src/templates/mod.rs`). Usage is unchanged: |
| 20 |
|
| 21 |
{%- import "partials/carousel.html" as carousel -%} |
| 22 |
{% call carousel::carousel("af-shots", frames) %}{% endcall %} |
| 23 |
|
| 24 |
THE MARKUP IS NO LONGER WRITTEN HERE. It comes from the description layer: |
| 25 |
`crate::quasi::widgets::carousel` says "an ordered set of pictures, called a |
| 26 |
carousel" and quasi-webview turns that into markup. This file is now the |
| 27 |
call, and the reason it still exists is that three pages already import it. |
| 28 |
|
| 29 |
What that buys, beyond one description instead of one template: |
| 30 |
|
| 31 |
- The frame's edge is a bevel from makeover, not a border and an rgba() |
| 32 |
shadow written by hand here. In-flow depth is a bevel; elevation is for |
| 33 |
what sits over the page. |
| 34 |
- Progressive enhancement runs the other way, and costs nothing to do it. |
| 35 |
This used to render frame one and leave the other frames unreachable |
| 36 |
without JS, because the controls that reach them are the scripted part. |
| 37 |
|
| 38 |
The description now carries the whole gallery, but the DEFAULT rendering |
| 39 |
shows one frame, so a visitor with JavaScript sees a settled page from |
| 40 |
first paint. `no-js.css`, loaded from the <noscript> below, is what opens |
| 41 |
the stack out for a visitor without it. Both properties, no layout shift: |
| 42 |
collapsing three frames to one after load was a visible jump that everyone |
| 43 |
paid so that a few could reach frames two and three. |
| 44 |
|
| 45 |
- The chrome is described too, as of makeover-layout 0.23.0. The description |
| 46 |
says one frame is showing and quasi-webview derives prev/position/next from |
| 47 |
that, for every widget at once rather than for this one. The island stopped |
| 48 |
injecting buttons and now only binds what is already there. |
| 49 |
#} |
| 50 |
|
| 51 |
{% macro carousel(id, frames) -%} |
| 52 |
<noscript><link rel="stylesheet" href="/static/no-js.css"></noscript> |
| 53 |
<mnw-carousel>{{ crate::quasi::widgets::carousel::html(id, frames)|safe }}</mnw-carousel> |
| 54 |
{%- endmacro %} |
| 55 |
|