feat(gallery): grid title, subtle download icon, full i18n
- Render block.title as <h3> above the grid when set; the carousel variant is unchanged. - Download CTA in the modal shrunk to a 9×9 icon-only button with text-white/80 hover-tint instead of the dark green link colour the app's `main a` rule was forcing in. Adds `no-underline` so the global underline doesn't sneak back in. - All previously hardcoded German strings (Download, Schließen, modal aria, open aria) now go through translations.ts → CMS translation_bundle. Cms_content app.json5 ships the matching keys. Open follow-up: per-image title/alt/caption is empty on the existing windwiderstand mediathek gallery → editor needs to fill those if hover labels are wanted.
This commit is contained in:
@@ -167,6 +167,9 @@
|
|||||||
{#if withUrl.length === 0}
|
{#if withUrl.length === 0}
|
||||||
<p class="text-sm text-stein-500">{t(T.image_gallery_empty)}</p>
|
<p class="text-sm text-stein-500">{t(T.image_gallery_empty)}</p>
|
||||||
{:else if block.variant === "grid"}
|
{:else if block.variant === "grid"}
|
||||||
|
{#if block.title}
|
||||||
|
<h3 class="text-lg font-semibold text-stein-900 mb-3">{block.title}</h3>
|
||||||
|
{/if}
|
||||||
<ul class="not-prose grid grid-cols-2 gap-2 sm:grid-cols-3 md:grid-cols-4">
|
<ul class="not-prose grid grid-cols-2 gap-2 sm:grid-cols-3 md:grid-cols-4">
|
||||||
{#each withUrl as item, i}
|
{#each withUrl as item, i}
|
||||||
{@const label = imageLabel(item.img)}
|
{@const label = imageLabel(item.img)}
|
||||||
@@ -175,7 +178,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="group relative block w-full aspect-square overflow-hidden rounded-sm bg-stein-100 cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-wald-500"
|
class="group relative block w-full aspect-square overflow-hidden rounded-sm bg-stein-100 cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-wald-500"
|
||||||
onclick={() => openModal(i)}
|
onclick={() => openModal(i)}
|
||||||
aria-label={label || `Bild ${i + 1}`}
|
aria-label={label || t(T.image_gallery_open_aria)}
|
||||||
>
|
>
|
||||||
<RustyImage
|
<RustyImage
|
||||||
src={item.url}
|
src={item.url}
|
||||||
@@ -207,7 +210,7 @@
|
|||||||
class="fixed inset-0 z-[100] flex items-center justify-center bg-black/85 p-4"
|
class="fixed inset-0 z-[100] flex items-center justify-center bg-black/85 p-4"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-label={curLabel || "Bild-Vorschau"}
|
aria-label={curLabel || t(T.image_gallery_modal_aria)}
|
||||||
onclick={closeModal}
|
onclick={closeModal}
|
||||||
transition:fade={{ duration: 150 }}
|
transition:fade={{ duration: 150 }}
|
||||||
>
|
>
|
||||||
@@ -216,7 +219,6 @@
|
|||||||
onclick={(e) => e.stopPropagation()}
|
onclick={(e) => e.stopPropagation()}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable-next-line @typescript-eslint/no-unused-expressions -->
|
|
||||||
<img
|
<img
|
||||||
src={cur.url}
|
src={cur.url}
|
||||||
alt={curLabel}
|
alt={curLabel}
|
||||||
@@ -235,10 +237,11 @@
|
|||||||
<a
|
<a
|
||||||
href={cur.url}
|
href={cur.url}
|
||||||
download={downloadFilename(cur.url)}
|
download={downloadFilename(cur.url)}
|
||||||
class="inline-flex items-center gap-1.5 rounded-md bg-white/10 px-3 py-1.5 text-sm font-medium text-white hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/50"
|
class="no-underline inline-flex h-9 w-9 items-center justify-center rounded-full text-white/80 hover:text-white hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/40"
|
||||||
|
title={t(T.image_gallery_download)}
|
||||||
|
aria-label={t(T.image_gallery_download)}
|
||||||
>
|
>
|
||||||
<Icon icon="mdi:download-outline" class="text-base" aria-hidden="true" />
|
<Icon icon="mdi:download-outline" class="text-xl" aria-hidden="true" />
|
||||||
Download
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{#if withUrl.length > 1}
|
{#if withUrl.length > 1}
|
||||||
@@ -263,7 +266,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="absolute -top-2 -right-2 inline-flex h-8 w-8 items-center justify-center rounded-full bg-white text-stein-900 shadow-md hover:bg-stein-100 focus:outline-none focus:ring-2 focus:ring-white/50"
|
class="absolute -top-2 -right-2 inline-flex h-8 w-8 items-center justify-center rounded-full bg-white text-stein-900 shadow-md hover:bg-stein-100 focus:outline-none focus:ring-2 focus:ring-white/50"
|
||||||
onclick={closeModal}
|
onclick={closeModal}
|
||||||
aria-label="Schließen"
|
aria-label={t(T.image_gallery_close)}
|
||||||
>
|
>
|
||||||
<Icon icon="mdi:close" class="text-lg" aria-hidden="true" />
|
<Icon icon="mdi:close" class="text-lg" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ const TRANSLATION_KEYS = [
|
|||||||
"image_gallery_position_aria",
|
"image_gallery_position_aria",
|
||||||
"image_gallery_slide_aria",
|
"image_gallery_slide_aria",
|
||||||
"image_gallery_empty",
|
"image_gallery_empty",
|
||||||
|
"image_gallery_download",
|
||||||
|
"image_gallery_close",
|
||||||
|
"image_gallery_open_aria",
|
||||||
|
"image_gallery_modal_aria",
|
||||||
"youtube_missing",
|
"youtube_missing",
|
||||||
"youtube_title_fallback",
|
"youtube_title_fallback",
|
||||||
"calendar_prev_month",
|
"calendar_prev_month",
|
||||||
|
|||||||
Reference in New Issue
Block a user