Repository Public
1import * as React from 'react';2import { cn } from '@/lib/cn';34export type Tone = 'neutral' | 'accent' | 'success' | 'warning' | 'error' | 'muted' | 'info';5const TONES: Record<Tone, string> = {6 neutral: 'border-transparent bg-surface-2 text-text-2',7 accent: 'border-transparent bg-accent/10 text-accent',8 success: 'border-transparent bg-success-vivid/12 text-success',9 warning: 'border-transparent bg-warning-vivid/15 text-warning',10 error: 'border-transparent bg-error-vivid/12 text-error',11 muted: 'border-line-2 bg-transparent text-muted',12 info: 'border-transparent bg-info/15 text-info-ink',13};14export function Badge({ tone = 'neutral', className, children, ...props }: React.HTMLAttributes<HTMLSpanElement> & { tone?: Tone }) {15 return (16 <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}>17 {children}18 </span>19 );20}2122const DOT: Record<Tone, string> = {23 neutral: 'bg-faint', accent: 'bg-accent', success: 'bg-success-vivid', warning: 'bg-warning-vivid', error: 'bg-error-vivid', muted: 'bg-faint', info: 'bg-info',24};25export function Dot({ tone, pulse, className, label }: { tone: Tone; pulse?: boolean; className?: string; label?: string }) {26 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)} />;27}2829