96 lines · 3.4 KB
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: "danger" | "success" }) {
  return (
    <figure className="flex min-w-0 flex-1 flex-col items-center gap-2">
      <figcaption className={cn("text-xs", tone === "danger" ? "text-kumo-danger" : "text-kumo-success")}>
        {label}
      </figcaption>
      {src ? (
        <img
          src={src}
          alt={label}
          className={cn("max-h-96 max-w-full border", tone === "danger" ? "border-danger-900" : "border-success-900")}
        />
      ) : (
        <div className="py-10 text-xs text-kumo-inactive">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" />