// components/ui/Badge.tsx 'use client'; import clsx from 'clsx'; import * as React from 'react'; type BadgeTone = | 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink'; type BadgeVariant = 'border' | 'flat'; type BadgeShape = 'rounded' | 'pill'; type BadgeSize = 'sm' | 'md'; export type BadgeProps = { children: React.ReactNode; tone?: BadgeTone; variant?: BadgeVariant; shape?: BadgeShape; size?: BadgeSize; /** Zeigt vorne einen farbigen Punkt an */ dot?: boolean; /** Wenn gesetzt, wird rechts ein Remove-Button angezeigt */ onRemove?: () => void; className?: string; }; /* ───────── Style-Mappings ───────── */ const baseClasses = 'inline-flex items-center text-xs font-medium'; const sizeClasses: Record = { md: 'px-2 py-1', sm: 'px-1.5 py-0.5', }; const shapeClasses: Record = { rounded: 'rounded-md', pill: 'rounded-full', }; const borderToneClasses: Record = { gray: 'bg-gray-50 text-gray-600 inset-ring inset-ring-gray-500/10 dark:bg-gray-400/10 dark:text-gray-400 dark:inset-ring-gray-400/20', red: 'bg-red-50 text-red-700 inset-ring inset-ring-red-600/10 dark:bg-red-400/10 dark:text-red-400 dark:inset-ring-red-400/20', yellow: 'bg-yellow-50 text-yellow-800 inset-ring inset-ring-yellow-600/20 dark:bg-yellow-400/10 dark:text-yellow-500 dark:inset-ring-yellow-400/20', green: 'bg-green-50 text-green-700 inset-ring inset-ring-green-600/20 dark:bg-green-400/10 dark:text-green-400 dark:inset-ring-green-500/20', blue: 'bg-blue-50 text-blue-700 inset-ring inset-ring-blue-700/10 dark:bg-blue-400/10 dark:text-blue-400 dark:inset-ring-blue-400/30', indigo: 'bg-indigo-50 text-indigo-700 inset-ring inset-ring-indigo-700/10 dark:bg-indigo-400/10 dark:text-indigo-400 dark:inset-ring-indigo-400/30', purple: 'bg-purple-50 text-purple-700 inset-ring inset-ring-purple-700/10 dark:bg-purple-400/10 dark:text-purple-400 dark:inset-ring-purple-400/30', pink: 'bg-pink-50 text-pink-700 inset-ring inset-ring-pink-700/10 dark:bg-pink-400/10 dark:text-pink-400 dark:inset-ring-pink-400/20', }; const flatToneClasses: Record = { gray: 'bg-gray-100 text-gray-600 dark:bg-gray-400/10 dark:text-gray-400', red: 'bg-red-100 text-red-700 dark:bg-red-400/10 dark:text-red-400', yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-400/10 dark:text-yellow-500', green: 'bg-green-100 text-green-700 dark:bg-green-400/10 dark:text-green-400', blue: 'bg-blue-100 text-blue-700 dark:bg-blue-400/10 dark:text-blue-400', indigo: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-400/10 dark:text-indigo-400', purple: 'bg-purple-100 text-purple-700 dark:bg-purple-400/10 dark:text-purple-400', pink: 'bg-pink-100 text-pink-700 dark:bg-pink-400/10 dark:text-pink-400', }; const dotToneClasses: Record = { gray: 'fill-gray-400', red: 'fill-red-500 dark:fill-red-400', yellow: 'fill-yellow-500 dark:fill-yellow-400', green: 'fill-green-500 dark:fill-green-400', blue: 'fill-blue-500 dark:fill-blue-400', indigo: 'fill-indigo-500 dark:fill-indigo-400', purple: 'fill-purple-500 dark:fill-purple-400', pink: 'fill-pink-500 dark:fill-pink-400', }; /* ───────── Component ───────── */ export default function Badge({ children, tone = 'gray', variant = 'border', shape = 'rounded', size = 'md', dot = false, onRemove, className, }: BadgeProps) { const toneClasses = variant === 'border' ? borderToneClasses[tone] : flatToneClasses[tone]; const hasRemove = typeof onRemove === 'function'; return ( {/* Dot (optional) */} {dot && ( )} {children} {/* Remove-Button (optional) */} {hasRemove && ( )} ); }