import { useState } from 'react'; import { CopyButton } from './CopyButton'; interface ImagePreviewProps { url: string; /** Optional label rendered as the header chip (e.g. `image_url`). */ label?: string; } /** Inline preview for an image ContentPart URL. * Renders the actual `` for `data:image/*` and `http(s)://` URLs; * falls back to the raw URL for any other scheme. * Click "expand" to lift the height cap to 80vh; click "open in tab" * to view the full asset in a new browser tab. */ export function ImagePreview({ url, label = 'image_url' }: ImagePreviewProps) { const [open, setOpen] = useState(false); const [failed, setFailed] = useState(false); const supported = url.startsWith('data:image/') || /^https?:\/\//.test(url) || url.startsWith('/'); const sizeLabel = url.startsWith('data:image/') ? `${url.length.toLocaleString()} chars` : new URL(url, window.location.href).hostname; if (!supported) { return (
{label} (unsupported scheme)
{url}
); } return (
{label} · {sizeLabel} open in tab ↗
{failed ? (
failed to load image
) : ( content image { setFailed(true); }} className={ 'block max-w-full object-contain ' + (open ? 'max-h-[80vh]' : 'max-h-[220px]') } /> )}
); }