diff --git a/package-lock.json b/package-lock.json index 9c688c3..649b443 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "dotenv": "^16.4.5", "escape-goat": "^4.0.0", "get-port": "^7.0.0", + "glightbox": "^3.3.1", "glob": "^11.0.3", "js-convert-case": "^4.2.0", "koa-mount": "^4.2.0", @@ -6064,6 +6065,11 @@ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, + "node_modules/glightbox": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/glightbox/-/glightbox-3.3.1.tgz", + "integrity": "sha512-nXoKfJRnQTDaAFAw5799hjpfAAHx5aLvOLG0SIGudeMCwtHgO3P2/avNYapJ+SL4UEZxO2YNBPtq6pzMhSx42g==" + }, "node_modules/glob": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", @@ -19515,6 +19521,11 @@ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, + "glightbox": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/glightbox/-/glightbox-3.3.1.tgz", + "integrity": "sha512-nXoKfJRnQTDaAFAw5799hjpfAAHx5aLvOLG0SIGudeMCwtHgO3P2/avNYapJ+SL4UEZxO2YNBPtq6pzMhSx42g==" + }, "glob": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", diff --git a/package.json b/package.json index bc5459f..452d480 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,10 @@ { "from": "node_modules/@sealcode/sealcodemirror/mode/javascript/javascript.js", "to": "dist/codemirror-javascript-mode.js" + }, + { + "from": "node_modules/glightbox/dist", + "to": "dist/glightbox" } ] }, @@ -109,6 +113,7 @@ "dotenv": "^16.4.5", "escape-goat": "^4.0.0", "get-port": "^7.0.0", + "glightbox": "^3.3.1", "glob": "^11.0.3", "js-convert-case": "^4.2.0", "koa-mount": "^4.2.0", diff --git a/src/back/jdd-components/horizontal-gallery/horizontal-gallery.css b/src/back/jdd-components/horizontal-gallery/horizontal-gallery.css index ff4ba94..4c844b0 100644 --- a/src/back/jdd-components/horizontal-gallery/horizontal-gallery.css +++ b/src/back/jdd-components/horizontal-gallery/horizontal-gallery.css @@ -69,6 +69,13 @@ max-width: 100cqw; align-items: center; + & > span { + display: grid; + max-height: min(75vh, 700px); + grid-template-rows: 1fr min-content; + height: 100%; + } + &, picture, img { @@ -80,10 +87,50 @@ ); /* at just 100cqw it breaks the scroller when the images are very horizontal */ } - picture { - height: auto; - width: 100% !important; - background-image: none !important; + .caption { + font-style: italic; + text-align: justify; + grid-row: 2/3; + grid-column: 1/2; + z-index: 1; + padding: 8px; + background-color: color-mix( + in srgb, + var(--color-brand-text-bg) 70%, + transparent + ); + backdrop-filter: blur(5px); + will-change: backdrop-filter background-color; + + &:hover { + background-color: color-mix( + in srgb, + var(--color-brand-text-bg) 90%, + transparent + ); + backdrop-filter: blur(10px); + } + } + + .image-wrapper { + grid-row: 1/3; + grid-column: 1/2; + + display: flex; + flex-flow: row; + align-items: center; + + cursor: pointer; + + &:has(picture:hover) + .caption:not(:hover) { + opacity: 0.1; + } + + picture { + height: auto; + width: 100% !important; + background-image: none !important; + } } } } diff --git a/src/back/jdd-components/horizontal-gallery/horizontal-gallery.jdd.tsx b/src/back/jdd-components/horizontal-gallery/horizontal-gallery.jdd.tsx index 57d0ad9..982fc58 100644 --- a/src/back/jdd-components/horizontal-gallery/horizontal-gallery.jdd.tsx +++ b/src/back/jdd-components/horizontal-gallery/horizontal-gallery.jdd.tsx @@ -7,13 +7,15 @@ import type { } 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(), + alt: new ComponentArguments.ShortText().setExampleValues([""]), + caption: new ComponentArguments.ShortText().setExampleValues([""]), }) ), } as const; @@ -40,15 +42,33 @@ export class HorizontalGallery extends Component {
{horizontalScroller({ - elements: (images || []).map((image) => - render_image(image.image, { - sizesAttr: "100vw", - container: { width: 800, height: 500, objectFit: "contain" }, - alt: image.alt, - }) - ), + elements: (images || []).map((image) => ( + <> +
+ {render_image(image.image, { + sizesAttr: "100vw", + container: { + width: 800, + height: 500, + objectFit: "contain", + }, + alt: image.alt, + })} +
+ {image.caption.trim() ? ( +
{image.caption}
+ ) : ( + "" + )} + + )), render: async ({ scroller, markers }) => (