Display bar chart labels inside bars with adaptive text color

Move game/type labels from a fixed-width column into the bar itself so
long names like "Pokemon Brilliant Diamond" aren't truncated. Compute
luminance from the bar's hex color to pick dark or light text, with a
subtle text shadow for readability at bar/track boundaries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 22:00:11 +01:00
parent 1884a085f3
commit 7d4fdcd8ae

View File

@@ -96,6 +96,13 @@ function PokemonList({
)
}
function hexLuminance(hex: string): number {
const r = parseInt(hex.slice(1, 3), 16)
const g = parseInt(hex.slice(3, 5), 16)
const b = parseInt(hex.slice(5, 7), 16)
return (0.299 * r + 0.587 * g + 0.114 * b) / 255
}
function HorizontalBar({
label,
value,
@@ -110,12 +117,10 @@ function HorizontalBar({
colorHex?: string
}) {
const width = max > 0 ? (value / max) * 100 : 0
const isLight = colorHex ? hexLuminance(colorHex) > 0.55 : false
return (
<div className="flex items-center gap-2 text-sm">
<span className="w-24 text-right text-gray-600 dark:text-gray-400 capitalize shrink-0 truncate">
{label}
</span>
<div className="flex-1 bg-gray-100 dark:bg-gray-700 rounded-full h-5 overflow-hidden">
<div className="flex-1 bg-gray-100 dark:bg-gray-700 rounded-full h-6 overflow-hidden relative">
<div
className={`h-full rounded-full ${color ?? ''}`}
style={{
@@ -123,6 +128,20 @@ function HorizontalBar({
...(colorHex ? { backgroundColor: colorHex } : {}),
}}
/>
<span
className={`absolute inset-0 flex items-center px-3 text-xs font-medium capitalize truncate ${
isLight
? 'text-gray-900 dark:text-gray-900'
: 'text-gray-700 dark:text-gray-200'
}`}
style={{
textShadow: isLight
? '0 0 4px rgba(255,255,255,0.8)'
: '0 0 4px rgba(0,0,0,0.3)',
}}
>
{label}
</span>
</div>
<span className="w-8 text-right text-gray-700 dark:text-gray-300 font-medium shrink-0">
{value}