SPB Git

Repository Public

badge.tsx 2.4 KB 47 lines tsx

1import * as React from 'react';2import type { Health } from '@cr/shared';3import { cn } from '@/lib/cn';45export type Tone = 'neutral' | 'accent' | 'success' | 'warning' | 'error' | 'muted' | 'coral';6const TONES: Record<Tone, string> = {7  neutral: 'border-transparent bg-surface-2 text-text-2',8  accent: 'border-transparent bg-accent/10 text-accent',9  success: 'border-transparent bg-success-vivid/12 text-success',10  warning: 'border-transparent bg-warning-vivid/15 text-warning',11  error: 'border-transparent bg-error-vivid/12 text-error',12  muted: 'border-line-2 bg-transparent text-muted',13  coral: 'border-transparent bg-coral/15 text-coral-ink',14};15export function Badge({ tone = 'neutral', className, children, ...props }: React.HTMLAttributes<HTMLSpanElement> & { tone?: Tone }) {16  return (17    <span className={cn('inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-2 text-[11px] font-medium leading-none', TONES[tone], className)} {...props}>18      {children}19    </span>20  );21}2223const DOT: Record<Tone, string> = {24  neutral: 'bg-faint', accent: 'bg-accent', success: 'bg-success-vivid', warning: 'bg-warning-vivid', error: 'bg-error-vivid', muted: 'bg-faint', coral: 'bg-coral',25};26export function Dot({ tone, pulse, className, label }: { tone: Tone; pulse?: boolean; className?: string; label?: string }) {27  return <span role={label ? 'img' : undefined} aria-label={label} className={cn('inline-block size-2 shrink-0 rounded-full', DOT[tone], pulse && 'anim-pulse', className)} />;28}2930export const HEALTH_TONE: Record<Health, Exclude<Tone, 'coral'>> = { ONLINE: 'success', OFFLINE: 'error', DEGRADED: 'warning', UNKNOWN: 'muted' };31/** Health indicator. UNKNOWN is a hollow ring so it can never be mistaken for a live state. */32export function StatusDot({ health, className, withLabel }: { health: Health; className?: string; withLabel?: boolean }) {33  const dot =34    health === 'UNKNOWN' ? (35      <span role="img" aria-label="UNKNOWN" className={cn('inline-block size-2 shrink-0 rounded-full border-[1.5px] border-faint', className)} />36    ) : (37      <Dot tone={HEALTH_TONE[health]} label={health} className={className} />38    );39  if (!withLabel) return dot;40  return (41    <span className="inline-flex items-center gap-1.5">42      {dot}43      <span className={cn('text-[11px] font-medium tracking-wide', health === 'UNKNOWN' ? 'text-muted' : 'text-text-2')}>{health}</span>44    </span>45  );46}47
Files main
Menu

Theme