diff --git a/assets/js/imageGallery.js b/assets/js/imageGallery.js new file mode 100644 index 000000000..ea38b2505 --- /dev/null +++ b/assets/js/imageGallery.js @@ -0,0 +1,42 @@ +const gallery = document.querySelector(".m-image-gallery"); +const galleryPictures = gallery.querySelector(".m-image-gallery__pictures"); + +const nextButton = gallery.querySelector("#next"); +const prevButton = gallery.querySelector("#prev"); + +// There is an problem with the scroll-snap on mobile devices, so we need to add the gap between the items when scrolling to make it work properly. +const galleryGap = 15; + +const getItemWidth = () => + galleryPictures.children[0]?.getBoundingClientRect().width ?? + galleryPictures.clientWidth; + +const updateButtonState = () => { + console.log("updateButtonState"); + const maxScrollLeft = + galleryPictures.scrollWidth - galleryPictures.clientWidth; + + prevButton.disabled = galleryPictures.scrollLeft === 0; + nextButton.disabled = galleryPictures.scrollLeft >= maxScrollLeft; +}; + +nextButton.addEventListener("click", () => { + galleryPictures.scrollTo({ + left: galleryPictures.scrollLeft + getItemWidth() + galleryGap, + behavior: "smooth", + }); +}); + +prevButton.addEventListener("click", () => { + galleryPictures.scrollTo({ + left: galleryPictures.scrollLeft - getItemWidth() - galleryGap, + behavior: "smooth", + }); +}); + +galleryPictures.addEventListener("scroll", updateButtonState, { + passive: true, +}); +window.addEventListener("resize", updateButtonState); + +updateButtonState(); diff --git a/assets/js/main.js b/assets/js/main.js index 250f2f335..eeb35b81a 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -11,3 +11,4 @@ import "./expander.js"; import "./dialog.js"; import "./fipValidityComparison.js"; import "./search.js"; +import "./imageGallery.js"; diff --git a/assets/sass/imageGallery.scss b/assets/sass/imageGallery.scss new file mode 100644 index 000000000..dd6fee58f --- /dev/null +++ b/assets/sass/imageGallery.scss @@ -0,0 +1,47 @@ +.m-image-gallery { + display: flex; + flex-direction: column; + gap: 0.4rem; +} + +.m-image-gallery__pictures { + display: flex; + margin: 0; + padding: 0; + gap: 1.5rem; + overflow-x: auto; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + list-style: none; + border-radius: var(--border-radius-l); + + -ms-overflow-style: none; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + @media (prefers-reduced-motion: reduce) { + scroll-behavior: auto; + } + + @include focus-indicator(0.2rem); +} + +.m-image-gallery__item { + flex: 0 0 100%; + scroll-snap-align: center; + list-style: none; +} + +.m-image-gallery__controls { + display: flex; + gap: 1rem; + align-self: center; + margin-bottom: 1rem; + + .a-button:disabled { + opacity: 0.35; + } +} diff --git a/assets/sass/main.scss b/assets/sass/main.scss index 3aed6e2f5..0a1654e72 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -22,6 +22,7 @@ @import "trainCategory.scss"; @import "tag.scss"; @import "floatImage.scss"; +@import "imageGallery.scss"; @import "teamMember.scss"; @import "dialog.scss"; @import "fip-validity.scss"; diff --git a/assets/sass/styles.scss b/assets/sass/styles.scss index c4a2a1df9..187f2555d 100644 --- a/assets/sass/styles.scss +++ b/assets/sass/styles.scss @@ -330,7 +330,7 @@ figure { display: flex; flex-direction: column; gap: 1.5rem; - overflow-x: auto; + overflow-x: visible; p { text-align: justify; diff --git a/content/operator/sz/image2.webp b/content/operator/sz/image2.webp new file mode 100644 index 000000000..a55e72462 Binary files /dev/null and b/content/operator/sz/image2.webp differ diff --git a/i18n/de.yaml b/i18n/de.yaml index 0da226c22..d5821c1cc 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -152,6 +152,10 @@ fipValidity: footer-love: aria-label: Made with love in Europe text: Made with ♥️ in Europe +gallery: + aria-label: Bildgalerie + next: Nächstes Bild + previous: Vorheriges Bild highlight: confusion: Verwechslungsgefahr important: Wichtige Information diff --git a/i18n/en.yaml b/i18n/en.yaml index 5339c6b5e..764e53fda 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -148,6 +148,10 @@ fipValidity: footer-love: aria-label: Made with love in Europe text: Made with ♥️ in Europe +gallery: + aria-label: Image gallery + next: Next Image + previous: Previous Image highlight: confusion: Risk of Confusion important: Important Information diff --git a/i18n/fr.yaml b/i18n/fr.yaml index 7e8d0f755..f62907144 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -156,6 +156,10 @@ fipValidity: footer-love: aria-label: Fait avec amour en Europe text: Fait avec ♥️ en Europe +gallery: + aria-label: Galerie d'images + next: Image suivante + previous: Image précédente general: Général highlight: confusion: Risque de confusion diff --git a/layouts/_partials/button.html b/layouts/_partials/button.html index f82b158a2..cc7960494 100644 --- a/layouts/_partials/button.html +++ b/layouts/_partials/button.html @@ -3,6 +3,7 @@ href="{{ .Destination }}" target="_blank" rel="noopener noreferrer" + {{- with .ID }}id="{{ . }}"{{- end -}} class="a-button a-button__external o-link__external" > {{- .Text -}}{{- partial "icon" "arrow_outward" -}} @@ -10,6 +11,7 @@ {{- else -}}