--- // @ts-ignore - types provided by Astro at runtime import { Image as AstroImage } from "astro:assets"; interface Props { /** Source image imported via astro:assets */ src: any; /** Alt text for accessibility */ alt: string; /** Optional HTML string caption (use slot caption for rich content) */ caption?: string; /** Optional class to apply on the
wrapper when caption is used */ figureClass?: string; /** Enable medium-zoom behavior on this image */ zoomable?: boolean; /** Show a download button overlay and enable download flow */ downloadable?: boolean; /** Optional explicit file name to use on download */ downloadName?: string; /** Optional explicit source URL to download instead of currentSrc */ downloadSrc?: string; /** Optional link that wraps the image (not the caption) */ linkHref?: string; /** Optional target for the link (default: _blank when linkHref provided) */ linkTarget?: string; /** Optional rel for the link (default: noopener noreferrer when linkHref provided) */ linkRel?: string; /** Make the image span full width */ fullWidth?: boolean; /** Any additional attributes should be forwarded to the underlying */ [key: string]: any; } const { caption, figureClass, zoomable, downloadable, downloadName, downloadSrc, linkHref, linkTarget, linkRel, fullWidth, src, ...imgProps } = Astro.props as Props; // Try to get original image src from ImageMetadata object const getOriginalSrc = (imageSrc: any): string => { if (typeof imageSrc === "string") { return imageSrc; } // ImageMetadata from astro:assets has a 'src' property with the URL if (imageSrc && typeof imageSrc === "object") { // Check if this is an import with ?url (returns the original path directly) if ("default" in imageSrc && typeof imageSrc.default === "string") { return imageSrc.default; } // Try src property (optimized version) if ("src" in imageSrc && typeof imageSrc.src === "string") { return imageSrc.src; } // Try pathname property if ("pathname" in imageSrc && typeof imageSrc.pathname === "string") { return imageSrc.pathname; } // Fallback: try all string properties for (const key of Object.keys(imageSrc)) { if (typeof imageSrc[key] === "string" && imageSrc[key].length > 0) { return imageSrc[key]; } } } return ""; }; const originalSrc = getOriginalSrc(src); // Apply safe defaults without requiring callers to specify them const MAX_DISPLAY_WIDTH = 1800; const resolvedFormat = (imgProps as any).format || "webp"; // If no explicit width is provided and we have metadata, cap to MAX_DISPLAY_WIDTH let resolvedWidth = (imgProps as any).width; if ( !resolvedWidth && src && typeof src === "object" && typeof src.width === "number" ) { resolvedWidth = Math.min(src.width, MAX_DISPLAY_WIDTH); } const hasCaptionSlot = Astro.slots.has("caption"); const hasCaption = hasCaptionSlot || (typeof caption === "string" && caption.length > 0); const hasTitle = Astro.slots.has("title"); const uid = `ri_${Math.random().toString(36).slice(2)}`; // Use booleans instead of strings to avoid truthy "0" problem const dataZoomable = zoomable !== false || !!(imgProps as any)["data-zoomable"]; const dataDownloadable = downloadable !== false || !!(imgProps as any)["data-downloadable"]; const hasLink = typeof linkHref === "string" && linkHref.length > 0; const resolvedTarget = hasLink ? linkTarget || "_blank" : undefined; const resolvedRel = hasLink ? linkRel || "noopener noreferrer" : undefined; // Use downloadSrc if provided, otherwise try to use the original src const resolvedDownloadSrc = downloadSrc || originalSrc; ---
{ hasCaption ? (
{dataDownloadable ? ( {hasLink ? ( ) : ( )} ) : hasLink ? ( ) : ( )}
{hasCaptionSlot ? ( ) : ( caption && )}
) : dataDownloadable ? ( {hasLink ? ( ) : ( )} ) : hasLink ? ( ) : ( ) }