Spaces:
Sleeping
Sleeping
| import { fmt } from "@/lib/data"; | |
| import HourBar from "./HourBar"; | |
| export interface TopicBarsProps { | |
| items: ReadonlyArray<{ label: string; vi?: string; hours: number }>; | |
| } | |
| /** Horizontal topic-distribution bars (widths relative to the largest topic). */ | |
| export default function TopicBars({ items }: TopicBarsProps) { | |
| const max = Math.max(...items.map((t) => t.hours)); | |
| const total = items.reduce((sum, t) => sum + t.hours, 0); | |
| return ( | |
| <ul className="hairline depth-1 flex flex-col rounded-sm bg-surface px-4 py-1"> | |
| {items.map((t, i) => ( | |
| <li | |
| key={t.label} | |
| className={ | |
| "grid grid-cols-[minmax(9rem,12rem)_1fr_auto] items-center gap-x-4 py-3 " + | |
| (i < items.length - 1 ? "hairline-b" : "") | |
| } | |
| > | |
| <span className="flex flex-col"> | |
| <span className="text-[13px] text-text">{t.label}</span> | |
| {t.vi && ( | |
| <span lang="vi" className="text-[11px] leading-snug text-muted"> | |
| {t.vi} | |
| </span> | |
| )} | |
| </span> | |
| {/* the dominant domain carries the one quiet phosphor note */} | |
| <HourBar | |
| share={t.hours / max} | |
| tone={t.hours === max ? "accent-soft" : "muted"} | |
| /> | |
| <span className="num whitespace-nowrap text-right text-[12px] text-text"> | |
| {fmt(t.hours, 1)} | |
| <span className="text-muted"> h</span> | |
| <span className="ml-2 hidden text-muted sm:inline"> | |
| {((t.hours / total) * 100).toFixed(0)}% | |
| </span> | |
| </span> | |
| </li> | |
| ))} | |
| </ul> | |
| ); | |
| } | |