Vectrum
Sign In
49 lines · 2.0 KB · TypeScript
"use client";

import Link from "next/link";
import type { ReactNode } from "react";
import { Button, Tooltip, TooltipProvider } from "@unlocalhosted/metalui";
import { CopyButton } from "./clone-button";
import { PencilIcon, TrashIcon } from "./icons";

// MetalUI's IconButton (variant ghost) recipe, for keys that navigate and so must be links.
const GHOST_KEY =
  "mu-icon-button mu-icon-trigger relative box-border inline-grid place-items-center flex-none p-0 border-0 bg-transparent cursor-pointer tap-highlight-none focus-visible:focus-ring-flush size-icon-button-ghost-size rounded-pill text-icon-button-ghost-ink transition-icon-button [&>svg]:size-icon-button-ghost-glyph hover:recipe-icon-button-ghost-hover hover:text-icon-button-ghost-ink-hover";

/** A ghost icon key that goes somewhere, named by its tooltip and its aria-label. */
function IconLink({ href, label, icon, className = "" }: { href: string; label: string; icon: ReactNode; className?: string }) {
  return (
    <Tooltip label={label}>
      <Link href={href} aria-label={label} className={`${GHOST_KEY} ${className}`}>
        {icon}
      </Link>
    </Tooltip>
  );
}

/** The file viewer's toolbar: Raw as a compact cap, then copy, edit and delete as ghost keys. */
export function FileActions({
  rawHref,
  text,
  editHref,
  deleteHref,
}: {
  rawHref: string;
  /** The file's text, to copy; null for binary or very large files. */
  text: string | null;
  editHref?: string;
  deleteHref?: string;
}) {
  return (
    <TooltipProvider>
      <div className="flex items-center gap-1">
        <Button size="compact" nativeButton={false} render={<Link href={rawHref} prefetch={false} />} className="mr-1">
          Raw
        </Button>
        {text !== null && <CopyButton text={text} label="Copy raw file" />}
        {editHref && <IconLink href={editHref} label="Edit this file" icon={<PencilIcon />} />}
        {deleteHref && <IconLink href={deleteHref} label="Delete this file" icon={<TrashIcon />} className="hover:text-red!" />}
      </div>
    </TooltipProvider>
  );
}