65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import React from 'react';
|
|
|
|
interface BadgeProps {
|
|
children: React.ReactNode;
|
|
variant?: 'emerald' | 'indigo' | 'cyan' | 'purple' | 'amber' | 'neutral' | 'tangerine' | 'sky';
|
|
showDot?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
export const Badge: React.FC<BadgeProps> = ({
|
|
children,
|
|
variant = 'tangerine',
|
|
showDot = true,
|
|
className = ''
|
|
}) => {
|
|
const styles = {
|
|
tangerine: {
|
|
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
|
dot: 'bg-orange-400'
|
|
},
|
|
sky: {
|
|
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
|
dot: 'bg-sky-400'
|
|
},
|
|
emerald: {
|
|
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
|
dot: 'bg-sky-400'
|
|
},
|
|
indigo: {
|
|
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
|
dot: 'bg-orange-400'
|
|
},
|
|
cyan: {
|
|
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
|
dot: 'bg-sky-400'
|
|
},
|
|
purple: {
|
|
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
|
dot: 'bg-sky-400'
|
|
},
|
|
amber: {
|
|
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
|
dot: 'bg-amber-400'
|
|
},
|
|
neutral: {
|
|
bg: 'bg-slate-800/80 text-slate-300 border-slate-700/60',
|
|
dot: 'bg-slate-400'
|
|
}
|
|
};
|
|
|
|
const current = styles[variant];
|
|
|
|
return (
|
|
<span className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium border backdrop-blur-md shadow-inner tracking-wide ${current.bg} ${className}`}>
|
|
{showDot && (
|
|
<span className="relative flex h-2 w-2">
|
|
<span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${current.dot}`} />
|
|
<span className={`relative inline-flex rounded-full h-2 w-2 ${current.dot}`} />
|
|
</span>
|
|
)}
|
|
{children}
|
|
</span>
|
|
);
|
|
};
|