1interface LabelBadgeProps {
2 name: string;
3 color: { R: number; G: number; B: number };
4 onClick?: (name: string) => void;
5}
6
7function contrastColor(r: number, g: number, b: number): string {
8 // Perceived luminance — pick black or white text for readability
9 const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
10 return luminance > 0.55 ? "rgba(0,0,0,0.75)" : "rgba(255,255,255,0.9)";
11}
12
13// Coloured label pill. Renders as a <button> when onClick is provided,
14// used in BugRow and UserProfilePage to filter issues by label.
15export function LabelBadge({ name, color, onClick }: LabelBadgeProps) {
16 const bg = `rgb(${color.R},${color.G},${color.B})`;
17 const text = contrastColor(color.R, color.G, color.B);
18
19 if (onClick) {
20 return (
21 <button
22 type="button"
23 className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium hover:opacity-80"
24 style={{ backgroundColor: bg, color: text }}
25 onClick={(e) => {
26 e.preventDefault();
27 e.stopPropagation();
28 onClick(name);
29 }}
30 >
31 {name}
32 </button>
33 );
34 }
35
36 return (
37 <span
38 className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium"
39 style={{ backgroundColor: bg, color: text }}
40 >
41 {name}
42 </span>
43 );
44}