import { useState } from "react";
import { Button } from "../ui/Button";
import { cn } from "~/utils/cn";
const MODES = ["side-by-side", "swipe"] as const;
const IMAGE_PATH = /\.(png|jpe?g|gif|webp|avif|ico|bmp)$/i;
const HALF = 50;
export function isImagePath(path: string): boolean {
return IMAGE_PATH.test(path);
}
/** Raw URL prefixes (`/owner/repo/raw/<rev>`) for the two sides of a diff. */
export type ImageSources = { base: string | null; head: string };
function Frame({ src, label, tone }: { src: string | null; label: string; tone: "red" | "green" }) {
return (
<figure className="flex min-w-0 flex-1 flex-col items-center gap-2">
<figcaption className={cn("text-xs", tone === "red" ? "text-red-400" : "text-emerald-400")}>{label}</figcaption>
{src ? (
<img
src={src}
alt={label}
className={cn("max-h-96 max-w-full border", tone === "red" ? "border-red-900" : "border-emerald-900")}
/>
) : (
<div className="py-10 text-xs text-gray-600">None</div>
)}
</figure>
);
}
function Swipe({ before, after }: { before: string; after: string }) {
const [position, setPosition] = useState(HALF);
return (
<div className="space-y-3">
<div className="relative mx-auto w-fit">
<img src={after} alt="After" className="block max-h-96 max-w-full" />
<div className="absolute inset-0 overflow-hidden" style={{ clipPath: `inset(0 ${100 - position}% 0 0)` }}>
<img src={before} alt="Before" className="block max-h-96 max-w-full" />