Badge

Interactive UI Explorer

아래에서 각 컴포넌트의 다양한 Variants States를 문서화된 형태로 테스트해볼 수 있습니다.

Live Preview
DefaultSuccessWarningErrorInfoPremiumNeon

Badge

상태, 카테고리 등을 표시하는 배지 컴포넌트입니다.

Variants

배지의 다양한 색상 variant

Default
<Badge variant="default">Default</Badge>
Default
Live Preview
Success
<Badge variant="success">Success</Badge>
Success
Live Preview
Warning
<Badge variant="warning">Warning</Badge>
Warning
Live Preview
Error
<Badge variant="error">Error</Badge>
Error
Live Preview
Info
<Badge variant="info">Info</Badge>
Info
Live Preview

Sizes

배지의 다양한 크기

Small
<Badge size="sm">Small</Badge>
Small
Live Preview
Medium
<Badge size="md">Medium</Badge>
Medium
Live Preview
Large
<Badge size="lg">Large</Badge>
Large
Live Preview
Implementation

제작 코드

이 컴포넌트가 실제로 어떻게 구현되어 있는지 — 본체 .tsx 파일을 그대로 보여줍니다. variant 매핑·접근성 처리·forwardRef 패턴 등 디테일을 그대로 확인할 수 있어요.

Badgetypescript
/**
 * Badge 컴포넌트
 * 
 * 상태, 카테고리 등을 표시하는 배지 컴포넌트입니다.
 */
import { HTMLAttributes, forwardRef } from 'react';
import { cn } from '@/lib/cn';

export type BadgeVariant = 'default' | 'success' | 'warning' | 'error' | 'info' | 'premium' | 'neon';
export type BadgeSize = 'sm' | 'md' | 'lg';

export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
  variant?: BadgeVariant;
  size?: BadgeSize;
}

const variantStyles: Record<BadgeVariant, string> = {
  default: 'bg-slate-100 text-slate-700 border border-slate-200',
  success: 'bg-emerald-50 text-emerald-700 border border-emerald-200',
  warning: 'bg-amber-50 text-amber-700 border border-amber-200',
  error: 'bg-rose-50 text-rose-700 border border-rose-200',
  info: 'bg-sky-50 text-sky-700 border border-sky-200',
  premium: 'bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 text-white shadow-[0_2px_10px_rgba(168,85,247,0.4)] border border-white/20 font-bold tracking-wide relative overflow-hidden before:absolute before:inset-0 before:bg-gradient-to-t before:from-black/10 before:to-transparent',
  neon: 'bg-transparent text-cyan-600 border border-cyan-400/60 shadow-[0_0_10px_rgba(6,182,212,0.15),inset_0_0_8px_rgba(6,182,212,0.08)] font-bold tracking-wide',
};

const sizeStyles: Record<BadgeSize, string> = {
  sm: 'px-2 py-0.5 text-xs',
  md: 'px-2.5 py-1 text-sm',
  lg: 'px-3 py-1.5 text-base',
};

export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
  ({ className, variant = 'default', size = 'md', children, ...props }, ref) => {
    return (
      <span
        ref={ref}
        className={cn(
          'inline-flex items-center rounded-full font-medium',
          variantStyles[variant],
          sizeStyles[size],
          className
        )}
        {...props}
      >
        {children}
      </span>
    );
  }
);

Badge.displayName = 'Badge';