SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
12 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
3.0 KB · 65 lines tsx
Raw Blame History
1import Link from 'next/link';2import { t } from '@/i18n';3import { routes } from '@/lib/site';4import { Logo } from '@/components/brand/Logo';5import { MoreMenu } from './more-menu';6import { NavLinks } from './nav-links';7import { SearchTrigger } from './search-trigger';8import { ThemeToggle } from './theme-toggle';910/** Primary desktop navigation (order from the product spec); everything else lives under "More". */11export const PRIMARY_NAV = [12  { key: 'nav.explore', href: routes.explore() },13  { key: 'nav.countries', href: routes.countries() },14  { key: 'nav.compare', href: routes.compare() },15  { key: 'nav.rankings', href: routes.rankings() },16  { key: 'nav.indicators', href: routes.indicators() },17  { key: 'nav.changes', href: routes.changes() },18] as const;1920export const MORE_NAV: ReadonlyArray<{ key: string; href: string; group: 'explore' | 'reference' }> = [21  { key: 'nav.regions', href: routes.regions(), group: 'explore' },22  { key: 'nav.trajectories', href: routes.trajectories(), group: 'explore' },23  { key: 'nav.scatter', href: routes.scatter(), group: 'explore' },24  { key: 'nav.finder', href: routes.finder(), group: 'explore' },25  { key: 'nav.extremes', href: routes.extremes(), group: 'explore' },26  { key: 'nav.peers', href: routes.peers(), group: 'explore' },27  { key: 'nav.stories', href: routes.stories(), group: 'explore' },28  { key: 'nav.sources', href: routes.sources(), group: 'reference' },29  { key: 'nav.api', href: routes.api(), group: 'reference' },30  { key: 'nav.downloads', href: routes.download(), group: 'reference' },31  { key: 'nav.updates', href: routes.updates(), group: 'reference' },32  { key: 'nav.methodology', href: routes.methodology(), group: 'reference' },33];3435/** Sticky top bar: wordmark, primary nav (md+), "More" menu, search trigger, theme toggle. 52 px tall on mobile, 56 on md. */36export function SiteHeader() {37  return (38    <header className="sticky top-0 z-30 border-b border-rule bg-paper/95 backdrop-blur supports-[backdrop-filter]:bg-paper/85">39      <div className="container-x mx-auto flex h-[52px] max-w-[1400px] items-center gap-3 md:h-14">40        <Link href={routes.home()} className="flex h-11 items-center rounded-sm pr-1" aria-label={t('brand.home')}>41          <span className="md:hidden lg:inline-flex">42            <Logo variant="full" />43          </span>44          <span className="hidden md:inline-flex lg:hidden">45            <Logo variant="mark" />46          </span>47        </Link>48        <NavLinks items={PRIMARY_NAV.map((n) => ({ href: n.href, label: t(n.key) }))} />49        <div className="hidden md:block">50          <MoreMenu items={MORE_NAV.map((n) => ({ href: n.href, label: t(n.key as 'nav.regions'), group: n.group }))} />51        </div>52        <div className="ml-auto flex items-center gap-1">53          <div className="hidden lg:block">54            <SearchTrigger variant="field" />55          </div>56          <div className="lg:hidden">57            <SearchTrigger variant="icon" />58          </div>59          <ThemeToggle />60        </div>61      </div>62    </header>63  );64}65