Files
windwiderstand/src/lib/components/ImageModal.svelte
T
Peter Meier 23faef550e
Deploy / verify (push) Successful in 58s
Deploy / deploy (push) Successful in 53s
feat(calendar): image/attachment per event, direct links, copy link, ImageModal component
- calendar_item schema: flyer → image (type: image), attachment (assetUrl)
- CalendarItemData: image + attachment fields
- event anchor IDs (#event-{slug}) with onMount hash scroll + auto-open
- share button uses direct calendar anchor URL
- copy link button (mdi:link-variant) copies anchor URL to clipboard
- ImageModal extracted as reusable component
- action buttons always show text (no expand-on-hover)
- onDestroy window guard (SSR fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 20:02:30 +02:00

45 lines
1.2 KiB
Svelte

<script lang="ts">
import { onMount, onDestroy } from "svelte";
import Icon from "@iconify/svelte";
import "$lib/iconify-offline";
let {
src,
alt = "",
onclose,
}: { src: string; alt?: string; onclose: () => void } = $props();
function onKeydown(e: KeyboardEvent) {
if (e.key === "Escape") onclose();
}
onMount(() => window.addEventListener("keydown", onKeydown));
onDestroy(() => {
if (typeof window !== "undefined")
window.removeEventListener("keydown", onKeydown);
});
</script>
<div
class="fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 p-4 cursor-zoom-out"
onclick={onclose}
role="dialog"
aria-modal="true"
aria-label={alt || "Bild Vollansicht"}
>
<img
{src}
{alt}
class="max-w-full max-h-full object-contain rounded shadow-2xl cursor-default"
onclick={(e) => e.stopPropagation()}
/>
<button
type="button"
onclick={onclose}
class="absolute top-4 right-4 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
aria-label="Schließen"
>
<Icon icon="mdi:close" class="size-5" aria-hidden="true" />
</button>
</div>