first publish
This commit is contained in:
70
src/components/layout/LangSwitch.tsx
Normal file
70
src/components/layout/LangSwitch.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
"use client";
|
||||
|
||||
import { usePathname } from "next/navigation";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { counterpart, langSwitch, otherLang, type Lang } from "@/lib/i18n";
|
||||
import { TransitionLink } from "@/components/motion/TransitionLink";
|
||||
|
||||
/**
|
||||
* Sprachumschalter im Kopf. Steht an der Stelle, an der vorher „Kontakt“ stand.
|
||||
*
|
||||
* Zeigt beide Sprachen: die aktive als stiller Zustand, die andere als Link auf das
|
||||
* Gegenstück derselben Seite (`counterpart()`), nicht pauschal auf die Startseite.
|
||||
*
|
||||
* Zur Flagge: Eine Flagge steht für ein Land, nicht für eine Sprache – deshalb steht
|
||||
* neben ihr immer das Sprachkürzel, und der zugängliche Name nennt die Sprache
|
||||
* ausgeschrieben. Wer die Flaggen weglassen will, entfernt hier zwei Zeilen.
|
||||
*/
|
||||
export function LangSwitch({ lang, className }: { lang: Lang; className?: string }) {
|
||||
const pathname = usePathname() ?? "/";
|
||||
const other = otherLang(lang);
|
||||
const href = counterpart(pathname, other);
|
||||
|
||||
const base =
|
||||
"inline-flex items-center gap-1.5 font-mono text-[11px] uppercase tracking-[0.14em] transition-colors duration-300";
|
||||
|
||||
return (
|
||||
<div className={cn("flex items-center gap-2", className)}>
|
||||
<span className={cn(base, "text-accent")} aria-current="true" title={langSwitch[lang].title}>
|
||||
<Flag lang={lang} />
|
||||
{langSwitch[lang].short}
|
||||
</span>
|
||||
<span aria-hidden="true" className="h-3 w-px bg-line" />
|
||||
<TransitionLink
|
||||
href={href}
|
||||
label={langSwitch[other].label}
|
||||
hrefLang={other}
|
||||
aria-label={langSwitch[other].title}
|
||||
className={cn(base, "-my-3 py-3 text-fg-muted hover:text-accent focus-visible:text-accent")}
|
||||
>
|
||||
<Flag lang={other} />
|
||||
{langSwitch[other].short}
|
||||
</TransitionLink>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** 16 × 11 px, randlos, damit die Fahne neben 11-px-Versalien nicht dominiert. */
|
||||
function Flag({ lang }: { lang: Lang }) {
|
||||
const common = { width: 16, height: 11, viewBox: "0 0 16 11", "aria-hidden": true as const, className: "shrink-0" };
|
||||
if (lang === "de") {
|
||||
return (
|
||||
<svg {...common}>
|
||||
<rect width="16" height="11" fill="#0C0C0C" />
|
||||
<rect y="3.667" width="16" height="3.667" fill="#DD0000" />
|
||||
<rect y="7.334" width="16" height="3.666" fill="#FFCE00" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<svg {...common}>
|
||||
<rect width="16" height="11" fill="#012169" />
|
||||
<path d="M0 0 16 11M16 0 0 11" stroke="#FFF" strokeWidth="2.2" />
|
||||
<path d="M0 0 16 11M16 0 0 11" stroke="#C8102E" strokeWidth="1.1" />
|
||||
<path d="M8 0v11M0 5.5h16" stroke="#FFF" strokeWidth="3.7" />
|
||||
<path d="M8 0v11M0 5.5h16" stroke="#C8102E" strokeWidth="2.2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default LangSwitch;
|
||||
Reference in New Issue
Block a user