51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
import clsx from 'clsx';
|
|
import React, { useMemo } from 'react';
|
|
|
|
import { hexToHsl } from '@/utils/theme';
|
|
|
|
interface IBadge {
|
|
title: React.ReactNode | string;
|
|
slug: string;
|
|
color?: string;
|
|
}
|
|
/** Badge to display on a user's profile. */
|
|
const Badge: React.FC<IBadge> = ({ title, slug, color }) => {
|
|
const fallback = !['patron', 'admin', 'moderator', 'opaque'].includes(slug);
|
|
|
|
const isDark = useMemo(() => {
|
|
if (!color) return false;
|
|
|
|
const hsl = hexToHsl(color);
|
|
|
|
if (hsl && hsl.l > 50) return false;
|
|
|
|
return true;
|
|
}, [color]);
|
|
|
|
return (
|
|
<span
|
|
data-testid='badge'
|
|
className={clsx(
|
|
'inline-flex items-center rounded px-2 py-0.5 text-xs font-medium',
|
|
color
|
|
? {
|
|
'bg-gray-100 text-gray-100': isDark,
|
|
'bg-gray-800 text-gray-900': !isDark,
|
|
}
|
|
: {
|
|
'bg-fuchsia-700 text-white': slug === 'patron',
|
|
'bg-black text-white': slug === 'admin',
|
|
'bg-cyan-600 text-white': slug === 'moderator',
|
|
'bg-gray-100 text-gray-900 dark:bg-gray-800 dark:text-gray-100': fallback,
|
|
'bg-white/75 text-gray-900': slug === 'opaque',
|
|
},
|
|
)}
|
|
style={color ? { background: color } : undefined}
|
|
>
|
|
{title}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
export { Badge as default };
|