~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
56 lines · 1.5 KB Raw History
import { CheckIcon, CircleDotIcon, XIcon } from 'lucide-react';
import { cn } from '#/lib/utils.js';

/**
 * How each issue state reads, in the two places a state is shown: a pill on
 * the thread, an icon on a row of many.
 *
 * The fill says whether anything was done, the same way a pull request's
 * does. Open is the live state and resolved is the one it was carried to, so
 * both are filled. Declined is the state where the work was not done, and it
 * reads unfilled, which is also the one difference a monochrome palette can
 * draw between two settled states.
 */
export const ISSUE_STATES = {
  open: {
    label: 'Open',
    Icon: CircleDotIcon,
    pill: 'bg-success text-background',
    ink: 'text-success',
  },
  resolved: {
    label: 'Resolved',
    Icon: CheckIcon,
    pill: 'bg-key text-background',
    ink: 'text-key',
  },
  declined: {
    label: 'Declined',
    Icon: XIcon,
    pill: 'border border-input text-muted-foreground',
    ink: 'text-faint',
  },
};

/** @param {string} state */
export const issueLook = (state) => ISSUE_STATES[state] ?? ISSUE_STATES.open;

/**
 * The state of one issue, as the first thing its page says.
 * @param {{state: string, className?: string}} props
 */
export function IssueStatePill({ state, className }) {
  const look = issueLook(state);
  return (
    <span
      className={cn(
        'flex shrink-0 items-center gap-1.5 rounded-full px-2.5 py-1 font-medium text-[12.5px]',
        look.pill,
        className,
      )}
    >
      <look.Icon className="size-3.5" />
      {look.label}
    </span>
  );
}