spb/countryatlas
Public
TypeScript 57%
Python 38.6%
JavaScript 3.6%
CSS 0.6%
1'use client';2import Link from 'next/link';3import { t } from '@/i18n';4import { cn } from '@/lib/cn';5import { displayValue, formatPeriod } from '@/lib/format';6import { routes } from '@/lib/site';7import type { MetricValue } from '@/lib/types';8import { ChangeChip } from '@/components/data/change-chip';9import { payloadFor, type MetricCountry } from '@/components/data/metric';10import { useProvenance } from '@/components/data/provenance-context';11import { RankBadge } from '@/components/data/rank-badge';1213/**14 * Latest values of a subtopic, shown while its charts are collapsed on a long topic page: name · value · period15 * (highlighted when ≥ 2 years older than the newest value of the block) · change · world rank. Value → provenance.16 */17export function TopicCompact({ rows, country, regionName }: { rows: MetricValue[]; country: MetricCountry; regionName?: string | null }) {18 const { open } = useProvenance();19 const latestYear = Math.max(0, ...rows.map((m) => m.year ?? 0));20 return (21 <div className="min-w-0">22 <p className="mb-1 text-xs text-ink-3">{t('topic.collapsedHint')}</p>23 <ul className="divide-y divide-rule border-b border-rule text-sm">24 {rows.map((m) => {25 const stale = m.year != null && latestYear - m.year >= 2;26 return (27 <li key={m.indicator} className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 py-1 sm:grid-cols-[minmax(0,1fr)_auto_minmax(5rem,auto)_minmax(6rem,auto)]">28 <Link href={routes.indicator(m.indicator)} className="link-quiet inline-flex min-h-[44px] min-w-0 items-center text-ink md:min-h-[36px]">29 <span className="truncate">{m.indicator_name ?? m.indicator}</span>30 </Link>31 <button type="button" onClick={() => open(payloadFor(m, country))} className="tnum -mx-1 inline-flex min-h-[44px] items-baseline justify-end gap-1.5 rounded-sm px-1 text-right hover:bg-surface-2 md:min-h-[36px]" aria-label={`${m.indicator_name ?? m.indicator}: ${displayValue(m.value, m, m.formatted)} (${formatPeriod(m.period, m.frequency)}). ${t('common.openProvenance')}`}>32 <span className="font-medium text-ink">{displayValue(m.value, m, m.formatted)}</span>33 <span className={cn('text-2xs', stale ? 'rounded-xs bg-surface-2 px-1 text-ink-2' : 'text-ink-3')}>{formatPeriod(m.period, m.frequency)}</span>34 </button>35 <span className="hidden justify-end sm:flex">36 <ChangeChip change={m.change} spec={m} showVs={false} />37 </span>38 <span className="hidden min-w-0 justify-end truncate text-right sm:flex">39 <RankBadge rank={m} regionName={regionName} compact />40 </span>41 </li>42 );43 })}44 </ul>45 </div>46 );47}48