@@ -0,0 +1,83 @@
|
||||
---
|
||||
import Moai from './Moai.astro';
|
||||
import LanguageSwitcher from './LanguageSwitcher.astro';
|
||||
import { localePath, useI18n } from '../i18n';
|
||||
import { pageLocale } from '../i18n/paths';
|
||||
|
||||
interface Props {
|
||||
current?: 'mints' | 'reviews' | 'wallets' | 'about';
|
||||
/** Shows the compact search affordance next to the brand (mint pages, /mints). */
|
||||
mintCount?: number;
|
||||
}
|
||||
const { current, mintCount } = Astro.props;
|
||||
|
||||
const { locale } = pageLocale(Astro);
|
||||
const t = useI18n(locale);
|
||||
|
||||
/*
|
||||
* Route slugs stay English in every language, so the href is the English path run
|
||||
* through `localePath`. See src/i18n/routing.ts for why that trade was made.
|
||||
*/
|
||||
const links = [
|
||||
{ path: '/mints', label: t('nav.mints'), key: 'mints' },
|
||||
{ path: '/reviews', label: t('nav.reviews'), key: 'reviews' },
|
||||
{ path: '/wallets', label: t('nav.wallets'), key: 'wallets' },
|
||||
{ path: '/about', label: t('nav.about'), key: 'about' },
|
||||
] as const;
|
||||
---
|
||||
|
||||
<header class="topbar">
|
||||
<div class="topbar-inner">
|
||||
<a class="brand" href={localePath('/', locale)}>
|
||||
<Moai />
|
||||
{/* Below 420px the wordmark is what pushes the nav off the right edge. The
|
||||
moai stays, and the name stays in the accessibility tree. */}
|
||||
<span class="brand-text">Cashumints.space</span>
|
||||
<span class="sr-only">Cashumints.space</span>
|
||||
</a>
|
||||
|
||||
{
|
||||
mintCount !== undefined && (
|
||||
<a class="topbar-search" href={`${localePath('/mints', locale)}#mint-search`}>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" />
|
||||
</svg>
|
||||
{t('nav.searchMints', { n: mintCount })}
|
||||
<kbd>/</kbd>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
<nav class="nav" aria-label={t('nav.main')}>
|
||||
{
|
||||
links.map((link) => (
|
||||
<a
|
||||
href={localePath(link.path, locale)}
|
||||
aria-current={current === link.key ? 'page' : undefined}
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
|
||||
{/*
|
||||
The language control, next to the account one and in every layout.
|
||||
|
||||
In the header rather than only in the footer because of who needs it: a reader who
|
||||
landed on a page in a language they do not read should not have to scroll the whole
|
||||
of it to get out. The footer keeps its own copy, where someone deliberately looking
|
||||
for site settings expects to find one.
|
||||
*/}
|
||||
<LanguageSwitcher variant="menu" />
|
||||
|
||||
{/*
|
||||
The account control. Prerendered logged out, because a static build cannot know
|
||||
who is reading; the island swaps in the avatar and name from the stored session
|
||||
and the cached profile on first paint, before any relay is asked anything.
|
||||
*/}
|
||||
<div class="auth" data-auth>
|
||||
<button class="auth-login" type="button" data-login-open>{t('login.open')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
Reference in New Issue
Block a user