36 lines · 1.1 KB
import { cn } from "~/utils/cn";
import { TONE_FILL, type Tone } from "~/ui/tones";

const FULL_PERCENT = 100;
const WARN_PERCENT = 80;

/** Picks neutral → warning → danger as usage approaches a quota. */
export function quotaTone(percent: number): Tone {
  if (percent >= FULL_PERCENT) return "danger";
  if (percent >= WARN_PERCENT) return "warning";
  return "neutral";
}

type Props = {
  /** 0–100. Omit for an indeterminate animation. */
  percent?: number;
  tone?: Tone;
  className?: string;
};

export function ProgressTrack({ percent, tone = "neutral", className }: Props) {
  const indeterminate = percent === undefined;
  return (
    <div aria-hidden className={cn("relative h-1.5 overflow-hidden rounded-full bg-kumo-fill", className)}>
      <div
        className={cn(
          "h-full rounded-full transition-all duration-700",
          TONE_FILL[tone],
          indeterminate && "animate-indeterminate absolute inset-y-0 w-1/3",
        )}
        style={indeterminate ? undefined : { width: `${Math.min(FULL_PERCENT, Math.max(0, percent))}%` }}
      />
    </div>
  );
}