SPB Git

Repository Public

badge.tsx 1.5 KB 29 lines tsx

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
Files main
Menu

Theme