2026-01-01 19:26:29 +01:00

104 lines
2.7 KiB
TypeScript

import type { FlatTemplatable } from "tempstream";
import { TempstreamJSX } from "tempstream";
import type {
ComponentToHTMLArgs,
ExtractStructuredComponentArgumentsParsed,
JDDContext,
} from "@sealcode/jdd";
import { Component, ComponentArguments, insert_nbsp } from "@sealcode/jdd";
import { horizontalScroller } from "../../routes/common/horizontal-scroller/horizontal-scroller.js";
import { htmlEscape } from "escape-goat";
const component_arguments = {
title: new ComponentArguments.ShortText(),
images: new ComponentArguments.List(
new ComponentArguments.Structured({
image: new ComponentArguments.Image(),
alt: new ComponentArguments.ShortText().setExampleValues([""]),
caption: new ComponentArguments.ShortText().setExampleValues([""]),
})
),
} as const;
export class HorizontalGallery extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
getTitle(
_: JDDContext,
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) {
return args.title || null;
}
toHTML({
args: { title, images },
classes,
jdd_context: { render_image },
index,
}: ComponentToHTMLArgs<typeof component_arguments>): FlatTemplatable {
return (
<div
class={["horizontal-gallery", ...classes]}
style={`--jdd-index: ${index}`}
data-controller="glightbox"
>
{horizontalScroller({
elements: (images || []).map((image) => (
<>
<div
class="image-wrapper"
data-glightbox-target="pictureWrapper"
data-glightbox-caption={htmlEscape(image.caption || "")}
>
{render_image(image.image, {
sizesAttr: "100vw",
container: {
width: 800,
height: 500,
objectFit: "contain",
},
alt: image.alt,
})}
</div>
{image.caption?.trim() ? (
<div class="caption">{image.caption}</div>
) : (
""
)}
</>
)),
render: async ({ scroller, markers }) => (
<div>
<div class="horizontal-gallery__top-bar">
<h2>{insert_nbsp(title)}</h2>
<div class="horizontal-gallery__buttons">
<button
class="prev-button"
data-action="horizontal-scroller#scrollLeft"
type="button"
>
<span style="transform: rotate(180deg); margin-right: 16px;">
</span>
</button>
<button
class="next-button"
data-action="horizontal-scroller#scrollRight"
type="button"
>
<span></span>
</button>
</div>
</div>
{scroller}
{markers}
</div>
),
})}
</div>
);
}
}