Vectrum
Sign In
30 lines · 1.4 KB · TypeScript
import { MergeIcon, PullRequestClosedIcon, PullRequestIcon } from "@/components/icons";
import { Label } from "@/components/ui";
import type { PullState } from "@/lib/pulls";

// A pull request's state: green open, dimmed draft, the accent for merged, red closed, like the
// issue status glyphs.

const COLORS: Record<PullState | "draft", string> = {
  open: "text-green-deep",
  draft: "text-ink3",
  merged: "text-[#8250df]",
  closed: "text-red",
};

export const pullStateName = (state: PullState, draft: boolean) => (state === "open" ? (draft ? "Draft" : "Open") : state === "merged" ? "Merged" : "Closed");

export function PullStateIcon({ state, draft = false, size = 16, className = "" }: { state: PullState; draft?: boolean; size?: number; className?: string }) {
  const kind = state === "open" && draft ? "draft" : state;
  const Icon = state === "merged" ? MergeIcon : state === "closed" ? PullRequestClosedIcon : PullRequestIcon;
  return <Icon width={size} height={size} className={`shrink-0 ${COLORS[kind]} ${className}`} aria-label={pullStateName(state, draft)} role="img" />;
}

export function PullStateLabel({ state, draft = false }: { state: PullState; draft?: boolean }) {
  const tone = state === "open" ? (draft ? "default" : "success") : state === "merged" ? "accent" : "danger";
  return (
    <Label tone={tone}>
      <PullStateIcon state={state} draft={draft} size={12} className="text-current" /> {pullStateName(state, draft)}
    </Label>
  );
}