since3-portal/modules/templates/catalog/shared/media.tsx
2026-10-10 02:38:50 +02:00

45 lines
1.4 KiB
TypeScript

import Image from "next/image"
import { cn } from "@/lib/utils"
function isImageUrl(src: string) {
// Eigene Dateien aus /public (z. B. /pictures/templates/...)
if (src.startsWith("/") && !src.startsWith("//")) return true
try {
const { protocol } = new URL(src)
return protocol === "https:" || protocol === "http:"
} catch {
return false
}
}
// Bild als Füllung des (relativ positionierten) Elternelements. Eigene Dateien und Unsplash laufen über die
// Bildoptimierung, beliebige andere Links unoptimiert. Leere oder halb getippte Links zeigen eine Fläche.
export function TImage({ src, alt = "", className, sizes = "100vw", eager }: {
src: string
alt?: string
className?: string
sizes?: string
eager?: boolean
}) {
if (!isImageUrl(src)) {
return (
<div
aria-hidden
className={cn("absolute inset-0 bg-[linear-gradient(135deg,var(--t-surface),color-mix(in_oklab,var(--t-muted)_35%,var(--t-surface)))]", className)}
/>
)
}
return (
<Image
src={src}
alt={alt}
fill
sizes={sizes}
unoptimized={!src.startsWith("/") && !src.startsWith("https://images.unsplash.com/")}
loading={eager ? "eager" : undefined}
fetchPriority={eager ? "high" : undefined}
className={cn("object-cover", className)}
/>
)
}