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) => { e.preventDefault(); e.stopPropagation(); onClick(name) }}
26 >
27 {name}
28 </button>
29 )
30 }
31
32 return (
33 <span
34 className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium"
35 style={{ backgroundColor: bg, color: text }}
36 >
37 {name}
38 </span>
39 )
40}