Add glightbox and use it in horizontal-scroller
This commit is contained in:
parent
f227889876
commit
99c6494fb2
11
package-lock.json
generated
11
package-lock.json
generated
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<typeof component_arguments> {
|
||||
<div
|
||||
class={["horizontal-gallery", ...classes]}
|
||||
style={`--jdd-index: ${index}`}
|
||||
data-controller="glightbox"
|
||||
>
|
||||
{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) => (
|
||||
<>
|
||||
<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">
|
||||
|
||||
@ -16,6 +16,9 @@ application.register("map-with-pins", MapWithPins);
|
||||
import { default as HorizontalScroller } from "./../back/routes/common/horizontal-scroller/horizontal-scroller.stimulus.js";
|
||||
application.register("horizontal-scroller", HorizontalScroller);
|
||||
|
||||
import { default as Glightbox } from "./controllers/glightbox.stimulus.js";
|
||||
application.register("glightbox", Glightbox);
|
||||
|
||||
import { default as AutogrowTextarea } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/autogrow-textarea.stimulus.js";
|
||||
application.register("autogrow-textarea", AutogrowTextarea);
|
||||
|
||||
|
||||
55
src/front/controllers/glightbox.stimulus.ts
Normal file
55
src/front/controllers/glightbox.stimulus.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
|
||||
/* ^ necessary until https://github.com/biati-digital/glightbox/pull/577 waits for merge */
|
||||
import { Controller } from "stimulus";
|
||||
import { addCSS, addJS } from "@sealcode/add-to-head";
|
||||
import type { default as GL } from "glightbox";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
GLightbox: typeof GL;
|
||||
}
|
||||
}
|
||||
|
||||
const settings = { touchNavigation: true };
|
||||
|
||||
export default class GlightboxController extends Controller {
|
||||
static targets = ["pictureWrapper"];
|
||||
|
||||
id: string;
|
||||
gallery: ReturnType<typeof GL>;
|
||||
declare pictureWrapperTargets: HTMLDivElement[];
|
||||
|
||||
async connect() {
|
||||
await this.initGallery();
|
||||
}
|
||||
|
||||
async initGallery() {
|
||||
await Promise.all([
|
||||
addJS("/dist/glightbox/js/glightbox.min.js"),
|
||||
addCSS("/dist/glightbox/css/glightbox.min.css"),
|
||||
]);
|
||||
this.gallery?.destroy();
|
||||
this.gallery = window.GLightbox({
|
||||
elements: this.pictureWrapperTargets.map((e) => {
|
||||
const img = e.querySelector("img");
|
||||
return {
|
||||
type: "image",
|
||||
href: img.getAttribute("src"),
|
||||
description: e.getAttribute("data-glightbox-caption"),
|
||||
alt: img.getAttribute("alt") || "",
|
||||
};
|
||||
}) as any,
|
||||
...settings,
|
||||
});
|
||||
|
||||
this.pictureWrapperTargets.map((e, index) => {
|
||||
e.addEventListener("click", () => {
|
||||
this.gallery.openAt(index);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async pictureWrapperTargetConnected() {
|
||||
await this.initGallery();
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,8 @@
|
||||
"lib": ["dom", "es2021"],
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"noUncheckedIndexedAccess": true
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["./src/front", "./src/**/*.stimulus.ts"]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user