spb/countryatlas
Public
TypeScript 57%
Python 38.6%
JavaScript 3.6%
CSS 0.6%
1import { t } from '@/i18n';2import { cn } from '@/lib/cn';3import { MAP_HEIGHT, MAP_WIDTH, isoLookupFromCountries, worldPaths } from '@/lib/map-geo';4import type { CountrySummary } from '@/lib/types';56/**7 * Server-rendered world map highlighting a group's members (accent) against the other countries (surface-2).8 * Static SVG — no hover layer needed, the members table below carries the detail.9 */10export function MemberMap({ members, countries, name, className }: { members: string[]; countries: CountrySummary[]; name: string; className?: string }) {11 const { paths, sphere } = worldPaths();12 const numeric = isoLookupFromCountries(countries as Array<{ id: string; iso_numeric?: string | null }>);13 const set = new Set(members);14 const summary = t('region.map.summary', { n: members.length, name });15 return (16 <figure className={cn('min-w-0', className)}>17 <div className="relative w-full" style={{ aspectRatio: `${MAP_WIDTH} / ${MAP_HEIGHT}` }}>18 <svg viewBox={`0 0 ${MAP_WIDTH} ${MAP_HEIGHT}`} className="h-full w-full" role="img" aria-label={summary}>19 <title>{summary}</title>20 <path d={sphere} fill="var(--surface)" stroke="var(--rule)" strokeWidth={1} />21 <g stroke="var(--surface)" strokeWidth={0.6} strokeLinejoin="round">22 {paths.map((p, i) => {23 const iso3 = p.iso3 ?? (p.numeric ? numeric.get(p.numeric) ?? null : null);24 const on = iso3 ? set.has(iso3) : false;25 return <path key={iso3 ?? `${p.name}-${i}`} d={p.d} fill={on ? 'var(--accent)' : 'var(--nodata)'} fillOpacity={on ? 0.9 : 0.55} />;26 })}27 </g>28 </svg>29 </div>30 <figcaption className="mt-2 flex flex-wrap items-center gap-x-3 text-2xs text-ink-2">31 <span className="inline-flex items-center gap-1">32 <span aria-hidden className="inline-block h-2.5 w-3.5 rounded-xs bg-accent" /> {name}33 </span>34 <span className="inline-flex items-center gap-1">35 <span aria-hidden className="inline-block h-2.5 w-3.5 rounded-xs bg-nodata" /> {t('chart.legend.noData')}36 </span>37 </figcaption>38 </figure>39 );40}41